From 352e9f3ee2ea23e400bcc53c511de0712f8439f5 Mon Sep 17 00:00:00 2001 From: Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com> Date: Sat, 19 Jul 2025 12:24:29 -0400 Subject: [PATCH] 2025/07/19 Update Added PEPS. Full compile. --- nasher.cfg | 12 +- pack_haks.cmd | 1 + src/hakpak/peps_prc8/2da/ai_messages.2da | 49 + src/hakpak/peps_prc8/2da/ai_spells.2da | 19400 +++++++ src/hakpak/peps_prc8/tga/armor_pallet.tga | Bin 0 -> 180268 bytes src/hakpak/peps_prc8/tga/gui_pal_tattoo.tga | Bin 0 -> 180268 bytes src/include/nw_inc_nui.nss | 852 +- src/include/prc_inc_combat.nss | 1 + src/module/dlg/nw_g_animal.dlg.json | 49670 ++++++++++++++++++ src/module/dlg/nw_g_fam.dlg.json | 23412 +++++++++ src/module/dlg/oc_ai_henchmen.dlg.json | 27180 ++++++++++ src/module/ifo/module.ifo.json | 9 +- src/module/nss/0c_assoc_actions.nss | 172 + src/module/nss/0c_cast_polymorp.nss | 18 + src/module/nss/0c_fire_henchmen.nss | 15 + src/module/nss/0c_get_convo.nss | 22 + src/module/nss/0c_get_henchman.nss | 25 + src/module/nss/0c_h_cast_spell.nss | 12 + src/module/nss/0c_henchmenspell.nss | 81 + src/module/nss/0c_if_a_magic_m.nss | 16 + src/module/nss/0c_if_ass_convo.nss | 132 + src/module/nss/0c_if_assoc_mode.nss | 22 + src/module/nss/0c_if_cntrspell.nss | 17 + src/module/nss/0c_if_com_script.nss | 16 + src/module/nss/0c_if_convo.nss | 21 + src/module/nss/0c_if_has_assoc.nss | 18 + src/module/nss/0c_if_has_class.nss | 28 + src/module/nss/0c_if_has_feat.nss | 22 + src/module/nss/0c_if_has_spell.nss | 26 + src/module/nss/0c_if_hen_leave.nss | 12 + src/module/nss/0c_if_identify.nss | 17 + src/module/nss/0c_if_not_master.nss | 11 + src/module/nss/0c_if_open_inven.nss | 13 + src/module/nss/0c_if_pickuploot.nss | 12 + src/module/nss/0c_if_polymorph.nss | 11 + src/module/nss/0c_if_scout.nss | 11 + src/module/nss/0c_if_skillrank.nss | 18 + src/module/nss/0c_if_taunt.nss | 15 + src/module/nss/0c_listhenchman.nss | 19 + src/module/nss/0c_no_com_script.nss | 27 + src/module/nss/0c_remove_effect.nss | 14 + src/module/nss/0c_summon_assoc.nss | 17 + src/module/nss/0c_use_feat.nss | 15 + src/module/nss/0e_c2_1_hb.nss | 16 + src/module/nss/0e_c2_7_ondeath.nss | 32 + src/module/nss/0e_ch_1_hb.nss | 14 + src/module/nss/0e_ch_7_ondeath.nss | 41 + src/module/nss/0e_do_combat_rnd.nss | 22 + src/module/nss/0e_gui_events.nss | 60 + src/module/nss/0e_m1_3_endround.nss | 46 + src/module/nss/0e_nui.nss | 1975 + src/module/nss/0e_nui_dm.nss | 700 + src/module/nss/0e_onclientload.nss | 23 + src/module/nss/0e_player_target.nss | 154 + src/module/nss/0e_prc_ch_events.nss | 78 + src/module/nss/0i_actions.nss | 2325 + src/module/nss/0i_associates.nss | 2192 + src/module/nss/0i_color.nss | 70 + src/module/nss/0i_combat.nss | 3498 ++ src/module/nss/0i_constants.nss | 667 + src/module/nss/0i_gui_events.nss | 1032 + src/module/nss/0i_items.nss | 1243 + src/module/nss/0i_main.nss | 1328 + src/module/nss/0i_menus.nss | 4823 ++ src/module/nss/0i_menus_dm.nss | 1386 + src/module/nss/0i_messages.nss | 88 + src/module/nss/0i_module.nss | 544 + src/module/nss/0i_nui.nss | 434 + src/module/nss/0i_player_target.nss | 793 + src/module/nss/0i_spells.nss | 2157 + src/module/nss/0i_states_cond.nss | 423 + src/module/nss/0i_talents.nss | 3098 ++ src/module/nss/0i_time.nss | 95 + src/module/nss/ai_a_ambusher.nss | 105 + src/module/nss/ai_a_atk_casters.nss | 159 + src/module/nss/ai_a_atk_nearest.nss | 80 + src/module/nss/ai_a_atk_warrior.nss | 159 + src/module/nss/ai_a_barbarian.nss | 87 + src/module/nss/ai_a_bard.nss | 83 + src/module/nss/ai_a_cleric.nss | 102 + src/module/nss/ai_a_cntrspell.nss | 69 + src/module/nss/ai_a_default.nss | 80 + src/module/nss/ai_a_defensive.nss | 77 + src/module/nss/ai_a_druid.nss | 86 + src/module/nss/ai_a_fighter.nss | 82 + src/module/nss/ai_a_flanker.nss | 117 + src/module/nss/ai_a_invisible.nss | 123 + src/module/nss/ai_a_monk.nss | 82 + src/module/nss/ai_a_no_cmb_mode.nss | 131 + src/module/nss/ai_a_paladin.nss | 110 + src/module/nss/ai_a_peaceful.nss | 81 + src/module/nss/ai_a_polymorphed.nss | 70 + src/module/nss/ai_a_ranged.nss | 129 + src/module/nss/ai_a_ranger.nss | 96 + src/module/nss/ai_a_rogue.nss | 83 + src/module/nss/ai_a_sorcerer.nss | 75 + src/module/nss/ai_a_taunter.nss | 53 + src/module/nss/ai_a_wizard.nss | 77 + src/module/nss/ai_ambusher.nss | 100 + src/module/nss/ai_barbarian.nss | 71 + src/module/nss/ai_bard.nss | 67 + src/module/nss/ai_cleric.nss | 68 + src/module/nss/ai_cntrspell.nss | 68 + src/module/nss/ai_coward.nss | 133 + src/module/nss/ai_default.nss | 49 + src/module/nss/ai_defensive.nss | 48 + src/module/nss/ai_dragon.nss | 51 + src/module/nss/ai_druid.nss | 70 + src/module/nss/ai_fighter.nss | 65 + src/module/nss/ai_flanker.nss | 102 + src/module/nss/ai_incorporeal.nss | 83 + src/module/nss/ai_invisible.nss | 93 + src/module/nss/ai_monk.nss | 65 + src/module/nss/ai_paladin.nss | 71 + src/module/nss/ai_polymorphed.nss | 55 + src/module/nss/ai_ranged.nss | 116 + src/module/nss/ai_ranger.nss | 79 + src/module/nss/ai_rogue.nss | 66 + src/module/nss/ai_shadow.nss | 77 + src/module/nss/ai_sorcerer.nss | 61 + src/module/nss/ai_taunter.nss | 78 + src/module/nss/ai_wizard.nss | 63 + src/module/nss/mm_prc_spells.nss | 161 + src/module/nss/nw_c2_default1.nss | 160 +- src/module/nss/nw_c2_default2.nss | 254 +- src/module/nss/nw_c2_default3.nss | 106 +- src/module/nss/nw_c2_default4.nss | 135 +- src/module/nss/nw_c2_default5.nss | 92 +- src/module/nss/nw_c2_default6.nss | 131 +- src/module/nss/nw_c2_default8.nss | 44 +- src/module/nss/nw_c2_defaultb.nss | 183 +- src/module/nss/nw_c2_defaulte.nss | 82 +- src/module/nss/nw_ch_ac1.nss | 158 + src/module/nss/nw_ch_ac2.nss | 107 + src/module/nss/nw_ch_ac3.nss | 56 + src/module/nss/nw_ch_ac4.nss | 45 + src/module/nss/nw_ch_ac5.nss | 51 + src/module/nss/nw_ch_ac6.nss | 32 + src/module/nss/nw_ch_ac8.nss | 25 + src/module/nss/nw_ch_aca.nss | 46 + src/module/nss/nw_ch_acb.nss | 42 + src/module/nss/nw_ch_ace.nss | 60 + src/module/nss/nw_ch_summon_9.nss | 40 + src/module/nss/pc_savebuffs.nss | 182 + src/module/nss/pe_buffing.nss | 534 + src/module/nss/pe_crafting.nss | 2153 + src/module/nss/pe_debug.nss | 900 + src/module/nss/pe_henchmen.nss | 589 + src/module/nss/pe_mod_set.nss | 119 + src/module/nss/pe_test.nss | 227 + src/module/nss/pi_buffing.nss | 338 + src/module/nss/pi_crafting.nss | 717 + src/module/nss/pi_debug.nss | 200 + src/module/nss/pi_forcerest.nss | 70 + src/module/nss/pi_henchmen.nss | 209 + src/module/nss/pi_test.nss | 103 + src/module/nss/pinc_henchmen.nss | 1531 + src/module/nss/xx_pc_1_hb.nss | 79 + src/module/nss/xx_pc_2_percept.nss | 107 + src/module/nss/xx_pc_3_endround.nss | 60 + src/module/nss/xx_pc_4_convers.nss | 30 + src/module/nss/xx_pc_5_phyatked.nss | 29 + src/module/nss/xx_pc_6_damaged.nss | 27 + src/module/nss/xx_pc_8_disturb.nss | 21 + src/module/nss/xx_pc_b_castat.nss | 35 + src/module/nss/xx_pc_e_blocked.nss | 68 + unpack_haks.cmd | 1 + update_src_from_haks.cmd | 2 + 168 files changed, 164196 insertions(+), 1158 deletions(-) create mode 100644 pack_haks.cmd create mode 100644 src/hakpak/peps_prc8/2da/ai_messages.2da create mode 100644 src/hakpak/peps_prc8/2da/ai_spells.2da create mode 100644 src/hakpak/peps_prc8/tga/armor_pallet.tga create mode 100644 src/hakpak/peps_prc8/tga/gui_pal_tattoo.tga create mode 100644 src/module/dlg/nw_g_animal.dlg.json create mode 100644 src/module/dlg/nw_g_fam.dlg.json create mode 100644 src/module/dlg/oc_ai_henchmen.dlg.json create mode 100644 src/module/nss/0c_assoc_actions.nss create mode 100644 src/module/nss/0c_cast_polymorp.nss create mode 100644 src/module/nss/0c_fire_henchmen.nss create mode 100644 src/module/nss/0c_get_convo.nss create mode 100644 src/module/nss/0c_get_henchman.nss create mode 100644 src/module/nss/0c_h_cast_spell.nss create mode 100644 src/module/nss/0c_henchmenspell.nss create mode 100644 src/module/nss/0c_if_a_magic_m.nss create mode 100644 src/module/nss/0c_if_ass_convo.nss create mode 100644 src/module/nss/0c_if_assoc_mode.nss create mode 100644 src/module/nss/0c_if_cntrspell.nss create mode 100644 src/module/nss/0c_if_com_script.nss create mode 100644 src/module/nss/0c_if_convo.nss create mode 100644 src/module/nss/0c_if_has_assoc.nss create mode 100644 src/module/nss/0c_if_has_class.nss create mode 100644 src/module/nss/0c_if_has_feat.nss create mode 100644 src/module/nss/0c_if_has_spell.nss create mode 100644 src/module/nss/0c_if_hen_leave.nss create mode 100644 src/module/nss/0c_if_identify.nss create mode 100644 src/module/nss/0c_if_not_master.nss create mode 100644 src/module/nss/0c_if_open_inven.nss create mode 100644 src/module/nss/0c_if_pickuploot.nss create mode 100644 src/module/nss/0c_if_polymorph.nss create mode 100644 src/module/nss/0c_if_scout.nss create mode 100644 src/module/nss/0c_if_skillrank.nss create mode 100644 src/module/nss/0c_if_taunt.nss create mode 100644 src/module/nss/0c_listhenchman.nss create mode 100644 src/module/nss/0c_no_com_script.nss create mode 100644 src/module/nss/0c_remove_effect.nss create mode 100644 src/module/nss/0c_summon_assoc.nss create mode 100644 src/module/nss/0c_use_feat.nss create mode 100644 src/module/nss/0e_c2_1_hb.nss create mode 100644 src/module/nss/0e_c2_7_ondeath.nss create mode 100644 src/module/nss/0e_ch_1_hb.nss create mode 100644 src/module/nss/0e_ch_7_ondeath.nss create mode 100644 src/module/nss/0e_do_combat_rnd.nss create mode 100644 src/module/nss/0e_gui_events.nss create mode 100644 src/module/nss/0e_m1_3_endround.nss create mode 100644 src/module/nss/0e_nui.nss create mode 100644 src/module/nss/0e_nui_dm.nss create mode 100644 src/module/nss/0e_onclientload.nss create mode 100644 src/module/nss/0e_player_target.nss create mode 100644 src/module/nss/0e_prc_ch_events.nss create mode 100644 src/module/nss/0i_actions.nss create mode 100644 src/module/nss/0i_associates.nss create mode 100644 src/module/nss/0i_color.nss create mode 100644 src/module/nss/0i_combat.nss create mode 100644 src/module/nss/0i_constants.nss create mode 100644 src/module/nss/0i_gui_events.nss create mode 100644 src/module/nss/0i_items.nss create mode 100644 src/module/nss/0i_main.nss create mode 100644 src/module/nss/0i_menus.nss create mode 100644 src/module/nss/0i_menus_dm.nss create mode 100644 src/module/nss/0i_messages.nss create mode 100644 src/module/nss/0i_module.nss create mode 100644 src/module/nss/0i_nui.nss create mode 100644 src/module/nss/0i_player_target.nss create mode 100644 src/module/nss/0i_spells.nss create mode 100644 src/module/nss/0i_states_cond.nss create mode 100644 src/module/nss/0i_talents.nss create mode 100644 src/module/nss/0i_time.nss create mode 100644 src/module/nss/ai_a_ambusher.nss create mode 100644 src/module/nss/ai_a_atk_casters.nss create mode 100644 src/module/nss/ai_a_atk_nearest.nss create mode 100644 src/module/nss/ai_a_atk_warrior.nss create mode 100644 src/module/nss/ai_a_barbarian.nss create mode 100644 src/module/nss/ai_a_bard.nss create mode 100644 src/module/nss/ai_a_cleric.nss create mode 100644 src/module/nss/ai_a_cntrspell.nss create mode 100644 src/module/nss/ai_a_default.nss create mode 100644 src/module/nss/ai_a_defensive.nss create mode 100644 src/module/nss/ai_a_druid.nss create mode 100644 src/module/nss/ai_a_fighter.nss create mode 100644 src/module/nss/ai_a_flanker.nss create mode 100644 src/module/nss/ai_a_invisible.nss create mode 100644 src/module/nss/ai_a_monk.nss create mode 100644 src/module/nss/ai_a_no_cmb_mode.nss create mode 100644 src/module/nss/ai_a_paladin.nss create mode 100644 src/module/nss/ai_a_peaceful.nss create mode 100644 src/module/nss/ai_a_polymorphed.nss create mode 100644 src/module/nss/ai_a_ranged.nss create mode 100644 src/module/nss/ai_a_ranger.nss create mode 100644 src/module/nss/ai_a_rogue.nss create mode 100644 src/module/nss/ai_a_sorcerer.nss create mode 100644 src/module/nss/ai_a_taunter.nss create mode 100644 src/module/nss/ai_a_wizard.nss create mode 100644 src/module/nss/ai_ambusher.nss create mode 100644 src/module/nss/ai_barbarian.nss create mode 100644 src/module/nss/ai_bard.nss create mode 100644 src/module/nss/ai_cleric.nss create mode 100644 src/module/nss/ai_cntrspell.nss create mode 100644 src/module/nss/ai_coward.nss create mode 100644 src/module/nss/ai_default.nss create mode 100644 src/module/nss/ai_defensive.nss create mode 100644 src/module/nss/ai_dragon.nss create mode 100644 src/module/nss/ai_druid.nss create mode 100644 src/module/nss/ai_fighter.nss create mode 100644 src/module/nss/ai_flanker.nss create mode 100644 src/module/nss/ai_incorporeal.nss create mode 100644 src/module/nss/ai_invisible.nss create mode 100644 src/module/nss/ai_monk.nss create mode 100644 src/module/nss/ai_paladin.nss create mode 100644 src/module/nss/ai_polymorphed.nss create mode 100644 src/module/nss/ai_ranged.nss create mode 100644 src/module/nss/ai_ranger.nss create mode 100644 src/module/nss/ai_rogue.nss create mode 100644 src/module/nss/ai_shadow.nss create mode 100644 src/module/nss/ai_sorcerer.nss create mode 100644 src/module/nss/ai_taunter.nss create mode 100644 src/module/nss/ai_wizard.nss create mode 100644 src/module/nss/mm_prc_spells.nss create mode 100644 src/module/nss/nw_ch_ac1.nss create mode 100644 src/module/nss/nw_ch_ac2.nss create mode 100644 src/module/nss/nw_ch_ac3.nss create mode 100644 src/module/nss/nw_ch_ac4.nss create mode 100644 src/module/nss/nw_ch_ac5.nss create mode 100644 src/module/nss/nw_ch_ac6.nss create mode 100644 src/module/nss/nw_ch_ac8.nss create mode 100644 src/module/nss/nw_ch_aca.nss create mode 100644 src/module/nss/nw_ch_acb.nss create mode 100644 src/module/nss/nw_ch_ace.nss create mode 100644 src/module/nss/nw_ch_summon_9.nss create mode 100644 src/module/nss/pc_savebuffs.nss create mode 100644 src/module/nss/pe_buffing.nss create mode 100644 src/module/nss/pe_crafting.nss create mode 100644 src/module/nss/pe_debug.nss create mode 100644 src/module/nss/pe_henchmen.nss create mode 100644 src/module/nss/pe_mod_set.nss create mode 100644 src/module/nss/pe_test.nss create mode 100644 src/module/nss/pi_buffing.nss create mode 100644 src/module/nss/pi_crafting.nss create mode 100644 src/module/nss/pi_debug.nss create mode 100644 src/module/nss/pi_forcerest.nss create mode 100644 src/module/nss/pi_henchmen.nss create mode 100644 src/module/nss/pi_test.nss create mode 100644 src/module/nss/pinc_henchmen.nss create mode 100644 src/module/nss/xx_pc_1_hb.nss create mode 100644 src/module/nss/xx_pc_2_percept.nss create mode 100644 src/module/nss/xx_pc_3_endround.nss create mode 100644 src/module/nss/xx_pc_4_convers.nss create mode 100644 src/module/nss/xx_pc_5_phyatked.nss create mode 100644 src/module/nss/xx_pc_6_damaged.nss create mode 100644 src/module/nss/xx_pc_8_disturb.nss create mode 100644 src/module/nss/xx_pc_b_castat.nss create mode 100644 src/module/nss/xx_pc_e_blocked.nss create mode 100644 unpack_haks.cmd create mode 100644 update_src_from_haks.cmd diff --git a/nasher.cfg b/nasher.cfg index bd9a76a..0d4465b 100644 --- a/nasher.cfg +++ b/nasher.cfg @@ -235,4 +235,14 @@ description = "PRC8 version of A Time For Heroes." filter = "xchst_inc.nss" [target.rules] - "*" = "src/module/$ext" \ No newline at end of file + "*" = "src/module/$ext" + + [target] +name = "pepshak" +file = "peps_prc8.hak" +description = "PEPS PRC hakpak for PRC8 version of A Time for Heroes." + [target.sources] + include = "src/hakpak/peps_prc8/**/*" + + [target.rules] + "*" = "src/hakpak/peps_prc8/$ext" \ No newline at end of file diff --git a/pack_haks.cmd b/pack_haks.cmd new file mode 100644 index 0000000..f07456c --- /dev/null +++ b/pack_haks.cmd @@ -0,0 +1 @@ +nasher pack pepshak --verbose \ No newline at end of file diff --git a/src/hakpak/peps_prc8/2da/ai_messages.2da b/src/hakpak/peps_prc8/2da/ai_messages.2da new file mode 100644 index 0000000..cc5d0c9 --- /dev/null +++ b/src/hakpak/peps_prc8/2da/ai_messages.2da @@ -0,0 +1,49 @@ +2DA V2.0 + + Message_Type Text +0 AI_Message "Picking up too much junk? Adjust the loot filter." +1 AI_Message "Try the AI on your player for a different experience!" +2 AI_Message "Does your associates talk to much? Reduce their speech." +3 AI_Message "Modes will keep your character engaged in that task." +4 AI_Message "Give Thieves picks to your rogues, they will use them." +5 AI_Message "Want your associates using more magic? Up their magic level." +6 AI_Message "Using up spells too fast? Control what they can cast!" +7 AI_Message "You can adjust when associates heal in and out of combat." +8 AI_Message "Don't want to be a team player? Turn party healing off." +9 AI_Message "Need help picking up all that loot? Turn Auto looting on." +10 Widget_Message "Place your widgets then lock'em into place!" +11 Widget_Message "Like an associates settings? Copy them to other associates." +12 Widget_Message "Use action button to control your associates actions." +13 Widget_Message "'All' commands are good for getting control of the party." +14 Widget_Message "Normal mode clears any specific commands." +15 Widget_Message "Follow command makes them stop fighting and follow!" +16 Widget_Message "Have traps? You can make a skilled associate use them." +17 Widget_Message "Put the camera focus on an associate to get better control." +18 Widget_Message "Don't like your associates familiar? Change it!" +19 Widget_Message "Don't like your associates animal companion? Change it!" +20 General_Message "Right click on the widget portrait to open the AI menu." +21 General_Message "Give your associates magic items, they can use more now!" +22 General_Message "Use the boxes to the right to add commands to your widgets." +23 General_Message "Use the mouse wheel to change a button's [values]." +24 General_Message "Use the mouse wheel to change a button's [values]." +25 General_Message "Use the mouse wheel to change a button's [values]." +26 General_Message "Want a module supported? Ask on Discord or the Vault." +27 Rule_Message "Allow more henchman into your party, upto 12 can join!" +28 Rule_Message "Too many widgets? You can turn your associate widgets off!" +29 Rule_Message "Party too big and can't get down the hall? Use Ghost mode!" +30 Rule_Message "Is the game too easy? Goto Main Options and change the RULES!" +31 Rule_Message "Increase the difficulty, make monster attack weaker targets." +32 Rule_Message "Monsters too powerful? Turn on moral checks." +33 Rule_Message "Allow casters to prebuff for stronger opponents." +34 Rule_Message "Allow casters to presummon for more enemy support." +35 Rule_Message "Change up your opponents tactics. Turn on monster tactics." +36 Rule_Message "Allow enemies to have their familiars and animal companions." +37 Rule_Message "Make summons more powerful, stop unsummons on master's death!" +38 Rule_Message "Want a pile on? Increase the distance monsters can respond!" +39 Rule_Message "Monster's perception can be changed up or down!" +40 Rule_Message "Want to see a massacre! Set the enemy corpses to remain." +41 Rule_Message "Looking for variety? Turn on wandering to get a surprise!" +42 Rule_Message "Not hard enough? Up the number of monsters you fight!" +43 Rule_Message "Monsters just falling over? Increase their health!" +44 Widget_Message "Change your associates memorized spells to what you need!" +45 Widget_message "Control the spells your party uses by turning on the Quick use widget!" diff --git a/src/hakpak/peps_prc8/2da/ai_spells.2da b/src/hakpak/peps_prc8/2da/ai_spells.2da new file mode 100644 index 0000000..14db4b5 --- /dev/null +++ b/src/hakpak/peps_prc8/2da/ai_spells.2da @@ -0,0 +1,19400 @@ +2DA V2.0 + + Label ImmunityType SaveType SpellResist Category HostileSetting Buff_Duration Buff_Target Buff_Group +0 Acid_Fog Acid **** 1 I 1 **** **** **** +1 Aid **** **** **** E 0 2 9 **** +2 Animate_Dead **** **** **** S 0 **** **** **** +3 Barkskin **** **** **** P 0 3 7 **** +4 Bestow_Curse **** Will 1 T 1 **** **** **** +5 Blade_Barrier **** Reflex 1 I 1 **** **** **** +6 Bless **** **** **** E 0 2 0 **** +7 Bless_Weapon[NOT_USED] **** **** **** **** **** **** **** **** +8 Blindness_and_Deafness Blindness Fortitude 1 R 1 **** **** **** +9 Bulls_Strength **** **** **** E 0 3 1 **** +10 Burning_Hands Fire Reflex 1 I 1 **** **** **** +11 Call_Lightning Electricity Reflex 1 D 1 **** **** **** +12 Calm_Emotions[NOT_USED] **** **** **** **** **** **** **** **** +13 Cats_Grace **** **** **** E 0 3 2 **** +14 Chain_Lightning Electricity Reflex 1 D 1 **** **** **** +15 Charm_Monster Mind_Affecting Will 1 R 1 **** **** **** +16 Charm_Person Mind_Affecting Will 1 R 1 **** **** **** +17 Charm_Person_or_Animal Mind_Affecting Will 1 R 1 **** **** **** +18 Circle_of_Death Death Fortitude 1 D 1 **** **** **** +19 Circle_of_Doom Negative Fortitude 1 D 1 **** **** **** +20 Clairaudience_and_Clairvoyance **** **** **** C 0 2 5 **** +21 Clarity **** **** **** C 0 2 13 **** +22 Cloak_of_Chaos[NOT_USED] **** **** **** **** **** **** **** **** +23 Cloudkill Poison Fortitude 0 I 1 **** **** **** +24 Color_Spray Blindness Will 1 I 1 **** **** **** +25 Cone_of_Cold Cold Reflex 1 I 1 **** **** **** +26 Confusion Confusion Will 1 D 1 **** **** **** +27 Contagion Disease Fortitude 1 T 1 **** **** **** +28 Control_Undead NoImmunity Will 1 R 1 **** **** **** +29 Create_Greater_Undead **** **** **** S 0 3 0 -2 +30 Create_Undead **** **** **** S 0 3 0 -2 +31 Cure_Critical_Wounds **** **** **** H 0 **** **** **** +32 Cure_Light_Wounds **** **** **** H 0 **** **** **** +33 Cure_Minor_Wounds **** **** **** H 0 **** **** **** +34 Cure_Moderate_Wounds **** **** **** H 0 **** **** **** +35 Cure_Serious_Wounds **** **** **** H 0 **** **** **** +36 Darkness **** **** **** I 0 **** **** **** +37 Daze Dazed Will 1 R 1 **** **** **** +38 Death_Ward **** **** **** E 0 3 11 **** +39 Delayed_Blast_Fireball Fire Reflex 1 I 1 **** **** **** +40 Dismissal **** **** 1 I 1 **** **** **** +41 Dispel_Magic **** **** **** R 0 **** **** **** +42 Divine_Power **** **** **** E 0 2 0 **** +43 Dominate_Animal Domination Will 1 R 1 **** **** **** +44 Dominate_Monster Domination Will 1 R 1 **** **** **** +45 Dominate_Person Domination Will 1 R 1 **** **** **** +46 Doom Fear Will 1 R 1 **** **** **** +47 Elemental_Shield **** **** **** P 0 2 7 **** +48 Elemental_Swarm **** **** **** S 0 3 0 -2 +49 Endurance **** **** **** E 0 3 3 **** +50 Endure_Elements **** **** **** P 0 3 10 -1 +51 Energy_Drain Level_Drain **** 1 R 1 **** **** **** +52 Enervation Level_Drain **** 1 R 1 **** **** **** +53 Entangle **** Reflex 0 I 1 **** **** **** +54 Fear Fear Will 1 D 1 **** **** **** +55 Feeblemind Mind_Affecting Will 1 R 1 **** **** **** +56 Finger_of_Death Death Fortitude 1 R 1 **** **** **** +57 Fire_Storm Fire Reflex 1 D 1 **** **** **** +58 Fireball Fire Reflex 1 I 1 **** **** **** +59 Flame_Arrow Fire Reflex 1 R 1 **** **** **** +60 Flame_Lash Fire Reflex 1 R 1 **** **** **** +61 Flame_Strike Fire Reflex 1 I 1 **** **** **** +62 Freedom_of_Movement **** **** **** E 0 2 9 **** +63 Gate **** **** **** S 0 3 0 -2 +64 Ghoul_Touch Poison Fortitude 1 T 1 **** **** **** +65 Globe_of_Invulnerability **** **** **** P 0 2 0 -7 +66 Grease **** Reflex 0 I 1 **** **** **** +67 Greater_Dispelling **** **** **** R 0 **** **** **** +68 Greater_Magic_Weapon[NOT_USED] **** **** **** **** **** **** **** **** +69 Greater_Planar_Binding **** **** **** S 0 3 0 -2 +70 Greater_Restoration **** **** **** C 0 **** **** **** +71 Greater_Shadow_Conjuration **** **** **** **** 1 **** **** **** +72 Greater_Spell_Breach **** **** 0 R 1 **** **** **** +73 Greater_Spell_Mantle **** **** **** P 0 2 0 -9 +74 Greater_Stoneskin **** **** **** P 0 3 0 -8 +75 Gust_of_Wind **** Fortitude 0 I 1 **** **** **** +76 Hammer_of_the_Gods Divine Will 1 D 1 **** **** **** +77 Harm Negative Will 1 T 1 **** **** **** +78 Haste **** **** **** E 0 2 9 -16 +79 Heal **** **** **** H 0 **** **** **** +80 Healing_Circle **** **** **** H 0 **** **** **** +81 Hold_Animal Paralysis Will 1 R 1 **** **** **** +82 Hold_Monster Paralysis Will 1 R 1 **** **** **** +83 Hold_Person Paralysis Will 1 R 1 **** **** **** +84 Holy_Aura[NOT_USED] **** **** **** **** **** **** **** **** +85 Holy_Sword[NOT_USED] **** **** **** **** **** **** **** **** +86 Identify **** **** **** **** 0 **** **** **** +87 Implosion Death Fortitude 1 I 1 **** **** **** +88 Improved_Invisibility **** **** **** E 0 2 7 -5 +89 Incendiary_Cloud Fire Reflex 0 I 1 **** **** **** +90 Invisibility **** **** **** E 0 2 7 -5 +91 Invisibility_Purge **** **** **** E 0 2 0 **** +92 Invisibility_Sphere **** **** **** E 0 2 0 -5 +93 Knock **** **** **** **** 0 **** **** **** +94 Lesser_Dispel **** **** **** R 0 **** **** **** +95 Lesser_Mind_Blank **** **** **** E 0 2 13 **** +96 Lesser_Planar_Binding **** **** **** S 0 3 0 -2 +97 Lesser_Restoration **** **** **** C 0 **** **** **** +98 Lesser_Spell_Breach **** **** 0 R 1 **** **** **** +99 Lesser_Spell_Mantle **** **** **** P 0 2 0 -9 +100 Light **** **** **** **** 0 3 0 -15 +101 Lightning_Bolt Electricity Reflex 1 I 1 **** **** **** +102 Mage_Armor **** **** **** P 0 3 7 -102 +103 Magic_Circle_against_Chaos **** **** **** P 0 3 14 -10 +104 Magic_Circle_against_Evil **** **** **** P 0 3 14 -11 +105 Magic_Circle_against_Good **** **** **** P 0 3 14 -12 +106 Magic_Circle_against_Law **** **** **** P 0 3 14 -13 +107 Magic_Missile **** **** 1 R 1 **** **** **** +108 Magic_Vestment[NOT_USED] **** **** **** **** **** **** **** **** +109 Magic_Weapon[NOT_USED] **** **** **** **** **** **** **** **** +110 Mass_Blindness_and_Deafness Blindness Will 1 D 1 **** **** **** +111 Mass_Charm Charm Will 1 D 1 **** **** **** +112 Mass_Domination Domination Will 1 D 1 **** **** **** +113 Mass_Haste **** **** **** E 0 2 0 -16 +114 Mass_Heal **** **** **** H 0 **** **** **** +115 Melfs_Acid_Arrow Acid **** 0 R 1 **** **** **** +116 Meteor_Swarm Fire Reflex 1 D 1 **** **** **** +117 Mind_Blank **** **** **** E 0 2 0 **** +118 Mind_Fog Mind_Affecting Will 1 I 1 **** **** **** +119 Minor_Globe_of_Invulnerability **** **** **** P 0 2 0 -7 +120 Ghostly_Visage **** **** **** P 0 2 0 -8 +121 Ethereal_Visage **** **** **** E 0 2 0 -8 +122 Mordenkainens_Disjunction **** **** **** I 0 **** **** **** +123 Mordenkainens_Sword **** **** **** S 0 2 0 -2 +124 Natures_Balance Postive Will 0 D 0 **** **** **** +125 Negative_Energy_Protection **** **** **** P 0 2 10 **** +126 Neutralize_Poison **** **** **** C 0 **** **** **** +127 Phantasmal_Killer Fear Will 1 R 1 **** **** **** +128 Planar_Binding **** **** **** S 0 3 0 -2 +129 Poison Poison Fortitude 1 R 1 **** **** **** +130 Polymorph_Self **** **** **** **** 0 2 0 -17 +131 Power_Word_Kill **** **** 1 R 1 **** **** **** +132 Power_Word_Stun **** **** 1 I 1 **** **** **** +133 Prayer **** **** **** E 0 2 0 **** +134 Premonition **** **** **** P 0 3 0 -8 +135 Prismatic_Spray Mind_Affecing Will 1 I 1 **** **** **** +136 Protection__from_Chaos[NOT_USED] **** **** **** **** **** **** **** **** +137 Protection_from_Elements **** **** **** P 0 3 10 -1 +138 Protection_from_Evil **** **** **** **** **** **** **** **** +139 Protection_from_Good **** **** **** **** **** **** **** **** +140 Protection_from_Law **** **** **** **** **** **** **** **** +141 Protection_from_Spells **** **** **** P 0 3 0 **** +142 Raise_Dead **** **** **** **** 0 **** **** **** +143 Ray_of_Enfeeblement **** **** 1 R 1 **** **** **** +144 Ray_of_Frost Cold **** 1 R 1 **** **** **** +145 Remove_Blindness_and_Deafness **** **** **** C 0 **** **** **** +146 Remove_Curse **** **** **** C 0 **** **** **** +147 Remove_Disease **** **** **** C 0 **** **** **** +148 Remove_Fear **** **** **** C 0 3 13 **** +149 Remove_Paralysis **** **** **** C 0 **** **** **** +150 Resist_Elements **** **** **** P 0 2 10 -1 +151 Resistance **** **** **** P 0 2 14 **** +152 Restoration **** **** **** C 0 **** **** **** +153 Resurrection **** **** **** **** 0 **** **** **** +154 Sanctuary **** **** **** E 0 2 8 -5 +155 Scare Fear Will 1 R 1 **** **** **** +156 Searing_Light Divine **** 1 R 1 **** **** **** +157 See_Invisibility **** **** **** E 0 2 9 **** +158 Shades **** **** **** **** 1 **** **** **** +159 Shadow_Conjuration **** **** **** **** 1 **** **** **** +160 Shadow_Shield **** **** **** P 0 2 0 **** +161 Shapechange **** **** **** **** 0 2 0 -17 +162 Shield_of_Law[NOT_USED] **** **** **** **** **** **** **** **** +163 Silence **** **** **** I 1 **** **** **** +164 Slay_Living Negative Fortitude 1 R 1 **** **** **** +165 Sleep Sleep Will 1 I 1 **** **** **** +166 Slow **** **** **** D 1 **** **** **** +167 Sound_Burst Sonic Fortitude 1 I 1 **** **** **** +168 Spell_Resistance **** **** **** P 0 2 14 **** +169 Spell_Mantle **** **** **** P 0 2 0 -9 +170 Sphere_of_Chaos **** **** **** E 1 **** **** **** +171 Stinking_Cloud Poison Fortitude 1 I 1 **** **** **** +172 Stoneskin **** **** **** P 0 3 7 -8 +173 Storm_of_Vengeance Electricity Reflex 1 D 1 **** **** **** +174 Summon_Creature_I **** **** **** S 0 3 0 -2 +175 Summon_Creature_II **** **** **** S 0 3 0 -2 +176 Summon_Creature_III **** **** **** S 0 3 0 -2 +177 Summon_Creature_IV **** **** **** S 0 3 0 -2 +178 Summon_Creature_IX **** **** **** S 0 3 0 -2 +179 Summon_Creature_V **** **** **** S 0 3 0 -2 +180 Summon_Creature_VI **** **** **** S 0 3 0 -2 +181 Summon_Creature_VII **** **** **** S 0 3 0 -2 +182 Summon_Creature_VIII **** **** **** S 0 3 0 -2 +183 Sunbeam Divine Reflex 1 D 1 **** **** **** +184 Tensers_Transformation **** **** **** E 0 **** **** **** +185 Time_Stop **** **** **** D 0 **** **** **** +186 True_Seeing **** **** **** E 0 2 9 **** +187 Unholy_Aura[NOT_USED] **** **** **** **** **** **** **** **** +188 Vampiric_Touch Negative **** 1 T 1 **** **** **** +189 Virtue **** **** **** E 0 2 10 **** +190 Wail_of_the_Banshee Death Fortitude 1 D 1 **** **** **** +191 Wall_of_Fire Fire Reflex 1 I 1 **** **** **** +192 Web **** Reflex 1 I 1 **** **** **** +193 Weird Fear Will 1 D 1 **** **** **** +194 Word_of_Faith Divine **** 1 D 1 **** **** **** +195 AURA_BLINDING Mind_Affecting Will 0 A 1 **** **** **** +196 Aura_Cold **** **** **** A 1 **** **** **** +197 Aura_Electricity **** **** **** A 1 **** **** **** +198 Aura_Fear **** **** **** A 1 **** **** **** +199 Aura_Fire **** **** **** A 1 **** **** **** +200 Aura_Menace **** **** **** A 1 **** **** **** +201 Aura_Protection **** **** **** A 0 **** **** **** +202 Aura_Stun **** **** **** A 1 **** **** **** +203 Aura_Unearthly_Visage **** **** **** A 1 **** **** **** +204 Aura_Unnatural **** **** **** A 1 **** **** **** +205 Bolt_Ability_Drain_Charisma **** **** 0 R 1 **** **** **** +206 Bolt_Ability_Drain_Constitution **** **** 0 R 1 **** **** **** +207 Bolt_Ability_Drain_Dexterity **** **** 0 R 1 **** **** **** +208 Bolt_Ability_Drain_Intelligence **** **** 0 R 1 **** **** **** +209 Bolt_Ability_Drain_Strength **** **** 0 R 1 **** **** **** +210 Bolt_Ability_Drain_Wisdom **** **** 0 R 1 **** **** **** +211 Bolt_Acid Acid **** 0 R 1 **** **** **** +212 Bolt_Charm **** **** 0 R 1 **** **** **** +213 Bolt_Cold Cold **** 0 R 1 **** **** **** +214 Bolt_Confuse **** **** 0 R 1 **** **** **** +215 Bolt_Daze **** **** 0 R 1 **** **** **** +216 Bolt_Death **** **** 0 R 1 **** **** **** +217 Bolt_Disease **** **** 0 R 1 **** **** **** +218 Bolt_Dominate **** **** 0 R 1 **** **** **** +219 Bolt_Fire Fire **** 0 R 1 **** **** **** +220 Bolt_Knockdown **** **** 0 R 1 **** **** **** +221 Bolt_Level_Drain **** **** 0 R 1 **** **** **** +222 Bolt_Lightning Electricity **** 0 R 1 **** **** **** +223 Bolt_Paralyze **** **** 0 R 1 **** **** **** +224 Bolt_Poison **** **** 0 R 1 **** **** **** +225 Bolt_Shards **** **** 0 R 1 **** **** **** +226 Bolt_Slow **** **** 0 R 1 **** **** **** +227 Bolt_Stun **** **** 0 R 1 **** **** **** +228 Bolt_Web **** **** 0 R 1 **** **** **** +229 Cone_Acid Acid Reflex 0 I 1 **** **** **** +230 Cone_Cold Cold Reflex 0 I 1 **** **** **** +231 Cone_Disease Disease Fortitude 0 I 1 **** **** **** +232 Cone_Fire Fire Reflex 0 I 1 **** **** **** +233 Cone_Lightning Electricity Reflex 0 I 1 **** **** **** +234 Cone_Poison Poison Fortitude 0 I 1 **** **** **** +235 Cone_Sonic Sonic Reflex 0 I 1 **** **** **** +236 Dragon_Breath_Acid Acid Reflex 0 **** 1 **** **** **** +237 Dragon_Breath_Cold Cold Reflex 0 **** 1 **** **** **** +238 Dragon_Breath_Fear Fear Will 0 **** 1 **** **** **** +239 Dragon_Breath_Fire Fire Reflex 0 **** 1 **** **** **** +240 Dragon_Breath_Gas Acid Reflex 0 **** 1 **** **** **** +241 Dragon_Breath_Lightning Electricity Reflex 0 **** 1 **** **** **** +242 Dragon_Breath_Paralyze Paralyze Fortitude 0 **** 1 **** **** **** +243 Dragon_Breath_Sleep Sleep Will 0 **** 1 **** **** **** +244 Dragon_Breath_Slow **** Reflex 0 **** 1 **** **** **** +245 Dragon_Breath_Weaken Negative Reflex 0 **** 1 **** **** **** +246 Dragon_Wing_Buffet **** **** **** **** 1 **** **** **** +247 Ferocity_1 **** **** **** **** 0 **** **** **** +248 Ferocity_2 **** **** **** **** 0 **** **** **** +249 Ferocity_3 **** **** **** **** 0 **** **** **** +250 Gaze_Charm Charm Will 0 I 1 **** **** **** +251 Gaze_Confusion Confusion Will 0 I 1 **** **** **** +252 Gaze_Daze Daze Will 0 I 1 **** **** **** +253 Gaze_Death Death Will 0 I 1 **** **** **** +254 Gaze_Destroy_Chaos Death Will 0 I 1 **** **** **** +255 Gaze_Destroy_Evil Death Will 0 I 1 **** **** **** +256 Gaze_Destroy_Good Death Will 0 I 1 **** **** **** +257 Gaze_Destroy_Law Death Will 0 I 1 **** **** **** +258 Gaze_Dominate Domination Will 0 I 1 **** **** **** +259 Gaze_Doom **** Will 0 I 1 **** **** **** +260 Gaze_Fear Fear Will 0 I 1 **** **** **** +261 Gaze_Paralysis **** Will 0 I 1 **** **** **** +262 Gaze_Stunned Mind_Affecting Will 0 I 1 **** **** **** +263 Golem_Breath_Gas Poison Fortitude 0 I 1 **** **** **** +264 Hell_Hound_Firebreath Fire **** 0 I 1 **** **** **** +265 Howl_Confuse Confusion Will 0 I 1 **** **** **** +266 Howl_Daze Daze Will 0 I 1 **** **** **** +267 Howl_Death Death Will 0 I 1 **** **** **** +268 Howl_Doom **** Will 0 I 1 **** **** **** +269 Howl_Fear Fear Will 0 I 1 **** **** **** +270 Howl_Paralysis **** Will 0 I 1 **** **** **** +271 Howl_Sonic Sonic Fortitude 0 I 1 **** **** **** +272 Howl_Stun Mind_Affecting Will 0 I 1 **** **** **** +273 Intensity_1 **** **** **** **** 0 **** **** **** +274 Intensity_2 **** **** **** **** 0 **** **** **** +275 Intensity_3 **** **** **** **** 0 **** **** **** +276 Krenshar_Scare Fear Will 0 D 1 **** **** **** +277 Lesser_Body_Adjustment **** **** **** H 0 **** **** **** +278 Mephit_Salt_Breath Acid Reflex 0 I 1 **** **** **** +279 Mephit_Steam_Breath Fire Reflex 0 I 1 **** **** **** +280 Mummy_Bolster_Undead **** **** **** E 1 **** **** **** +281 Pulse_Drown **** Reflex 0 D 1 **** **** **** +282 Pulse_Spores Disease Fortitude 0 D 1 **** **** **** +283 Pulse_Whirlwind **** Reflex 0 D 1 **** **** **** +284 Pulse_Fire Fire Reflex 0 I 1 **** **** **** +285 Pulse_Lightning Electricity Reflex 0 I 1 **** **** **** +286 Pulse_Cold Cold Reflex 0 I 1 **** **** **** +287 Pulse_Negative Negative Reflex 0 I 1 **** **** **** +288 Pulse_Holy Divine Reflex 0 I 1 **** **** **** +289 Pulse_Death Death Fortitude 0 I 1 **** **** **** +290 Pulse_Level_Drain Level_Drain Fortitude 0 I 1 **** **** **** +291 Pulse_Ability_Drain_Intelligence Ability_Drain Fortitude 0 D 1 **** **** **** +292 Pulse_Ability_Drain_Charisma Ability_Drain Fortitude 0 D 1 **** **** **** +293 Pulse_Ability_Drain_Constitution Ability_Drain Fortitude 0 D 1 **** **** **** +294 Pulse_Ability_Drain_Dexterity Ability_Drain Fortitude 0 D 1 **** **** **** +295 Pulse_Ability_Drain_Strength Ability_Drain Fortitude 0 D 1 **** **** **** +296 Pulse_Ability_Drain_Wisdom Ability_Drain Fortitude 0 D 1 **** **** **** +297 Pulse_Poison Poison Fortitude 0 D 1 **** **** **** +298 Pulse_Disease Disease Fortitude 0 D 1 **** **** **** +299 Rage_3 **** **** **** *** 0 **** **** **** +300 Rage_4 **** **** **** *** 0 **** **** **** +301 Rage_5 **** **** **** **** 0 **** **** **** +302 Smoke_Claw **** Fortitude 0 T 1 **** **** **** +303 Summon_Slaad **** **** **** S 1 **** **** **** +304 Summon_Tanarri **** **** **** S 1 **** **** **** +305 Trumpet_Blast **** Will 0 D 1 **** **** **** +306 Tyrant_Fog_Mist **** **** **** A 1 **** **** **** +307 BARBARIAN_RAGE **** **** **** **** 0 **** **** **** +308 Turn_Undead Divine **** **** D 1 **** **** **** +309 Wholeness_of_Body **** **** **** H 0 **** **** **** +310 Quivering_Palm **** **** **** **** 1 **** **** **** +311 Empty_Body **** **** **** E 0 **** **** **** +312 Detect_Evil **** **** **** **** 0 **** **** **** +313 Lay_On_Hands **** **** **** H 0 **** **** **** +314 Aura_Of_Courage **** **** **** **** 0 **** **** **** +315 Smite_Evil **** **** **** T 1 **** **** **** +316 Remove_Disease **** **** **** C 0 **** **** **** +317 Summon_Animal_Companion **** **** **** **** 0 **** **** **** +318 Summon_Familiar **** **** **** **** 0 **** **** **** +319 Elemental_Shape **** **** **** **** 0 **** **** **** +320 Wild_Shape **** **** **** **** 0 **** **** **** +321 PROTECTION_FROM_ALIGNMENT **** **** **** **** 0 **** **** **** +322 Magic_Circle_against_Alignment **** **** **** **** 0 **** **** **** +323 Aura_versus_Alignment **** **** **** **** 0 **** **** **** +324 SHADES_Summon_Shadow **** **** **** D 0 **** **** **** +325 DELETED_PRO_Cold **** **** **** **** 0 **** **** **** +326 DELETED_PRO_Fire **** **** **** **** 0 **** **** **** +327 DELETED_PRO_Acid **** **** **** **** 0 **** **** **** +328 DELETED_PRO_Sonic **** **** **** **** 0 **** **** **** +329 DELETED_PRO_Elec **** **** **** **** 0 **** **** **** +330 DELETED_END_Cold **** **** **** **** 0 **** **** **** +331 DELETED_END_Fire **** **** **** **** 0 **** **** **** +332 DELETED_END_Acid **** **** **** **** 0 **** **** **** +333 DELETED_END_Sonic **** **** **** **** 0 **** **** **** +334 DELETED_END_Elec **** **** **** **** 0 **** **** **** +335 DELETED_RES_Cold **** **** **** **** 0 **** **** **** +336 DELETED_RES_Fire **** **** **** **** 0 **** **** **** +337 DELETED_RES_Acid **** **** **** **** 0 **** **** **** +338 DELETED_RES_Sonic **** **** **** **** 0 **** **** **** +339 DELETED_RES_Elec **** **** **** **** 0 **** **** **** +340 SHADES_Cone_of_Cold Cold Reflex 1 I 1 **** **** **** +341 SHADES_Fireball Fire Reflex 1 I 1 **** **** **** +342 SHADES_Stoneskin **** **** **** P 0 **** **** **** +343 SHADES_Wall_of_Fire Fire Reflex 1 I 1 **** **** **** +344 SHADOW_CON_Summon_Shadow **** **** **** D 0 **** **** **** +345 SHADOW_CON_Darkness **** **** **** I 0 **** **** **** +346 SHADOW_CON_Inivsibility **** **** **** E 0 **** **** **** +347 SHADOW_CON_Mage_Armor **** **** **** P 0 **** **** **** +348 SHADOW_CON_Magic_Missile **** **** 1 R 1 **** **** **** +349 GR_SHADOW_CON_Summon_Shadow **** **** **** D 0 **** **** **** +350 GR_SHADOW_CON_Acid_Arrow Acid **** 1 R 1 **** **** **** +351 GR_SHADOW_CON_Ghostly_Visage **** **** **** P 0 **** **** **** +352 GR_SHADOW_CON_Web **** Reflex 0 I 1 **** **** **** +353 GR_SHADOW_CON_Minor_Globe **** **** **** P 0 **** **** **** +354 Eagle_Splendor **** **** **** E 0 3 6 **** +355 Owls_Wisdom **** **** **** E 0 3 5 **** +356 Foxs_Cunning **** **** **** E 0 3 4 **** +357 Greater_Eagle_Splendor[NOT_USED] **** **** **** **** **** **** **** **** +358 Greater_Owls_Wisdom[NOT_USED] **** **** **** **** **** **** **** **** +359 Greater_Foxs_Cunning[NOT_USED] **** **** **** **** **** **** **** **** +360 Greater_Bulls_Strength[NOT_USED] **** **** **** **** **** **** **** **** +361 Greater_Cats_Grace[NOT_USED] **** **** **** **** *** **** **** **** +362 Greater_Endurance[NOT_USED] **** **** **** **** **** **** **** **** +363 Awaken **** **** **** E 0 **** **** **** +364 Creeping_Doom **** **** 0 D 1 **** **** **** +365 Ultravision **** **** **** E 0 3 9 **** +366 Destruction Death Fortitude 1 R 1 **** **** **** +367 Horrid_Wilting **** Fortitude 1 D 1 **** **** **** +368 Ice_Storm Cold **** 1 I 1 **** **** **** +369 Energy_Buffer **** **** **** P 0 2 0 -1 +370 Negative_Energy_Burst Negative Will 1 D 1 **** **** **** +371 Negative_Energy_Ray Negative Will 1 R 1 **** **** **** +372 Aura_of_Vitality **** **** **** E 0 2 0 **** +373 War_Cry **** **** **** D 0 **** **** **** +374 Regenerate **** **** **** E 0 2 10 -6 +375 Evards_Black_Tentacles **** Fortitude 0 D 1 **** **** **** +376 Legend_Lore **** **** **** **** 0 **** **** **** +377 Find_Traps **** **** **** **** 0 **** **** **** +378 Summon_Mephit **** **** **** S 0 **** **** **** +379 Summon_Celestial **** **** **** S 0 **** **** **** +380 Battle_Mastery_Spell **** **** **** E 0 **** **** **** +381 Divine_Strength **** **** **** E 0 **** **** **** +382 Divine_Protection **** **** **** E 0 **** **** **** +383 Negative_Plane_Avatar **** **** **** E 0 **** **** **** +384 Divine_Trickery **** **** **** E 0 **** **** **** +385 Rogues_Cunning **** **** **** E 0 **** **** **** +386 ACTIVATE_ITEM **** **** **** **** 0 **** **** **** +387 Polymorph_GIANT_SPIDER **** **** **** **** 0 **** **** **** +388 Polymorph_TROLL **** **** **** **** 0 **** **** **** +389 Polymorph_UMBER_HULK **** **** **** **** 0 **** **** **** +390 Polymorph_PIXIE **** **** **** **** 0 **** **** **** +391 Polymorph_ZOMBIE **** **** **** **** 0 **** **** **** +392 Shapechange_RED_DRAGON **** **** **** **** 0 **** **** **** +393 Shapechange_FIRE_GIANT **** **** **** **** 0 **** **** **** +394 Shapechange_BALOR **** **** **** **** 0 **** **** **** +395 Shapechange_DEATH_SLAAD **** **** **** **** 0 **** **** **** +396 Shapechange_IRON_GOLEM **** **** **** **** 0 **** **** **** +397 Elemental_Shape_FIRE **** **** **** **** 0 **** **** **** +398 Elemental_Shape_WATER **** **** **** **** 0 **** **** **** +399 Elemental_Shape_EARTH **** **** **** **** 0 **** **** **** +400 Elemental_Shape_AIR **** **** **** **** 0 **** **** **** +401 Wild_Shape_BROWN_BEAR **** **** **** **** 0 **** **** **** +402 Wild_Shape_PANTHER **** **** **** **** 0 **** **** **** +403 Wild_Shape_WOLF **** **** **** **** 0 **** **** **** +404 Wild_Shape_BOAR **** **** **** **** 0 **** **** **** +405 Wild_Shape_BADGER **** **** **** **** 0 **** **** **** +406 Special_Alcohol_Beer **** **** **** **** 0 **** **** **** +407 Special_Alcohol_Wine **** **** **** **** 0 **** **** **** +408 Special_Alcohol_Spirits **** **** **** **** 0 **** **** **** +409 Special_Herb_Belladonna **** **** **** **** 0 **** **** **** +410 Special_Herb_Garlic **** **** **** **** 0 **** **** **** +411 Bards_Song **** **** **** **** 0 **** **** **** +412 Aura_Fear_Dragon **** **** **** A 1 **** **** **** +413 ACTIVATE_ITEM_SELF **** **** **** **** 0 **** **** **** +414 Divine_Favor **** **** **** E 0 2 0 **** +415 True_Strike **** **** **** E 0 **** **** **** +416 Flare **** Fortitude 1 R 1 **** **** **** +417 Shield **** **** **** P 0 2 7 **** +418 Entropic_Shield **** **** **** P 0 2 0 **** +419 Continual_Flame **** **** **** **** 0 3 0 -15 +420 One_With_The_Land **** **** **** **** 0 3 0 **** +421 Camoflage **** **** **** **** 0 3 0 **** +422 Blood_Frenzy **** **** **** **** 0 2 0 **** +423 Bombardment **** Reflex 1 I 1 **** **** **** +424 Acid_Splash Acid **** 0 R 1 **** **** **** +425 Quillfire Poison Fortitude 0 R 1 **** **** **** +426 Earthquake **** Fortitude 0 I 1 **** **** **** +427 Sunburst Divine Reflex 1 D 1 **** **** **** +428 ACTIVATE_ITEM_SELF2 **** **** **** **** 0 **** **** **** +429 AuraOfGlory Mind_Affecting **** **** E 0 2 0 **** +430 Banishment **** Will 1 I 1 **** **** **** +431 Inflict_Minor_Wounds Negative Will 1 T 1 **** **** **** +432 Inflict_Light_Wounds Negative Will 1 T 1 **** **** **** +433 Inflict_Moderate_Wounds Negative Will 1 T 1 **** **** **** +434 Inflict_Serious_Wounds Negative Will 1 T 1 **** **** **** +435 Inflict_Critical_Wounds Negative Will 1 T 1 **** **** **** +436 BalagarnsIronHorn **** **** 1 D 1 **** **** **** +437 Drown **** Fortitude 1 R 1 **** **** **** +438 Owls_Insight **** **** **** E 0 3 5 **** +439 Electric_Jolt Electricity **** 0 R 1 **** **** **** +440 Firebrand Fire Reflex 1 R 1 **** **** **** +441 Wounding_Whispers Sonic **** 0 P 0 2 0 **** +442 Amplify **** **** **** E 0 2 5 **** +443 Etherealness **** **** **** E 0 2 0 -5 +444 Undeaths_Eternal_Foe **** **** **** E 0 2 10 **** +445 Dirge **** Fortitude 0 I 1 **** **** **** +446 Inferno Fire **** 1 R 1 **** **** **** +447 Isaacs_Lesser_Missile_Storm **** **** 1 R 1 **** **** **** +448 Isaacs_Greater_Missile_Storm **** **** 1 R 1 **** **** **** +449 Bane Fear Will 1 E 1 **** **** **** +450 Shield_of_Faith **** **** **** P 0 2 7 -3 +451 Planar_Ally **** **** **** S 0 3 0 -2 +452 Magic_Fang **** **** **** P 0 **** **** **** +453 Greater_Magic_Fang **** **** **** P 0 **** **** **** +454 Spike_Growth **** Reflex 1 I 1 **** **** **** +455 Mass_Camoflage **** **** **** E 0 2 0 **** +456 Expeditious_Retreat **** **** **** E 0 2 7 **** +457 Tashas_Hideous_Laughter Mind_Affecting Will 1 R 1 **** **** **** +458 Displacement **** **** **** E 0 2 7 -8 +459 Bigbys_Interposing_Hand **** **** **** R 0 **** **** **** +460 Bigbys_Forceful_Hand **** **** 1 R 1 **** **** **** +461 Bigbys_Grasping_Hand **** **** 1 R 1 **** **** **** +462 Bigbys_Clenched_Fist **** **** 1 R 1 **** **** **** +463 Bigbys_Crushing_Hand **** **** 1 R 1 **** **** **** +464 Grenade_Fire Fire **** 0 I 1 **** **** **** +465 Grenade_Tangle **** Reflex 0 I 1 **** **** **** +466 Grenade_Holy Divine **** 0 I 1 **** **** **** +467 Grenade_Choking **** **** 0 I 1 **** **** **** +468 Grenade_Thunderstone **** Fortitude 0 I 1 **** **** **** +469 Grenade_Acid Acid **** 0 I 1 **** **** **** +470 Grenade_Chicken **** **** 0 R 1 **** **** **** +471 Grenade_Caltrops **** **** 0 I 1 **** **** **** +472 ACTIVATE_ITEM_PORTAL **** **** **** **** 0 **** **** **** +473 Divine_Might **** **** **** **** 0 **** **** **** +474 Divine_Shield **** **** **** **** 0 **** **** **** +475 SHADOW_DAZE Daze Will 1 R 1 **** **** **** +476 SUMMON_SHADOW **** **** **** R 1 **** **** **** +477 SHADOW_EVADE **** **** **** E 0 **** **** **** +478 TYMORAS_SMILE **** **** **** E 0 **** **** **** +479 CRAFT_HARPER_ITEM **** **** **** **** 0 **** **** **** +480 Sleep Sleep Will 1 D 1 **** **** **** +481 Cats_Grace **** **** **** E 0 **** **** **** +482 Eagle_Splendor **** **** **** E 0 **** **** **** +483 Invisibility **** **** **** E 0 **** **** **** +484 **** **** **** **** **** **** **** **** **** +485 Flesh_to_stone **** Fortitude 1 R 1 **** **** **** +486 Stone_to_flesh **** **** **** E 0 **** **** **** +487 Trap_Arrow **** **** **** **** 1 **** **** **** +488 Trap_Bolt **** **** **** **** 1 **** **** **** +489 PADDING **** **** **** **** **** **** **** **** +490 PADDING **** **** **** **** **** **** **** **** +491 PADDING **** **** **** **** **** **** **** **** +492 PADDING **** **** **** **** **** **** **** **** +493 Trap_Dart **** **** **** **** 1 **** **** **** +494 Trap_Shuriken **** **** **** **** 1 **** **** **** +495 Breath_Petrify Petrification Fortitude 0 R 1 **** **** **** +496 Touch_Petrify Petrification Fortitude 0 R 1 **** **** **** +497 Gaze_Petrify Petrification Fortitude 0 R 1 **** **** **** +498 Manticore_Spikes **** **** **** R 1 **** **** **** +499 RodOfWonder **** **** **** **** 1 **** **** **** +500 DeckOfManyThings **** **** **** **** 0 **** **** **** +501 PADDING **** **** **** **** **** **** **** **** +502 ElementalSummoningItem **** **** **** **** 0 3 0 -2 +503 DeckAvatar **** **** **** **** 0 **** **** **** +504 Gem_Spray **** **** **** **** 1 **** **** **** +505 Butterfly_Spray **** **** **** **** 1 **** **** **** +506 HealingKit **** **** **** E **** **** **** **** +507 PowerStone **** **** **** **** 0 **** **** **** +508 Spellstaff **** **** **** **** 0 **** **** **** +509 Charger **** **** **** **** 0 **** **** **** +510 Decharger **** **** **** **** 0 **** **** **** +511 Kobold_Jump **** **** **** **** **** **** **** **** +512 Crumble Sonic **** 0 R 1 **** **** **** +513 Infestation_of_Maggots Disease Fortitude 1 T 1 **** **** **** +514 Healing_Sting Negative Fortitude 1 T 1 **** **** **** +515 Great_Thunderclap Sonic **** 0 I 1 **** **** **** +516 Ball_Lightning Electricity **** 1 I 1 **** **** **** +517 Battletide **** **** 1 D 1 **** **** **** +518 Combust Fire Reflex 1 T 1 **** **** **** +519 Death_Armor **** **** **** P 0 2 0 **** +520 Gedlees_Electric_Loop Electricity Reflex 1 D 1 **** **** **** +521 Horizikauls_Boom Sonic Will 1 R 1 **** **** **** +522 Ironguts **** **** **** E 0 3 11 **** +523 Mestils_Acid_Breath Acid Reflex 1 I 1 **** **** **** +524 Mestils_Acid_Sheath Acid **** **** P 0 2 9 **** +525 Monstrous_Regeneration **** **** **** H 0 2 10 -6 +526 Scintillating_Sphere Electricity Reflex 1 I 1 **** **** **** +527 Stone_Bones **** **** **** P 0 3 7 **** +528 Undeath_to_Death **** Will 1 D 1 **** **** **** +529 Vine_Mine **** **** 0 **** 1 **** **** **** +530 Vine_Mine_Entangle **** **** 0 I 1 **** **** **** +531 Vine_Mine_Hamper_Movement **** **** 0 I 1 **** **** **** +532 Vine_Mine_Camouflage **** **** **** P 0 **** **** **** +533 Black_Blade_of_Disaster **** **** **** S 0 **** **** **** +534 Shelgarns_Persistent_Blade **** **** **** S 0 2 0 -2 +535 Blade_Thirst **** **** **** E 0 2 15 -14 +536 Deafening_Clang **** **** **** E 0 2 15 -14 +537 Bless_Weapon **** **** **** E 0 2 15 **** +538 Holy_Sword **** **** **** E 0 2 15 **** +539 Keen_Edge **** **** **** E 0 3 15 **** +540 **** **** **** **** **** **** **** **** **** +541 Blackstaff **** **** **** E 0 2 15 **** +542 Flame_Weapon **** **** **** E 0 3 15 **** +543 Ice_Dagger Cold Reflex 1 R 1 **** **** **** +544 Magic_Weapon **** **** **** E 0 3 15 -14 +545 Greater_Magic_Weapon **** **** **** E 0 3 15 -14 +546 Magic_Vestment **** **** **** E 0 3 15 -4 +547 Stonehold Paralysis Will 1 I 1 **** **** **** +548 Darkfire **** **** **** E 0 3 15 **** +549 Glyph_of_Warding Sonic Reflex 1 I 1 **** **** **** +550 **** **** **** **** **** **** **** **** **** +551 MONSTER_MindBlast **** **** **** I 1 **** **** **** +552 MONSTER_CharmMonster **** **** **** R 1 **** **** **** +553 Goblin_Ballista_Fireball Fire **** **** **** 1 **** **** **** +554 Ioun_Stone_Dusty_Rose **** **** **** **** 0 **** **** **** +555 Ioun_Stone_Pale_Blue **** **** **** **** 0 **** **** **** +556 Ioun_Stone_Scarlet_Blue **** **** **** **** 0 **** **** **** +557 Ioun_Stone_Blue **** **** **** **** 0 **** **** **** +558 Ioun_Stone_Deep_Red **** **** **** **** 0 **** **** **** +559 Ioun_Stone_Pink **** **** **** **** 0 **** **** **** +560 Ioun_Stone_Pink_Green **** **** **** **** 0 **** **** **** +561 Whirlwind **** **** **** **** 0 **** **** **** +562 AuraOfGlory_X2 Mind_Affecting **** **** E 0 **** **** **** +563 Haste_Slow_X2 **** **** **** E 0 **** **** **** +564 Summon_Shadow_X2 **** **** **** S 0 **** **** **** +565 Tide_of_Battle **** **** **** D 0 **** **** **** +566 Evil_Blight **** **** **** T 0 **** **** **** +567 Cure_Critical_Wounds_Others **** **** **** H 0 **** **** **** +568 Restoration_Others **** **** **** C 0 **** **** **** +569 Cloud_of_Bewilderment Poison Fortitude 1 I 1 **** **** **** +570 PADDING **** **** **** **** **** **** **** **** +571 PADDING **** **** **** **** **** **** **** **** +572 PADDING **** **** **** **** **** **** **** **** +573 PADDING **** **** **** **** **** **** **** **** +574 PADDING **** **** **** **** **** **** **** **** +575 PADDING **** **** **** **** **** **** **** **** +576 PADDING **** **** **** **** **** **** **** **** +577 PADDING **** **** **** **** **** **** **** **** +578 PADDING **** **** **** **** **** **** **** **** +579 PADDING **** **** **** **** **** **** **** **** +580 PADDING **** **** **** **** **** **** **** **** +581 PADDING **** **** **** **** **** **** **** **** +582 PADDING **** **** **** **** **** **** **** **** +583 PADDING **** **** **** **** **** **** **** **** +584 PADDING **** **** **** **** **** **** **** **** +585 PADDING **** **** **** **** **** **** **** **** +586 PADDING **** **** **** **** **** **** **** **** +587 PADDING **** **** **** **** **** **** **** **** +588 PADDING **** **** **** **** **** **** **** **** +589 PADDING **** **** **** **** **** **** **** **** +590 PADDING **** **** **** **** **** **** **** **** +591 PADDING **** **** **** **** **** **** **** **** +592 PADDING **** **** **** **** **** **** **** **** +593 PADDING **** **** **** **** **** **** **** **** +594 PADDING **** **** **** **** **** **** **** **** +595 PADDING **** **** **** **** **** **** **** **** +596 PADDING **** **** **** **** **** **** **** **** +597 PADDING **** **** **** **** **** **** **** **** +598 PADDING **** **** **** **** **** **** **** **** +599 PADDING **** **** **** **** **** **** **** **** +600 ARImbueArrow **** **** **** **** 1 **** **** **** +601 ARSeekerArrow **** **** **** **** 1 **** **** **** +602 ARSeekerArrow2 **** **** **** **** 1 **** **** **** +603 ARHailOfArrows **** **** **** I 1 **** **** **** +604 ARArrowOfDeath **** **** **** **** 1 **** **** **** +605 ASGhostlyVisage **** **** **** P 0 **** **** **** +606 ASDarkness **** **** **** **** 0 **** **** **** +607 ASInvisibility **** **** **** E 0 **** **** **** +608 ASImprovedInvisibility **** **** **** E 0 **** **** **** +609 BGCreateDead **** **** **** S 1 **** **** **** +610 BGFiendish Negative **** **** T 1 **** **** **** +611 BGInflictSerious Negative **** **** T 1 **** **** **** +612 BGInflictCritical Negative **** **** T 1 **** **** **** +613 BK_Contagion Disease **** **** T 1 **** **** **** +614 BK_BullsStrength **** **** **** E 0 **** **** **** +615 Twinfists **** **** **** **** 0 **** **** **** +616 LichLyrics **** **** **** **** 0 **** **** **** +617 Iceberry **** **** **** **** 0 **** **** **** +618 Flameberry **** **** **** **** 0 **** **** **** +619 PrayerBox **** **** **** **** 0 **** **** **** +620 Flying_Debris **** **** **** **** **** **** **** **** +621 PADDING **** **** **** **** **** **** **** **** +622 DC_Divine_Wrath **** **** **** E 0 **** **** **** +623 PM_Animate_Dead **** **** **** S 0 **** **** **** +624 PM_Summon_Undead **** **** **** S 0 **** **** **** +625 PM_Undead_Graft1 Mind_Affecting **** **** T 1 **** **** **** +626 PM_Undead_Graft2 Mind_Affecting **** **** T 1 **** **** **** +627 PM_Summon_Greater_Undead **** **** **** S 0 **** **** **** +628 PM_Deathless_Master_Touch Death **** **** T 1 **** **** **** +629 PADDING **** **** **** **** **** **** **** **** +630 PADDING **** **** **** **** **** **** **** **** +631 PADDING **** **** **** **** **** **** **** **** +632 PADDING **** **** **** **** **** **** **** **** +633 PADDING **** **** **** **** **** **** **** **** +634 PADDING **** **** **** **** **** **** **** **** +635 PADDING **** **** **** **** **** **** **** **** +636 Hellball **** Reflex 0 I 1 **** **** **** +637 Mummy_Dust **** **** **** S 0 **** **** **** +638 Dragon_Knight **** **** **** S 0 **** **** **** +639 Epic_Mage_Armor **** **** **** P 0 **** **** **** +640 Ruin Positive Fortitude 0 R 1 **** **** **** +641 DWDEF_Defensive_Stance **** **** **** A 0 **** **** **** +642 Mighty_Rage **** **** **** A 0 **** **** **** +643 PlanarTurning **** **** **** D 1 **** **** **** +644 Curse_Song **** **** **** E 0 **** **** **** +645 Improved_Whirlwind **** **** **** **** 0 **** **** **** +646 Greater_Wild_Shape_1 **** **** **** **** 0 **** **** **** +647 Epic_Blinding_speed **** **** **** E 0 **** **** **** +648 Dye_Armor_cloth1 **** **** **** **** 0 **** **** **** +649 Dye_Armor_Cloth2 **** **** **** **** 0 **** **** **** +650 Dye_Armor_Leather1 **** **** **** **** 0 **** **** **** +651 Dye_Armor_Leather2 **** **** **** **** 0 **** **** **** +652 Dye_Armor_Metal1 **** **** **** **** 0 **** **** **** +653 Dye_Armor_Metal2 **** **** **** **** 0 **** **** **** +654 Add_Item_Property **** **** **** **** 0 **** **** **** +655 Poison_Weapon **** **** **** **** 0 **** **** **** +656 Craft_Weapon **** **** **** **** 0 **** **** **** +657 Craft_Armor **** **** **** **** 0 **** **** **** +658 Greater_Wild_Shape_Wyrmling_Red **** **** **** **** 0 **** **** **** +659 Greater_Wild_Shape_Wyrmling_Blue **** **** **** **** 0 **** **** **** +660 Greater_Wild_Shape_Wyrmling_Black **** **** **** **** 0 **** **** **** +661 Greater_Wild_Shape_Wyrmling_White **** **** **** **** 0 **** **** **** +662 Greater_Wild_Shape_Wyrmling_Green **** **** **** **** 0 **** **** **** +663 WyrmlingPCBreathCold Cold Reflex 0 I 1 **** **** **** +664 WyrmlingPCBreathAcid Acid Reflex 0 I 1 **** **** **** +665 WyrmlingPCBreathFire Fire Reflex 0 I 1 **** **** **** +666 WyrmlingPCBreathGas Acid Reflex 0 I 1 **** **** **** +667 WyrmlingPCBreathLightning Electricity Reflex 0 I 1 **** **** **** +668 ITEM_Teleport **** **** **** **** **** **** **** **** +669 ITEM_Chaos_Shield **** **** **** **** **** **** **** **** +670 Greater_Wild_Shape_Basilisk **** **** **** **** 0 **** **** **** +671 Greater_Wild_Shape_Beholder **** **** **** **** 0 **** **** **** +672 Greater_Wild_Shape_Harpy **** **** **** **** 0 **** **** **** +673 Greater_Wild_Shape_Drider **** **** **** **** 0 **** **** **** +674 Greater_Wild_Shape_Manticore **** **** **** **** 0 **** **** **** +675 Greater_Wild_Shape_2 **** **** **** **** 0 **** **** **** +676 Greater_Wild_Shape_3 **** **** **** **** 0 **** **** **** +677 Greater_Wild_Shape_4 **** **** **** **** 0 **** **** **** +678 Greater_Wild_Shape_Gargoyle **** **** **** **** 0 **** **** **** +679 Greater_Wild_Shape_Medusa **** **** **** **** 0 **** **** **** +680 Greater_Wild_Shape_Minotaur **** **** **** **** 0 **** **** **** +681 Humanoid_Shape **** **** **** **** 0 **** **** **** +682 Humanoid_Shape_Drow **** **** **** **** 0 **** **** **** +683 Humanoid_Shape_Lizardfolk **** **** **** **** 0 **** **** **** +684 Humanoid_Shape_KoboldAssa **** **** **** **** 0 **** **** **** +685 Undead_shape **** **** **** **** 0 **** **** **** +686 Harpysong Mind_Affecting Will 0 I 1 **** **** **** +687 GWildShape_Stonegaze Petrification Fortitude 0 R 1 **** **** **** +688 GWildShape_DriderDarkness **** **** **** **** 0 **** **** **** +689 SlayRakshasa **** **** **** **** **** **** **** **** +690 RedDragonDiscipleBreath Fire Relfex 0 I 1 **** **** **** +691 Greater_Wild_Shape_Mindflayer **** **** **** **** 0 **** **** **** +692 Greater_Wild_Shape_Spikes **** **** **** R 1 **** **** **** +693 GWildShape_Mindblast **** **** **** I 1 **** **** **** +694 Greater_Wild_Shape_DireTiger **** **** **** **** 0 **** **** **** +695 Epic_Warding **** **** **** P 1 **** **** **** +696 OnHitFireDamage Fire **** **** **** 1 **** **** **** +697 ACTIVATE_ITEM_L **** **** **** **** 0 **** **** **** +698 Dragon_Breath_Negative Negative Reflex 0 I 1 **** **** **** +699 **** **** **** **** P 0 **** **** **** +700 ACTIVATE_ITEM_ONHITSPELLCAST **** **** **** **** 0 **** **** **** +701 Summon_Baatezu **** **** **** S 1 **** **** **** +702 OnHitPlanarRift Cold **** **** R 1 **** **** **** +703 OnHitDarkfire Cold **** **** R 1 **** **** **** +704 Undead_Shape_risen_lord **** **** **** **** 0 **** **** **** +705 Undead_Shape_Vampire **** **** **** **** 0 **** **** **** +706 Undead_Shape_Spectre **** **** **** **** 0 **** **** **** +707 Greater_Wild_Shape_Red_dragon **** **** **** **** 0 **** **** **** +708 Greater_Wild_Shape_Blue_dragon **** **** **** **** 0 **** **** **** +709 Greater_Wild_Shape_Green_dragon **** **** **** **** 0 **** **** **** +710 EyeballRay0 Cold Fortitude 0 R 1 **** **** **** +711 EyeballRay1 Negative Fortitude 0 R 1 **** **** **** +712 EyeballRay2 Fire Fortitude 0 R 1 **** **** **** +713 Mindflayer_Mindblast_10 Mind_Affecting Will 0 I 1 **** **** **** +714 Mindflayer_Paragon_Mindblast **** **** **** P 1 **** **** **** +715 Golem_Ranged_Slam **** Reflex 0 R 1 **** **** **** +716 SuckBrain **** **** **** P 0 **** **** **** +717 ACTIVATE_ITEM_SEQUENCER_1 **** **** **** **** 0 **** **** **** +718 ACTIVATE_ITEM_SEQUENCER_2 **** **** **** **** 0 **** **** **** +719 ACTIVATE_ITEM_SEQUENCER_3 **** **** **** **** 0 **** **** **** +720 CLEAR_SEQUENCER **** **** **** **** 0 **** **** **** +721 OnHitFlamingSkin **** **** **** **** 0 **** **** **** +722 Mimic_Eat **** **** **** R **** **** **** **** +723 Mimic_Gem_Thrower **** **** **** R **** **** **** **** +724 Etherealness **** **** **** **** 0 **** **** **** +725 Dragon_Shape **** **** **** **** 0 **** **** **** +726 Mimic_Eat_Enemy **** **** **** R **** **** **** **** +727 Beholder_Anti_Magic_Cone **** **** **** I **** **** **** **** +728 **** **** **** **** **** 1 **** **** **** +729 Mimic_Steal_armor **** **** **** R **** **** **** **** +730 **** **** **** **** **** 0 **** **** **** +731 Bebelith_Web **** Reflex 0 R 1 **** **** **** +732 Outsider_Shape **** **** **** **** 0 **** **** **** +733 Outsider_Shape_Azer **** **** **** **** 0 **** **** **** +734 Outsider_Shape_Rakshasa **** **** **** **** 0 **** **** **** +735 Outsider_Shape_DeathSlaad **** **** **** **** 0 **** **** **** +736 Beholder_Special_Spell_AI **** **** **** I 1 **** **** **** +737 Construct_Shape **** **** **** **** 0 **** **** **** +738 Construct_Shape_StoneGolem **** **** **** **** 0 **** **** **** +739 Construct_Shape_DemonFleshGolem **** **** **** **** 0 **** **** **** +740 Construct_Shape_IronGolem **** **** **** **** 0 **** **** **** +741 Psionic_Inertial_Barrier **** **** **** P 0 **** **** **** +742 Craft_Weapon_Component **** **** **** **** 0 **** **** **** +743 Craft_Armor_Component **** **** **** **** 0 **** **** **** +744 Grenade_FireBomb Fire **** 0 R 1 **** **** **** +745 Grenade_AcidBomb Acid **** 0 R 1 **** **** **** +746 Hell_Catapult_Male **** **** **** R **** **** **** **** +747 Hell_Catapult_Female **** **** **** R **** **** **** **** +748 Hell_Br_Catapult_Male **** **** **** R **** **** **** **** +749 Hell_Brazier_Male **** **** **** R **** **** **** **** +750 Hell_Fence_Male **** **** **** R **** **** **** **** +751 Hell_Boulder_Male **** **** **** R **** **** **** **** +752 Hell_Tree_Male **** **** **** R **** **** **** **** +753 Hell_KNOWER_EFFECT1 **** **** **** R **** **** **** **** +754 Hell_KNOWER_EFFECT2 **** **** **** R **** **** **** **** +755 Hell_KNOWER_EFFECT3 **** **** **** R **** **** **** **** +756 OnHitBebilithAttack **** **** **** **** 1 **** **** **** +757 ShadowBlend **** **** **** **** 0 **** **** **** +758 OnHitDemilichTouch **** **** **** **** 1 **** **** **** +759 UndeadSelfHarm Positive **** **** H 0 **** **** **** +760 OnHitDracolichTouch **** **** **** **** 1 **** **** **** +761 Aura_of_Hellfire Fire **** **** D 1 **** **** **** +762 Hell_Inferno Fire **** **** R 1 **** **** **** +763 Psionic_Mass_Concussion **** **** **** D 1 **** **** **** +764 GlyphOfWardingDefault **** **** **** I 1 **** **** **** +765 Hell_KNOWER_EFFECT4 **** **** **** R **** **** **** **** +766 Hell_KNOWER_EFFECT5 **** **** **** R **** **** **** **** +767 Intelligent_Weapon_Talk **** **** **** **** 0 **** **** **** +768 Intelligent_Weapon_OnHit **** **** **** **** 1 **** **** **** +769 Shadow_Attack **** **** **** T 1 **** **** **** +770 Slaad_Chaos_Spittle Acid **** **** R 1 **** **** **** +771 Dragon_Breath_Prismatic Mind_Affecting Reflex 0 I 1 **** **** **** +772 Spiral_Fireball Fire **** **** I 1 **** **** **** +773 Battle_Boulder_Toss **** **** **** R **** **** **** **** +774 Deflecting_Force **** **** **** P 0 **** **** **** +775 Giant_hurl_rock **** **** 0 R 1 **** **** **** +776 Beholder_Node_1 Death Fortitude 0 I 1 **** **** **** +777 Beholder_Node_2 **** Will 0 I 1 **** **** **** +778 Beholder_Node_3 Petrification Fortitude 0 I 1 **** **** **** +779 Beholder_Node_4 Charm Will 0 I 1 **** **** **** +780 Beholder_Node_5 **** Will 0 I 1 **** **** **** +781 Bridge_VFX **** **** **** R **** **** **** **** +782 Sphere_Spell **** **** **** R **** **** **** **** +783 Beholder_Node_6 **** Fortitude 0 I 1 **** **** **** +784 Beholder_Node_7 Fear Will 0 I 1 **** **** **** +785 Beholder_Node_8 **** **** 0 I 1 **** **** **** +786 Beholder_Node_9 **** **** 0 I 1 **** **** **** +787 Beholder_Node_10 **** **** 0 I 1 **** **** **** +788 OnHitParalyze **** **** **** **** 1 **** **** **** +789 Illithid_Mindblast **** Will 0 I 1 **** **** **** +790 OnHitDeafenClang **** **** **** **** 1 **** **** **** +791 OnHitKnockDown **** **** **** **** 0 **** **** **** +792 OnHitFreeze **** **** **** **** 0 **** **** **** +793 Demonic_Grappling_Hand **** **** **** R **** **** **** **** +794 Ballista_Bolt **** **** **** I 1 **** **** **** +795 ACTIVATE_ITEM_T **** **** **** **** 0 **** **** **** +796 Dragon_Breath_Lightning Electricity Reflex 0 I 1 **** **** **** +797 Dragon_Breath_Fire Fire Reflex 0 I 1 **** **** **** +798 Dragon_Breath_Gas Acid Reflex 0 I 1 **** **** **** +799 Vampire_Invisibility **** **** **** E 0 **** **** **** +800 Vampire_DominationGaze Domination Will 0 I 1 **** **** **** +801 Azer_Fire_Blast Fire Reflex 0 R 1 **** **** **** +802 Shifter_Spectre_Attack Drain Fortitude 0 T 1 **** **** **** +803 SeaHag_EvilEye Drain Fortitude 0 I 1 **** **** **** +804 Aura_HorrificAppearance **** Fortitude 0 A 1 **** **** **** +805 Troglodyte_Stench **** **** **** A 1 **** **** **** +806 PDK_RallyingCry **** **** **** E 0 **** **** **** +807 PDK_Shield **** **** **** E 0 **** **** **** +808 PDK_Fear Fear Will 1 D 1 **** **** **** +809 PDK_OathOfWrath **** **** **** R 0 **** **** **** +810 PDK_FinalStand **** **** **** E 0 **** **** **** +811 PDK_InspireCourage **** **** **** E 0 **** **** **** +812 Horse_Menu **** **** **** **** 0 **** **** **** +813 Horse_Mount **** **** **** **** 0 **** **** **** +814 Horse_Dismount **** **** **** **** 0 **** **** **** +815 Horse_Party_Mount **** **** **** **** 0 **** **** **** +816 Horse_Party_Dismount **** **** **** **** 0 **** **** **** +817 Horse_Assign_Mount **** **** **** **** 0 **** **** **** +818 Paladin_Summon_Mount **** **** **** **** 0 **** **** **** +819 Nightmare_Smoke **** **** **** A 1 **** **** **** +820 DM_TOOL_01 **** **** **** **** 0 **** **** **** +821 DM_TOOL_02 **** **** **** **** 0 **** **** **** +822 DM_TOOL_03 **** **** **** **** 0 **** **** **** +823 DM_TOOL_04 **** **** **** **** 0 **** **** **** +824 DM_TOOL_05 **** **** **** **** 0 **** **** **** +825 DM_TOOL_06 **** **** **** **** 0 **** **** **** +826 DM_TOOL_07 **** **** **** **** 0 **** **** **** +827 DM_TOOL_08 **** **** **** **** 0 **** **** **** +828 DM_TOOL_09 **** **** **** **** 0 **** **** **** +829 DM_TOOL_10 **** **** **** **** 0 **** **** **** +830 PLAYER_TOOL_01 **** **** **** **** 0 **** **** **** +831 PLAYER_TOOL_02 **** **** **** **** 0 **** **** **** +832 PLAYER_TOOL_03 **** **** **** **** 0 **** **** **** +833 PLAYER_TOOL_04 **** **** **** **** 0 **** **** **** +834 PLAYER_TOOL_05 **** **** **** **** 0 **** **** **** +835 PLAYER_TOOL_06 **** **** **** **** 0 **** **** **** +836 PLAYER_TOOL_07 **** **** **** **** 0 **** **** **** +837 PLAYER_TOOL_08 **** **** **** **** 0 **** **** **** +838 PLAYER_TOOL_09 **** **** **** **** 0 **** **** **** +839 PLAYER_TOOL_10 **** **** **** **** 0 **** **** **** +840 **** **** **** **** **** **** **** **** **** +841 **** **** **** **** **** **** **** **** **** +842 **** **** **** **** **** **** **** **** **** +843 **** **** **** **** **** **** **** **** **** +844 **** **** **** **** **** **** **** **** **** +845 **** **** **** **** **** **** **** **** **** +846 **** **** **** **** **** **** **** **** **** +847 **** **** **** **** **** **** **** **** **** +848 **** **** **** **** **** **** **** **** **** +849 **** **** **** **** **** **** **** **** **** +850 **** **** **** **** **** **** **** **** **** +851 **** **** **** **** **** **** **** **** **** +852 **** **** **** **** **** **** **** **** **** +853 **** **** **** **** **** **** **** **** **** +854 **** **** **** **** **** **** **** **** **** +855 **** **** **** **** **** **** **** **** **** +856 **** **** **** **** **** **** **** **** **** +857 **** **** **** **** **** **** **** **** **** +858 **** **** **** **** **** **** **** **** **** +859 **** **** **** **** **** **** **** **** **** +860 **** **** **** **** **** **** **** **** **** +861 **** **** **** **** **** **** **** **** **** +862 **** **** **** **** **** **** **** **** **** +863 **** **** **** **** **** **** **** **** **** +864 **** **** **** **** **** **** **** **** **** +865 **** **** **** **** **** **** **** **** **** +866 **** **** **** **** **** **** **** **** **** +867 **** **** **** **** **** **** **** **** **** +868 **** **** **** **** **** **** **** **** **** +869 **** **** **** **** **** **** **** **** **** +870 **** **** **** **** **** **** **** **** **** +871 **** **** **** **** **** **** **** **** **** +872 **** **** **** **** **** **** **** **** **** +873 **** **** **** **** **** **** **** **** **** +874 **** **** **** **** **** **** **** **** **** +875 **** **** **** **** **** **** **** **** **** +876 **** **** **** **** **** **** **** **** **** +877 **** **** **** **** **** **** **** **** **** +878 **** **** **** **** **** **** **** **** **** +879 **** **** **** **** **** **** **** **** **** +880 **** **** **** **** **** **** **** **** **** +881 **** **** **** **** **** **** **** **** **** +882 **** **** **** **** **** **** **** **** **** +883 **** **** **** **** **** **** **** **** **** +884 **** **** **** **** **** **** **** **** **** +885 **** **** **** **** **** **** **** **** **** +886 **** **** **** **** **** **** **** **** **** +887 **** **** **** **** **** **** **** **** **** +888 **** **** **** **** **** **** **** **** **** +889 **** **** **** **** **** **** **** **** **** +890 **** **** **** **** **** **** **** **** **** +891 **** **** **** **** **** **** **** **** **** +892 **** **** **** **** **** **** **** **** **** +893 **** **** **** **** **** **** **** **** **** +894 **** **** **** **** **** **** **** **** **** +895 **** **** **** **** **** **** **** **** **** +896 **** **** **** **** **** **** **** **** **** +897 **** **** **** **** **** **** **** **** **** +898 **** **** **** **** **** **** **** **** **** +899 **** **** **** **** **** **** **** **** **** +900 **** **** **** **** **** **** **** **** **** +901 **** **** **** **** **** **** **** **** **** +902 **** **** **** **** **** **** **** **** **** +903 **** **** **** **** **** **** **** **** **** +904 **** **** **** **** **** **** **** **** **** +905 **** **** **** **** **** **** **** **** **** +906 **** **** **** **** **** **** **** **** **** +907 **** **** **** **** **** **** **** **** **** +908 **** **** **** **** **** **** **** **** **** +909 **** **** **** **** **** **** **** **** **** +910 **** **** **** **** **** **** **** **** **** +911 **** **** **** **** **** **** **** **** **** +912 **** **** **** **** **** **** **** **** **** +913 **** **** **** **** **** **** **** **** **** +914 **** **** **** **** **** **** **** **** **** +915 **** **** **** **** **** **** **** **** **** +916 **** **** **** **** **** **** **** **** **** +917 **** **** **** **** **** **** **** **** **** +918 **** **** **** **** **** **** **** **** **** +919 **** **** **** **** **** **** **** **** **** +920 **** **** **** **** **** **** **** **** **** +921 **** **** **** **** **** **** **** **** **** +922 **** **** **** **** **** **** **** **** **** +923 **** **** **** **** **** **** **** **** **** +924 **** **** **** **** **** **** **** **** **** +925 **** **** **** **** **** **** **** **** **** +926 **** **** **** **** **** **** **** **** **** +927 **** **** **** **** **** **** **** **** **** +928 **** **** **** **** **** **** **** **** **** +929 **** **** **** **** **** **** **** **** **** +930 **** **** **** **** **** **** **** **** **** +931 **** **** **** **** **** **** **** **** **** +932 **** **** **** **** **** **** **** **** **** +933 **** **** **** **** **** **** **** **** **** +934 **** **** **** **** **** **** **** **** **** +935 **** **** **** **** **** **** **** **** **** +936 **** **** **** **** **** **** **** **** **** +937 **** **** **** **** **** **** **** **** **** +938 **** **** **** **** **** **** **** **** **** +939 **** **** **** **** **** **** **** **** **** +940 **** **** **** **** **** **** **** **** **** +941 **** **** **** **** **** **** **** **** **** +942 **** **** **** **** **** **** **** **** **** +943 **** **** **** **** **** **** **** **** **** +944 **** **** **** **** **** **** **** **** **** +945 **** **** **** **** **** **** **** **** **** +946 **** **** **** **** **** **** **** **** **** +947 **** **** **** **** **** **** **** **** **** +948 **** **** **** **** **** **** **** **** **** +949 **** **** **** **** **** **** **** **** **** +950 **** **** **** **** **** **** **** **** **** +951 **** **** **** **** **** **** **** **** **** +952 **** **** **** **** **** **** **** **** **** +953 **** **** **** **** **** **** **** **** **** +954 **** **** **** **** **** **** **** **** **** +955 **** **** **** **** **** **** **** **** **** +956 **** **** **** **** **** **** **** **** **** +957 **** **** **** **** **** **** **** **** **** +958 **** **** **** **** **** **** **** **** **** +959 **** **** **** **** **** **** **** **** **** +960 **** **** **** **** **** **** **** **** **** +961 **** **** **** **** **** **** **** **** **** +962 **** **** **** **** **** **** **** **** **** +963 **** **** **** **** **** **** **** **** **** +964 **** **** **** **** **** **** **** **** **** +965 **** **** **** **** **** **** **** **** **** +966 **** **** **** **** **** **** **** **** **** +967 **** **** **** **** **** **** **** **** **** +968 **** **** **** **** **** **** **** **** **** +969 **** **** **** **** **** **** **** **** **** +970 **** **** **** **** **** **** **** **** **** +971 **** **** **** **** **** **** **** **** **** +972 **** **** **** **** **** **** **** **** **** +973 **** **** **** **** **** **** **** **** **** +974 **** **** **** **** **** **** **** **** **** +975 **** **** **** **** **** **** **** **** **** +976 **** **** **** **** **** **** **** **** **** +977 **** **** **** **** **** **** **** **** **** +978 **** **** **** **** **** **** **** **** **** +979 **** **** **** **** **** **** **** **** **** +980 **** **** **** **** **** **** **** **** **** +981 **** **** **** **** **** **** **** **** **** +982 **** **** **** **** **** **** **** **** **** +983 **** **** **** **** **** **** **** **** **** +984 **** **** **** **** **** **** **** **** **** +985 **** **** **** **** **** **** **** **** **** +986 **** **** **** **** **** **** **** **** **** +987 **** **** **** **** **** **** **** **** **** +988 **** **** **** **** **** **** **** **** **** +989 **** **** **** **** **** **** **** **** **** +990 **** **** **** **** **** **** **** **** **** +991 **** **** **** **** **** **** **** **** **** +992 **** **** **** **** **** **** **** **** **** +993 **** **** **** **** **** **** **** **** **** +994 **** **** **** **** **** **** **** **** **** +995 **** **** **** **** **** **** **** **** **** +996 **** **** **** **** **** **** **** **** **** +997 **** **** **** **** **** **** **** **** **** +998 **** **** **** **** **** **** **** **** **** +999 **** **** **** **** **** **** **** **** **** +1000 **** **** **** **** **** **** **** **** **** +1001 **** **** **** **** **** **** **** **** **** +1002 **** **** **** **** **** **** **** **** **** +1003 **** **** **** **** **** **** **** **** **** +1004 **** **** **** **** **** **** **** **** **** +1005 **** **** **** **** **** **** **** **** **** +1006 **** **** **** **** **** **** **** **** **** +1007 **** **** **** **** **** **** **** **** **** +1008 **** **** **** **** **** **** **** **** **** +1009 **** **** **** **** **** **** **** **** **** +1010 **** **** **** **** **** **** **** **** **** +1011 **** **** **** **** **** **** **** **** **** +1012 **** **** **** **** **** **** **** **** **** +1013 **** **** **** **** **** **** **** **** **** +1014 **** **** **** **** **** **** **** **** **** +1015 **** **** **** **** **** **** **** **** **** +1016 **** **** **** **** **** **** **** **** **** +1017 **** **** **** **** **** **** **** **** **** +1018 **** **** **** **** **** **** **** **** **** +1019 **** **** **** **** **** **** **** **** **** +1020 **** **** **** **** **** **** **** **** **** +1021 **** **** **** **** **** **** **** **** **** +1022 **** **** **** **** **** **** **** **** **** +1023 **** **** **** **** **** **** **** **** **** +1024 **** **** **** **** **** **** **** **** **** +1025 **** **** **** **** **** **** **** **** **** +1026 **** **** **** **** **** **** **** **** **** +1027 **** **** **** **** **** **** **** **** **** +1028 **** **** **** **** **** **** **** **** **** +1029 **** **** **** **** **** **** **** **** **** +1030 **** **** **** **** **** **** **** **** **** +1031 **** **** **** **** **** **** **** **** **** +1032 **** **** **** **** **** **** **** **** **** +1033 **** **** **** **** **** **** **** **** **** +1034 **** **** **** **** **** **** **** **** **** +1035 **** **** **** **** **** **** **** **** **** +1036 **** **** **** **** **** **** **** **** **** +1037 **** **** **** **** **** **** **** **** **** +1038 **** **** **** **** **** **** **** **** **** +1039 **** **** **** **** **** **** **** **** **** +1040 **** **** **** **** **** **** **** **** **** +1041 **** **** **** **** **** **** **** **** **** +1042 **** **** **** **** **** **** **** **** **** +1043 **** **** **** **** **** **** **** **** **** +1044 **** **** **** **** **** **** **** **** **** +1045 **** **** **** **** **** **** **** **** **** +1046 **** **** **** **** **** **** **** **** **** +1047 **** **** **** **** **** **** **** **** **** +1048 **** **** **** **** **** **** **** **** **** +1049 **** **** **** **** **** **** **** **** **** +1050 **** **** **** **** **** **** **** **** **** +1051 **** **** **** **** **** **** **** **** **** +1052 **** **** **** **** **** **** **** **** **** +1053 **** **** **** **** **** **** **** **** **** +1054 **** **** **** **** **** **** **** **** **** +1055 **** **** **** **** **** **** **** **** **** +1056 **** **** **** **** **** **** **** **** **** +1057 **** **** **** **** **** **** **** **** **** +1058 **** **** **** **** **** **** **** **** **** +1059 **** **** **** **** **** **** **** **** **** +1060 **** **** **** **** **** **** **** **** **** +1061 **** **** **** **** **** **** **** **** **** +1062 **** **** **** **** **** **** **** **** **** +1063 **** **** **** **** **** **** **** **** **** +1064 **** **** **** **** **** **** **** **** **** +1065 **** **** **** **** **** **** **** **** **** +1066 **** **** **** **** **** **** **** **** **** +1067 **** **** **** **** **** **** **** **** **** +1068 **** **** **** **** **** **** **** **** **** +1069 **** **** **** **** **** **** **** **** **** +1070 **** **** **** **** **** **** **** **** **** +1071 **** **** **** **** **** **** **** **** **** +1072 **** **** **** **** **** **** **** **** **** +1073 **** **** **** **** **** **** **** **** **** +1074 **** **** **** **** **** **** **** **** **** +1075 **** **** **** **** **** **** **** **** **** +1076 **** **** **** **** **** **** **** **** **** +1077 **** **** **** **** **** **** **** **** **** +1078 **** **** **** **** **** **** **** **** **** +1079 **** **** **** **** **** **** **** **** **** +1080 **** **** **** **** **** **** **** **** **** +1081 **** **** **** **** **** **** **** **** **** +1082 **** **** **** **** **** **** **** **** **** +1083 **** **** **** **** **** **** **** **** **** +1084 **** **** **** **** **** **** **** **** **** +1085 **** **** **** **** **** **** **** **** **** +1086 **** **** **** **** **** **** **** **** **** +1087 **** **** **** **** **** **** **** **** **** +1088 **** **** **** **** **** **** **** **** **** +1089 **** **** **** **** **** **** **** **** **** +1090 **** **** **** **** **** **** **** **** **** +1091 **** **** **** **** **** **** **** **** **** +1092 **** **** **** **** **** **** **** **** **** +1093 **** **** **** **** **** **** **** **** **** +1094 **** **** **** **** **** **** **** **** **** +1095 **** **** **** **** **** **** **** **** **** +1096 **** **** **** **** **** **** **** **** **** +1097 **** **** **** **** **** **** **** **** **** +1098 **** **** **** **** **** **** **** **** **** +1099 **** **** **** **** **** **** **** **** **** +1100 **** **** **** **** **** **** **** **** **** +1101 **** **** **** **** **** **** **** **** **** +1102 **** **** **** **** **** **** **** **** **** +1103 **** **** **** **** **** **** **** **** **** +1104 **** **** **** **** **** **** **** **** **** +1105 **** **** **** **** **** **** **** **** **** +1106 **** **** **** **** **** **** **** **** **** +1107 **** **** **** **** **** **** **** **** **** +1108 **** **** **** **** **** **** **** **** **** +1109 **** **** **** **** **** **** **** **** **** +1110 **** **** **** **** **** **** **** **** **** +1111 **** **** **** **** **** **** **** **** **** +1112 **** **** **** **** **** **** **** **** **** +1113 **** **** **** **** **** **** **** **** **** +1114 **** **** **** **** **** **** **** **** **** +1115 **** **** **** **** **** **** **** **** **** +1116 **** **** **** **** **** **** **** **** **** +1117 **** **** **** **** **** **** **** **** **** +1118 **** **** **** **** **** **** **** **** **** +1119 **** **** **** **** **** **** **** **** **** +1120 **** **** **** **** **** **** **** **** **** +1121 **** **** **** **** **** **** **** **** **** +1122 **** **** **** **** **** **** **** **** **** +1123 **** **** **** **** **** **** **** **** **** +1124 **** **** **** **** **** **** **** **** **** +1125 **** **** **** **** **** **** **** **** **** +1126 **** **** **** **** **** **** **** **** **** +1127 **** **** **** **** **** **** **** **** **** +1128 **** **** **** **** **** **** **** **** **** +1129 **** **** **** **** **** **** **** **** **** +1130 **** **** **** **** **** **** **** **** **** +1131 **** **** **** **** **** **** **** **** **** +1132 **** **** **** **** **** **** **** **** **** +1133 **** **** **** **** **** **** **** **** **** +1134 **** **** **** **** **** **** **** **** **** +1135 **** **** **** **** **** **** **** **** **** +1136 **** **** **** **** **** **** **** **** **** +1137 **** **** **** **** **** **** **** **** **** +1138 **** **** **** **** **** **** **** **** **** +1139 **** **** **** **** **** **** **** **** **** +1140 **** **** **** **** **** **** **** **** **** +1141 **** **** **** **** **** **** **** **** **** +1142 **** **** **** **** **** **** **** **** **** +1143 **** **** **** **** **** **** **** **** **** +1144 **** **** **** **** **** **** **** **** **** +1145 **** **** **** **** **** **** **** **** **** +1146 **** **** **** **** **** **** **** **** **** +1147 **** **** **** **** **** **** **** **** **** +1148 **** **** **** **** **** **** **** **** **** +1149 **** **** **** **** **** **** **** **** **** +1150 **** **** **** **** **** **** **** **** **** +1151 **** **** **** **** **** **** **** **** **** +1152 **** **** **** **** **** **** **** **** **** +1153 **** **** **** **** **** **** **** **** **** +1154 **** **** **** **** **** **** **** **** **** +1155 **** **** **** **** **** **** **** **** **** +1156 **** **** **** **** **** **** **** **** **** +1157 **** **** **** **** **** **** **** **** **** +1158 **** **** **** **** **** **** **** **** **** +1159 **** **** **** **** **** **** **** **** **** +1160 **** **** **** **** **** **** **** **** **** +1161 **** **** **** **** **** **** **** **** **** +1162 **** **** **** **** **** **** **** **** **** +1163 **** **** **** **** **** **** **** **** **** +1164 **** **** **** **** **** **** **** **** **** +1165 **** **** **** **** **** **** **** **** **** +1166 **** **** **** **** **** **** **** **** **** +1167 **** **** **** **** **** **** **** **** **** +1168 **** **** **** **** **** **** **** **** **** +1169 **** **** **** **** **** **** **** **** **** +1170 **** **** **** **** **** **** **** **** **** +1171 **** **** **** **** **** **** **** **** **** +1172 **** **** **** **** **** **** **** **** **** +1173 **** **** **** **** **** **** **** **** **** +1174 **** **** **** **** **** **** **** **** **** +1175 **** **** **** **** **** **** **** **** **** +1176 **** **** **** **** **** **** **** **** **** +1177 **** **** **** **** **** **** **** **** **** +1178 **** **** **** **** **** **** **** **** **** +1179 **** **** **** **** **** **** **** **** **** +1180 **** **** **** **** **** **** **** **** **** +1181 **** **** **** **** **** **** **** **** **** +1182 **** **** **** **** **** **** **** **** **** +1183 **** **** **** **** **** **** **** **** **** +1184 **** **** **** **** **** **** **** **** **** +1185 **** **** **** **** **** **** **** **** **** +1186 **** **** **** **** **** **** **** **** **** +1187 **** **** **** **** **** **** **** **** **** +1188 **** **** **** **** **** **** **** **** **** +1189 **** **** **** **** **** **** **** **** **** +1190 **** **** **** **** **** **** **** **** **** +1191 **** **** **** **** **** **** **** **** **** +1192 **** **** **** **** **** **** **** **** **** +1193 **** **** **** **** **** **** **** **** **** +1194 **** **** **** **** **** **** **** **** **** +1195 **** **** **** **** **** **** **** **** **** +1196 **** **** **** **** **** **** **** **** **** +1197 **** **** **** **** **** **** **** **** **** +1198 **** **** **** **** **** **** **** **** **** +1199 **** **** **** **** **** **** **** **** **** +1200 **** **** **** **** **** **** **** **** **** +1201 **** **** **** **** **** **** **** **** **** +1202 **** **** **** **** **** **** **** **** **** +1203 **** **** **** **** **** **** **** **** **** +1204 **** **** **** **** **** **** **** **** **** +1205 **** **** **** **** **** **** **** **** **** +1206 **** **** **** **** **** **** **** **** **** +1207 **** **** **** **** **** **** **** **** **** +1208 **** **** **** **** **** **** **** **** **** +1209 **** **** **** **** **** **** **** **** **** +1210 **** **** **** **** **** **** **** **** **** +1211 **** **** **** **** **** **** **** **** **** +1212 **** **** **** **** **** **** **** **** **** +1213 **** **** **** **** **** **** **** **** **** +1214 **** **** **** **** **** **** **** **** **** +1215 **** **** **** **** **** **** **** **** **** +1216 **** **** **** **** **** **** **** **** **** +1217 **** **** **** **** **** **** **** **** **** +1218 **** **** **** **** **** **** **** **** **** +1219 **** **** **** **** **** **** **** **** **** +1220 **** **** **** **** **** **** **** **** **** +1221 **** **** **** **** **** **** **** **** **** +1222 **** **** **** **** **** **** **** **** **** +1223 **** **** **** **** **** **** **** **** **** +1224 **** **** **** **** **** **** **** **** **** +1225 **** **** **** **** **** **** **** **** **** +1226 **** **** **** **** **** **** **** **** **** +1227 **** **** **** **** **** **** **** **** **** +1228 **** **** **** **** **** **** **** **** **** +1229 **** **** **** **** **** **** **** **** **** +1230 **** **** **** **** **** **** **** **** **** +1231 **** **** **** **** **** **** **** **** **** +1232 **** **** **** **** **** **** **** **** **** +1233 **** **** **** **** **** **** **** **** **** +1234 **** **** **** **** **** **** **** **** **** +1235 **** **** **** **** **** **** **** **** **** +1236 **** **** **** **** **** **** **** **** **** +1237 **** **** **** **** **** **** **** **** **** +1238 **** **** **** **** **** **** **** **** **** +1239 **** **** **** **** **** **** **** **** **** +1240 **** **** **** **** **** **** **** **** **** +1241 **** **** **** **** **** **** **** **** **** +1242 **** **** **** **** **** **** **** **** **** +1243 **** **** **** **** **** **** **** **** **** +1244 **** **** **** **** **** **** **** **** **** +1245 **** **** **** **** **** **** **** **** **** +1246 **** **** **** **** **** **** **** **** **** +1247 **** **** **** **** **** **** **** **** **** +1248 **** **** **** **** **** **** **** **** **** +1249 **** **** **** **** **** **** **** **** **** +1250 **** **** **** **** **** **** **** **** **** +1251 **** **** **** **** **** **** **** **** **** +1252 **** **** **** **** **** **** **** **** **** +1253 **** **** **** **** **** **** **** **** **** +1254 **** **** **** **** **** **** **** **** **** +1255 **** **** **** **** **** **** **** **** **** +1256 **** **** **** **** **** **** **** **** **** +1257 **** **** **** **** **** **** **** **** **** +1258 **** **** **** **** **** **** **** **** **** +1259 **** **** **** **** **** **** **** **** **** +1260 **** **** **** **** **** **** **** **** **** +1261 **** **** **** **** **** **** **** **** **** +1262 **** **** **** **** **** **** **** **** **** +1263 **** **** **** **** **** **** **** **** **** +1264 **** **** **** **** **** **** **** **** **** +1265 **** **** **** **** **** **** **** **** **** +1266 **** **** **** **** **** **** **** **** **** +1267 **** **** **** **** **** **** **** **** **** +1268 **** **** **** **** **** **** **** **** **** +1269 **** **** **** **** **** **** **** **** **** +1270 **** **** **** **** **** **** **** **** **** +1271 **** **** **** **** **** **** **** **** **** +1272 **** **** **** **** **** **** **** **** **** +1273 **** **** **** **** **** **** **** **** **** +1274 **** **** **** **** **** **** **** **** **** +1275 **** **** **** **** **** **** **** **** **** +1276 **** **** **** **** **** **** **** **** **** +1277 **** **** **** **** **** **** **** **** **** +1278 **** **** **** **** **** **** **** **** **** +1279 **** **** **** **** **** **** **** **** **** +1280 **** **** **** **** **** **** **** **** **** +1281 **** **** **** **** **** **** **** **** **** +1282 **** **** **** **** **** **** **** **** **** +1283 **** **** **** **** **** **** **** **** **** +1284 **** **** **** **** **** **** **** **** **** +1285 **** **** **** **** **** **** **** **** **** +1286 **** **** **** **** **** **** **** **** **** +1287 **** **** **** **** **** **** **** **** **** +1288 **** **** **** **** **** **** **** **** **** +1289 **** **** **** **** **** **** **** **** **** +1290 **** **** **** **** **** **** **** **** **** +1291 **** **** **** **** **** **** **** **** **** +1292 **** **** **** **** **** **** **** **** **** +1293 **** **** **** **** **** **** **** **** **** +1294 **** **** **** **** **** **** **** **** **** +1295 **** **** **** **** **** **** **** **** **** +1296 **** **** **** **** **** **** **** **** **** +1297 **** **** **** **** **** **** **** **** **** +1298 **** **** **** **** **** **** **** **** **** +1299 **** **** **** **** **** **** **** **** **** +1300 **** **** **** **** **** **** **** **** **** +1301 **** **** **** **** **** **** **** **** **** +1302 **** **** **** **** **** **** **** **** **** +1303 **** **** **** **** **** **** **** **** **** +1304 **** **** **** **** **** **** **** **** **** +1305 **** **** **** **** **** **** **** **** **** +1306 **** **** **** **** **** **** **** **** **** +1307 **** **** **** **** **** **** **** **** **** +1308 **** **** **** **** **** **** **** **** **** +1309 **** **** **** **** **** **** **** **** **** +1310 **** **** **** **** **** **** **** **** **** +1311 **** **** **** **** **** **** **** **** **** +1312 **** **** **** **** **** **** **** **** **** +1313 **** **** **** **** **** **** **** **** **** +1314 **** **** **** **** **** **** **** **** **** +1315 **** **** **** **** **** **** **** **** **** +1316 **** **** **** **** **** **** **** **** **** +1317 **** **** **** **** **** **** **** **** **** +1318 **** **** **** **** **** **** **** **** **** +1319 **** **** **** **** **** **** **** **** **** +1320 **** **** **** **** **** **** **** **** **** +1321 **** **** **** **** **** **** **** **** **** +1322 **** **** **** **** **** **** **** **** **** +1323 **** **** **** **** **** **** **** **** **** +1324 **** **** **** **** **** **** **** **** **** +1325 **** **** **** **** **** **** **** **** **** +1326 **** **** **** **** **** **** **** **** **** +1327 **** **** **** **** **** **** **** **** **** +1328 **** **** **** **** **** **** **** **** **** +1329 **** **** **** **** **** **** **** **** **** +1330 **** **** **** **** **** **** **** **** **** +1331 **** **** **** **** **** **** **** **** **** +1332 **** **** **** **** **** **** **** **** **** +1333 **** **** **** **** **** **** **** **** **** +1334 **** **** **** **** **** **** **** **** **** +1335 **** **** **** **** **** **** **** **** **** +1336 **** **** **** **** **** **** **** **** **** +1337 **** **** **** **** **** **** **** **** **** +1338 **** **** **** **** **** **** **** **** **** +1339 **** **** **** **** **** **** **** **** **** +1340 **** **** **** **** **** **** **** **** **** +1341 **** **** **** **** **** **** **** **** **** +1342 **** **** **** **** **** **** **** **** **** +1343 **** **** **** **** **** **** **** **** **** +1344 **** **** **** **** **** **** **** **** **** +1345 **** **** **** **** **** **** **** **** **** +1346 **** **** **** **** **** **** **** **** **** +1347 **** **** **** **** **** **** **** **** **** +1348 **** **** **** **** **** **** **** **** **** +1349 **** **** **** **** **** **** **** **** **** +1350 **** **** **** **** **** **** **** **** **** +1351 **** **** **** **** **** **** **** **** **** +1352 **** **** **** **** **** **** **** **** **** +1353 **** **** **** **** **** **** **** **** **** +1354 **** **** **** **** **** **** **** **** **** +1355 **** **** **** **** **** **** **** **** **** +1356 **** **** **** **** **** **** **** **** **** +1357 **** **** **** **** **** **** **** **** **** +1358 **** **** **** **** **** **** **** **** **** +1359 **** **** **** **** **** **** **** **** **** +1360 **** **** **** **** **** **** **** **** **** +1361 **** **** **** **** **** **** **** **** **** +1362 **** **** **** **** **** **** **** **** **** +1363 **** **** **** **** **** **** **** **** **** +1364 **** **** **** **** **** **** **** **** **** +1365 **** **** **** **** **** **** **** **** **** +1366 **** **** **** **** **** **** **** **** **** +1367 **** **** **** **** **** **** **** **** **** +1368 **** **** **** **** **** **** **** **** **** +1369 **** **** **** **** **** **** **** **** **** +1370 **** **** **** **** **** **** **** **** **** +1371 **** **** **** **** **** **** **** **** **** +1372 **** **** **** **** **** **** **** **** **** +1373 **** **** **** **** **** **** **** **** **** +1374 **** **** **** **** **** **** **** **** **** +1375 **** **** **** **** **** **** **** **** **** +1376 **** **** **** **** **** **** **** **** **** +1377 **** **** **** **** **** **** **** **** **** +1378 **** **** **** **** **** **** **** **** **** +1379 **** **** **** **** **** **** **** **** **** +1380 **** **** **** **** **** **** **** **** **** +1381 **** **** **** **** **** **** **** **** **** +1382 **** **** **** **** **** **** **** **** **** +1383 **** **** **** **** **** **** **** **** **** +1384 **** **** **** **** **** **** **** **** **** +1385 **** **** **** **** **** **** **** **** **** +1386 **** **** **** **** **** **** **** **** **** +1387 **** **** **** **** **** **** **** **** **** +1388 **** **** **** **** **** **** **** **** **** +1389 **** **** **** **** **** **** **** **** **** +1390 **** **** **** **** **** **** **** **** **** +1391 **** **** **** **** **** **** **** **** **** +1392 **** **** **** **** **** **** **** **** **** +1393 **** **** **** **** **** **** **** **** **** +1394 **** **** **** **** **** **** **** **** **** +1395 **** **** **** **** **** **** **** **** **** +1396 **** **** **** **** **** **** **** **** **** +1397 **** **** **** **** **** **** **** **** **** +1398 **** **** **** **** **** **** **** **** **** +1399 **** **** **** **** **** **** **** **** **** +1400 **** **** **** **** **** **** **** **** **** +1401 **** **** **** **** **** **** **** **** **** +1402 **** **** **** **** **** **** **** **** **** +1403 **** **** **** **** **** **** **** **** **** +1404 **** **** **** **** **** **** **** **** **** +1405 **** **** **** **** **** **** **** **** **** +1406 **** **** **** **** **** **** **** **** **** +1407 **** **** **** **** **** **** **** **** **** +1408 **** **** **** **** **** **** **** **** **** +1409 **** **** **** **** **** **** **** **** **** +1410 **** **** **** **** **** **** **** **** **** +1411 **** **** **** **** **** **** **** **** **** +1412 **** **** **** **** **** **** **** **** **** +1413 **** **** **** **** **** **** **** **** **** +1414 **** **** **** **** **** **** **** **** **** +1415 **** **** **** **** **** **** **** **** **** +1416 **** **** **** **** **** **** **** **** **** +1417 **** **** **** **** **** **** **** **** **** +1418 **** **** **** **** **** **** **** **** **** +1419 **** **** **** **** **** **** **** **** **** +1420 **** **** **** **** **** **** **** **** **** +1421 **** **** **** **** **** **** **** **** **** +1422 **** **** **** **** **** **** **** **** **** +1423 **** **** **** **** **** **** **** **** **** +1424 **** **** **** **** **** **** **** **** **** +1425 **** **** **** **** **** **** **** **** **** +1426 **** **** **** **** **** **** **** **** **** +1427 **** **** **** **** **** **** **** **** **** +1428 **** **** **** **** **** **** **** **** **** +1429 **** **** **** **** **** **** **** **** **** +1430 **** **** **** **** **** **** **** **** **** +1431 **** **** **** **** **** **** **** **** **** +1432 **** **** **** **** **** **** **** **** **** +1433 **** **** **** **** **** **** **** **** **** +1434 **** **** **** **** **** **** **** **** **** +1435 **** **** **** **** **** **** **** **** **** +1436 **** **** **** **** **** **** **** **** **** +1437 **** **** **** **** **** **** **** **** **** +1438 **** **** **** **** **** **** **** **** **** +1439 **** **** **** **** **** **** **** **** **** +1440 **** **** **** **** **** **** **** **** **** +1441 **** **** **** **** **** **** **** **** **** +1442 **** **** **** **** **** **** **** **** **** +1443 **** **** **** **** **** **** **** **** **** +1444 **** **** **** **** **** **** **** **** **** +1445 **** **** **** **** **** **** **** **** **** +1446 **** **** **** **** **** **** **** **** **** +1447 **** **** **** **** **** **** **** **** **** +1448 **** **** **** **** **** **** **** **** **** +1449 **** **** **** **** **** **** **** **** **** +1450 **** **** **** **** **** **** **** **** **** +1451 **** **** **** **** **** **** **** **** **** +1452 **** **** **** **** **** **** **** **** **** +1453 **** **** **** **** **** **** **** **** **** +1454 **** **** **** **** **** **** **** **** **** +1455 **** **** **** **** **** **** **** **** **** +1456 **** **** **** **** **** **** **** **** **** +1457 **** **** **** **** **** **** **** **** **** +1458 **** **** **** **** **** **** **** **** **** +1459 **** **** **** **** **** **** **** **** **** +1460 **** **** **** **** **** **** **** **** **** +1461 **** **** **** **** **** **** **** **** **** +1462 **** **** **** **** **** **** **** **** **** +1463 **** **** **** **** **** **** **** **** **** +1464 **** **** **** **** **** **** **** **** **** +1465 **** **** **** **** **** **** **** **** **** +1466 **** **** **** **** **** **** **** **** **** +1467 **** **** **** **** **** **** **** **** **** +1468 **** **** **** **** **** **** **** **** **** +1469 **** **** **** **** **** **** **** **** **** +1470 **** **** **** **** **** **** **** **** **** +1471 **** **** **** **** **** **** **** **** **** +1472 **** **** **** **** **** **** **** **** **** +1473 **** **** **** **** **** **** **** **** **** +1474 **** **** **** **** **** **** **** **** **** +1475 **** **** **** **** **** **** **** **** **** +1476 **** **** **** **** **** **** **** **** **** +1477 **** **** **** **** **** **** **** **** **** +1478 **** **** **** **** **** **** **** **** **** +1479 **** **** **** **** **** **** **** **** **** +1480 **** **** **** **** **** **** **** **** **** +1481 **** **** **** **** **** **** **** **** **** +1482 **** **** **** **** **** **** **** **** **** +1483 **** **** **** **** **** **** **** **** **** +1484 **** **** **** **** **** **** **** **** **** +1485 Warsoul_CultPower **** **** **** **** **** **** **** **** +1486 Warsoul_SoulTyrant **** **** **** **** **** **** **** **** +1487 SPIRETOP_FOG_CLOUD_BREATH **** **** **** **** **** **** **** **** +1488 MEPHLING_BREATH_WEAPON **** **** **** **** **** **** **** **** +1489 ARANEA_ALTFORM_RADIAL **** **** **** **** **** **** **** **** +1490 ARANEA_ALT_HUMANOID **** **** **** **** **** **** **** **** +1491 ARANEA_ALT_HYBRID **** **** **** **** **** **** **** **** +1492 ARANEA_ALT_SPIDER **** **** **** **** **** **** **** **** +1493 ARANEA_WEB **** **** **** **** **** **** **** **** +1494 MUCKDWELLER_SQUIRT **** **** **** **** **** **** **** **** +1495 TN_DES_20 **** **** **** **** **** **** **** **** +1496 TN_DES_100 **** **** **** **** **** **** **** **** +1497 TN_Unsummon **** **** **** **** **** **** **** **** +1498 VAMPIRIC_DRAIN **** **** **** **** **** **** **** **** +1499 Dancing_Lights **** **** **** **** **** **** **** **** +1500 Read_Magic **** **** **** **** **** **** **** **** +1501 Sobriety **** **** **** **** **** **** **** **** +1502 Crafters_Blessing **** **** **** **** **** **** **** **** +1503 Crafters_Curse **** **** **** **** **** **** **** **** +1504 Lesser_Planar_Ally **** **** **** S 0 3 0 -2 +1505 Greater_Planar_Ally **** **** **** S 0 3 0 -2 +1506 Eternal_Charm_Monster **** **** **** **** **** **** **** **** +1507 Eternal_Charm_Person **** **** **** **** **** **** **** **** +1508 Weapon_of_Impact **** **** **** E 0 3 15 **** +1509 Shillelagh **** **** **** E 0 2 15 -14 +1510 Daze_Monster Dazed Will 1 R 1 **** **** **** +1511 Curse_Water **** **** **** **** **** **** **** **** +1512 Mislead **** **** **** P 0 2 0 **** +1513 Power_Word_Blind **** **** 1 R 1 **** **** **** +1514 BFZ_FatefulStride **** **** **** **** **** **** **** **** +1515 PA_FLETCH_1 **** **** **** **** **** **** **** **** +1516 PA_FLETCH_2 **** **** **** **** **** **** **** **** +1517 PA_FLETCH_3 **** **** **** **** **** **** **** **** +1518 PA_FLETCH_4 **** **** **** **** **** **** **** **** +1519 PA_FLETCH_5 **** **** **** **** **** **** **** **** +1520 PA_POWERSHOT **** **** **** **** **** **** **** **** +1521 PA_IMP_POWERSHOT **** **** **** **** **** **** **** **** +1522 PA_SUP_POWERSHOT **** **** **** **** **** **** **** **** +1523 Hext_StrBoost **** **** **** **** **** **** **** **** +1524 AT_RL_LOCK **** **** **** **** **** **** **** **** +1525 AT_RL_TRAP **** **** **** **** **** **** **** **** +1526 AT_ISA **** **** **** **** **** **** **** **** +1527 TN_CGUNDEAD **** **** **** **** **** **** **** **** +1528 Thousand_Faces_MEDIUM **** **** **** **** **** **** **** **** +1529 Thousand_Faces_SMALL **** **** **** **** **** **** **** **** +1530 Thousand_Faces_DWARF **** **** **** **** **** **** **** **** +1531 Thousand_Faces_ELF **** **** **** **** **** **** **** **** +1532 Thousand_Faces_HALF_ELF **** **** **** **** **** **** **** **** +1533 Thousand_Faces_HALF_ORC **** **** **** **** **** **** **** **** +1534 Thousand_Faces_HUMAN **** **** **** **** **** **** **** **** +1535 Thousand_Faces_GNOME **** **** **** **** **** **** **** **** +1536 Thousand_Faces_HALFLING **** **** **** **** **** **** **** **** +1537 Thousand_Face_OFF **** **** **** **** **** **** **** **** +1538 OcRay_ChPer **** **** **** **** **** **** **** **** +1539 OcRay_Sleep **** **** **** **** **** **** **** **** +1540 OcRay_InfW **** **** **** **** **** **** **** **** +1541 OcRay_Slow **** **** **** **** **** **** **** **** +1542 OcRay_Fear **** **** **** **** **** **** **** **** +1543 OcRay_ChMon **** **** **** **** **** **** **** **** +1544 OcRay_Tele **** **** **** **** **** **** **** **** +1545 OcRay_FlSt **** **** **** **** **** **** **** **** +1546 OcRay_Dis **** **** **** **** **** **** **** **** +1547 OcRay_Death **** **** **** **** **** **** **** **** +1548 Samu_AncestralDaisho **** **** **** **** **** **** **** **** +1549 Warpr_Rally **** **** **** **** **** **** **** **** +1550 Warpr_Inflame **** **** **** **** **** **** **** **** +1551 Warpr_ImplicableFoe **** **** **** **** **** **** **** **** +1552 Warpr_Healing_Circle **** **** **** **** **** **** **** **** +1553 TN_CLUNDEAD **** **** **** **** **** **** **** **** +1554 TN_EnergyDrain **** **** **** **** **** **** **** **** +1555 Warpr_Mass_Haste **** **** **** **** **** **** **** **** +1556 TO_Fear **** **** **** **** **** **** **** **** +1557 TO_Pallor **** **** **** **** **** **** **** **** +1558 TO_Carrion **** **** **** **** **** **** **** **** +1559 TO_DeathTouch **** **** **** **** **** **** **** **** +1560 TO_MNRUndead **** **** **** **** **** **** **** **** +1561 TO_MJRUndead **** **** **** **** **** **** **** **** +1562 TO_Nightwing **** **** **** **** **** **** **** **** +1563 Warpr_Mass_Heal **** **** **** **** **** **** **** **** +1564 SB_ShockWeap **** **** **** **** **** **** **** **** +1565 SB_HolyWeap **** **** **** **** **** **** **** **** +1566 SB_BrillWeap **** **** **** **** **** **** **** **** +1567 Spell_Turning **** **** **** P 0 3 0 -9 +1568 Death_Knell **** **** **** **** **** **** **** **** +1569 SereneGuardian_PainfulRelease **** **** **** **** **** **** **** **** +1570 SereneGuardian_DamagingRelease **** **** **** **** **** **** **** **** +1571 SereneGuardian_StaggeringRelease **** **** **** **** **** **** **** **** +1572 SereneGuardian_ConfoundingRelease **** **** **** **** **** **** **** **** +1573 SereneGuardian_SoulRelease **** **** **** **** **** **** **** **** +1574 AnimalTrance Mind_Affecting Will 1 R 1 **** **** **** +1575 Blink **** **** **** E 0 2 0 **** +1576 DetectMagic **** **** **** **** **** **** **** **** +1577 Marrusault_Howl **** **** **** **** **** **** **** **** +1578 Hybsil_Mirror_Image **** **** **** **** **** **** **** **** +1579 HYBSIL_DANCLIGHTS **** **** **** **** **** **** **** **** +1580 HYBSIL_JUMP **** **** **** **** **** **** **** **** +1581 Bariaur_Charge **** **** **** **** **** **** **** **** +1582 Wildren_fury **** **** **** **** **** **** **** **** +1583 KotMC_CombatSense **** **** **** **** **** **** **** **** +1584 InvestArmour **** **** **** **** **** **** **** **** +1585 ThayK_FinalStand **** **** **** **** **** **** **** **** +1586 ArmouredMind **** **** **** **** **** **** **** **** +1587 Diabol_Diabolism **** **** **** **** **** **** **** **** +1588 Diabol_VDiabolism **** **** **** **** **** **** **** **** +1589 MindOverBody **** **** **** **** **** **** **** **** +1590 Maester_Identification **** **** **** **** **** **** **** **** +1591 LendResolve **** **** **** **** **** **** **** **** +1592 Ollam_InspireCompetence **** **** **** **** **** **** **** **** +1593 Ollam_InspireResilience **** **** **** **** **** **** **** **** +1594 Duskblade_Channeling **** **** **** **** **** **** **** **** +1595 DivineWholeness **** **** **** **** **** **** **** **** +1596 Hexblade_Companion **** **** **** **** **** **** **** **** +1597 TribalFrenzy **** **** **** **** **** **** **** **** +1598 HexbladeCurse **** **** **** **** **** **** **** **** +1599 HexbladeAura **** **** **** **** **** **** **** **** +1600 Changestaff **** **** **** S 0 3 0 -2 +1601 Rage **** **** **** E 0 2 9 **** +1602 Arach_SpidMount **** **** **** **** **** **** **** **** +1603 Arach_DominateMale **** **** **** **** **** **** **** **** +1604 Arach_ZinCarla **** **** **** **** **** **** **** **** +1605 Arach_YochlolMaster **** **** **** **** **** **** **** **** +1606 Arach_YochlolYoch **** **** **** **** **** **** **** **** +1607 Arach_YochlolSpid **** **** **** **** **** **** **** **** +1608 Arach_YochloloGas **** **** **** **** **** **** **** **** +1609 Arach_YochlolRevert **** **** **** **** **** **** **** **** +1610 Duskblade_Quickcast **** **** **** **** **** **** **** **** +1611 WarStrike **** **** **** **** **** **** **** **** +1612 SelvetarmsWrath **** **** **** **** **** **** **** **** +1613 SpidersGrace **** **** **** **** **** **** **** **** +1614 SpiderServantMonstrous **** **** **** **** **** **** **** **** +1615 SpiderServantSword **** **** **** **** **** **** **** **** +1616 SpiderServantMyrlochar **** **** **** **** **** **** **** **** +1617 SpiderServantPhase **** **** **** **** **** **** **** **** +1618 SpiderServantMasterFeat **** **** **** **** **** **** **** **** +1619 Judgment **** **** **** **** **** **** **** **** +1620 Healer_Clean_Para **** **** **** **** **** **** **** **** +1621 InscribeRune **** **** **** **** **** **** **** **** +1622 MaximizeRune **** **** **** **** **** **** **** **** +1623 RuneChant **** **** **** **** **** **** **** **** +1624 ImprovedRunecast **** **** **** **** **** **** **** **** +1625 RuneCharges **** **** **** **** **** **** **** **** +1626 RuneUsesPerDay **** **** **** **** **** **** **** **** +1627 RuneCountOne **** **** **** **** **** **** **** **** +1628 RuneCountTen **** **** **** **** **** **** **** **** +1629 RuneClear **** **** **** **** **** **** **** **** +1630 Healer_Clean_Dis **** **** **** **** **** **** **** **** +1631 PDK_RallyingCry **** **** **** **** **** **** **** **** +1632 PDK_Fear **** **** **** **** **** **** **** **** +1633 PDK_OathOfWrath **** **** **** **** **** **** **** **** +1634 PDK_FinalStand **** **** **** **** **** **** **** **** +1635 PDK_InspireCourage **** **** **** **** **** **** **** **** +1636 Healer_Clean_Fear **** **** **** **** **** **** **** **** +1637 WidenSpell **** **** **** **** **** **** **** **** +1638 Healer_Clean_Poison **** **** **** **** **** **** **** **** +1639 Dirge_Sorrow **** **** **** **** **** **** **** **** +1640 Dirge_Bolster **** **** **** **** **** **** **** **** +1641 Dirge_Grief **** **** **** **** **** **** **** **** +1642 Dirge_Horror **** **** **** **** **** **** **** **** +1643 Dirge_Awaken **** **** **** **** **** **** **** **** +1644 Healer_Clean_Blind **** **** **** **** **** **** **** **** +1645 Suel_DispellingStrike **** **** **** **** **** **** **** **** +1646 SancMind_CleanStrike **** **** **** **** **** **** **** **** +1647 SancMind_DisruptBlow **** **** **** **** **** **** **** **** +1648 SancMind_PartitionMind **** **** **** **** **** **** **** **** +1649 Healer_Clean_Spirit **** **** **** **** **** **** **** **** +1650 ClangeddinsStrike **** **** **** **** **** **** **** **** +1651 ClangeddinsMight **** **** **** **** **** **** **** **** +1652 Rockburst **** **** **** **** **** **** **** **** +1653 Healer_Clean_Petri **** **** **** **** **** **** **** **** +1654 CheckDomainSlots **** **** **** **** **** **** **** **** +1655 CastDomainLevel1 **** **** **** **** **** **** **** **** +1656 CastDomainLevel1Slot1 **** **** **** **** **** **** **** **** +1657 CastDomainLevel1Slot2 **** **** **** **** **** **** **** **** +1658 CastDomainLevel1Slot3 **** **** **** **** **** **** **** **** +1659 CastDomainLevel1Slot4 **** **** **** **** **** **** **** **** +1660 CastDomainLevel1Slot5 **** **** **** **** **** **** **** **** +1661 CastDomainLevel2 **** **** **** **** **** **** **** **** +1662 CastDomainLevel2Slot1 **** **** **** **** **** **** **** **** +1663 CastDomainLevel2Slot2 **** **** **** **** **** **** **** **** +1664 CastDomainLevel2Slot3 **** **** **** **** **** **** **** **** +1665 CastDomainLevel2Slot4 **** **** **** **** **** **** **** **** +1666 CastDomainLevel2Slot5 **** **** **** **** **** **** **** **** +1667 CastDomainLevel3 **** **** **** **** **** **** **** **** +1668 CastDomainLevel3Slot1 **** **** **** **** **** **** **** **** +1669 CastDomainLevel3Slot2 **** **** **** **** **** **** **** **** +1670 CastDomainLevel3Slot3 **** **** **** **** **** **** **** **** +1671 CastDomainLevel3Slot4 **** **** **** **** **** **** **** **** +1672 CastDomainLevel3Slot5 **** **** **** **** **** **** **** **** +1673 CastDomainLevel4 **** **** **** **** **** **** **** **** +1674 CastDomainLevel4Slot1 **** **** **** **** **** **** **** **** +1675 CastDomainLevel4Slot2 **** **** **** **** **** **** **** **** +1676 CastDomainLevel4Slot3 **** **** **** **** **** **** **** **** +1677 CastDomainLevel4Slot4 **** **** **** **** **** **** **** **** +1678 CastDomainLevel4Slot5 **** **** **** **** **** **** **** **** +1679 CastDomainLevel5 **** **** **** **** **** **** **** **** +1680 CastDomainLevel5Slot1 **** **** **** **** **** **** **** **** +1681 CastDomainLevel5Slot2 **** **** **** **** **** **** **** **** +1682 CastDomainLevel5Slot3 **** **** **** **** **** **** **** **** +1683 CastDomainLevel5Slot4 **** **** **** **** **** **** **** **** +1684 CastDomainLevel5Slot5 **** **** **** **** **** **** **** **** +1685 CastDomainLevel6 **** **** **** **** **** **** **** **** +1686 CastDomainLevel6Slot1 **** **** **** **** **** **** **** **** +1687 CastDomainLevel6Slot2 **** **** **** **** **** **** **** **** +1688 CastDomainLevel6Slot3 **** **** **** **** **** **** **** **** +1689 CastDomainLevel6Slot4 **** **** **** **** **** **** **** **** +1690 CastDomainLevel6Slot5 **** **** **** **** **** **** **** **** +1691 CastDomainLevel7 **** **** **** **** **** **** **** **** +1692 CastDomainLevel7Slot1 **** **** **** **** **** **** **** **** +1693 CastDomainLevel7Slot2 **** **** **** **** **** **** **** **** +1694 CastDomainLevel7Slot3 **** **** **** **** **** **** **** **** +1695 CastDomainLevel7Slot4 **** **** **** **** **** **** **** **** +1696 CastDomainLevel7Slot5 **** **** **** **** **** **** **** **** +1697 Healer_New_Limb **** **** **** **** **** **** **** **** +1698 Healer_New_Life **** **** **** **** **** **** **** **** +1699 SenseMagic **** **** **** **** **** **** **** **** +1700 CHANNEL_SPELL **** **** **** **** **** **** **** **** +1701 CastDomainLevel8 **** **** **** **** **** **** **** **** +1702 CastDomainLevel8Slot1 **** **** **** **** **** **** **** **** +1703 CastDomainLevel8Slot2 **** **** **** **** **** **** **** **** +1704 CastDomainLevel8Slot3 **** **** **** **** **** **** **** **** +1705 CastDomainLevel8Slot4 **** **** **** **** **** **** **** **** +1706 CastDomainLevel8Slot5 **** **** **** **** **** **** **** **** +1707 CastDomainLevel9 **** **** **** **** **** **** **** **** +1708 CastDomainLevel9Slot1 **** **** **** **** **** **** **** **** +1709 CastDomainLevel9Slot2 **** **** **** **** **** **** **** **** +1710 CastDomainLevel9Slot3 **** **** **** **** **** **** **** **** +1711 CastDomainLevel9Slot4 **** **** **** **** **** **** **** **** +1712 CastDomainLevel9Slot5 **** **** **** **** **** **** **** **** +1713 DualBoost **** **** **** **** **** **** **** **** +1714 Charm_Domain_Power **** **** **** **** **** **** **** **** +1715 Death_Domain_Power **** **** **** **** **** **** **** **** +1716 Destruction_Domain_Power **** **** **** **** **** **** **** **** +1717 Family_Domain_Power **** **** **** **** **** **** **** **** +1718 Halfling_Domain_Power **** **** **** **** **** **** **** **** +1719 Hate_Domain_Power **** **** **** **** **** **** **** **** +1720 Nobility_Domain_Power **** **** **** **** **** **** **** **** +1721 Orc_Domain_Power **** **** **** **** **** **** **** **** +1722 Protection_Domain_Power **** **** **** **** **** **** **** **** +1723 Renewal_Domain_Power **** **** **** **** **** **** **** **** +1724 Strength_Domain_Power **** **** **** **** **** **** **** **** +1725 Travel_Domain_Power **** **** **** **** **** **** **** **** +1726 Turn_Scaleykind **** **** **** **** **** **** **** **** +1727 Turn_Slime **** **** **** **** **** **** **** **** +1728 DrowJudicator_Command_Spiders **** **** **** **** **** **** **** **** +1729 Turn_Plant **** **** **** **** **** **** **** **** +1730 Turn_Air **** **** **** **** **** **** **** **** +1731 Turn_Earth **** **** **** **** **** **** **** **** +1732 Turn_Fire **** **** **** **** **** **** **** **** +1733 Turn_Water **** **** **** **** **** **** **** **** +1734 Turn_Blightspawned **** **** **** **** **** **** **** **** +1735 AppraiseMagicValue **** **** **** **** **** **** **** **** +1736 CraftSkullTalisman **** **** **** **** **** **** **** **** +1737 Grenade_Cursed_Water **** **** **** **** **** **** **** **** +1738 Frostrager_OneTwoPunch **** **** **** **** **** **** **** **** +1739 ZealousSurge **** **** **** **** **** **** **** **** +1740 CrusaderSmite **** **** **** **** **** **** **** **** +1741 Animalistic_Power **** **** **** E 0 2 1 **** +1742 Bigbys_Striking_Fist **** Reflex 1 R 1 **** **** **** +1743 Bigbys_Tripping_Hand **** Reflex 1 R 1 **** **** **** +1744 Blade_of_Blood **** **** **** **** **** **** **** **** +1745 Blade_of_Blood_1d6 **** **** **** E 0 2 15 **** +1746 Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +1747 FEAT_FRIGHTFUL_CLEAVE **** **** **** **** **** **** **** **** +1748 FEAT_FRIGHTFUL_ATTACK **** **** **** **** **** **** **** **** +1749 FEAT_GFKILL_GHOST_STEP **** **** **** **** **** **** **** **** +1750 Acrobatic_Charge **** **** **** **** **** **** **** **** +1751 Stunning_Shout **** **** **** **** **** **** **** **** +1752 Ki_Save **** **** **** **** **** **** **** **** +1753 Ki_Skill **** **** **** **** **** **** **** **** +1754 Ki_Heal **** **** **** **** **** **** **** **** +1755 Deadly_Shout **** **** **** **** **** **** **** **** +1756 Censure_Demons **** **** **** **** **** **** **** **** +1757 Courage_Of_Heaven **** **** **** **** **** **** **** **** +1758 Consecrated_Aura **** **** **** **** **** **** **** **** +1759 Holy_Aura_Versus_Demons **** **** **** **** **** **** **** **** +1760 ChosenWeapon **** **** **** **** **** **** **** **** +1761 DexterousAttack **** **** **** **** **** **** **** **** +1762 FlurryOfSwords **** **** **** **** **** **** **** **** +1763 FalseKeeness **** **** **** **** **** **** **** **** +1764 Blur **** **** **** **** **** **** **** **** +1765 MirrorImage **** **** **** **** **** **** **** **** +1766 SuddenEmpower **** **** **** **** **** **** **** **** +1767 SuddenExtend **** **** **** **** **** **** **** **** +1768 SuddenMaximize **** **** **** **** **** **** **** **** +1769 SuddenWiden **** **** **** **** **** **** **** **** +1770 FightingChallenge **** **** **** **** **** **** **** **** +1771 TestOfMettle **** **** **** **** **** **** **** **** +1772 CallToBattle **** **** **** **** **** **** **** **** +1773 DauntingChallenge **** **** **** **** **** **** **** **** +1774 BondOfLoyalty **** **** **** **** **** **** **** **** +1775 LoyalBeyondDeath **** **** **** **** **** **** **** **** +1776 ShieldBlock **** **** **** **** **** **** **** **** +1777 BulwarkOfDefense **** **** **** **** **** **** **** **** +1778 VigilantDefender **** **** **** **** **** **** **** **** +1779 ShieldAlly **** **** **** **** **** **** **** **** +1780 ImprovedShieldAlly **** **** **** **** **** **** **** **** +1781 AttuneGem **** **** **** **** **** **** **** **** +1782 AttuneGemCraft **** **** **** **** **** **** **** **** +1783 AttuneGemCheckGem **** **** **** **** **** **** **** **** +1784 SummonUndeadI **** **** **** S 0 2 0 **** +1785 SummonUndeadII **** **** **** S 0 2 0 **** +1786 SummonUndeadIII **** **** **** S 0 2 0 **** +1787 SummonUndeadIV **** **** **** S 0 2 0 **** +1788 SummonUndeadV **** **** **** S 0 2 0 **** +1789 Scare Fear Will 1 I 1 **** **** **** +1790 Animate_Object **** **** **** **** **** **** **** **** +1791 Chill_Touch Negative Fortitude 1 T 1 **** **** **** +1792 Spellbook **** **** **** **** **** **** **** **** +1793 PnPFamiliarHide **** **** **** **** **** **** **** **** +1794 ChangeCodeSwitches **** **** **** **** **** **** **** **** +1795 FEAT_ZONE_OF_ANIMATION **** **** **** **** **** **** **** **** +1796 AugmentFamiliar **** **** **** **** **** **** **** **** +1797 Deflect **** **** **** P 0 2 0 **** +1798 EndScrying **** **** **** **** **** **** **** **** +1799 FalseLife **** **** **** P 0 3 0 **** +1800 ProtectionArrows **** **** **** P 0 2 7 **** +1801 TouchIdiocy **** **** 1 T 1 **** **** **** +1802 DeepSlumber Mind_Affecting Will 1 I 1 **** **** **** +1803 HoundDoom **** **** **** **** **** **** **** **** +1804 RepelVermin **** **** **** P 0 3 0 **** +1805 BalefulPolymorph **** Fortitude 1 R 1 **** **** **** +1806 BreakEnchantment **** **** **** **** **** **** **** **** +1807 CursedBlade **** **** **** **** **** **** **** **** +1808 SolidFog **** **** **** I 1 **** **** **** +1809 DetectScrying **** **** **** **** **** **** **** **** +1810 Channeled_Pyroburst **** **** **** **** **** **** **** **** +1811 Channeled_Pyroburst_Swift **** **** **** **** **** **** **** **** +1812 Channeled_Pyroburst_Standard **** **** **** **** **** **** **** **** +1813 Channeled_Pyroburst_Full **** **** **** **** **** **** **** **** +1814 Channeled_Pyroburst_Two **** **** **** **** **** **** **** **** +1815 Crown_Might **** **** **** E 0 3 1 **** +1816 Crown_Protection **** **** **** P 0 3 14 **** +1817 Lesser_Deflect **** **** **** P 0 2 0 **** +1818 Dimension_Hop **** **** **** **** **** **** **** **** +1819 Dispelling_Touch **** **** **** **** **** **** **** **** +1820 Doom_Scarabs **** Will 0 I 1 **** **** **** +1821 Energy_Aegis **** **** **** **** **** **** **** **** +1822 Energy_Aegis_Acid **** **** **** **** **** **** **** **** +1823 Energy_Aegis_Cold **** **** **** **** **** **** **** **** +1824 Energy_Aegis_Elec **** **** **** **** **** **** **** **** +1825 Energy_Aegis_Fire **** **** **** **** **** **** **** **** +1826 Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +1827 Energy_Surge **** **** **** **** **** **** **** **** +1828 Energy_Surge_Acid **** **** **** **** **** **** **** **** +1829 Energy_Surge_Cold **** **** **** **** **** **** **** **** +1830 Energy_Surge_Elec **** **** **** **** **** **** **** **** +1831 Energy_Surge_Fire **** **** **** **** **** **** **** **** +1832 Energy_Surge_Sonic **** **** **** **** **** **** **** **** +1833 Halt **** Will 1 R 1 **** **** **** +1834 Kelgores_Fire_Bolt Fire Reflex 0 R 1 **** **** **** +1835 Regroup **** **** **** **** **** **** **** **** +1836 Rouse **** **** **** **** **** **** **** **** +1837 Seeking_Ray Electricity **** 1 R 1 **** **** **** +1838 Slashing_Dispel **** **** **** R 1 **** **** **** +1839 Sonic_Shield **** **** **** P 0 2 0 **** +1840 Sure_Strike **** **** **** E 0 2 0 **** +1841 CoC_Bless **** **** **** **** **** **** **** **** +1842 CoC_Wrath **** **** **** **** **** **** **** **** +1843 OAAnimalCompanion **** **** **** **** **** **** **** **** +1844 Celestial_Companion **** **** **** **** **** **** **** **** +1845 Unicorn_Companion **** **** **** **** **** **** **** **** +1846 Lammasu_Companion **** **** **** **** **** **** **** **** +1847 Androsphinx_Companion **** **** **** **** **** **** **** **** +1848 SongArcanePower **** **** **** **** **** **** **** **** +1849 Close_Wounds **** **** **** H 0 **** **** **** +1850 Revivify **** **** **** **** **** **** **** **** +1851 Bless_Water **** **** **** **** **** **** **** **** +1852 Calm_Emotions **** **** **** **** **** **** **** **** +1853 Repulsion **** **** **** P 0 2 0 **** +1854 Holy_Aura **** **** **** P 0 2 0 **** +1855 True_Resurrection **** **** **** **** **** **** **** **** +1856 Foresight **** **** **** P 0 3 0 **** +1857 SongTimelessness **** **** **** **** **** **** **** **** +1858 Draconic_Arcane_Grace_Master_1_5 **** **** **** **** **** **** **** **** +1859 Draconic_Arcane_Grace_Master_6_9 **** **** **** **** **** **** **** **** +1860 Draconic_Breath_Master_1_5 **** **** **** **** **** **** **** **** +1861 Draconic_Breath_Master_6_9 **** **** **** **** **** **** **** **** +1862 Draconic_Arcane_Grace_1 **** **** **** **** **** **** **** **** +1863 Draconic_Arcane_Grace_2 **** **** **** **** **** **** **** **** +1864 Draconic_Arcane_Grace_3 **** **** **** **** **** **** **** **** +1865 Draconic_Arcane_Grace_4 **** **** **** **** **** **** **** **** +1866 Draconic_Arcane_Grace_5 **** **** **** **** **** **** **** **** +1867 Draconic_Arcane_Grace_6 **** **** **** **** **** **** **** **** +1868 Draconic_Arcane_Grace_7 **** **** **** **** **** **** **** **** +1869 Draconic_Arcane_Grace_8 **** **** **** **** **** **** **** **** +1870 Draconic_Arcane_Grace_9 **** **** **** **** **** **** **** **** +1871 Draconic_Breath_1 **** **** **** **** **** **** **** **** +1872 Draconic_Breath_2 **** **** **** **** **** **** **** **** +1873 Draconic_Breath_3 **** **** **** **** **** **** **** **** +1874 Draconic_Breath_4 **** **** **** **** **** **** **** **** +1875 Draconic_Breath_5 **** **** **** **** **** **** **** **** +1876 Draconic_Breath_6 **** **** **** **** **** **** **** **** +1877 Draconic_Breath_7 **** **** **** **** **** **** **** **** +1878 Draconic_Breath_8 **** **** **** **** **** **** **** **** +1879 Draconic_Breath_9 **** **** **** **** **** **** **** **** +1880 Breath_of_Life **** **** **** **** **** **** **** **** +1881 Swift_Wing_Wings **** **** **** **** **** **** **** **** +1882 ToT_Frightful_Presence **** **** **** **** **** **** **** **** +1883 ToT_Dominate_Dragon **** **** **** **** **** **** **** **** +1884 ToT_Breath_Weapon **** **** **** **** **** **** **** **** +1885 ToT_Cold_Cone **** **** **** **** **** **** **** **** +1886 ToT_Acid_Line **** **** **** **** **** **** **** **** +1887 ToT_Acid_Cone **** **** **** **** **** **** **** **** +1888 ToT_Elec_Line **** **** **** **** **** **** **** **** +1889 ToT_Fire_Cone **** **** **** **** **** **** **** **** +1890 Dragonfire_Strike_Toggle **** **** **** **** **** **** **** **** +1891 True_Stealth_Toggle **** **** **** **** **** **** **** **** +1892 Fire_Lash **** **** **** **** **** **** **** **** +1893 Bolt_of_Fire **** **** **** **** **** **** **** **** +1894 Nimbus **** **** **** **** **** **** **** **** +1895 Nimbus_Touch_Attack **** **** **** **** **** **** **** **** +1896 Firewalk **** **** **** **** **** **** **** **** +1897 Heat_Death **** **** **** **** **** **** **** **** +1898 Conflagration **** **** **** **** **** **** **** **** +1899 SongCosmicFire **** **** **** **** **** **** **** **** +1900 Shifter_GWShape **** **** **** **** **** **** **** **** +1901 Shifter_EGWShape **** **** **** **** **** **** **** **** +1902 Shifter_Options **** **** **** **** **** **** **** **** +1903 Shifter_TrueForm **** **** **** **** **** **** **** **** +1904 Lich_Touch **** **** **** **** **** **** **** **** +1905 Lich_Fear_Aura **** **** **** **** **** **** **** **** +1906 Lich_AlterSelf **** **** **** **** **** **** **** **** +1907 Lich_CraftWonderus **** **** **** **** **** **** **** **** +1908 Lich_Trap **** **** **** **** **** **** **** **** +1909 Assassin_DeathAttack **** **** **** **** **** **** **** **** +1910 SPELL_LASHER_THIRD_HAND **** **** **** **** **** **** **** **** +1911 SPELL_LASHER_CRACK **** **** **** **** **** **** **** **** +1912 SPELL_LASHER_STUN_SNAP **** **** **** **** **** **** **** **** +1913 SPELL_LASHER_DEATH_SPIRAL **** **** **** **** **** **** **** **** +1914 SPELL_LASHER_LASHW **** **** **** **** **** **** **** **** +1915 ForceOfPersonality **** **** **** **** **** **** **** **** +1916 InsightfulReflexes **** **** **** **** **** **** **** **** +1917 SPELL_LASHER_CRACK_DOOM **** **** **** **** **** **** **** **** +1918 Shifter_Effects_Application **** **** **** **** **** **** **** **** +1919 Shifter_QuickShiftSlots_1 **** **** **** **** **** **** **** **** +1920 Shifter_QuickShiftSlots_2 **** **** **** **** **** **** **** **** +1921 Shifter_QuickSlot_1 **** **** **** **** **** **** **** **** +1922 Shifter_QuickSlot_2 **** **** **** **** **** **** **** **** +1923 Shifter_QuickSlot_3 **** **** **** **** **** **** **** **** +1924 Shifter_QuickSlot_4 **** **** **** **** **** **** **** **** +1925 Shifter_QuickSlot_5 **** **** **** **** **** **** **** **** +1926 Shifter_QuickSlot_6 **** **** **** **** **** **** **** **** +1927 Shifter_QuickSlot_7 **** **** **** **** **** **** **** **** +1928 Shifter_QuickSlot_8 **** **** **** **** **** **** **** **** +1929 Shifter_QuickSlot_9 **** **** **** **** **** **** **** **** +1930 Shifter_QuickSlot_10 **** **** **** **** **** **** **** **** +1931 FEAT_RACE_GAZECONF **** **** **** **** **** **** **** **** +1932 FEAT_RACE_GAZEEVIL **** **** **** **** **** **** **** **** +1933 FEAT_RACE_GAZEPETRIFY **** **** **** **** **** **** **** **** +1934 SlayerOfDomielDetectEvil **** **** **** **** **** **** **** **** +1935 FEAT_RACE_VAMPTOUCH **** **** **** **** **** **** **** **** +1936 FEAT_IRDA_CHANGE_SHAPE **** **** **** **** **** **** **** **** +1937 Irda_Select_Form **** **** **** **** **** **** **** **** +1938 Irda_Options **** **** **** **** **** **** **** **** +1939 Irda_True_Form **** **** **** **** **** **** **** **** +1940 Irda_Quickslot_1 **** **** **** **** **** **** **** **** +1941 Irda_Quickslot_2 **** **** **** **** **** **** **** **** +1942 FEAT_CHANGELING_CHANGE_SHAPE **** **** **** **** **** **** **** **** +1943 Changeling_Select_Form **** **** **** **** **** **** **** **** +1944 Changeling_Options **** **** **** **** **** **** **** **** +1945 Changeling_True_Form **** **** **** **** **** **** **** **** +1946 Changeling_Quickslot_1 **** **** **** **** **** **** **** **** +1947 Changeling_Quickslot_2 **** **** **** **** **** **** **** **** +1948 Nymph_Stunning_Glance **** **** **** **** **** **** **** **** +1949 Nymph_Blinding_Beauty **** **** **** **** **** **** **** **** +1950 SlayerOfDomielDeathTouch1 **** **** **** **** **** **** **** **** +1951 Rakshasa_Disguise **** **** **** **** **** **** **** **** +1952 EndPRCPolymorph **** **** **** **** **** **** **** **** +1953 Shout Sonic Fortitude 1 I 1 **** **** **** +1954 Greater_Shout Sonic Fortitude 1 I 1 **** **** **** +1955 Feyri_Alter **** **** **** **** **** **** **** **** +1956 Nixie_Waterbreathing **** **** **** **** **** **** **** **** +1957 Urdinnir_StoneSkin **** **** **** **** **** **** **** **** +1958 Race_Darkness **** **** **** **** **** **** **** **** +1959 Race_Daze **** **** **** **** **** **** **** **** +1960 Race_Light **** **** **** **** **** **** **** **** +1961 Svirf_BlindDeaf **** **** **** **** **** **** **** **** +1962 Duegar_Invis **** **** **** **** **** **** **** **** +1963 Illithid_Charm_Monster **** **** **** **** **** **** **** **** +1964 Race_Charm_Person **** **** **** **** **** **** **** **** +1965 Faerie_Fire **** **** **** **** **** **** **** **** +1966 Avariel_Dive **** **** **** **** **** **** **** **** +1967 Minotaur_Charge **** **** **** **** **** **** **** **** +1968 Race_Blur **** **** **** **** **** **** **** **** +1969 Feyri_Enervation **** **** **** **** **** **** **** **** +1970 Race_Entangle **** **** **** **** **** **** **** **** +1971 Race_Fear **** **** **** **** **** **** **** **** +1972 Race_Clair **** **** **** **** **** **** **** **** +1973 Race_Neutralize_Poison **** **** **** **** **** **** **** **** +1974 Pixie_Confusion **** **** **** **** **** **** **** **** +1975 Pixie_Invis **** **** **** **** **** **** **** **** +1976 Pixie_Dispel **** **** **** **** **** **** **** **** +1977 Race_Chill_Touch **** **** **** **** **** **** **** **** +1978 Pixie_Polymorph **** **** **** **** **** **** **** **** +1979 Pixie_BROWN_BEAR **** **** **** **** **** **** **** **** +1980 Pixie_PANTHER **** **** **** **** **** **** **** **** +1981 Pixie_WOLF **** **** **** **** **** **** **** **** +1982 Pixie_BOAR **** **** **** **** **** **** **** **** +1983 Pixie_BADGER **** **** **** **** **** **** **** **** +1984 EnergyRay **** **** **** **** **** **** **** **** +1985 EnergyRay_Cold **** **** **** **** **** **** **** **** +1986 EnergyRay_Elec **** **** **** **** **** **** **** **** +1987 EnergyRay_Fire **** **** **** **** **** **** **** **** +1988 EnergyRay_Sonic **** **** **** **** **** **** **** **** +1989 Race_Silence **** **** **** **** **** **** **** **** +1990 Race_Mage_Hand **** **** **** **** **** **** **** **** +1991 Race_Elan_Resistance **** **** **** **** **** **** **** **** +1992 Race_Elan_Resiliance **** **** **** **** **** **** **** **** +1993 Race_Halfgiant_Stomp **** **** **** **** **** **** **** **** +1994 Race_Maenad_Outburst **** **** **** **** **** **** **** **** +1995 Race_Xeph_Burst **** **** **** **** **** **** **** **** +1996 Race_Vampiric_Touch **** **** **** **** **** **** **** **** +1997 SacredPurifier_SacredStrike **** **** **** **** **** **** **** **** +1998 FogCloud **** **** **** **** **** **** **** **** +1999 PsychicRenewal **** **** **** **** **** **** **** **** +2000 Mastery_Elements(Normal) **** **** **** **** **** **** **** **** +2001 Mastery_Elements(Fire) **** **** **** **** **** **** **** **** +2002 Mastery_Elements(Cold) **** **** **** **** **** **** **** **** +2003 Mastery_Elements(Acid) **** **** **** **** **** **** **** **** +2004 Mastery_Elements(Electricity) **** **** **** **** **** **** **** **** +2005 Mastery_Elements(Sonic) **** **** **** **** **** **** **** **** +2006 Mastery_Shaping **** **** **** **** **** **** **** **** +2007 Arcane_Fire **** **** **** **** **** **** **** **** +2008 Spell_Like **** **** **** **** **** **** **** **** +2009 Mastery_Elements(Master) **** **** **** **** **** **** **** **** +2010 MinOozyTouchBrown **** **** **** **** **** **** **** **** +2011 MinOozyTouchGray **** **** **** **** **** **** **** **** +2012 MinOozyTouchOchr **** **** **** **** **** **** **** **** +2013 MinOozyTouchFungus **** **** **** **** **** **** **** **** +2014 MajOozyTouchBlack **** **** **** **** **** **** **** **** +2015 MajOozyTouchCube **** **** **** **** **** **** **** **** +2016 MajOozyTouchSlime **** **** **** **** **** **** **** **** +2017 MajOozyTouchYellow **** **** **** **** **** **** **** **** +2018 OozyGlob **** **** **** **** **** **** **** **** +2019 OozyGlob(Brown) **** **** **** **** **** **** **** **** +2020 OozyGlob(Gray) **** **** **** **** **** **** **** **** +2021 OozyGlob(Ochre) **** **** **** **** **** **** **** **** +2022 OozyGlob(Fungus) **** **** **** **** **** **** **** **** +2023 SlimeWave **** **** **** **** **** **** **** **** +2024 Feat_End_Spell_Effects **** **** **** **** **** **** **** **** +2025 HavocMage_BattleCast **** **** **** **** **** **** **** **** +2026 EndPRCTreeshape **** **** **** **** **** **** **** **** +2027 BAELNORN_EYES **** **** **** **** **** **** **** **** +2028 Cohort **** **** **** **** **** **** **** **** +2029 Hath_GrCommand **** **** **** **** **** **** **** **** +2030 ShadowbaneSmite **** **** **** **** **** **** **** **** +2031 Shadowbane_SacredStealth **** **** **** **** **** **** **** **** +2032 NimbusOfLight **** **** **** **** **** **** **** **** +2033 ServanOfHeaven **** **** **** **** **** **** **** **** +2034 Ranged_Smite **** **** **** **** **** **** **** **** +2035 HathranFear **** **** **** **** **** **** **** **** +2036 SLA_I **** **** **** **** **** **** **** **** +2037 SLA_II **** **** **** **** **** **** **** **** +2038 SLA_III **** **** **** **** **** **** **** **** +2039 SLA_IV **** **** **** **** **** **** **** **** +2040 SLA_V **** **** **** **** **** **** **** **** +2041 MLGreaterTurn **** **** **** **** **** **** **** **** +2042 MLMaximizeTurn **** **** **** **** **** **** **** **** +2043 MLSearingRay **** **** **** **** **** **** **** **** +2044 MLRejuvenationOfMorn **** **** **** **** **** **** **** **** +2045 MLAuraOfRadiance **** **** **** **** **** **** **** **** +2046 MLDaylight **** **** **** **** **** **** **** **** +2047 EXTRA_SUMMONING **** **** **** **** **** **** **** **** +2048 SummonAir **** **** **** **** **** **** **** **** +2049 SummonEarth **** **** **** **** **** **** **** **** +2050 SummonFire **** **** **** **** **** **** **** **** +2051 SummonWater **** **** **** **** **** **** **** **** +2052 Anti-paladin_Summon_Mount **** **** **** **** **** **** **** **** +2053 Rune_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +2054 Rune_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +2055 Rune_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +2056 ShadowInq_PierceShadows **** **** **** **** **** **** **** **** +2057 ShadowInq_BurningLight **** **** **** **** **** **** **** **** +2058 ShadowStk_SacredDefense **** **** **** **** **** **** **** **** +2059 ShadowStk_SacredStrike **** **** **** **** **** **** **** **** +2060 BurnSpell **** **** **** **** **** **** **** **** +2061 KnightWeave_Damage **** **** **** **** **** **** **** **** +2062 KnightWeave_Heal **** **** **** **** **** **** **** **** +2063 Enthrall **** **** **** **** **** **** **** **** +2064 Spelldance_Enthrall **** **** **** **** **** **** **** **** +2065 Spelldance_Sleep **** **** **** **** **** **** **** **** +2066 MountainFortressStance **** **** **** **** **** **** **** **** +2067 CrashingMountainJuggernaught **** **** **** **** **** **** **** **** +2068 DragonsTooth **** **** **** **** **** **** **** **** +2069 AwakenTheStoneDragon **** **** **** **** **** **** **** **** +2070 Spell_Jump **** **** **** **** **** **** **** **** +2071 IRON_BODY **** **** **** **** **** **** **** **** +2072 ENLARGE_PERSON **** **** **** E 0 2 9 -2072 +2073 MASS_ENLARGE_PERSON **** **** **** E 0 2 9 -2072 +2074 REDUCE_PERSON **** Fortitude 1 R 1 **** **** **** +2075 MASS_REDUCE_PERSON **** Fortitude 1 I 1 **** **** **** +2076 ANTIMAGIC_FIELD **** **** **** P 0 3 0 -7 +2077 NONDETECTION **** **** **** **** **** **** **** **** +2078 RAINBOW_PATTERN Mind_Affecting Will 1 I 1 **** **** **** +2079 MAGE_HAND **** **** **** **** **** **** **** **** +2080 DETECT_UNDEAD **** **** **** **** **** **** **** **** +2081 GLIBNESS **** **** **** **** **** **** **** **** +2082 Imbue_Item **** **** **** **** **** **** **** **** +2083 Eldritch_Blast **** **** **** **** **** **** **** **** +2084 FIENDISH_RESILIENCE **** **** **** **** **** **** **** **** +2085 PouncingStrike **** **** **** **** **** **** **** **** +2086 SPELL_AP_DEATHKNELL **** **** **** **** **** **** **** **** +2087 SPELL_AP_CONTAGION **** **** **** **** **** **** **** **** +2088 SPELL_AP_SMITEGOOD **** **** **** **** **** **** **** **** +2089 SPELL_AP_AURAFEAR **** **** **** **** **** **** **** **** +2090 SPELL_INTUTIVATK **** **** **** **** **** **** **** **** +2091 Blacklight **** Will 1 I 1 **** **** **** +2092 DarkBolt **** **** **** **** **** **** **** **** +2093 DarkBolt_all **** **** **** **** **** **** **** **** +2094 DarkBolt_1 **** **** **** **** **** **** **** **** +2095 Darkness_Armor **** **** **** **** **** **** **** **** +2096 Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +2097 Nature_Avatar **** **** **** **** **** **** **** **** +2098 Unyielding_Roots **** **** **** H 0 **** **** **** +2099 Blessing_of_bahamut **** **** **** P 0 2 0 **** +2100 BloodClawShifting **** **** **** **** **** **** **** **** +2101 Adept_Fire_Breath **** **** **** **** **** **** **** **** +2102 Adept_Fire_Cone **** **** **** **** **** **** **** **** +2103 Adept_Fire_Line **** **** **** **** **** **** **** **** +2104 Adept_Frost_Cone **** **** **** **** **** **** **** **** +2105 Adept_Electric_Line **** **** **** **** **** **** **** **** +2106 Adept_Sickness_Cone **** **** **** **** **** **** **** **** +2107 Adept_Acid_Breath **** **** **** **** **** **** **** **** +2108 Adept_Acid_Cone **** **** **** **** **** **** **** **** +2109 Adept_Acid_Line **** **** **** **** **** **** **** **** +2110 Adept_Shaped_Breath **** **** **** **** **** **** **** **** +2111 Adept_Slow_Cone **** **** **** **** **** **** **** **** +2112 Adept_Weakening_Cone **** **** **** **** **** **** **** **** +2113 Adept_Cloud_Breath **** **** **** **** **** **** **** **** +2114 Adept_Enduring_Breath **** **** **** **** **** **** **** **** +2115 Adept_Sleep_Cone **** **** **** **** **** **** **** **** +2116 Adept_Thunder_Cone **** **** **** **** **** **** **** **** +2117 Adept_Bahamut_Line **** **** **** **** **** **** **** **** +2118 Adept_Force_Line **** **** **** **** **** **** **** **** +2119 Adept_Paralyzation_Cone **** **** **** **** **** **** **** **** +2120 Adept_Tiamat_Breath **** **** **** **** **** **** **** **** +2121 RKVDivineRecovery **** **** **** **** **** **** **** **** +2122 Mass_Contagion Disease Fortitude 1 I 1 **** **** **** +2123 SPELL_SACREDSPEED **** **** **** **** **** **** **** **** +2124 SPELL_INNERARMOR **** **** **** **** **** **** **** **** +2125 SPELL_SACREDFLAME **** **** **** **** **** **** **** **** +2126 SPELL_SHADOWSHIELD **** **** **** **** **** **** **** **** +2127 SPELL_SHADOWWALK **** **** **** **** **** **** **** **** +2128 SPELL_SHADOWDOUBLE **** **** **** **** **** **** **** **** +2129 SPELL_NS_INVISIBILITY **** **** **** **** **** **** **** **** +2130 SPELL_NS_WEB **** **** **** **** **** **** **** **** +2131 SPELL_NS_POISON **** **** **** **** **** **** **** **** +2132 SPELL_NS_SHADOWWALK **** **** **** **** **** **** **** **** +2133 SPELL_NS_POISONSPELL **** **** **** **** **** **** **** **** +2134 SPELL_UR_FAVORITE_ENEMY **** **** **** **** **** **** **** **** +2135 SPELL_DSL_SONG_STRENGTH **** **** **** **** **** **** **** **** +2136 SPELL_DSL_SONG_COMPULSION **** **** **** **** **** **** **** **** +2137 SPELL_DSL_SONG_SPEED **** **** **** **** **** **** **** **** +2138 SPELL_DSL_SONG_FEAR **** **** **** **** **** **** **** **** +2139 SPELL_DSL_SONG_HEALING **** **** **** **** **** **** **** **** +2140 SPELL_UR_HAWK_TOTEM **** **** **** **** **** **** **** **** +2141 SPELL_NS_LINGDMG **** **** **** **** **** **** **** **** +2142 SPELL_UR_ANIMALCOMPANION **** **** **** **** **** **** **** **** +2143 SPELL_UR_HIPS **** **** **** **** **** **** **** **** +2144 LuckyShot **** **** **** **** **** **** **** **** +2145 MINSTREL_SONG_CHARM **** **** **** **** **** **** **** **** +2146 RKVDivineImpteus **** **** **** **** **** **** **** **** +2147 MINSTREL_SONG_IMM_FEAR **** **** **** **** **** **** **** **** +2148 MINSTREL_SONG_SHIELD_AC **** **** **** **** **** **** **** **** +2149 MINSTREL_SONG_SONIC_WEAP **** **** **** **** **** **** **** **** +2150 MINSTREL_SONG_STRENGTH **** **** **** **** **** **** **** **** +2151 MINSTREL_SONG_CONSTITUTION **** **** **** **** **** **** **** **** +2152 MINSTREL_SONG_DEXTERITY **** **** **** **** **** **** **** **** +2153 MINSTREL_SONG_INTELLIGENCE **** **** **** **** **** **** **** **** +2154 MINSTREL_SONG_WISDOM **** **** **** **** **** **** **** **** +2155 MINSTREL_SONG_CHARISMA **** **** **** **** **** **** **** **** +2156 MINSTREL_SONG_WOUND_WHISP **** **** **** **** **** **** **** **** +2157 MINSTREL_SONG_SLEEP **** **** **** **** **** **** **** **** +2158 MINSTREL_SONG_SILENCE **** **** **** **** **** **** **** **** +2159 MINSTREL_SONG_HASTE **** **** **** **** **** **** **** **** +2160 MINSTREL_SONG_SLOW **** **** **** **** **** **** **** **** +2161 SPELL_BRAWLER_EXTRA_ATT **** **** **** **** **** **** **** **** +2162 SPELL_EPIC_DIVINE_VIGOR **** **** **** **** **** **** **** **** +2163 SPELL_INVOKE_DIVINE_WRATH **** **** **** **** **** **** **** **** +2164 SPELL_DIVINE_VIGOR **** **** **** **** **** **** **** **** +2165 SPELL_DIVINE_CLEANSING **** **** **** **** **** **** **** **** +2166 SPELL_DIVINE_RESISTANCE **** **** **** **** **** **** **** **** +2167 Consecrate **** **** **** **** **** **** **** **** +2168 BOLT_XAGYA **** **** **** **** **** **** **** **** +2169 SPELL_DISCIPLE_OF_SUN **** **** **** **** **** **** **** **** +2170 PowerAtk_Single_Radial_Master **** **** **** **** **** **** **** **** +2171 PowerAttack_0 **** **** **** **** **** **** **** **** +2172 PowerAttack_1 **** **** **** **** **** **** **** **** +2173 PowerAttack_2 **** **** **** **** **** **** **** **** +2174 PowerAttack_3 **** **** **** **** **** **** **** **** +2175 PowerAttack_4 **** **** **** **** **** **** **** **** +2176 PowerAtk_Fives_Radial **** **** **** **** **** **** **** **** +2177 PowerAttack_0 **** **** **** **** **** **** **** **** +2178 PowerAttack_5 **** **** **** **** **** **** **** **** +2179 PowerAttack_10 **** **** **** **** **** **** **** **** +2180 PowerAttack_15 **** **** **** **** **** **** **** **** +2181 PowerAttack_20 **** **** **** **** **** **** **** **** +2182 SPELL_FURIOUS_ASSAULT **** **** **** **** **** **** **** **** +2183 Summon_Energon **** **** **** **** **** **** **** **** +2184 SPELL_SMITE_UNDEAD **** **** **** **** **** **** **** **** +2185 SPELL_DIVINE_VENGEANCE **** **** **** **** **** **** **** **** +2186 SPELL_POSITIVE_ENERGY_BURST **** **** **** **** **** **** **** **** +2187 SPELL_FIST_OF_IRON **** **** **** **** **** **** **** **** +2188 RKVDivineFury **** **** **** **** **** **** **** **** +2189 Summon_Familiar **** **** **** **** **** **** **** **** +2190 RavageGoldenIce **** **** **** **** **** **** **** **** +2191 SPELL_STIGMATA **** **** **** **** **** **** **** **** +2192 SPELL_STIGMATA5 **** **** **** **** **** **** **** **** +2193 SPELL_STIGMATA2 **** **** **** **** **** **** **** **** +2194 SPELL_STIGMATA3 **** **** **** **** **** **** **** **** +2195 SPELL_STIGMATA4 **** **** **** **** **** **** **** **** +2196 SPELL_HOLYRADIANCE **** **** **** **** **** **** **** **** +2197 FEAT_ANIMALMASTERY **** **** **** **** **** **** **** **** +2198 IncreaseUnarmedEpic **** **** **** **** **** **** **** **** +2199 FEAT_ARCH_RANGEDDISARM **** **** **** **** **** **** **** **** +2200 FEAT_SONG_OF_FURY **** **** **** **** **** **** **** **** +2201 FEAT_EXTRASHOT **** **** **** **** **** **** **** **** +2202 FEAT_RANGEDTRIP **** **** **** **** **** **** **** **** +2203 Pinpoint_Accuracy **** **** **** **** **** **** **** **** +2204 Pinpoint_Accuracy2 **** **** **** **** **** **** **** **** +2205 Pinpoint_Accuracy4 **** **** **** **** **** **** **** **** +2206 Pinpoint_Accuracy6 **** **** **** **** **** **** **** **** +2207 Imp_ManyShot **** **** **** **** **** **** **** **** +2208 Imp_ManyShot5 **** **** **** **** **** **** **** **** +2209 Imp_ManyShot6 **** **** **** **** **** **** **** **** +2210 LIPS_RAPTUR **** **** **** **** **** **** **** **** +2211 TEARS_EVERGOLD **** **** **** **** **** **** **** **** +2212 Elemental_Conflag **** **** **** **** **** **** **** **** +2213 Elemental_FIRE **** **** **** **** **** **** **** **** +2214 Elemental_WATER **** **** **** **** **** **** **** **** +2215 Elemental_EARTH **** **** **** **** **** **** **** **** +2216 Elemental_AIR **** **** **** **** **** **** **** **** +2217 Smite_Evil_Raziel **** **** **** **** **** **** **** **** +2218 FEAT_MAGIC_CIRCLE_EVIL **** **** **** **** **** **** **** **** +2219 Inspire_allies **** **** **** **** **** **** **** **** +2220 TEMPUS_ENCHANT_WEAPON **** **** **** **** **** **** **** **** +2221 TEMPUS_IDENTIFY_ARMS **** **** **** **** **** **** **** **** +2222 Shadowlord_Jump **** **** **** **** **** **** **** **** +2223 Shadowlord_Blur **** **** **** **** **** **** **** **** +2224 DivineSpirit **** **** **** **** **** **** **** **** +2225 InstantClarity **** **** **** **** **** **** **** **** +2226 TrapEngineer **** **** **** **** **** **** **** **** +2227 ContagiousTouch Disease Fortitude 1 T 1 **** **** **** +2228 Blighter_Blightfire **** **** **** **** **** **** **** **** +2229 Blighter_AnimateDeadAnimal **** **** **** **** **** **** **** **** +2230 Blighter_Unbond **** **** **** **** **** **** **** **** +2231 Blighter_Plague **** **** **** **** **** **** **** **** +2232 Battlesmith_TemperedInBlood **** **** **** **** **** **** **** **** +2233 Battlesmith_Boosts **** **** **** **** **** **** **** **** +2234 PsyRogue_ShadowJump **** **** **** **** **** **** **** **** +2235 POLYMORPH_ELEM **** **** **** **** **** **** **** **** +2236 ClawDragon **** **** **** **** **** **** **** **** +2237 FrightfulPresence **** **** **** **** **** **** **** **** +2238 ShapeDragon **** **** **** **** **** **** **** **** +2239 ShapeDragonGold **** **** **** **** **** **** **** **** +2240 ShapeDragonRed **** **** **** **** **** **** **** **** +2241 ShapeDragonPrysmatic **** **** **** **** **** **** **** **** +2242 Dragon_Breath_Fire **** **** **** **** **** **** **** **** +2243 Dragon_Breath_Gas **** **** **** **** **** **** **** **** +2244 Dragon_Breath_Prismatic **** **** **** **** **** **** **** **** +2245 ManyShot **** **** **** **** **** **** **** **** +2246 ManyShot2 **** **** **** **** **** **** **** **** +2247 Magic_Missile **** **** 1 R 1 **** **** **** +2248 ManyShot4 **** **** **** **** **** **** **** **** +2249 ManyShot6 **** **** **** **** **** **** **** **** +2250 Examine_Recipe **** **** **** **** **** **** **** **** +2251 Read **** **** **** **** **** **** **** **** +2252 Item_Creation **** **** **** **** **** **** **** **** +2253 Craft_Item **** **** **** **** **** **** **** **** +2254 Examine_Recipe **** **** **** **** **** **** **** **** +2255 NEW_CRAFTING **** **** **** **** **** **** **** **** +2256 Spelldance_Confuse **** **** **** **** **** **** **** **** +2257 Spelldance **** **** **** **** **** **** **** **** +2258 IncreaseUnarmedShape **** **** **** **** **** **** **** **** +2259 SPELL_AP_TURNOUTS **** **** **** **** **** **** **** **** +2260 Riddle_of_Awareness **** **** **** **** **** **** **** **** +2261 Happo_Zanshin **** **** **** **** **** **** **** **** +2262 Riddle_of_Interaction **** **** **** **** **** **** **** **** +2263 Blind_Sight **** **** **** **** **** **** **** **** +2264 Hitsu_Do **** **** **** **** **** **** **** **** +2265 Walk_Through_the_Mountains **** **** **** **** **** **** **** **** +2266 Riddle_of_Invulnerability **** **** **** **** **** **** **** **** +2267 Spelldance_Max **** **** **** **** **** **** **** **** +2268 Bottle_Proficiency **** **** **** **** **** **** **** **** +2269 Stagger **** **** **** **** **** **** **** **** +2270 Swaying_Waist **** **** **** **** **** **** **** **** +2271 Spelldance_Emp **** **** **** **** **** **** **** **** +2272 Lurch **** **** **** **** **** **** **** **** +2273 Drunken_Embrace **** **** **** **** **** **** **** **** +2274 For_Medicinal_Purposes **** **** **** **** **** **** **** **** +2275 Breath_of_Flame **** **** **** **** **** **** **** **** +2276 Spelldance_Ext **** **** **** **** **** **** **** **** +2277 ACP_Fighting_Stance_change **** **** **** **** **** **** **** **** +2278 ACP_Fighting_Stance_KENSAI **** **** **** **** **** **** **** **** +2279 ACP_Fighting_Stance_ASSASSIN **** **** **** **** **** **** **** **** +2280 ACP_Fighting_Stance_HEAVY **** **** **** **** **** **** **** **** +2281 ACP_Fighting_Stance_FENCING **** **** **** **** **** **** **** **** +2282 ACP_Fighting_Stance_NORMAL **** **** **** **** **** **** **** **** +2283 Undead_Wild_Shape_Master **** **** **** **** **** **** **** **** +2284 Undead_Wild_Shape_BROWN_BEAR **** **** **** **** **** **** **** **** +2285 Undead_Wild_Shape_PANTHER **** **** **** **** **** **** **** **** +2286 Undead_Wild_Shape_WOLF **** **** **** **** **** **** **** **** +2287 Undead_Wild_Shape_BOAR **** **** **** **** **** **** **** **** +2288 Undead_Wild_Shape_BADGER **** **** **** **** **** **** **** **** +2289 Ashrati_Bodylamp **** **** **** **** **** **** **** **** +2290 RAY_CHARM_PERSON **** **** **** **** **** **** **** **** +2291 RAY_CHARM_MONSTER **** **** **** **** **** **** **** **** +2292 RAY_SLEEP **** **** **** **** **** **** **** **** +2293 RAY_FLESH_TO_STONE **** **** **** **** **** **** **** **** +2294 RAY_DISINTIGRATE **** **** **** **** **** **** **** **** +2295 RAY_FEAR **** **** **** **** **** **** **** **** +2296 RAY_SLOW **** **** **** **** **** **** **** **** +2297 RAY_INFLICT_MODERATE_WOUNDS **** **** **** **** **** **** **** **** +2298 RAY_FINGER_OF_DEATH **** **** **** **** **** **** **** **** +2299 PsyRogue_BlindSpot **** **** **** **** **** **** **** **** +2300 SPELL_FOM_DIVINE_SONG_BLESS **** **** **** **** **** **** **** **** +2301 SPELL_FOM_DIVINE_SONG_CONVICTION **** **** **** **** **** **** **** **** +2302 SPELL_FOM_DIVINE_SONG_CURELIGHT **** **** **** **** **** **** **** **** +2303 SPELL_FOM_DIVINE_SONG_REMOVEFEAR **** **** **** **** **** **** **** **** +2304 SPELL_FOM_DIVINE_SONG_SANCTUARY **** **** **** **** **** **** **** **** +2305 SPELL_FOM_DIVINE_SONG_SHIELDFAITH **** **** **** **** **** **** **** **** +2306 SPELL_FOM_DIVINE_SONG_AID **** **** **** **** **** **** **** **** +2307 SPELL_FOM_DIVINE_SONG_BULLSTRENGTH **** **** **** **** **** **** **** **** +2308 SPELL_FOM_DIVINE_SONG_CUREMODERATE **** **** **** **** **** **** **** **** +2309 SPELL_FOM_DIVINE_SONG_EAGLESPLENDOR **** **** **** **** **** **** **** **** +2310 SPELL_FOM_DIVINE_SONG_ENDURANCE **** **** **** **** **** **** **** **** +2311 SPELL_FOM_DIVINE_SONG_FOXCUNNING **** **** **** **** **** **** **** **** +2312 SPELL_FOM_DIVINE_SONG_LESSRESTORE **** **** **** **** **** **** **** **** +2313 SPELL_FOM_DIVINE_SONG_OWLWISDOM **** **** **** **** **** **** **** **** +2314 SPELL_FOM_DIVINE_SONG_CLAIRVOYANCE **** **** **** **** **** **** **** **** +2315 SPELL_FOM_DIVINE_SONG_CLARITY **** **** **** **** **** **** **** **** +2316 SPELL_FOM_DIVINE_SONG_CURESERIOUS **** **** **** **** **** **** **** **** +2317 SPELL_FOM_DIVINE_SONG_NEGATIVEPROT **** **** **** **** **** **** **** **** +2318 SPELL_FOM_DIVINE_SONG_PRAYER **** **** **** **** **** **** **** **** +2319 SPELL_FOM_DIVINE_SONG_PROTELEMENTS **** **** **** **** **** **** **** **** +2320 SPELL_FOM_DIVINE_SONG_REMOVECURSE **** **** **** **** **** **** **** **** +2321 SPELL_FOM_DIVINE_SONG_CURECRITICAL **** **** **** **** **** **** **** **** +2322 SPELL_FOM_DIVINE_SONG_DEATHWARD **** **** **** **** **** **** **** **** +2323 SPELL_FOM_DIVINE_SONG_FREEDOMMOVEMENT **** **** **** **** **** **** **** **** +2324 SPELL_FOM_DIVINE_SONG_PANACEA **** **** **** **** **** **** **** **** +2325 SPELL_FOM_DIVINE_SONG_RESTORATION **** **** **** **** **** **** **** **** +2326 SPELL_FOM_DIVINE_SONG_STONESKIN **** **** **** **** **** **** **** **** +2327 SPELL_FOM_DIVINE_SONG_TRUESEEING **** **** **** **** **** **** **** **** +2328 SPELL_FOM_DIVINE_SONG_MONSTREGEN **** **** **** **** **** **** **** **** +2329 SPELL_FOM_DIVINE_SONG_RAISEDEAD **** **** **** **** **** **** **** **** +2330 SPELL_FOM_DIVINE_SONG_SPELLRESISTANCE **** **** **** **** **** **** **** **** +2331 SPELL_FOM_ENCOREPERFORMANCE **** **** **** **** **** **** **** **** +2332 Ashrati_BodylampDazzle **** **** **** **** **** **** **** **** +2333 Killoren_Aspect_A **** **** **** **** **** **** **** **** +2334 Killoren_Aspect_D **** **** **** **** **** **** **** **** +2335 Killoren_Aspect_H **** **** **** **** **** **** **** **** +2336 Killoren_Hunter **** **** **** **** **** **** **** **** +2337 Skarn_Spines **** **** **** **** **** **** **** **** +2338 ScorpionsGrasp **** **** **** **** **** **** **** **** +2339 CultistShatteredPeak_SmiteMage **** **** **** **** **** **** **** **** +2340 AwesomeBlow **** **** **** **** **** **** **** **** +2341 BloodedOne_War_Cry **** **** **** **** **** **** **** **** +2342 Desecrate **** **** **** **** **** **** **** **** +2343 BlastOfForce **** Fortitude 1 R 1 **** **** **** +2344 ShieldBash **** **** **** **** **** **** **** **** +2345 ShieldCharge **** **** **** **** **** **** **** **** +2346 ShieldSlam **** **** **** **** **** **** **** **** +2347 PhantomSteed **** **** **** **** **** **** **** **** +2348 GaseousForm **** **** **** **** **** **** **** **** +2349 begin_psionics **** **** **** **** **** **** **** **** +2350 Augment_QuickSelects **** **** **** **** **** **** **** **** +2351 Augment_Digits_0_4 **** **** **** **** **** **** **** **** +2352 Augment_Digits_5_9 **** **** **** **** **** **** **** **** +2353 Augment_Tens **** **** **** **** **** **** **** **** +2354 Augment_StartConvo **** **** **** **** **** **** **** **** +2355 Augment_Off **** **** **** **** **** **** **** **** +2356 Augment_ToggleMaxAugment **** **** **** **** **** **** **** **** +2357 Augment_Quickselect1 **** **** **** **** **** **** **** **** +2358 Augment_Quickselect2 **** **** **** **** **** **** **** **** +2359 Augment_0 **** **** **** **** **** **** **** **** +2360 Augment_1 **** **** **** **** **** **** **** **** +2361 Augment_2 **** **** **** **** **** **** **** **** +2362 Augment_3 **** **** **** **** **** **** **** **** +2363 Augment_4 **** **** **** **** **** **** **** **** +2364 Augment_5 **** **** **** **** **** **** **** **** +2365 Augment_6 **** **** **** **** **** **** **** **** +2366 Augment_7 **** **** **** **** **** **** **** **** +2367 Augment_8 **** **** **** **** **** **** **** **** +2368 Augment_9 **** **** **** **** **** **** **** **** +2369 Augment_00 **** **** **** **** **** **** **** **** +2370 Augment_10 **** **** **** **** **** **** **** **** +2371 Augment_20 **** **** **** **** **** **** **** **** +2372 Augment_30 **** **** **** **** **** **** **** **** +2373 Augment_40 **** **** **** **** **** **** **** **** +2374 Augment_QuickSelects_2 **** **** **** **** **** **** **** **** +2375 **** **** **** **** **** **** **** **** **** +2376 **** **** **** **** **** **** **** **** **** +2377 Wilder_WildSurge_Off **** **** **** **** **** **** **** **** +2378 Wilder_WildSurge_1-5_RadialMaster **** **** **** **** **** **** **** **** +2379 Wilder_WildSurge_6-10_RadialMaster **** **** **** **** **** **** **** **** +2380 Wilder_WildSurge_1 **** **** **** **** **** **** **** **** +2381 Wilder_WildSurge_2 **** **** **** **** **** **** **** **** +2382 Wilder_WildSurge_3 **** **** **** **** **** **** **** **** +2383 Wilder_WildSurge_4 **** **** **** **** **** **** **** **** +2384 Wilder_WildSurge_5 **** **** **** **** **** **** **** **** +2385 Wilder_WildSurge_6 **** **** **** **** **** **** **** **** +2386 Wilder_WildSurge_7 **** **** **** **** **** **** **** **** +2387 Wilder_WildSurge_8 **** **** **** **** **** **** **** **** +2388 Wilder_WildSurge_9 **** **** **** **** **** **** **** **** +2389 Wilder_WildSurge_10 **** **** **** **** **** **** **** **** +2390 Wilder_WildSurge_11 **** **** **** **** **** **** **** **** +2391 **** **** **** **** **** **** **** **** **** +2392 Augment_Quickselect3 **** **** **** **** **** **** **** **** +2393 Augment_Quickselect4 **** **** **** **** **** **** **** **** +2394 Augment_Quickselect5 **** **** **** **** **** **** **** **** +2395 Augment_Quickselect6 **** **** **** **** **** **** **** **** +2396 Augment_Quickselect7 **** **** **** **** **** **** **** **** +2397 **** **** **** **** **** **** **** **** **** +2398 Manifest_Shield_of_Thought **** **** **** **** **** **** **** **** +2399 Spiritual_Force **** **** **** **** **** **** **** **** +2400 Manifest_Mindblade **** **** **** **** **** **** **** **** +2401 Throw_Mindblade **** **** **** **** **** **** **** **** +2402 Psychic_Strike **** **** **** **** **** **** **** **** +2403 Free_Draw **** **** **** **** **** **** **** **** +2404 Shape_Mindblade_RadialMaster **** **** **** **** **** **** **** **** +2405 Shape_Mindblade_Shortsword **** **** **** **** **** **** **** **** +2406 Shape_Mindblade_2xShortsword **** **** **** **** **** **** **** **** +2407 Shape_Mindblade_Longsword **** **** **** **** **** **** **** **** +2408 Shape_Mindblade_Bastardsword **** **** **** **** **** **** **** **** +2409 Mindblade_Enhancement **** **** **** **** **** **** **** **** +2410 Bladewind **** **** **** **** **** **** **** **** +2411 KnifeToTheSoul_RadialMaster **** **** **** **** **** **** **** **** +2412 KnifeToTheSoul_Off **** **** **** **** **** **** **** **** +2413 KnifeToTheSoul_Intelligence **** **** **** **** **** **** **** **** +2414 KnifeToTheSoul_Wisdom **** **** **** **** **** **** **** **** +2415 KnifeToTheSoul_Charisma **** **** **** **** **** **** **** **** +2416 KnifeToTheSoul_DieRadial1_Radialmaster **** **** **** **** **** **** **** **** +2417 KnifeToTheSoul_1Die **** **** **** **** **** **** **** **** +2418 KnifeToTheSoul_2Die **** **** **** **** **** **** **** **** +2419 KnifeToTheSoul_3Die **** **** **** **** **** **** **** **** +2420 KnifeToTheSoul_4Die **** **** **** **** **** **** **** **** +2421 KnifeToTheSoul_5Die **** **** **** **** **** **** **** **** +2422 KnifeToTheSoul_DieRadial2_Radialmaster **** **** **** **** **** **** **** **** +2423 KnifeToTheSoul_6Die **** **** **** **** **** **** **** **** +2424 KnifeToTheSoul_7Die **** **** **** **** **** **** **** **** +2425 KnifeToTheSoul_8Die **** **** **** **** **** **** **** **** +2426 KnifeToTheSoul_9Die **** **** **** **** **** **** **** **** +2427 KnifeToTheSoul_10Die **** **** **** **** **** **** **** **** +2428 ChangeHandedness **** **** **** **** **** **** **** **** +2429 Mindblade_Lucky **** **** **** **** **** **** **** **** +2430 Healing_Kicker_1_Sanctuary **** **** **** **** **** **** **** **** +2431 Healing_Kicker_2_ReflexSaves **** **** **** **** **** **** **** **** +2432 Healing_Kicker_3_Aid **** **** **** **** **** **** **** **** +2433 Spontaneous_Heal **** **** **** **** **** **** **** **** +2434 StrengthOfTwo **** **** **** **** **** **** **** **** +2435 OotBI_RangedPrecision **** **** **** **** **** **** **** **** +2436 OotBI_GreaterWeaponFocus **** **** **** **** **** **** **** **** +2437 Thrallherd_Master **** **** **** **** **** **** **** **** +2438 Thrallherd_Fighter **** **** **** **** **** **** **** **** +2439 Thrallherd_Cleric **** **** **** **** **** **** **** **** +2440 Thrallherd_Rogue **** **** **** **** **** **** **** **** +2441 Thrallherd_Wizard **** **** **** **** **** **** **** **** +2442 PsionicCharm **** **** **** **** **** **** **** **** +2443 PsionicDominate **** **** **** **** **** **** **** **** +2444 Twofold_Master **** **** **** **** **** **** **** **** +2445 Twofold_Fighter **** **** **** **** **** **** **** **** +2446 Twofold_Cleric **** **** **** **** **** **** **** **** +2447 Twofold_Rogue **** **** **** **** **** **** **** **** +2448 Twofold_Wizard **** **** **** **** **** **** **** **** +2449 **** **** **** **** **** **** **** **** **** +2450 Warmind_PersSuperior **** **** **** **** **** **** **** **** +2451 Warmind_DefPosture **** **** **** **** **** **** **** **** +2452 Warmind_OverwhelmForce **** **** **** **** **** **** **** **** +2453 **** **** **** **** **** **** **** **** **** +2454 ShadowmindDistract **** **** **** **** **** **** **** **** +2455 ShadowmindCloudMind **** **** **** **** **** **** **** **** +2456 ShadowmindCloudMindMass **** **** **** **** **** **** **** **** +2457 ShadowmindMindStab **** **** **** **** **** **** **** **** +2458 **** **** **** **** **** **** **** **** **** +2459 DiamondDragon_Claws **** **** **** **** **** **** **** **** +2460 DiamondDragon_Breath **** **** **** **** **** **** **** **** +2461 DiamondDragon_Wings **** **** **** **** **** **** **** **** +2462 DiamondDragon_Tail **** **** **** **** **** **** **** **** +2463 DiamondDragon_Aura **** **** **** **** **** **** **** **** +2464 DiamondDragon_Breath_Cold **** **** **** **** **** **** **** **** +2465 DiamondDragon_Breath_Electric **** **** **** **** **** **** **** **** +2466 DiamondDragon_Breath_Fire **** **** **** **** **** **** **** **** +2467 DiamondDragon_Breath_Sonic **** **** **** **** **** **** **** **** +2468 Psionic_Paralysis_Sleep_Immunity **** **** **** **** **** **** **** **** +2469 **** **** **** **** **** **** **** **** **** +2470 FistOfDalQuor_StunningStrike **** **** **** **** **** **** **** **** +2471 **** **** **** **** **** **** **** **** **** +2472 ForestMaster_ForestDominion **** **** **** **** **** **** **** **** +2473 ForestMaster_GreatMalletRadialMaster **** **** **** **** **** **** **** **** +2474 ForestMaster_IcyMallet **** **** **** **** **** **** **** **** +2475 ForestMaster_ShockMallet **** **** **** **** **** **** **** **** +2476 ForestMaster_DeepRoots **** **** **** **** **** **** **** **** +2477 **** **** **** **** **** **** **** **** **** +2478 **** **** **** **** **** **** **** **** **** +2479 SPELL_CHASING_PERFECTION **** **** **** **** **** **** **** **** +2480 SPELL_FORCE_MISSILES **** **** 1 R 1 **** **** **** +2481 SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +2482 SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +2483 SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +2484 SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +2485 SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +2486 SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +2487 SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +2488 SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +2489 ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +2490 ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +2491 ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +2492 ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +2493 ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +2494 SPELL_DIVINE_SACRIFICE_2 **** **** **** **** **** **** **** **** +2495 SPELL_DIVINE_SACRIFICE_4 **** **** **** **** **** **** **** **** +2496 SPELL_DIVINE_SACRIFICE_6 **** **** **** **** **** **** **** **** +2497 SPELL_DIVINE_SACRIFICE_8 **** **** **** **** **** **** **** **** +2498 SPELL_DIVINE_SACRIFICE_10 **** **** **** **** **** **** **** **** +2499 Command_Undead **** **** **** **** **** **** **** **** +2500 SPELL_PRC_EXTRA_STUNNING **** **** **** **** **** **** **** **** +2501 SPELL_EF_FIST_OF_ENERGY **** **** **** **** **** **** **** **** +2502 SPELL_EF_FIST_OF_ENERGY_FIRE **** **** **** **** **** **** **** **** +2503 SPELL_EF_FIST_OF_ENERGY_ELECTRICITY **** **** **** **** **** **** **** **** +2504 SPELL_EF_SPELL_SELECT **** **** **** **** **** **** **** **** +2505 SPELL_EF_SPELL_SELECT_CONVO **** **** **** **** **** **** **** **** +2506 SPELL_EF_SPELL_SELECT_QUICK1 **** **** **** **** **** **** **** **** +2507 SPELL_EF_SPELL_SELECT_QUICK2 **** **** **** **** **** **** **** **** +2508 SPELL_EF_SPELL_SELECT_QUICK3 **** **** **** **** **** **** **** **** +2509 SPELL_EF_SPELL_SELECT_QUICK4 **** **** **** **** **** **** **** **** +2510 SPELL_EF_ARCANE_FIST **** **** **** **** **** **** **** **** +2511 SPELL_EF_ARCANE_REJUVENATION **** **** **** **** **** **** **** **** +2512 ABERRATE **** **** **** **** **** **** **** **** +2513 ABSORB_STRENGTH **** **** **** **** **** **** **** **** +2514 ABYSSAL_MIGHT **** **** **** E 0 3 0 **** +2515 ANGRY_ACHE **** Fortitude 1 R 1 **** **** **** +2516 APOCALYPSE_FROM_THE_SKY **** **** **** **** **** **** **** **** +2517 APOCALYPSE_FROM_THE_SKY_FIRE **** **** **** **** **** **** **** **** +2518 APOCALYPSE_FROM_THE_SKY_ACID **** **** **** **** **** **** **** **** +2519 APOCALYPSE_FROM_THE_SKY_SONIC **** **** **** **** **** **** **** **** +2520 BESTOW_WOUND **** Fortitude 1 T 1 **** **** **** +2521 BODAK_BIRTH **** **** **** **** **** **** **** **** +2522 BONEBLADE **** **** **** **** **** **** **** **** +2523 BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +2524 BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +2525 BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +2526 BONEBLAST **** Fortitude 1 T 1 **** **** **** +2527 CALL_DRETCH_HORDE **** **** **** **** **** **** **** **** +2528 CALL_LEMURE_HORDE **** **** **** **** **** **** **** **** +2529 CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +2530 CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +2531 CLOUD_OF_THE_ACHAIERAI **** Fortitude 1 I 1 **** **** **** +2532 CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +2533 CRUSHING_FIST_OF_SPITE **** Reflex 1 I 1 **** **** **** +2534 CURSE_OF_THE_PUTRID_HUSK Fear Will 1 R 1 **** **** **** +2535 DAMNING_DARKNESS **** **** **** I 1 **** **** **** +2536 DEATH_BY_THORNS **** **** **** **** **** **** **** **** +2537 DEMONCALL **** **** **** **** **** **** **** **** +2538 DEMONFLESH **** **** **** **** **** **** **** **** +2539 DESPOIL **** **** **** **** **** **** **** **** +2540 DEVILS_EGO **** **** **** **** **** **** **** **** +2541 DEVILS_EYE **** **** **** **** **** **** **** **** +2542 DEVILS_TAIL **** **** **** **** **** **** **** **** +2543 DREAD_WORD **** **** **** **** **** **** **** **** +2544 DRUG_RESISTANCE **** **** **** **** **** **** **** **** +2545 ECTOPLASMIC_ENCHANCEMENT **** **** **** **** **** **** **** **** +2546 ETERNITY_OF_TORTURE **** **** **** **** **** **** **** **** +2547 EVIL_EYE **** Will 1 R 1 **** **** **** +2548 EYE_OF_THE_BEHOLDER **** **** **** **** **** **** **** **** +2549 EVIL_WEATHER **** **** **** **** **** **** **** **** +2550 EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +2551 EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +2552 EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +2553 EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +2554 EXTRACT_DRUG **** **** **** **** **** **** **** **** +2555 EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +2556 EXTRACT_VODARE **** **** **** **** **** **** **** **** +2557 EXTRACT_SANNISH **** **** **** **** **** **** **** **** +2558 EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +2559 FANGS_OF_THE_VAMPIRE_KING **** **** **** **** **** **** **** **** +2560 FIENDISH_CLARITY **** **** **** E 0 3 0 **** +2561 FLESH_ARMOR **** **** **** **** **** **** **** **** +2562 FLESH_RIPPER **** **** 1 R 1 **** **** **** +2563 GRIM_REVENGE **** Fortitude 1 R 1 **** **** **** +2564 GUTWRENCH Death Fortitude 1 R 1 **** **** **** +2565 HEARTACHE Mind_Affecting Will 1 R 1 **** **** **** +2566 HEARTCLUTCH **** Fortitude 1 R 1 **** **** **** +2567 HELLFIRE **** **** **** **** **** **** **** **** +2568 HELLFIRE_STORM **** **** **** **** **** **** **** **** +2569 HELLS_POWER **** **** **** **** **** **** **** **** +2570 LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +2571 LIQUID_PAIN **** **** **** **** **** **** **** **** +2572 MORALITY_UNDONE **** **** **** **** **** **** **** **** +2573 POWER_LEECH **** **** **** **** **** **** **** **** +2574 RAPTURE_OF_RUPTURE **** **** **** **** **** **** **** **** +2575 REALITY_BLIND Mind_Affecting Will 1 R 1 **** **** **** +2576 RED_FESTER **** **** **** **** **** **** **** **** +2577 RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +2578 ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +2579 SEETHING_EYEBANE **** **** **** **** **** **** **** **** +2580 SHRIVELING Negative Reflex 1 R 1 **** **** **** +2581 SONG_OF_FESTERING_DEATH **** Fortitude 1 R 1 **** **** **** +2582 SORROW Mind_Affecting Will 1 R 1 **** **** **** +2583 EXALTED_RAIMENT **** **** **** **** **** **** **** **** +2584 SPORES_OF_THE_VROCK **** Fortitude 1 I 1 **** **** **** +2585 STUNNING_SCREECH **** Fortitude 1 I 1 **** **** **** +2586 STOP_HEART **** Fortitude 1 R 1 **** **** **** +2587 THOUSAND_NEEDLES **** Fortitude 1 R 1 **** **** **** +2588 TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +2589 TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +2590 UNHEAVENED **** **** **** P 0 3 14 **** +2591 UNLIVING_WEAPON **** **** **** **** **** **** **** **** +2592 UTTERDARK **** **** **** I 1 **** **** **** +2593 WAVE_OF_GRIEF Mind_Affecting Will 1 I 1 **** **** **** +2594 WAVE_OF_PAIN **** Fortitude 1 I 1 **** **** **** +2595 WRACK **** Fortitude 1 I 1 **** **** **** +2596 WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +2597 AGONY **** **** **** **** **** **** **** **** +2598 BACCARAN **** **** **** **** **** **** **** **** +2599 DEVILWEED **** **** **** **** **** **** **** **** +2600 LUHIX **** **** **** **** **** **** **** **** +2601 MUSHROOM_POWDER **** **** **** **** **** **** **** **** +2602 SANNISH **** **** **** **** **** **** **** **** +2603 TERRAN_BRANDY **** **** **** **** **** **** **** **** +2604 VODARE **** **** **** **** **** **** **** **** +2605 LESSER_SHIVERING_TOUCH **** **** 1 R 1 **** **** **** +2606 SHIVERING_TOUCH **** **** 1 R 1 **** **** **** +2607 AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +2608 BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +2609 DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +2610 DIAMOND_SPRAY **** **** **** **** **** **** **** **** +2611 DRAGON_CLOUD **** **** **** **** **** **** **** **** +2612 EXALTED_FURY **** **** **** **** **** **** **** **** +2613 HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +2614 PHIERANS_RESOLVE **** **** **** **** **** **** **** **** +2615 PHOENIX_FIRE **** **** **** **** **** **** **** **** +2616 RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +2617 SICKEN_EVIL **** **** **** **** **** **** **** **** +2618 STORM_OF_SHARDS **** **** **** **** **** **** **** **** +2619 SUNMANTLE **** **** **** **** **** **** **** **** +2620 TWILIGHT_LUCK **** **** **** **** **** **** **** **** +2621 AMBER_SARCOPHAGUS **** **** 1 R 1 **** **** **** +2622 BLINDING_GLORY **** **** **** I 1 **** **** **** +2623 BOLT_OF_GLORY **** **** **** **** **** **** **** **** +2624 CALL_FAITHFUL_SERVANTS **** **** **** S 0 2 0 **** +2625 CELESTIAL_BLOOD **** **** **** P 0 2 7 **** +2626 CHAAVS_LAUGH **** Will 1 D 1 **** **** **** +2627 CONVERT_WAND **** **** **** **** **** **** **** **** +2628 DANCING_WEB **** Reflex 1 I 1 **** **** **** +2629 DIVINE_SACRIFICE **** **** **** **** **** **** **** **** +2630 ELATION **** **** **** E 0 2 0 **** +2631 ENERGIZE_POTION **** **** **** **** **** **** **** **** +2632 EYES_OF_THE_AVORAL **** **** **** E 0 3 5 **** +2633 VisionOfGlory **** **** **** **** **** **** **** **** +2634 LANTERN_LIGHT **** **** 1 R 1 **** **** **** +2635 LAST_JUDGEMENT **** **** **** **** **** **** **** **** +2636 LUMINOUS_ARMOR **** **** **** P 0 3 8 -3 +2637 GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +2638 RAIN_OF_BLACK_TULIPS **** **** **** **** **** **** **** **** +2639 RAIN_OF_ROSES **** **** **** **** **** **** **** **** +2640 RAY_OF_HOPE **** **** **** E 0 2 9 **** +2641 RIGHTEOUS_SMITE **** Will 1 I 1 **** **** **** +2642 STARMANTLE **** **** **** P 0 2 7 **** +2643 TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +2644 MASOCHISM **** **** **** E 0 2 0 **** +2645 ADDICTION **** **** **** **** **** **** **** **** +2646 ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +2647 ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +2648 ADDICTION_VODARE **** **** **** **** **** **** **** **** +2649 ADDICTION_AGONY **** **** **** **** **** **** **** **** +2650 **StartDomainReserver** **** **** **** **** **** **** **** **** +2651 Sun_Domain_Power **** **** **** **** **** **** **** **** +2652 **** **** **** **** **** **** **** **** **** +2653 **** **** **** **** **** **** **** **** **** +2654 **** **** **** **** **** **** **** **** **** +2655 **** **** **** **** **** **** **** **** **** +2656 **** **** **** **** **** **** **** **** **** +2657 **** **** **** **** **** **** **** **** **** +2658 **** **** **** **** **** **** **** **** **** +2659 **** **** **** **** **** **** **** **** **** +2660 **** **** **** **** **** **** **** **** **** +2661 **** **** **** **** **** **** **** **** **** +2662 **** **** **** **** **** **** **** **** **** +2663 **** **** **** **** **** **** **** **** **** +2664 **** **** **** **** **** **** **** **** **** +2665 **** **** **** **** **** **** **** **** **** +2666 **** **** **** **** **** **** **** **** **** +2667 **** **** **** **** **** **** **** **** **** +2668 **** **** **** **** **** **** **** **** **** +2669 **** **** **** **** **** **** **** **** **** +2670 **** **** **** **** **** **** **** **** **** +2671 **** **** **** **** **** **** **** **** **** +2672 **** **** **** **** **** **** **** **** **** +2673 **** **** **** **** **** **** **** **** **** +2674 **** **** **** **** **** **** **** **** **** +2675 **** **** **** **** **** **** **** **** **** +2676 **** **** **** **** **** **** **** **** **** +2677 **** **** **** **** **** **** **** **** **** +2678 **** **** **** **** **** **** **** **** **** +2679 **** **** **** **** **** **** **** **** **** +2680 **** **** **** **** **** **** **** **** **** +2681 **** **** **** **** **** **** **** **** **** +2682 **** **** **** **** **** **** **** **** **** +2683 **** **** **** **** **** **** **** **** **** +2684 **** **** **** **** **** **** **** **** **** +2685 **** **** **** **** **** **** **** **** **** +2686 **** **** **** **** **** **** **** **** **** +2687 **** **** **** **** **** **** **** **** **** +2688 **** **** **** **** **** **** **** **** **** +2689 **** **** **** **** **** **** **** **** **** +2690 **EndDomainReserver** **** **** **** **** **** **** **** **** +2691 end_psionics **** **** **** **** **** **** **** **** +2692 BATTLE_RAGE **** **** **** **** **** **** **** **** +2693 Teleport_Management_Radial_Master **** **** **** **** **** **** **** **** +2694 Teleport_Mark_Location **** **** **** **** **** **** **** **** +2695 Teleport_Options_Dialog **** **** **** **** **** **** **** **** +2696 Teleport_End_Quickselect **** **** **** **** **** **** **** **** +2697 Teleport_Quickselect_1 **** **** **** **** **** **** **** **** +2698 Teleport_Quickselect_2 **** **** **** **** **** **** **** **** +2699 PnP_Scry_Familiar **** **** **** **** **** **** **** **** +2700 FRENZY **** **** **** **** **** **** **** **** +2701 INSPIRE_FRENZY **** **** **** **** **** **** **** **** +2702 (*Deprecated*)SUPREME_POWER_ATTACK **** **** **** **** **** **** **** **** +2703 REMOVE_FRENZY **** **** **** **** **** **** **** **** +2704 PnP_Familiar **** **** **** **** **** **** **** **** +2705 Frostrager_OneTwoPunch **** **** **** **** **** **** **** **** +2706 RANCOR **** **** **** **** **** **** **** **** +2707 FH_DEATH_ATTACK **** **** **** **** **** **** **** **** +2708 COMMAND_THE_HORDE **** **** **** **** **** **** **** **** +2709 BLINDING_SPITTLE **** **** **** **** **** **** **** **** +2710 BLINDSIGHT_5_FT **** **** **** **** **** **** **** **** +2711 BLINDSIGHT_10_FT **** **** **** **** **** **** **** **** +2712 OW_INSPIRE_COURAGE **** **** **** **** **** **** **** **** +2713 FINAL_RAGE **** **** **** **** **** **** **** **** +2714 RELEASE_HORDE **** **** **** **** **** **** **** **** +2715 GATHER_HORDE_I **** **** **** **** **** **** **** **** +2716 GATHER_HORDE_II **** **** **** **** **** **** **** **** +2717 Gather_Skull_Splitter **** **** **** **** **** **** **** **** +2718 Gather_Weapon_Master **** **** **** **** **** **** **** **** +2719 Gather_Axe_Thrower **** **** **** **** **** **** **** **** +2720 Gather_Shaman **** **** **** **** **** **** **** **** +2721 BLOOD_OF_THE_WARLORD **** **** **** **** **** **** **** **** +2722 Dirge_Sorrow **** **** **** **** **** **** **** **** +2723 InlindlSchool **** **** **** **** **** **** **** **** +2724 SpinningHalberd **** **** **** **** **** **** **** **** +2725 Shou_Flurry_Light **** **** **** **** **** **** **** **** +2726 Shou_Flurry_All **** **** **** **** **** **** **** **** +2727 FEAT_JUMP **** **** **** **** **** **** **** **** +2728 Battlerager_damage **** **** **** **** **** **** **** **** +2729 Hextor_damage **** **** **** **** **** **** **** **** +2730 Thayanknight_damage **** **** **** **** **** **** **** **** +2731 Man_at_arms_damage **** **** **** **** **** **** **** **** +2732 SetCompositeAttackBonus **** **** **** **** **** **** **** **** +2733 KnightChalice_damage **** **** **** **** **** **** **** **** +2734 UnarmedAttackPenetration **** **** **** **** **** **** **** **** +2735 SPELL_TOG_CHARM **** **** **** **** **** **** **** **** +2736 TOG_SUMMON_DEMON **** **** **** **** **** **** **** **** +2737 TOG_SUMMON_SUCCUBUS **** **** **** **** **** **** **** **** +2738 TOG_SUMMON_VROCK **** **** **** **** **** **** **** **** +2739 TOG_SUMMON_GLABREZU **** **** **** **** **** **** **** **** +2740 TOG_SUMMON_MARILITH **** **** **** **** **** **** **** **** +2741 TOG_SUMMON_BALOR **** **** **** **** **** **** **** **** +2742 Ninja_Ghost_Step **** **** **** **** **** **** **** **** +2743 Ninja_Ghost_Strike **** **** **** **** **** **** **** **** +2744 Ninja_Ghost_walk **** **** **** **** **** **** **** **** +2745 Ninja_Greater_Ki_Dodge **** **** **** **** **** **** **** **** +2746 Ninja_Ki_Dodge **** **** **** **** **** **** **** **** +2747 Ninja_Ghost_Step_2 **** **** **** **** **** **** **** **** +2748 SlayerOfDomielDivineGrace **** **** **** **** **** **** **** **** +2749 FEAT_CLIMB **** **** **** **** **** **** **** **** +2750 Unmovable **** **** **** **** **** **** **** **** +2751 Unstoppable **** **** **** **** **** **** **** **** +2752 Beguiling_Nature **** **** **** **** **** **** **** **** +2753 Suggestion **** **** **** **** **** **** **** **** +2754 Baal_Summon_1 **** **** **** **** **** **** **** **** +2755 Baal_Summon_2 **** **** **** **** **** **** **** **** +2756 Insect_Plague **** **** **** **** **** **** **** **** +2757 IAIJUTSU_FINESSE **** **** **** **** **** **** **** **** +2758 Iaijutsu_Attack **** **** **** **** **** **** **** **** +2759 Iaijutsu_Spirit_Stike **** **** **** **** **** **** **** **** +2760 Iaijutsu_Echo_Edge **** **** **** **** **** **** **** **** +2761 Iaijutsu_Two_Cuts **** **** **** **** **** **** **** **** +2762 Iron_Hews **** **** **** **** **** **** **** **** +2763 Rusting_Grasp **** **** **** **** **** **** **** **** +2764 Summon_Erinyes **** **** **** **** **** **** **** **** +2765 Greater_Hews **** **** **** **** **** **** **** **** +2766 Iron_Skin **** **** **** **** **** **** **** **** +2767 Iron_Body **** **** **** **** **** **** **** **** +2768 Pain_Touch **** **** **** **** **** **** **** **** +2769 Cruelest_Cut **** **** **** **** **** **** **** **** +2770 Rava_Aura **** **** **** **** **** **** **** **** +2771 Visage_Terror **** **** **** **** **** **** **** **** +2772 Kiai_Smite **** **** **** **** **** **** **** **** +2773 Staredown **** **** **** **** **** **** **** **** +2774 Mass_Staredown **** **** **** **** **** **** **** **** +2775 WeaponAndTorch **** **** **** **** **** **** **** **** +2776 Contact_Shadowlords **** **** **** **** **** **** **** **** +2777 Scribe_Runescar **** **** **** **** **** **** **** **** +2778 LH_Scribe **** **** **** **** **** **** **** **** +2779 RH_Scribe **** **** **** **** **** **** **** **** +2780 LA_Scribe **** **** **** **** **** **** **** **** +2781 RA_Scribe **** **** **** **** **** **** **** **** +2782 LC_Scribe **** **** **** **** **** **** **** **** +2783 RC_Scribe **** **** **** **** **** **** **** **** +2784 F_Scribe **** **** **** **** **** **** **** **** +2785 Rune_Bers **** **** **** **** **** **** **** **** +2786 Blight_Touch **** **** **** **** **** **** **** **** +2787 SE_Soul_Radiance **** **** **** **** **** **** **** **** +2788 SE_Energy_Drain **** **** **** **** **** **** **** **** +2789 SE_Soul_Blast **** **** **** **** **** **** **** **** +2790 BlightMind **** **** **** **** **** **** **** **** +2791 AnvilofThunder **** **** **** **** **** **** **** **** +2792 HammersEdge **** **** **** **** **** **** **** **** +2793 HighSwordLowAxe **** **** **** **** **** **** **** **** +2794 PowerAttack_Quick_Radial **** **** **** **** **** **** **** **** +2795 PowerAttack_ChangeQuickselect **** **** **** **** **** **** **** **** +2796 PowerAttack_Off **** **** **** **** **** **** **** **** +2797 PowerAttack_Quickslot_1 **** **** **** **** **** **** **** **** +2798 PowerAttack_Quickslot_2 **** **** **** **** **** **** **** **** +2799 PowerAttack_Quickslot_3 **** **** **** **** **** **** **** **** +2800 PsionicFocus_RadialMaster **** **** **** **** **** **** **** **** +2801 CloakDance **** **** **** **** **** **** **** **** +2802 RecklessOffense **** **** **** **** **** **** **** **** +2803 MentalLeap **** **** **** **** **** **** **** **** +2804 PowerPenetration **** **** **** **** **** **** **** **** +2805 GreaterPowerPenetration **** **** **** **** **** **** **** **** +2806 PowerSpecialization **** **** **** **** **** **** **** **** +2807 PsionicEndowment **** **** **** **** **** **** **** **** +2808 GreaterPsionicEndowment **** **** **** **** **** **** **** **** +2809 PsionicFist **** **** **** **** **** **** **** **** +2810 GreaterPsionicFist **** **** **** **** **** **** **** **** +2811 PsionicWeapon **** **** **** **** **** **** **** **** +2812 GreaterPsionicWeapon **** **** **** **** **** **** **** **** +2813 PsionicShot **** **** **** **** **** **** **** **** +2814 GreaterPsionicShot **** **** **** **** **** **** **** **** +2815 OverchannelRadialMaster **** **** **** **** **** **** **** **** +2816 OverchannelOff **** **** **** **** **** **** **** **** +2817 Overchannel_1 **** **** **** **** **** **** **** **** +2818 Overchannel_2 **** **** **** **** **** **** **** **** +2819 Overchannel_3 **** **** **** **** **** **** **** **** +2820 SpeedOfThought_Applying **** **** **** **** **** **** **** **** +2821 Talented **** **** **** **** **** **** **** **** +2822 Psionic_Meditation **** **** **** **** **** **** **** **** +2823 UnavoidableStrike **** **** **** **** **** **** **** **** +2824 WoundingAttackRadialMaster **** **** **** **** **** **** **** **** +2825 WoundingAttackMelee **** **** **** **** **** **** **** **** +2826 WoundingAttackRanged **** **** **** **** **** **** **** **** +2827 DeepImpact **** **** **** **** **** **** **** **** +2828 FellShot **** **** **** **** **** **** **** **** +2829 Metapsi_ChainPower **** **** **** **** **** **** **** **** +2830 Metapsi_EmpowerPower **** **** **** **** **** **** **** **** +2831 Metapsi_ExtendPower **** **** **** **** **** **** **** **** +2832 Metapsi_MaximizePower **** **** **** **** **** **** **** **** +2833 Metapsi_SplitPsionicRay **** **** **** **** **** **** **** **** +2834 Metapsi_TwinPower **** **** **** **** **** **** **** **** +2835 Metapsi_WidenPower **** **** **** **** **** **** **** **** +2836 PsionicFocus_Gain **** **** **** **** **** **** **** **** +2837 PsionicFocus_TurnOffAllFocusUsingAbilities **** **** **** **** **** **** **** **** +2838 Metapsi_QuickenPower **** **** **** **** **** **** **** **** +2839 Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +2840 Disguise_Self_Learn **** **** **** **** **** **** **** **** +2841 Disguise_Self_Options **** **** **** **** **** **** **** **** +2842 Disguise_Self_QS1 **** **** **** **** **** **** **** **** +2843 Disguise_Self_QS2 **** **** **** **** **** **** **** **** +2844 Disguise_Self_QS3 **** **** **** **** **** **** **** **** +2845 Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +2846 Alter_Self_Learn **** **** **** **** **** **** **** **** +2847 Alter_Self_Options **** **** **** **** **** **** **** **** +2848 Alter_Self_QS1 **** **** **** **** **** **** **** **** +2849 Alter_Self_QS2 **** **** **** **** **** **** **** **** +2850 Alter_Self_QS3 **** **** **** **** **** **** **** **** +2851 Avasculate **** Fortitude 1 R 1 **** **** **** +2852 Avascular_Mass **** Fortitude 1 I 1 **** **** **** +2853 Mass_Aid **** **** **** E 0 2 0 **** +2854 Necrotic_Awareness **** **** **** **** **** **** **** **** +2855 Necrotic_Cyst **** **** **** **** **** **** **** **** +2856 Necrotic_Bloat **** **** **** **** **** **** **** **** +2857 Necrotic_Domination **** **** **** **** **** **** **** **** +2858 Necrotic_Burst **** **** **** **** **** **** **** **** +2859 Necrotic_Eruption **** **** **** **** **** **** **** **** +2860 Necrotic_Empowerment **** **** **** **** **** **** **** **** +2861 Necrotic_Termination **** **** **** **** **** **** **** **** +2862 Ghoul_Gauntlet Death Fortitude 1 T 1 **** **** **** +2863 Energy_Ebb Level_Drain Fortitude 1 R 1 **** **** **** +2864 Nights_Caress **** Fortitude 1 T 1 **** **** **** +2865 Agony **** **** **** **** **** **** **** **** +2866 Baccaran **** **** **** **** **** **** **** **** +2867 Devilweed **** **** **** **** **** **** **** **** +2868 Luhix **** **** **** **** **** **** **** **** +2869 Mushroom_Powder **** **** **** **** **** **** **** **** +2870 Sannish **** **** **** **** **** **** **** **** +2871 Terran_Brandy **** **** **** **** **** **** **** **** +2872 Vodare **** **** **** **** **** **** **** **** +2873 ThrowEnergizedPotion **** **** **** **** **** **** **** **** +2874 Teleport_RadialMaster **** **** **** **** **** **** **** **** +2875 Teleport_SelfOnly **** **** **** **** **** **** **** **** +2876 Teleport_Party **** **** **** **** **** **** **** **** +2877 TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +2878 TeleportationCircle_Visible **** **** **** **** **** **** **** **** +2879 TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +2880 PoisonedWeapon **** **** **** **** **** **** **** **** +2881 Grenade_Poisonvial **** **** **** **** **** **** **** **** +2882 Poison_Weapon **** **** **** **** **** **** **** **** +2883 Poison_Item **** **** **** **** **** **** **** **** +2884 Poison_Food **** **** **** **** **** **** **** **** +2885 Clean_Poison_Off **** **** **** **** **** **** **** **** +2886 Pox **** Fortitude 1 I 1 **** **** **** +2887 Pestilence Disease Fortitude 1 T 1 **** **** **** +2888 Maze **** **** 1 R 1 **** **** **** +2889 Dimensional_Anchor **** **** **** **** **** **** **** **** +2890 DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +2891 DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +2892 DimensionDoor_Party **** **** **** **** **** **** **** **** +2893 GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +2894 GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +2895 GreaterTeleport_Party **** **** **** **** **** **** **** **** +2896 DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +2897 DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +2898 Dimensional_Lock **** **** **** **** **** **** **** **** +2899 End_Projection **** **** **** **** **** **** **** **** +2900 Wolf_From **** **** **** **** **** **** **** **** +2901 Werewolf_Form **** **** **** **** **** **** **** **** +2902 PROJECTION **** **** **** **** **** **** **** **** +2903 BAELNORN_TOUCH **** **** **** **** **** **** **** **** +2904 Wolf_Empathy **** **** **** **** **** **** **** **** +2905 FEAT_HOUND_AURAMENACE **** **** **** **** **** **** **** **** +2906 FEAT_RACE_WEB **** **** **** **** **** **** **** **** +2907 FEAT_RACE_MINOR_SHAPE_CHANGE **** **** **** **** **** **** **** **** +2908 FEAT_CHANGELING_QUICK_CHANGE **** **** **** **** **** **** **** **** +2909 Quick_Change_Learn **** **** **** **** **** **** **** **** +2910 Quick_Change_Options **** **** **** **** **** **** **** **** +2911 Quick_Change_True **** **** **** **** **** **** **** **** +2912 Quick_Change_QS1 **** **** **** **** **** **** **** **** +2913 Quick_Change_QS2 **** **** **** **** **** **** **** **** +2914 Grig_Pyrotechnics **** **** **** **** **** **** **** **** +2915 Grig_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +2916 Grig_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +2917 Bralani_Lightning_Bolt **** **** **** **** **** **** **** **** +2918 Bralani_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +2919 Bralani_Gust_of_Wind **** **** **** **** **** **** **** **** +2920 Bralani_Mirror_Image **** **** **** **** **** **** **** **** +2921 CrusaderReadyManeuver **** **** **** **** **** **** **** **** +2922 FEAT_RACE_FLARE **** **** **** **** **** **** **** **** +2923 SwordsageReadyManeuver **** **** **** **** **** **** **** **** +2924 Faerie_Fire **** **** **** **** **** **** **** **** +2925 FEAT_RACE_CONEOFCOLD **** **** **** **** **** **** **** **** +2926 WarbladeReadyManeuver **** **** **** **** **** **** **** **** +2927 FEAT_RACE_CHAINLIGHT **** **** **** **** **** **** **** **** +2928 FEAT_RACE_CALLLIGHT **** **** **** **** **** **** **** **** +2929 FEAT_RACE_BLESS **** **** **** **** **** **** **** **** +2930 FEAT_HOUND_AID **** **** **** **** **** **** **** **** +2931 WarbladeRecoverManeuver **** **** **** **** **** **** **** **** +2932 FEAT_HOUND_CONTFLAME **** **** **** **** **** **** **** **** +2933 FEAT_HOUND_DETECTEVIL **** **** **** **** **** **** **** **** +2934 FEAT_HOUND_MAGICCIRCLE **** **** **** **** **** **** **** **** +2935 FEAT_HOUND_TELEPORT **** **** **** **** **** **** **** **** +2936 FEAT_HOUND_DISGUISE **** **** **** **** **** **** **** **** +2937 FEAT_ZENYTH_TRUE_STRIKE **** **** **** **** **** **** **** **** +2938 Racial_Magic_Circle_vs_Good **** **** **** **** **** **** **** **** +2939 Racial_Magic_Circle_vs_Evil **** **** **** **** **** **** **** **** +2940 Racial_Magic_Circle_vs_Law **** **** **** **** **** **** **** **** +2941 Racial_Magic_Circle_vs_Chaos **** **** **** **** **** **** **** **** +2942 Racial_Magic_Circle_against_Alignment **** **** **** **** **** **** **** **** +2943 FEAT_NATHRI_EXP_RETREAT **** **** **** **** **** **** **** **** +2944 FEAT_BLADELING_RAZOR_STORM **** **** **** **** **** **** **** **** +2945 Racial_Detect_Good **** **** **** **** **** **** **** **** +2946 Racial_Detect_Law **** **** **** **** **** **** **** **** +2947 Kapak_Saliva_Application **** **** **** **** **** **** **** **** +2948 OnHit_Kapak_Saliva **** **** **** **** **** **** **** **** +2949 Shifter_Shifting **** **** **** **** **** **** **** **** +2950 FEAT_FEYRI_CHANGE_SHAPE **** **** **** **** **** **** **** **** +2951 Feyri_Select_Form **** **** **** **** **** **** **** **** +2952 Feyri_Options **** **** **** **** **** **** **** **** +2953 Feyri_True_Form **** **** **** **** **** **** **** **** +2954 Feyri_Quickslot_1 **** **** **** **** **** **** **** **** +2955 Feyri_Quickslot_2 **** **** **** **** **** **** **** **** +2956 Nymph_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +2957 Nymph_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +2958 Nymph_DimensionDoor_Party **** **** **** **** **** **** **** **** +2959 Nymph_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +2960 Nymph_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +2961 FEAT_RAK_CHANGE_SHAPE **** **** **** **** **** **** **** **** +2962 Raksahsa_Select_Form **** **** **** **** **** **** **** **** +2963 Raksahsa_Options **** **** **** **** **** **** **** **** +2964 Rakshasa_True_Form **** **** **** **** **** **** **** **** +2965 Rakshasa_Quickslot_1 **** **** **** **** **** **** **** **** +2966 Rakshasa_Quickslot_2 **** **** **** **** **** **** **** **** +2967 Forestlord_Treewalk_Selected **** **** **** **** **** **** **** **** +2968 Forestlord_Treewalk_Dirdist **** **** **** **** **** **** **** **** +2969 Glimmerskin_Touch_of_Luck **** **** **** **** **** **** **** **** +2970 Forestlord_Treewalk_Master_Radial **** **** **** **** **** **** **** **** +2971 Daylight **** **** **** **** 0 3 0 -15 +2972 Clinging_Breath **** **** **** **** **** **** **** **** +2973 Clinging_Conv **** **** **** **** **** **** **** **** +2974 Clinging_Off **** **** **** **** **** **** **** **** +2975 Clinging_QS1 **** **** **** **** **** **** **** **** +2976 Clinging_QS2 **** **** **** **** **** **** **** **** +2977 Clinging_QS3 **** **** **** **** **** **** **** **** +2978 Lingering_Breath **** **** **** **** **** **** **** **** +2979 Lingering_Conv **** **** **** **** **** **** **** **** +2980 Lingering_Off **** **** **** **** **** **** **** **** +2981 Lingering_QS1 **** **** **** **** **** **** **** **** +2982 Lingering_QS2 **** **** **** **** **** **** **** **** +2983 Lingering_QS3 **** **** **** **** **** **** **** **** +2984 Heighten_Breath **** **** **** **** **** **** **** **** +2985 Heighten_Conv **** **** **** **** **** **** **** **** +2986 Heighten_Off **** **** **** **** **** **** **** **** +2987 Heighten_QS1 **** **** **** **** **** **** **** **** +2988 Heighten_QS2 **** **** **** **** **** **** **** **** +2989 Heighten_Max **** **** **** **** **** **** **** **** +2990 Exhale_Barrier **** **** **** **** **** **** **** **** +2991 Spreading_Breath **** **** **** **** **** **** **** **** +2992 Tempest_Breath **** **** **** **** **** **** **** **** +2993 Exhale_Immunity **** **** **** **** **** **** **** **** +2994 Enlarge_Breath **** **** **** **** **** **** **** **** +2995 Maximize_Breath **** **** **** **** **** **** **** **** +2996 Exhale_Immunity **** **** **** **** **** **** **** **** +2997 Shape_Breath **** **** **** **** **** **** **** **** +2998 Poison_Weapon **** **** **** **** **** **** **** **** +2999 Avenging_Strike **** **** **** **** **** **** **** **** +3000 HellFire_Grasp **** **** **** **** **** **** **** **** +3001 Hellfire_Blast **** **** **** **** **** **** **** **** +3002 Hellfire_Flare **** **** **** **** **** **** **** **** +3003 Summon_Hamatula **** **** **** **** **** **** **** **** +3004 HellFire **** **** **** **** **** **** **** **** +3005 Fire_Shield **** **** **** **** **** **** **** **** +3006 HellFire_Storm **** **** **** **** **** **** **** **** +3007 Body_of_Fire **** **** **** **** **** **** **** **** +3008 Disciple_of_Darkness **** **** **** **** **** **** **** **** +3009 MOS_Summon **** **** **** **** **** **** **** **** +3010 MOS_Summon **** **** **** **** **** **** **** **** +3011 MOS_Summon **** **** **** **** **** **** **** **** +3012 MOS_Summon **** **** **** **** **** **** **** **** +3013 SPELL_SPELLFIRE_WIELDER **** **** **** **** **** **** **** **** +3014 SPELL_SPELLFIRE_INCREASE **** **** **** **** **** **** **** **** +3015 SPELL_SPELLFIRE_DECREASE **** **** **** **** **** **** **** **** +3016 SPELL_SPELLFIRE_QUICKSELECT **** **** **** **** **** **** **** **** +3017 SPELL_SPELLFIRE_ATTACK **** **** **** **** **** **** **** **** +3018 SPELL_SPELLFIRE_HEAL **** **** **** **** **** **** **** **** +3019 SPELL_SPELLFIRE_CHECK **** **** **** **** **** **** **** **** +3020 SPELL_SPELLFIRE_PLUS_ONE **** **** **** **** **** **** **** **** +3021 SPELL_SPELLFIRE_PLUS_FIVE **** **** **** **** **** **** **** **** +3022 SPELL_SPELLFIRE_PLUS_TEN **** **** **** **** **** **** **** **** +3023 SPELL_SPELLFIRE_PLUS_TWENTY **** **** **** **** **** **** **** **** +3024 SPELL_SPELLFIRE_MINUS_ONE **** **** **** **** **** **** **** **** +3025 SPELL_SPELLFIRE_MINUS_FIVE **** **** **** **** **** **** **** **** +3026 SPELL_SPELLFIRE_MINUS_TEN **** **** **** **** **** **** **** **** +3027 SPELL_SPELLFIRE_MINUS_TWENTY **** **** **** **** **** **** **** **** +3028 SPELL_SPELLFIRE_CHECK_EXP **** **** **** **** **** **** **** **** +3029 SPELL_SPELLFIRE_QUICKSELECT_CHANGE **** **** **** **** **** **** **** **** +3030 SPELL_SPELLFIRE_QUICKSELECT_1 **** **** **** **** **** **** **** **** +3031 SPELL_SPELLFIRE_QUICKSELECT_2 **** **** **** **** **** **** **** **** +3032 SPELL_SPELLFIRE_QUICKSELECT_3 **** **** **** **** **** **** **** **** +3033 SPELL_SPELLFIRE_DRAIN_CHARGED **** **** **** **** **** **** **** **** +3034 SPELL_SPELLFIRE_RAPID_BLAST **** **** **** **** **** **** **** **** +3035 SPELL_SPELLFIRE_RAPID_BLAST_TWO **** **** **** **** **** **** **** **** +3036 SPELL_SPELLFIRE_RAPID_BLAST_THREE **** **** **** **** **** **** **** **** +3037 SPELL_SPELLFIRE_DRAIN_PERMANENT **** **** **** **** **** **** **** **** +3038 SPELL_SPELLFIRE_CHARGE_ITEM **** **** **** **** **** **** **** **** +3039 SPELL_SPELLFIRE_CROWN **** **** **** **** **** **** **** **** +3040 SPELL_SPELLFIRE_MAELSTROM **** **** **** **** **** **** **** **** +3041 SPELL_SPELLFIRE_ABSORB **** **** **** **** **** **** **** **** +3042 SPELLS_SPELLS_TOUCH_ATTACK **** **** **** **** **** **** **** **** +3043 SPELLS_SPELLS_RANGED_ATTACK **** **** **** **** **** **** **** **** +3044 SPELLS_SPELLS_CONCENTRATION_TARGET **** **** **** **** **** **** **** **** +3045 SPELLS_SPELLS_HOLD_CHARGE_TOGGLE **** **** **** **** **** **** **** **** +3046 Virtuoso_Sustaining_Song **** **** **** **** **** **** **** **** +3047 Virtuoso_Calumny **** **** **** **** **** **** **** **** +3048 Virtuoso_Jarring_Song **** **** **** **** **** **** **** **** +3049 Virtuoso_Sharp_Note **** **** **** **** **** **** **** **** +3050 Virtuoso_Mindbending_Melody **** **** **** **** **** **** **** **** +3051 Virtuoso_Greater_Calumny **** **** **** **** **** **** **** **** +3052 Virtuoso_Magical_Melody **** **** **** **** **** **** **** **** +3053 Virtuoso_Song_of_Fury **** **** **** **** **** **** **** **** +3054 Virtuoso_Revealing_Melody **** **** **** **** **** **** **** **** +3055 ShockingGrasp Electricity **** 1 T 1 **** **** **** +3056 ScorchingRay Fire **** 1 R 1 **** **** **** +3057 RayofExhaustion **** Fortitude 1 R 1 **** **** **** +3058 WavesofFatigue **** **** 1 I 1 **** **** **** +3059 Asmodeus_DreadMight **** **** **** **** **** **** **** **** +3060 DOA_SUMMON_SUCCUBUS **** **** **** **** **** **** **** **** +3061 DOA_SUMMON_VROCK **** **** **** **** **** **** **** **** +3062 DOA_SUMMON_GLABREZU **** **** **** **** **** **** **** **** +3063 DOA_SUMMON_MARILITH **** **** **** **** **** **** **** **** +3064 DOA_SUMMON_BALOR **** **** **** **** **** **** **** **** +3065 SoheiKiFrenzy **** **** **** **** **** **** **** **** +3066 AsmodeusLearnSecrets1 **** **** **** **** **** **** **** **** +3067 AsmodeusCharm **** **** **** **** **** **** **** **** +3068 AsmodeusHellcat **** **** **** **** **** **** **** **** +3069 AsmodeusEvilAuthority **** **** **** **** **** **** **** **** +3070 AsmodeusSummonDevil **** **** **** **** **** **** **** **** +3071 DoA_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +3072 DoA_GreaterCommand_Approach **** **** **** **** **** **** **** **** +3073 DoA_GreaterCommand_Drop **** **** **** **** **** **** **** **** +3074 DoA_GreaterCommand_Fall **** **** **** **** **** **** **** **** +3075 DoA_GreaterCommand_Flee **** **** **** **** **** **** **** **** +3076 DoA_GreaterCommand_Halt **** **** **** **** **** **** **** **** +3077 DoA_Command_RadialMaster **** **** **** **** **** **** **** **** +3078 DoA_Command_Approach **** **** **** **** **** **** **** **** +3079 DoA_Command_Drop **** **** **** **** **** **** **** **** +3080 DoA_Command_Fall **** **** **** **** **** **** **** **** +3081 DoA_Command_Flee **** **** **** **** **** **** **** **** +3082 DoA_Command_Halt **** **** **** **** **** **** **** **** +3083 VisionOfHeaven Daze Will 1 R 1 **** **** **** +3084 SwordOfConscience **** **** **** **** **** **** **** **** +3085 Obscuring_Mist **** **** **** P 0 2 0 -5 +3086 GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +3087 GreaterCommand_Approach **** **** **** **** **** **** **** **** +3088 GreaterCommand_Drop **** **** **** **** **** **** **** **** +3089 GreaterCommand_Fall **** **** **** **** **** **** **** **** +3090 GreaterCommand_Flee **** **** **** **** **** **** **** **** +3091 GreaterCommand_Halt **** **** **** **** **** **** **** **** +3092 Command_RadialMaster **** **** **** **** **** **** **** **** +3093 Command_Approach **** **** **** **** **** **** **** **** +3094 Command_Drop **** **** **** **** **** **** **** **** +3095 Command_Fall **** **** **** **** **** **** **** **** +3096 Command_Flee **** **** **** **** **** **** **** **** +3097 Command_Halt **** **** **** **** **** **** **** **** +3098 PolarRay Cold **** 1 R 1 **** **** **** +3099 BloodOfTheMartyr **** **** **** **** **** **** **** **** +3100 Acid_Orb Acid Fortitude 0 R 1 **** **** **** +3101 Cold_Orb Cold Fortitude 0 R 1 **** **** **** +3102 Electric_Orb Electricity Fortitude 0 R 1 **** **** **** +3103 Fire_Orb Fire Fortitude 0 R 1 **** **** **** +3104 Sonic_Orb Sonic Fortitude 0 R 1 **** **** **** +3105 Ice_Burst Cold Reflex 1 I 1 **** **** **** +3106 Acid_Storm Acid Reflex 1 I 1 **** **** **** +3107 Mass_Hold_Person Paralysis Will 1 D 1 **** **** **** +3108 Mass_Hold_Monster Paralysis Will 1 D 1 **** **** **** +3109 Burning_Bolt Fire **** 1 R 1 **** **** **** +3110 Blast_of_Flame Fire Reflex 1 I 1 **** **** **** +3111 Disintegrate **** Fortitude 1 R 1 **** **** **** +3112 Mantle_of_Eg_Might **** **** **** E 0 3 9 **** +3113 Energy_Immunity **** **** **** **** **** **** **** **** +3114 EI_Acid **** **** **** **** **** **** **** **** +3115 EI_Cold **** **** **** **** **** **** **** **** +3116 EI_Elec **** **** **** **** **** **** **** **** +3117 EI_Fire **** **** **** **** **** **** **** **** +3118 EI_Sonic **** **** **** **** **** **** **** **** +3119 Mass_Bulls_Strength **** **** **** E 0 3 0 **** +3120 Mass_Cats_Grace **** **** **** E 0 3 0 **** +3121 Mass_Eagle_Splendor **** **** **** E 0 3 0 **** +3122 Mass_Endurance **** **** **** E 0 3 0 **** +3123 Mass_Foxs_Cunning **** **** **** E 0 3 0 **** +3124 Mass_Owls_Wisdom **** **** **** E 0 3 0 **** +3125 Mass_Ultravision **** **** **** P 0 3 0 **** +3126 Lower_Spell_Resistance **** **** **** **** **** **** **** **** +3127 Serpents_Sigh **** **** **** **** **** **** **** **** +3128 SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +3129 SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +3130 SS_Cone_of_Acid **** **** **** **** **** **** **** **** +3131 SS_Cone_of_Cold **** **** **** **** **** **** **** **** +3132 SS_Cone_of_Fire **** **** **** **** **** **** **** **** +3133 Heroism **** **** **** E 0 3 9 -3133 +3134 Greater_Heroism **** **** **** E 0 2 9 -3133 +3135 Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +3136 Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +3137 Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +3138 Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +3139 Righteous_Might **** **** **** E 0 2 0 **** +3140 Recitation **** **** **** E 0 2 0 **** +3141 Forceblast **** Reflex 1 R 1 **** **** **** +3142 Glitterdust **** Will **** I 1 **** **** **** +3143 Mords_Mansion **** **** **** **** **** **** **** **** +3144 Lesser_Acid_Orb Acid **** **** R 1 **** **** **** +3145 Lesser_Cold_Orb Cold **** **** R 1 **** **** **** +3146 Lesser_Electric_Orb Electricity **** **** R 1 **** **** **** +3147 Lesser_Fire_Orb Fire **** **** R 1 **** **** **** +3148 Lesser_Sonic_Orb Sonic **** **** R 1 **** **** **** +3149 Baleful_Transposition **** **** **** **** **** **** **** **** +3150 Benign_Transposition **** **** **** **** **** **** **** **** +3151 Conviction **** **** **** P 0 2 14 -3151 +3152 Legions_Conviction **** **** **** P 0 2 14 -3151 +3153 Curse_of_Impending_Blades **** **** 1 R 1 **** **** **** +3154 Legions_Curse_of_Impending_Blades **** **** 1 R 1 **** **** **** +3155 Curse_of_Petty_Failing **** **** 1 R 1 **** **** **** +3156 Legions_Curse_of_Petty_Failing **** **** 1 R 1 **** **** **** +3157 Divine_Protection **** **** **** P 0 2 0 **** +3158 Fireburst Fire Reflex 1 I 1 **** **** **** +3159 Greater_Fireburst Fire Reflex 1 I 1 **** **** **** +3160 Lionheart **** **** **** P 0 2 13 **** +3161 Living_Undeath **** **** **** P 0 2 12 **** +3162 Panacea **** **** **** **** **** **** **** **** +3163 Legions_Shield_of_Faith **** **** **** P 0 3 7 -3 +3164 Slashing_Darkness Positive **** 1 R 1 **** **** **** +3165 Agnazzars_Scorcher Fire Reflex 0 I 1 **** **** **** +3166 Create_Magic_Tattoo **** **** **** **** **** **** **** **** +3167 CT_Scribe **** **** **** **** **** **** **** **** +3168 Flashburst Blindness Will 1 I 1 **** **** **** +3169 Flensing **** Fortitude 1 R 1 **** **** **** +3170 Shadow_Spray **** Fortitude 1 I 1 **** **** **** +3171 Snillocs_Snowball_Swarm Cold Reflex 1 I 1 **** **** **** +3172 Beltyns_Burning_Blood Fire Fortitude 1 R 1 **** **** **** +3173 Ilyykurs_Mantle **** **** **** P 0 2 0 **** +3174 Improved_Mage_Armor **** **** **** P 0 2 7 -102 +3175 Nybors_Gentle_Reminder Mind_Affecting Fortitude 1 R 1 **** **** **** +3176 Nybors_Stern_Reproof Death Fortitude 1 R 1 **** **** **** +3177 Sinsaburs_Baleful_Bolt **** Reflex 1 I 1 **** **** **** +3178 Snillocs_Snowball Cold **** 1 R 1 **** **** **** +3179 Soulscour Mind_Affecting Will 1 T 1 **** **** **** +3180 Sphere_of_Ultimate_Destruction Death Fortitude 1 R 1 **** **** **** +3181 Clarity_of_Mind **** **** **** P 0 3 13 **** +3182 Mass_Drown **** Fortitude 1 I 1 **** **** **** +3183 Hail_of_Stone **** **** 1 I 1 **** **** **** +3184 Spiderskin **** **** **** P 0 3 7 **** +3185 Viscid_Glob **** Reflex 1 R 1 **** **** **** +3186 Word_of_Balance **** **** 1 I 1 **** **** **** +3187 Greenfire **** **** **** **** **** **** **** **** +3188 Blank **** **** **** **** **** **** **** **** +3189 Summon7Air **** **** **** **** **** **** **** **** +3190 Summon7Earth **** **** **** **** **** **** **** **** +3191 Summon7Fire **** **** **** **** **** **** **** **** +3192 Summon7Water **** **** **** **** **** **** **** **** +3193 Summon8Air **** **** **** **** **** **** **** **** +3194 Summon8Earth **** **** **** **** **** **** **** **** +3195 Summon8Fire **** **** **** **** **** **** **** **** +3196 Summon8Water **** **** **** **** **** **** **** **** +3197 Summon9Air **** **** **** **** **** **** **** **** +3198 Summon9Earth **** **** **** **** **** **** **** **** +3199 Summon9Fire **** **** **** **** **** **** **** **** +3200 Summon9Water **** **** **** **** **** **** **** **** +3201 Detect_Evil **** **** **** **** **** **** **** **** +3202 Detect_Good **** **** **** **** **** **** **** **** +3203 Detect_Law **** **** **** **** **** **** **** **** +3204 Detect_Chaos **** **** **** **** **** **** **** **** +3205 UndetectableAlignment **** **** **** **** **** **** **** **** +3206 Unholy_Sword **** **** **** **** **** **** **** **** +3207 DeeperDarkness **** **** **** I 1 **** **** **** +3208 Blur **** **** **** P 0 2 7 -5 +3209 MirrorImage **** **** **** P 0 2 0 **** +3210 Swashbuckler_damage **** **** **** **** **** **** **** **** +3211 CoC_damage **** **** **** **** **** **** **** **** +3212 Insanity Confusion Will 1 R 1 **** **** **** +3213 Mass_Inflict_Light_Wounds Negative Will 1 I 1 **** **** **** +3214 Mass_Inflict_Moderate_Wounds Negative Will 1 I 1 **** **** **** +3215 Mass_Inflict_Serious_Wounds Negative Will 1 I 1 **** **** **** +3216 Mass_Inflict_Critical_Wounds Negative Will 1 I 1 **** **** **** +3217 Greater_Harm Negative Will 1 T 1 **** **** **** +3218 Mass_Harm Negative Will 1 I 1 **** **** **** +3219 Scrying **** **** **** **** **** **** **** **** +3220 Holy_Word **** **** 1 D 1 **** **** **** +3221 Blasphemy **** **** 1 D 1 **** **** **** +3222 Dictum **** **** 1 D 1 **** **** **** +3223 Word_of_Chaos **** **** 1 D 1 **** **** **** +3224 **Truenaming** **** **** **** **** **** **** **** **** +3225 DefensiveEdge **** **** **** **** **** **** **** **** +3226 DefensiveEdge_Normal **** **** **** **** **** **** **** **** +3227 DefensiveEdge_Reverse **** **** **** **** **** **** **** **** +3228 InertialSurge **** **** **** **** **** **** **** **** +3229 InertialSurge_Normal **** **** **** **** **** **** **** **** +3230 InertialSurge_Reverse **** **** **** **** **** **** **** **** +3231 KnightsPuissance **** **** **** **** **** **** **** **** +3232 KnightsPuissance_Normal **** **** **** **** **** **** **** **** +3233 KnightsPuissance_Reverse **** **** **** **** **** **** **** **** +3234 UniversalAptitude **** **** **** **** **** **** **** **** +3235 UniversalAptitude_Normal **** **** **** **** **** **** **** **** +3236 UniversalAptitude_Reverse **** **** **** **** **** **** **** **** +3237 WordOfNurturingMinor **** **** **** **** **** **** **** **** +3238 WordOfNurturingMinor_Normal **** **** **** **** **** **** **** **** +3239 WordOfNurturingMinor_Reverse **** **** **** **** **** **** **** **** +3240 FortifyArmour **** **** **** **** **** **** **** **** +3241 FortifyArmour_SneakAttacks **** **** **** **** **** **** **** **** +3242 FortifyArmour_Criticals **** **** **** **** **** **** **** **** +3243 KeenWeapon **** **** **** **** **** **** **** **** +3244 FogOfTheVoid **** **** **** **** **** **** **** **** +3245 FogOfTheVoid_FogCloud **** **** **** **** **** **** **** **** +3246 FogOfTheVoid_SolidFog **** **** **** **** **** **** **** **** +3247 ShieldOfTheLandscape **** **** **** **** **** **** **** **** +3248 Shockwave **** **** **** **** **** **** **** **** +3249 ArchersEye **** **** **** **** **** **** **** **** +3250 ArchersEye_Normal **** **** **** **** **** **** **** **** +3251 ArchersEye_Reverse **** **** **** **** **** **** **** **** +3252 HiddenTruth **** **** **** **** **** **** **** **** +3253 HiddenTruth_Normal **** **** **** **** **** **** **** **** +3254 HiddenTruth_Reverse **** **** **** **** **** **** **** **** +3255 PercieveTheUnseen **** **** **** **** **** **** **** **** +3256 PercieveTheUnseen_Normal **** **** **** **** **** **** **** **** +3257 PercieveTheUnseen_Reverse **** **** **** **** **** **** **** **** +3258 SilentCaster **** **** **** **** **** **** **** **** +3259 SilentCaster_Normal **** **** **** **** **** **** **** **** +3260 SilentCaster_Reverse **** **** **** **** **** **** **** **** +3261 SpeedOfTheZephyr **** **** **** **** **** **** **** **** +3262 SpeedOfTheZephyr_Normal **** **** **** **** **** **** **** **** +3263 SpeedOfTheZephyr_Reverse **** **** **** **** **** **** **** **** +3264 StrikeOfMight **** **** **** **** **** **** **** **** +3265 StrikeOfMight_Normal **** **** **** **** **** **** **** **** +3266 StrikeOfMight_Reverse **** **** **** **** **** **** **** **** +3267 TemporalTwist **** **** **** **** **** **** **** **** +3268 TemporalTwist_Normal **** **** **** **** **** **** **** **** +3269 TemporalTwist_Reverse **** **** **** **** **** **** **** **** +3270 WordOfNurturingLesser **** **** **** **** **** **** **** **** +3271 WordOfNurturingLesser_Normal **** **** **** **** **** **** **** **** +3272 WordOfNurturingLesser_Reverse **** **** **** **** **** **** **** **** +3273 AgitateItem **** **** **** **** **** **** **** **** +3274 AgitateItem_Hot **** **** **** **** **** **** **** **** +3275 AgitateItem_Cold **** **** **** **** **** **** **** **** +3276 AnalyzeIten **** **** **** **** **** **** **** **** +3277 EnergyVortex **** **** **** **** **** **** **** **** +3278 EnergyVortex_Acid **** **** **** **** **** **** **** **** +3279 EnergyVortex_Cold **** **** **** **** **** **** **** **** +3280 EnergyVortex_Elec **** **** **** **** **** **** **** **** +3281 EnergyVortex_Fire **** **** **** **** **** **** **** **** +3282 SpeakRockToMud **** **** **** **** **** **** **** **** +3283 TransformTheLandscape **** **** **** **** **** **** **** **** +3284 AcceleratedAttack **** **** **** **** **** **** **** **** +3285 AcceleratedAttack_Normal **** **** **** **** **** **** **** **** +3286 AcceleratedAttack_Reverse **** **** **** **** **** **** **** **** +3287 EnergyNegation **** **** **** **** **** **** **** **** +3288 EnergyNegation_Normal **** **** **** **** **** **** **** **** +3289 EnergyNegation_Reverse **** **** **** **** **** **** **** **** +3290 EnergyNegation_Choice **** **** **** **** **** **** **** **** +3291 IncarnationOfAngels **** **** **** **** **** **** **** **** +3292 IncarnationOfAngels_Normal **** **** **** **** **** **** **** **** +3293 IncarnationOfAngels_Reverse **** **** **** **** **** **** **** **** +3294 SpeedOfTheZephyrGreater **** **** **** **** **** **** **** **** +3295 SpeedOfTheZephyrGreater_Normal **** **** **** **** **** **** **** **** +3296 SpeedOfTheZephyrGreater_Reverse **** **** **** **** **** **** **** **** +3297 TemporalSpiral **** **** **** **** **** **** **** **** +3298 TemporalSpiral_Normal **** **** **** **** **** **** **** **** +3299 TemporalSpiral_Reverse **** **** **** **** **** **** **** **** +3300 VisionSharpened **** **** **** **** **** **** **** **** +3301 VisionSharpened_Normal **** **** **** **** **** **** **** **** +3302 VisionSharpened_Reverse **** **** **** **** **** **** **** **** +3303 WordOfNurturingModerate **** **** **** **** **** **** **** **** +3304 WordOfNurturingModerate_Normal **** **** **** **** **** **** **** **** +3305 WordOfNurturingModerate_Reverse **** **** **** **** **** **** **** **** +3306 RemoveItem **** **** **** **** **** **** **** **** +3307 SuppressWeapon **** **** **** **** **** **** **** **** +3308 LoreOfTheWorld **** **** **** **** **** **** **** **** +3309 MasterTheFourWinds **** **** **** **** **** **** **** **** +3310 ThwartTheTraveller **** **** **** **** **** **** **** **** +3311 BreathOfCleansing **** **** **** **** **** **** **** **** +3312 BreathOfCleansing_Normal **** **** **** **** **** **** **** **** +3313 BreathOfCleansing_Reverse **** **** **** **** **** **** **** **** +3314 CasterLens **** **** **** **** **** **** **** **** +3315 CasterLens_Normal **** **** **** **** **** **** **** **** +3316 CasterLens_Reverse **** **** **** **** **** **** **** **** +3317 ConfoundingResistance **** **** **** **** **** **** **** **** +3318 ConfoundingResistance_Normal **** **** **** **** **** **** **** **** +3319 ConfoundingResistance_Reverse **** **** **** **** **** **** **** **** +3320 MoraleBoost **** **** **** **** **** **** **** **** +3321 MoraleBoost_Normal **** **** **** **** **** **** **** **** +3322 MoraleBoost_Reverse **** **** **** **** **** **** **** **** +3323 MagicalContraction **** **** **** **** **** **** **** **** +3324 MagicalContraction_Normal **** **** **** **** **** **** **** **** +3325 MagicalContraction_Reverse **** **** **** **** **** **** **** **** +3326 SpellRebirth **** **** **** **** **** **** **** **** +3327 SpellRebirth_Normal **** **** **** **** **** **** **** **** +3328 SpellRebirth_Reverse **** **** **** **** **** **** **** **** +3329 WordOfNurturingPotent **** **** **** **** **** **** **** **** +3330 WordOfNurturingPotent_Normal **** **** **** **** **** **** **** **** +3331 WordOfNurturingPotent_Reverse **** **** **** **** **** **** **** **** +3332 WordOfBolstering **** **** **** **** **** **** **** **** +3333 WordOfBolstering_Normal **** **** **** **** **** **** **** **** +3334 WordOfBolstering_Reverse **** **** **** **** **** **** **** **** +3335 WordOfBolstering_Choice **** **** **** **** **** **** **** **** +3336 SuppressItem **** **** **** **** **** **** **** **** +3337 TransmuteWeapon **** **** **** **** **** **** **** **** +3338 AngerTheSleepingEarth **** **** **** **** **** **** **** **** +3339 ConjunctiveGate **** **** **** **** **** **** **** **** +3340 DenyPassage **** **** **** **** **** **** **** **** +3341 EldritchAttraction **** **** **** **** **** **** **** **** +3342 EldritchAttraction_Normal **** **** **** **** **** **** **** **** +3343 EldritchAttraction_Reverse **** **** **** **** **** **** **** **** +3344 EnergyNegationGreater **** **** **** **** **** **** **** **** +3345 EnergyNegationGreater_Normal **** **** **** **** **** **** **** **** +3346 EnergyNegationGreater_Reverse **** **** **** **** **** **** **** **** +3347 EnergyNegationGreater_Choice **** **** **** **** **** **** **** **** +3348 EssenceOfLifespark **** **** **** **** **** **** **** **** +3349 EssenceOfLifespark_Normal **** **** **** **** **** **** **** **** +3350 EssenceOfLifespark_Reverse **** **** **** **** **** **** **** **** +3351 PreturnaturalClarity **** **** **** **** **** **** **** **** +3352 PreturnaturalClarity_Attack **** **** **** **** **** **** **** **** +3353 PreturnaturalClarity_Skill **** **** **** **** **** **** **** **** +3354 PreturnaturalClarity_Save **** **** **** **** **** **** **** **** +3355 PreturnaturalClarity_Reverse **** **** **** **** **** **** **** **** +3356 SensoryFocus **** **** **** **** **** **** **** **** +3357 SensoryFocus_Normal **** **** **** **** **** **** **** **** +3358 SensoryFocus_Reverse **** **** **** **** **** **** **** **** +3359 WardOfPeace **** **** **** **** **** **** **** **** +3360 WardOfPeace_Normal **** **** **** **** **** **** **** **** +3361 WardOfPeace_Reverse **** **** **** **** **** **** **** **** +3362 WordOfNurturingCritical **** **** **** **** **** **** **** **** +3363 WordOfNurturingCritical_Normal **** **** **** **** **** **** **** **** +3364 WordOfNurturingCritical_Reverse **** **** **** **** **** **** **** **** +3365 MetamagicCatalyst **** **** **** **** **** **** **** **** +3366 MetamagicCatalyst_Empower **** **** **** **** **** **** **** **** +3367 MetamagicCatalyst_Extend **** **** **** **** **** **** **** **** +3368 MetamagicCatalyst_Maximize **** **** **** **** **** **** **** **** +3369 SeizeItem **** **** **** **** **** **** **** **** +3370 BreathOfRecovery **** **** **** **** **** **** **** **** +3371 BreathOfRecovery_Normal **** **** **** **** **** **** **** **** +3372 BreathOfRecovery_Reverse **** **** **** **** **** **** **** **** +3373 EtherReforged **** **** **** **** **** **** **** **** +3374 EtherReforged_Normal **** **** **** **** **** **** **** **** +3375 EtherReforged_Reverse **** **** **** **** **** **** **** **** +3376 KnightsPuissanceGreater **** **** **** **** **** **** **** **** +3377 KnightsPuissanceGreater_Normal **** **** **** **** **** **** **** **** +3378 KnightsPuissanceGreater_Reverse **** **** **** **** **** **** **** **** +3379 MysticRampart **** **** **** **** **** **** **** **** +3380 MysticRampart_Normal **** **** **** **** **** **** **** **** +3381 MysticRampart_Reverse **** **** **** **** **** **** **** **** +3382 SingularMind **** **** **** **** **** **** **** **** +3383 SingularMind_Normal **** **** **** **** **** **** **** **** +3384 SingularMind_Reverse **** **** **** **** **** **** **** **** +3385 WordOfNurturingGreater **** **** **** **** **** **** **** **** +3386 WordOfNurturingGreater_Normal **** **** **** **** **** **** **** **** +3387 WordOfNurturingGreater_Reverse **** **** **** **** **** **** **** **** +3388 DRAGON_ALLY **** **** **** **** **** **** **** **** +3389 OnHit_Dragonfire_Inspiration **** **** **** **** **** **** **** **** +3390 Dragonfire_Inspiration_Toggle **** **** **** **** **** **** **** **** +3391 Dragonfire_Assault_Toggle **** **** **** **** **** **** **** **** +3392 Dragonfire_Channeling **** **** **** **** **** **** **** **** +3393 Marrutact_Howl **** **** **** **** **** **** **** **** +3394 BrilliantEnergyArrows **** **** **** R 1 **** **** **** +3395 HideFromAnimals **** **** **** **** **** **** **** **** +3396 Longstrider **** **** **** E 0 3 0 **** +3397 SerpentArrows **** **** **** R 1 **** **** **** +3398 Treeshape **** **** **** **** **** **** **** **** +3399 WaterBreathing **** **** **** **** **** **** **** **** +3400 RECITATION_FORTIFIED **** **** **** **** **** **** **** **** +3401 RECITATION_MEDITATIVE **** **** **** **** **** **** **** **** +3402 RECITATION_MINDFUL **** **** **** **** **** **** **** **** +3403 RECITATION_SANGUINE **** **** **** **** **** **** **** **** +3404 RECITATION_VITAL **** **** **** **** **** **** **** **** +3405 EmpowerUtterance **** **** **** **** **** **** **** **** +3406 ExtendUtterance **** **** **** **** **** **** **** **** +3407 QuickenUtterance **** **** **** **** **** **** **** **** +3408 Truenamer_Ignore_SR **** **** **** **** **** **** **** **** +3409 Truenamer_Crafted_Tool_Target **** **** **** **** **** **** **** **** +3410 Truenamer_Crafted_Tool_Target_Conversation **** **** **** **** **** **** **** **** +3411 Truenamer_Crafted_Tool_Target_Choice1 **** **** **** **** **** **** **** **** +3412 Truenamer_Crafted_Tool_Target_Choice2 **** **** **** **** **** **** **** **** +3413 Truenamer_Crafted_Tool_Target_Choice3 **** **** **** **** **** **** **** **** +3414 Truenamer_Crafted_Tool_Target_Choice4 **** **** **** **** **** **** **** **** +3415 SeeTheNamed **** **** **** **** **** **** **** **** +3416 SpeakUntoTheMasses **** **** **** **** **** **** **** **** +3417 SayMyNameAndIAmThere **** **** **** **** **** **** **** **** +3418 SyllableOfDetachment **** **** **** **** **** **** **** **** +3419 SyllableOfAffliction_Master **** **** **** **** **** **** **** **** +3420 SyllableOfAffliction_Sight **** **** **** **** **** **** **** **** +3421 SyllableOfAffliction_Hearing **** **** **** **** **** **** **** **** +3422 SyllableOfAffliction_Touch **** **** **** **** **** **** **** **** +3423 SyllableOfExile **** **** **** **** **** **** **** **** +3424 SyllableOfDissolution **** **** **** **** **** **** **** **** +3425 SyllableOfEnervation **** **** **** **** **** **** **** **** +3426 Brimstone_TongueOfFire3d6 **** **** **** **** **** **** **** **** +3427 Brimstone_TongueOfFire5d6 **** **** **** **** **** **** **** **** +3428 Brimstone_TongueOfFire8d6 **** **** **** **** **** **** **** **** +3429 Brimstone_LesserHeavenlyEntreaty **** **** **** **** **** **** **** **** +3430 Brimstone_NormalHeavenlyEntreaty **** **** **** **** **** **** **** **** +3431 Brimstone_GreaterHeavenlyEntreaty **** **** **** **** **** **** **** **** +3432 HideFromUndead **** **** **** **** **** **** **** **** +3433 CrushingDespair Mind_Affecting Will 1 I 1 **** **** **** +3434 HaltUndead **** **** **** **** **** **** **** **** +3435 Eyebite **** Fortitude 1 R 1 **** **** **** +3436 SongOfDiscord Mind_Affecting Will 1 I 1 **** **** **** +3437 FireInTheBlood **** **** **** E 0 2 0 **** +3438 VileDeath **** **** **** **** **** **** **** **** +3439 PlagueOfUndead **** **** **** S 0 3 0 -2 +3440 DNecroCharnelTouch **** **** **** **** **** **** **** **** +3441 DNecroScabTouch **** **** **** **** **** **** **** **** +3442 DNecroEnervTouch **** **** **** **** **** **** **** **** +3443 DNecroNegative_Energy_Burst **** **** **** **** **** **** **** **** +3444 DNecroFearAura **** **** **** **** **** **** **** **** +3445 NobleCoord **** **** **** **** **** **** **** **** +3446 NobleFavor **** **** **** **** **** **** **** **** +3447 NobleGreat **** **** **** **** **** **** **** **** +3448 NobleInspire **** **** **** **** **** **** **** **** +3449 Extend_Spell_Ability **** **** **** **** **** **** **** **** +3450 Silent_Spell_Ability **** **** **** **** **** **** **** **** +3451 Still_Spell_Ability **** **** **** **** **** **** **** **** +3452 Empower_Spell_Ability **** **** **** **** **** **** **** **** +3453 Maximize_Spell_Ability **** **** **** **** **** **** **** **** +3454 Quicken_Spell_Ability **** **** **** **** **** **** **** **** +3455 Weapon_Aptitude **** **** **** **** **** **** **** **** +3456 Weapon_Aptitude_Options **** **** **** **** **** **** **** **** +3457 Greater_Resistance **** **** **** P 0 3 14 **** +3458 Superior_Resistance **** **** **** P 0 3 14 **** +3459 Vigor **** **** **** E 0 2 10 -3459 +3460 Lesser_Vigor **** **** **** E 0 2 10 -3459 +3461 Mass_Lesser_Vigor **** **** **** E 0 2 10 -3459 +3462 Vigorous_Circle **** **** **** E 0 2 10 -3459 +3463 Mystic_Barrier **** **** **** **** **** **** **** **** +3464 Cadence_Bull **** **** **** **** **** **** **** **** +3465 Cadence_Iron **** **** **** **** **** **** **** **** +3466 Cadence_Heart **** **** **** **** **** **** **** **** +3467 Cadence_Swallow **** **** **** **** **** **** **** **** +3468 Cadence_Wound **** **** **** **** **** **** **** **** +3469 Cadence_Fool **** **** **** **** **** **** **** **** +3470 Cadence_Fort **** **** **** **** **** **** **** **** +3471 Cadence_Fright **** **** **** **** **** **** **** **** +3472 Cadence_Drake **** **** **** **** **** **** **** **** +3473 Cadence_Step **** **** **** **** **** **** **** **** +3474 ResonantVoice **** **** **** **** **** **** **** **** +3475 Grapple **** **** **** **** **** **** **** **** +3476 Bullrush **** **** **** **** **** **** **** **** +3477 Overrun **** **** **** **** **** **** **** **** +3478 Trip **** **** **** **** **** **** **** **** +3479 Charge **** **** **** **** **** **** **** **** +3480 ChargeBullrush **** **** **** **** **** **** **** **** +3481 GrappleEnd **** **** **** **** **** **** **** **** +3482 CombatMove_RadialMaster **** **** **** **** **** **** **** **** +3483 MasterWand **** **** **** **** **** **** **** **** +3484 RecklessWandWielder **** **** **** **** **** **** **** **** +3485 DoubleWandWielder **** **** **** **** **** **** **** **** +3486 Wandstrike **** **** **** **** **** **** **** **** +3487 WildMage_RandomDeflector **** **** **** **** **** **** **** **** +3488 WildMage_RodOfWonder **** **** **** **** **** **** **** **** +3489 WildMage_Wildstrike **** **** **** **** **** **** **** **** +3490 FMM_SwiftShield **** **** **** **** **** **** **** **** +3491 Disarm **** **** **** **** **** **** **** **** +3492 CombatMove_RadialMaster2 **** **** **** **** **** **** **** **** +3493 RangedDisarm **** **** **** **** **** **** **** **** +3494 Stonechild_Magic_Stone **** **** **** **** **** **** **** **** +3495 FightingDefensively **** **** **** **** **** **** **** **** +3496 CombatMove_RadialMaster3 **** **** **** **** **** **** **** **** +3497 Turn_Cold **** **** **** **** **** **** **** **** +3498 ChosenOfIborighu **** **** **** **** **** **** **** **** +3499 SnowflakeWardance **** **** **** **** **** **** **** **** +3500 Min_aura_1 **** **** **** **** **** **** **** **** +3501 Min_aura_2 **** **** **** **** **** **** **** **** +3502 Min_aura_3 **** **** **** **** **** **** **** **** +3503 Min_aura_4 **** **** **** **** **** **** **** **** +3504 Min_aura_5 **** **** **** **** **** **** **** **** +3505 Min_aura_6 **** **** **** **** **** **** **** **** +3506 Min_aura_7 **** **** **** **** **** **** **** **** +3507 Min_aura_8 **** **** **** **** **** **** **** **** +3508 Min_aura_9 **** **** **** **** **** **** **** **** +3509 Min_aura_10 **** **** **** **** **** **** **** **** +3510 Min_aura_11 **** **** **** **** **** **** **** **** +3511 Maj_aura_1 **** **** **** **** **** **** **** **** +3512 Maj_aura_2 **** **** **** **** **** **** **** **** +3513 Maj_aura_3 **** **** **** **** **** **** **** **** +3514 Maj_aura_4 **** **** **** **** **** **** **** **** +3515 Maj_aura_5 **** **** **** **** **** **** **** **** +3516 Maj_aura_6 **** **** **** **** **** **** **** **** +3517 Maj_aura_7 **** **** **** **** **** **** **** **** +3518 Grant_Move **** **** **** **** **** **** **** **** +3519 Maj_aura_8 **** **** **** **** **** **** **** **** +3520 Maj_aura_9 **** **** **** **** **** **** **** **** +3521 Maj_aura_10 **** **** **** **** **** **** **** **** +3522 Maj_aura_11 **** **** **** **** **** **** **** **** +3523 Maj_aura_12 **** **** **** **** **** **** **** **** +3524 Maj_aura_13 **** **** **** **** **** **** **** **** +3525 **Truenaming_RealUtters** **** **** **** **** **** **** **** **** +3526 Defensive_Edge_Normal **** **** **** **** **** **** **** **** +3527 Defensive_Edge_Reverse **** **** **** **** **** **** **** **** +3528 InertialSurge_Normal **** **** **** **** **** **** **** **** +3529 InertialSurge_Reverse **** **** **** **** **** **** **** **** +3530 KnightsPuissance_Normal **** **** **** **** **** **** **** **** +3531 KnightsPuissance_Reverse **** **** **** **** **** **** **** **** +3532 UniversalAptitude_Normal **** **** **** **** **** **** **** **** +3533 UniversalAptitude_Reverse **** **** **** **** **** **** **** **** +3534 WordOfNurturingMinor_Normal **** **** **** **** **** **** **** **** +3535 WordOfNurturingMinor_Reverse **** **** **** **** **** **** **** **** +3536 FortifyArmour_SneakAttacks **** **** **** **** **** **** **** **** +3537 FortifyArmour_Criticals **** **** **** **** **** **** **** **** +3538 KeenWeapon **** **** **** **** **** **** **** **** +3539 FogOfTheVoid_FogCloud **** **** **** **** **** **** **** **** +3540 FogOfTheVoid_SolidFog **** **** **** **** **** **** **** **** +3541 ShieldOfTheLandscape **** **** **** **** **** **** **** **** +3542 Shockwave **** **** **** **** **** **** **** **** +3543 ArchersEye_Normal **** **** **** **** **** **** **** **** +3544 ArchersEye_Reverse **** **** **** **** **** **** **** **** +3545 HiddenTruth_Normal **** **** **** **** **** **** **** **** +3546 HiddenTruth_Reverse **** **** **** **** **** **** **** **** +3547 PercieveTheUnseen_Normal **** **** **** **** **** **** **** **** +3548 PercieveTheUnseen_Reverse **** **** **** **** **** **** **** **** +3549 SilentCaster_Normal **** **** **** **** **** **** **** **** +3550 SilentCaster_Reverse **** **** **** **** **** **** **** **** +3551 SpeedOfTheZephyr_Normal **** **** **** **** **** **** **** **** +3552 SpeedOfTheZephyr_Reverse **** **** **** **** **** **** **** **** +3553 StrikeOfMight_Normal **** **** **** **** **** **** **** **** +3554 StrikeOfMight_Reverse **** **** **** **** **** **** **** **** +3555 TemporalTwist_Normal **** **** **** **** **** **** **** **** +3556 TemporalTwist_Reverse **** **** **** **** **** **** **** **** +3557 WordOfNurturingLesser_Normal **** **** **** **** **** **** **** **** +3558 WordOfNurturingLesser_Reverse **** **** **** **** **** **** **** **** +3559 AgitateItem_Hot **** **** **** **** **** **** **** **** +3560 AgitateItem_Cold **** **** **** **** **** **** **** **** +3561 AnalyzeIten **** **** **** **** **** **** **** **** +3562 EnergyVortex_Acid **** **** **** **** **** **** **** **** +3563 EnergyVortex_Cold **** **** **** **** **** **** **** **** +3564 EnergyVortex_Elec **** **** **** **** **** **** **** **** +3565 EnergyVortex_Fire **** **** **** **** **** **** **** **** +3566 SpeakRockToMud **** **** **** **** **** **** **** **** +3567 TransformTheLandscape **** **** **** **** **** **** **** **** +3568 AcceleratedAttack_Normal **** **** **** **** **** **** **** **** +3569 AcceleratedAttack_Reverse **** **** **** **** **** **** **** **** +3570 EnergyNegation_Normal **** **** **** **** **** **** **** **** +3571 EnergyNegation_Reverse **** **** **** **** **** **** **** **** +3572 IncarnationOfAngels_Normal **** **** **** **** **** **** **** **** +3573 IncarnationOfAngels_Reverse **** **** **** **** **** **** **** **** +3574 SpeedOfTheZephyrGreater_Normal **** **** **** **** **** **** **** **** +3575 SpeedOfTheZephyrGreater_Reverse **** **** **** **** **** **** **** **** +3576 TemporalSpiral_Normal **** **** **** **** **** **** **** **** +3577 TemporalSpiral_Reverse **** **** **** **** **** **** **** **** +3578 VisionSharpened_Normal **** **** **** **** **** **** **** **** +3579 VisionSharpened_Reverse **** **** **** **** **** **** **** **** +3580 WordOfNurturingModerate_Normal **** **** **** **** **** **** **** **** +3581 WordOfNurturingModerate_Reverse **** **** **** **** **** **** **** **** +3582 RemoveItem **** **** **** **** **** **** **** **** +3583 SuppressWeapon **** **** **** **** **** **** **** **** +3584 LoreOfTheWorld **** **** **** **** **** **** **** **** +3585 MasterTheFourWinds **** **** **** **** **** **** **** **** +3586 ThwartTheTraveller **** **** **** **** **** **** **** **** +3587 BreathOfCleansing_Normal **** **** **** **** **** **** **** **** +3588 BreathOfCleansing_Reverse **** **** **** **** **** **** **** **** +3589 CasterLens_Normal **** **** **** **** **** **** **** **** +3590 CasterLens_Reverse **** **** **** **** **** **** **** **** +3591 ConfoundingResistance_Normal **** **** **** **** **** **** **** **** +3592 ConfoundingResistance_Reverse **** **** **** **** **** **** **** **** +3593 MoraleBoost_Normal **** **** **** **** **** **** **** **** +3594 MoraleBoost_Reverse **** **** **** **** **** **** **** **** +3595 MagicalContraction_Normal **** **** **** **** **** **** **** **** +3596 MagicalContraction_Reverse **** **** **** **** **** **** **** **** +3597 SpellRebirth_Normal **** **** **** **** **** **** **** **** +3598 SpellRebirth_Reverse **** **** **** **** **** **** **** **** +3599 WordOfNurturingPotent_Normal **** **** **** **** **** **** **** **** +3600 WordOfNurturingPotent_Reverse **** **** **** **** **** **** **** **** +3601 WordOfBolstering_Normal **** **** **** **** **** **** **** **** +3602 WordOfBolstering_Reverse **** **** **** **** **** **** **** **** +3603 SuppressItem **** **** **** **** **** **** **** **** +3604 TransmuteWeapon **** **** **** **** **** **** **** **** +3605 AngerTheSleepingEarth **** **** **** **** **** **** **** **** +3606 ConjunctiveGate **** **** **** **** **** **** **** **** +3607 DenyPassage **** **** **** **** **** **** **** **** +3608 EldritchAttraction_Normal **** **** **** **** **** **** **** **** +3609 EldritchAttraction_Reverse **** **** **** **** **** **** **** **** +3610 EnergyNegationGreater_Normal **** **** **** **** **** **** **** **** +3611 EnergyNegationGreater_Reverse **** **** **** **** **** **** **** **** +3612 EssenceOfLifespark_Normal **** **** **** **** **** **** **** **** +3613 EssenceOfLifespark_Reverse **** **** **** **** **** **** **** **** +3614 PreturnaturalClarity_Attack **** **** **** **** **** **** **** **** +3615 PreturnaturalClarity_Skill **** **** **** **** **** **** **** **** +3616 PreturnaturalClarity_Save **** **** **** **** **** **** **** **** +3617 PreturnaturalClarity_Reverse **** **** **** **** **** **** **** **** +3618 SensoryFocus_Normal **** **** **** **** **** **** **** **** +3619 SensoryFocus_Reverse **** **** **** **** **** **** **** **** +3620 WardOfPeace_Normal **** **** **** **** **** **** **** **** +3621 WardOfPeace_Reverse **** **** **** **** **** **** **** **** +3622 WordOfNurturingCritical_Normal **** **** **** **** **** **** **** **** +3623 WordOfNurturingCritical_Reverse **** **** **** **** **** **** **** **** +3624 MetamagicCatalyst_Empower **** **** **** **** **** **** **** **** +3625 MetamagicCatalyst_Extend **** **** **** **** **** **** **** **** +3626 MetamagicCatalyst_Maximize **** **** **** **** **** **** **** **** +3627 SeizeItem **** **** **** **** **** **** **** **** +3628 BreathOfRecovery_Normal **** **** **** **** **** **** **** **** +3629 BreathOfRecovery_Reverse **** **** **** **** **** **** **** **** +3630 EtherReforged_Normal **** **** **** **** **** **** **** **** +3631 EtherReforged_Reverse **** **** **** **** **** **** **** **** +3632 KnightsPuissanceGreater_Normal **** **** **** **** **** **** **** **** +3633 KnightsPuissanceGreater_Reverse **** **** **** **** **** **** **** **** +3634 MysticRampart_Normal **** **** **** **** **** **** **** **** +3635 MysticRampart_Reverse **** **** **** **** **** **** **** **** +3636 SingularMind_Normal **** **** **** **** **** **** **** **** +3637 SingularMind_Reverse **** **** **** **** **** **** **** **** +3638 WordOfNurturingGreater_Normal **** **** **** **** **** **** **** **** +3639 WordOfNurturingGreater_Reverse **** **** **** **** **** **** **** **** +3640 **** **** **** **** **** **** **** **** **** +3641 Wild_Shape_Plant **** **** **** **** **** **** **** **** +3642 Wild_Shape_Plant_01 **** **** **** **** **** **** **** **** +3643 Wild_Shape_Plant_02 **** **** **** **** **** **** **** **** +3644 Wild_Shape_Plant_03 **** **** **** **** **** **** **** **** +3645 Wild_Shape_Plant_04 **** **** **** **** **** **** **** **** +3646 Wild_Shape_Plant_05 **** **** **** **** **** **** **** **** +3647 **** **** **** **** **** **** **** **** **** +3648 **** **** **** **** **** **** **** **** **** +3649 Unseen_Weapon_Activate **** **** **** **** **** **** **** **** +3650 Unseen_Weapon_Unerring_Strike **** **** **** **** **** **** **** **** +3651 Unseen_Weapon_Unexpected_Strike **** **** **** **** **** **** **** **** +3652 Unseen_Weapon_Ephemeral_Weapon **** **** **** **** **** **** **** **** +3653 Unseen_Weapon_Shadowy_Strike **** **** **** **** **** **** **** **** +3654 Unseen_Weapon_Far_Shadow **** **** **** **** **** **** **** **** +3655 GreaterScrying **** **** **** **** **** **** **** **** +3656 DiscernLocation **** **** **** **** **** **** **** **** +3657 LocateCreature **** **** **** **** **** **** **** **** +3658 LocateObject **** **** **** **** **** **** **** **** +3659 ArcaneEye **** **** **** **** **** **** **** **** +3660 ObscureObject **** **** **** **** **** **** **** **** +3661 Sequester **** **** **** **** **** **** **** **** +3662 SarcophagusOfStone **** Reflex **** R 1 **** **** **** +3663 ArrowOfBone **** **** **** **** **** **** **** **** +3664 DraconicMight **** **** **** E 0 2 9 **** +3665 ExtractWaterElemental **** Fortitude 1 R 1 **** **** **** +3666 HeartRipper **** **** **** **** **** **** **** **** +3667 LifeBolt **** **** **** **** **** **** **** **** +3668 RainbowBlast **** Reflex 1 I 1 **** **** **** +3669 ToweringOak **** **** **** E 0 2 0 **** +3670 LifeBolt1Bolt **** **** **** **** **** **** **** **** +3671 LifeBolt2Bolts **** **** **** **** **** **** **** **** +3672 LifeBolt3Bolts **** **** **** **** **** **** **** **** +3673 LifeBolt4Bolts **** **** **** **** **** **** **** **** +3674 LifeBolt5Bolts **** **** **** **** **** **** **** **** +3675 DisruptUndead **** **** **** **** **** **** **** **** +3676 Otilukes_Resilient_Sphere **** Reflex 1 R 1 **** **** **** +3677 FistOfStone **** **** **** E 0 2 0 **** +3678 BladesOfFire **** **** **** E 0 2 15 **** +3679 FireTrap **** **** **** **** **** **** **** **** +3680 Pyrotechnics **** **** **** **** **** **** **** **** +3681 IceKnife **** **** **** **** **** **** **** **** +3682 MassFireShieldRed **** **** **** **** **** **** **** **** +3683 WhirlingBlade **** **** **** I 1 **** **** **** +3684 PnP_FireShield **** **** **** **** **** **** **** **** +3685 RingOfBlades **** **** **** E 0 2 7 **** +3686 SleetStorm **** **** **** I 1 **** **** **** +3687 OrbOfForce **** **** **** R 1 **** **** **** +3688 MassFireShield **** **** **** **** **** **** **** **** +3689 PrismaticRay **** Reflex 1 R 1 **** **** **** +3690 SwordsageRecoverManeuver **** **** **** **** **** **** **** **** +3691 OtilukesFreezingSphere Cold Reflex 1 I 1 **** **** **** +3692 WavesOfExhaustion **** **** 1 I 1 **** **** **** +3693 PrismaticWall **** Reflex 1 I 1 **** **** **** +3694 ScintillatingPattern Mind_Affecting **** 1 I 1 **** **** **** +3695 PrismaticSphere **** **** **** P 0 2 0 **** +3696 Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +3697 Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +3698 GreaterDisruptUndead **** **** **** **** **** **** **** **** +3699 PnP_FireShieldRed **** **** **** **** **** **** **** **** +3700 PnPFireShieldBlue **** **** **** **** **** **** **** **** +3701 MassFireShieldBlue **** **** **** **** **** **** **** **** +3702 ArrowStorm **** **** **** **** **** **** **** **** +3703 ArrowSplit **** **** **** R 1 **** **** **** +3704 BloodfreezeArrow Cold Fortitude 1 R 1 **** **** **** +3705 DischargeCrown **** **** **** **** **** **** **** **** +3706 DoublestrikeArrow **** **** **** D 1 **** **** **** +3707 DetectFavoredEnemies **** **** **** **** **** **** **** **** +3708 DarkflameArrow **** **** 1 R 1 **** **** **** +3709 HealAnimalCompanion **** **** **** **** **** **** **** **** +3710 ShadowArrow **** **** 1 R 1 **** **** **** +3711 Snare **** **** **** **** **** **** **** **** +3712 SpellslayerArrow **** **** 1 R 1 **** **** **** +3713 AcidicFire **** **** **** **** **** **** **** **** +3714 AlchemistsFrost **** **** **** **** **** **** **** **** +3715 AlchemicalSleepingGas **** **** **** **** **** **** **** **** +3716 AlchemistsSpark **** **** **** **** **** **** **** **** +3717 BlendCream **** **** **** **** **** **** **** **** +3718 Brittlebone **** **** **** **** **** **** **** **** +3719 Cracklepowder **** **** **** **** **** **** **** **** +3720 EmbalmingFire **** **** **** **** **** **** **** **** +3721 FareyeOil **** **** **** **** **** **** **** **** +3722 FesteringBomb **** **** **** **** **** **** **** **** +3723 FlashPellet **** **** **** **** **** **** **** **** +3724 HealersBalm **** **** **** **** **** **** **** **** +3725 KeenearPowder **** **** **** **** **** **** **** **** +3726 LockslipGrease **** **** **** **** **** **** **** **** +3727 NaturesDraught **** **** **** **** **** **** **** **** +3728 Nerv **** **** **** **** **** **** **** **** +3729 ScreamingFlask **** **** **** **** **** **** **** **** +3730 Softfoot **** **** **** **** **** **** **** **** +3731 WeepingStone **** **** **** **** **** **** **** **** +3732 BileDroppings **** **** **** **** **** **** **** **** +3733 Shedden **** **** **** **** **** **** **** **** +3734 Shedden2 **** **** **** **** **** **** **** **** +3735 Shedden3 **** **** **** **** **** **** **** **** +3736 Shedden4 **** **** **** **** **** **** **** **** +3737 Shedden5 **** **** **** **** **** **** **** **** +3738 Antitoxin **** **** **** **** **** **** **** **** +3739 SuddenRecover **** **** **** **** **** **** **** **** +3740 SongWhiteRaven **** **** **** **** **** **** **** **** +3741 StonePower **** **** **** **** **** **** **** **** +3742 MorphemeSavant_Master **** **** **** **** **** **** **** **** +3743 ShadowmasterConceal **** **** **** **** **** **** **** **** +3744 Shadowmaster_Shades_Master **** **** **** **** **** **** **** **** +3745 Shadowmaster_Summon_Shadow **** **** **** **** **** **** **** **** +3746 Shadowmaster_Cone_of_Cold **** **** **** **** **** **** **** **** +3747 Shadowmaster_Fireball **** **** **** **** **** **** **** **** +3748 Shadowmaster_Stoneskin **** **** **** **** **** **** **** **** +3749 Shadowmaster_Wall_of_Fire **** **** **** **** **** **** **** **** +3750 MorphemeSavantKill **** **** **** **** **** **** **** **** +3751 MorphemeSavantStun **** **** **** **** **** **** **** **** +3752 MasterOfElements_Master **** **** **** **** **** **** **** **** +3753 MasterOfElements_SummonAir **** **** **** **** **** **** **** **** +3754 MasterOfElements_SummonEarth **** **** **** **** **** **** **** **** +3755 MasterOfElements_SummonFire **** **** **** **** **** **** **** **** +3756 MasterOfElements_SummonWater **** **** **** **** **** **** **** **** +3757 MasterOfElements_Dominate **** **** **** **** **** **** **** **** +3758 LordOfAllEssences **** **** **** **** **** **** **** **** +3759 TouchVitality_Master **** **** **** **** **** **** **** **** +3760 PresenceAura **** **** **** **** **** **** **** **** +3761 VigorAura **** **** **** **** **** **** **** **** +3762 ToughnesAura **** **** **** **** **** **** **** **** +3763 EnergyShldAura **** **** **** **** **** **** **** **** +3764 ResistanceAura **** **** **** **** **** **** **** **** +3765 PowerAura **** **** **** **** **** **** **** **** +3766 SenseAura **** **** **** **** **** **** **** **** +3767 TouchVitality **** **** **** **** **** **** **** **** +3768 TouchVitalityMinor **** **** **** **** **** **** **** **** +3769 TouchVitalityRestore **** **** **** **** **** **** **** **** +3770 TouchVitalityMajor **** **** **** **** **** **** **** **** +3771 DragonShamanBreath **** **** **** **** **** **** **** **** +3772 InsightAura **** **** **** **** **** **** **** **** +3773 ResolveAura **** **** **** **** **** **** **** **** +3774 StaminaAura **** **** **** **** **** **** **** **** +3775 SwiftnessAura **** **** **** **** **** **** **** **** +3776 BonusResistAcidAura **** **** **** **** **** **** **** **** +3777 BonusResistColdAura **** **** **** **** **** **** **** **** +3778 BonusResistElecAura **** **** **** **** **** **** **** **** +3779 BonusResistFireAura **** **** **** **** **** **** **** **** +3780 MarshalInsightAura **** **** **** **** **** **** **** **** +3781 MarshalPresenceAura **** **** **** **** **** **** **** **** +3782 MarshalResistAcidAura **** **** **** **** **** **** **** **** +3783 MarshalResistColdAura **** **** **** **** **** **** **** **** +3784 MarshalResistElecAura **** **** **** **** **** **** **** **** +3785 MarshalResistFireAura **** **** **** **** **** **** **** **** +3786 MarshalResolveAura **** **** **** **** **** **** **** **** +3787 MarshalSensesAura **** **** **** **** **** **** **** **** +3788 MarshalStaminaAura **** **** **** **** **** **** **** **** +3789 MarshalSwiftnessAura **** **** **** **** **** **** **** **** +3790 MarshalToughnessAura **** **** **** **** **** **** **** **** +3791 DivineIntercession **** **** **** **** **** **** **** **** +3792 ProfaneAgony **** **** **** **** **** **** **** **** +3793 LolthsBoon **** **** **** **** **** **** **** **** +3794 Snap_Kick **** **** **** **** **** **** **** **** +3795 Verminlord_Master **** **** **** **** **** **** **** **** +3796 Verminlord_CreepingDoom **** **** **** **** **** **** **** **** +3797 Verminlord_Dominate_Vermin **** **** **** **** **** **** **** **** +3798 DespanaSchool **** **** **** **** **** **** **** **** +3799 Crinti_ShadowRide **** **** **** **** **** **** **** **** +3800 Crinti_ShadowWalk **** **** **** **** **** **** **** **** +3801 Earth_Strike **** **** **** **** **** **** **** **** +3802 FrostFolk_IceBlast **** **** **** **** **** **** **** **** +3803 TouchFatigue **** Fortitude 1 T 1 **** **** **** +3804 Uldra_Ray_of_Frost **** **** **** **** **** **** **** **** +3805 Uldra_TouchFatigue **** **** **** **** **** **** **** **** +3806 BonusInsightAura **** **** **** **** **** **** **** **** +3807 BonusPresenceAura **** **** **** **** **** **** **** **** +3808 BonusResolveAura **** **** **** **** **** **** **** **** +3809 BonusSensesAura **** **** **** **** **** **** **** **** +3810 BonusStaminaAura **** **** **** **** **** **** **** **** +3811 BonusSwiftnessAura **** **** **** **** **** **** **** **** +3812 BonusToughnessAura **** **** **** **** **** **** **** **** +3813 MagicPowerAura **** **** **** **** **** **** **** **** +3814 MarshalMagicPowerAura **** **** **** **** **** **** **** **** +3815 BonusMagicPowerAura **** **** **** **** **** **** **** **** +3816 Marrulurk_NauseatingBreath **** **** **** **** **** **** **** **** +3817 EnergyAura **** **** **** **** **** **** **** **** +3818 MarshalAcidEnergyAura **** **** **** **** **** **** **** **** +3819 MarshalColdEnergyAura **** **** **** **** **** **** **** **** +3820 MarshalElecEnergyAura **** **** **** **** **** **** **** **** +3821 MarshalFireEnergyAura **** **** **** **** **** **** **** **** +3822 BonusAcidEnergyAura **** **** **** **** **** **** **** **** +3823 BonusColdEnergyAura **** **** **** **** **** **** **** **** +3824 BonusElecEnergyAura **** **** **** **** **** **** **** **** +3825 BonusFireEnergyAura **** **** **** **** **** **** **** **** +3826 ExtaminaarCharmAnimal **** **** **** **** **** **** **** **** +3827 SuddenStalagmite **** Reflex **** R 1 **** **** **** +3828 BonesOfTheEarth **** **** **** **** **** **** **** **** +3829 BonesOfTheEarth_Feat **** **** **** **** **** **** **** **** +3830 Hallow **** **** **** **** **** **** **** **** +3831 DauntingPresence **** **** **** **** **** **** **** **** +3832 ProfaneLifeleech **** **** **** **** **** **** **** **** +3833 SacredVitality **** **** **** **** **** **** **** **** +3834 SacredVengeance **** **** **** **** **** **** **** **** +3835 Deformity(eyes) **** **** **** **** **** **** **** **** +3836 Deformity(parasite) **** **** **** **** **** **** **** **** +3837 DarkSpeech **** **** **** **** **** **** **** **** +3838 DarkSpeechDread **** **** **** **** **** **** **** **** +3839 DarkSpeechPower **** **** **** **** **** **** **** **** +3840 DarkWhispers **** **** **** **** **** **** **** **** +3841 Deformity(madness) **** **** **** **** **** **** **** **** +3842 ReflexivePsychosis **** **** **** **** **** **** **** **** +3843 ChosenOfEvil **** **** **** **** **** **** **** **** +3844 MastersWill **** **** **** **** **** **** **** **** +3845 ChosenOfEvilAttack **** **** **** **** **** **** **** **** +3846 ChosenOfEvilSkill **** **** **** **** **** **** **** **** +3847 ChosenOfEvilSave **** **** **** **** **** **** **** **** +3848 ShieldOther **** **** **** P 0 3 9 **** +3849 TensersFloatingDisk **** **** **** **** **** **** **** **** +3850 Wolfskin **** **** **** P 0 2 0 -17 +3851 True_Casting **** **** **** **** **** **** **** **** +3852 Mass_Spell_Resistance **** **** **** P 0 2 14 **** +3853 Magic_Stone **** **** **** **** **** **** **** **** +3854 Control_Weather **** **** **** **** **** **** **** **** +3855 CW_Rain **** **** **** **** **** **** **** **** +3856 CW_Snow **** **** **** **** **** **** **** **** +3857 CW_Clear **** **** **** **** **** **** **** **** +3858 Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +3859 Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +3860 Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +3861 Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +3862 Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +3863 Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +3864 Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +3865 Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +3866 Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +3867 Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +3868 Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +3869 Elder_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +3870 Elder_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +3871 Elder_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +3872 Elder_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +3873 Elder_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +3874 Elder_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +3875 Elemental_Strike **** **** **** **** **** **** **** **** +3876 Elemental_Strike_Acid **** **** **** **** **** **** **** **** +3877 Elemental_Strike_Cold **** **** **** **** **** **** **** **** +3878 Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +3879 Elemental_Strike_Fire **** **** **** **** **** **** **** **** +3880 Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +3881 WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +3882 WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +3883 WordOfRecall_Party **** **** **** **** **** **** **** **** +3884 TransportViaPlants_RadialMaster **** **** **** **** **** **** **** **** +3885 TransportViaPlants_SelfOnly **** **** **** **** **** **** **** **** +3886 TransportViaPlants_Party **** **** **** **** **** **** **** **** +3887 Factotum_ArcaneDilettante_1 **** **** **** **** **** **** **** **** +3888 Factotum_ArcaneDilettante_2 **** **** **** **** **** **** **** **** +3889 Factotum_ArcaneDilettante_3 **** **** **** **** **** **** **** **** +3890 Factotum_ArcaneDilettante_4 **** **** **** **** **** **** **** **** +3891 Factotum_ArcaneDilettante_5 **** **** **** **** **** **** **** **** +3892 Factotum_ArcaneDilettante_6 **** **** **** **** **** **** **** **** +3893 Factotum_ArcaneDilettante_7 **** **** **** **** **** **** **** **** +3894 Factotum_ArcaneDilettante_8 **** **** **** **** **** **** **** **** +3895 Factotum_Cunning_Insight_Attack **** **** **** **** **** **** **** **** +3896 Factotum_Cunning_Insight_Damage **** **** **** **** **** **** **** **** +3897 Factotum_Cunning_Insight_Saves **** **** **** **** **** **** **** **** +3898 Factotum_Cunning_Defense **** **** **** **** **** **** **** **** +3899 Factotum_Cunning_Strike **** **** **** **** **** **** **** **** +3900 Factotum_Cunning_Surge **** **** **** **** **** **** **** **** +3901 Factotum_Cunning_Breach **** **** **** **** **** **** **** **** +3902 Factotum_Cunning_Dodge **** **** **** **** **** **** **** **** +3903 Factotum_Cunning_Knowledge **** **** **** **** **** **** **** **** +3904 Factotum_Opportunistic_Piety_Heal **** **** **** **** **** **** **** **** +3905 Factotum_Opportunistic_Piety_Turn **** **** **** **** **** **** **** **** +3906 Factotum_ArcaneDilettante_SlotCheck **** **** **** **** **** **** **** **** +3907 Sharess_Fascinate **** **** **** **** **** **** **** **** +3908 Sharess_Confuse **** **** **** **** **** **** **** **** +3909 Sharess_Dominate **** **** **** **** **** **** **** **** +3910 Sharess_Sanctuary **** **** **** **** **** **** **** **** +3911 Sharess_Haste **** **** **** **** **** **** **** **** +3912 ForceOrb **** Reflex 1 R 1 **** **** **** +3913 Forsaker_FastHealing **** **** **** **** **** **** **** **** +3914 AugmentTrueFriend **** **** **** **** **** **** **** **** +3915 UrPriestSiphonSpellPower **** **** **** **** **** **** **** **** +3916 UrPriestSiphonSpellPower_Conv **** **** **** **** **** **** **** **** +3917 Factotum_CunningBrilliance_1 **** **** **** **** **** **** **** **** +3918 Factotum_CunningBrilliance_2 **** **** **** **** **** **** **** **** +3919 Factotum_CunningBrilliance_3 **** **** **** **** **** **** **** **** +3920 Factotum_CunningBrilliance_SlotCheck **** **** **** **** **** **** **** **** +3921 Arkamoi_ArcaneMastermind **** **** **** **** **** **** **** **** +3922 AlignedAura **** **** **** **** **** **** **** **** +3923 Angelskin **** **** **** **** **** **** **** **** +3924 AxiomaticStorm **** **** **** **** **** **** **** **** +3925 Bladebane **** **** **** **** **** **** **** **** +3926 BlessedAim **** **** **** **** **** **** **** **** +3927 BlessingOfTheRighteous **** **** **** **** **** **** **** **** +3928 ClearMind **** **** **** **** **** **** **** **** +3929 CloakOfBravery **** **** **** **** **** **** **** **** +3930 Diamondsteel **** **** **** **** **** **** **** **** +3931 LesserAspectOfTheDiety **** **** **** **** **** **** **** **** +3932 LawfulSword **** **** **** **** **** **** **** **** +3933 LesserAuraOfCold **** **** **** **** **** **** **** **** +3934 AuraOfTheSun **** **** **** **** **** **** **** **** +3935 RighteousFury **** **** **** **** **** **** **** **** +3936 SeekEternalRest **** **** **** **** **** **** **** **** +3937 StrengthOfStone **** **** **** **** **** **** **** **** +3938 UndeadBaneWeapon **** **** **** **** **** **** **** **** +3939 LesserViageOfTheDiety **** **** **** **** **** **** **** **** +3940 AlignedAuraChaos **** **** **** **** **** **** **** **** +3941 AlignedAuraEvil **** **** **** **** **** **** **** **** +3942 AlignedAuraGood **** **** **** **** **** **** **** **** +3943 AlignedAuraLaw **** **** **** **** **** **** **** **** +3944 AxiomaticWater **** **** **** **** **** **** **** **** +3945 BlazeOfLight **** **** **** **** **** **** **** **** +3946 CallMount **** **** **** **** **** **** **** **** +3947 Castigate **** **** **** **** **** **** **** **** +3948 CheckmatesLight **** **** **** **** **** **** **** **** +3949 ConduitOfLight **** **** **** **** **** **** **** **** +3950 CurseOfTheBrute **** **** **** **** **** **** **** **** +3951 Denounce **** **** **** **** **** **** **** **** +3952 DevastatingSmite **** **** **** **** **** **** **** **** +3953 DivinePresence **** **** **** **** **** **** **** **** +3954 EmbraceOfEndlessDay **** **** **** **** **** **** **** **** +3955 EnergizedShield **** **** **** **** **** **** **** **** +3956 LesserEnergizedShield **** **** **** **** **** **** **** **** +3957 EstanasStew **** **** **** **** **** **** **** **** +3958 FavorOfTheMartyr **** **** **** **** **** **** **** **** +3959 Forceward **** **** **** **** **** **** **** **** +3960 GloryOfTheMartyr **** **** **** **** **** **** **** **** +3961 HolyFire **** **** **** **** **** **** **** **** +3962 HolyStorm **** **** **** **** **** **** **** **** +3963 InvokeTheCeruleanSign **** **** **** **** **** **** **** **** +3964 IrresistibleForce **** **** **** **** **** **** **** **** +3965 LegionsMagicWeapon **** **** **** **** **** **** **** **** +3966 MajorResistance **** **** **** **** **** **** **** **** +3967 MeteoricStrike **** **** **** **** **** **** **** **** +3968 QuickMarch **** **** **** **** **** **** **** **** +3969 ResistEnergy **** **** **** **** **** **** **** **** +3970 Revenance **** **** **** **** **** **** **** **** +3971 RhinosRush **** **** **** **** **** **** **** **** +3972 RighteousAura **** **** **** **** **** **** **** **** +3973 SeedOfLife **** **** **** **** **** **** **** **** +3974 ShieldOfWarding **** **** **** **** **** **** **** **** +3975 SmiteHeretic **** **** **** **** **** **** **** **** +3976 SmiteOfSacredFire **** **** **** **** **** **** **** **** +3977 SoldiersOfSanctity **** **** **** **** **** **** **** **** +3978 SoulOfLight **** **** **** **** **** **** **** **** +3979 SoulOfOrder **** **** **** **** **** **** **** **** +3980 Stabilize **** **** **** **** **** **** **** **** +3981 StrategicCharge **** **** **** **** **** **** **** **** +3982 TouchOfRestoration **** **** **** **** **** **** **** **** +3983 TruePrayerOfTheChosen **** **** **** **** **** **** **** **** +3984 TruePrayerOfTheFaithful **** **** **** **** **** **** **** **** +3985 UnmovableIbject **** **** **** **** **** **** **** **** +3986 BFZ_FatefulStride **** **** **** **** **** **** **** **** +3987 TN_DES_100 **** **** **** **** **** **** **** **** +3988 TN_DES_20 **** **** **** **** **** **** **** **** +3989 Hext_Fright **** **** **** **** **** **** **** **** +3990 INSTRUMENT **** **** **** **** **** **** **** **** +3991 LLIIRAS_AURA **** **** **** **** **** **** **** **** +3992 MIELIKKI_TRUTH **** **** **** **** **** **** **** **** +3993 LYCANBANE **** **** **** **** **** **** **** **** +3994 CRAFT_MHARPER_ITEM **** **** **** **** **** **** **** **** +3995 Shou_Flurry **** **** **** **** **** **** **** **** +3996 TN_Unsummon **** **** **** **** **** **** **** **** +3997 Summon_fiend **** **** **** **** **** **** **** **** +3998 Pit_Glare **** **** **** **** **** **** **** **** +3999 Fiendish_Glare **** **** **** **** **** **** **** **** +4000 Epic_Spell_Achilles_Heel **** **** **** **** **** **** **** **** +4001 Epic_Spell_All_Hope_Lost **** **** **** **** **** **** **** **** +4002 Epic_Spell_Allied_Martyr **** **** **** **** **** **** **** **** +4003 Epic_Spell_Anarchys_Call **** **** **** **** **** **** **** **** +4004 Epic_Spell_Animus_Blast **** **** **** **** **** **** **** **** +4005 Epic_Spell_Animus_Blizzard **** **** **** **** **** **** **** **** +4006 Epic_Spell_Army_Unfallen **** **** **** **** **** **** **** **** +4007 Epic_Spell_Audience_of_Stone **** **** **** **** **** **** **** **** +4008 Epic_Spell_Battle_Bounding **** **** **** **** **** **** **** **** +4009 Epic_Spell_Celestial_Council **** **** **** **** **** **** **** **** +4010 Epic_Spell_Champions_Valor **** **** **** **** **** **** **** **** +4011 Epic_Spell_Contingent_Resurrection **** **** **** **** **** **** **** **** +4012 Epic_Spell_Contingent_Reunion **** **** **** **** **** **** **** **** +4013 Epic_Spell_Deadeye_Sense **** **** **** **** **** **** **** **** +4014 Epic_Spell_Deathmark **** **** **** **** **** **** **** **** +4015 Epic_Spell_Dire_Winter **** **** **** **** **** **** **** **** +4016 Epic_Spell_Dragon_Knight **** **** **** **** **** **** **** **** +4017 Epic_Spell_Dreamscape **** **** **** **** **** **** **** **** +4018 Epic_Spell_Dullblades **** **** **** **** **** **** **** **** +4019 Epic_Spell_Dweomer_Thief **** **** **** **** **** **** **** **** +4020 Epic_Spell_Enslave **** **** **** **** **** **** **** **** +4021 Epic_Spell_Epic_Mage_Armor **** **** **** **** **** **** **** **** +4022 Epic_Spell_Epic_Repulsion **** **** **** **** **** **** **** **** +4023 Epic_Spell_Epic_Spell_Reflection **** **** **** **** **** **** **** **** +4024 Epic_Spell_Epic_Warding **** **** **** **** **** **** **** **** +4025 Epic_Spell_Eternal_Freedom **** **** **** **** **** **** **** **** +4026 Epic_Spell_Fiendish_Words **** **** **** **** **** **** **** **** +4027 Epic_Spell_Fleetness_of_Foot **** **** **** **** **** **** **** **** +4028 Epic_Spell_Gem_Cage **** **** **** **** **** **** **** **** +4029 Epic_Spell_Godsmite **** **** **** **** **** **** **** **** +4030 Epic_Spell_Greater_Ruin **** **** **** **** **** **** **** **** +4031 Epic_Spell_Greater_Spell_Resistance **** **** **** **** **** **** **** **** +4032 Epic_Spell_Greater_Timestop **** **** **** **** **** **** **** **** +4033 Epic_Spell_Hell_Send **** **** **** **** **** **** **** **** +4034 Epic_Spell_Hellball **** **** **** **** **** **** **** **** +4035 Epic_Spell_Herculean_Alliance **** **** **** **** **** **** **** **** +4036 Epic_Spell_Herculean_Empowerment **** **** **** **** **** **** **** **** +4037 Epic_Spell_Impenetrability **** **** **** **** **** **** **** **** +4038 Epic_Spell_Leech_Field **** **** **** **** **** **** **** **** +4039 Epic_Spell_Legendary_Artisan **** **** **** **** **** **** **** **** +4040 Epic_Spell_Life_Force_Transfer **** **** **** **** **** **** **** **** +4041 Epic_Spell_Magma_Burst **** **** **** **** **** **** **** **** +4042 Epic_Spell_Mass_Penguin **** **** **** **** **** **** **** **** +4043 Epic_Spell_Momento_Mori **** **** **** **** **** **** **** **** +4044 Epic_Spell_Mummy_Dust **** **** **** **** **** **** **** **** +4045 Epic_Spell_Nailed_to_the_Sky **** **** **** **** **** **** **** **** +4046 Epic_Spell_Nights_Undoing **** **** **** **** **** **** **** **** +4047 Epic_Spell_Order_Restored **** **** **** **** **** **** **** **** +4048 Epic_Spell_Paths_Become_Known **** **** **** **** **** **** **** **** +4049 Epic_Spell_Peerless_Penitence **** **** **** **** **** **** **** **** +4050 Epic_Spell_Pestilence **** **** **** **** **** **** **** **** +4051 Epic_Spell_Pious_Parley **** **** **** **** **** **** **** **** +4052 Epic_Spell_Planar_Cell **** **** **** **** **** **** **** **** +4053 Epic_Spell_Psionic_Salvo **** **** **** **** **** **** **** **** +4054 Epic_Spell_Rain_of_Fire **** **** **** **** **** **** **** **** +4055 Epic_Spell_Risen_Reunited **** **** **** **** **** **** **** **** +4056 Epic_Spell_Ruin **** **** **** **** **** **** **** **** +4057 Epic_Spell_Singular_Sunder **** **** **** **** **** **** **** **** +4058 Epic_Spell_Spell_Worm **** **** **** **** **** **** **** **** +4059 Epic_Spell_Storm_Mantle **** **** **** **** **** **** **** **** +4060 Epic_Spell_Summon_Aberration **** **** **** **** **** **** **** **** +4061 Epic_Spell_Superb_Dispelling **** **** **** **** **** **** **** **** +4062 Epic_Spell_Symrustars_Spellbinding **** **** **** **** **** **** **** **** +4063 Epic_Spell_The_Withering **** **** **** **** **** **** **** **** +4064 Epic_Spell_Tolodines_Killing_Wind **** **** **** **** **** **** **** **** +4065 Epic_Spell_Transcendent_Vitality **** **** **** **** **** **** **** **** +4066 Epic_Spell_Twinfiend **** **** **** **** **** **** **** **** +4067 Epic_Spell_Unholy_Disciple **** **** **** **** **** **** **** **** +4068 Epic_Spell_Unimpinged **** **** **** **** **** **** **** **** +4069 Epic_Spell_Unseen_Wanderer **** **** **** **** **** **** **** **** +4070 Epic_Spell_Whip_of_Shar **** **** **** **** **** **** **** **** +4071 Wander_Unseen **** **** **** **** **** **** **** **** +4072 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4073 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4074 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4075 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4076 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4077 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4078 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4079 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4080 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4081 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4082 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4083 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4084 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4085 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4086 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4087 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4088 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4089 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4090 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4091 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4092 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4093 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4094 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4095 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4096 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4097 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4098 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4099 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4100 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4101 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4102 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4103 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4104 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4105 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4106 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4107 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4108 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4109 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4110 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4111 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4112 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4113 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4114 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4115 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4116 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4117 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4118 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4119 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4120 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4121 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4122 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4123 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4124 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4125 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4126 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4127 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4128 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4129 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4130 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4131 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4132 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4133 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4134 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4135 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4136 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4137 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4138 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4139 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4140 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4141 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4142 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4143 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4144 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4145 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4146 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4147 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4148 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4149 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4150 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4151 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4152 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4153 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4154 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4155 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4156 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4157 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4158 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4159 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4160 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4161 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4162 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4163 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4164 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4165 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4166 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4167 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4168 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4169 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4170 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4171 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4172 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4173 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4174 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4175 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4176 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4177 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4178 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4179 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4180 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4181 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4182 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4183 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4184 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4185 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4186 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4187 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4188 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4189 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4190 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4191 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4192 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4193 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4194 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4195 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4196 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4197 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4198 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4199 ReservedForISCAndESS **** **** **** **** **** **** **** **** +4200 ####START_OF_NEW_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +4201 Bard_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +4202 Bard_Dancing_Lights **** **** **** **** **** **** **** **** +4203 Bard_Daze **** **** **** **** **** **** **** **** +4204 Bard_Flare **** **** **** **** **** **** **** **** +4205 Bard_Light **** **** **** **** **** **** **** **** +4206 Bard_MAGE_HAND **** **** **** **** **** **** **** **** +4207 Bard_Read_Magic **** **** **** **** **** **** **** **** +4208 Bard_Resistance **** **** **** **** **** **** **** **** +4209 Bard_Amplify **** **** **** **** **** **** **** **** +4210 Bard_BalagarnsIronHorn **** **** **** **** **** **** **** **** +4211 Bard_Cause_Fear **** **** **** **** **** **** **** **** +4212 Bard_Charm_Person **** **** **** **** **** **** **** **** +4213 Bard_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4214 Bard_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +4215 Bard_Disguise_Self_Learn **** **** **** **** **** **** **** **** +4216 Bard_Disguise_Self_Options **** **** **** **** **** **** **** **** +4217 Bard_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +4218 Bard_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +4219 Bard_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +4220 Bard_Expeditious_Retreat **** **** **** **** **** **** **** **** +4221 Bard_EXTRACT_DRUG **** **** **** **** **** **** **** **** +4222 Bard_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +4223 Bard_EXTRACT_VODARE **** **** **** **** **** **** **** **** +4224 Bard_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +4225 Bard_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +4226 Bard_Grease **** **** **** **** **** **** **** **** +4227 Bard_Identify **** **** **** **** **** **** **** **** +4228 Bard_Lesser_Dispel **** **** **** **** **** **** **** **** +4229 Bard_Mage_Armor **** **** **** **** **** **** **** **** +4230 Bard_Magic_Weapon **** **** **** **** **** **** **** **** +4231 Bard_ObscureObject **** **** **** **** **** **** **** **** +4232 Bard_Protection_from_Chaos **** **** **** **** **** **** **** **** +4233 Bard_Protection_from_Evil **** **** **** **** **** **** **** **** +4234 Bard_Protection_from_Good **** **** **** **** **** **** **** **** +4235 Bard_Protection_from_Law **** **** **** **** **** **** **** **** +4236 Bard_RAY_OF_HOPE **** **** **** **** **** **** **** **** +4237 Bard_Sleep **** **** **** **** **** **** **** **** +4238 Bard_SORROW **** **** **** **** **** **** **** **** +4239 Bard_Summon_Creature_I **** **** **** **** **** **** **** **** +4240 Bard_ADDICTION **** **** **** **** **** **** **** **** +4241 Bard_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +4242 Bard_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +4243 Bard_ADDICTION_VODARE **** **** **** **** **** **** **** **** +4244 Bard_ADDICTION_AGONY **** **** **** **** **** **** **** **** +4245 Bard_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +4246 Bard_Alter_Self_Learn **** **** **** **** **** **** **** **** +4247 Bard_Alter_Self_Options **** **** **** **** **** **** **** **** +4248 Bard_Alter_Self_QS1 **** **** **** **** **** **** **** **** +4249 Bard_Alter_Self_QS2 **** **** **** **** **** **** **** **** +4250 Bard_Alter_Self_QS3 **** **** **** **** **** **** **** **** +4251 Bard_Blindness_and_Deafness **** **** **** **** **** **** **** **** +4252 Bard_Blur **** **** **** **** **** **** **** **** +4253 Bard_Bulls_Strength **** **** **** **** **** **** **** **** +4254 Bard_Calm_Emotions **** **** **** **** **** **** **** **** +4255 Bard_Cats_Grace **** **** **** **** **** **** **** **** +4256 Bard_Clarity **** **** **** **** **** **** **** **** +4257 Bard_Cloud_of_Bewilderment **** **** **** **** **** **** **** **** +4258 Bard_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +4259 Bard_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +4260 Bard_Darkness **** **** **** **** **** **** **** **** +4261 Bard_Daze_Monster **** **** **** **** **** **** **** **** +4262 Bard_Eagle_Splendor **** **** **** **** **** **** **** **** +4263 Bard_ELATION **** **** **** **** **** **** **** **** +4264 Bard_Foxs_Cunning **** **** **** **** **** **** **** **** +4265 Bard_Ghostly_Visage **** **** **** **** **** **** **** **** +4266 Bard_Glitterdust **** **** **** **** **** **** **** **** +4267 Bard_Heroism **** **** **** **** **** **** **** **** +4268 Bard_Hold_Person **** **** **** **** **** **** **** **** +4269 Bard_Invisibility **** **** **** **** **** **** **** **** +4270 Bard_LocateObject **** **** **** **** **** **** **** **** +4271 Bard_MirrorImage **** **** **** **** **** **** **** **** +4272 Bard_Owls_Wisdom **** **** **** **** **** **** **** **** +4273 Bard_Pyrotechnics **** **** **** **** **** **** **** **** +4274 Bard_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +4275 Bard_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +4276 Bard_Scare **** **** **** **** **** **** **** **** +4277 Bard_See_Invisibility **** **** **** **** **** **** **** **** +4278 Bard_Silence **** **** **** **** **** **** **** **** +4279 Bard_SONG_OF_FESTERING_DEATH **** **** **** **** **** **** **** **** +4280 Bard_Sound_Burst **** **** **** **** **** **** **** **** +4281 Bard_Summon_Creature_II **** **** **** **** **** **** **** **** +4282 Bard_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +4283 Bard_Ultravision **** **** **** **** **** **** **** **** +4284 Bard_UndetectableAlignment **** **** **** **** **** **** **** **** +4285 Bard_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +4286 Bard_WhirlingBlade **** **** **** **** **** **** **** **** +4287 Bard_Bestow_Curse **** **** **** **** **** **** **** **** +4288 Bard_Charm_Monster **** **** **** **** **** **** **** **** +4289 Bard_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +4290 Bard_Confusion **** **** **** **** **** **** **** **** +4291 Bard_CrushingDespair **** **** **** **** **** **** **** **** +4292 Bard_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +4293 Bard_CURSE_OF_THE_PUTRID_HUSK **** **** **** **** **** **** **** **** +4294 Bard_Daylight **** **** **** **** **** **** **** **** +4295 Bard_Dispel_Magic **** **** **** **** **** **** **** **** +4296 Bard_Displacement **** **** **** **** **** **** **** **** +4297 Bard_Fear **** **** **** **** **** **** **** **** +4298 Bard_Find_Traps **** **** **** **** **** **** **** **** +4299 Bard_GLIBNESS **** **** **** **** **** **** **** **** +4300 Bard_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +4301 Bard_Gust_of_Wind **** **** **** **** **** **** **** **** +4302 Bard_Halt **** **** **** **** **** **** **** **** +4303 Bard_Haste **** **** **** **** **** **** **** **** +4304 Bard_Invisibility_Sphere **** **** **** **** **** **** **** **** +4305 Bard_Keen_Edge **** **** **** **** **** **** **** **** +4306 Bard_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +4307 Bard_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +4308 Bard_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +4309 Bard_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +4310 Bard_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +4311 Bard_Remove_Curse **** **** **** **** **** **** **** **** +4312 Bard_Remove_Disease **** **** **** **** **** **** **** **** +4313 Bard_Scrying **** **** **** **** **** **** **** **** +4314 Bard_Slow **** **** **** **** **** **** **** **** +4315 Bard_Sonic_Shield **** **** **** **** **** **** **** **** +4316 Bard_STUNNING_SCREECH **** **** **** **** **** **** **** **** +4317 Bard_Summon_Creature_III **** **** **** **** **** **** **** **** +4318 Bard_Weapon_of_Impact **** **** **** **** **** **** **** **** +4319 Bard_Wounding_Whispers **** **** **** **** **** **** **** **** +4320 Bard_BreakEnchantment **** **** **** **** **** **** **** **** +4321 Bard_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +4322 Bard_DetectScrying **** **** **** **** **** **** **** **** +4323 Bard_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +4324 Bard_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +4325 Bard_DimensionDoor_Party **** **** **** **** **** **** **** **** +4326 Bard_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +4327 Bard_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +4328 Bard_Dismissal **** **** **** **** **** **** **** **** +4329 Bard_Dominate_Person **** **** **** **** **** **** **** **** +4330 Bard_Greater_Resistance **** **** **** **** **** **** **** **** +4331 Bard_Hold_Monster **** **** **** **** **** **** **** **** +4332 Bard_Improved_Invisibility **** **** **** **** **** **** **** **** +4333 Bard_Legend_Lore **** **** **** **** **** **** **** **** +4334 Bard_LocateCreature **** **** **** **** **** **** **** **** +4335 Bard_Mass_Ultravision **** **** **** **** **** **** **** **** +4336 Bard_Neutralize_Poison **** **** **** **** **** **** **** **** +4337 Bard_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +4338 Bard_RepelVermin **** **** **** **** **** **** **** **** +4339 Bard_Shout **** **** **** **** **** **** **** **** +4340 Bard_Summon_Creature_IV **** **** **** **** **** **** **** **** +4341 Bard_War_Cry **** **** **** **** **** **** **** **** +4342 Bard_Ethereal_Visage **** **** **** **** **** **** **** **** +4343 Bard_Greater_Dispelling **** **** **** **** **** **** **** **** +4344 Bard_Greater_Heroism **** **** **** **** **** **** **** **** +4345 Bard_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +4346 Bard_Healing_Circle **** **** **** **** **** **** **** **** +4347 Bard_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4348 Bard_Mind_Fog **** **** **** **** **** **** **** **** +4349 Bard_Mislead **** **** **** **** **** **** **** **** +4350 Bard_MORALITY_UNDONE **** **** **** **** **** **** **** **** +4351 Bard_SongOfDiscord **** **** **** **** **** **** **** **** +4352 Bard_Summon_Creature_V **** **** **** **** **** **** **** **** +4353 Bard_Animate_Object **** **** **** **** **** **** **** **** +4354 Bard_Dirge **** **** **** **** **** **** **** **** +4355 Bard_Energy_Buffer **** **** **** **** **** **** **** **** +4356 Bard_Eyebite **** **** **** **** **** **** **** **** +4357 Bard_Greater_Shout **** **** **** **** **** **** **** **** +4358 Bard_GreaterScrying **** **** **** **** **** **** **** **** +4359 Bard_Ice_Storm **** **** **** **** **** **** **** **** +4360 Bard_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +4361 Bard_Mass_Cats_Grace **** **** **** **** **** **** **** **** +4362 Bard_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +4363 Bard_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +4364 Bard_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +4365 Bard_Mass_Haste **** **** **** **** **** **** **** **** +4366 Bard_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +4367 Bard_Summon_Creature_VI **** **** **** **** **** **** **** **** +4368 Bard_Superior_Resistance **** **** **** **** **** **** **** **** +4369 Bard_WAVE_OF_PAIN **** **** **** **** **** **** **** **** +4370 Sorcerer_Acid_Splash **** **** **** **** **** **** **** **** +4371 Sorcerer_Dancing_Lights **** **** **** **** **** **** **** **** +4372 Sorcerer_Daze **** **** **** **** **** **** **** **** +4373 Sorcerer_DisruptUndead **** **** **** **** **** **** **** **** +4374 Sorcerer_Electric_Jolt **** **** **** **** **** **** **** **** +4375 Sorcerer_Flare **** **** **** **** **** **** **** **** +4376 Sorcerer_Light **** **** **** **** **** **** **** **** +4377 Sorcerer_MAGE_HAND **** **** **** **** **** **** **** **** +4378 Sorcerer_Ray_of_Frost **** **** **** **** **** **** **** **** +4379 Sorcerer_Read_Magic **** **** **** **** **** **** **** **** +4380 Sorcerer_Resistance **** **** **** **** **** **** **** **** +4381 Sorcerer_ABERRATE **** **** **** **** **** **** **** **** +4382 Sorcerer_Benign_Transposition **** **** **** **** **** **** **** **** +4383 Sorcerer_BESTOW_WOUND **** **** **** **** **** **** **** **** +4384 Sorcerer_Bigbys_Tripping_Hand **** **** **** **** **** **** **** **** +4385 Sorcerer_Blade_of_Blood **** **** **** **** **** **** **** **** +4386 Sorcerer_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +4387 Sorcerer_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +4388 Sorcerer_Burning_Bolt **** **** **** **** **** **** **** **** +4389 Sorcerer_Burning_Hands **** **** **** **** **** **** **** **** +4390 Sorcerer_Cause_Fear **** **** **** **** **** **** **** **** +4391 Sorcerer_Charm_Person **** **** **** **** **** **** **** **** +4392 Sorcerer_Chill_Touch **** **** **** **** **** **** **** **** +4393 Sorcerer_Color_Spray **** **** **** **** **** **** **** **** +4394 Sorcerer_DETECT_UNDEAD **** **** **** **** **** **** **** **** +4395 Sorcerer_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +4396 Sorcerer_Disguise_Self_Learn **** **** **** **** **** **** **** **** +4397 Sorcerer_Disguise_Self_Options **** **** **** **** **** **** **** **** +4398 Sorcerer_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +4399 Sorcerer_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +4400 Sorcerer_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +4401 Sorcerer_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +4402 Sorcerer_Endure_Elements **** **** **** **** **** **** **** **** +4403 Sorcerer_ENLARGE_PERSON **** **** **** **** **** **** **** **** +4404 Sorcerer_Expeditious_Retreat **** **** **** **** **** **** **** **** +4405 Sorcerer_EXTRACT_DRUG **** **** **** **** **** **** **** **** +4406 Sorcerer_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +4407 Sorcerer_EXTRACT_VODARE **** **** **** **** **** **** **** **** +4408 Sorcerer_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +4409 Sorcerer_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +4410 Sorcerer_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +4411 Sorcerer_FistOfStone **** **** **** **** **** **** **** **** +4412 Sorcerer_Grease **** **** **** **** **** **** **** **** +4413 Sorcerer_Hail_of_Stone **** **** **** **** **** **** **** **** +4414 Sorcerer_Horizikauls_Boom **** **** **** **** **** **** **** **** +4415 Sorcerer_Ice_Dagger **** **** **** **** **** **** **** **** +4416 Sorcerer_Identify **** **** **** **** **** **** **** **** +4417 Sorcerer_Ironguts **** **** **** **** **** **** **** **** +4418 Sorcerer_Kelgores_Fire_Bolt **** **** **** **** **** **** **** **** +4419 Sorcerer_LANTERN_LIGHT **** **** **** **** **** **** **** **** +4420 Sorcerer_Lesser_Acid_Orb **** **** **** **** **** **** **** **** +4421 Sorcerer_Lesser_Cold_Orb **** **** **** **** **** **** **** **** +4422 Sorcerer_Lesser_Deflect **** **** **** **** **** **** **** **** +4423 Sorcerer_Lesser_Electric_Orb **** **** **** **** **** **** **** **** +4424 Sorcerer_Lesser_Fire_Orb **** **** **** **** **** **** **** **** +4425 Sorcerer_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +4426 Sorcerer_Lesser_Sonic_Orb **** **** **** **** **** **** **** **** +4427 Sorcerer_Mage_Armor **** **** **** **** **** **** **** **** +4428 Sorcerer_Magic_Missile **** **** **** **** **** **** **** **** +4429 Sorcerer_Magic_Weapon **** **** **** **** **** **** **** **** +4430 Sorcerer_Necrotic_Awareness **** **** **** **** **** **** **** **** +4431 Sorcerer_Negative_Energy_Ray **** **** **** **** **** **** **** **** +4432 Sorcerer_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +4433 Sorcerer_Obscuring_Mist **** **** **** **** **** **** **** **** +4434 Sorcerer_Protection_from_Chaos **** **** **** **** **** **** **** **** +4435 Sorcerer_Protection_from_Evil **** **** **** **** **** **** **** **** +4436 Sorcerer_Protection_from_Good **** **** **** **** **** **** **** **** +4437 Sorcerer_Protection_from_Law **** **** **** **** **** **** **** **** +4438 Sorcerer_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +4439 Sorcerer_REDUCE_PERSON **** **** **** **** **** **** **** **** +4440 Sorcerer_Rouse **** **** **** **** **** **** **** **** +4441 Sorcerer_Shelgarns_Persistent_Blade **** **** **** **** **** **** **** **** +4442 Sorcerer_Shield **** **** **** **** **** **** **** **** +4443 Sorcerer_ShockingGrasp **** **** **** **** **** **** **** **** +4444 Sorcerer_Sleep **** **** **** **** **** **** **** **** +4445 Sorcerer_Snillocs_Snowball **** **** **** **** **** **** **** **** +4446 Sorcerer_Spell_Jump **** **** **** **** **** **** **** **** +4447 Sorcerer_Summon_Creature_I **** **** **** **** **** **** **** **** +4448 Sorcerer_SummonUndeadI **** **** **** **** **** **** **** **** +4449 Sorcerer_TensersFloatingDisk **** **** **** **** **** **** **** **** +4450 Sorcerer_True_Casting **** **** **** **** **** **** **** **** +4451 Sorcerer_True_Strike **** **** **** **** **** **** **** **** +4452 Sorcerer_ADDICTION **** **** **** **** **** **** **** **** +4453 Sorcerer_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +4454 Sorcerer_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +4455 Sorcerer_ADDICTION_VODARE **** **** **** **** **** **** **** **** +4456 Sorcerer_ADDICTION_AGONY **** **** **** **** **** **** **** **** +4457 Sorcerer_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +4458 Sorcerer_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +4459 Sorcerer_Alter_Self_Learn **** **** **** **** **** **** **** **** +4460 Sorcerer_Alter_Self_Options **** **** **** **** **** **** **** **** +4461 Sorcerer_Alter_Self_QS1 **** **** **** **** **** **** **** **** +4462 Sorcerer_Alter_Self_QS2 **** **** **** **** **** **** **** **** +4463 Sorcerer_Alter_Self_QS3 **** **** **** **** **** **** **** **** +4464 Sorcerer_Animalistic_Power **** **** **** **** **** **** **** **** +4465 Sorcerer_AugmentFamiliar **** **** **** **** **** **** **** **** +4466 Sorcerer_BalagarnsIronHorn **** **** **** **** **** **** **** **** +4467 Sorcerer_Baleful_Transposition **** **** **** **** **** **** **** **** +4468 Sorcerer_Bigbys_Striking_Fist **** **** **** **** **** **** **** **** +4469 Sorcerer_BladesOfFire **** **** **** **** **** **** **** **** +4470 Sorcerer_Blindness_and_Deafness **** **** **** **** **** **** **** **** +4471 Sorcerer_Blur **** **** **** **** **** **** **** **** +4472 Sorcerer_Bulls_Strength **** **** **** **** **** **** **** **** +4473 Sorcerer_Cats_Grace **** **** **** **** **** **** **** **** +4474 Sorcerer_Cloud_of_Bewilderment **** **** **** **** **** **** **** **** +4475 Sorcerer_Combust **** **** **** **** **** **** **** **** +4476 Sorcerer_Command_Undead **** **** **** **** **** **** **** **** +4477 Sorcerer_Continual_Flame **** **** **** **** **** **** **** **** +4478 Sorcerer_Create_Magic_Tattoo **** **** **** **** **** **** **** **** +4479 Sorcerer_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +4480 Sorcerer_Darkness **** **** **** **** **** **** **** **** +4481 Sorcerer_Daze_Monster **** **** **** **** **** **** **** **** +4482 Sorcerer_Death_Armor **** **** **** **** **** **** **** **** +4483 Sorcerer_Deflect **** **** **** **** **** **** **** **** +4484 Sorcerer_Dimension_Hop **** **** **** **** **** **** **** **** +4485 Sorcerer_Dispelling_Touch **** **** **** **** **** **** **** **** +4486 Sorcerer_Eagle_Splendor **** **** **** **** **** **** **** **** +4487 Sorcerer_Endurance **** **** **** **** **** **** **** **** +4488 Sorcerer_ENERGIZE_POTION **** **** **** **** **** **** **** **** +4489 Sorcerer_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +4490 Sorcerer_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +4491 Sorcerer_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +4492 Sorcerer_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +4493 Sorcerer_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +4494 Sorcerer_FalseLife **** **** **** **** **** **** **** **** +4495 Sorcerer_Fireburst **** **** **** **** **** **** **** **** +4496 Sorcerer_Flame_Weapon **** **** **** **** **** **** **** **** +4497 Sorcerer_FogCloud **** **** **** **** **** **** **** **** +4498 Sorcerer_Foxs_Cunning **** **** **** **** **** **** **** **** +4499 Sorcerer_Gedlees_Electric_Loop **** **** **** **** **** **** **** **** +4500 Sorcerer_Ghostly_Visage **** **** **** **** **** **** **** **** +4501 Sorcerer_Ghoul_Touch **** **** **** **** **** **** **** **** +4502 Sorcerer_Glitterdust **** **** **** **** **** **** **** **** +4503 Sorcerer_Invisibility **** **** **** **** **** **** **** **** +4504 Sorcerer_Knock **** **** **** **** **** **** **** **** +4505 Sorcerer_Lesser_Dispel **** **** **** **** **** **** **** **** +4506 Sorcerer_LifeBolt **** **** **** **** **** **** **** **** +4507 Sorcerer_LifeBolt1Bolt **** **** **** **** **** **** **** **** +4508 Sorcerer_LifeBolt2Bolts **** **** **** **** **** **** **** **** +4509 Sorcerer_LifeBolt3Bolts **** **** **** **** **** **** **** **** +4510 Sorcerer_LifeBolt4Bolts **** **** **** **** **** **** **** **** +4511 Sorcerer_LifeBolt5Bolts **** **** **** **** **** **** **** **** +4512 Sorcerer_LocateObject **** **** **** **** **** **** **** **** +4513 Sorcerer_MASOCHISM **** **** **** **** **** **** **** **** +4514 Sorcerer_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +4515 Sorcerer_MirrorImage **** **** **** **** **** **** **** **** +4516 Sorcerer_Necrotic_Cyst **** **** **** **** **** **** **** **** +4517 Sorcerer_ObscureObject **** **** **** **** **** **** **** **** +4518 Sorcerer_Owls_Wisdom **** **** **** **** **** **** **** **** +4519 Sorcerer_ProtectionArrows **** **** **** **** **** **** **** **** +4520 Sorcerer_Pyrotechnics **** **** **** **** **** **** **** **** +4521 Sorcerer_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +4522 Sorcerer_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +4523 Sorcerer_Resist_Elements **** **** **** **** **** **** **** **** +4524 Sorcerer_Scare **** **** **** **** **** **** **** **** +4525 Sorcerer_ScorchingRay **** **** **** **** **** **** **** **** +4526 Sorcerer_See_Invisibility **** **** **** **** **** **** **** **** +4527 Sorcerer_Seeking_Ray **** **** **** **** **** **** **** **** +4528 Sorcerer_Shadow_Spray **** **** **** **** **** **** **** **** +4529 Sorcerer_SHRIVELING **** **** **** **** **** **** **** **** +4530 Sorcerer_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +4531 Sorcerer_Stone_Bones **** **** **** **** **** **** **** **** +4532 Sorcerer_Summon_Creature_II **** **** **** **** **** **** **** **** +4533 Sorcerer_SummonUndeadII **** **** **** **** **** **** **** **** +4534 Sorcerer_Sure_Strike **** **** **** **** **** **** **** **** +4535 Sorcerer_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +4536 Sorcerer_TouchIdiocy **** **** **** **** **** **** **** **** +4537 Sorcerer_Ultravision **** **** **** **** **** **** **** **** +4538 Sorcerer_UNHEAVENED **** **** **** **** **** **** **** **** +4539 Sorcerer_Web **** **** **** **** **** **** **** **** +4540 Sorcerer_WhirlingBlade **** **** **** **** **** **** **** **** +4541 Sorcerer_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +4542 Sorcerer_Clarity **** **** **** **** **** **** **** **** +4543 Sorcerer_Crown_Might **** **** **** **** **** **** **** **** +4544 Sorcerer_Crown_Protection **** **** **** **** **** **** **** **** +4545 Sorcerer_CURSE_OF_THE_PUTRID_HUSK **** **** **** **** **** **** **** **** +4546 Sorcerer_Daylight **** **** **** **** **** **** **** **** +4547 Sorcerer_DeepSlumber **** **** **** **** **** **** **** **** +4548 Sorcerer_DEVILS_EYE **** **** **** **** **** **** **** **** +4549 Sorcerer_Dispel_Magic **** **** **** **** **** **** **** **** +4550 Sorcerer_Displacement **** **** **** **** **** **** **** **** +4551 Sorcerer_DREAD_WORD **** **** **** **** **** **** **** **** +4552 Sorcerer_ELATION **** **** **** **** **** **** **** **** +4553 Sorcerer_Energy_Aegis **** **** **** **** **** **** **** **** +4554 Sorcerer_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +4555 Sorcerer_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +4556 Sorcerer_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +4557 Sorcerer_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +4558 Sorcerer_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +4559 Sorcerer_Energy_Surge **** **** **** **** **** **** **** **** +4560 Sorcerer_Energy_Surge_Acid **** **** **** **** **** **** **** **** +4561 Sorcerer_Energy_Surge_Cold **** **** **** **** **** **** **** **** +4562 Sorcerer_Energy_Surge_Elec **** **** **** **** **** **** **** **** +4563 Sorcerer_Energy_Surge_Fire **** **** **** **** **** **** **** **** +4564 Sorcerer_Energy_Surge_Sonic **** **** **** **** **** **** **** **** +4565 Sorcerer_EVIL_EYE **** **** **** **** **** **** **** **** +4566 Sorcerer_Find_Traps **** **** **** **** **** **** **** **** +4567 Sorcerer_Fireball **** **** **** **** **** **** **** **** +4568 Sorcerer_Flame_Arrow **** **** **** **** **** **** **** **** +4569 Sorcerer_Flashburst **** **** **** **** **** **** **** **** +4570 Sorcerer_Forceblast **** **** **** **** **** **** **** **** +4571 Sorcerer_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +4572 Sorcerer_GreaterDisruptUndead **** **** **** **** **** **** **** **** +4573 Sorcerer_Gust_of_Wind **** **** **** **** **** **** **** **** +4574 Sorcerer_Halt **** **** **** **** **** **** **** **** +4575 Sorcerer_HaltUndead **** **** **** **** **** **** **** **** +4576 Sorcerer_Haste **** **** **** **** **** **** **** **** +4577 Sorcerer_Heroism **** **** **** **** **** **** **** **** +4578 Sorcerer_Hold_Person **** **** **** **** **** **** **** **** +4579 Sorcerer_Ice_Burst **** **** **** **** **** **** **** **** +4580 Sorcerer_Improved_Mage_Armor **** **** **** **** **** **** **** **** +4581 Sorcerer_Invisibility_Sphere **** **** **** **** **** **** **** **** +4582 Sorcerer_Keen_Edge **** **** **** **** **** **** **** **** +4583 Sorcerer_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +4584 Sorcerer_Lightning_Bolt **** **** **** **** **** **** **** **** +4585 Sorcerer_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +4586 Sorcerer_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +4587 Sorcerer_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +4588 Sorcerer_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +4589 Sorcerer_Mestils_Acid_Breath **** **** **** **** **** **** **** **** +4590 Sorcerer_Necrotic_Bloat **** **** **** **** **** **** **** **** +4591 Sorcerer_Negative_Energy_Burst **** **** **** **** **** **** **** **** +4592 Sorcerer_NONDETECTION **** **** **** **** **** **** **** **** +4593 Sorcerer_Protection_from_Elements **** **** **** **** **** **** **** **** +4594 Sorcerer_RainbowBlast **** **** **** **** **** **** **** **** +4595 Sorcerer_RayofExhaustion **** **** **** **** **** **** **** **** +4596 Sorcerer_REALITY_BLIND **** **** **** **** **** **** **** **** +4597 Sorcerer_Regroup **** **** **** **** **** **** **** **** +4598 Sorcerer_Scintillating_Sphere **** **** **** **** **** **** **** **** +4599 Sorcerer_Serpents_Sigh **** **** **** **** **** **** **** **** +4600 Sorcerer_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +4601 Sorcerer_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +4602 Sorcerer_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +4603 Sorcerer_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +4604 Sorcerer_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +4605 Sorcerer_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +4606 Sorcerer_SleetStorm **** **** **** **** **** **** **** **** +4607 Sorcerer_Slow **** **** **** **** **** **** **** **** +4608 Sorcerer_Spiderskin **** **** **** **** **** **** **** **** +4609 Sorcerer_Stinking_Cloud **** **** **** **** **** **** **** **** +4610 Sorcerer_Summon_Creature_III **** **** **** **** **** **** **** **** +4611 Sorcerer_SummonUndeadIII **** **** **** **** **** **** **** **** +4612 Sorcerer_Vampiric_Touch **** **** **** **** **** **** **** **** +4613 Sorcerer_WaterBreathing **** **** **** **** **** **** **** **** +4614 Sorcerer_Weapon_of_Impact **** **** **** **** **** **** **** **** +4615 Sorcerer_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +4616 Sorcerer_Acid_Orb **** **** **** **** **** **** **** **** +4617 Sorcerer_ArcaneEye **** **** **** **** **** **** **** **** +4618 Sorcerer_Bestow_Curse **** **** **** **** **** **** **** **** +4619 Sorcerer_Blast_of_Flame **** **** **** **** **** **** **** **** +4620 Sorcerer_Channeled_Pyroburst **** **** **** **** **** **** **** **** +4621 Sorcerer_Channeled_Pyroburst_Swift **** **** **** **** **** **** **** **** +4622 Sorcerer_Channeled_Pyroburst_Standard **** **** **** **** **** **** **** **** +4623 Sorcerer_Channeled_Pyroburst_Full **** **** **** **** **** **** **** **** +4624 Sorcerer_Channeled_Pyroburst_Two **** **** **** **** **** **** **** **** +4625 Sorcerer_Charm_Monster **** **** **** **** **** **** **** **** +4626 Sorcerer_Cold_Orb **** **** **** **** **** **** **** **** +4627 Sorcerer_Confusion **** **** **** **** **** **** **** **** +4628 Sorcerer_Contagion **** **** **** **** **** **** **** **** +4629 Sorcerer_CrushingDespair **** **** **** **** **** **** **** **** +4630 Sorcerer_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +4631 Sorcerer_DANCING_WEB **** **** **** **** **** **** **** **** +4632 Sorcerer_DetectScrying **** **** **** **** **** **** **** **** +4633 Sorcerer_Dimensional_Anchor **** **** **** **** **** **** **** **** +4634 Sorcerer_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +4635 Sorcerer_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +4636 Sorcerer_DimensionDoor_Party **** **** **** **** **** **** **** **** +4637 Sorcerer_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +4638 Sorcerer_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +4639 Sorcerer_Doom_Scarabs **** **** **** **** **** **** **** **** +4640 Sorcerer_Electric_Orb **** **** **** **** **** **** **** **** +4641 Sorcerer_Elemental_Shield **** **** **** **** **** **** **** **** +4642 Sorcerer_Enervation **** **** **** **** **** **** **** **** +4643 Sorcerer_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +4644 Sorcerer_Fear **** **** **** **** **** **** **** **** +4645 Sorcerer_Fire_Orb **** **** **** **** **** **** **** **** +4646 Sorcerer_FireTrap **** **** **** **** **** **** **** **** +4647 Sorcerer_Greater_Resistance **** **** **** **** **** **** **** **** +4648 Sorcerer_GRIM_REVENGE **** **** **** **** **** **** **** **** +4649 Sorcerer_Ice_Storm **** **** **** **** **** **** **** **** +4650 Sorcerer_Ilyykurs_Mantle **** **** **** **** **** **** **** **** +4651 Sorcerer_Improved_Invisibility **** **** **** **** **** **** **** **** +4652 Sorcerer_Isaacs_Lesser_Missile_Storm **** **** **** **** **** **** **** **** +4653 Sorcerer_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +4654 Sorcerer_LIQUID_PAIN **** **** **** **** **** **** **** **** +4655 Sorcerer_LocateCreature **** **** **** **** **** **** **** **** +4656 Sorcerer_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +4657 Sorcerer_MASS_ENLARGE_PERSON **** **** **** **** **** **** **** **** +4658 Sorcerer_MASS_REDUCE_PERSON **** **** **** **** **** **** **** **** +4659 Sorcerer_Mass_Ultravision **** **** **** **** **** **** **** **** +4660 Sorcerer_Minor_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +4661 Sorcerer_Necrotic_Domination **** **** **** **** **** **** **** **** +4662 Sorcerer_OrbOfForce **** **** **** **** **** **** **** **** +4663 Sorcerer_Otilukes_Resilient_Sphere **** **** **** **** **** **** **** **** +4664 Sorcerer_Phantasmal_Killer **** **** **** **** **** **** **** **** +4665 Sorcerer_PnP_FireShield **** **** **** **** **** **** **** **** +4666 Sorcerer_PnP_FireShieldRed **** **** **** **** **** **** **** **** +4667 Sorcerer_PnPFireShieldBlue **** **** **** **** **** **** **** **** +4668 Sorcerer_Polymorph_Self **** **** **** **** **** **** **** **** +4669 Sorcerer_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +4670 Sorcerer_Polymorph_TROLL **** **** **** **** **** **** **** **** +4671 Sorcerer_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +4672 Sorcerer_Polymorph_PIXIE **** **** **** **** **** **** **** **** +4673 Sorcerer_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +4674 Sorcerer_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +4675 Sorcerer_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +4676 Sorcerer_Remove_Curse **** **** **** **** **** **** **** **** +4677 Sorcerer_Scrying **** **** **** **** **** **** **** **** +4678 Sorcerer_SerpentArrows **** **** **** **** **** **** **** **** +4679 Sorcerer_Shadow_Conjuration **** **** **** **** **** **** **** **** +4680 Sorcerer_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +4681 Sorcerer_SHADOW_CON_Darkness **** **** **** **** **** **** **** **** +4682 Sorcerer_SHADOW_CON_Inivsibility **** **** **** **** **** **** **** **** +4683 Sorcerer_SHADOW_CON_Mage_Armor **** **** **** **** **** **** **** **** +4684 Sorcerer_SHADOW_CON_Magic_Missile **** **** **** **** **** **** **** **** +4685 Sorcerer_Shout **** **** **** **** **** **** **** **** +4686 Sorcerer_Sinsaburs_Baleful_Bolt **** **** **** **** **** **** **** **** +4687 Sorcerer_Slashing_Dispel **** **** **** **** **** **** **** **** +4688 Sorcerer_SolidFog **** **** **** **** **** **** **** **** +4689 Sorcerer_Sonic_Orb **** **** **** **** **** **** **** **** +4690 Sorcerer_Stoneskin **** **** **** **** **** **** **** **** +4691 Sorcerer_Summon_Creature_IV **** **** **** **** **** **** **** **** +4692 Sorcerer_SummonUndeadIV **** **** **** **** **** **** **** **** +4693 Sorcerer_Viscid_Glob **** **** **** **** **** **** **** **** +4694 Sorcerer_Wall_of_Fire **** **** **** **** **** **** **** **** +4695 Sorcerer_WRACK **** **** **** **** **** **** **** **** +4696 Sorcerer_Animate_Dead **** **** **** **** **** **** **** **** +4697 Sorcerer_BalefulPolymorph **** **** **** **** **** **** **** **** +4698 Sorcerer_Ball_Lightning **** **** **** **** **** **** **** **** +4699 Sorcerer_Beltyns_Burning_Blood **** **** **** **** **** **** **** **** +4700 Sorcerer_Bigbys_Interposing_Hand **** **** **** **** **** **** **** **** +4701 Sorcerer_BreakEnchantment **** **** **** **** **** **** **** **** +4702 Sorcerer_CALL_DRETCH_HORDE **** **** **** **** **** **** **** **** +4703 Sorcerer_CALL_LEMURE_HORDE **** **** **** **** **** **** **** **** +4704 Sorcerer_Cloudkill **** **** **** **** **** **** **** **** +4705 Sorcerer_Cone_of_Cold **** **** **** **** **** **** **** **** +4706 Sorcerer_Dismissal **** **** **** **** **** **** **** **** +4707 Sorcerer_Dominate_Person **** **** **** **** **** **** **** **** +4708 Sorcerer_DraconicMight **** **** **** **** **** **** **** **** +4709 Sorcerer_Energy_Buffer **** **** **** **** **** **** **** **** +4710 Sorcerer_Feeblemind **** **** **** **** **** **** **** **** +4711 Sorcerer_Firebrand **** **** **** **** **** **** **** **** +4712 Sorcerer_Greater_Fireburst **** **** **** **** **** **** **** **** +4713 Sorcerer_Greater_Shadow_Conjuration **** **** **** **** **** **** **** **** +4714 Sorcerer_GR_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +4715 Sorcerer_GR_SHADOW_CON_Acid_Arrow **** **** **** **** **** **** **** **** +4716 Sorcerer_GR_SHADOW_CON_Ghostly_Visage **** **** **** **** **** **** **** **** +4717 Sorcerer_GR_SHADOW_CON_Web **** **** **** **** **** **** **** **** +4718 Sorcerer_GR_SHADOW_CON_Minor_Globe **** **** **** **** **** **** **** **** +4719 Sorcerer_Hold_Monster **** **** **** **** **** **** **** **** +4720 Sorcerer_Lesser_Mind_Blank **** **** **** **** **** **** **** **** +4721 Sorcerer_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +4722 Sorcerer_Lesser_Spell_Mantle **** **** **** **** **** **** **** **** +4723 Sorcerer_Magic_Missile **** **** **** **** **** **** **** **** +4724 Sorcerer_MassFireShield **** **** **** **** **** **** **** **** +4725 Sorcerer_MassFireShieldRed **** **** **** **** **** **** **** **** +4726 Sorcerer_MassFireShieldBlue **** **** **** **** **** **** **** **** +4727 Sorcerer_Mestils_Acid_Sheath **** **** **** **** **** **** **** **** +4728 Sorcerer_Mind_Fog **** **** **** **** **** **** **** **** +4729 Sorcerer_Necrotic_Burst **** **** **** **** **** **** **** **** +4730 Sorcerer_Nights_Caress **** **** **** **** **** **** **** **** +4731 Sorcerer_PrismaticRay **** **** **** **** **** **** **** **** +4732 Sorcerer_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +4733 Sorcerer_Sonic_Shield **** **** **** **** **** **** **** **** +4734 Sorcerer_STOP_HEART **** **** **** **** **** **** **** **** +4735 Sorcerer_Summon_Creature_V **** **** **** **** **** **** **** **** +4736 Sorcerer_SummonUndeadV **** **** **** **** **** **** **** **** +4737 Sorcerer_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +4738 Sorcerer_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +4739 Sorcerer_Teleport_RadialMaster **** **** **** **** **** **** **** **** +4740 Sorcerer_Teleport_SelfOnly **** **** **** **** **** **** **** **** +4741 Sorcerer_Teleport_Party **** **** **** **** **** **** **** **** +4742 Sorcerer_WavesofFatigue **** **** **** **** **** **** **** **** +4743 Sorcerer_Acid_Fog **** **** **** **** **** **** **** **** +4744 Sorcerer_Acid_Storm **** **** **** **** **** **** **** **** +4745 Sorcerer_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +4746 Sorcerer_Bigbys_Forceful_Hand **** **** **** **** **** **** **** **** +4747 Sorcerer_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +4748 Sorcerer_Chain_Lightning **** **** **** **** **** **** **** **** +4749 Sorcerer_Circle_of_Death **** **** **** **** **** **** **** **** +4750 Sorcerer_Disintegrate **** **** **** **** **** **** **** **** +4751 Sorcerer_ECTOPLASMIC_ENCHANCEMENT **** **** **** **** **** **** **** **** +4752 Sorcerer_Ethereal_Visage **** **** **** **** **** **** **** **** +4753 Sorcerer_ExtractWaterElemental **** **** **** **** **** **** **** **** +4754 Sorcerer_Eyebite **** **** **** **** **** **** **** **** +4755 Sorcerer_Flesh_to_stone **** **** **** **** **** **** **** **** +4756 Sorcerer_Ghoul_Gauntlet **** **** **** **** **** **** **** **** +4757 Sorcerer_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +4758 Sorcerer_Greater_Dispelling **** **** **** **** **** **** **** **** +4759 Sorcerer_Greater_Heroism **** **** **** **** **** **** **** **** +4760 Sorcerer_Greater_Spell_Breach **** **** **** **** **** **** **** **** +4761 Sorcerer_Greater_Stoneskin **** **** **** **** **** **** **** **** +4762 Sorcerer_Isaacs_Greater_Missile_Storm **** **** **** **** **** **** **** **** +4763 Sorcerer_Legend_Lore **** **** **** **** **** **** **** **** +4764 Sorcerer_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +4765 Sorcerer_Mass_Cats_Grace **** **** **** **** **** **** **** **** +4766 Sorcerer_Mass_Contagion **** **** **** **** **** **** **** **** +4767 Sorcerer_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +4768 Sorcerer_Mass_Endurance **** **** **** **** **** **** **** **** +4769 Sorcerer_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +4770 Sorcerer_Mass_Haste **** **** **** **** **** **** **** **** +4771 Sorcerer_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +4772 Sorcerer_Mislead **** **** **** **** **** **** **** **** +4773 Sorcerer_Necrotic_Eruption **** **** **** **** **** **** **** **** +4774 Sorcerer_OtilukesFreezingSphere **** **** **** **** **** **** **** **** +4775 Sorcerer_Planar_Binding **** **** **** **** **** **** **** **** +4776 Sorcerer_Repulsion **** **** **** **** **** **** **** **** +4777 Sorcerer_Shades **** **** **** **** **** **** **** **** +4778 Sorcerer_SHADES_Summon_Shadow **** **** **** **** **** **** **** **** +4779 Sorcerer_SHADES_Cone_of_Cold **** **** **** **** **** **** **** **** +4780 Sorcerer_SHADES_Fireball **** **** **** **** **** **** **** **** +4781 Sorcerer_SHADES_Stoneskin **** **** **** **** **** **** **** **** +4782 Sorcerer_SHADES_Wall_of_Fire **** **** **** **** **** **** **** **** +4783 Sorcerer_STARMANTLE **** **** **** **** **** **** **** **** +4784 Sorcerer_Stone_to_flesh **** **** **** **** **** **** **** **** +4785 Sorcerer_Summon_Creature_VI **** **** **** **** **** **** **** **** +4786 Sorcerer_Superior_Resistance **** **** **** **** **** **** **** **** +4787 Sorcerer_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +4788 Sorcerer_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +4789 Sorcerer_Tensers_Transformation **** **** **** **** **** **** **** **** +4790 Sorcerer_True_Seeing **** **** **** **** **** **** **** **** +4791 Sorcerer_Undeath_to_Death **** **** **** **** **** **** **** **** +4792 Sorcerer_AMBER_SARCOPHAGUS **** **** **** **** **** **** **** **** +4793 Sorcerer_ArrowOfBone **** **** **** **** **** **** **** **** +4794 Sorcerer_Avasculate **** **** **** **** **** **** **** **** +4795 Sorcerer_Banishment **** **** **** **** **** **** **** **** +4796 Sorcerer_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +4797 Sorcerer_Control_Undead **** **** **** **** **** **** **** **** +4798 Sorcerer_Control_Weather **** **** **** **** **** **** **** **** +4799 Sorcerer_CW_Rain **** **** **** **** **** **** **** **** +4800 Sorcerer_CW_Snow **** **** **** **** **** **** **** **** +4801 Sorcerer_CW_Clear **** **** **** **** **** **** **** **** +4802 Sorcerer_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +4803 Sorcerer_DRAGON_ALLY **** **** **** **** **** **** **** **** +4804 Sorcerer_Energy_Ebb **** **** **** **** **** **** **** **** +4805 Sorcerer_Energy_Immunity **** **** **** **** **** **** **** **** +4806 Sorcerer_EI_Acid **** **** **** **** **** **** **** **** +4807 Sorcerer_EI_Cold **** **** **** **** **** **** **** **** +4808 Sorcerer_EI_Elec **** **** **** **** **** **** **** **** +4809 Sorcerer_EI_Fire **** **** **** **** **** **** **** **** +4810 Sorcerer_EI_Sonic **** **** **** **** **** **** **** **** +4811 Sorcerer_EYE_OF_THE_BEHOLDER **** **** **** **** **** **** **** **** +4812 Sorcerer_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +4813 Sorcerer_Finger_of_Death **** **** **** **** **** **** **** **** +4814 Sorcerer_Great_Thunderclap **** **** **** **** **** **** **** **** +4815 Sorcerer_GreaterScrying **** **** **** **** **** **** **** **** +4816 Sorcerer_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +4817 Sorcerer_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +4818 Sorcerer_GreaterTeleport_Party **** **** **** **** **** **** **** **** +4819 Sorcerer_Insanity **** **** **** **** **** **** **** **** +4820 Sorcerer_Mass_Hold_Person **** **** **** **** **** **** **** **** +4821 Sorcerer_Mordenkainens_Sword **** **** **** **** **** **** **** **** +4822 Sorcerer_Mords_Mansion **** **** **** **** **** **** **** **** +4823 Sorcerer_Nybors_Stern_Reproof **** **** **** **** **** **** **** **** +4824 Sorcerer_Power_Word_Blind **** **** **** **** **** **** **** **** +4825 Sorcerer_Power_Word_Stun **** **** **** **** **** **** **** **** +4826 Sorcerer_Prismatic_Spray **** **** **** **** **** **** **** **** +4827 Sorcerer_Protection_from_Spells **** **** **** **** **** **** **** **** +4828 Sorcerer_Sequester **** **** **** **** **** **** **** **** +4829 Sorcerer_Shadow_Shield **** **** **** **** **** **** **** **** +4830 Sorcerer_Spell_Mantle **** **** **** **** **** **** **** **** +4831 Sorcerer_Spell_Turning **** **** **** **** **** **** **** **** +4832 Sorcerer_Summon_Creature_VII **** **** **** **** **** **** **** **** +4833 Sorcerer_Summon7Air **** **** **** **** **** **** **** **** +4834 Sorcerer_Summon7Earth **** **** **** **** **** **** **** **** +4835 Sorcerer_Summon7Fire **** **** **** **** **** **** **** **** +4836 Sorcerer_Summon7Water **** **** **** **** **** **** **** **** +4837 Sorcerer_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +4838 Sorcerer_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +4839 Sorcerer_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +4840 Sorcerer_WavesOfExhaustion **** **** **** **** **** **** **** **** +4841 Sorcerer_Avascular_Mass **** **** **** **** **** **** **** **** +4842 Sorcerer_Bigbys_Clenched_Fist **** **** **** **** **** **** **** **** +4843 Sorcerer_Blackstaff **** **** **** **** **** **** **** **** +4844 Sorcerer_Create_Undead **** **** **** **** **** **** **** **** +4845 Sorcerer_Dimensional_Lock **** **** **** **** **** **** **** **** +4846 Sorcerer_DiscernLocation **** **** **** **** **** **** **** **** +4847 Sorcerer_Etherealness **** **** **** **** **** **** **** **** +4848 Sorcerer_Flensing **** **** **** **** **** **** **** **** +4849 Sorcerer_Greater_Planar_Binding **** **** **** **** **** **** **** **** +4850 Sorcerer_Greater_Shout **** **** **** **** **** **** **** **** +4851 Sorcerer_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +4852 Sorcerer_GUTWRENCH **** **** **** **** **** **** **** **** +4853 Sorcerer_Horrid_Wilting **** **** **** **** **** **** **** **** +4854 Sorcerer_Incendiary_Cloud **** **** **** **** **** **** **** **** +4855 Sorcerer_IRON_BODY **** **** **** **** **** **** **** **** +4856 Sorcerer_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +4857 Sorcerer_Mantle_of_Eg_Might **** **** **** **** **** **** **** **** +4858 Sorcerer_Mass_Blindness_and_Deafness **** **** **** **** **** **** **** **** +4859 Sorcerer_Mass_Charm **** **** **** **** **** **** **** **** +4860 Sorcerer_Maze **** **** **** **** **** **** **** **** +4861 Sorcerer_Mind_Blank **** **** **** **** **** **** **** **** +4862 Sorcerer_Necrotic_Empowerment **** **** **** **** **** **** **** **** +4863 Sorcerer_PolarRay **** **** **** **** **** **** **** **** +4864 Sorcerer_Premonition **** **** **** **** **** **** **** **** +4865 Sorcerer_PrismaticWall **** **** **** **** **** **** **** **** +4866 Sorcerer_ScintillatingPattern **** **** **** **** **** **** **** **** +4867 Sorcerer_Summon_Creature_VIII **** **** **** **** **** **** **** **** +4868 Sorcerer_Summon8Air **** **** **** **** **** **** **** **** +4869 Sorcerer_Summon8Earth **** **** **** **** **** **** **** **** +4870 Sorcerer_Summon8Fire **** **** **** **** **** **** **** **** +4871 Sorcerer_Summon8Water **** **** **** **** **** **** **** **** +4872 Sorcerer_Sunburst **** **** **** **** **** **** **** **** +4873 Sorcerer_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +4874 Sorcerer_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +4875 Sorcerer_Bigbys_Crushing_Hand **** **** **** **** **** **** **** **** +4876 Sorcerer_Black_Blade_of_Disaster **** **** **** **** **** **** **** **** +4877 Sorcerer_BLINDING_GLORY **** **** **** **** **** **** **** **** +4878 Sorcerer_CRUSHING_FIST_OF_SPITE **** **** **** **** **** **** **** **** +4879 Sorcerer_Dominate_Monster **** **** **** **** **** **** **** **** +4880 Sorcerer_Energy_Drain **** **** **** **** **** **** **** **** +4881 Sorcerer_Foresight **** **** **** **** **** **** **** **** +4882 Sorcerer_Gate **** **** **** **** **** **** **** **** +4883 Sorcerer_Greater_Spell_Mantle **** **** **** **** **** **** **** **** +4884 Sorcerer_Mass_Hold_Monster **** **** **** **** **** **** **** **** +4885 Sorcerer_Meteor_Swarm **** **** **** **** **** **** **** **** +4886 Sorcerer_Mordenkainens_Disjunction **** **** **** **** **** **** **** **** +4887 Sorcerer_Necrotic_Termination **** **** **** **** **** **** **** **** +4888 Sorcerer_PlagueOfUndead **** **** **** **** **** **** **** **** +4889 Sorcerer_Power_Word_Kill **** **** **** **** **** **** **** **** +4890 Sorcerer_PrismaticSphere **** **** **** **** **** **** **** **** +4891 Sorcerer_Shapechange **** **** **** **** **** **** **** **** +4892 Sorcerer_Shapechange_RED_DRAGON **** **** **** **** **** **** **** **** +4893 Sorcerer_Shapechange_FIRE_GIANT **** **** **** **** **** **** **** **** +4894 Sorcerer_Shapechange_BALOR **** **** **** **** **** **** **** **** +4895 Sorcerer_Shapechange_DEATH_SLAAD **** **** **** **** **** **** **** **** +4896 Sorcerer_Shapechange_IRON_GOLEM **** **** **** **** **** **** **** **** +4897 Sorcerer_Sphere_of_Ultimate_Destruction **** **** **** **** **** **** **** **** +4898 Sorcerer_Summon_Creature_IX **** **** **** **** **** **** **** **** +4899 Sorcerer_Summon9Air **** **** **** **** **** **** **** **** +4900 Sorcerer_Summon9Earth **** **** **** **** **** **** **** **** +4901 Sorcerer_Summon9Fire **** **** **** **** **** **** **** **** +4902 Sorcerer_Summon9Water **** **** **** **** **** **** **** **** +4903 Sorcerer_TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +4904 Sorcerer_TeleportationCircle_Visible **** **** **** **** **** **** **** **** +4905 Sorcerer_TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +4906 Sorcerer_Time_Stop **** **** **** **** **** **** **** **** +4907 Sorcerer_UTTERDARK **** **** **** **** **** **** **** **** +4908 Sorcerer_VileDeath **** **** **** **** **** **** **** **** +4909 Sorcerer_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +4910 Sorcerer_Weird **** **** **** **** **** **** **** **** +4911 Harper_Camoflage **** **** **** **** **** **** **** **** +4912 Harper_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +4913 Harper_Alter_Self_Learn **** **** **** **** **** **** **** **** +4914 Harper_Alter_Self_Options **** **** **** **** **** **** **** **** +4915 Harper_Alter_Self_QS1 **** **** **** **** **** **** **** **** +4916 Harper_Alter_Self_QS2 **** **** **** **** **** **** **** **** +4917 Harper_Alter_Self_QS3 **** **** **** **** **** **** **** **** +4918 Harper_Charm_Person **** **** **** **** **** **** **** **** +4919 Harper_Spell_Jump **** **** **** **** **** **** **** **** +4920 Harper_Light **** **** **** **** **** **** **** **** +4921 Harper_Read_Magic **** **** **** **** **** **** **** **** +4922 Harper_Sleep **** **** **** **** **** **** **** **** +4923 Harper_Cats_Grace **** **** **** **** **** **** **** **** +4924 Harper_Eagle_Splendor **** **** **** **** **** **** **** **** +4925 Harper_Invisibility **** **** **** **** **** **** **** **** +4926 Harper_Knock **** **** **** **** **** **** **** **** +4927 Harper_LocateObject **** **** **** **** **** **** **** **** +4928 Harper_See_Invisibility **** **** **** **** **** **** **** **** +4929 Harper_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +4930 Harper_NONDETECTION **** **** **** **** **** **** **** **** +4931 Harper_UndetectableAlignment **** **** **** **** **** **** **** **** +4932 Assassin_ADDICTION **** **** **** **** **** **** **** **** +4933 Assassin_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +4934 Assassin_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +4935 Assassin_ADDICTION_VODARE **** **** **** **** **** **** **** **** +4936 Assassin_ADDICTION_AGONY **** **** **** **** **** **** **** **** +4937 Assassin_ANGRY_ACHE **** **** **** **** **** **** **** **** +4938 Assassin_Blade_of_Blood **** **** **** **** **** **** **** **** +4939 Assassin_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +4940 Assassin_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +4941 Assassin_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +4942 Assassin_Disguise_Self_Learn **** **** **** **** **** **** **** **** +4943 Assassin_Disguise_Self_Options **** **** **** **** **** **** **** **** +4944 Assassin_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +4945 Assassin_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +4946 Assassin_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +4947 Assassin_Spell_Jump **** **** **** **** **** **** **** **** +4948 Assassin_Obscuring_Mist **** **** **** **** **** **** **** **** +4949 Assassin_Sleep **** **** **** **** **** **** **** **** +4950 Assassin_True_Strike **** **** **** **** **** **** **** **** +4951 Assassin_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +4952 Assassin_Alter_Self_Learn **** **** **** **** **** **** **** **** +4953 Assassin_Alter_Self_Options **** **** **** **** **** **** **** **** +4954 Assassin_Alter_Self_QS1 **** **** **** **** **** **** **** **** +4955 Assassin_Alter_Self_QS2 **** **** **** **** **** **** **** **** +4956 Assassin_Alter_Self_QS3 **** **** **** **** **** **** **** **** +4957 Assassin_Cats_Grace **** **** **** **** **** **** **** **** +4958 Assassin_Darkness **** **** **** **** **** **** **** **** +4959 Assassin_Foxs_Cunning **** **** **** **** **** **** **** **** +4960 Assassin_IceKnife **** **** **** **** **** **** **** **** +4961 Assassin_Invisibility **** **** **** **** **** **** **** **** +4962 Assassin_UndetectableAlignment **** **** **** **** **** **** **** **** +4963 Assassin_DeeperDarkness **** **** **** **** **** **** **** **** +4964 Assassin_DeepSlumber **** **** **** **** **** **** **** **** +4965 Assassin_FalseLife **** **** **** **** **** **** **** **** +4966 Assassin_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +4967 Assassin_MASOCHISM **** **** **** **** **** **** **** **** +4968 Assassin_NONDETECTION **** **** **** **** **** **** **** **** +4969 Assassin_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +4970 Assassin_CursedBlade **** **** **** **** **** **** **** **** +4971 Assassin_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +4972 Assassin_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +4973 Assassin_DimensionDoor_Party **** **** **** **** **** **** **** **** +4974 Assassin_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +4975 Assassin_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +4976 Assassin_FLESH_ARMOR **** **** **** **** **** **** **** **** +4977 Assassin_Freedom_of_Movement **** **** **** **** **** **** **** **** +4978 Assassin_GLIBNESS **** **** **** **** **** **** **** **** +4979 Assassin_HeartRipper **** **** **** **** **** **** **** **** +4980 Assassin_Improved_Invisibility **** **** **** **** **** **** **** **** +4981 Assassin_LocateCreature **** **** **** **** **** **** **** **** +4982 Assassin_Poison **** **** **** **** **** **** **** **** +4983 Assassin_STOP_HEART **** **** **** **** **** **** **** **** +4984 Blackguard_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4985 Blackguard_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4986 Blackguard_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4987 Blackguard_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4988 Blackguard_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +4989 Blackguard_Cause_Fear **** **** **** **** **** **** **** **** +4990 Blackguard_Exteneded_Cause_Fear **** **** **** **** **** **** **** **** +4991 Blackguard_Still_Cause_Fear **** **** **** **** **** **** **** **** +4992 Blackguard_Doom **** **** **** **** **** **** **** **** +4993 Blackguard_Exteneded_Doom **** **** **** **** **** **** **** **** +4994 Blackguard_Silent_Doom **** **** **** **** **** **** **** **** +4995 Blackguard_Still_Doom **** **** **** **** **** **** **** **** +4996 Blackguard_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +4997 Blackguard_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +4998 Blackguard_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +4999 Blackguard_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5000 Blackguard_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5001 Blackguard_Magic_Weapon **** **** **** **** **** **** **** **** +5002 Blackguard_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +5003 Blackguard_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +5004 Blackguard_Still_Magic_Weapon **** **** **** **** **** **** **** **** +5005 Blackguard_Summon_Creature_I **** **** **** **** **** **** **** **** +5006 Blackguard_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +5007 Blackguard_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +5008 Blackguard_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +5009 Blackguard_Blade_of_Blood **** **** **** **** **** **** **** **** +5010 Blackguard_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5011 Blackguard_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5012 Blackguard_Empowered_Blade_of_Blood **** **** **** **** **** **** **** **** +5013 Blackguard_Empowered_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5014 Blackguard_Empowered_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5015 Blackguard_Exteneded_Blade_of_Blood **** **** **** **** **** **** **** **** +5016 Blackguard_Exteneded_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5017 Blackguard_Exteneded_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5018 Blackguard_Maximized_Blade_of_Blood **** **** **** **** **** **** **** **** +5019 Blackguard_Maximized_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5020 Blackguard_Maximized_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5021 Blackguard_Silent_Blade_of_Blood **** **** **** **** **** **** **** **** +5022 Blackguard_Silent_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5023 Blackguard_Silent_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5024 Blackguard_Still_Blade_of_Blood **** **** **** **** **** **** **** **** +5025 Blackguard_Still_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5026 Blackguard_Still_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5027 Blackguard_BONEBLAST **** **** **** **** **** **** **** **** +5028 Blackguard_Silent_BONEBLAST **** **** **** **** **** **** **** **** +5029 Blackguard_Still_BONEBLAST **** **** **** **** **** **** **** **** +5030 Blackguard_DEMONFLESH **** **** **** **** **** **** **** **** +5031 Blackguard_Exteneded_DEMONFLESH **** **** **** **** **** **** **** **** +5032 Blackguard_Silent_DEMONFLESH **** **** **** **** **** **** **** **** +5033 Blackguard_Still_DEMONFLESH **** **** **** **** **** **** **** **** +5034 Blackguard_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5035 Blackguard_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5036 Blackguard_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5037 Blackguard_SummonUndeadI **** **** **** **** **** **** **** **** +5038 Blackguard_Exteneded_SummonUndeadI **** **** **** **** **** **** **** **** +5039 Blackguard_Silent_SummonUndeadI **** **** **** **** **** **** **** **** +5040 Blackguard_Still_SummonUndeadI **** **** **** **** **** **** **** **** +5041 Blackguard_Bulls_Strength **** **** **** **** **** **** **** **** +5042 Blackguard_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +5043 Blackguard_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +5044 Blackguard_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +5045 Blackguard_Still_Bulls_Strength **** **** **** **** **** **** **** **** +5046 Blackguard_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5047 Blackguard_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5048 Blackguard_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5049 Blackguard_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5050 Blackguard_Darkness **** **** **** **** **** **** **** **** +5051 Blackguard_Exteneded_Darkness **** **** **** **** **** **** **** **** +5052 Blackguard_Silent_Darkness **** **** **** **** **** **** **** **** +5053 Blackguard_Eagle_Splendor **** **** **** **** **** **** **** **** +5054 Blackguard_Empowered_Eagle_Splendor **** **** **** **** **** **** **** **** +5055 Blackguard_Exteneded_Eagle_Splendor **** **** **** **** **** **** **** **** +5056 Blackguard_Silent_Eagle_Splendor **** **** **** **** **** **** **** **** +5057 Blackguard_Still_Eagle_Splendor **** **** **** **** **** **** **** **** +5058 Blackguard_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5059 Blackguard_Empowered_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5060 Blackguard_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5061 Blackguard_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5062 Blackguard_Summon_Creature_II **** **** **** **** **** **** **** **** +5063 Blackguard_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +5064 Blackguard_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +5065 Blackguard_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +5066 Blackguard_BONEBLADE **** **** **** **** **** **** **** **** +5067 Blackguard_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5068 Blackguard_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5069 Blackguard_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5070 Blackguard_Exteneded_BONEBLADE **** **** **** **** **** **** **** **** +5071 Blackguard_Exteneded_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5072 Blackguard_Exteneded_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5073 Blackguard_Exteneded_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5074 Blackguard_Silent_BONEBLADE **** **** **** **** **** **** **** **** +5075 Blackguard_Silent_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5076 Blackguard_Silent_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5077 Blackguard_Silent_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5078 Blackguard_Still_BONEBLADE **** **** **** **** **** **** **** **** +5079 Blackguard_Still_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5080 Blackguard_Still_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5081 Blackguard_Still_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5082 Blackguard_Death_Knell **** **** **** **** **** **** **** **** +5083 Blackguard_Empowered_Death_Knell **** **** **** **** **** **** **** **** +5084 Blackguard_Exteneded_Death_Knell **** **** **** **** **** **** **** **** +5085 Blackguard_Silent_Death_Knell **** **** **** **** **** **** **** **** +5086 Blackguard_Still_Death_Knell **** **** **** **** **** **** **** **** +5087 Blackguard_DEMONCALL **** **** **** **** **** **** **** **** +5088 Blackguard_Silent_DEMONCALL **** **** **** **** **** **** **** **** +5089 Blackguard_Still_DEMONCALL **** **** **** **** **** **** **** **** +5090 Blackguard_DEVILS_EYE **** **** **** **** **** **** **** **** +5091 Blackguard_Silent_DEVILS_EYE **** **** **** **** **** **** **** **** +5092 Blackguard_Still_DEVILS_EYE **** **** **** **** **** **** **** **** +5093 Blackguard_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5094 Blackguard_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5095 Blackguard_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5096 Blackguard_SummonUndeadII **** **** **** **** **** **** **** **** +5097 Blackguard_Exteneded_SummonUndeadII **** **** **** **** **** **** **** **** +5098 Blackguard_Silent_SummonUndeadII **** **** **** **** **** **** **** **** +5099 Blackguard_Still_SummonUndeadII **** **** **** **** **** **** **** **** +5100 Blackguard_Contagion **** **** **** **** **** **** **** **** +5101 Blackguard_Silent_Contagion **** **** **** **** **** **** **** **** +5102 Blackguard_Still_Contagion **** **** **** **** **** **** **** **** +5103 Blackguard_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5104 Blackguard_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5105 Blackguard_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5106 Blackguard_DeeperDarkness **** **** **** **** **** **** **** **** +5107 Blackguard_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +5108 Blackguard_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +5109 Blackguard_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5110 Blackguard_Silent_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5111 Blackguard_Still_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5112 Blackguard_Protection_from_Elements **** **** **** **** **** **** **** **** +5113 Blackguard_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +5114 Blackguard_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +5115 Blackguard_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +5116 Blackguard_Summon_Creature_III **** **** **** **** **** **** **** **** +5117 Blackguard_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +5118 Blackguard_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +5119 Blackguard_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +5120 Blackguard_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5121 Blackguard_Exteneded_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5122 Blackguard_Silent_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5123 Blackguard_Still_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5124 Blackguard_RED_FESTER **** **** **** **** **** **** **** **** +5125 Blackguard_Silent_RED_FESTER **** **** **** **** **** **** **** **** +5126 Blackguard_Still_RED_FESTER **** **** **** **** **** **** **** **** +5127 Blackguard_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5128 Blackguard_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5129 Blackguard_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5130 Blackguard_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5131 Blackguard_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5132 Blackguard_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5133 Blackguard_MASOCHISM **** **** **** **** **** **** **** **** +5134 Blackguard_Exteneded_MASOCHISM **** **** **** **** **** **** **** **** +5135 Blackguard_SummonUndeadIII **** **** **** **** **** **** **** **** +5136 Blackguard_Exteneded_SummonUndeadIII **** **** **** **** **** **** **** **** +5137 Blackguard_Silent_SummonUndeadIII **** **** **** **** **** **** **** **** +5138 Blackguard_Still_SummonUndeadIII **** **** **** **** **** **** **** **** +5139 Blackguard_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +5140 Blackguard_Freedom_of_Movement **** **** **** **** **** **** **** **** +5141 Blackguard_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +5142 Blackguard_Poison **** **** **** **** **** **** **** **** +5143 Blackguard_Summon_Creature_IV **** **** **** **** **** **** **** **** +5144 Blackguard_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +5145 Blackguard_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +5146 Blackguard_SummonUndeadIV **** **** **** **** **** **** **** **** +5147 Ocular_Adept_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +5148 Ocular_Adept_Quickened_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +5149 Ocular_Adept_Silent_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +5150 Ocular_Adept_Still_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +5151 Ocular_Adept_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +5152 Ocular_Adept_Quickened_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +5153 Ocular_Adept_Silent_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +5154 Ocular_Adept_Still_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +5155 Ocular_Adept_Light **** **** **** **** **** **** **** **** +5156 Ocular_Adept_Exteneded_Light **** **** **** **** **** **** **** **** +5157 Ocular_Adept_Quickened_Light **** **** **** **** **** **** **** **** +5158 Ocular_Adept_Silent_Light **** **** **** **** **** **** **** **** +5159 Ocular_Adept_Read_Magic **** **** **** **** **** **** **** **** +5160 Ocular_Adept_Quickened_Read_Magic **** **** **** **** **** **** **** **** +5161 Ocular_Adept_Silent_Read_Magic **** **** **** **** **** **** **** **** +5162 Ocular_Adept_Still_Read_Magic **** **** **** **** **** **** **** **** +5163 Ocular_Adept_Resistance **** **** **** **** **** **** **** **** +5164 Ocular_Adept_Exteneded_Resistance **** **** **** **** **** **** **** **** +5165 Ocular_Adept_Quickened_Resistance **** **** **** **** **** **** **** **** +5166 Ocular_Adept_Silent_Resistance **** **** **** **** **** **** **** **** +5167 Ocular_Adept_Still_Resistance **** **** **** **** **** **** **** **** +5168 Ocular_Adept_Virtue **** **** **** **** **** **** **** **** +5169 Ocular_Adept_Exteneded_Virtue **** **** **** **** **** **** **** **** +5170 Ocular_Adept_Quickened_Virtue **** **** **** **** **** **** **** **** +5171 Ocular_Adept_Silent_Virtue **** **** **** **** **** **** **** **** +5172 Ocular_Adept_Still_Virtue **** **** **** **** **** **** **** **** +5173 Ocular_Adept_ANGRY_ACHE **** **** **** **** **** **** **** **** +5174 Ocular_Adept_Exteneded_ANGRY_ACHE **** **** **** **** **** **** **** **** +5175 Ocular_Adept_Quickened_ANGRY_ACHE **** **** **** **** **** **** **** **** +5176 Ocular_Adept_Silent_ANGRY_ACHE **** **** **** **** **** **** **** **** +5177 Ocular_Adept_Still_ANGRY_ACHE **** **** **** **** **** **** **** **** +5178 Ocular_Adept_Bane **** **** **** **** **** **** **** **** +5179 Ocular_Adept_Exteneded_Bane **** **** **** **** **** **** **** **** +5180 Ocular_Adept_Quickened_Bane **** **** **** **** **** **** **** **** +5181 Ocular_Adept_Silent_Bane **** **** **** **** **** **** **** **** +5182 Ocular_Adept_Still_Bane **** **** **** **** **** **** **** **** +5183 Ocular_Adept_Blade_of_Blood **** **** **** **** **** **** **** **** +5184 Ocular_Adept_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5185 Ocular_Adept_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5186 Ocular_Adept_Empowered_Blade_of_Blood **** **** **** **** **** **** **** **** +5187 Ocular_Adept_Empowered_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5188 Ocular_Adept_Empowered_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5189 Ocular_Adept_Exteneded_Blade_of_Blood **** **** **** **** **** **** **** **** +5190 Ocular_Adept_Exteneded_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5191 Ocular_Adept_Exteneded_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5192 Ocular_Adept_Maximized_Blade_of_Blood **** **** **** **** **** **** **** **** +5193 Ocular_Adept_Maximized_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5194 Ocular_Adept_Maximized_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5195 Ocular_Adept_Quickened_Blade_of_Blood **** **** **** **** **** **** **** **** +5196 Ocular_Adept_Quickened_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5197 Ocular_Adept_Quickened_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5198 Ocular_Adept_Silent_Blade_of_Blood **** **** **** **** **** **** **** **** +5199 Ocular_Adept_Silent_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5200 Ocular_Adept_Silent_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5201 Ocular_Adept_Still_Blade_of_Blood **** **** **** **** **** **** **** **** +5202 Ocular_Adept_Still_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +5203 Ocular_Adept_Still_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +5204 Ocular_Adept_Bless **** **** **** **** **** **** **** **** +5205 Ocular_Adept_Exteneded_Bless **** **** **** **** **** **** **** **** +5206 Ocular_Adept_Quickened_Bless **** **** **** **** **** **** **** **** +5207 Ocular_Adept_Silent_Bless **** **** **** **** **** **** **** **** +5208 Ocular_Adept_Still_Bless **** **** **** **** **** **** **** **** +5209 Ocular_Adept_Bless_Water **** **** **** **** **** **** **** **** +5210 Ocular_Adept_Quickened_Bless_Water **** **** **** **** **** **** **** **** +5211 Ocular_Adept_Silent_Bless_Water **** **** **** **** **** **** **** **** +5212 Ocular_Adept_Still_Bless_Water **** **** **** **** **** **** **** **** +5213 Ocular_Adept_Cause_Fear **** **** **** **** **** **** **** **** +5214 Ocular_Adept_Exteneded_Cause_Fear **** **** **** **** **** **** **** **** +5215 Ocular_Adept_Quickened_Cause_Fear **** **** **** **** **** **** **** **** +5216 Ocular_Adept_Still_Cause_Fear **** **** **** **** **** **** **** **** +5217 Ocular_Adept_Command_RadialMaster **** **** **** **** **** **** **** **** +5218 Ocular_Adept_Command_Approach **** **** **** **** **** **** **** **** +5219 Ocular_Adept_Command_Drop **** **** **** **** **** **** **** **** +5220 Ocular_Adept_Command_Fall **** **** **** **** **** **** **** **** +5221 Ocular_Adept_Command_Flee **** **** **** **** **** **** **** **** +5222 Ocular_Adept_Command_Halt **** **** **** **** **** **** **** **** +5223 Ocular_Adept_Exteneded_Command_RadialMaster **** **** **** **** **** **** **** **** +5224 Ocular_Adept_Exteneded_Command_Approach **** **** **** **** **** **** **** **** +5225 Ocular_Adept_Exteneded_Command_Drop **** **** **** **** **** **** **** **** +5226 Ocular_Adept_Exteneded_Command_Fall **** **** **** **** **** **** **** **** +5227 Ocular_Adept_Exteneded_Command_Flee **** **** **** **** **** **** **** **** +5228 Ocular_Adept_Exteneded_Command_Halt **** **** **** **** **** **** **** **** +5229 Ocular_Adept_Quickened_Command_RadialMaster **** **** **** **** **** **** **** **** +5230 Ocular_Adept_Quickened_Command_Approach **** **** **** **** **** **** **** **** +5231 Ocular_Adept_Quickened_Command_Drop **** **** **** **** **** **** **** **** +5232 Ocular_Adept_Quickened_Command_Fall **** **** **** **** **** **** **** **** +5233 Ocular_Adept_Quickened_Command_Flee **** **** **** **** **** **** **** **** +5234 Ocular_Adept_Quickened_Command_Halt **** **** **** **** **** **** **** **** +5235 Ocular_Adept_Silent_Command_RadialMaster **** **** **** **** **** **** **** **** +5236 Ocular_Adept_Silent_Command_Approach **** **** **** **** **** **** **** **** +5237 Ocular_Adept_Silent_Command_Drop **** **** **** **** **** **** **** **** +5238 Ocular_Adept_Silent_Command_Fall **** **** **** **** **** **** **** **** +5239 Ocular_Adept_Silent_Command_Flee **** **** **** **** **** **** **** **** +5240 Ocular_Adept_Silent_Command_Halt **** **** **** **** **** **** **** **** +5241 Ocular_Adept_Still_Command_RadialMaster **** **** **** **** **** **** **** **** +5242 Ocular_Adept_Still_Command_Approach **** **** **** **** **** **** **** **** +5243 Ocular_Adept_Still_Command_Drop **** **** **** **** **** **** **** **** +5244 Ocular_Adept_Still_Command_Fall **** **** **** **** **** **** **** **** +5245 Ocular_Adept_Still_Command_Flee **** **** **** **** **** **** **** **** +5246 Ocular_Adept_Still_Command_Halt **** **** **** **** **** **** **** **** +5247 Ocular_Adept_Conviction **** **** **** **** **** **** **** **** +5248 Ocular_Adept_Exteneded_Conviction **** **** **** **** **** **** **** **** +5249 Ocular_Adept_Quickened_Conviction **** **** **** **** **** **** **** **** +5250 Ocular_Adept_Silent_Conviction **** **** **** **** **** **** **** **** +5251 Ocular_Adept_Still_Conviction **** **** **** **** **** **** **** **** +5252 Ocular_Adept_Crafters_Blessing **** **** **** **** **** **** **** **** +5253 Ocular_Adept_Exteneded_Crafters_Blessing **** **** **** **** **** **** **** **** +5254 Ocular_Adept_Quickened_Crafters_Blessing **** **** **** **** **** **** **** **** +5255 Ocular_Adept_Silent_Crafters_Blessing **** **** **** **** **** **** **** **** +5256 Ocular_Adept_Still_Crafters_Blessing **** **** **** **** **** **** **** **** +5257 Ocular_Adept_Crafters_Curse **** **** **** **** **** **** **** **** +5258 Ocular_Adept_Exteneded_Crafters_Curse **** **** **** **** **** **** **** **** +5259 Ocular_Adept_Quickened_Crafters_Curse **** **** **** **** **** **** **** **** +5260 Ocular_Adept_Silent_Crafters_Curse **** **** **** **** **** **** **** **** +5261 Ocular_Adept_Still_Crafters_Curse **** **** **** **** **** **** **** **** +5262 Ocular_Adept_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5263 Ocular_Adept_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5264 Ocular_Adept_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5265 Ocular_Adept_Quickened_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5266 Ocular_Adept_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5267 Ocular_Adept_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +5268 Ocular_Adept_Curse_Water **** **** **** **** **** **** **** **** +5269 Ocular_Adept_Quickened_Curse_Water **** **** **** **** **** **** **** **** +5270 Ocular_Adept_Silent_Curse_Water **** **** **** **** **** **** **** **** +5271 Ocular_Adept_Still_Curse_Water **** **** **** **** **** **** **** **** +5272 Ocular_Adept_Detect_Chaos **** **** **** **** **** **** **** **** +5273 Ocular_Adept_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +5274 Ocular_Adept_Quickened_Detect_Chaos **** **** **** **** **** **** **** **** +5275 Ocular_Adept_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +5276 Ocular_Adept_Still_Detect_Chaos **** **** **** **** **** **** **** **** +5277 Ocular_Adept_Detect_Evil **** **** **** **** **** **** **** **** +5278 Ocular_Adept_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +5279 Ocular_Adept_Quickened_Detect_Evil **** **** **** **** **** **** **** **** +5280 Ocular_Adept_Silent_Detect_Evil **** **** **** **** **** **** **** **** +5281 Ocular_Adept_Still_Detect_Evil **** **** **** **** **** **** **** **** +5282 Ocular_Adept_Detect_Good **** **** **** **** **** **** **** **** +5283 Ocular_Adept_Exteneded_Detect_Good **** **** **** **** **** **** **** **** +5284 Ocular_Adept_Quickened_Detect_Good **** **** **** **** **** **** **** **** +5285 Ocular_Adept_Silent_Detect_Good **** **** **** **** **** **** **** **** +5286 Ocular_Adept_Still_Detect_Good **** **** **** **** **** **** **** **** +5287 Ocular_Adept_Detect_Law **** **** **** **** **** **** **** **** +5288 Ocular_Adept_Exteneded_Detect_Law **** **** **** **** **** **** **** **** +5289 Ocular_Adept_Quickened_Detect_Law **** **** **** **** **** **** **** **** +5290 Ocular_Adept_Silent_Detect_Law **** **** **** **** **** **** **** **** +5291 Ocular_Adept_Still_Detect_Law **** **** **** **** **** **** **** **** +5292 Ocular_Adept_DETECT_UNDEAD **** **** **** **** **** **** **** **** +5293 Ocular_Adept_Exteneded_DETECT_UNDEAD **** **** **** **** **** **** **** **** +5294 Ocular_Adept_Quickened_DETECT_UNDEAD **** **** **** **** **** **** **** **** +5295 Ocular_Adept_Silent_DETECT_UNDEAD **** **** **** **** **** **** **** **** +5296 Ocular_Adept_Still_DETECT_UNDEAD **** **** **** **** **** **** **** **** +5297 Ocular_Adept_Divine_Favor **** **** **** **** **** **** **** **** +5298 Ocular_Adept_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +5299 Ocular_Adept_Quickened_Divine_Favor **** **** **** **** **** **** **** **** +5300 Ocular_Adept_Silent_Divine_Favor **** **** **** **** **** **** **** **** +5301 Ocular_Adept_Still_Divine_Favor **** **** **** **** **** **** **** **** +5302 Ocular_Adept_Doom **** **** **** **** **** **** **** **** +5303 Ocular_Adept_Exteneded_Doom **** **** **** **** **** **** **** **** +5304 Ocular_Adept_Quickened_Doom **** **** **** **** **** **** **** **** +5305 Ocular_Adept_Silent_Doom **** **** **** **** **** **** **** **** +5306 Ocular_Adept_Still_Doom **** **** **** **** **** **** **** **** +5307 Ocular_Adept_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +5308 Ocular_Adept_Quickened_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +5309 Ocular_Adept_Silent_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +5310 Ocular_Adept_Endure_Elements **** **** **** **** **** **** **** **** +5311 Ocular_Adept_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +5312 Ocular_Adept_Quickened_Endure_Elements **** **** **** **** **** **** **** **** +5313 Ocular_Adept_Silent_Endure_Elements **** **** **** **** **** **** **** **** +5314 Ocular_Adept_Still_Endure_Elements **** **** **** **** **** **** **** **** +5315 Ocular_Adept_Entropic_Shield **** **** **** **** **** **** **** **** +5316 Ocular_Adept_Exteneded_Entropic_Shield **** **** **** **** **** **** **** **** +5317 Ocular_Adept_Quickened_Entropic_Shield **** **** **** **** **** **** **** **** +5318 Ocular_Adept_Silent_Entropic_Shield **** **** **** **** **** **** **** **** +5319 Ocular_Adept_Still_Entropic_Shield **** **** **** **** **** **** **** **** +5320 Ocular_Adept_EXTRACT_DRUG **** **** **** **** **** **** **** **** +5321 Ocular_Adept_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +5322 Ocular_Adept_EXTRACT_VODARE **** **** **** **** **** **** **** **** +5323 Ocular_Adept_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +5324 Ocular_Adept_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5325 Ocular_Adept_Quickened_EXTRACT_DRUG **** **** **** **** **** **** **** **** +5326 Ocular_Adept_Quickened_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +5327 Ocular_Adept_Quickened_EXTRACT_VODARE **** **** **** **** **** **** **** **** +5328 Ocular_Adept_Quickened_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +5329 Ocular_Adept_Quickened_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5330 Ocular_Adept_Silent_EXTRACT_DRUG **** **** **** **** **** **** **** **** +5331 Ocular_Adept_Silent_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +5332 Ocular_Adept_Silent_EXTRACT_VODARE **** **** **** **** **** **** **** **** +5333 Ocular_Adept_Silent_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +5334 Ocular_Adept_Silent_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5335 Ocular_Adept_Still_EXTRACT_DRUG **** **** **** **** **** **** **** **** +5336 Ocular_Adept_Still_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +5337 Ocular_Adept_Still_EXTRACT_VODARE **** **** **** **** **** **** **** **** +5338 Ocular_Adept_Still_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +5339 Ocular_Adept_Still_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5340 Ocular_Adept_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +5341 Ocular_Adept_Exteneded_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +5342 Ocular_Adept_Quickened_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +5343 Ocular_Adept_Still_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +5344 Ocular_Adept_HEARTACHE **** **** **** **** **** **** **** **** +5345 Ocular_Adept_Exteneded_HEARTACHE **** **** **** **** **** **** **** **** +5346 Ocular_Adept_Quickened_HEARTACHE **** **** **** **** **** **** **** **** +5347 Ocular_Adept_Silent_HEARTACHE **** **** **** **** **** **** **** **** +5348 Ocular_Adept_Still_HEARTACHE **** **** **** **** **** **** **** **** +5349 Ocular_Adept_HideFromUndead **** **** **** **** **** **** **** **** +5350 Ocular_Adept_Exteneded_HideFromUndead **** **** **** **** **** **** **** **** +5351 Ocular_Adept_Quickened_HideFromUndead **** **** **** **** **** **** **** **** +5352 Ocular_Adept_Still_HideFromUndead **** **** **** **** **** **** **** **** +5353 Ocular_Adept_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5354 Ocular_Adept_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5355 Ocular_Adept_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5356 Ocular_Adept_Quickened_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5357 Ocular_Adept_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5358 Ocular_Adept_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +5359 Ocular_Adept_LANTERN_LIGHT **** **** **** **** **** **** **** **** +5360 Ocular_Adept_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +5361 Ocular_Adept_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +5362 Ocular_Adept_Quickened_LANTERN_LIGHT **** **** **** **** **** **** **** **** +5363 Ocular_Adept_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +5364 Ocular_Adept_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5365 Ocular_Adept_Empowered_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5366 Ocular_Adept_Exteneded_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5367 Ocular_Adept_Maximized_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5368 Ocular_Adept_Quickened_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5369 Ocular_Adept_Silent_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5370 Ocular_Adept_Still_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5371 Ocular_Adept_Lesser_Vigor **** **** **** **** **** **** **** **** +5372 Ocular_Adept_Exteneded_Lesser_Vigor **** **** **** **** **** **** **** **** +5373 Ocular_Adept_Quickened_Lesser_Vigor **** **** **** **** **** **** **** **** +5374 Ocular_Adept_Silent_Lesser_Vigor **** **** **** **** **** **** **** **** +5375 Ocular_Adept_Still_Lesser_Vigor **** **** **** **** **** **** **** **** +5376 Ocular_Adept_Magic_Stone **** **** **** **** **** **** **** **** +5377 Ocular_Adept_Exteneded_Magic_Stone **** **** **** **** **** **** **** **** +5378 Ocular_Adept_Quickened_Magic_Stone **** **** **** **** **** **** **** **** +5379 Ocular_Adept_Silent_Magic_Stone **** **** **** **** **** **** **** **** +5380 Ocular_Adept_Still_Magic_Stone **** **** **** **** **** **** **** **** +5381 Ocular_Adept_Magic_Weapon **** **** **** **** **** **** **** **** +5382 Ocular_Adept_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +5383 Ocular_Adept_Quickened_Magic_Weapon **** **** **** **** **** **** **** **** +5384 Ocular_Adept_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +5385 Ocular_Adept_Still_Magic_Weapon **** **** **** **** **** **** **** **** +5386 Ocular_Adept_Necrotic_Awareness **** **** **** **** **** **** **** **** +5387 Ocular_Adept_Quickened_Necrotic_Awareness **** **** **** **** **** **** **** **** +5388 Ocular_Adept_Silent_Necrotic_Awareness **** **** **** **** **** **** **** **** +5389 Ocular_Adept_Still_Necrotic_Awareness **** **** **** **** **** **** **** **** +5390 Ocular_Adept_Obscuring_Mist **** **** **** **** **** **** **** **** +5391 Ocular_Adept_Exteneded_Obscuring_Mist **** **** **** **** **** **** **** **** +5392 Ocular_Adept_Quickened_Obscuring_Mist **** **** **** **** **** **** **** **** +5393 Ocular_Adept_Silent_Obscuring_Mist **** **** **** **** **** **** **** **** +5394 Ocular_Adept_Still_Obscuring_Mist **** **** **** **** **** **** **** **** +5395 Ocular_Adept_Protection_from_Chaos **** **** **** **** **** **** **** **** +5396 Ocular_Adept_Exteneded_Protection_from_Chaos **** **** **** **** **** **** **** **** +5397 Ocular_Adept_Quickened_Protection_from_Chaos **** **** **** **** **** **** **** **** +5398 Ocular_Adept_Silent_Protection_from_Chaos **** **** **** **** **** **** **** **** +5399 Ocular_Adept_Still_Protection_from_Chaos **** **** **** **** **** **** **** **** +5400 Ocular_Adept_Protection_from_Evil **** **** **** **** **** **** **** **** +5401 Ocular_Adept_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +5402 Ocular_Adept_Quickened_Protection_from_Evil **** **** **** **** **** **** **** **** +5403 Ocular_Adept_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +5404 Ocular_Adept_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +5405 Ocular_Adept_Protection_from_Good **** **** **** **** **** **** **** **** +5406 Ocular_Adept_Exteneded_Protection_from_Good **** **** **** **** **** **** **** **** +5407 Ocular_Adept_Quickened_Protection_from_Good **** **** **** **** **** **** **** **** +5408 Ocular_Adept_Silent_Protection_from_Good **** **** **** **** **** **** **** **** +5409 Ocular_Adept_Still_Protection_from_Good **** **** **** **** **** **** **** **** +5410 Ocular_Adept_Protection_from_Law **** **** **** **** **** **** **** **** +5411 Ocular_Adept_Exteneded_Protection_from_Law **** **** **** **** **** **** **** **** +5412 Ocular_Adept_Quickened_Protection_from_Law **** **** **** **** **** **** **** **** +5413 Ocular_Adept_Silent_Protection_from_Law **** **** **** **** **** **** **** **** +5414 Ocular_Adept_Still_Protection_from_Law **** **** **** **** **** **** **** **** +5415 Ocular_Adept_RAY_OF_HOPE **** **** **** **** **** **** **** **** +5416 Ocular_Adept_Exteneded_RAY_OF_HOPE **** **** **** **** **** **** **** **** +5417 Ocular_Adept_Quickened_RAY_OF_HOPE **** **** **** **** **** **** **** **** +5418 Ocular_Adept_Silent_RAY_OF_HOPE **** **** **** **** **** **** **** **** +5419 Ocular_Adept_Still_RAY_OF_HOPE **** **** **** **** **** **** **** **** +5420 Ocular_Adept_Remove_Fear **** **** **** **** **** **** **** **** +5421 Ocular_Adept_Exteneded_Remove_Fear **** **** **** **** **** **** **** **** +5422 Ocular_Adept_Quickened_Remove_Fear **** **** **** **** **** **** **** **** +5423 Ocular_Adept_Silent_Remove_Fear **** **** **** **** **** **** **** **** +5424 Ocular_Adept_Still_Remove_Fear **** **** **** **** **** **** **** **** +5425 Ocular_Adept_Sanctuary **** **** **** **** **** **** **** **** +5426 Ocular_Adept_Exteneded_Sanctuary **** **** **** **** **** **** **** **** +5427 Ocular_Adept_Quickened_Sanctuary **** **** **** **** **** **** **** **** +5428 Ocular_Adept_Silent_Sanctuary **** **** **** **** **** **** **** **** +5429 Ocular_Adept_Still_Sanctuary **** **** **** **** **** **** **** **** +5430 Ocular_Adept_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5431 Ocular_Adept_Quickened_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5432 Ocular_Adept_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5433 Ocular_Adept_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +5434 Ocular_Adept_Shield_of_Faith **** **** **** **** **** **** **** **** +5435 Ocular_Adept_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +5436 Ocular_Adept_Quickened_Shield_of_Faith **** **** **** **** **** **** **** **** +5437 Ocular_Adept_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +5438 Ocular_Adept_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +5439 Ocular_Adept_SORROW **** **** **** **** **** **** **** **** +5440 Ocular_Adept_Quickened_SORROW **** **** **** **** **** **** **** **** +5441 Ocular_Adept_Silent_SORROW **** **** **** **** **** **** **** **** +5442 Ocular_Adept_Still_SORROW **** **** **** **** **** **** **** **** +5443 Ocular_Adept_Summon_Creature_I **** **** **** **** **** **** **** **** +5444 Ocular_Adept_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +5445 Ocular_Adept_Quickened_Summon_Creature_I **** **** **** **** **** **** **** **** +5446 Ocular_Adept_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +5447 Ocular_Adept_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +5448 Ocular_Adept_SummonUndeadI **** **** **** **** **** **** **** **** +5449 Ocular_Adept_Exteneded_SummonUndeadI **** **** **** **** **** **** **** **** +5450 Ocular_Adept_Quickened_SummonUndeadI **** **** **** **** **** **** **** **** +5451 Ocular_Adept_Silent_SummonUndeadI **** **** **** **** **** **** **** **** +5452 Ocular_Adept_Still_SummonUndeadI **** **** **** **** **** **** **** **** +5453 Ocular_Adept_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +5454 Ocular_Adept_Exteneded_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +5455 Ocular_Adept_Quickened_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +5456 Ocular_Adept_Silent_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +5457 Ocular_Adept_Still_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +5458 Ocular_Adept_VisionOfHeaven **** **** **** **** **** **** **** **** +5459 Ocular_Adept_Exteneded_VisionOfHeaven **** **** **** **** **** **** **** **** +5460 Ocular_Adept_Quickened_VisionOfHeaven **** **** **** **** **** **** **** **** +5461 Ocular_Adept_Silent_VisionOfHeaven **** **** **** **** **** **** **** **** +5462 Ocular_Adept_ADDICTION **** **** **** **** **** **** **** **** +5463 Ocular_Adept_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +5464 Ocular_Adept_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5465 Ocular_Adept_ADDICTION_VODARE **** **** **** **** **** **** **** **** +5466 Ocular_Adept_ADDICTION_AGONY **** **** **** **** **** **** **** **** +5467 Ocular_Adept_Silent_ADDICTION **** **** **** **** **** **** **** **** +5468 Ocular_Adept_Silent_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +5469 Ocular_Adept_Silent_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5470 Ocular_Adept_Silent_ADDICTION_VODARE **** **** **** **** **** **** **** **** +5471 Ocular_Adept_Silent_ADDICTION_AGONY **** **** **** **** **** **** **** **** +5472 Ocular_Adept_Still_ADDICTION **** **** **** **** **** **** **** **** +5473 Ocular_Adept_Still_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +5474 Ocular_Adept_Still_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +5475 Ocular_Adept_Still_ADDICTION_VODARE **** **** **** **** **** **** **** **** +5476 Ocular_Adept_Still_ADDICTION_AGONY **** **** **** **** **** **** **** **** +5477 Ocular_Adept_Aid **** **** **** **** **** **** **** **** +5478 Ocular_Adept_Empowered_Aid **** **** **** **** **** **** **** **** +5479 Ocular_Adept_Exteneded_Aid **** **** **** **** **** **** **** **** +5480 Ocular_Adept_Maximized_Aid **** **** **** **** **** **** **** **** +5481 Ocular_Adept_Silent_Aid **** **** **** **** **** **** **** **** +5482 Ocular_Adept_Still_Aid **** **** **** **** **** **** **** **** +5483 Ocular_Adept_Animalistic_Power **** **** **** **** **** **** **** **** +5484 Ocular_Adept_Exteneded_Animalistic_Power **** **** **** **** **** **** **** **** +5485 Ocular_Adept_BONEBLAST **** **** **** **** **** **** **** **** +5486 Ocular_Adept_Silent_BONEBLAST **** **** **** **** **** **** **** **** +5487 Ocular_Adept_Still_BONEBLAST **** **** **** **** **** **** **** **** +5488 Ocular_Adept_Bulls_Strength **** **** **** **** **** **** **** **** +5489 Ocular_Adept_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +5490 Ocular_Adept_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +5491 Ocular_Adept_Maximized_Bulls_Strength **** **** **** **** **** **** **** **** +5492 Ocular_Adept_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +5493 Ocular_Adept_Still_Bulls_Strength **** **** **** **** **** **** **** **** +5494 Ocular_Adept_Calm_Emotions **** **** **** **** **** **** **** **** +5495 Ocular_Adept_Exteneded_Calm_Emotions **** **** **** **** **** **** **** **** +5496 Ocular_Adept_Silent_Calm_Emotions **** **** **** **** **** **** **** **** +5497 Ocular_Adept_Still_Calm_Emotions **** **** **** **** **** **** **** **** +5498 Ocular_Adept_Consecrated_Aura **** **** **** **** **** **** **** **** +5499 Ocular_Adept_Exteneded_Consecrated_Aura **** **** **** **** **** **** **** **** +5500 Ocular_Adept_Silent_Consecrated_Aura **** **** **** **** **** **** **** **** +5501 Ocular_Adept_Still_Consecrated_Aura **** **** **** **** **** **** **** **** +5502 Ocular_Adept_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5503 Ocular_Adept_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5504 Ocular_Adept_Maximized_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5505 Ocular_Adept_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5506 Ocular_Adept_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +5507 Ocular_Adept_Darkness **** **** **** **** **** **** **** **** +5508 Ocular_Adept_Exteneded_Darkness **** **** **** **** **** **** **** **** +5509 Ocular_Adept_Silent_Darkness **** **** **** **** **** **** **** **** +5510 Ocular_Adept_Death_Knell **** **** **** **** **** **** **** **** +5511 Ocular_Adept_Empowered_Death_Knell **** **** **** **** **** **** **** **** +5512 Ocular_Adept_Exteneded_Death_Knell **** **** **** **** **** **** **** **** +5513 Ocular_Adept_Maximized_Death_Knell **** **** **** **** **** **** **** **** +5514 Ocular_Adept_Silent_Death_Knell **** **** **** **** **** **** **** **** +5515 Ocular_Adept_Still_Death_Knell **** **** **** **** **** **** **** **** +5516 Ocular_Adept_Divine_Protection **** **** **** **** **** **** **** **** +5517 Ocular_Adept_Exteneded_Divine_Protection **** **** **** **** **** **** **** **** +5518 Ocular_Adept_Silent_Divine_Protection **** **** **** **** **** **** **** **** +5519 Ocular_Adept_Still_Divine_Protection **** **** **** **** **** **** **** **** +5520 Ocular_Adept_Eagle_Splendor **** **** **** **** **** **** **** **** +5521 Ocular_Adept_Empowered_Eagle_Splendor **** **** **** **** **** **** **** **** +5522 Ocular_Adept_Exteneded_Eagle_Splendor **** **** **** **** **** **** **** **** +5523 Ocular_Adept_Maximized_Eagle_Splendor **** **** **** **** **** **** **** **** +5524 Ocular_Adept_Silent_Eagle_Splendor **** **** **** **** **** **** **** **** +5525 Ocular_Adept_Still_Eagle_Splendor **** **** **** **** **** **** **** **** +5526 Ocular_Adept_ELATION **** **** **** **** **** **** **** **** +5527 Ocular_Adept_Exteneded_ELATION **** **** **** **** **** **** **** **** +5528 Ocular_Adept_Silent_ELATION **** **** **** **** **** **** **** **** +5529 Ocular_Adept_Still_ELATION **** **** **** **** **** **** **** **** +5530 Ocular_Adept_Endurance **** **** **** **** **** **** **** **** +5531 Ocular_Adept_Empowered_Endurance **** **** **** **** **** **** **** **** +5532 Ocular_Adept_Exteneded_Endurance **** **** **** **** **** **** **** **** +5533 Ocular_Adept_Maximized_Endurance **** **** **** **** **** **** **** **** +5534 Ocular_Adept_Silent_Endurance **** **** **** **** **** **** **** **** +5535 Ocular_Adept_Still_Endurance **** **** **** **** **** **** **** **** +5536 Ocular_Adept_Find_Traps **** **** **** **** **** **** **** **** +5537 Ocular_Adept_Exteneded_Find_Traps **** **** **** **** **** **** **** **** +5538 Ocular_Adept_Silent_Find_Traps **** **** **** **** **** **** **** **** +5539 Ocular_Adept_Still_Find_Traps **** **** **** **** **** **** **** **** +5540 Ocular_Adept_Foxs_Cunning **** **** **** **** **** **** **** **** +5541 Ocular_Adept_Empowered_Foxs_Cunning **** **** **** **** **** **** **** **** +5542 Ocular_Adept_Exteneded_Foxs_Cunning **** **** **** **** **** **** **** **** +5543 Ocular_Adept_Maximized_Foxs_Cunning **** **** **** **** **** **** **** **** +5544 Ocular_Adept_Silent_Foxs_Cunning **** **** **** **** **** **** **** **** +5545 Ocular_Adept_Still_Foxs_Cunning **** **** **** **** **** **** **** **** +5546 Ocular_Adept_Hold_Person **** **** **** **** **** **** **** **** +5547 Ocular_Adept_Exteneded_Hold_Person **** **** **** **** **** **** **** **** +5548 Ocular_Adept_Silent_Hold_Person **** **** **** **** **** **** **** **** +5549 Ocular_Adept_Still_Hold_Person **** **** **** **** **** **** **** **** +5550 Ocular_Adept_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5551 Ocular_Adept_Empowered_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5552 Ocular_Adept_Maximized_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5553 Ocular_Adept_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5554 Ocular_Adept_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +5555 Ocular_Adept_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5556 Ocular_Adept_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5557 Ocular_Adept_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +5558 Ocular_Adept_Lesser_Dispel **** **** **** **** **** **** **** **** +5559 Ocular_Adept_Silent_Lesser_Dispel **** **** **** **** **** **** **** **** +5560 Ocular_Adept_Still_Lesser_Dispel **** **** **** **** **** **** **** **** +5561 Ocular_Adept_Lesser_Restoration **** **** **** **** **** **** **** **** +5562 Ocular_Adept_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +5563 Ocular_Adept_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +5564 Ocular_Adept_Living_Undeath **** **** **** **** **** **** **** **** +5565 Ocular_Adept_Exteneded_Living_Undeath **** **** **** **** **** **** **** **** +5566 Ocular_Adept_Silent_Living_Undeath **** **** **** **** **** **** **** **** +5567 Ocular_Adept_Still_Living_Undeath **** **** **** **** **** **** **** **** +5568 Ocular_Adept_Necrotic_Cyst **** **** **** **** **** **** **** **** +5569 Ocular_Adept_Silent_Necrotic_Cyst **** **** **** **** **** **** **** **** +5570 Ocular_Adept_Still_Necrotic_Cyst **** **** **** **** **** **** **** **** +5571 Ocular_Adept_Negative_Energy_Ray **** **** **** **** **** **** **** **** +5572 Ocular_Adept_Empowered_Negative_Energy_Ray **** **** **** **** **** **** **** **** +5573 Ocular_Adept_Maximized_Negative_Energy_Ray **** **** **** **** **** **** **** **** +5574 Ocular_Adept_Silent_Negative_Energy_Ray **** **** **** **** **** **** **** **** +5575 Ocular_Adept_Still_Negative_Energy_Ray **** **** **** **** **** **** **** **** +5576 Ocular_Adept_Owls_Wisdom **** **** **** **** **** **** **** **** +5577 Ocular_Adept_Empowered_Owls_Wisdom **** **** **** **** **** **** **** **** +5578 Ocular_Adept_Exteneded_Owls_Wisdom **** **** **** **** **** **** **** **** +5579 Ocular_Adept_Maximized_Owls_Wisdom **** **** **** **** **** **** **** **** +5580 Ocular_Adept_Silent_Owls_Wisdom **** **** **** **** **** **** **** **** +5581 Ocular_Adept_Still_Owls_Wisdom **** **** **** **** **** **** **** **** +5582 Ocular_Adept_Remove_Paralysis **** **** **** **** **** **** **** **** +5583 Ocular_Adept_Silent_Remove_Paralysis **** **** **** **** **** **** **** **** +5584 Ocular_Adept_Still_Remove_Paralysis **** **** **** **** **** **** **** **** +5585 Ocular_Adept_Resist_Elements **** **** **** **** **** **** **** **** +5586 Ocular_Adept_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +5587 Ocular_Adept_Silent_Resist_Elements **** **** **** **** **** **** **** **** +5588 Ocular_Adept_Still_Resist_Elements **** **** **** **** **** **** **** **** +5589 Ocular_Adept_ShieldOther **** **** **** **** **** **** **** **** +5590 Ocular_Adept_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +5591 Ocular_Adept_Silent_ShieldOther **** **** **** **** **** **** **** **** +5592 Ocular_Adept_Still_ShieldOther **** **** **** **** **** **** **** **** +5593 Ocular_Adept_Silence **** **** **** **** **** **** **** **** +5594 Ocular_Adept_Exteneded_Silence **** **** **** **** **** **** **** **** +5595 Ocular_Adept_Silent_Silence **** **** **** **** **** **** **** **** +5596 Ocular_Adept_Still_Silence **** **** **** **** **** **** **** **** +5597 Ocular_Adept_Sound_Burst **** **** **** **** **** **** **** **** +5598 Ocular_Adept_Maximized_Sound_Burst **** **** **** **** **** **** **** **** +5599 Ocular_Adept_Silent_Sound_Burst **** **** **** **** **** **** **** **** +5600 Ocular_Adept_Still_Sound_Burst **** **** **** **** **** **** **** **** +5601 Ocular_Adept_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +5602 Ocular_Adept_Empowered_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +5603 Ocular_Adept_Maximized_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +5604 Ocular_Adept_Silent_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +5605 Ocular_Adept_Still_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +5606 Ocular_Adept_Stone_Bones **** **** **** **** **** **** **** **** +5607 Ocular_Adept_Exteneded_Stone_Bones **** **** **** **** **** **** **** **** +5608 Ocular_Adept_Silent_Stone_Bones **** **** **** **** **** **** **** **** +5609 Ocular_Adept_Still_Stone_Bones **** **** **** **** **** **** **** **** +5610 Ocular_Adept_Summon_Creature_II **** **** **** **** **** **** **** **** +5611 Ocular_Adept_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +5612 Ocular_Adept_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +5613 Ocular_Adept_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +5614 Ocular_Adept_SummonUndeadII **** **** **** **** **** **** **** **** +5615 Ocular_Adept_Exteneded_SummonUndeadII **** **** **** **** **** **** **** **** +5616 Ocular_Adept_Silent_SummonUndeadII **** **** **** **** **** **** **** **** +5617 Ocular_Adept_Still_SummonUndeadII **** **** **** **** **** **** **** **** +5618 Ocular_Adept_Ultravision **** **** **** **** **** **** **** **** +5619 Ocular_Adept_Exteneded_Ultravision **** **** **** **** **** **** **** **** +5620 Ocular_Adept_Silent_Ultravision **** **** **** **** **** **** **** **** +5621 Ocular_Adept_Still_Ultravision **** **** **** **** **** **** **** **** +5622 Ocular_Adept_UndetectableAlignment **** **** **** **** **** **** **** **** +5623 Ocular_Adept_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +5624 Ocular_Adept_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +5625 Ocular_Adept_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +5626 Ocular_Adept_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +5627 Ocular_Adept_Exteneded_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +5628 Ocular_Adept_Still_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +5629 Ocular_Adept_Animate_Dead **** **** **** **** **** **** **** **** +5630 Ocular_Adept_Exteneded_Animate_Dead **** **** **** **** **** **** **** **** +5631 Ocular_Adept_Silent_Animate_Dead **** **** **** **** **** **** **** **** +5632 Ocular_Adept_Still_Animate_Dead **** **** **** **** **** **** **** **** +5633 Ocular_Adept_Bestow_Curse **** **** **** **** **** **** **** **** +5634 Ocular_Adept_Silent_Bestow_Curse **** **** **** **** **** **** **** **** +5635 Ocular_Adept_Still_Bestow_Curse **** **** **** **** **** **** **** **** +5636 Ocular_Adept_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5637 Ocular_Adept_Exteneded_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5638 Ocular_Adept_Silent_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5639 Ocular_Adept_BONEBLADE **** **** **** **** **** **** **** **** +5640 Ocular_Adept_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5641 Ocular_Adept_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5642 Ocular_Adept_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5643 Ocular_Adept_Exteneded_BONEBLADE **** **** **** **** **** **** **** **** +5644 Ocular_Adept_Exteneded_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5645 Ocular_Adept_Exteneded_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5646 Ocular_Adept_Exteneded_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5647 Ocular_Adept_Silent_BONEBLADE **** **** **** **** **** **** **** **** +5648 Ocular_Adept_Silent_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5649 Ocular_Adept_Silent_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5650 Ocular_Adept_Silent_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5651 Ocular_Adept_Still_BONEBLADE **** **** **** **** **** **** **** **** +5652 Ocular_Adept_Still_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +5653 Ocular_Adept_Still_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +5654 Ocular_Adept_Still_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +5655 Ocular_Adept_Clarity **** **** **** **** **** **** **** **** +5656 Ocular_Adept_Exteneded_Clarity **** **** **** **** **** **** **** **** +5657 Ocular_Adept_Still_Clarity **** **** **** **** **** **** **** **** +5658 Ocular_Adept_Close_Wounds **** **** **** **** **** **** **** **** +5659 Ocular_Adept_Empowered_Close_Wounds **** **** **** **** **** **** **** **** +5660 Ocular_Adept_Silent_Close_Wounds **** **** **** **** **** **** **** **** +5661 Ocular_Adept_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +5662 Ocular_Adept_Silent_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +5663 Ocular_Adept_Still_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +5664 Ocular_Adept_Contagion **** **** **** **** **** **** **** **** +5665 Ocular_Adept_Silent_Contagion **** **** **** **** **** **** **** **** +5666 Ocular_Adept_Still_Contagion **** **** **** **** **** **** **** **** +5667 Ocular_Adept_Continual_Flame **** **** **** **** **** **** **** **** +5668 Ocular_Adept_Silent_Continual_Flame **** **** **** **** **** **** **** **** +5669 Ocular_Adept_Still_Continual_Flame **** **** **** **** **** **** **** **** +5670 Ocular_Adept_Crown_Might **** **** **** **** **** **** **** **** +5671 Ocular_Adept_Exteneded_Crown_Might **** **** **** **** **** **** **** **** +5672 Ocular_Adept_Silent_Crown_Might **** **** **** **** **** **** **** **** +5673 Ocular_Adept_Still_Crown_Might **** **** **** **** **** **** **** **** +5674 Ocular_Adept_Crown_Protection **** **** **** **** **** **** **** **** +5675 Ocular_Adept_Exteneded_Crown_Protection **** **** **** **** **** **** **** **** +5676 Ocular_Adept_Silent_Crown_Protection **** **** **** **** **** **** **** **** +5677 Ocular_Adept_Still_Crown_Protection **** **** **** **** **** **** **** **** +5678 Ocular_Adept_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5679 Ocular_Adept_Empowered_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5680 Ocular_Adept_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5681 Ocular_Adept_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +5682 Ocular_Adept_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +5683 Ocular_Adept_Exteneded_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +5684 Ocular_Adept_Silent_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +5685 Ocular_Adept_Still_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +5686 Ocular_Adept_Darkfire **** **** **** **** **** **** **** **** +5687 Ocular_Adept_Exteneded_Darkfire **** **** **** **** **** **** **** **** +5688 Ocular_Adept_Silent_Darkfire **** **** **** **** **** **** **** **** +5689 Ocular_Adept_Still_Darkfire **** **** **** **** **** **** **** **** +5690 Ocular_Adept_Daylight **** **** **** **** **** **** **** **** +5691 Ocular_Adept_Exteneded_Daylight **** **** **** **** **** **** **** **** +5692 Ocular_Adept_Silent_Daylight **** **** **** **** **** **** **** **** +5693 Ocular_Adept_Still_Daylight **** **** **** **** **** **** **** **** +5694 Ocular_Adept_DeeperDarkness **** **** **** **** **** **** **** **** +5695 Ocular_Adept_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +5696 Ocular_Adept_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +5697 Ocular_Adept_DEVILS_EYE **** **** **** **** **** **** **** **** +5698 Ocular_Adept_Silent_DEVILS_EYE **** **** **** **** **** **** **** **** +5699 Ocular_Adept_Still_DEVILS_EYE **** **** **** **** **** **** **** **** +5700 Ocular_Adept_Dispel_Magic **** **** **** **** **** **** **** **** +5701 Ocular_Adept_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +5702 Ocular_Adept_Still_Dispel_Magic **** **** **** **** **** **** **** **** +5703 Ocular_Adept_ENERGIZE_POTION **** **** **** **** **** **** **** **** +5704 Ocular_Adept_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +5705 Ocular_Adept_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +5706 Ocular_Adept_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +5707 Ocular_Adept_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +5708 Ocular_Adept_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +5709 Ocular_Adept_Silent_ENERGIZE_POTION **** **** **** **** **** **** **** **** +5710 Ocular_Adept_Silent_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +5711 Ocular_Adept_Silent_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +5712 Ocular_Adept_Silent_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +5713 Ocular_Adept_Silent_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +5714 Ocular_Adept_Silent_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +5715 Ocular_Adept_Still_ENERGIZE_POTION **** **** **** **** **** **** **** **** +5716 Ocular_Adept_Still_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +5717 Ocular_Adept_Still_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +5718 Ocular_Adept_Still_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +5719 Ocular_Adept_Still_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +5720 Ocular_Adept_Still_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +5721 Ocular_Adept_Energy_Aegis **** **** **** **** **** **** **** **** +5722 Ocular_Adept_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +5723 Ocular_Adept_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +5724 Ocular_Adept_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +5725 Ocular_Adept_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +5726 Ocular_Adept_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +5727 Ocular_Adept_Exteneded_Energy_Aegis **** **** **** **** **** **** **** **** +5728 Ocular_Adept_Exteneded_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +5729 Ocular_Adept_Exteneded_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +5730 Ocular_Adept_Exteneded_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +5731 Ocular_Adept_Exteneded_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +5732 Ocular_Adept_Exteneded_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +5733 Ocular_Adept_Silent_Energy_Aegis **** **** **** **** **** **** **** **** +5734 Ocular_Adept_Silent_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +5735 Ocular_Adept_Silent_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +5736 Ocular_Adept_Silent_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +5737 Ocular_Adept_Silent_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +5738 Ocular_Adept_Silent_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +5739 Ocular_Adept_Still_Energy_Aegis **** **** **** **** **** **** **** **** +5740 Ocular_Adept_Still_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +5741 Ocular_Adept_Still_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +5742 Ocular_Adept_Still_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +5743 Ocular_Adept_Still_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +5744 Ocular_Adept_Still_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +5745 Ocular_Adept_FLESH_RIPPER **** **** **** **** **** **** **** **** +5746 Ocular_Adept_Empowered_FLESH_RIPPER **** **** **** **** **** **** **** **** +5747 Ocular_Adept_Silent_FLESH_RIPPER **** **** **** **** **** **** **** **** +5748 Ocular_Adept_Still_FLESH_RIPPER **** **** **** **** **** **** **** **** +5749 Ocular_Adept_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +5750 Ocular_Adept_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +5751 Ocular_Adept_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +5752 Ocular_Adept_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +5753 Ocular_Adept_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +5754 Ocular_Adept_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +5755 Ocular_Adept_Empowered_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +5756 Ocular_Adept_Empowered_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +5757 Ocular_Adept_Empowered_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +5758 Ocular_Adept_Empowered_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +5759 Ocular_Adept_Empowered_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +5760 Ocular_Adept_Empowered_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +5761 Ocular_Adept_Exteneded_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +5762 Ocular_Adept_Exteneded_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +5763 Ocular_Adept_Exteneded_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +5764 Ocular_Adept_Exteneded_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +5765 Ocular_Adept_Exteneded_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +5766 Ocular_Adept_Exteneded_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +5767 Ocular_Adept_Silent_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +5768 Ocular_Adept_Silent_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +5769 Ocular_Adept_Silent_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +5770 Ocular_Adept_Silent_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +5771 Ocular_Adept_Silent_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +5772 Ocular_Adept_Silent_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +5773 Ocular_Adept_Still_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +5774 Ocular_Adept_Still_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +5775 Ocular_Adept_Still_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +5776 Ocular_Adept_Still_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +5777 Ocular_Adept_Still_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +5778 Ocular_Adept_Still_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +5779 Ocular_Adept_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5780 Ocular_Adept_Empowered_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5781 Ocular_Adept_Silent_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5782 Ocular_Adept_Still_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +5783 Ocular_Adept_Invisibility_Purge **** **** **** **** **** **** **** **** +5784 Ocular_Adept_Exteneded_Invisibility_Purge **** **** **** **** **** **** **** **** +5785 Ocular_Adept_Silent_Invisibility_Purge **** **** **** **** **** **** **** **** +5786 Ocular_Adept_Still_Invisibility_Purge **** **** **** **** **** **** **** **** +5787 Ocular_Adept_Legions_Conviction **** **** **** **** **** **** **** **** +5788 Ocular_Adept_Exteneded_Legions_Conviction **** **** **** **** **** **** **** **** +5789 Ocular_Adept_Silent_Legions_Conviction **** **** **** **** **** **** **** **** +5790 Ocular_Adept_Still_Legions_Conviction **** **** **** **** **** **** **** **** +5791 Ocular_Adept_LocateObject **** **** **** **** **** **** **** **** +5792 Ocular_Adept_Exteneded_LocateObject **** **** **** **** **** **** **** **** +5793 Ocular_Adept_Silent_LocateObject **** **** **** **** **** **** **** **** +5794 Ocular_Adept_Still_LocateObject **** **** **** **** **** **** **** **** +5795 Ocular_Adept_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +5796 Ocular_Adept_Exteneded_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +5797 Ocular_Adept_Silent_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +5798 Ocular_Adept_Still_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +5799 Ocular_Adept_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +5800 Ocular_Adept_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +5801 Ocular_Adept_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +5802 Ocular_Adept_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +5803 Ocular_Adept_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +5804 Ocular_Adept_Exteneded_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +5805 Ocular_Adept_Silent_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +5806 Ocular_Adept_Still_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +5807 Ocular_Adept_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +5808 Ocular_Adept_Exteneded_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +5809 Ocular_Adept_Silent_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +5810 Ocular_Adept_Still_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +5811 Ocular_Adept_Magic_Vestment **** **** **** **** **** **** **** **** +5812 Ocular_Adept_Exteneded_Magic_Vestment **** **** **** **** **** **** **** **** +5813 Ocular_Adept_Silent_Magic_Vestment **** **** **** **** **** **** **** **** +5814 Ocular_Adept_Still_Magic_Vestment **** **** **** **** **** **** **** **** +5815 Ocular_Adept_MASOCHISM **** **** **** **** **** **** **** **** +5816 Ocular_Adept_Exteneded_MASOCHISM **** **** **** **** **** **** **** **** +5817 Ocular_Adept_Mass_Aid **** **** **** **** **** **** **** **** +5818 Ocular_Adept_Empowered_Mass_Aid **** **** **** **** **** **** **** **** +5819 Ocular_Adept_Exteneded_Mass_Aid **** **** **** **** **** **** **** **** +5820 Ocular_Adept_Silent_Mass_Aid **** **** **** **** **** **** **** **** +5821 Ocular_Adept_Still_Mass_Aid **** **** **** **** **** **** **** **** +5822 Ocular_Adept_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +5823 Ocular_Adept_Exteneded_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +5824 Ocular_Adept_Silent_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +5825 Ocular_Adept_Still_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +5826 Ocular_Adept_Necrotic_Bloat **** **** **** **** **** **** **** **** +5827 Ocular_Adept_Empowered_Necrotic_Bloat **** **** **** **** **** **** **** **** +5828 Ocular_Adept_Negative_Energy_Protection **** **** **** **** **** **** **** **** +5829 Ocular_Adept_Exteneded_Negative_Energy_Protection **** **** **** **** **** **** **** **** +5830 Ocular_Adept_Silent_Negative_Energy_Protection **** **** **** **** **** **** **** **** +5831 Ocular_Adept_Still_Negative_Energy_Protection **** **** **** **** **** **** **** **** +5832 Ocular_Adept_ObscureObject **** **** **** **** **** **** **** **** +5833 Ocular_Adept_Exteneded_ObscureObject **** **** **** **** **** **** **** **** +5834 Ocular_Adept_Silent_ObscureObject **** **** **** **** **** **** **** **** +5835 Ocular_Adept_Still_ObscureObject **** **** **** **** **** **** **** **** +5836 Ocular_Adept_Prayer **** **** **** **** **** **** **** **** +5837 Ocular_Adept_Exteneded_Prayer **** **** **** **** **** **** **** **** +5838 Ocular_Adept_Silent_Prayer **** **** **** **** **** **** **** **** +5839 Ocular_Adept_Still_Prayer **** **** **** **** **** **** **** **** +5840 Ocular_Adept_Protection_from_Elements **** **** **** **** **** **** **** **** +5841 Ocular_Adept_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +5842 Ocular_Adept_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +5843 Ocular_Adept_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +5844 Ocular_Adept_RED_FESTER **** **** **** **** **** **** **** **** +5845 Ocular_Adept_Silent_RED_FESTER **** **** **** **** **** **** **** **** +5846 Ocular_Adept_Still_RED_FESTER **** **** **** **** **** **** **** **** +5847 Ocular_Adept_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5848 Ocular_Adept_Silent_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5849 Ocular_Adept_Still_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +5850 Ocular_Adept_Remove_Curse **** **** **** **** **** **** **** **** +5851 Ocular_Adept_Silent_Remove_Curse **** **** **** **** **** **** **** **** +5852 Ocular_Adept_Still_Remove_Curse **** **** **** **** **** **** **** **** +5853 Ocular_Adept_Remove_Disease **** **** **** **** **** **** **** **** +5854 Ocular_Adept_Silent_Remove_Disease **** **** **** **** **** **** **** **** +5855 Ocular_Adept_Still_Remove_Disease **** **** **** **** **** **** **** **** +5856 Ocular_Adept_RingOfBlades **** **** **** **** **** **** **** **** +5857 Ocular_Adept_Exteneded_RingOfBlades **** **** **** **** **** **** **** **** +5858 Ocular_Adept_Silent_RingOfBlades **** **** **** **** **** **** **** **** +5859 Ocular_Adept_Still_RingOfBlades **** **** **** **** **** **** **** **** +5860 Ocular_Adept_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5861 Ocular_Adept_Empowered_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5862 Ocular_Adept_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5863 Ocular_Adept_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +5864 Ocular_Adept_Searing_Light **** **** **** **** **** **** **** **** +5865 Ocular_Adept_Empowered_Searing_Light **** **** **** **** **** **** **** **** +5866 Ocular_Adept_Silent_Searing_Light **** **** **** **** **** **** **** **** +5867 Ocular_Adept_Still_Searing_Light **** **** **** **** **** **** **** **** +5868 Ocular_Adept_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5869 Ocular_Adept_Empowered_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5870 Ocular_Adept_Exteneded_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5871 Ocular_Adept_Silent_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5872 Ocular_Adept_Still_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +5873 Ocular_Adept_SHRIVELING **** **** **** **** **** **** **** **** +5874 Ocular_Adept_Empowered_SHRIVELING **** **** **** **** **** **** **** **** +5875 Ocular_Adept_Silent_SHRIVELING **** **** **** **** **** **** **** **** +5876 Ocular_Adept_Still_SHRIVELING **** **** **** **** **** **** **** **** +5877 Ocular_Adept_Slashing_Darkness **** **** **** **** **** **** **** **** +5878 Ocular_Adept_Empowered_Slashing_Darkness **** **** **** **** **** **** **** **** +5879 Ocular_Adept_Silent_Slashing_Darkness **** **** **** **** **** **** **** **** +5880 Ocular_Adept_Still_Slashing_Darkness **** **** **** **** **** **** **** **** +5881 Ocular_Adept_Summon_Creature_III **** **** **** **** **** **** **** **** +5882 Ocular_Adept_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +5883 Ocular_Adept_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +5884 Ocular_Adept_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +5885 Ocular_Adept_SummonUndeadIII **** **** **** **** **** **** **** **** +5886 Ocular_Adept_Exteneded_SummonUndeadIII **** **** **** **** **** **** **** **** +5887 Ocular_Adept_Silent_SummonUndeadIII **** **** **** **** **** **** **** **** +5888 Ocular_Adept_Still_SummonUndeadIII **** **** **** **** **** **** **** **** +5889 Ocular_Adept_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5890 Ocular_Adept_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5891 Ocular_Adept_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +5892 Ocular_Adept_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +5893 Ocular_Adept_Empowered_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +5894 Ocular_Adept_Silent_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +5895 Ocular_Adept_Still_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +5896 Ocular_Adept_Vigor **** **** **** **** **** **** **** **** +5897 Ocular_Adept_Exteneded_Vigor **** **** **** **** **** **** **** **** +5898 Ocular_Adept_Silent_Vigor **** **** **** **** **** **** **** **** +5899 Ocular_Adept_Still_Vigor **** **** **** **** **** **** **** **** +5900 Ocular_Adept_WaterBreathing **** **** **** **** **** **** **** **** +5901 Ocular_Adept_Exteneded_WaterBreathing **** **** **** **** **** **** **** **** +5902 Ocular_Adept_Silent_WaterBreathing **** **** **** **** **** **** **** **** +5903 Ocular_Adept_Still_WaterBreathing **** **** **** **** **** **** **** **** +5904 Ocular_Adept_WRACK **** **** **** **** **** **** **** **** +5905 Ocular_Adept_Exteneded_WRACK **** **** **** **** **** **** **** **** +5906 Ocular_Adept_Silent_WRACK **** **** **** **** **** **** **** **** +5907 Ocular_Adept_Still_WRACK **** **** **** **** **** **** **** **** +5908 Ocular_Adept_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +5909 Ocular_Adept_Exteneded_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +5910 Ocular_Adept_Silent_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +5911 Ocular_Adept_Still_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +5912 Ocular_Adept_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5913 Ocular_Adept_Exteneded_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5914 Ocular_Adept_Silent_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5915 Ocular_Adept_Still_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +5916 Ocular_Adept_BloodOfTheMartyr **** **** **** **** **** **** **** **** +5917 Ocular_Adept_Silent_BloodOfTheMartyr **** **** **** **** **** **** **** **** +5918 Ocular_Adept_Still_BloodOfTheMartyr **** **** **** **** **** **** **** **** +5919 Ocular_Adept_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +5920 Ocular_Adept_Exteneded_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +5921 Ocular_Adept_Silent_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +5922 Ocular_Adept_Still_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +5923 Ocular_Adept_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +5924 Ocular_Adept_Silent_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +5925 Ocular_Adept_Still_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +5926 Ocular_Adept_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +5927 Ocular_Adept_Exteneded_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +5928 Ocular_Adept_Silent_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +5929 Ocular_Adept_Death_Ward **** **** **** **** **** **** **** **** +5930 Ocular_Adept_Exteneded_Death_Ward **** **** **** **** **** **** **** **** +5931 Ocular_Adept_Silent_Death_Ward **** **** **** **** **** **** **** **** +5932 Ocular_Adept_Still_Death_Ward **** **** **** **** **** **** **** **** +5933 Ocular_Adept_Dimensional_Anchor **** **** **** **** **** **** **** **** +5934 Ocular_Adept_Exteneded_Dimensional_Anchor **** **** **** **** **** **** **** **** +5935 Ocular_Adept_Silent_Dimensional_Anchor **** **** **** **** **** **** **** **** +5936 Ocular_Adept_Still_Dimensional_Anchor **** **** **** **** **** **** **** **** +5937 Ocular_Adept_Dismissal **** **** **** **** **** **** **** **** +5938 Ocular_Adept_Silent_Dismissal **** **** **** **** **** **** **** **** +5939 Ocular_Adept_Still_Dismissal **** **** **** **** **** **** **** **** +5940 Ocular_Adept_Divine_Power **** **** **** **** **** **** **** **** +5941 Ocular_Adept_Exteneded_Divine_Power **** **** **** **** **** **** **** **** +5942 Ocular_Adept_Silent_Divine_Power **** **** **** **** **** **** **** **** +5943 Ocular_Adept_Still_Divine_Power **** **** **** **** **** **** **** **** +5944 Ocular_Adept_Freedom_of_Movement **** **** **** **** **** **** **** **** +5945 Ocular_Adept_Exteneded_Freedom_of_Movement **** **** **** **** **** **** **** **** +5946 Ocular_Adept_Silent_Freedom_of_Movement **** **** **** **** **** **** **** **** +5947 Ocular_Adept_Still_Freedom_of_Movement **** **** **** **** **** **** **** **** +5948 Ocular_Adept_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +5949 Ocular_Adept_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +5950 Ocular_Adept_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +5951 Ocular_Adept_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +5952 Ocular_Adept_Greater_Resistance **** **** **** **** **** **** **** **** +5953 Ocular_Adept_Exteneded_Greater_Resistance **** **** **** **** **** **** **** **** +5954 Ocular_Adept_Silent_Greater_Resistance **** **** **** **** **** **** **** **** +5955 Ocular_Adept_Still_Greater_Resistance **** **** **** **** **** **** **** **** +5956 Ocular_Adept_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +5957 Ocular_Adept_Silent_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +5958 Ocular_Adept_Still_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +5959 Ocular_Adept_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +5960 Ocular_Adept_Silent_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +5961 Ocular_Adept_Still_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +5962 Ocular_Adept_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +5963 Ocular_Adept_Exteneded_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +5964 Ocular_Adept_Silent_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +5965 Ocular_Adept_Still_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +5966 Ocular_Adept_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +5967 Ocular_Adept_Exteneded_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +5968 Ocular_Adept_Silent_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +5969 Ocular_Adept_Still_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +5970 Ocular_Adept_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +5971 Ocular_Adept_Exteneded_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +5972 Ocular_Adept_Silent_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +5973 Ocular_Adept_Still_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +5974 Ocular_Adept_Mass_Ultravision **** **** **** **** **** **** **** **** +5975 Ocular_Adept_Exteneded_Mass_Ultravision **** **** **** **** **** **** **** **** +5976 Ocular_Adept_Silent_Mass_Ultravision **** **** **** **** **** **** **** **** +5977 Ocular_Adept_Still_Mass_Ultravision **** **** **** **** **** **** **** **** +5978 Ocular_Adept_Necrotic_Domination **** **** **** **** **** **** **** **** +5979 Ocular_Adept_Exteneded_Necrotic_Domination **** **** **** **** **** **** **** **** +5980 Ocular_Adept_Silent_Necrotic_Domination **** **** **** **** **** **** **** **** +5981 Ocular_Adept_Still_Necrotic_Domination **** **** **** **** **** **** **** **** +5982 Ocular_Adept_Neutralize_Poison **** **** **** **** **** **** **** **** +5983 Ocular_Adept_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +5984 Ocular_Adept_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +5985 Ocular_Adept_Panacea **** **** **** **** **** **** **** **** +5986 Ocular_Adept_Silent_Panacea **** **** **** **** **** **** **** **** +5987 Ocular_Adept_Still_Panacea **** **** **** **** **** **** **** **** +5988 Ocular_Adept_Poison **** **** **** **** **** **** **** **** +5989 Ocular_Adept_Silent_Poison **** **** **** **** **** **** **** **** +5990 Ocular_Adept_Still_Poison **** **** **** **** **** **** **** **** +5991 Ocular_Adept_Recitation **** **** **** **** **** **** **** **** +5992 Ocular_Adept_Exteneded_Recitation **** **** **** **** **** **** **** **** +5993 Ocular_Adept_Silent_Recitation **** **** **** **** **** **** **** **** +5994 Ocular_Adept_Still_Recitation **** **** **** **** **** **** **** **** +5995 Ocular_Adept_RepelVermin **** **** **** **** **** **** **** **** +5996 Ocular_Adept_Exteneded_RepelVermin **** **** **** **** **** **** **** **** +5997 Ocular_Adept_Silent_RepelVermin **** **** **** **** **** **** **** **** +5998 Ocular_Adept_Still_RepelVermin **** **** **** **** **** **** **** **** +5999 Ocular_Adept_Restoration **** **** **** **** **** **** **** **** +6000 Ocular_Adept_Silent_Restoration **** **** **** **** **** **** **** **** +6001 Ocular_Adept_Still_Restoration **** **** **** **** **** **** **** **** +6002 Ocular_Adept_STOP_HEART **** **** **** **** **** **** **** **** +6003 Ocular_Adept_Still_STOP_HEART **** **** **** **** **** **** **** **** +6004 Ocular_Adept_Summon_Creature_IV **** **** **** **** **** **** **** **** +6005 Ocular_Adept_Exteneded_Summon_Creature_IV **** **** **** **** **** **** **** **** +6006 Ocular_Adept_Silent_Summon_Creature_IV **** **** **** **** **** **** **** **** +6007 Ocular_Adept_Still_Summon_Creature_IV **** **** **** **** **** **** **** **** +6008 Ocular_Adept_SummonUndeadIV **** **** **** **** **** **** **** **** +6009 Ocular_Adept_Exteneded_SummonUndeadIV **** **** **** **** **** **** **** **** +6010 Ocular_Adept_Silent_SummonUndeadIV **** **** **** **** **** **** **** **** +6011 Ocular_Adept_Still_SummonUndeadIV **** **** **** **** **** **** **** **** +6012 Ocular_Adept_SwordOfConscience **** **** **** **** **** **** **** **** +6013 Ocular_Adept_Silent_SwordOfConscience **** **** **** **** **** **** **** **** +6014 Ocular_Adept_Battletide **** **** **** **** **** **** **** **** +6015 Ocular_Adept_BreakEnchantment **** **** **** **** **** **** **** **** +6016 Ocular_Adept_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +6017 Ocular_Adept_Circle_of_Doom **** **** **** **** **** **** **** **** +6018 Ocular_Adept_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +6019 Ocular_Adept_CONVERT_WAND **** **** **** **** **** **** **** **** +6020 Ocular_Adept_DANCING_WEB **** **** **** **** **** **** **** **** +6021 Ocular_Adept_FireInTheBlood **** **** **** **** **** **** **** **** +6022 Ocular_Adept_Flame_Strike **** **** **** **** **** **** **** **** +6023 Ocular_Adept_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6024 Ocular_Adept_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +6025 Ocular_Adept_GreaterCommand_Approach **** **** **** **** **** **** **** **** +6026 Ocular_Adept_GreaterCommand_Drop **** **** **** **** **** **** **** **** +6027 Ocular_Adept_GreaterCommand_Fall **** **** **** **** **** **** **** **** +6028 Ocular_Adept_GreaterCommand_Flee **** **** **** **** **** **** **** **** +6029 Ocular_Adept_GreaterCommand_Halt **** **** **** **** **** **** **** **** +6030 Ocular_Adept_Healing_Circle **** **** **** **** **** **** **** **** +6031 Ocular_Adept_HEARTCLUTCH **** **** **** **** **** **** **** **** +6032 Ocular_Adept_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +6033 Ocular_Adept_Mass_Contagion **** **** **** **** **** **** **** **** +6034 Ocular_Adept_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6035 Ocular_Adept_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +6036 Ocular_Adept_MORALITY_UNDONE **** **** **** **** **** **** **** **** +6037 Ocular_Adept_Necrotic_Burst **** **** **** **** **** **** **** **** +6038 Ocular_Adept_POWER_LEECH **** **** **** **** **** **** **** **** +6039 Ocular_Adept_Raise_Dead **** **** **** **** **** **** **** **** +6040 Ocular_Adept_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +6041 Ocular_Adept_Revivify **** **** **** **** **** **** **** **** +6042 Ocular_Adept_Righteous_Might **** **** **** **** **** **** **** **** +6043 Ocular_Adept_Scrying **** **** **** **** **** **** **** **** +6044 Ocular_Adept_Slay_Living **** **** **** **** **** **** **** **** +6045 Ocular_Adept_Soulscour **** **** **** **** **** **** **** **** +6046 Ocular_Adept_Spell_Resistance **** **** **** **** **** **** **** **** +6047 Ocular_Adept_Summon_Creature_V **** **** **** **** **** **** **** **** +6048 Ocular_Adept_SummonUndeadV **** **** **** **** **** **** **** **** +6049 Ocular_Adept_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +6050 Ocular_Adept_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +6051 Ocular_Adept_True_Seeing **** **** **** **** **** **** **** **** +6052 Hexblade_AugmentFamiliar **** **** **** **** **** **** **** **** +6053 Hexblade_Light **** **** **** **** **** **** **** **** +6054 Hexblade_Cause_Fear **** **** **** **** **** **** **** **** +6055 Hexblade_Charm_Person **** **** **** **** **** **** **** **** +6056 Hexblade_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +6057 Hexblade_Disguise_Self_Learn **** **** **** **** **** **** **** **** +6058 Hexblade_Disguise_Self_Options **** **** **** **** **** **** **** **** +6059 Hexblade_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +6060 Hexblade_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +6061 Hexblade_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +6062 Hexblade_Entropic_Shield **** **** **** **** **** **** **** **** +6063 Hexblade_Expeditious_Retreat **** **** **** **** **** **** **** **** +6064 Hexblade_Identify **** **** **** **** **** **** **** **** +6065 Hexblade_Magic_Weapon **** **** **** **** **** **** **** **** +6066 Hexblade_Protection_from_Chaos **** **** **** **** **** **** **** **** +6067 Hexblade_Protection_from_Evil **** **** **** **** **** **** **** **** +6068 Hexblade_Protection_from_Good **** **** **** **** **** **** **** **** +6069 Hexblade_Protection_from_Law **** **** **** **** **** **** **** **** +6070 Hexblade_Read_Magic **** **** **** **** **** **** **** **** +6071 Hexblade_Sleep **** **** **** **** **** **** **** **** +6072 Hexblade_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6073 Hexblade_UndetectableAlignment **** **** **** **** **** **** **** **** +6074 Hexblade_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +6075 Hexblade_Alter_Self_Learn **** **** **** **** **** **** **** **** +6076 Hexblade_Alter_Self_Options **** **** **** **** **** **** **** **** +6077 Hexblade_Alter_Self_QS1 **** **** **** **** **** **** **** **** +6078 Hexblade_Alter_Self_QS2 **** **** **** **** **** **** **** **** +6079 Hexblade_Alter_Self_QS3 **** **** **** **** **** **** **** **** +6080 Hexblade_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6081 Hexblade_Blood_Frenzy **** **** **** **** **** **** **** **** +6082 Hexblade_Bulls_Strength **** **** **** **** **** **** **** **** +6083 Hexblade_Darkness **** **** **** **** **** **** **** **** +6084 Hexblade_Eagle_Splendor **** **** **** **** **** **** **** **** +6085 Hexblade_FalseLife **** **** **** **** **** **** **** **** +6086 Hexblade_Glitterdust **** **** **** **** **** **** **** **** +6087 Hexblade_Invisibility **** **** **** **** **** **** **** **** +6088 Hexblade_MirrorImage **** **** **** **** **** **** **** **** +6089 Hexblade_ProtectionArrows **** **** **** **** **** **** **** **** +6090 Hexblade_Pyrotechnics **** **** **** **** **** **** **** **** +6091 Hexblade_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +6092 Hexblade_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +6093 Hexblade_Resist_Elements **** **** **** **** **** **** **** **** +6094 Hexblade_See_Invisibility **** **** **** **** **** **** **** **** +6095 Hexblade_TouchIdiocy **** **** **** **** **** **** **** **** +6096 Hexblade_Charm_Monster **** **** **** **** **** **** **** **** +6097 Hexblade_Confusion **** **** **** **** **** **** **** **** +6098 Hexblade_DeepSlumber **** **** **** **** **** **** **** **** +6099 Hexblade_Dispel_Magic **** **** **** **** **** **** **** **** +6100 Hexblade_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +6101 Hexblade_HoundDoom **** **** **** **** **** **** **** **** +6102 Hexblade_Invisibility_Sphere **** **** **** **** **** **** **** **** +6103 Hexblade_NONDETECTION **** **** **** **** **** **** **** **** +6104 Hexblade_Poison **** **** **** **** **** **** **** **** +6105 Hexblade_Protection_from_Elements **** **** **** **** **** **** **** **** +6106 Hexblade_RepelVermin **** **** **** **** **** **** **** **** +6107 Hexblade_Slow **** **** **** **** **** **** **** **** +6108 Hexblade_Stinking_Cloud **** **** **** **** **** **** **** **** +6109 Hexblade_Vampiric_Touch **** **** **** **** **** **** **** **** +6110 Hexblade_BalefulPolymorph **** **** **** **** **** **** **** **** +6111 Hexblade_BreakEnchantment **** **** **** **** **** **** **** **** +6112 Hexblade_CursedBlade **** **** **** **** **** **** **** **** +6113 Hexblade_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +6114 Hexblade_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +6115 Hexblade_DimensionDoor_Party **** **** **** **** **** **** **** **** +6116 Hexblade_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +6117 Hexblade_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +6118 Hexblade_Dominate_Person **** **** **** **** **** **** **** **** +6119 Hexblade_Enervation **** **** **** **** **** **** **** **** +6120 Hexblade_Improved_Invisibility **** **** **** **** **** **** **** **** +6121 Hexblade_Phantasmal_Killer **** **** **** **** **** **** **** **** +6122 Hexblade_Polymorph_Self **** **** **** **** **** **** **** **** +6123 Hexblade_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +6124 Hexblade_Polymorph_TROLL **** **** **** **** **** **** **** **** +6125 Hexblade_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +6126 Hexblade_Polymorph_PIXIE **** **** **** **** **** **** **** **** +6127 Hexblade_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +6128 Hexblade_Fear **** **** **** **** **** **** **** **** +6129 Hexblade_Scrying **** **** **** **** **** **** **** **** +6130 Hexblade_SolidFog **** **** **** **** **** **** **** **** +6131 Duskblade_Acid_Splash **** **** **** **** **** **** **** **** +6132 Duskblade_DisruptUndead **** **** **** **** **** **** **** **** +6133 Duskblade_Ray_of_Frost **** **** **** **** **** **** **** **** +6134 Duskblade_Blade_of_Blood **** **** **** **** **** **** **** **** +6135 Duskblade_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +6136 Duskblade_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +6137 Duskblade_Kelgores_Fire_Bolt **** **** **** **** **** **** **** **** +6138 Duskblade_Lesser_Deflect **** **** **** **** **** **** **** **** +6139 Duskblade_Rouse **** **** **** **** **** **** **** **** +6140 Duskblade_Bigbys_Tripping_Hand **** **** **** **** **** **** **** **** +6141 Duskblade_Burning_Hands **** **** **** **** **** **** **** **** +6142 Duskblade_Chill_Touch **** **** **** **** **** **** **** **** +6143 Duskblade_Color_Spray **** **** **** **** **** **** **** **** +6144 Duskblade_Expeditious_Retreat **** **** **** **** **** **** **** **** +6145 Duskblade_Spell_Jump **** **** **** **** **** **** **** **** +6146 Duskblade_Magic_Weapon **** **** **** **** **** **** **** **** +6147 Duskblade_Obscuring_Mist **** **** **** **** **** **** **** **** +6148 Duskblade_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +6149 Duskblade_Cause_Fear **** **** **** **** **** **** **** **** +6150 Duskblade_True_Strike **** **** **** **** **** **** **** **** +6151 Duskblade_Resist_Elements **** **** **** **** **** **** **** **** +6152 Duskblade_ShockingGrasp **** **** **** **** **** **** **** **** +6153 Duskblade_Animalistic_Power **** **** **** **** **** **** **** **** +6154 Duskblade_Deflect **** **** **** **** **** **** **** **** +6155 Duskblade_Dimension_Hop **** **** **** **** **** **** **** **** +6156 Duskblade_Seeking_Ray **** **** **** **** **** **** **** **** +6157 Duskblade_Sure_Strike **** **** **** **** **** **** **** **** +6158 Duskblade_Bigbys_Striking_Fist **** **** **** **** **** **** **** **** +6159 Duskblade_Bulls_Strength **** **** **** **** **** **** **** **** +6160 Duskblade_Cats_Grace **** **** **** **** **** **** **** **** +6161 Duskblade_Endurance **** **** **** **** **** **** **** **** +6162 Duskblade_Ghoul_Touch **** **** **** **** **** **** **** **** +6163 Duskblade_Invisibility **** **** **** **** **** **** **** **** +6164 Duskblade_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +6165 Duskblade_TouchIdiocy **** **** **** **** **** **** **** **** +6166 Duskblade_See_Invisibility **** **** **** **** **** **** **** **** +6167 Duskblade_ScorchingRay **** **** **** **** **** **** **** **** +6168 Duskblade_Crown_Might **** **** **** **** **** **** **** **** +6169 Duskblade_Crown_Protection **** **** **** **** **** **** **** **** +6170 Duskblade_Dispelling_Touch **** **** **** **** **** **** **** **** +6171 Duskblade_Doom_Scarabs **** **** **** **** **** **** **** **** +6172 Duskblade_Energy_Aegis **** **** **** **** **** **** **** **** +6173 Duskblade_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +6174 Duskblade_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +6175 Duskblade_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +6176 Duskblade_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +6177 Duskblade_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +6178 Duskblade_Energy_Surge **** **** **** **** **** **** **** **** +6179 Duskblade_Energy_Surge_Acid **** **** **** **** **** **** **** **** +6180 Duskblade_Energy_Surge_Cold **** **** **** **** **** **** **** **** +6181 Duskblade_Energy_Surge_Elec **** **** **** **** **** **** **** **** +6182 Duskblade_Energy_Surge_Fire **** **** **** **** **** **** **** **** +6183 Duskblade_Energy_Surge_Sonic **** **** **** **** **** **** **** **** +6184 Duskblade_Halt **** **** **** **** **** **** **** **** +6185 Duskblade_Regroup **** **** **** **** **** **** **** **** +6186 Duskblade_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +6187 Duskblade_Keen_Edge **** **** **** **** **** **** **** **** +6188 Duskblade_Protection_from_Elements **** **** **** **** **** **** **** **** +6189 Duskblade_Vampiric_Touch **** **** **** **** **** **** **** **** +6190 Duskblade_RayofExhaustion **** **** **** **** **** **** **** **** +6191 Duskblade_Channeled_Pyroburst **** **** **** **** **** **** **** **** +6192 Duskblade_Channeled_Pyroburst_Swift **** **** **** **** **** **** **** **** +6193 Duskblade_Channeled_Pyroburst_Standard **** **** **** **** **** **** **** **** +6194 Duskblade_Channeled_Pyroburst_Full **** **** **** **** **** **** **** **** +6195 Duskblade_Channeled_Pyroburst_Two **** **** **** **** **** **** **** **** +6196 Duskblade_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +6197 Duskblade_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +6198 Duskblade_DimensionDoor_Party **** **** **** **** **** **** **** **** +6199 Duskblade_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +6200 Duskblade_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +6201 Duskblade_Elemental_Shield **** **** **** **** **** **** **** **** +6202 Duskblade_Enervation **** **** **** **** **** **** **** **** +6203 Duskblade_Phantasmal_Killer **** **** **** **** **** **** **** **** +6204 Duskblade_Shout **** **** **** **** **** **** **** **** +6205 Duskblade_Bigbys_Interposing_Hand **** **** **** **** **** **** **** **** +6206 Duskblade_Dispel_Magic **** **** **** **** **** **** **** **** +6207 Duskblade_Slashing_Dispel **** **** **** **** **** **** **** **** +6208 Duskblade_Sonic_Shield **** **** **** **** **** **** **** **** +6209 Duskblade_Hold_Monster **** **** **** **** **** **** **** **** +6210 Duskblade_Chain_Lightning **** **** **** **** **** **** **** **** +6211 Duskblade_Disintegrate **** **** **** **** **** **** **** **** +6212 Duskblade_Bigbys_Clenched_Fist **** **** **** **** **** **** **** **** +6213 Duskblade_PolarRay **** **** **** **** **** **** **** **** +6214 Duskblade_WavesofFatigue **** **** **** **** **** **** **** **** +6215 Healer_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +6216 Healer_Quickened_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +6217 Healer_Silent_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +6218 Healer_Still_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +6219 Healer_Light **** **** **** **** **** **** **** **** +6220 Healer_Exteneded_Light **** **** **** **** **** **** **** **** +6221 Healer_Quickened_Light **** **** **** **** **** **** **** **** +6222 Healer_Silent_Light **** **** **** **** **** **** **** **** +6223 Healer_Read_Magic **** **** **** **** **** **** **** **** +6224 Healer_Quickened_Read_Magic **** **** **** **** **** **** **** **** +6225 Healer_Silent_Read_Magic **** **** **** **** **** **** **** **** +6226 Healer_Still_Read_Magic **** **** **** **** **** **** **** **** +6227 Healer_Bless_Water **** **** **** **** **** **** **** **** +6228 Healer_Quickened_Bless_Water **** **** **** **** **** **** **** **** +6229 Healer_Silent_Bless_Water **** **** **** **** **** **** **** **** +6230 Healer_Still_Bless_Water **** **** **** **** **** **** **** **** +6231 Healer_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6232 Healer_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6233 Healer_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6234 Healer_Quickened_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6235 Healer_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6236 Healer_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6237 Healer_Lesser_Vigor **** **** **** **** **** **** **** **** +6238 Healer_Exteneded_Lesser_Vigor **** **** **** **** **** **** **** **** +6239 Healer_Quickened_Lesser_Vigor **** **** **** **** **** **** **** **** +6240 Healer_Silent_Lesser_Vigor **** **** **** **** **** **** **** **** +6241 Healer_Still_Lesser_Vigor **** **** **** **** **** **** **** **** +6242 Healer_Protection_from_Evil **** **** **** **** **** **** **** **** +6243 Healer_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +6244 Healer_Quickened_Protection_from_Evil **** **** **** **** **** **** **** **** +6245 Healer_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +6246 Healer_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +6247 Healer_Remove_Fear **** **** **** **** **** **** **** **** +6248 Healer_Exteneded_Remove_Fear **** **** **** **** **** **** **** **** +6249 Healer_Quickened_Remove_Fear **** **** **** **** **** **** **** **** +6250 Healer_Silent_Remove_Fear **** **** **** **** **** **** **** **** +6251 Healer_Still_Remove_Fear **** **** **** **** **** **** **** **** +6252 Healer_Remove_Paralysis **** **** **** **** **** **** **** **** +6253 Healer_Quickened_Remove_Paralysis **** **** **** **** **** **** **** **** +6254 Healer_Silent_Remove_Paralysis **** **** **** **** **** **** **** **** +6255 Healer_Still_Remove_Paralysis **** **** **** **** **** **** **** **** +6256 Healer_Sanctuary **** **** **** **** **** **** **** **** +6257 Healer_Exteneded_Sanctuary **** **** **** **** **** **** **** **** +6258 Healer_Quickened_Sanctuary **** **** **** **** **** **** **** **** +6259 Healer_Silent_Sanctuary **** **** **** **** **** **** **** **** +6260 Healer_Still_Sanctuary **** **** **** **** **** **** **** **** +6261 Healer_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6262 Healer_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6263 Healer_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6264 Healer_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +6265 Healer_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +6266 Healer_Quickened_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +6267 Healer_Calm_Emotions **** **** **** **** **** **** **** **** +6268 Healer_Exteneded_Calm_Emotions **** **** **** **** **** **** **** **** +6269 Healer_Quickened_Calm_Emotions **** **** **** **** **** **** **** **** +6270 Healer_Silent_Calm_Emotions **** **** **** **** **** **** **** **** +6271 Healer_Still_Calm_Emotions **** **** **** **** **** **** **** **** +6272 Healer_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6273 Healer_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6274 Healer_Maximized_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6275 Healer_Quickened_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6276 Healer_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6277 Healer_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6278 Healer_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6279 Healer_Quickened_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6280 Healer_Silent_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6281 Healer_Still_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6282 Healer_Remove_Disease **** **** **** **** **** **** **** **** +6283 Healer_Quickened_Remove_Disease **** **** **** **** **** **** **** **** +6284 Healer_Silent_Remove_Disease **** **** **** **** **** **** **** **** +6285 Healer_Still_Remove_Disease **** **** **** **** **** **** **** **** +6286 Healer_Lesser_Restoration **** **** **** **** **** **** **** **** +6287 Healer_Quickened_Lesser_Restoration **** **** **** **** **** **** **** **** +6288 Healer_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +6289 Healer_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +6290 Healer_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6291 Healer_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6292 Healer_Quickened_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6293 Healer_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6294 Healer_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6295 Healer_Maximized_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6296 Healer_Quickened_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6297 Healer_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6298 Healer_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6299 Healer_Close_Wounds **** **** **** **** **** **** **** **** +6300 Healer_Empowered_Close_Wounds **** **** **** **** **** **** **** **** +6301 Healer_Maximized_Close_Wounds **** **** **** **** **** **** **** **** +6302 Healer_Quickened_Close_Wounds **** **** **** **** **** **** **** **** +6303 Healer_Silent_Close_Wounds **** **** **** **** **** **** **** **** +6304 Healer_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6305 Healer_Empowered_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6306 Healer_Maximized_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6307 Healer_Quickened_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6308 Healer_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6309 Healer_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6310 Healer_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +6311 Healer_Exteneded_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +6312 Healer_Quickened_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +6313 Healer_Silent_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +6314 Healer_Still_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +6315 Healer_Neutralize_Poison **** **** **** **** **** **** **** **** +6316 Healer_Quickened_Neutralize_Poison **** **** **** **** **** **** **** **** +6317 Healer_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +6318 Healer_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +6319 Healer_Remove_Curse **** **** **** **** **** **** **** **** +6320 Healer_Quickened_Remove_Curse **** **** **** **** **** **** **** **** +6321 Healer_Silent_Remove_Curse **** **** **** **** **** **** **** **** +6322 Healer_Still_Remove_Curse **** **** **** **** **** **** **** **** +6323 Healer_Restoration **** **** **** **** **** **** **** **** +6324 Healer_Quickened_Restoration **** **** **** **** **** **** **** **** +6325 Healer_Silent_Restoration **** **** **** **** **** **** **** **** +6326 Healer_Still_Restoration **** **** **** **** **** **** **** **** +6327 Healer_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6328 Healer_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6329 Healer_Quickened_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6330 Healer_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6331 Healer_Empowered_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6332 Healer_Maximized_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6333 Healer_Quickened_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6334 Healer_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6335 Healer_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6336 Healer_Vigor **** **** **** **** **** **** **** **** +6337 Healer_Exteneded_Vigor **** **** **** **** **** **** **** **** +6338 Healer_Quickened_Vigor **** **** **** **** **** **** **** **** +6339 Healer_Silent_Vigor **** **** **** **** **** **** **** **** +6340 Healer_Still_Vigor **** **** **** **** **** **** **** **** +6341 Healer_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6342 Healer_Empowered_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6343 Healer_Maximized_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6344 Healer_Quickened_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6345 Healer_Silent_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6346 Healer_Still_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6347 Healer_Death_Ward **** **** **** **** **** **** **** **** +6348 Healer_Exteneded_Death_Ward **** **** **** **** **** **** **** **** +6349 Healer_Quickened_Death_Ward **** **** **** **** **** **** **** **** +6350 Healer_Silent_Death_Ward **** **** **** **** **** **** **** **** +6351 Healer_Still_Death_Ward **** **** **** **** **** **** **** **** +6352 Healer_Freedom_of_Movement **** **** **** **** **** **** **** **** +6353 Healer_Exteneded_Freedom_of_Movement **** **** **** **** **** **** **** **** +6354 Healer_Quickened_Freedom_of_Movement **** **** **** **** **** **** **** **** +6355 Healer_Silent_Freedom_of_Movement **** **** **** **** **** **** **** **** +6356 Healer_Still_Freedom_of_Movement **** **** **** **** **** **** **** **** +6357 Healer_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6358 Healer_Empowered_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6359 Healer_Maximized_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6360 Healer_Quickened_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6361 Healer_Silent_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6362 Healer_Still_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +6363 Healer_Panacea **** **** **** **** **** **** **** **** +6364 Healer_Empowered_Panacea **** **** **** **** **** **** **** **** +6365 Healer_Maximized_Panacea **** **** **** **** **** **** **** **** +6366 Healer_Quickened_Panacea **** **** **** **** **** **** **** **** +6367 Healer_Silent_Panacea **** **** **** **** **** **** **** **** +6368 Healer_Still_Panacea **** **** **** **** **** **** **** **** +6369 Healer_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6370 Healer_Exteneded_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6371 Healer_Quickened_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6372 Healer_SUNMANTLE **** **** **** **** **** **** **** **** +6373 Healer_Exteneded_SUNMANTLE **** **** **** **** **** **** **** **** +6374 Healer_Quickened_SUNMANTLE **** **** **** **** **** **** **** **** +6375 Healer_Still_SUNMANTLE **** **** **** **** **** **** **** **** +6376 Healer_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6377 Healer_Empowered_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6378 Healer_Exteneded_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6379 Healer_Maximized_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6380 Healer_Quickened_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6381 Healer_Silent_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6382 Healer_Still_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6383 Healer_BreakEnchantment **** **** **** **** **** **** **** **** +6384 Healer_Quickened_BreakEnchantment **** **** **** **** **** **** **** **** +6385 Healer_Silent_BreakEnchantment **** **** **** **** **** **** **** **** +6386 Healer_Still_BreakEnchantment **** **** **** **** **** **** **** **** +6387 Healer_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6388 Healer_Exteneded_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6389 Healer_Quickened_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6390 Healer_Silent_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6391 Healer_Still_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +6392 Healer_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6393 Healer_Empowered_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6394 Healer_Maximized_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6395 Healer_Quickened_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6396 Healer_Silent_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6397 Healer_Still_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +6398 Healer_Raise_Dead **** **** **** **** **** **** **** **** +6399 Healer_Quickened_Raise_Dead **** **** **** **** **** **** **** **** +6400 Healer_Silent_Raise_Dead **** **** **** **** **** **** **** **** +6401 Healer_Still_Raise_Dead **** **** **** **** **** **** **** **** +6402 Healer_Revivify **** **** **** **** **** **** **** **** +6403 Healer_Quickened_Revivify **** **** **** **** **** **** **** **** +6404 Healer_Silent_Revivify **** **** **** **** **** **** **** **** +6405 Healer_Still_Revivify **** **** **** **** **** **** **** **** +6406 Healer_Stone_to_flesh **** **** **** **** **** **** **** **** +6407 Healer_Exteneded_Stone_to_flesh **** **** **** **** **** **** **** **** +6408 Healer_Quickened_Stone_to_flesh **** **** **** **** **** **** **** **** +6409 Healer_Silent_Stone_to_flesh **** **** **** **** **** **** **** **** +6410 Healer_Still_Stone_to_flesh **** **** **** **** **** **** **** **** +6411 Healer_True_Seeing **** **** **** **** **** **** **** **** +6412 Healer_Exteneded_True_Seeing **** **** **** **** **** **** **** **** +6413 Healer_Quickened_True_Seeing **** **** **** **** **** **** **** **** +6414 Healer_Silent_True_Seeing **** **** **** **** **** **** **** **** +6415 Healer_Still_True_Seeing **** **** **** **** **** **** **** **** +6416 Healer_SICKEN_EVIL **** **** **** **** **** **** **** **** +6417 Healer_Exteneded_SICKEN_EVIL **** **** **** **** **** **** **** **** +6418 Healer_Quickened_SICKEN_EVIL **** **** **** **** **** **** **** **** +6419 Healer_Silent_SICKEN_EVIL **** **** **** **** **** **** **** **** +6420 Healer_Still_SICKEN_EVIL **** **** **** **** **** **** **** **** +6421 Healer_Greater_Restoration **** **** **** **** **** **** **** **** +6422 Healer_Silent_Greater_Restoration **** **** **** **** **** **** **** **** +6423 Healer_Still_Greater_Restoration **** **** **** **** **** **** **** **** +6424 Healer_Heal **** **** **** **** **** **** **** **** +6425 Healer_Silent_Heal **** **** **** **** **** **** **** **** +6426 Healer_Still_Heal **** **** **** **** **** **** **** **** +6427 Healer_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6428 Healer_Empowered_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6429 Healer_Maximized_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6430 Healer_Silent_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6431 Healer_Still_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +6432 Healer_Regenerate **** **** **** **** **** **** **** **** +6433 Healer_Exteneded_Regenerate **** **** **** **** **** **** **** **** +6434 Healer_Silent_Regenerate **** **** **** **** **** **** **** **** +6435 Healer_Still_Regenerate **** **** **** **** **** **** **** **** +6436 Healer_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +6437 Healer_Exteneded_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +6438 Healer_Silent_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +6439 Healer_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +6440 Healer_Empowered_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +6441 Healer_Maximized_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +6442 Healer_Silent_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +6443 Healer_Still_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +6444 Healer_Vigorous_Circle **** **** **** **** **** **** **** **** +6445 Healer_Exteneded_Vigorous_Circle **** **** **** **** **** **** **** **** +6446 Healer_Silent_Vigorous_Circle **** **** **** **** **** **** **** **** +6447 Healer_Still_Vigorous_Circle **** **** **** **** **** **** **** **** +6448 Healer_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6449 Healer_Empowered_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6450 Healer_Silent_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6451 Healer_Still_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +6452 Healer_Resurrection **** **** **** **** **** **** **** **** +6453 Healer_Silent_Resurrection **** **** **** **** **** **** **** **** +6454 Healer_Still_Resurrection **** **** **** **** **** **** **** **** +6455 Healer_Repulsion **** **** **** **** **** **** **** **** +6456 Healer_Exteneded_Repulsion **** **** **** **** **** **** **** **** +6457 Healer_Silent_Repulsion **** **** **** **** **** **** **** **** +6458 Healer_Still_Repulsion **** **** **** **** **** **** **** **** +6459 Healer_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +6460 Healer_Empowered_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +6461 Healer_Exteneded_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +6462 Healer_Silent_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +6463 Healer_Still_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +6464 Healer_PHOENIX_FIRE **** **** **** **** **** **** **** **** +6465 Healer_Empowered_PHOENIX_FIRE **** **** **** **** **** **** **** **** +6466 Healer_Silent_PHOENIX_FIRE **** **** **** **** **** **** **** **** +6467 Healer_Still_PHOENIX_FIRE **** **** **** **** **** **** **** **** +6468 Healer_DiscernLocation **** **** **** **** **** **** **** **** +6469 Healer_Exteneded_DiscernLocation **** **** **** **** **** **** **** **** +6470 Healer_Silent_DiscernLocation **** **** **** **** **** **** **** **** +6471 Healer_Still_DiscernLocation **** **** **** **** **** **** **** **** +6472 Healer_Holy_Aura **** **** **** **** **** **** **** **** +6473 Healer_Exteneded_Holy_Aura **** **** **** **** **** **** **** **** +6474 Healer_Silent_Holy_Aura **** **** **** **** **** **** **** **** +6475 Healer_Still_Holy_Aura **** **** **** **** **** **** **** **** +6476 Healer_Mass_Heal **** **** **** **** **** **** **** **** +6477 Healer_Silent_Mass_Heal **** **** **** **** **** **** **** **** +6478 Healer_Still_Mass_Heal **** **** **** **** **** **** **** **** +6479 Healer_DRAGON_CLOUD **** **** **** **** **** **** **** **** +6480 Healer_Silent_DRAGON_CLOUD **** **** **** **** **** **** **** **** +6481 Healer_Still_DRAGON_CLOUD **** **** **** **** **** **** **** **** +6482 Healer_Foresight **** **** **** **** **** **** **** **** +6483 Healer_Gate **** **** **** **** **** **** **** **** +6484 Healer_True_Resurrection **** **** **** **** **** **** **** **** +6485 Healer_EXALTED_FURY **** **** **** **** **** **** **** **** +6486 CelebrantSharess_Cause_Fear **** **** **** **** **** **** **** **** +6487 CelebrantSharess_Charm_Person **** **** **** **** **** **** **** **** +6488 CelebrantSharess_Daze **** **** **** **** **** **** **** **** +6489 CelebrantSharess_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +6490 CelebrantSharess_Disguise_Self_Learn **** **** **** **** **** **** **** **** +6491 CelebrantSharess_Disguise_Self_Options **** **** **** **** **** **** **** **** +6492 CelebrantSharess_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +6493 CelebrantSharess_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +6494 CelebrantSharess_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +6495 CelebrantSharess_RAY_OF_HOPE **** **** **** **** **** **** **** **** +6496 CelebrantSharess_Read_Magic **** **** **** **** **** **** **** **** +6497 CelebrantSharess_Remove_Fear **** **** **** **** **** **** **** **** +6498 CelebrantSharess_Sleep **** **** **** **** **** **** **** **** +6499 CelebrantSharess_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6500 CelebrantSharess_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +6501 CelebrantSharess_Alter_Self_Learn **** **** **** **** **** **** **** **** +6502 CelebrantSharess_Alter_Self_Options **** **** **** **** **** **** **** **** +6503 CelebrantSharess_Alter_Self_QS1 **** **** **** **** **** **** **** **** +6504 CelebrantSharess_Alter_Self_QS2 **** **** **** **** **** **** **** **** +6505 CelebrantSharess_Alter_Self_QS3 **** **** **** **** **** **** **** **** +6506 CelebrantSharess_Calm_Emotions **** **** **** **** **** **** **** **** +6507 CelebrantSharess_Cats_Grace **** **** **** **** **** **** **** **** +6508 CelebrantSharess_Daze_Monster **** **** **** **** **** **** **** **** +6509 CelebrantSharess_Eagle_Splendor **** **** **** **** **** **** **** **** +6510 CelebrantSharess_ELATION **** **** **** **** **** **** **** **** +6511 CelebrantSharess_Enthrall **** **** **** **** **** **** **** **** +6512 CelebrantSharess_Heroism **** **** **** **** **** **** **** **** +6513 CelebrantSharess_Hold_Person **** **** **** **** **** **** **** **** +6514 CelebrantSharess_Rage **** **** **** **** **** **** **** **** +6515 CelebrantSharess_Scare **** **** **** **** **** **** **** **** +6516 CelebrantSharess_Charm_Monster **** **** **** **** **** **** **** **** +6517 CelebrantSharess_Confusion **** **** **** **** **** **** **** **** +6518 CelebrantSharess_CrushingDespair **** **** **** **** **** **** **** **** +6519 CelebrantSharess_DeepSlumber **** **** **** **** **** **** **** **** +6520 CelebrantSharess_Fear **** **** **** **** **** **** **** **** +6521 CelebrantSharess_GLIBNESS **** **** **** **** **** **** **** **** +6522 CelebrantSharess_Slow **** **** **** **** **** **** **** **** +6523 CelebrantSharess_War_Cry **** **** **** **** **** **** **** **** +6524 CelebrantSharess_BreakEnchantment **** **** **** **** **** **** **** **** +6525 CelebrantSharess_Dominate_Person **** **** **** **** **** **** **** **** +6526 CelebrantSharess_Hold_Monster **** **** **** **** **** **** **** **** +6527 CelebrantSharess_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +6528 CultistShatteredP_Endure_Elements **** **** **** **** **** **** **** **** +6529 CultistShatteredP_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +6530 CultistShatteredP_Silent_Endure_Elements **** **** **** **** **** **** **** **** +6531 CultistShatteredP_Still_Endure_Elements **** **** **** **** **** **** **** **** +6532 CultistShatteredP_Protection_from_Chaos **** **** **** **** **** **** **** **** +6533 CultistShatteredP_Exteneded_Protection_from_Chaos **** **** **** **** **** **** **** **** +6534 CultistShatteredP_Silent_Protection_from_Chaos **** **** **** **** **** **** **** **** +6535 CultistShatteredP_Still_Protection_from_Chaos **** **** **** **** **** **** **** **** +6536 CultistShatteredP_Protection_from_Evil **** **** **** **** **** **** **** **** +6537 CultistShatteredP_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +6538 CultistShatteredP_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +6539 CultistShatteredP_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +6540 CultistShatteredP_Protection_from_Good **** **** **** **** **** **** **** **** +6541 CultistShatteredP_Exteneded_Protection_from_Good **** **** **** **** **** **** **** **** +6542 CultistShatteredP_Silent_Protection_from_Good **** **** **** **** **** **** **** **** +6543 CultistShatteredP_Still_Protection_from_Good **** **** **** **** **** **** **** **** +6544 CultistShatteredP_Protection_from_Law **** **** **** **** **** **** **** **** +6545 CultistShatteredP_Exteneded_Protection_from_Law **** **** **** **** **** **** **** **** +6546 CultistShatteredP_Silent_Protection_from_Law **** **** **** **** **** **** **** **** +6547 CultistShatteredP_Still_Protection_from_Law **** **** **** **** **** **** **** **** +6548 CultistShatteredP_Shield **** **** **** **** **** **** **** **** +6549 CultistShatteredP_Exteneded_Shield **** **** **** **** **** **** **** **** +6550 CultistShatteredP_Silent_Shield **** **** **** **** **** **** **** **** +6551 CultistShatteredP_Still_Shield **** **** **** **** **** **** **** **** +6552 CultistShatteredP_Ironguts **** **** **** **** **** **** **** **** +6553 CultistShatteredP_Exteneded_Ironguts **** **** **** **** **** **** **** **** +6554 CultistShatteredP_Silent_Ironguts **** **** **** **** **** **** **** **** +6555 CultistShatteredP_Still_Ironguts **** **** **** **** **** **** **** **** +6556 CultistShatteredP_Lesser_Deflect **** **** **** **** **** **** **** **** +6557 CultistShatteredP_Exteneded_Lesser_Deflect **** **** **** **** **** **** **** **** +6558 CultistShatteredP_Silent_Lesser_Deflect **** **** **** **** **** **** **** **** +6559 CultistShatteredP_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6560 CultistShatteredP_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6561 CultistShatteredP_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6562 CultistShatteredP_Charm_Person **** **** **** **** **** **** **** **** +6563 CultistShatteredP_Exteneded_Charm_Person **** **** **** **** **** **** **** **** +6564 CultistShatteredP_Silent_Charm_Person **** **** **** **** **** **** **** **** +6565 CultistShatteredP_Still_Charm_Person **** **** **** **** **** **** **** **** +6566 CultistShatteredP_Sleep **** **** **** **** **** **** **** **** +6567 CultistShatteredP_Empowered_Sleep **** **** **** **** **** **** **** **** +6568 CultistShatteredP_Exteneded_Sleep **** **** **** **** **** **** **** **** +6569 CultistShatteredP_Silent_Sleep **** **** **** **** **** **** **** **** +6570 CultistShatteredP_Still_Sleep **** **** **** **** **** **** **** **** +6571 CultistShatteredP_Rouse **** **** **** **** **** **** **** **** +6572 CultistShatteredP_Silent_Rouse **** **** **** **** **** **** **** **** +6573 CultistShatteredP_Still_Rouse **** **** **** **** **** **** **** **** +6574 CultistShatteredP_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +6575 CultistShatteredP_Silent_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +6576 CultistShatteredP_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +6577 CultistShatteredP_Exteneded_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +6578 CultistShatteredP_Silent_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +6579 CultistShatteredP_Still_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +6580 CultistShatteredP_Lesser_Dispel **** **** **** **** **** **** **** **** +6581 CultistShatteredP_Silent_Lesser_Dispel **** **** **** **** **** **** **** **** +6582 CultistShatteredP_Still_Lesser_Dispel **** **** **** **** **** **** **** **** +6583 CultistShatteredP_Resist_Elements **** **** **** **** **** **** **** **** +6584 CultistShatteredP_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +6585 CultistShatteredP_Silent_Resist_Elements **** **** **** **** **** **** **** **** +6586 CultistShatteredP_Still_Resist_Elements **** **** **** **** **** **** **** **** +6587 CultistShatteredP_Deflect **** **** **** **** **** **** **** **** +6588 CultistShatteredP_Exteneded_Deflect **** **** **** **** **** **** **** **** +6589 CultistShatteredP_Silent_Deflect **** **** **** **** **** **** **** **** +6590 CultistShatteredP_ProtectionArrows **** **** **** **** **** **** **** **** +6591 CultistShatteredP_Exteneded_ProtectionArrows **** **** **** **** **** **** **** **** +6592 CultistShatteredP_Silent_ProtectionArrows **** **** **** **** **** **** **** **** +6593 CultistShatteredP_Still_ProtectionArrows **** **** **** **** **** **** **** **** +6594 CultistShatteredP_Dispelling_Touch **** **** **** **** **** **** **** **** +6595 CultistShatteredP_Silent_Dispelling_Touch **** **** **** **** **** **** **** **** +6596 CultistShatteredP_Still_Dispelling_Touch **** **** **** **** **** **** **** **** +6597 CultistShatteredP_UNHEAVENED **** **** **** **** **** **** **** **** +6598 CultistShatteredP_Silent_UNHEAVENED **** **** **** **** **** **** **** **** +6599 CultistShatteredP_Still_UNHEAVENED **** **** **** **** **** **** **** **** +6600 CultistShatteredP_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6601 CultistShatteredP_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6602 CultistShatteredP_ObscureObject **** **** **** **** **** **** **** **** +6603 CultistShatteredP_Exteneded_ObscureObject **** **** **** **** **** **** **** **** +6604 CultistShatteredP_Silent_ObscureObject **** **** **** **** **** **** **** **** +6605 CultistShatteredP_Still_ObscureObject **** **** **** **** **** **** **** **** +6606 CultistShatteredP_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6607 CultistShatteredP_Exteneded_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6608 CultistShatteredP_Silent_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6609 CultistShatteredP_Still_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6610 CultistShatteredP_Daze_Monster **** **** **** **** **** **** **** **** +6611 CultistShatteredP_Exteneded_Daze_Monster **** **** **** **** **** **** **** **** +6612 CultistShatteredP_Silent_Daze_Monster **** **** **** **** **** **** **** **** +6613 CultistShatteredP_Still_Daze_Monster **** **** **** **** **** **** **** **** +6614 CultistShatteredP_TouchIdiocy **** **** **** **** **** **** **** **** +6615 CultistShatteredP_Exteneded_TouchIdiocy **** **** **** **** **** **** **** **** +6616 CultistShatteredP_Silent_TouchIdiocy **** **** **** **** **** **** **** **** +6617 CultistShatteredP_Still_TouchIdiocy **** **** **** **** **** **** **** **** +6618 CultistShatteredP_MASOCHISM **** **** **** **** **** **** **** **** +6619 CultistShatteredP_Exteneded_MASOCHISM **** **** **** **** **** **** **** **** +6620 CultistShatteredP_ADDICTION **** **** **** **** **** **** **** **** +6621 CultistShatteredP_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +6622 CultistShatteredP_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +6623 CultistShatteredP_ADDICTION_VODARE **** **** **** **** **** **** **** **** +6624 CultistShatteredP_ADDICTION_AGONY **** **** **** **** **** **** **** **** +6625 CultistShatteredP_Silent_ADDICTION **** **** **** **** **** **** **** **** +6626 CultistShatteredP_Silent_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +6627 CultistShatteredP_Silent_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +6628 CultistShatteredP_Silent_ADDICTION_VODARE **** **** **** **** **** **** **** **** +6629 CultistShatteredP_Silent_ADDICTION_AGONY **** **** **** **** **** **** **** **** +6630 CultistShatteredP_Still_ADDICTION **** **** **** **** **** **** **** **** +6631 CultistShatteredP_Still_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +6632 CultistShatteredP_Still_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +6633 CultistShatteredP_Still_ADDICTION_VODARE **** **** **** **** **** **** **** **** +6634 CultistShatteredP_Still_ADDICTION_AGONY **** **** **** **** **** **** **** **** +6635 CultistShatteredP_Clarity **** **** **** **** **** **** **** **** +6636 CultistShatteredP_Dispel_Magic **** **** **** **** **** **** **** **** +6637 CultistShatteredP_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +6638 CultistShatteredP_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +6639 CultistShatteredP_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +6640 CultistShatteredP_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +6641 CultistShatteredP_Protection_from_Elements **** **** **** **** **** **** **** **** +6642 CultistShatteredP_Energy_Aegis **** **** **** **** **** **** **** **** +6643 CultistShatteredP_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +6644 CultistShatteredP_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +6645 CultistShatteredP_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +6646 CultistShatteredP_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +6647 CultistShatteredP_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +6648 CultistShatteredP_NONDETECTION **** **** **** **** **** **** **** **** +6649 CultistShatteredP_Hold_Person **** **** **** **** **** **** **** **** +6650 CultistShatteredP_Rage **** **** **** **** **** **** **** **** +6651 CultistShatteredP_DeepSlumber **** **** **** **** **** **** **** **** +6652 CultistShatteredP_EVIL_EYE **** **** **** **** **** **** **** **** +6653 CultistShatteredP_ELATION **** **** **** **** **** **** **** **** +6654 CultistShatteredP_Heroism **** **** **** **** **** **** **** **** +6655 Beguiler_Dancing_Lights **** **** **** **** **** **** **** **** +6656 Beguiler_Daze **** **** **** **** **** **** **** **** +6657 Beguiler_Read_Magic **** **** **** **** **** **** **** **** +6658 Beguiler_Charm_Person **** **** **** **** **** **** **** **** +6659 Beguiler_Color_Spray **** **** **** **** **** **** **** **** +6660 Beguiler_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +6661 Beguiler_Disguise_Self_Learn **** **** **** **** **** **** **** **** +6662 Beguiler_Disguise_Self_Options **** **** **** **** **** **** **** **** +6663 Beguiler_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +6664 Beguiler_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +6665 Beguiler_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +6666 Beguiler_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +6667 Beguiler_Expeditious_Retreat **** **** **** **** **** **** **** **** +6668 Beguiler_Mage_Armor **** **** **** **** **** **** **** **** +6669 Beguiler_Nybors_Gentle_Reminder **** **** **** **** **** **** **** **** +6670 Beguiler_Obscuring_Mist **** **** **** **** **** **** **** **** +6671 Beguiler_Rouse **** **** **** **** **** **** **** **** +6672 Beguiler_Sleep **** **** **** **** **** **** **** **** +6673 Beguiler_UndetectableAlignment **** **** **** **** **** **** **** **** +6674 Beguiler_ADDICTION **** **** **** **** **** **** **** **** +6675 Beguiler_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +6676 Beguiler_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +6677 Beguiler_ADDICTION_VODARE **** **** **** **** **** **** **** **** +6678 Beguiler_ADDICTION_AGONY **** **** **** **** **** **** **** **** +6679 Beguiler_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6680 Beguiler_Blur **** **** **** **** **** **** **** **** +6681 Beguiler_Continual_Flame **** **** **** **** **** **** **** **** +6682 Beguiler_Daze_Monster **** **** **** **** **** **** **** **** +6683 Beguiler_FogCloud **** **** **** **** **** **** **** **** +6684 Beguiler_Ghostly_Visage **** **** **** **** **** **** **** **** +6685 Beguiler_Glitterdust **** **** **** **** **** **** **** **** +6686 Beguiler_Invisibility **** **** **** **** **** **** **** **** +6687 Beguiler_Knock **** **** **** **** **** **** **** **** +6688 Beguiler_MASOCHISM **** **** **** **** **** **** **** **** +6689 Beguiler_MirrorImage **** **** **** **** **** **** **** **** +6690 Beguiler_See_Invisibility **** **** **** **** **** **** **** **** +6691 Beguiler_Shadow_Spray **** **** **** **** **** **** **** **** +6692 Beguiler_Silence **** **** **** **** **** **** **** **** +6693 Beguiler_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +6694 Beguiler_TouchIdiocy **** **** **** **** **** **** **** **** +6695 Beguiler_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +6696 Beguiler_CURSE_OF_THE_PUTRID_HUSK **** **** **** **** **** **** **** **** +6697 Beguiler_DeepSlumber **** **** **** **** **** **** **** **** +6698 Beguiler_Dispel_Magic **** **** **** **** **** **** **** **** +6699 Beguiler_Displacement **** **** **** **** **** **** **** **** +6700 Beguiler_ELATION **** **** **** **** **** **** **** **** +6701 Beguiler_EVIL_EYE **** **** **** **** **** **** **** **** +6702 Beguiler_GLIBNESS **** **** **** **** **** **** **** **** +6703 Beguiler_Halt **** **** **** **** **** **** **** **** +6704 Beguiler_Haste **** **** **** **** **** **** **** **** +6705 Beguiler_Heroism **** **** **** **** **** **** **** **** +6706 Beguiler_Hold_Person **** **** **** **** **** **** **** **** +6707 Beguiler_Invisibility_Sphere **** **** **** **** **** **** **** **** +6708 Beguiler_NONDETECTION **** **** **** **** **** **** **** **** +6709 Beguiler_REALITY_BLIND **** **** **** **** **** **** **** **** +6710 Beguiler_Slow **** **** **** **** **** **** **** **** +6711 Beguiler_Charm_Monster **** **** **** **** **** **** **** **** +6712 Beguiler_Confusion **** **** **** **** **** **** **** **** +6713 Beguiler_CrushingDespair **** **** **** **** **** **** **** **** +6714 Beguiler_Freedom_of_Movement **** **** **** **** **** **** **** **** +6715 Beguiler_Improved_Invisibility **** **** **** **** **** **** **** **** +6716 Beguiler_LocateCreature **** **** **** **** **** **** **** **** +6717 Beguiler_Phantasmal_Killer **** **** **** **** **** **** **** **** +6718 Beguiler_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +6719 Beguiler_Shadow_Conjuration **** **** **** **** **** **** **** **** +6720 Beguiler_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +6721 Beguiler_SHADOW_CON_Darkness **** **** **** **** **** **** **** **** +6722 Beguiler_SHADOW_CON_Inivsibility **** **** **** **** **** **** **** **** +6723 Beguiler_SHADOW_CON_Mage_Armor **** **** **** **** **** **** **** **** +6724 Beguiler_SHADOW_CON_Magic_Missile **** **** **** **** **** **** **** **** +6725 Beguiler_SolidFog **** **** **** **** **** **** **** **** +6726 Beguiler_BreakEnchantment **** **** **** **** **** **** **** **** +6727 Beguiler_Dominate_Person **** **** **** **** **** **** **** **** +6728 Beguiler_Feeblemind **** **** **** **** **** **** **** **** +6729 Beguiler_Greater_Shadow_Conjuration **** **** **** **** **** **** **** **** +6730 Beguiler_GR_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +6731 Beguiler_GR_SHADOW_CON_Acid_Arrow **** **** **** **** **** **** **** **** +6732 Beguiler_GR_SHADOW_CON_Ghostly_Visage **** **** **** **** **** **** **** **** +6733 Beguiler_GR_SHADOW_CON_Web **** **** **** **** **** **** **** **** +6734 Beguiler_GR_SHADOW_CON_Minor_Globe **** **** **** **** **** **** **** **** +6735 Beguiler_Hold_Monster **** **** **** **** **** **** **** **** +6736 Beguiler_Mind_Fog **** **** **** **** **** **** **** **** +6737 Beguiler_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +6738 Beguiler_Ethereal_Visage **** **** **** **** **** **** **** **** +6739 Beguiler_Greater_Dispelling **** **** **** **** **** **** **** **** +6740 Beguiler_Greater_Heroism **** **** **** **** **** **** **** **** +6741 Beguiler_Mass_Haste **** **** **** **** **** **** **** **** +6742 Beguiler_Mislead **** **** **** **** **** **** **** **** +6743 Beguiler_Repulsion **** **** **** **** **** **** **** **** +6744 Beguiler_Shades **** **** **** **** **** **** **** **** +6745 Beguiler_SHADES_Summon_Shadow **** **** **** **** **** **** **** **** +6746 Beguiler_SHADES_Cone_of_Cold **** **** **** **** **** **** **** **** +6747 Beguiler_SHADES_Fireball **** **** **** **** **** **** **** **** +6748 Beguiler_SHADES_Stoneskin **** **** **** **** **** **** **** **** +6749 Beguiler_SHADES_Wall_of_Fire **** **** **** **** **** **** **** **** +6750 Beguiler_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +6751 Beguiler_True_Seeing **** **** **** **** **** **** **** **** +6752 Beguiler_Etherealness **** **** **** **** **** **** **** **** +6753 Beguiler_Insanity **** **** **** **** **** **** **** **** +6754 Beguiler_Mass_Hold_Person **** **** **** **** **** **** **** **** +6755 Beguiler_Nybors_Stern_Reproof **** **** **** **** **** **** **** **** +6756 Beguiler_Power_Word_Blind **** **** **** **** **** **** **** **** +6757 Beguiler_Protection_from_Spells **** **** **** **** **** **** **** **** +6758 Beguiler_Shadow_Shield **** **** **** **** **** **** **** **** +6759 Beguiler_Spell_Turning **** **** **** **** **** **** **** **** +6760 Beguiler_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +6761 Beguiler_DiscernLocation **** **** **** **** **** **** **** **** +6762 Beguiler_Mass_Blindness_and_Deafness **** **** **** **** **** **** **** **** +6763 Beguiler_Mass_Charm **** **** **** **** **** **** **** **** +6764 Beguiler_Mind_Blank **** **** **** **** **** **** **** **** +6765 Beguiler_Power_Word_Stun **** **** **** **** **** **** **** **** +6766 Beguiler_ScintillatingPattern **** **** **** **** **** **** **** **** +6767 Beguiler_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +6768 Beguiler_Dominate_Monster **** **** **** **** **** **** **** **** +6769 Beguiler_Foresight **** **** **** **** **** **** **** **** +6770 Beguiler_Mass_Hold_Monster **** **** **** **** **** **** **** **** +6771 Beguiler_Power_Word_Kill **** **** **** **** **** **** **** **** +6772 Beguiler_Time_Stop **** **** **** **** **** **** **** **** +6773 Beguiler_Weird **** **** **** **** **** **** **** **** +6774 KnightOfTheChalic_Bless_Water **** **** **** **** **** **** **** **** +6775 KnightOfTheChalic_Silent_Bless_Water **** **** **** **** **** **** **** **** +6776 KnightOfTheChalic_Still_Bless_Water **** **** **** **** **** **** **** **** +6777 KnightOfTheChalic_Bless_Weapon **** **** **** **** **** **** **** **** +6778 KnightOfTheChalic_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +6779 KnightOfTheChalic_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +6780 KnightOfTheChalic_Still_Bless_Weapon **** **** **** **** **** **** **** **** +6781 KnightOfTheChalic_Divine_Favor **** **** **** **** **** **** **** **** +6782 KnightOfTheChalic_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +6783 KnightOfTheChalic_Silent_Divine_Favor **** **** **** **** **** **** **** **** +6784 KnightOfTheChalic_Still_Divine_Favor **** **** **** **** **** **** **** **** +6785 KnightOfTheChalic_Detect_Chaos **** **** **** **** **** **** **** **** +6786 KnightOfTheChalic_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +6787 KnightOfTheChalic_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +6788 KnightOfTheChalic_Still_Detect_Chaos **** **** **** **** **** **** **** **** +6789 KnightOfTheChalic_Detect_Evil **** **** **** **** **** **** **** **** +6790 KnightOfTheChalic_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +6791 KnightOfTheChalic_Silent_Detect_Evil **** **** **** **** **** **** **** **** +6792 KnightOfTheChalic_Still_Detect_Evil **** **** **** **** **** **** **** **** +6793 KnightOfTheChalic_Doom **** **** **** **** **** **** **** **** +6794 KnightOfTheChalic_Exteneded_Doom **** **** **** **** **** **** **** **** +6795 KnightOfTheChalic_Silent_Doom **** **** **** **** **** **** **** **** +6796 KnightOfTheChalic_Still_Doom **** **** **** **** **** **** **** **** +6797 KnightOfTheChalic_Endure_Elements **** **** **** **** **** **** **** **** +6798 KnightOfTheChalic_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +6799 KnightOfTheChalic_Silent_Endure_Elements **** **** **** **** **** **** **** **** +6800 KnightOfTheChalic_Still_Endure_Elements **** **** **** **** **** **** **** **** +6801 KnightOfTheChalic_Magic_Weapon **** **** **** **** **** **** **** **** +6802 KnightOfTheChalic_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +6803 KnightOfTheChalic_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +6804 KnightOfTheChalic_Still_Magic_Weapon **** **** **** **** **** **** **** **** +6805 KnightOfTheChalic_Protection_from_Evil **** **** **** **** **** **** **** **** +6806 KnightOfTheChalic_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +6807 KnightOfTheChalic_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +6808 KnightOfTheChalic_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +6809 KnightOfTheChalic_Remove_Fear **** **** **** **** **** **** **** **** +6810 KnightOfTheChalic_Exteneded_Remove_Fear **** **** **** **** **** **** **** **** +6811 KnightOfTheChalic_Silent_Remove_Fear **** **** **** **** **** **** **** **** +6812 KnightOfTheChalic_Still_Remove_Fear **** **** **** **** **** **** **** **** +6813 KnightOfTheChalic_Summon_Creature_I **** **** **** **** **** **** **** **** +6814 KnightOfTheChalic_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +6815 KnightOfTheChalic_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +6816 KnightOfTheChalic_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +6817 KnightOfTheChalic_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +6818 KnightOfTheChalic_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +6819 KnightOfTheChalic_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6820 KnightOfTheChalic_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6821 KnightOfTheChalic_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6822 KnightOfTheChalic_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6823 KnightOfTheChalic_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6824 KnightOfTheChalic_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6825 KnightOfTheChalic_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6826 KnightOfTheChalic_Aid **** **** **** **** **** **** **** **** +6827 KnightOfTheChalic_Empowered_Aid **** **** **** **** **** **** **** **** +6828 KnightOfTheChalic_Exteneded_Aid **** **** **** **** **** **** **** **** +6829 KnightOfTheChalic_Silent_Aid **** **** **** **** **** **** **** **** +6830 KnightOfTheChalic_Still_Aid **** **** **** **** **** **** **** **** +6831 KnightOfTheChalic_Bulls_Strength **** **** **** **** **** **** **** **** +6832 KnightOfTheChalic_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +6833 KnightOfTheChalic_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +6834 KnightOfTheChalic_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +6835 KnightOfTheChalic_Still_Bulls_Strength **** **** **** **** **** **** **** **** +6836 KnightOfTheChalic_Consecrated_Aura **** **** **** **** **** **** **** **** +6837 KnightOfTheChalic_Exteneded_Consecrated_Aura **** **** **** **** **** **** **** **** +6838 KnightOfTheChalic_Silent_Consecrated_Aura **** **** **** **** **** **** **** **** +6839 KnightOfTheChalic_Still_Consecrated_Aura **** **** **** **** **** **** **** **** +6840 KnightOfTheChalic_Endurance **** **** **** **** **** **** **** **** +6841 KnightOfTheChalic_Empowered_Endurance **** **** **** **** **** **** **** **** +6842 KnightOfTheChalic_Exteneded_Endurance **** **** **** **** **** **** **** **** +6843 KnightOfTheChalic_Silent_Endurance **** **** **** **** **** **** **** **** +6844 KnightOfTheChalic_Still_Endurance **** **** **** **** **** **** **** **** +6845 KnightOfTheChalic_Resist_Elements **** **** **** **** **** **** **** **** +6846 KnightOfTheChalic_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +6847 KnightOfTheChalic_Silent_Resist_Elements **** **** **** **** **** **** **** **** +6848 KnightOfTheChalic_Still_Resist_Elements **** **** **** **** **** **** **** **** +6849 KnightOfTheChalic_Sound_Burst **** **** **** **** **** **** **** **** +6850 KnightOfTheChalic_Silent_Sound_Burst **** **** **** **** **** **** **** **** +6851 KnightOfTheChalic_Still_Sound_Burst **** **** **** **** **** **** **** **** +6852 KnightOfTheChalic_Summon_Creature_II **** **** **** **** **** **** **** **** +6853 KnightOfTheChalic_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +6854 KnightOfTheChalic_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +6855 KnightOfTheChalic_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +6856 KnightOfTheChalic_UndetectableAlignment **** **** **** **** **** **** **** **** +6857 KnightOfTheChalic_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +6858 KnightOfTheChalic_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +6859 KnightOfTheChalic_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +6860 KnightOfTheChalic_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6861 KnightOfTheChalic_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6862 KnightOfTheChalic_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6863 KnightOfTheChalic_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6864 KnightOfTheChalic_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6865 KnightOfTheChalic_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6866 KnightOfTheChalic_Dispel_Magic **** **** **** **** **** **** **** **** +6867 KnightOfTheChalic_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +6868 KnightOfTheChalic_Still_Dispel_Magic **** **** **** **** **** **** **** **** +6869 KnightOfTheChalic_Summon_Creature_III **** **** **** **** **** **** **** **** +6870 KnightOfTheChalic_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +6871 KnightOfTheChalic_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +6872 KnightOfTheChalic_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +6873 KnightOfTheChalic_Invisibility_Purge **** **** **** **** **** **** **** **** +6874 KnightOfTheChalic_Exteneded_Invisibility_Purge **** **** **** **** **** **** **** **** +6875 KnightOfTheChalic_Silent_Invisibility_Purge **** **** **** **** **** **** **** **** +6876 KnightOfTheChalic_Still_Invisibility_Purge **** **** **** **** **** **** **** **** +6877 KnightOfTheChalic_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +6878 KnightOfTheChalic_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +6879 KnightOfTheChalic_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +6880 KnightOfTheChalic_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +6881 KnightOfTheChalic_Magic_Vestment **** **** **** **** **** **** **** **** +6882 KnightOfTheChalic_Exteneded_Magic_Vestment **** **** **** **** **** **** **** **** +6883 KnightOfTheChalic_Silent_Magic_Vestment **** **** **** **** **** **** **** **** +6884 KnightOfTheChalic_Still_Magic_Vestment **** **** **** **** **** **** **** **** +6885 KnightOfTheChalic_Prayer **** **** **** **** **** **** **** **** +6886 KnightOfTheChalic_Exteneded_Prayer **** **** **** **** **** **** **** **** +6887 KnightOfTheChalic_Silent_Prayer **** **** **** **** **** **** **** **** +6888 KnightOfTheChalic_Still_Prayer **** **** **** **** **** **** **** **** +6889 KnightOfTheChalic_Protection_from_Elements **** **** **** **** **** **** **** **** +6890 KnightOfTheChalic_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +6891 KnightOfTheChalic_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +6892 KnightOfTheChalic_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +6893 KnightOfTheChalic_Searing_Light **** **** **** **** **** **** **** **** +6894 KnightOfTheChalic_Silent_Searing_Light **** **** **** **** **** **** **** **** +6895 KnightOfTheChalic_Still_Searing_Light **** **** **** **** **** **** **** **** +6896 KnightOfTheChalic_Shout **** **** **** **** **** **** **** **** +6897 KnightOfTheChalic_Silent_Shout **** **** **** **** **** **** **** **** +6898 KnightOfTheChalic_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6899 KnightOfTheChalic_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6900 KnightOfTheChalic_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6901 KnightOfTheChalic_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6902 KnightOfTheChalic_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6903 KnightOfTheChalic_Dimensional_Anchor **** **** **** **** **** **** **** **** +6904 KnightOfTheChalic_Dismissal **** **** **** **** **** **** **** **** +6905 KnightOfTheChalic_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +6906 KnightOfTheChalic_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +6907 KnightOfTheChalic_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +6908 KnightOfTheChalic_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6909 KnightOfTheChalic_SUNMANTLE **** **** **** **** **** **** **** **** +6910 KnightOfTheChalic_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6911 Vigilant_Blur **** **** **** **** **** **** **** **** +6912 Vigilant_Exteneded_Blur **** **** **** **** **** **** **** **** +6913 Vigilant_Silent_Blur **** **** **** **** **** **** **** **** +6914 Vigilant_Expeditious_Retreat **** **** **** **** **** **** **** **** +6915 Vigilant_Exteneded_Expeditious_Retreat **** **** **** **** **** **** **** **** +6916 Vigilant_Silent_Expeditious_Retreat **** **** **** **** **** **** **** **** +6917 Vigilant_Still_Expeditious_Retreat **** **** **** **** **** **** **** **** +6918 Vigilant_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6919 Vigilant_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6920 Vigilant_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6921 Vigilant_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +6922 Vigilant_Resist_Elements **** **** **** **** **** **** **** **** +6923 Vigilant_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +6924 Vigilant_Silent_Resist_Elements **** **** **** **** **** **** **** **** +6925 Vigilant_Still_Resist_Elements **** **** **** **** **** **** **** **** +6926 Vigilant_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6927 Vigilant_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6928 Vigilant_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +6929 Vigilant_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6930 Vigilant_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6931 Vigilant_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6932 Vigilant_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +6933 Vigilant_Detect_Chaos **** **** **** **** **** **** **** **** +6934 Vigilant_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +6935 Vigilant_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +6936 Vigilant_Still_Detect_Chaos **** **** **** **** **** **** **** **** +6937 Vigilant_Detect_Evil **** **** **** **** **** **** **** **** +6938 Vigilant_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +6939 Vigilant_Silent_Detect_Evil **** **** **** **** **** **** **** **** +6940 Vigilant_Still_Detect_Evil **** **** **** **** **** **** **** **** +6941 Vigilant_Detect_Good **** **** **** **** **** **** **** **** +6942 Vigilant_Exteneded_Detect_Good **** **** **** **** **** **** **** **** +6943 Vigilant_Silent_Detect_Good **** **** **** **** **** **** **** **** +6944 Vigilant_Still_Detect_Good **** **** **** **** **** **** **** **** +6945 Vigilant_Detect_Law **** **** **** **** **** **** **** **** +6946 Vigilant_Exteneded_Detect_Law **** **** **** **** **** **** **** **** +6947 Vigilant_Silent_Detect_Law **** **** **** **** **** **** **** **** +6948 Vigilant_Still_Detect_Law **** **** **** **** **** **** **** **** +6949 Vigilant_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6950 Vigilant_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6951 Vigilant_Protection_from_Elements **** **** **** **** **** **** **** **** +6952 Vigilant_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +6953 Vigilant_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +6954 Vigilant_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +6955 Vigilant_Snare **** **** **** **** **** **** **** **** +6956 Vigilant_Silent_Snare **** **** **** **** **** **** **** **** +6957 Vigilant_Still_Snare **** **** **** **** **** **** **** **** +6958 Vigilant_Silence **** **** **** **** **** **** **** **** +6959 Vigilant_Exteneded_Silence **** **** **** **** **** **** **** **** +6960 Vigilant_Silent_Silence **** **** **** **** **** **** **** **** +6961 Vigilant_Still_Silence **** **** **** **** **** **** **** **** +6962 Vigilant_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6963 Vigilant_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +6964 Vigilant_Endurance **** **** **** **** **** **** **** **** +6965 Vigilant_Exteneded_Endurance **** **** **** **** **** **** **** **** +6966 Vigilant_Silent_Endurance **** **** **** **** **** **** **** **** +6967 Vigilant_Still_Endurance **** **** **** **** **** **** **** **** +6968 Vigilant_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6969 Vigilant_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6970 Vigilant_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +6971 Vigilant_Neutralize_Poison **** **** **** **** **** **** **** **** +6972 Vigilant_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +6973 Vigilant_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +6974 Vigilant_Remove_Disease **** **** **** **** **** **** **** **** +6975 Vigilant_Silent_Remove_Disease **** **** **** **** **** **** **** **** +6976 Vigilant_Still_Remove_Disease **** **** **** **** **** **** **** **** +6977 Vigilant_Spike_Growth **** **** **** **** **** **** **** **** +6978 Vigilant_Exteneded_Spike_Growth **** **** **** **** **** **** **** **** +6979 Vigilant_Silent_Spike_Growth **** **** **** **** **** **** **** **** +6980 Vigilant_Still_Spike_Growth **** **** **** **** **** **** **** **** +6981 Vigilant_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +6982 Vigilant_Freedom_of_Movement **** **** **** **** **** **** **** **** +6983 Vigilant_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +6984 Vigilant_RepelVermin **** **** **** **** **** **** **** **** +6985 Vigilant_SUNMANTLE **** **** **** **** **** **** **** **** +6986 Vassal_Shield_of_Faith **** **** **** **** **** **** **** **** +6987 Vassal_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +6988 Vassal_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +6989 Vassal_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +6990 Vassal_Protection_from_Evil **** **** **** **** **** **** **** **** +6991 Vassal_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +6992 Vassal_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +6993 Vassal_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +6994 Vassal_Endure_Elements **** **** **** **** **** **** **** **** +6995 Vassal_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +6996 Vassal_Silent_Endure_Elements **** **** **** **** **** **** **** **** +6997 Vassal_Still_Endure_Elements **** **** **** **** **** **** **** **** +6998 Vassal_Divine_Favor **** **** **** **** **** **** **** **** +6999 Vassal_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +7000 Vassal_Silent_Divine_Favor **** **** **** **** **** **** **** **** +7001 Vassal_Still_Divine_Favor **** **** **** **** **** **** **** **** +7002 Vassal_Bless_Weapon **** **** **** **** **** **** **** **** +7003 Vassal_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +7004 Vassal_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +7005 Vassal_Still_Bless_Weapon **** **** **** **** **** **** **** **** +7006 Vassal_Bless **** **** **** **** **** **** **** **** +7007 Vassal_Exteneded_Bless **** **** **** **** **** **** **** **** +7008 Vassal_Silent_Bless **** **** **** **** **** **** **** **** +7009 Vassal_Still_Bless **** **** **** **** **** **** **** **** +7010 Vassal_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7011 Vassal_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7012 Vassal_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7013 Vassal_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7014 Vassal_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7015 Vassal_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7016 Vassal_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7017 Vassal_Protection_from_Elements **** **** **** **** **** **** **** **** +7018 Vassal_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +7019 Vassal_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +7020 Vassal_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +7021 Vassal_Bulls_Strength **** **** **** **** **** **** **** **** +7022 Vassal_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +7023 Vassal_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +7024 Vassal_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +7025 Vassal_Still_Bulls_Strength **** **** **** **** **** **** **** **** +7026 Vassal_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +7027 Vassal_Alter_Self_Learn **** **** **** **** **** **** **** **** +7028 Vassal_Alter_Self_Options **** **** **** **** **** **** **** **** +7029 Vassal_Alter_Self_QS1 **** **** **** **** **** **** **** **** +7030 Vassal_Alter_Self_QS2 **** **** **** **** **** **** **** **** +7031 Vassal_Alter_Self_QS3 **** **** **** **** **** **** **** **** +7032 Vassal_Exteneded_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +7033 Vassal_Exteneded_Alter_Self_Learn **** **** **** **** **** **** **** **** +7034 Vassal_Exteneded_Alter_Self_Options **** **** **** **** **** **** **** **** +7035 Vassal_Exteneded_Alter_Self_QS1 **** **** **** **** **** **** **** **** +7036 Vassal_Exteneded_Alter_Self_QS2 **** **** **** **** **** **** **** **** +7037 Vassal_Exteneded_Alter_Self_QS3 **** **** **** **** **** **** **** **** +7038 Vassal_Silent_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +7039 Vassal_Silent_Alter_Self_Learn **** **** **** **** **** **** **** **** +7040 Vassal_Silent_Alter_Self_Options **** **** **** **** **** **** **** **** +7041 Vassal_Silent_Alter_Self_QS1 **** **** **** **** **** **** **** **** +7042 Vassal_Silent_Alter_Self_QS2 **** **** **** **** **** **** **** **** +7043 Vassal_Silent_Alter_Self_QS3 **** **** **** **** **** **** **** **** +7044 Vassal_Still_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +7045 Vassal_Still_Alter_Self_Learn **** **** **** **** **** **** **** **** +7046 Vassal_Still_Alter_Self_Options **** **** **** **** **** **** **** **** +7047 Vassal_Still_Alter_Self_QS1 **** **** **** **** **** **** **** **** +7048 Vassal_Still_Alter_Self_QS2 **** **** **** **** **** **** **** **** +7049 Vassal_Still_Alter_Self_QS3 **** **** **** **** **** **** **** **** +7050 Vassal_Endurance **** **** **** **** **** **** **** **** +7051 Vassal_Empowered_Endurance **** **** **** **** **** **** **** **** +7052 Vassal_Exteneded_Endurance **** **** **** **** **** **** **** **** +7053 Vassal_Silent_Endurance **** **** **** **** **** **** **** **** +7054 Vassal_Still_Endurance **** **** **** **** **** **** **** **** +7055 Vassal_ShieldOther **** **** **** **** **** **** **** **** +7056 Vassal_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +7057 Vassal_Silent_ShieldOther **** **** **** **** **** **** **** **** +7058 Vassal_Still_ShieldOther **** **** **** **** **** **** **** **** +7059 Vassal_UndetectableAlignment **** **** **** **** **** **** **** **** +7060 Vassal_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +7061 Vassal_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +7062 Vassal_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +7063 Vassal_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7064 Vassal_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7065 Vassal_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7066 Vassal_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7067 Vassal_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7068 Vassal_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7069 Vassal_Searing_Light **** **** **** **** **** **** **** **** +7070 Vassal_Silent_Searing_Light **** **** **** **** **** **** **** **** +7071 Vassal_Still_Searing_Light **** **** **** **** **** **** **** **** +7072 Vassal_Resist_Elements **** **** **** **** **** **** **** **** +7073 Vassal_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +7074 Vassal_Silent_Resist_Elements **** **** **** **** **** **** **** **** +7075 Vassal_Still_Resist_Elements **** **** **** **** **** **** **** **** +7076 Vassal_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7077 Vassal_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7078 Vassal_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7079 Vassal_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7080 Vassal_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +7081 Vassal_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +7082 Vassal_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7083 Vassal_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7084 Vassal_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7085 Vassal_Holy_Sword **** **** **** **** **** **** **** **** +7086 Vassal_Divine_Power **** **** **** **** **** **** **** **** +7087 Vassal_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +7088 Vassal_SUNMANTLE **** **** **** **** **** **** **** **** +7089 Vassal_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7090 SublimeChord_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +7091 SublimeChord_Acid_Orb **** **** **** **** **** **** **** **** +7092 SublimeChord_ArcaneEye **** **** **** **** **** **** **** **** +7093 SublimeChord_Bestow_Curse **** **** **** **** **** **** **** **** +7094 SublimeChord_Blast_of_Flame **** **** **** **** **** **** **** **** +7095 SublimeChord_BreakEnchantment **** **** **** **** **** **** **** **** +7096 SublimeChord_Channeled_Pyroburst **** **** **** **** **** **** **** **** +7097 SublimeChord_Channeled_Pyroburst_Swift **** **** **** **** **** **** **** **** +7098 SublimeChord_Channeled_Pyroburst_Standard **** **** **** **** **** **** **** **** +7099 SublimeChord_Channeled_Pyroburst_Full **** **** **** **** **** **** **** **** +7100 SublimeChord_Channeled_Pyroburst_Two **** **** **** **** **** **** **** **** +7101 SublimeChord_Charm_Monster **** **** **** **** **** **** **** **** +7102 SublimeChord_Cold_Orb **** **** **** **** **** **** **** **** +7103 SublimeChord_Confusion **** **** **** **** **** **** **** **** +7104 SublimeChord_Contagion **** **** **** **** **** **** **** **** +7105 SublimeChord_CrushingDespair **** **** **** **** **** **** **** **** +7106 SublimeChord_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +7107 SublimeChord_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +7108 SublimeChord_DANCING_WEB **** **** **** **** **** **** **** **** +7109 SublimeChord_DetectScrying **** **** **** **** **** **** **** **** +7110 SublimeChord_Dimensional_Anchor **** **** **** **** **** **** **** **** +7111 SublimeChord_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +7112 SublimeChord_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +7113 SublimeChord_DimensionDoor_Party **** **** **** **** **** **** **** **** +7114 SublimeChord_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +7115 SublimeChord_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +7116 SublimeChord_Dismissal **** **** **** **** **** **** **** **** +7117 SublimeChord_Dominate_Person **** **** **** **** **** **** **** **** +7118 SublimeChord_Doom_Scarabs **** **** **** **** **** **** **** **** +7119 SublimeChord_Electric_Orb **** **** **** **** **** **** **** **** +7120 SublimeChord_Elemental_Shield **** **** **** **** **** **** **** **** +7121 SublimeChord_Enervation **** **** **** **** **** **** **** **** +7122 SublimeChord_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +7123 SublimeChord_Fear **** **** **** **** **** **** **** **** +7124 SublimeChord_Fire_Orb **** **** **** **** **** **** **** **** +7125 SublimeChord_FireTrap **** **** **** **** **** **** **** **** +7126 SublimeChord_Greater_Resistance **** **** **** **** **** **** **** **** +7127 SublimeChord_GRIM_REVENGE **** **** **** **** **** **** **** **** +7128 SublimeChord_Hold_Monster **** **** **** **** **** **** **** **** +7129 SublimeChord_Ilyykurs_Mantle **** **** **** **** **** **** **** **** +7130 SublimeChord_Improved_Invisibility **** **** **** **** **** **** **** **** +7131 SublimeChord_Isaacs_Lesser_Missile_Storm **** **** **** **** **** **** **** **** +7132 SublimeChord_Legend_Lore **** **** **** **** **** **** **** **** +7133 SublimeChord_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +7134 SublimeChord_LIQUID_PAIN **** **** **** **** **** **** **** **** +7135 SublimeChord_LocateCreature **** **** **** **** **** **** **** **** +7136 SublimeChord_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +7137 SublimeChord_MASS_ENLARGE_PERSON **** **** **** **** **** **** **** **** +7138 SublimeChord_MASS_REDUCE_PERSON **** **** **** **** **** **** **** **** +7139 SublimeChord_Mass_Ultravision **** **** **** **** **** **** **** **** +7140 SublimeChord_Minor_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +7141 SublimeChord_Necrotic_Domination **** **** **** **** **** **** **** **** +7142 SublimeChord_Neutralize_Poison **** **** **** **** **** **** **** **** +7143 SublimeChord_OrbOfForce **** **** **** **** **** **** **** **** +7144 SublimeChord_Otilukes_Resilient_Sphere **** **** **** **** **** **** **** **** +7145 SublimeChord_Phantasmal_Killer **** **** **** **** **** **** **** **** +7146 SublimeChord_PnP_FireShield **** **** **** **** **** **** **** **** +7147 SublimeChord_PnP_FireShieldRed **** **** **** **** **** **** **** **** +7148 SublimeChord_PnPFireShieldBlue **** **** **** **** **** **** **** **** +7149 SublimeChord_Polymorph_Self **** **** **** **** **** **** **** **** +7150 SublimeChord_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +7151 SublimeChord_Polymorph_TROLL **** **** **** **** **** **** **** **** +7152 SublimeChord_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +7153 SublimeChord_Polymorph_PIXIE **** **** **** **** **** **** **** **** +7154 SublimeChord_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +7155 SublimeChord_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +7156 SublimeChord_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7157 SublimeChord_Remove_Curse **** **** **** **** **** **** **** **** +7158 SublimeChord_RepelVermin **** **** **** **** **** **** **** **** +7159 SublimeChord_Scrying **** **** **** **** **** **** **** **** +7160 SublimeChord_SerpentArrows **** **** **** **** **** **** **** **** +7161 SublimeChord_Shadow_Conjuration **** **** **** **** **** **** **** **** +7162 SublimeChord_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +7163 SublimeChord_SHADOW_CON_Darkness **** **** **** **** **** **** **** **** +7164 SublimeChord_SHADOW_CON_Inivsibility **** **** **** **** **** **** **** **** +7165 SublimeChord_SHADOW_CON_Mage_Armor **** **** **** **** **** **** **** **** +7166 SublimeChord_SHADOW_CON_Magic_Missile **** **** **** **** **** **** **** **** +7167 SublimeChord_Shout **** **** **** **** **** **** **** **** +7168 SublimeChord_Sinsaburs_Baleful_Bolt **** **** **** **** **** **** **** **** +7169 SublimeChord_Slashing_Dispel **** **** **** **** **** **** **** **** +7170 SublimeChord_SolidFog **** **** **** **** **** **** **** **** +7171 SublimeChord_Sonic_Orb **** **** **** **** **** **** **** **** +7172 SublimeChord_Stoneskin **** **** **** **** **** **** **** **** +7173 SublimeChord_Summon_Creature_IV **** **** **** **** **** **** **** **** +7174 SublimeChord_SummonUndeadIV **** **** **** **** **** **** **** **** +7175 SublimeChord_Viscid_Glob **** **** **** **** **** **** **** **** +7176 SublimeChord_Wall_of_Fire **** **** **** **** **** **** **** **** +7177 SublimeChord_War_Cry **** **** **** **** **** **** **** **** +7178 SublimeChord_WRACK **** **** **** **** **** **** **** **** +7179 SublimeChord_Animate_Dead **** **** **** **** **** **** **** **** +7180 SublimeChord_BalefulPolymorph **** **** **** **** **** **** **** **** +7181 SublimeChord_Ball_Lightning **** **** **** **** **** **** **** **** +7182 SublimeChord_Beltyns_Burning_Blood **** **** **** **** **** **** **** **** +7183 SublimeChord_Bigbys_Interposing_Hand **** **** **** **** **** **** **** **** +7184 SublimeChord_CALL_DRETCH_HORDE **** **** **** **** **** **** **** **** +7185 SublimeChord_CALL_LEMURE_HORDE **** **** **** **** **** **** **** **** +7186 SublimeChord_Cloudkill **** **** **** **** **** **** **** **** +7187 SublimeChord_Cone_of_Cold **** **** **** **** **** **** **** **** +7188 SublimeChord_DraconicMight **** **** **** **** **** **** **** **** +7189 SublimeChord_Ethereal_Visage **** **** **** **** **** **** **** **** +7190 SublimeChord_Feeblemind **** **** **** **** **** **** **** **** +7191 SublimeChord_Firebrand **** **** **** **** **** **** **** **** +7192 SublimeChord_Greater_Dispelling **** **** **** **** **** **** **** **** +7193 SublimeChord_Greater_Fireburst **** **** **** **** **** **** **** **** +7194 SublimeChord_Greater_Heroism **** **** **** **** **** **** **** **** +7195 SublimeChord_Greater_Shadow_Conjuration **** **** **** **** **** **** **** **** +7196 SublimeChord_GR_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +7197 SublimeChord_GR_SHADOW_CON_Acid_Arrow **** **** **** **** **** **** **** **** +7198 SublimeChord_GR_SHADOW_CON_Ghostly_Visage **** **** **** **** **** **** **** **** +7199 SublimeChord_GR_SHADOW_CON_Web **** **** **** **** **** **** **** **** +7200 SublimeChord_GR_SHADOW_CON_Minor_Globe **** **** **** **** **** **** **** **** +7201 SublimeChord_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +7202 SublimeChord_Healing_Circle **** **** **** **** **** **** **** **** +7203 SublimeChord_Lesser_Mind_Blank **** **** **** **** **** **** **** **** +7204 SublimeChord_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +7205 SublimeChord_Lesser_Spell_Mantle **** **** **** **** **** **** **** **** +7206 SublimeChord_Magic_Missile **** **** **** **** **** **** **** **** +7207 SublimeChord_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7208 SublimeChord_MassFireShield **** **** **** **** **** **** **** **** +7209 SublimeChord_MassFireShieldRed **** **** **** **** **** **** **** **** +7210 SublimeChord_MassFireShieldBlue **** **** **** **** **** **** **** **** +7211 SublimeChord_Mestils_Acid_Sheath **** **** **** **** **** **** **** **** +7212 SublimeChord_Mind_Fog **** **** **** **** **** **** **** **** +7213 SublimeChord_Mislead **** **** **** **** **** **** **** **** +7214 SublimeChord_MORALITY_UNDONE **** **** **** **** **** **** **** **** +7215 SublimeChord_Necrotic_Burst **** **** **** **** **** **** **** **** +7216 SublimeChord_Nights_Caress **** **** **** **** **** **** **** **** +7217 SublimeChord_PrismaticRay **** **** **** **** **** **** **** **** +7218 SublimeChord_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +7219 SublimeChord_SongOfDiscord **** **** **** **** **** **** **** **** +7220 SublimeChord_Sonic_Shield **** **** **** **** **** **** **** **** +7221 SublimeChord_STOP_HEART **** **** **** **** **** **** **** **** +7222 SublimeChord_Summon_Creature_V **** **** **** **** **** **** **** **** +7223 SublimeChord_SummonUndeadV **** **** **** **** **** **** **** **** +7224 SublimeChord_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +7225 SublimeChord_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +7226 SublimeChord_Teleport_RadialMaster **** **** **** **** **** **** **** **** +7227 SublimeChord_Teleport_SelfOnly **** **** **** **** **** **** **** **** +7228 SublimeChord_Teleport_Party **** **** **** **** **** **** **** **** +7229 SublimeChord_WavesofFatigue **** **** **** **** **** **** **** **** +7230 SublimeChord_Acid_Fog **** **** **** **** **** **** **** **** +7231 SublimeChord_Acid_Storm **** **** **** **** **** **** **** **** +7232 SublimeChord_Animate_Object **** **** **** **** **** **** **** **** +7233 SublimeChord_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +7234 SublimeChord_Bigbys_Forceful_Hand **** **** **** **** **** **** **** **** +7235 SublimeChord_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +7236 SublimeChord_Chain_Lightning **** **** **** **** **** **** **** **** +7237 SublimeChord_Circle_of_Death **** **** **** **** **** **** **** **** +7238 SublimeChord_Dirge **** **** **** **** **** **** **** **** +7239 SublimeChord_Disintegrate **** **** **** **** **** **** **** **** +7240 SublimeChord_ECTOPLASMIC_ENCHANCEMENT **** **** **** **** **** **** **** **** +7241 SublimeChord_Energy_Buffer **** **** **** **** **** **** **** **** +7242 SublimeChord_ExtractWaterElemental **** **** **** **** **** **** **** **** +7243 SublimeChord_Eyebite **** **** **** **** **** **** **** **** +7244 SublimeChord_Flesh_to_stone **** **** **** **** **** **** **** **** +7245 SublimeChord_Ghoul_Gauntlet **** **** **** **** **** **** **** **** +7246 SublimeChord_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +7247 SublimeChord_Greater_Shout **** **** **** **** **** **** **** **** +7248 SublimeChord_Greater_Spell_Breach **** **** **** **** **** **** **** **** +7249 SublimeChord_Greater_Stoneskin **** **** **** **** **** **** **** **** +7250 SublimeChord_GreaterScrying **** **** **** **** **** **** **** **** +7251 SublimeChord_Ice_Storm **** **** **** **** **** **** **** **** +7252 SublimeChord_Isaacs_Greater_Missile_Storm **** **** **** **** **** **** **** **** +7253 SublimeChord_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +7254 SublimeChord_Mass_Cats_Grace **** **** **** **** **** **** **** **** +7255 SublimeChord_Mass_Contagion **** **** **** **** **** **** **** **** +7256 SublimeChord_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7257 SublimeChord_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +7258 SublimeChord_Mass_Endurance **** **** **** **** **** **** **** **** +7259 SublimeChord_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +7260 SublimeChord_Mass_Haste **** **** **** **** **** **** **** **** +7261 SublimeChord_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +7262 SublimeChord_Necrotic_Eruption **** **** **** **** **** **** **** **** +7263 SublimeChord_OtilukesFreezingSphere **** **** **** **** **** **** **** **** +7264 SublimeChord_Planar_Binding **** **** **** **** **** **** **** **** +7265 SublimeChord_Repulsion **** **** **** **** **** **** **** **** +7266 SublimeChord_Shades **** **** **** **** **** **** **** **** +7267 SublimeChord_SHADES_Summon_Shadow **** **** **** **** **** **** **** **** +7268 SublimeChord_SHADES_Cone_of_Cold **** **** **** **** **** **** **** **** +7269 SublimeChord_SHADES_Fireball **** **** **** **** **** **** **** **** +7270 SublimeChord_SHADES_Stoneskin **** **** **** **** **** **** **** **** +7271 SublimeChord_SHADES_Wall_of_Fire **** **** **** **** **** **** **** **** +7272 SublimeChord_STARMANTLE **** **** **** **** **** **** **** **** +7273 SublimeChord_Stone_to_flesh **** **** **** **** **** **** **** **** +7274 SublimeChord_Summon_Creature_VI **** **** **** **** **** **** **** **** +7275 SublimeChord_Superior_Resistance **** **** **** **** **** **** **** **** +7276 SublimeChord_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +7277 SublimeChord_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +7278 SublimeChord_Tensers_Transformation **** **** **** **** **** **** **** **** +7279 SublimeChord_True_Seeing **** **** **** **** **** **** **** **** +7280 SublimeChord_Undeath_to_Death **** **** **** **** **** **** **** **** +7281 SublimeChord_WAVE_OF_PAIN **** **** **** **** **** **** **** **** +7282 SublimeChord_AMBER_SARCOPHAGUS **** **** **** **** **** **** **** **** +7283 SublimeChord_ArrowOfBone **** **** **** **** **** **** **** **** +7284 SublimeChord_Avasculate **** **** **** **** **** **** **** **** +7285 SublimeChord_Banishment **** **** **** **** **** **** **** **** +7286 SublimeChord_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +7287 SublimeChord_Control_Undead **** **** **** **** **** **** **** **** +7288 SublimeChord_Control_Weather **** **** **** **** **** **** **** **** +7289 SublimeChord_CW_Rain **** **** **** **** **** **** **** **** +7290 SublimeChord_CW_Snow **** **** **** **** **** **** **** **** +7291 SublimeChord_CW_Clear **** **** **** **** **** **** **** **** +7292 SublimeChord_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +7293 SublimeChord_DRAGON_ALLY **** **** **** **** **** **** **** **** +7294 SublimeChord_Energy_Ebb **** **** **** **** **** **** **** **** +7295 SublimeChord_Energy_Immunity **** **** **** **** **** **** **** **** +7296 SublimeChord_EI_Acid **** **** **** **** **** **** **** **** +7297 SublimeChord_EI_Cold **** **** **** **** **** **** **** **** +7298 SublimeChord_EI_Elec **** **** **** **** **** **** **** **** +7299 SublimeChord_EI_Fire **** **** **** **** **** **** **** **** +7300 SublimeChord_EI_Sonic **** **** **** **** **** **** **** **** +7301 SublimeChord_EYE_OF_THE_BEHOLDER **** **** **** **** **** **** **** **** +7302 SublimeChord_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +7303 SublimeChord_Finger_of_Death **** **** **** **** **** **** **** **** +7304 SublimeChord_Great_Thunderclap **** **** **** **** **** **** **** **** +7305 SublimeChord_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +7306 SublimeChord_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +7307 SublimeChord_GreaterTeleport_Party **** **** **** **** **** **** **** **** +7308 SublimeChord_Insanity **** **** **** **** **** **** **** **** +7309 SublimeChord_Mass_Hold_Person **** **** **** **** **** **** **** **** +7310 SublimeChord_Mordenkainens_Sword **** **** **** **** **** **** **** **** +7311 SublimeChord_Mords_Mansion **** **** **** **** **** **** **** **** +7312 SublimeChord_Nybors_Stern_Reproof **** **** **** **** **** **** **** **** +7313 SublimeChord_Power_Word_Blind **** **** **** **** **** **** **** **** +7314 SublimeChord_Power_Word_Stun **** **** **** **** **** **** **** **** +7315 SublimeChord_Prismatic_Spray **** **** **** **** **** **** **** **** +7316 SublimeChord_Protection_from_Spells **** **** **** **** **** **** **** **** +7317 SublimeChord_Sequester **** **** **** **** **** **** **** **** +7318 SublimeChord_Shadow_Shield **** **** **** **** **** **** **** **** +7319 SublimeChord_Spell_Mantle **** **** **** **** **** **** **** **** +7320 SublimeChord_Spell_Turning **** **** **** **** **** **** **** **** +7321 SublimeChord_Summon_Creature_VII **** **** **** **** **** **** **** **** +7322 SublimeChord_Summon7Air **** **** **** **** **** **** **** **** +7323 SublimeChord_Summon7Earth **** **** **** **** **** **** **** **** +7324 SublimeChord_Summon7Fire **** **** **** **** **** **** **** **** +7325 SublimeChord_Summon7Water **** **** **** **** **** **** **** **** +7326 SublimeChord_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +7327 SublimeChord_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +7328 SublimeChord_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +7329 SublimeChord_WavesOfExhaustion **** **** **** **** **** **** **** **** +7330 SublimeChord_Avascular_Mass **** **** **** **** **** **** **** **** +7331 SublimeChord_Bigbys_Clenched_Fist **** **** **** **** **** **** **** **** +7332 SublimeChord_Blackstaff **** **** **** **** **** **** **** **** +7333 SublimeChord_Create_Undead **** **** **** **** **** **** **** **** +7334 SublimeChord_Dimensional_Lock **** **** **** **** **** **** **** **** +7335 SublimeChord_DiscernLocation **** **** **** **** **** **** **** **** +7336 SublimeChord_Etherealness **** **** **** **** **** **** **** **** +7337 SublimeChord_Flensing **** **** **** **** **** **** **** **** +7338 SublimeChord_Greater_Planar_Binding **** **** **** **** **** **** **** **** +7339 SublimeChord_GUTWRENCH **** **** **** **** **** **** **** **** +7340 SublimeChord_Horrid_Wilting **** **** **** **** **** **** **** **** +7341 SublimeChord_Incendiary_Cloud **** **** **** **** **** **** **** **** +7342 SublimeChord_IRON_BODY **** **** **** **** **** **** **** **** +7343 SublimeChord_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +7344 SublimeChord_Mantle_of_Eg_Might **** **** **** **** **** **** **** **** +7345 SublimeChord_Mass_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7346 SublimeChord_Mass_Charm **** **** **** **** **** **** **** **** +7347 SublimeChord_Maze **** **** **** **** **** **** **** **** +7348 SublimeChord_Mind_Blank **** **** **** **** **** **** **** **** +7349 SublimeChord_Necrotic_Empowerment **** **** **** **** **** **** **** **** +7350 SublimeChord_PolarRay **** **** **** **** **** **** **** **** +7351 SublimeChord_Premonition **** **** **** **** **** **** **** **** +7352 SublimeChord_PrismaticWall **** **** **** **** **** **** **** **** +7353 SublimeChord_ScintillatingPattern **** **** **** **** **** **** **** **** +7354 SublimeChord_Summon_Creature_VIII **** **** **** **** **** **** **** **** +7355 SublimeChord_Summon8Air **** **** **** **** **** **** **** **** +7356 SublimeChord_Summon8Earth **** **** **** **** **** **** **** **** +7357 SublimeChord_Summon8Fire **** **** **** **** **** **** **** **** +7358 SublimeChord_Summon8Water **** **** **** **** **** **** **** **** +7359 SublimeChord_Sunburst **** **** **** **** **** **** **** **** +7360 SublimeChord_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +7361 SublimeChord_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +7362 SublimeChord_Bigbys_Crushing_Hand **** **** **** **** **** **** **** **** +7363 SublimeChord_Black_Blade_of_Disaster **** **** **** **** **** **** **** **** +7364 SublimeChord_BLINDING_GLORY **** **** **** **** **** **** **** **** +7365 SublimeChord_CRUSHING_FIST_OF_SPITE **** **** **** **** **** **** **** **** +7366 SublimeChord_Dominate_Monster **** **** **** **** **** **** **** **** +7367 SublimeChord_Energy_Drain **** **** **** **** **** **** **** **** +7368 SublimeChord_Foresight **** **** **** **** **** **** **** **** +7369 SublimeChord_Gate **** **** **** **** **** **** **** **** +7370 SublimeChord_Greater_Spell_Mantle **** **** **** **** **** **** **** **** +7371 SublimeChord_Mass_Hold_Monster **** **** **** **** **** **** **** **** +7372 SublimeChord_Meteor_Swarm **** **** **** **** **** **** **** **** +7373 SublimeChord_Mordenkainens_Disjunction **** **** **** **** **** **** **** **** +7374 SublimeChord_Necrotic_Termination **** **** **** **** **** **** **** **** +7375 SublimeChord_PlagueOfUndead **** **** **** **** **** **** **** **** +7376 SublimeChord_Power_Word_Kill **** **** **** **** **** **** **** **** +7377 SublimeChord_PrismaticSphere **** **** **** **** **** **** **** **** +7378 SublimeChord_Shapechange **** **** **** **** **** **** **** **** +7379 SublimeChord_Shapechange_RED_DRAGON **** **** **** **** **** **** **** **** +7380 SublimeChord_Shapechange_FIRE_GIANT **** **** **** **** **** **** **** **** +7381 SublimeChord_Shapechange_BALOR **** **** **** **** **** **** **** **** +7382 SublimeChord_Shapechange_DEATH_SLAAD **** **** **** **** **** **** **** **** +7383 SublimeChord_Shapechange_IRON_GOLEM **** **** **** **** **** **** **** **** +7384 SublimeChord_Sphere_of_Ultimate_Destruction **** **** **** **** **** **** **** **** +7385 SublimeChord_Summon_Creature_IX **** **** **** **** **** **** **** **** +7386 SublimeChord_Summon9Air **** **** **** **** **** **** **** **** +7387 SublimeChord_Summon9Earth **** **** **** **** **** **** **** **** +7388 SublimeChord_Summon9Fire **** **** **** **** **** **** **** **** +7389 SublimeChord_Summon9Water **** **** **** **** **** **** **** **** +7390 SublimeChord_TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +7391 SublimeChord_TeleportationCircle_Visible **** **** **** **** **** **** **** **** +7392 SublimeChord_TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +7393 SublimeChord_Time_Stop **** **** **** **** **** **** **** **** +7394 SublimeChord_UTTERDARK **** **** **** **** **** **** **** **** +7395 SublimeChord_VileDeath **** **** **** **** **** **** **** **** +7396 SublimeChord_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +7397 SublimeChord_Weird **** **** **** **** **** **** **** **** +7398 KnightoftheWeave_Bless **** **** **** **** **** **** **** **** +7399 KnightoftheWeave_Bless_Weapon **** **** **** **** **** **** **** **** +7400 KnightoftheWeave_Charm_Person **** **** **** **** **** **** **** **** +7401 KnightoftheWeave_Command_RadialMaster **** **** **** **** **** **** **** **** +7402 KnightoftheWeave_Command_Approach **** **** **** **** **** **** **** **** +7403 KnightoftheWeave_Command_Drop **** **** **** **** **** **** **** **** +7404 KnightoftheWeave_Command_Fall **** **** **** **** **** **** **** **** +7405 KnightoftheWeave_Command_Flee **** **** **** **** **** **** **** **** +7406 KnightoftheWeave_Command_Halt **** **** **** **** **** **** **** **** +7407 KnightoftheWeave_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7408 KnightoftheWeave_Divine_Favor **** **** **** **** **** **** **** **** +7409 KnightoftheWeave_Lesser_Restoration **** **** **** **** **** **** **** **** +7410 KnightoftheWeave_Mage_Armor **** **** **** **** **** **** **** **** +7411 KnightoftheWeave_Magic_Missile **** **** **** **** **** **** **** **** +7412 KnightoftheWeave_Magic_Weapon **** **** **** **** **** **** **** **** +7413 KnightoftheWeave_Read_Magic **** **** **** **** **** **** **** **** +7414 KnightoftheWeave_Shield **** **** **** **** **** **** **** **** +7415 KnightoftheWeave_Bulls_Strength **** **** **** **** **** **** **** **** +7416 KnightoftheWeave_Cats_Grace **** **** **** **** **** **** **** **** +7417 KnightoftheWeave_Endurance **** **** **** **** **** **** **** **** +7418 KnightoftheWeave_Ultravision **** **** **** **** **** **** **** **** +7419 KnightoftheWeave_Eagle_Splendor **** **** **** **** **** **** **** **** +7420 KnightoftheWeave_Resist_Elements **** **** **** **** **** **** **** **** +7421 KnightoftheWeave_See_Invisibility **** **** **** **** **** **** **** **** +7422 KnightoftheWeave_ShieldOther **** **** **** **** **** **** **** **** +7423 KnightoftheWeave_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7424 KnightoftheWeave_Daylight **** **** **** **** **** **** **** **** +7425 KnightoftheWeave_Dispel_Magic **** **** **** **** **** **** **** **** +7426 KnightoftheWeave_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7427 KnightoftheWeave_Remove_Curse **** **** **** **** **** **** **** **** +7428 KnightoftheWeave_BreakEnchantment **** **** **** **** **** **** **** **** +7429 KnightoftheWeave_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +7430 KnightoftheWeave_Death_Ward **** **** **** **** **** **** **** **** +7431 KnightoftheWeave_Minor_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +7432 KnightoftheWeave_Neutralize_Poison **** **** **** **** **** **** **** **** +7433 KnightoftheWeave_Restoration **** **** **** **** **** **** **** **** +7434 KnightoftheWeave_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +7435 KnightoftheWeave_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +7436 KnightoftheWeave_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +7437 KnightoftheWeave_DimensionDoor_Party **** **** **** **** **** **** **** **** +7438 KnightoftheWeave_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +7439 KnightoftheWeave_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +7440 KnightoftheWeave_Spell_Resistance **** **** **** **** **** **** **** **** +7441 KnightoftheWeave_True_Seeing **** **** **** **** **** **** **** **** +7442 KnightoftheWeave_Banishment **** **** **** **** **** **** **** **** +7443 KnightoftheWeave_Greater_Dispelling **** **** **** **** **** **** **** **** +7444 KnightoftheWeave_Teleport_RadialMaster **** **** **** **** **** **** **** **** +7445 KnightoftheWeave_Teleport_SelfOnly **** **** **** **** **** **** **** **** +7446 KnightoftheWeave_Teleport_Party **** **** **** **** **** **** **** **** +7447 Anti_Paladin_Bane **** **** **** **** **** **** **** **** +7448 Anti_Paladin_Exteneded_Bane **** **** **** **** **** **** **** **** +7449 Anti_Paladin_Silent_Bane **** **** **** **** **** **** **** **** +7450 Anti_Paladin_Still_Bane **** **** **** **** **** **** **** **** +7451 Anti_Paladin_Cause_Fear **** **** **** **** **** **** **** **** +7452 Anti_Paladin_Exteneded_Cause_Fear **** **** **** **** **** **** **** **** +7453 Anti_Paladin_Still_Cause_Fear **** **** **** **** **** **** **** **** +7454 Anti_Paladin_Curse_Water **** **** **** **** **** **** **** **** +7455 Anti_Paladin_Silent_Curse_Water **** **** **** **** **** **** **** **** +7456 Anti_Paladin_Still_Curse_Water **** **** **** **** **** **** **** **** +7457 Anti_Paladin_Doom **** **** **** **** **** **** **** **** +7458 Anti_Paladin_Exteneded_Doom **** **** **** **** **** **** **** **** +7459 Anti_Paladin_Silent_Doom **** **** **** **** **** **** **** **** +7460 Anti_Paladin_Still_Doom **** **** **** **** **** **** **** **** +7461 Anti_Paladin_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7462 Anti_Paladin_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7463 Anti_Paladin_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7464 Anti_Paladin_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7465 Anti_Paladin_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7466 Anti_Paladin_Magic_Weapon **** **** **** **** **** **** **** **** +7467 Anti_Paladin_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +7468 Anti_Paladin_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +7469 Anti_Paladin_Still_Magic_Weapon **** **** **** **** **** **** **** **** +7470 Anti_Paladin_Protection_from_Good **** **** **** **** **** **** **** **** +7471 Anti_Paladin_Exteneded_Protection_from_Good **** **** **** **** **** **** **** **** +7472 Anti_Paladin_Silent_Protection_from_Good **** **** **** **** **** **** **** **** +7473 Anti_Paladin_Still_Protection_from_Good **** **** **** **** **** **** **** **** +7474 Anti_Paladin_Protection_from_Law **** **** **** **** **** **** **** **** +7475 Anti_Paladin_Exteneded_Protection_from_Law **** **** **** **** **** **** **** **** +7476 Anti_Paladin_Silent_Protection_from_Law **** **** **** **** **** **** **** **** +7477 Anti_Paladin_Still_Protection_from_Law **** **** **** **** **** **** **** **** +7478 Anti_Paladin_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7479 Anti_Paladin_Empowered_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7480 Anti_Paladin_Exteneded_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7481 Anti_Paladin_Maximized_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7482 Anti_Paladin_Silent_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7483 Anti_Paladin_Still_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7484 Anti_Paladin_Read_Magic **** **** **** **** **** **** **** **** +7485 Anti_Paladin_Silent_Read_Magic **** **** **** **** **** **** **** **** +7486 Anti_Paladin_Still_Read_Magic **** **** **** **** **** **** **** **** +7487 Anti_Paladin_Summon_Creature_I **** **** **** **** **** **** **** **** +7488 Anti_Paladin_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +7489 Anti_Paladin_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +7490 Anti_Paladin_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +7491 Anti_Paladin_ANGRY_ACHE **** **** **** **** **** **** **** **** +7492 Anti_Paladin_Exteneded_ANGRY_ACHE **** **** **** **** **** **** **** **** +7493 Anti_Paladin_Silent_ANGRY_ACHE **** **** **** **** **** **** **** **** +7494 Anti_Paladin_Still_ANGRY_ACHE **** **** **** **** **** **** **** **** +7495 Anti_Paladin_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7496 Anti_Paladin_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7497 Anti_Paladin_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7498 Anti_Paladin_Bulls_Strength **** **** **** **** **** **** **** **** +7499 Anti_Paladin_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +7500 Anti_Paladin_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +7501 Anti_Paladin_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +7502 Anti_Paladin_Still_Bulls_Strength **** **** **** **** **** **** **** **** +7503 Anti_Paladin_Darkness **** **** **** **** **** **** **** **** +7504 Anti_Paladin_Exteneded_Darkness **** **** **** **** **** **** **** **** +7505 Anti_Paladin_Silent_Darkness **** **** **** **** **** **** **** **** +7506 Anti_Paladin_Summon_Creature_II **** **** **** **** **** **** **** **** +7507 Anti_Paladin_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +7508 Anti_Paladin_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +7509 Anti_Paladin_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +7510 Anti_Paladin_UndetectableAlignment **** **** **** **** **** **** **** **** +7511 Anti_Paladin_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +7512 Anti_Paladin_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +7513 Anti_Paladin_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +7514 Anti_Paladin_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7515 Anti_Paladin_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7516 Anti_Paladin_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7517 Anti_Paladin_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7518 Anti_Paladin_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7519 Anti_Paladin_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7520 Anti_Paladin_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7521 Anti_Paladin_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +7522 Anti_Paladin_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +7523 Anti_Paladin_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +7524 Anti_Paladin_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +7525 Anti_Paladin_Exteneded_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +7526 Anti_Paladin_Silent_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +7527 Anti_Paladin_Still_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +7528 Anti_Paladin_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +7529 Anti_Paladin_Exteneded_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +7530 Anti_Paladin_Silent_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +7531 Anti_Paladin_Still_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +7532 Anti_Paladin_Summon_Creature_III **** **** **** **** **** **** **** **** +7533 Anti_Paladin_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +7534 Anti_Paladin_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +7535 Anti_Paladin_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +7536 Anti_Paladin_Bestow_Curse **** **** **** **** **** **** **** **** +7537 Anti_Paladin_Silent_Bestow_Curse **** **** **** **** **** **** **** **** +7538 Anti_Paladin_Still_Bestow_Curse **** **** **** **** **** **** **** **** +7539 Anti_Paladin_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7540 Anti_Paladin_Exteneded_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7541 Anti_Paladin_Silent_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7542 Anti_Paladin_DeeperDarkness **** **** **** **** **** **** **** **** +7543 Anti_Paladin_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +7544 Anti_Paladin_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +7545 Anti_Paladin_RED_FESTER **** **** **** **** **** **** **** **** +7546 Anti_Paladin_Silent_RED_FESTER **** **** **** **** **** **** **** **** +7547 Anti_Paladin_Still_RED_FESTER **** **** **** **** **** **** **** **** +7548 Anti_Paladin_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +7549 Anti_Paladin_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +7550 Anti_Paladin_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +7551 Anti_Paladin_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +7552 Anti_Paladin_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +7553 Anti_Paladin_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +7554 Anti_Paladin_MASOCHISM **** **** **** **** **** **** **** **** +7555 Anti_Paladin_Exteneded_MASOCHISM **** **** **** **** **** **** **** **** +7556 Anti_Paladin_Death_Ward **** **** **** **** **** **** **** **** +7557 Anti_Paladin_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +7558 Anti_Paladin_Fear **** **** **** **** **** **** **** **** +7559 Anti_Paladin_Poison **** **** **** **** **** **** **** **** +7560 Anti_Paladin_Unholy_Sword **** **** **** **** **** **** **** **** +7561 Anti_Paladin_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +7562 Soldier_of_Light_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7563 Soldier_of_Light_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7564 Soldier_of_Light_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7565 Soldier_of_Light_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7566 Soldier_of_Light_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7567 Soldier_of_Light_Bless_Water **** **** **** **** **** **** **** **** +7568 Soldier_of_Light_Silent_Bless_Water **** **** **** **** **** **** **** **** +7569 Soldier_of_Light_Still_Bless_Water **** **** **** **** **** **** **** **** +7570 Soldier_of_Light_Bless_Weapon **** **** **** **** **** **** **** **** +7571 Soldier_of_Light_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +7572 Soldier_of_Light_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +7573 Soldier_of_Light_Still_Bless_Weapon **** **** **** **** **** **** **** **** +7574 Soldier_of_Light_Bless **** **** **** **** **** **** **** **** +7575 Soldier_of_Light_Exteneded_Bless **** **** **** **** **** **** **** **** +7576 Soldier_of_Light_Silent_Bless **** **** **** **** **** **** **** **** +7577 Soldier_of_Light_Still_Bless **** **** **** **** **** **** **** **** +7578 Soldier_of_Light_Detect_Evil **** **** **** **** **** **** **** **** +7579 Soldier_of_Light_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +7580 Soldier_of_Light_Silent_Detect_Evil **** **** **** **** **** **** **** **** +7581 Soldier_of_Light_Still_Detect_Evil **** **** **** **** **** **** **** **** +7582 Soldier_of_Light_HideFromUndead **** **** **** **** **** **** **** **** +7583 Soldier_of_Light_Exteneded_HideFromUndead **** **** **** **** **** **** **** **** +7584 Soldier_of_Light_Still_HideFromUndead **** **** **** **** **** **** **** **** +7585 Soldier_of_Light_Magic_Weapon **** **** **** **** **** **** **** **** +7586 Soldier_of_Light_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +7587 Soldier_of_Light_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +7588 Soldier_of_Light_Still_Magic_Weapon **** **** **** **** **** **** **** **** +7589 Soldier_of_Light_Shield_of_Faith **** **** **** **** **** **** **** **** +7590 Soldier_of_Light_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +7591 Soldier_of_Light_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +7592 Soldier_of_Light_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +7593 Soldier_of_Light_Protection_from_Evil **** **** **** **** **** **** **** **** +7594 Soldier_of_Light_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +7595 Soldier_of_Light_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +7596 Soldier_of_Light_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +7597 Soldier_of_Light_Light **** **** **** **** **** **** **** **** +7598 Soldier_of_Light_Exteneded_Light **** **** **** **** **** **** **** **** +7599 Soldier_of_Light_Silent_Light **** **** **** **** **** **** **** **** +7600 Soldier_of_Light_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7601 Soldier_of_Light_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7602 Soldier_of_Light_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7603 Soldier_of_Light_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7604 Soldier_of_Light_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7605 Soldier_of_Light_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7606 Soldier_of_Light_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7607 Soldier_of_Light_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7608 Soldier_of_Light_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7609 Soldier_of_Light_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7610 Soldier_of_Light_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7611 Soldier_of_Light_Aid **** **** **** **** **** **** **** **** +7612 Soldier_of_Light_Empowered_Aid **** **** **** **** **** **** **** **** +7613 Soldier_of_Light_Exteneded_Aid **** **** **** **** **** **** **** **** +7614 Soldier_of_Light_Silent_Aid **** **** **** **** **** **** **** **** +7615 Soldier_of_Light_Still_Aid **** **** **** **** **** **** **** **** +7616 Soldier_of_Light_Consecrated_Aura **** **** **** **** **** **** **** **** +7617 Soldier_of_Light_Exteneded_Consecrated_Aura **** **** **** **** **** **** **** **** +7618 Soldier_of_Light_Silent_Consecrated_Aura **** **** **** **** **** **** **** **** +7619 Soldier_of_Light_Still_Consecrated_Aura **** **** **** **** **** **** **** **** +7620 Soldier_of_Light_Daylight **** **** **** **** **** **** **** **** +7621 Soldier_of_Light_Exteneded_Daylight **** **** **** **** **** **** **** **** +7622 Soldier_of_Light_Silent_Daylight **** **** **** **** **** **** **** **** +7623 Soldier_of_Light_Still_Daylight **** **** **** **** **** **** **** **** +7624 Soldier_of_Light_Lesser_Restoration **** **** **** **** **** **** **** **** +7625 Soldier_of_Light_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +7626 Soldier_of_Light_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +7627 Soldier_of_Light_ShieldOther **** **** **** **** **** **** **** **** +7628 Soldier_of_Light_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +7629 Soldier_of_Light_Silent_ShieldOther **** **** **** **** **** **** **** **** +7630 Soldier_of_Light_Still_ShieldOther **** **** **** **** **** **** **** **** +7631 Soldier_of_Light_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7632 Soldier_of_Light_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7633 Soldier_of_Light_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7634 Soldier_of_Light_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7635 Soldier_of_Light_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7636 Soldier_of_Light_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7637 Soldier_of_Light_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +7638 Soldier_of_Light_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +7639 Soldier_of_Light_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +7640 Soldier_of_Light_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7641 Soldier_of_Light_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7642 Soldier_of_Light_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7643 Soldier_of_Light_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7644 Soldier_of_Light_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7645 Soldier_of_Light_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7646 Soldier_of_Light_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7647 Soldier_of_Light_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7648 Soldier_of_Light_Searing_Light **** **** **** **** **** **** **** **** +7649 Soldier_of_Light_Silent_Searing_Light **** **** **** **** **** **** **** **** +7650 Soldier_of_Light_Still_Searing_Light **** **** **** **** **** **** **** **** +7651 Soldier_of_Light_Negative_Energy_Protection **** **** **** **** **** **** **** **** +7652 Soldier_of_Light_Exteneded_Negative_Energy_Protection **** **** **** **** **** **** **** **** +7653 Soldier_of_Light_Silent_Negative_Energy_Protection **** **** **** **** **** **** **** **** +7654 Soldier_of_Light_Still_Negative_Energy_Protection **** **** **** **** **** **** **** **** +7655 Soldier_of_Light_Prayer **** **** **** **** **** **** **** **** +7656 Soldier_of_Light_Exteneded_Prayer **** **** **** **** **** **** **** **** +7657 Soldier_of_Light_Silent_Prayer **** **** **** **** **** **** **** **** +7658 Soldier_of_Light_Still_Prayer **** **** **** **** **** **** **** **** +7659 Soldier_of_Light_Remove_Disease **** **** **** **** **** **** **** **** +7660 Soldier_of_Light_Silent_Remove_Disease **** **** **** **** **** **** **** **** +7661 Soldier_of_Light_Still_Remove_Disease **** **** **** **** **** **** **** **** +7662 Soldier_of_Light_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +7663 Soldier_of_Light_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +7664 Soldier_of_Light_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7665 Soldier_of_Light_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7666 Soldier_of_Light_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7667 Soldier_of_Light_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +7668 Soldier_of_Light_Death_Ward **** **** **** **** **** **** **** **** +7669 Soldier_of_Light_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +7670 Soldier_of_Light_Holy_Sword **** **** **** **** **** **** **** **** +7671 Soldier_of_Light_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +7672 Soldier_of_Light_Restoration **** **** **** **** **** **** **** **** +7673 Soldier_of_Light_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +7674 Soldier_of_Light_SUNMANTLE **** **** **** **** **** **** **** **** +7675 Soldier_of_Light_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7676 Telflammar_Shadow_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7677 Telflammar_Shadow_Exteneded_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7678 Telflammar_Shadow_Silent_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7679 Telflammar_Shadow_Ultravision **** **** **** **** **** **** **** **** +7680 Telflammar_Shadow_Exteneded_Ultravision **** **** **** **** **** **** **** **** +7681 Telflammar_Shadow_Silent_Ultravision **** **** **** **** **** **** **** **** +7682 Telflammar_Shadow_Still_Ultravision **** **** **** **** **** **** **** **** +7683 Telflammar_Shadow_Chill_Touch **** **** **** **** **** **** **** **** +7684 Telflammar_Shadow_Empowered_Chill_Touch **** **** **** **** **** **** **** **** +7685 Telflammar_Shadow_Exteneded_Chill_Touch **** **** **** **** **** **** **** **** +7686 Telflammar_Shadow_Silent_Chill_Touch **** **** **** **** **** **** **** **** +7687 Telflammar_Shadow_Still_Chill_Touch **** **** **** **** **** **** **** **** +7688 Telflammar_Shadow_Darkness **** **** **** **** **** **** **** **** +7689 Telflammar_Shadow_Exteneded_Darkness **** **** **** **** **** **** **** **** +7690 Telflammar_Shadow_Silent_Darkness **** **** **** **** **** **** **** **** +7691 Telflammar_Shadow_Shadow_Spray **** **** **** **** **** **** **** **** +7692 Telflammar_Shadow_Empowered_Shadow_Spray **** **** **** **** **** **** **** **** +7693 Telflammar_Shadow_Exteneded_Shadow_Spray **** **** **** **** **** **** **** **** +7694 Telflammar_Shadow_Silent_Shadow_Spray **** **** **** **** **** **** **** **** +7695 Telflammar_Shadow_Still_Shadow_Spray **** **** **** **** **** **** **** **** +7696 Telflammar_Shadow_Invisibility **** **** **** **** **** **** **** **** +7697 Telflammar_Shadow_Exteneded_Invisibility **** **** **** **** **** **** **** **** +7698 Telflammar_Shadow_Silent_Invisibility **** **** **** **** **** **** **** **** +7699 Telflammar_Shadow_Still_Invisibility **** **** **** **** **** **** **** **** +7700 Telflammar_Shadow_Knock **** **** **** **** **** **** **** **** +7701 Telflammar_Shadow_Still_Knock **** **** **** **** **** **** **** **** +7702 Telflammar_Shadow_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7703 Telflammar_Shadow_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7704 Telflammar_Shadow_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +7705 Telflammar_Shadow_Blacklight **** **** **** **** **** **** **** **** +7706 Telflammar_Shadow_Exteneded_Blacklight **** **** **** **** **** **** **** **** +7707 Telflammar_Shadow_Silent_Blacklight **** **** **** **** **** **** **** **** +7708 Telflammar_Shadow_Still_Blacklight **** **** **** **** **** **** **** **** +7709 Telflammar_Shadow_Displacement **** **** **** **** **** **** **** **** +7710 Telflammar_Shadow_Exteneded_Displacement **** **** **** **** **** **** **** **** +7711 Telflammar_Shadow_Silent_Displacement **** **** **** **** **** **** **** **** +7712 Telflammar_Shadow_Haste **** **** **** **** **** **** **** **** +7713 Telflammar_Shadow_Exteneded_Haste **** **** **** **** **** **** **** **** +7714 Telflammar_Shadow_Silent_Haste **** **** **** **** **** **** **** **** +7715 Telflammar_Shadow_Still_Haste **** **** **** **** **** **** **** **** +7716 Telflammar_Shadow_Improved_Invisibility **** **** **** **** **** **** **** **** +7717 Telflammar_Shadow_Exteneded_Improved_Invisibility **** **** **** **** **** **** **** **** +7718 Telflammar_Shadow_Silent_Improved_Invisibility **** **** **** **** **** **** **** **** +7719 Telflammar_Shadow_Still_Improved_Invisibility **** **** **** **** **** **** **** **** +7720 Telflammar_Shadow_Vampiric_Touch **** **** **** **** **** **** **** **** +7721 Telflammar_Shadow_Silent_Vampiric_Touch **** **** **** **** **** **** **** **** +7722 Telflammar_Shadow_Still_Vampiric_Touch **** **** **** **** **** **** **** **** +7723 Telflammar_Shadow_NONDETECTION **** **** **** **** **** **** **** **** +7724 Telflammar_Shadow_Exteneded_NONDETECTION **** **** **** **** **** **** **** **** +7725 Telflammar_Shadow_Silent_NONDETECTION **** **** **** **** **** **** **** **** +7726 Telflammar_Shadow_Still_NONDETECTION **** **** **** **** **** **** **** **** +7727 Telflammar_Shadow_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7728 Telflammar_Shadow_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7729 Telflammar_Shadow_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +7730 Telflammar_Shadow_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +7731 Telflammar_Shadow_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +7732 Telflammar_Shadow_DimensionDoor_Party **** **** **** **** **** **** **** **** +7733 Telflammar_Shadow_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +7734 Telflammar_Shadow_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +7735 Telflammar_Shadow_Confusion **** **** **** **** **** **** **** **** +7736 Telflammar_Shadow_DarkBolt **** **** **** **** **** **** **** **** +7737 Telflammar_Shadow_DarkBolt_all **** **** **** **** **** **** **** **** +7738 Telflammar_Shadow_DarkBolt_1 **** **** **** **** **** **** **** **** +7739 Telflammar_Shadow_Invisibility_Sphere **** **** **** **** **** **** **** **** +7740 Telflammar_Shadow_Mislead **** **** **** **** **** **** **** **** +7741 Telflammar_Shadow_DetectScrying **** **** **** **** **** **** **** **** +7742 Telflammar_Shadow_RED_FESTER **** **** **** **** **** **** **** **** +7743 Telflammar_Shadow_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +7744 Telflammar_Shadow_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +7745 Telflammar_Shadow_MASOCHISM **** **** **** **** **** **** **** **** +7746 JusticeOfWealdAnd_Camoflage **** **** **** **** **** **** **** **** +7747 JusticeOfWealdAnd_Endure_Elements **** **** **** **** **** **** **** **** +7748 JusticeOfWealdAnd_Faerie_Fire **** **** **** **** **** **** **** **** +7749 JusticeOfWealdAnd_HideFromAnimals **** **** **** **** **** **** **** **** +7750 JusticeOfWealdAnd_Spell_Jump **** **** **** **** **** **** **** **** +7751 JusticeOfWealdAnd_Longstrider **** **** **** **** **** **** **** **** +7752 JusticeOfWealdAnd_Obscuring_Mist **** **** **** **** **** **** **** **** +7753 JusticeOfWealdAnd_Barkskin **** **** **** **** **** **** **** **** +7754 JusticeOfWealdAnd_BrilliantEnergyArrows **** **** **** **** **** **** **** **** +7755 JusticeOfWealdAnd_Cats_Grace **** **** **** **** **** **** **** **** +7756 JusticeOfWealdAnd_FogCloud **** **** **** **** **** **** **** **** +7757 JusticeOfWealdAnd_Snare **** **** **** **** **** **** **** **** +7758 JusticeOfWealdAnd_SpellslayerArrow **** **** **** **** **** **** **** **** +7759 JusticeOfWealdAnd_Treeshape **** **** **** **** **** **** **** **** +7760 JusticeOfWealdAnd_ArrowSplit **** **** **** **** **** **** **** **** +7761 JusticeOfWealdAnd_DarkflameArrow **** **** **** **** **** **** **** **** +7762 JusticeOfWealdAnd_Ultravision **** **** **** **** **** **** **** **** +7763 JusticeOfWealdAnd_SerpentArrows **** **** **** **** **** **** **** **** +7764 JusticeOfWealdAnd_Spike_Growth **** **** **** **** **** **** **** **** +7765 JusticeOfWealdAnd_WaterBreathing **** **** **** **** **** **** **** **** +7766 JusticeOfWealdAnd_BloodfreezeArrow **** **** **** **** **** **** **** **** +7767 JusticeOfWealdAnd_DoublestrikeArrow **** **** **** **** **** **** **** **** +7768 JusticeOfWealdAnd_Freedom_of_Movement **** **** **** **** **** **** **** **** +7769 JusticeOfWealdAnd_Poison **** **** **** **** **** **** **** **** +7770 JusticeOfWealdAnd_Scrying **** **** **** **** **** **** **** **** +7771 JusticeOfWealdAnd_ShadowArrow **** **** **** **** **** **** **** **** +7772 KnightMiddleCircl_Bless **** **** **** **** **** **** **** **** +7773 KnightMiddleCircl_Exteneded_Bless **** **** **** **** **** **** **** **** +7774 KnightMiddleCircl_Silent_Bless **** **** **** **** **** **** **** **** +7775 KnightMiddleCircl_Still_Bless **** **** **** **** **** **** **** **** +7776 KnightMiddleCircl_Bless_Weapon **** **** **** **** **** **** **** **** +7777 KnightMiddleCircl_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +7778 KnightMiddleCircl_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +7779 KnightMiddleCircl_Still_Bless_Weapon **** **** **** **** **** **** **** **** +7780 KnightMiddleCircl_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7781 KnightMiddleCircl_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7782 KnightMiddleCircl_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7783 KnightMiddleCircl_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +7784 KnightMiddleCircl_DETECT_UNDEAD **** **** **** **** **** **** **** **** +7785 KnightMiddleCircl_Exteneded_DETECT_UNDEAD **** **** **** **** **** **** **** **** +7786 KnightMiddleCircl_Silent_DETECT_UNDEAD **** **** **** **** **** **** **** **** +7787 KnightMiddleCircl_Still_DETECT_UNDEAD **** **** **** **** **** **** **** **** +7788 KnightMiddleCircl_Divine_Favor **** **** **** **** **** **** **** **** +7789 KnightMiddleCircl_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +7790 KnightMiddleCircl_Silent_Divine_Favor **** **** **** **** **** **** **** **** +7791 KnightMiddleCircl_Still_Divine_Favor **** **** **** **** **** **** **** **** +7792 KnightMiddleCircl_Magic_Weapon **** **** **** **** **** **** **** **** +7793 KnightMiddleCircl_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +7794 KnightMiddleCircl_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +7795 KnightMiddleCircl_Still_Magic_Weapon **** **** **** **** **** **** **** **** +7796 KnightMiddleCircl_Protection_from_Evil **** **** **** **** **** **** **** **** +7797 KnightMiddleCircl_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +7798 KnightMiddleCircl_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +7799 KnightMiddleCircl_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +7800 KnightMiddleCircl_Read_Magic **** **** **** **** **** **** **** **** +7801 KnightMiddleCircl_Silent_Read_Magic **** **** **** **** **** **** **** **** +7802 KnightMiddleCircl_Still_Read_Magic **** **** **** **** **** **** **** **** +7803 KnightMiddleCircl_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +7804 KnightMiddleCircl_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +7805 KnightMiddleCircl_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7806 KnightMiddleCircl_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7807 KnightMiddleCircl_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +7808 KnightMiddleCircl_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7809 KnightMiddleCircl_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7810 KnightMiddleCircl_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +7811 KnightMiddleCircl_Aid **** **** **** **** **** **** **** **** +7812 KnightMiddleCircl_Exteneded_Aid **** **** **** **** **** **** **** **** +7813 KnightMiddleCircl_Silent_Aid **** **** **** **** **** **** **** **** +7814 KnightMiddleCircl_Still_Aid **** **** **** **** **** **** **** **** +7815 KnightMiddleCircl_Divine_Protection **** **** **** **** **** **** **** **** +7816 KnightMiddleCircl_Exteneded_Divine_Protection **** **** **** **** **** **** **** **** +7817 KnightMiddleCircl_Silent_Divine_Protection **** **** **** **** **** **** **** **** +7818 KnightMiddleCircl_Still_Divine_Protection **** **** **** **** **** **** **** **** +7819 KnightMiddleCircl_Conviction **** **** **** **** **** **** **** **** +7820 KnightMiddleCircl_Exteneded_Conviction **** **** **** **** **** **** **** **** +7821 KnightMiddleCircl_Silent_Conviction **** **** **** **** **** **** **** **** +7822 KnightMiddleCircl_Still_Conviction **** **** **** **** **** **** **** **** +7823 KnightMiddleCircl_ShieldOther **** **** **** **** **** **** **** **** +7824 KnightMiddleCircl_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +7825 KnightMiddleCircl_Silent_ShieldOther **** **** **** **** **** **** **** **** +7826 KnightMiddleCircl_Still_ShieldOther **** **** **** **** **** **** **** **** +7827 KnightMiddleCircl_UndetectableAlignment **** **** **** **** **** **** **** **** +7828 KnightMiddleCircl_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +7829 KnightMiddleCircl_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +7830 KnightMiddleCircl_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +7831 KnightMiddleCircl_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7832 KnightMiddleCircl_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7833 KnightMiddleCircl_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +7834 KnightMiddleCircl_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7835 KnightMiddleCircl_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +7836 KnightMiddleCircl_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +7837 KnightMiddleCircl_Dispel_Magic **** **** **** **** **** **** **** **** +7838 KnightMiddleCircl_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +7839 KnightMiddleCircl_Prayer **** **** **** **** **** **** **** **** +7840 KnightMiddleCircl_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +7841 KnightMiddleCircl_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +7842 DreadNecromancer_ANGRY_ACHE **** **** **** **** **** **** **** **** +7843 DreadNecromancer_Bane **** **** **** **** **** **** **** **** +7844 DreadNecromancer_BESTOW_WOUND **** **** **** **** **** **** **** **** +7845 DreadNecromancer_Blade_of_Blood **** **** **** **** **** **** **** **** +7846 DreadNecromancer_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +7847 DreadNecromancer_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +7848 DreadNecromancer_Cause_Fear **** **** **** **** **** **** **** **** +7849 DreadNecromancer_Chill_Touch **** **** **** **** **** **** **** **** +7850 DreadNecromancer_DETECT_UNDEAD **** **** **** **** **** **** **** **** +7851 DreadNecromancer_Doom **** **** **** **** **** **** **** **** +7852 DreadNecromancer_HideFromUndead **** **** **** **** **** **** **** **** +7853 DreadNecromancer_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7854 DreadNecromancer_Necrotic_Awareness **** **** **** **** **** **** **** **** +7855 DreadNecromancer_Negative_Energy_Ray **** **** **** **** **** **** **** **** +7856 DreadNecromancer_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +7857 DreadNecromancer_SummonUndeadI **** **** **** **** **** **** **** **** +7858 DreadNecromancer_UndetectableAlignment **** **** **** **** **** **** **** **** +7859 DreadNecromancer_Blindness_and_Deafness **** **** **** **** **** **** **** **** +7860 DreadNecromancer_BONEBLAST **** **** **** **** **** **** **** **** +7861 DreadNecromancer_Command_Undead **** **** **** **** **** **** **** **** +7862 DreadNecromancer_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +7863 DreadNecromancer_Darkness **** **** **** **** **** **** **** **** +7864 DreadNecromancer_Death_Armor **** **** **** **** **** **** **** **** +7865 DreadNecromancer_Death_Knell **** **** **** **** **** **** **** **** +7866 DreadNecromancer_FalseLife **** **** **** **** **** **** **** **** +7867 DreadNecromancer_Ghoul_Touch **** **** **** **** **** **** **** **** +7868 DreadNecromancer_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +7869 DreadNecromancer_LifeBolt **** **** **** **** **** **** **** **** +7870 DreadNecromancer_LifeBolt1Bolt **** **** **** **** **** **** **** **** +7871 DreadNecromancer_LifeBolt2Bolts **** **** **** **** **** **** **** **** +7872 DreadNecromancer_LifeBolt3Bolts **** **** **** **** **** **** **** **** +7873 DreadNecromancer_LifeBolt4Bolts **** **** **** **** **** **** **** **** +7874 DreadNecromancer_LifeBolt5Bolts **** **** **** **** **** **** **** **** +7875 DreadNecromancer_Living_Undeath **** **** **** **** **** **** **** **** +7876 DreadNecromancer_Necrotic_Cyst **** **** **** **** **** **** **** **** +7877 DreadNecromancer_Scare **** **** **** **** **** **** **** **** +7878 DreadNecromancer_SHRIVELING **** **** **** **** **** **** **** **** +7879 DreadNecromancer_SummonUndeadII **** **** **** **** **** **** **** **** +7880 DreadNecromancer_Animate_Dead **** **** **** **** **** **** **** **** +7881 DreadNecromancer_BONEBLADE **** **** **** **** **** **** **** **** +7882 DreadNecromancer_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +7883 DreadNecromancer_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +7884 DreadNecromancer_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +7885 DreadNecromancer_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +7886 DreadNecromancer_CrushingDespair **** **** **** **** **** **** **** **** +7887 DreadNecromancer_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +7888 DreadNecromancer_GreaterDisruptUndead **** **** **** **** **** **** **** **** +7889 DreadNecromancer_HaltUndead **** **** **** **** **** **** **** **** +7890 DreadNecromancer_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +7891 DreadNecromancer_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +7892 DreadNecromancer_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +7893 DreadNecromancer_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +7894 DreadNecromancer_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +7895 DreadNecromancer_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +7896 DreadNecromancer_Necrotic_Bloat **** **** **** **** **** **** **** **** +7897 DreadNecromancer_Negative_Energy_Burst **** **** **** **** **** **** **** **** +7898 DreadNecromancer_RayofExhaustion **** **** **** **** **** **** **** **** +7899 DreadNecromancer_Slashing_Darkness **** **** **** **** **** **** **** **** +7900 DreadNecromancer_SummonUndeadIII **** **** **** **** **** **** **** **** +7901 DreadNecromancer_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +7902 DreadNecromancer_Vampiric_Touch **** **** **** **** **** **** **** **** +7903 DreadNecromancer_WRACK **** **** **** **** **** **** **** **** +7904 DreadNecromancer_Bestow_Curse **** **** **** **** **** **** **** **** +7905 DreadNecromancer_BloodOfTheMartyr **** **** **** **** **** **** **** **** +7906 DreadNecromancer_Contagion **** **** **** **** **** **** **** **** +7907 DreadNecromancer_Death_Ward **** **** **** **** **** **** **** **** +7908 DreadNecromancer_Dispel_Magic **** **** **** **** **** **** **** **** +7909 DreadNecromancer_Doom_Scarabs **** **** **** **** **** **** **** **** +7910 DreadNecromancer_Enervation **** **** **** **** **** **** **** **** +7911 DreadNecromancer_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +7912 DreadNecromancer_Fear **** **** **** **** **** **** **** **** +7913 DreadNecromancer_GRIM_REVENGE **** **** **** **** **** **** **** **** +7914 DreadNecromancer_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +7915 DreadNecromancer_LIQUID_PAIN **** **** **** **** **** **** **** **** +7916 DreadNecromancer_Necrotic_Domination **** **** **** **** **** **** **** **** +7917 DreadNecromancer_Phantasmal_Killer **** **** **** **** **** **** **** **** +7918 DreadNecromancer_Poison **** **** **** **** **** **** **** **** +7919 DreadNecromancer_Sinsaburs_Baleful_Bolt **** **** **** **** **** **** **** **** +7920 DreadNecromancer_STOP_HEART **** **** **** **** **** **** **** **** +7921 DreadNecromancer_SummonUndeadIV **** **** **** **** **** **** **** **** +7922 DreadNecromancer_Beltyns_Burning_Blood **** **** **** **** **** **** **** **** +7923 DreadNecromancer_Circle_of_Doom **** **** **** **** **** **** **** **** +7924 DreadNecromancer_Cloudkill **** **** **** **** **** **** **** **** +7925 DreadNecromancer_FireInTheBlood **** **** **** **** **** **** **** **** +7926 DreadNecromancer_Greater_Dispelling **** **** **** **** **** **** **** **** +7927 DreadNecromancer_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +7928 DreadNecromancer_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +7929 DreadNecromancer_Mass_Contagion **** **** **** **** **** **** **** **** +7930 DreadNecromancer_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +7931 DreadNecromancer_Necrotic_Burst **** **** **** **** **** **** **** **** +7932 DreadNecromancer_Nights_Caress **** **** **** **** **** **** **** **** +7933 DreadNecromancer_Slay_Living **** **** **** **** **** **** **** **** +7934 DreadNecromancer_Soulscour **** **** **** **** **** **** **** **** +7935 DreadNecromancer_SummonUndeadV **** **** **** **** **** **** **** **** +7936 DreadNecromancer_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +7937 DreadNecromancer_Undeath_to_Death **** **** **** **** **** **** **** **** +7938 DreadNecromancer_WavesofFatigue **** **** **** **** **** **** **** **** +7939 DreadNecromancer_Acid_Fog **** **** **** **** **** **** **** **** +7940 DreadNecromancer_Circle_of_Death **** **** **** **** **** **** **** **** +7941 DreadNecromancer_Create_Undead **** **** **** **** **** **** **** **** +7942 DreadNecromancer_ECTOPLASMIC_ENCHANCEMENT **** **** **** **** **** **** **** **** +7943 DreadNecromancer_Eyebite **** **** **** **** **** **** **** **** +7944 DreadNecromancer_Ghoul_Gauntlet **** **** **** **** **** **** **** **** +7945 DreadNecromancer_Harm **** **** **** **** **** **** **** **** +7946 DreadNecromancer_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +7947 DreadNecromancer_Necrotic_Eruption **** **** **** **** **** **** **** **** +7948 DreadNecromancer_Planar_Binding **** **** **** **** **** **** **** **** +7949 DreadNecromancer_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +7950 DreadNecromancer_WavesOfExhaustion **** **** **** **** **** **** **** **** +7951 DreadNecromancer_ArrowOfBone **** **** **** **** **** **** **** **** +7952 DreadNecromancer_Avasculate **** **** **** **** **** **** **** **** +7953 DreadNecromancer_Control_Undead **** **** **** **** **** **** **** **** +7954 DreadNecromancer_Destruction **** **** **** **** **** **** **** **** +7955 DreadNecromancer_Energy_Ebb **** **** **** **** **** **** **** **** +7956 DreadNecromancer_Finger_of_Death **** **** **** **** **** **** **** **** +7957 DreadNecromancer_Greater_Harm **** **** **** **** **** **** **** **** +7958 DreadNecromancer_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +7959 DreadNecromancer_SongOfDiscord **** **** **** **** **** **** **** **** +7960 DreadNecromancer_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +7961 DreadNecromancer_VileDeath **** **** **** **** **** **** **** **** +7962 DreadNecromancer_Avascular_Mass **** **** **** **** **** **** **** **** +7963 DreadNecromancer_Create_Greater_Undead **** **** **** **** **** **** **** **** +7964 DreadNecromancer_GUTWRENCH **** **** **** **** **** **** **** **** +7965 DreadNecromancer_Horrid_Wilting **** **** **** **** **** **** **** **** +7966 DreadNecromancer_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +7967 DreadNecromancer_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +7968 DreadNecromancer_Necrotic_Empowerment **** **** **** **** **** **** **** **** +7969 DreadNecromancer_Pestilence **** **** **** **** **** **** **** **** +7970 DreadNecromancer_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +7971 DreadNecromancer_Energy_Drain **** **** **** **** **** **** **** **** +7972 DreadNecromancer_Mass_Harm **** **** **** **** **** **** **** **** +7973 DreadNecromancer_Necrotic_Termination **** **** **** **** **** **** **** **** +7974 DreadNecromancer_PlagueOfUndead **** **** **** **** **** **** **** **** +7975 DreadNecromancer_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +7976 ****_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +7977 ****_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +7978 ****_Light **** **** **** **** **** **** **** **** +7979 ****_Read_Magic **** **** **** **** **** **** **** **** +7980 ****_Resistance **** **** **** **** **** **** **** **** +7981 ****_Virtue **** **** **** **** **** **** **** **** +7982 ****_ANGRY_ACHE **** **** **** **** **** **** **** **** +7983 ****_Bane **** **** **** **** **** **** **** **** +7984 ****_Blade_of_Blood **** **** **** **** **** **** **** **** +7985 ****_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +7986 ****_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +7987 ****_Bless **** **** **** **** **** **** **** **** +7988 ****_Bless_Water **** **** **** **** **** **** **** **** +7989 ****_Cause_Fear **** **** **** **** **** **** **** **** +7990 ****_Command_RadialMaster **** **** **** **** **** **** **** **** +7991 ****_Command_Approach **** **** **** **** **** **** **** **** +7992 ****_Command_Drop **** **** **** **** **** **** **** **** +7993 ****_Command_Fall **** **** **** **** **** **** **** **** +7994 ****_Command_Flee **** **** **** **** **** **** **** **** +7995 ****_Command_Halt **** **** **** **** **** **** **** **** +7996 ****_Conviction **** **** **** **** **** **** **** **** +7997 ****_Crafters_Blessing **** **** **** **** **** **** **** **** +7998 ****_Crafters_Curse **** **** **** **** **** **** **** **** +7999 ****_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8000 ****_Curse_Water **** **** **** **** **** **** **** **** +8001 ****_Detect_Chaos **** **** **** **** **** **** **** **** +8002 ****_Detect_Evil **** **** **** **** **** **** **** **** +8003 ****_Detect_Good **** **** **** **** **** **** **** **** +8004 ****_Detect_Law **** **** **** **** **** **** **** **** +8005 ****_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8006 ****_Divine_Favor **** **** **** **** **** **** **** **** +8007 ****_Doom **** **** **** **** **** **** **** **** +8008 ****_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +8009 ****_Endure_Elements **** **** **** **** **** **** **** **** +8010 ****_Entropic_Shield **** **** **** **** **** **** **** **** +8011 ****_EXTRACT_DRUG **** **** **** **** **** **** **** **** +8012 ****_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +8013 ****_EXTRACT_VODARE **** **** **** **** **** **** **** **** +8014 ****_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +8015 ****_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8016 ****_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +8017 ****_HEARTACHE **** **** **** **** **** **** **** **** +8018 ****_HideFromUndead **** **** **** **** **** **** **** **** +8019 ****_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8020 ****_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8021 ****_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8022 ****_Lesser_Vigor **** **** **** **** **** **** **** **** +8023 ****_Magic_Stone **** **** **** **** **** **** **** **** +8024 ****_Magic_Weapon **** **** **** **** **** **** **** **** +8025 ****_Necrotic_Awareness **** **** **** **** **** **** **** **** +8026 ****_Obscuring_Mist **** **** **** **** **** **** **** **** +8027 ****_Protection_from_Chaos **** **** **** **** **** **** **** **** +8028 ****_Protection_from_Evil **** **** **** **** **** **** **** **** +8029 ****_Protection_from_Good **** **** **** **** **** **** **** **** +8030 ****_Protection_from_Law **** **** **** **** **** **** **** **** +8031 ****_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8032 ****_Remove_Fear **** **** **** **** **** **** **** **** +8033 ****_Sanctuary **** **** **** **** **** **** **** **** +8034 ****_Shield_of_Faith **** **** **** **** **** **** **** **** +8035 ****_SORROW **** **** **** **** **** **** **** **** +8036 ****_Summon_Creature_I **** **** **** **** **** **** **** **** +8037 ****_SummonUndeadI **** **** **** **** **** **** **** **** +8038 ****_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8039 ****_VisionOfHeaven **** **** **** **** **** **** **** **** +8040 ****_ADDICTION **** **** **** **** **** **** **** **** +8041 ****_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +8042 ****_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8043 ****_ADDICTION_VODARE **** **** **** **** **** **** **** **** +8044 ****_ADDICTION_AGONY **** **** **** **** **** **** **** **** +8045 ****_Aid **** **** **** **** **** **** **** **** +8046 ****_Animalistic_Power **** **** **** **** **** **** **** **** +8047 ****_BONEBLAST **** **** **** **** **** **** **** **** +8048 ****_Bulls_Strength **** **** **** **** **** **** **** **** +8049 ****_Calm_Emotions **** **** **** **** **** **** **** **** +8050 ****_Consecrated_Aura **** **** **** **** **** **** **** **** +8051 ****_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8052 ****_Darkness **** **** **** **** **** **** **** **** +8053 ****_Death_Knell **** **** **** **** **** **** **** **** +8054 ****_Divine_Protection **** **** **** **** **** **** **** **** +8055 ****_Eagle_Splendor **** **** **** **** **** **** **** **** +8056 ****_ELATION **** **** **** **** **** **** **** **** +8057 ****_Endurance **** **** **** **** **** **** **** **** +8058 ****_Find_Traps **** **** **** **** **** **** **** **** +8059 ****_Foxs_Cunning **** **** **** **** **** **** **** **** +8060 ****_Hold_Person **** **** **** **** **** **** **** **** +8061 ****_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +8062 ****_Lesser_Dispel **** **** **** **** **** **** **** **** +8063 ****_Lesser_Restoration **** **** **** **** **** **** **** **** +8064 ****_Living_Undeath **** **** **** **** **** **** **** **** +8065 ****_Necrotic_Cyst **** **** **** **** **** **** **** **** +8066 ****_Negative_Energy_Ray **** **** **** **** **** **** **** **** +8067 ****_Owls_Wisdom **** **** **** **** **** **** **** **** +8068 ****_Remove_Paralysis **** **** **** **** **** **** **** **** +8069 ****_Resist_Elements **** **** **** **** **** **** **** **** +8070 ****_ShieldOther **** **** **** **** **** **** **** **** +8071 ****_Silence **** **** **** **** **** **** **** **** +8072 ****_Sound_Burst **** **** **** **** **** **** **** **** +8073 ****_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +8074 ****_Stone_Bones **** **** **** **** **** **** **** **** +8075 ****_Summon_Creature_II **** **** **** **** **** **** **** **** +8076 ****_SummonUndeadII **** **** **** **** **** **** **** **** +8077 ****_Ultravision **** **** **** **** **** **** **** **** +8078 ****_UndetectableAlignment **** **** **** **** **** **** **** **** +8079 ****_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +8080 ****_Animate_Dead **** **** **** **** **** **** **** **** +8081 ****_Bestow_Curse **** **** **** **** **** **** **** **** +8082 ****_Blindness_and_Deafness **** **** **** **** **** **** **** **** +8083 ****_BONEBLADE **** **** **** **** **** **** **** **** +8084 ****_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +8085 ****_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +8086 ****_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +8087 ****_Clarity **** **** **** **** **** **** **** **** +8088 ****_Close_Wounds **** **** **** **** **** **** **** **** +8089 ****_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +8090 ****_Contagion **** **** **** **** **** **** **** **** +8091 ****_Continual_Flame **** **** **** **** **** **** **** **** +8092 ****_Crown_Might **** **** **** **** **** **** **** **** +8093 ****_Crown_Protection **** **** **** **** **** **** **** **** +8094 ****_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +8095 ****_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +8096 ****_Darkfire **** **** **** **** **** **** **** **** +8097 ****_Daylight **** **** **** **** **** **** **** **** +8098 ****_DeeperDarkness **** **** **** **** **** **** **** **** +8099 ****_DEVILS_EYE **** **** **** **** **** **** **** **** +8100 ****_Dispel_Magic **** **** **** **** **** **** **** **** +8101 ****_ENERGIZE_POTION **** **** **** **** **** **** **** **** +8102 ****_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +8103 ****_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +8104 ****_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +8105 ****_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +8106 ****_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +8107 ****_Energy_Aegis **** **** **** **** **** **** **** **** +8108 ****_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +8109 ****_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +8110 ****_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +8111 ****_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +8112 ****_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +8113 ****_FLESH_RIPPER **** **** **** **** **** **** **** **** +8114 ****_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +8115 ****_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +8116 ****_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +8117 ****_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +8118 ****_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +8119 ****_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +8120 ****_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +8121 ****_Invisibility_Purge **** **** **** **** **** **** **** **** +8122 ****_Legions_Conviction **** **** **** **** **** **** **** **** +8123 ****_LocateObject **** **** **** **** **** **** **** **** +8124 ****_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +8125 ****_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +8126 ****_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +8127 ****_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +8128 ****_Magic_Vestment **** **** **** **** **** **** **** **** +8129 ****_MASOCHISM **** **** **** **** **** **** **** **** +8130 ****_Mass_Aid **** **** **** **** **** **** **** **** +8131 ****_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +8132 ****_Necrotic_Bloat **** **** **** **** **** **** **** **** +8133 ****_Negative_Energy_Protection **** **** **** **** **** **** **** **** +8134 ****_ObscureObject **** **** **** **** **** **** **** **** +8135 ****_Prayer **** **** **** **** **** **** **** **** +8136 ****_Protection_from_Elements **** **** **** **** **** **** **** **** +8137 ****_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +8138 ****_Remove_Curse **** **** **** **** **** **** **** **** +8139 ****_Remove_Disease **** **** **** **** **** **** **** **** +8140 ****_RingOfBlades **** **** **** **** **** **** **** **** +8141 ****_Searing_Light **** **** **** **** **** **** **** **** +8142 ****_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8143 ****_SHRIVELING **** **** **** **** **** **** **** **** +8144 ****_Slashing_Darkness **** **** **** **** **** **** **** **** +8145 ****_Summon_Creature_III **** **** **** **** **** **** **** **** +8146 ****_SummonUndeadIII **** **** **** **** **** **** **** **** +8147 ****_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +8148 ****_Vigor **** **** **** **** **** **** **** **** +8149 ****_WaterBreathing **** **** **** **** **** **** **** **** +8150 ****_WRACK **** **** **** **** **** **** **** **** +8151 ****_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +8152 ****_BloodOfTheMartyr **** **** **** **** **** **** **** **** +8153 ****_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +8154 ****_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +8155 ****_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +8156 ****_Death_Ward **** **** **** **** **** **** **** **** +8157 ****_Dimensional_Anchor **** **** **** **** **** **** **** **** +8158 ****_Dismissal **** **** **** **** **** **** **** **** +8159 ****_Divine_Power **** **** **** **** **** **** **** **** +8160 ****_Freedom_of_Movement **** **** **** **** **** **** **** **** +8161 ****_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +8162 ****_Greater_Resistance **** **** **** **** **** **** **** **** +8163 ****_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +8164 ****_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +8165 ****_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +8166 ****_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +8167 ****_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +8168 ****_Mass_Ultravision **** **** **** **** **** **** **** **** +8169 ****_Necrotic_Domination **** **** **** **** **** **** **** **** +8170 ****_Neutralize_Poison **** **** **** **** **** **** **** **** +8171 ****_Panacea **** **** **** **** **** **** **** **** +8172 ****_Poison **** **** **** **** **** **** **** **** +8173 ****_Recitation **** **** **** **** **** **** **** **** +8174 ****_RepelVermin **** **** **** **** **** **** **** **** +8175 ****_Restoration **** **** **** **** **** **** **** **** +8176 ****_STOP_HEART **** **** **** **** **** **** **** **** +8177 ****_Summon_Creature_IV **** **** **** **** **** **** **** **** +8178 ****_SummonUndeadIV **** **** **** **** **** **** **** **** +8179 ****_SwordOfConscience **** **** **** **** **** **** **** **** +8180 ****_Battletide **** **** **** **** **** **** **** **** +8181 ****_BreakEnchantment **** **** **** **** **** **** **** **** +8182 ****_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +8183 ****_Circle_of_Doom **** **** **** **** **** **** **** **** +8184 ****_CONVERT_WAND **** **** **** **** **** **** **** **** +8185 ****_DANCING_WEB **** **** **** **** **** **** **** **** +8186 ****_FireInTheBlood **** **** **** **** **** **** **** **** +8187 ****_Flame_Strike **** **** **** **** **** **** **** **** +8188 ****_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +8189 ****_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +8190 ****_GreaterCommand_Approach **** **** **** **** **** **** **** **** +8191 ****_GreaterCommand_Drop **** **** **** **** **** **** **** **** +8192 ****_GreaterCommand_Fall **** **** **** **** **** **** **** **** +8193 ****_GreaterCommand_Flee **** **** **** **** **** **** **** **** +8194 ****_GreaterCommand_Halt **** **** **** **** **** **** **** **** +8195 ****_Healing_Circle **** **** **** **** **** **** **** **** +8196 ****_HEARTCLUTCH **** **** **** **** **** **** **** **** +8197 ****_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +8198 ****_Mass_Contagion **** **** **** **** **** **** **** **** +8199 ****_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8200 ****_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8201 ****_MORALITY_UNDONE **** **** **** **** **** **** **** **** +8202 ****_Necrotic_Burst **** **** **** **** **** **** **** **** +8203 ****_Raise_Dead **** **** **** **** **** **** **** **** +8204 ****_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +8205 ****_Revivify **** **** **** **** **** **** **** **** +8206 ****_Righteous_Might **** **** **** **** **** **** **** **** +8207 ****_Scrying **** **** **** **** **** **** **** **** +8208 ****_Slay_Living **** **** **** **** **** **** **** **** +8209 ****_Soulscour **** **** **** **** **** **** **** **** +8210 ****_Spell_Resistance **** **** **** **** **** **** **** **** +8211 ****_Summon_Creature_V **** **** **** **** **** **** **** **** +8212 ****_SummonUndeadV **** **** **** **** **** **** **** **** +8213 ****_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +8214 ****_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +8215 ****_True_Seeing **** **** **** **** **** **** **** **** +8216 ****_Animate_Object **** **** **** **** **** **** **** **** +8217 ****_Banishment **** **** **** **** **** **** **** **** +8218 ****_Blade_Barrier **** **** **** **** **** **** **** **** +8219 ****_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +8220 ****_CELESTIAL_BLOOD **** **** **** **** **** **** **** **** +8221 ****_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +8222 ****_Control_Undead **** **** **** **** **** **** **** **** +8223 ****_Create_Undead **** **** **** **** **** **** **** **** +8224 ****_Energy_Immunity **** **** **** **** **** **** **** **** +8225 ****_EI_Acid **** **** **** **** **** **** **** **** +8226 ****_EI_Cold **** **** **** **** **** **** **** **** +8227 ****_EI_Elec **** **** **** **** **** **** **** **** +8228 ****_EI_Fire **** **** **** **** **** **** **** **** +8229 ****_EI_Sonic **** **** **** **** **** **** **** **** +8230 ****_Etherealness **** **** **** **** **** **** **** **** +8231 ****_Greater_Dispelling **** **** **** **** **** **** **** **** +8232 ****_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +8233 ****_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +8234 ****_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +8235 ****_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +8236 ****_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +8237 ****_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +8238 ****_Harm **** **** **** **** **** **** **** **** +8239 ****_Heal **** **** **** **** **** **** **** **** +8240 ****_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +8241 ****_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8242 ****_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +8243 ****_Mass_Endurance **** **** **** **** **** **** **** **** +8244 ****_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +8245 ****_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +8246 ****_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +8247 ****_Necrotic_Eruption **** **** **** **** **** **** **** **** +8248 ****_Planar_Ally **** **** **** **** **** **** **** **** +8249 ****_SarcophagusOfStone **** **** **** **** **** **** **** **** +8250 ****_Summon_Creature_VI **** **** **** **** **** **** **** **** +8251 ****_Superior_Resistance **** **** **** **** **** **** **** **** +8252 ****_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +8253 ****_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +8254 ****_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +8255 ****_Undeath_to_Death **** **** **** **** **** **** **** **** +8256 ****_Vigorous_Circle **** **** **** **** **** **** **** **** +8257 ****_WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +8258 ****_WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +8259 ****_WordOfRecall_Party **** **** **** **** **** **** **** **** +8260 ****_Blasphemy **** **** **** **** **** **** **** **** +8261 ****_Control_Weather **** **** **** **** **** **** **** **** +8262 ****_CW_Rain **** **** **** **** **** **** **** **** +8263 ****_CW_Snow **** **** **** **** **** **** **** **** +8264 ****_CW_Clear **** **** **** **** **** **** **** **** +8265 ****_Destruction **** **** **** **** **** **** **** **** +8266 ****_Dictum **** **** **** **** **** **** **** **** +8267 ****_Energy_Ebb **** **** **** **** **** **** **** **** +8268 ****_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +8269 ****_Greater_Harm **** **** **** **** **** **** **** **** +8270 ****_Greater_Restoration **** **** **** **** **** **** **** **** +8271 ****_GreaterScrying **** **** **** **** **** **** **** **** +8272 ****_Holy_Word **** **** **** **** **** **** **** **** +8273 ****_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +8274 ****_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +8275 ****_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +8276 ****_Regenerate **** **** **** **** **** **** **** **** +8277 ****_Repulsion **** **** **** **** **** **** **** **** +8278 ****_Resurrection **** **** **** **** **** **** **** **** +8279 ****_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +8280 ****_Summon_Creature_VII **** **** **** **** **** **** **** **** +8281 ****_Summon7Air **** **** **** **** **** **** **** **** +8282 ****_Summon7Earth **** **** **** **** **** **** **** **** +8283 ****_Summon7Fire **** **** **** **** **** **** **** **** +8284 ****_Summon7Water **** **** **** **** **** **** **** **** +8285 ****_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +8286 ****_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +8287 ****_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +8288 ****_Word_of_Chaos **** **** **** **** **** **** **** **** +8289 ****_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +8290 ****_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +8291 ****_Aura_versus_Alignment **** **** **** **** **** **** **** **** +8292 ****_Unholy_Aura **** **** **** **** **** **** **** **** +8293 ****_Holy_Aura **** **** **** **** **** **** **** **** +8294 ****_BODAK_BIRTH **** **** **** **** **** **** **** **** +8295 ****_Create_Greater_Undead **** **** **** **** **** **** **** **** +8296 ****_Dimensional_Lock **** **** **** **** **** **** **** **** +8297 ****_DiscernLocation **** **** **** **** **** **** **** **** +8298 ****_Earthquake **** **** **** **** **** **** **** **** +8299 ****_Fire_Storm **** **** **** **** **** **** **** **** +8300 ****_Greater_Planar_Ally **** **** **** **** **** **** **** **** +8301 ****_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +8302 ****_Holy_Aura **** **** **** **** **** **** **** **** +8303 ****_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +8304 ****_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +8305 ****_Mass_Heal **** **** **** **** **** **** **** **** +8306 ****_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +8307 ****_Necrotic_Empowerment **** **** **** **** **** **** **** **** +8308 ****_Pestilence **** **** **** **** **** **** **** **** +8309 ****_Summon_Creature_VIII **** **** **** **** **** **** **** **** +8310 ****_Summon8Air **** **** **** **** **** **** **** **** +8311 ****_Summon8Earth **** **** **** **** **** **** **** **** +8312 ****_Summon8Fire **** **** **** **** **** **** **** **** +8313 ****_Summon8Water **** **** **** **** **** **** **** **** +8314 ****_Sunbeam **** **** **** **** **** **** **** **** +8315 ****_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +8316 ****_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +8317 ****_DESPOIL **** **** **** **** **** **** **** **** +8318 ****_Elder_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +8319 ****_Elder_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +8320 ****_Elder_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +8321 ****_Elder_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +8322 ****_Elder_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +8323 ****_Elder_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +8324 ****_Energy_Drain **** **** **** **** **** **** **** **** +8325 ****_Gate **** **** **** **** **** **** **** **** +8326 ****_Implosion **** **** **** **** **** **** **** **** +8327 ****_Mass_Harm **** **** **** **** **** **** **** **** +8328 ****_Necrotic_Termination **** **** **** **** **** **** **** **** +8329 ****_PlagueOfUndead **** **** **** **** **** **** **** **** +8330 ****_Storm_of_Vengeance **** **** **** **** **** **** **** **** +8331 ****_Summon_Creature_IX **** **** **** **** **** **** **** **** +8332 ****_Summon9Air **** **** **** **** **** **** **** **** +8333 ****_Summon9Earth **** **** **** **** **** **** **** **** +8334 ****_Summon9Fire **** **** **** **** **** **** **** **** +8335 ****_Summon9Water **** **** **** **** **** **** **** **** +8336 ****_True_Resurrection **** **** **** **** **** **** **** **** +8337 ****_Undeaths_Eternal_Foe **** **** **** **** **** **** **** **** +8338 ****_VileDeath **** **** **** **** **** **** **** **** +8339 Archivist_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +8340 Archivist_Quickened_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +8341 Archivist_Silent_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +8342 Archivist_Still_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +8343 Archivist_Flare **** **** **** **** **** **** **** **** +8344 Archivist_Exteneded_Flare **** **** **** **** **** **** **** **** +8345 Archivist_Quickened_Flare **** **** **** **** **** **** **** **** +8346 Archivist_Silent_Flare **** **** **** **** **** **** **** **** +8347 Archivist_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +8348 Archivist_Quickened_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +8349 Archivist_Silent_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +8350 Archivist_Still_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +8351 Archivist_Light **** **** **** **** **** **** **** **** +8352 Archivist_Exteneded_Light **** **** **** **** **** **** **** **** +8353 Archivist_Quickened_Light **** **** **** **** **** **** **** **** +8354 Archivist_Silent_Light **** **** **** **** **** **** **** **** +8355 Archivist_Read_Magic **** **** **** **** **** **** **** **** +8356 Archivist_Quickened_Read_Magic **** **** **** **** **** **** **** **** +8357 Archivist_Silent_Read_Magic **** **** **** **** **** **** **** **** +8358 Archivist_Still_Read_Magic **** **** **** **** **** **** **** **** +8359 Archivist_Resistance **** **** **** **** **** **** **** **** +8360 Archivist_Exteneded_Resistance **** **** **** **** **** **** **** **** +8361 Archivist_Quickened_Resistance **** **** **** **** **** **** **** **** +8362 Archivist_Silent_Resistance **** **** **** **** **** **** **** **** +8363 Archivist_Still_Resistance **** **** **** **** **** **** **** **** +8364 Archivist_Virtue **** **** **** **** **** **** **** **** +8365 Archivist_Exteneded_Virtue **** **** **** **** **** **** **** **** +8366 Archivist_Quickened_Virtue **** **** **** **** **** **** **** **** +8367 Archivist_Silent_Virtue **** **** **** **** **** **** **** **** +8368 Archivist_Still_Virtue **** **** **** **** **** **** **** **** +8369 Archivist_ANGRY_ACHE **** **** **** **** **** **** **** **** +8370 Archivist_Exteneded_ANGRY_ACHE **** **** **** **** **** **** **** **** +8371 Archivist_Quickened_ANGRY_ACHE **** **** **** **** **** **** **** **** +8372 Archivist_Silent_ANGRY_ACHE **** **** **** **** **** **** **** **** +8373 Archivist_Still_ANGRY_ACHE **** **** **** **** **** **** **** **** +8374 Archivist_Bane **** **** **** **** **** **** **** **** +8375 Archivist_Exteneded_Bane **** **** **** **** **** **** **** **** +8376 Archivist_Quickened_Bane **** **** **** **** **** **** **** **** +8377 Archivist_Silent_Bane **** **** **** **** **** **** **** **** +8378 Archivist_Still_Bane **** **** **** **** **** **** **** **** +8379 Archivist_Blade_of_Blood **** **** **** **** **** **** **** **** +8380 Archivist_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8381 Archivist_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8382 Archivist_Empowered_Blade_of_Blood **** **** **** **** **** **** **** **** +8383 Archivist_Empowered_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8384 Archivist_Empowered_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8385 Archivist_Exteneded_Blade_of_Blood **** **** **** **** **** **** **** **** +8386 Archivist_Exteneded_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8387 Archivist_Exteneded_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8388 Archivist_Maximized_Blade_of_Blood **** **** **** **** **** **** **** **** +8389 Archivist_Maximized_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8390 Archivist_Maximized_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8391 Archivist_Quickened_Blade_of_Blood **** **** **** **** **** **** **** **** +8392 Archivist_Quickened_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8393 Archivist_Quickened_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8394 Archivist_Silent_Blade_of_Blood **** **** **** **** **** **** **** **** +8395 Archivist_Silent_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8396 Archivist_Silent_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8397 Archivist_Still_Blade_of_Blood **** **** **** **** **** **** **** **** +8398 Archivist_Still_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +8399 Archivist_Still_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +8400 Archivist_Bless **** **** **** **** **** **** **** **** +8401 Archivist_Exteneded_Bless **** **** **** **** **** **** **** **** +8402 Archivist_Quickened_Bless **** **** **** **** **** **** **** **** +8403 Archivist_Silent_Bless **** **** **** **** **** **** **** **** +8404 Archivist_Still_Bless **** **** **** **** **** **** **** **** +8405 Archivist_Bless_Water **** **** **** **** **** **** **** **** +8406 Archivist_Quickened_Bless_Water **** **** **** **** **** **** **** **** +8407 Archivist_Silent_Bless_Water **** **** **** **** **** **** **** **** +8408 Archivist_Still_Bless_Water **** **** **** **** **** **** **** **** +8409 Archivist_Bless_Weapon **** **** **** **** **** **** **** **** +8410 Archivist_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +8411 Archivist_Quickened_Bless_Weapon **** **** **** **** **** **** **** **** +8412 Archivist_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +8413 Archivist_Still_Bless_Weapon **** **** **** **** **** **** **** **** +8414 Archivist_Camoflage **** **** **** **** **** **** **** **** +8415 Archivist_Exteneded_Camoflage **** **** **** **** **** **** **** **** +8416 Archivist_Quickened_Camoflage **** **** **** **** **** **** **** **** +8417 Archivist_Silent_Camoflage **** **** **** **** **** **** **** **** +8418 Archivist_Still_Camoflage **** **** **** **** **** **** **** **** +8419 Archivist_Cause_Fear **** **** **** **** **** **** **** **** +8420 Archivist_Exteneded_Cause_Fear **** **** **** **** **** **** **** **** +8421 Archivist_Quickened_Cause_Fear **** **** **** **** **** **** **** **** +8422 Archivist_Still_Cause_Fear **** **** **** **** **** **** **** **** +8423 Archivist_Charm_Person **** **** **** **** **** **** **** **** +8424 Archivist_Exteneded_Charm_Person **** **** **** **** **** **** **** **** +8425 Archivist_Quickened_Charm_Person **** **** **** **** **** **** **** **** +8426 Archivist_Silent_Charm_Person **** **** **** **** **** **** **** **** +8427 Archivist_Still_Charm_Person **** **** **** **** **** **** **** **** +8428 Archivist_Color_Spray **** **** **** **** **** **** **** **** +8429 Archivist_Empowered_Color_Spray **** **** **** **** **** **** **** **** +8430 Archivist_Maximized_Color_Spray **** **** **** **** **** **** **** **** +8431 Archivist_Quickened_Color_Spray **** **** **** **** **** **** **** **** +8432 Archivist_Silent_Color_Spray **** **** **** **** **** **** **** **** +8433 Archivist_Still_Color_Spray **** **** **** **** **** **** **** **** +8434 Archivist_Command_RadialMaster **** **** **** **** **** **** **** **** +8435 Archivist_Command_Approach **** **** **** **** **** **** **** **** +8436 Archivist_Command_Drop **** **** **** **** **** **** **** **** +8437 Archivist_Command_Fall **** **** **** **** **** **** **** **** +8438 Archivist_Command_Flee **** **** **** **** **** **** **** **** +8439 Archivist_Command_Halt **** **** **** **** **** **** **** **** +8440 Archivist_Exteneded_Command_RadialMaster **** **** **** **** **** **** **** **** +8441 Archivist_Exteneded_Command_Approach **** **** **** **** **** **** **** **** +8442 Archivist_Exteneded_Command_Drop **** **** **** **** **** **** **** **** +8443 Archivist_Exteneded_Command_Fall **** **** **** **** **** **** **** **** +8444 Archivist_Exteneded_Command_Flee **** **** **** **** **** **** **** **** +8445 Archivist_Exteneded_Command_Halt **** **** **** **** **** **** **** **** +8446 Archivist_Quickened_Command_RadialMaster **** **** **** **** **** **** **** **** +8447 Archivist_Quickened_Command_Approach **** **** **** **** **** **** **** **** +8448 Archivist_Quickened_Command_Drop **** **** **** **** **** **** **** **** +8449 Archivist_Quickened_Command_Fall **** **** **** **** **** **** **** **** +8450 Archivist_Quickened_Command_Flee **** **** **** **** **** **** **** **** +8451 Archivist_Quickened_Command_Halt **** **** **** **** **** **** **** **** +8452 Archivist_Silent_Command_RadialMaster **** **** **** **** **** **** **** **** +8453 Archivist_Silent_Command_Approach **** **** **** **** **** **** **** **** +8454 Archivist_Silent_Command_Drop **** **** **** **** **** **** **** **** +8455 Archivist_Silent_Command_Fall **** **** **** **** **** **** **** **** +8456 Archivist_Silent_Command_Flee **** **** **** **** **** **** **** **** +8457 Archivist_Silent_Command_Halt **** **** **** **** **** **** **** **** +8458 Archivist_Still_Command_RadialMaster **** **** **** **** **** **** **** **** +8459 Archivist_Still_Command_Approach **** **** **** **** **** **** **** **** +8460 Archivist_Still_Command_Drop **** **** **** **** **** **** **** **** +8461 Archivist_Still_Command_Fall **** **** **** **** **** **** **** **** +8462 Archivist_Still_Command_Flee **** **** **** **** **** **** **** **** +8463 Archivist_Still_Command_Halt **** **** **** **** **** **** **** **** +8464 Archivist_Conviction **** **** **** **** **** **** **** **** +8465 Archivist_Exteneded_Conviction **** **** **** **** **** **** **** **** +8466 Archivist_Quickened_Conviction **** **** **** **** **** **** **** **** +8467 Archivist_Silent_Conviction **** **** **** **** **** **** **** **** +8468 Archivist_Still_Conviction **** **** **** **** **** **** **** **** +8469 Archivist_Crafters_Blessing **** **** **** **** **** **** **** **** +8470 Archivist_Exteneded_Crafters_Blessing **** **** **** **** **** **** **** **** +8471 Archivist_Quickened_Crafters_Blessing **** **** **** **** **** **** **** **** +8472 Archivist_Silent_Crafters_Blessing **** **** **** **** **** **** **** **** +8473 Archivist_Still_Crafters_Blessing **** **** **** **** **** **** **** **** +8474 Archivist_Crafters_Curse **** **** **** **** **** **** **** **** +8475 Archivist_Exteneded_Crafters_Curse **** **** **** **** **** **** **** **** +8476 Archivist_Quickened_Crafters_Curse **** **** **** **** **** **** **** **** +8477 Archivist_Silent_Crafters_Curse **** **** **** **** **** **** **** **** +8478 Archivist_Still_Crafters_Curse **** **** **** **** **** **** **** **** +8479 Archivist_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8480 Archivist_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8481 Archivist_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8482 Archivist_Quickened_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8483 Archivist_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8484 Archivist_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +8485 Archivist_Curse_Water **** **** **** **** **** **** **** **** +8486 Archivist_Quickened_Curse_Water **** **** **** **** **** **** **** **** +8487 Archivist_Silent_Curse_Water **** **** **** **** **** **** **** **** +8488 Archivist_Still_Curse_Water **** **** **** **** **** **** **** **** +8489 Archivist_Deafening_Clang **** **** **** **** **** **** **** **** +8490 Archivist_Exteneded_Deafening_Clang **** **** **** **** **** **** **** **** +8491 Archivist_Quickened_Deafening_Clang **** **** **** **** **** **** **** **** +8492 Archivist_Silent_Deafening_Clang **** **** **** **** **** **** **** **** +8493 Archivist_Still_Deafening_Clang **** **** **** **** **** **** **** **** +8494 Archivist_DEMONFLESH **** **** **** **** **** **** **** **** +8495 Archivist_Exteneded_DEMONFLESH **** **** **** **** **** **** **** **** +8496 Archivist_Quickened_DEMONFLESH **** **** **** **** **** **** **** **** +8497 Archivist_Silent_DEMONFLESH **** **** **** **** **** **** **** **** +8498 Archivist_Still_DEMONFLESH **** **** **** **** **** **** **** **** +8499 Archivist_Detect_Chaos **** **** **** **** **** **** **** **** +8500 Archivist_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +8501 Archivist_Quickened_Detect_Chaos **** **** **** **** **** **** **** **** +8502 Archivist_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +8503 Archivist_Still_Detect_Chaos **** **** **** **** **** **** **** **** +8504 Archivist_Detect_Evil **** **** **** **** **** **** **** **** +8505 Archivist_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +8506 Archivist_Quickened_Detect_Evil **** **** **** **** **** **** **** **** +8507 Archivist_Silent_Detect_Evil **** **** **** **** **** **** **** **** +8508 Archivist_Still_Detect_Evil **** **** **** **** **** **** **** **** +8509 Archivist_Detect_Good **** **** **** **** **** **** **** **** +8510 Archivist_Exteneded_Detect_Good **** **** **** **** **** **** **** **** +8511 Archivist_Quickened_Detect_Good **** **** **** **** **** **** **** **** +8512 Archivist_Silent_Detect_Good **** **** **** **** **** **** **** **** +8513 Archivist_Still_Detect_Good **** **** **** **** **** **** **** **** +8514 Archivist_Detect_Law **** **** **** **** **** **** **** **** +8515 Archivist_Exteneded_Detect_Law **** **** **** **** **** **** **** **** +8516 Archivist_Quickened_Detect_Law **** **** **** **** **** **** **** **** +8517 Archivist_Silent_Detect_Law **** **** **** **** **** **** **** **** +8518 Archivist_Still_Detect_Law **** **** **** **** **** **** **** **** +8519 Archivist_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8520 Archivist_Exteneded_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8521 Archivist_Quickened_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8522 Archivist_Silent_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8523 Archivist_Still_DETECT_UNDEAD **** **** **** **** **** **** **** **** +8524 Archivist_DetectFavoredEnemies **** **** **** **** **** **** **** **** +8525 Archivist_Quickened_DetectFavoredEnemies **** **** **** **** **** **** **** **** +8526 Archivist_Silent_DetectFavoredEnemies **** **** **** **** **** **** **** **** +8527 Archivist_Still_DetectFavoredEnemies **** **** **** **** **** **** **** **** +8528 Archivist_Divine_Favor **** **** **** **** **** **** **** **** +8529 Archivist_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +8530 Archivist_Quickened_Divine_Favor **** **** **** **** **** **** **** **** +8531 Archivist_Silent_Divine_Favor **** **** **** **** **** **** **** **** +8532 Archivist_Still_Divine_Favor **** **** **** **** **** **** **** **** +8533 Archivist_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +8534 Archivist_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +8535 Archivist_Quickened_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +8536 Archivist_DIVINE_SACRIFICE **** **** **** **** **** **** **** **** +8537 Archivist_SPELL_DIVINE_SACRIFICE_2 **** **** **** **** **** **** **** **** +8538 Archivist_SPELL_DIVINE_SACRIFICE_4 **** **** **** **** **** **** **** **** +8539 Archivist_SPELL_DIVINE_SACRIFICE_6 **** **** **** **** **** **** **** **** +8540 Archivist_SPELL_DIVINE_SACRIFICE_8 **** **** **** **** **** **** **** **** +8541 Archivist_SPELL_DIVINE_SACRIFICE_10 **** **** **** **** **** **** **** **** +8542 Archivist_Doom **** **** **** **** **** **** **** **** +8543 Archivist_Exteneded_Doom **** **** **** **** **** **** **** **** +8544 Archivist_Quickened_Doom **** **** **** **** **** **** **** **** +8545 Archivist_Silent_Doom **** **** **** **** **** **** **** **** +8546 Archivist_Still_Doom **** **** **** **** **** **** **** **** +8547 Archivist_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +8548 Archivist_Quickened_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +8549 Archivist_Silent_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +8550 Archivist_Endure_Elements **** **** **** **** **** **** **** **** +8551 Archivist_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +8552 Archivist_Quickened_Endure_Elements **** **** **** **** **** **** **** **** +8553 Archivist_Silent_Endure_Elements **** **** **** **** **** **** **** **** +8554 Archivist_Still_Endure_Elements **** **** **** **** **** **** **** **** +8555 Archivist_Entangle **** **** **** **** **** **** **** **** +8556 Archivist_Exteneded_Entangle **** **** **** **** **** **** **** **** +8557 Archivist_Quickened_Entangle **** **** **** **** **** **** **** **** +8558 Archivist_Silent_Entangle **** **** **** **** **** **** **** **** +8559 Archivist_Still_Entangle **** **** **** **** **** **** **** **** +8560 Archivist_Entropic_Shield **** **** **** **** **** **** **** **** +8561 Archivist_Exteneded_Entropic_Shield **** **** **** **** **** **** **** **** +8562 Archivist_Quickened_Entropic_Shield **** **** **** **** **** **** **** **** +8563 Archivist_Silent_Entropic_Shield **** **** **** **** **** **** **** **** +8564 Archivist_Still_Entropic_Shield **** **** **** **** **** **** **** **** +8565 Archivist_Expeditious_Retreat **** **** **** **** **** **** **** **** +8566 Archivist_Exteneded_Expeditious_Retreat **** **** **** **** **** **** **** **** +8567 Archivist_Quickened_Expeditious_Retreat **** **** **** **** **** **** **** **** +8568 Archivist_Silent_Expeditious_Retreat **** **** **** **** **** **** **** **** +8569 Archivist_Still_Expeditious_Retreat **** **** **** **** **** **** **** **** +8570 Archivist_EXTRACT_DRUG **** **** **** **** **** **** **** **** +8571 Archivist_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +8572 Archivist_EXTRACT_VODARE **** **** **** **** **** **** **** **** +8573 Archivist_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +8574 Archivist_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8575 Archivist_Quickened_EXTRACT_DRUG **** **** **** **** **** **** **** **** +8576 Archivist_Quickened_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +8577 Archivist_Quickened_EXTRACT_VODARE **** **** **** **** **** **** **** **** +8578 Archivist_Quickened_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +8579 Archivist_Quickened_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8580 Archivist_Silent_EXTRACT_DRUG **** **** **** **** **** **** **** **** +8581 Archivist_Silent_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +8582 Archivist_Silent_EXTRACT_VODARE **** **** **** **** **** **** **** **** +8583 Archivist_Silent_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +8584 Archivist_Silent_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8585 Archivist_Still_EXTRACT_DRUG **** **** **** **** **** **** **** **** +8586 Archivist_Still_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +8587 Archivist_Still_EXTRACT_VODARE **** **** **** **** **** **** **** **** +8588 Archivist_Still_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +8589 Archivist_Still_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8590 Archivist_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +8591 Archivist_Exteneded_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +8592 Archivist_Quickened_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +8593 Archivist_Still_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +8594 Archivist_Faerie_Fire **** **** **** **** **** **** **** **** +8595 Archivist_Exteneded_Faerie_Fire **** **** **** **** **** **** **** **** +8596 Archivist_Quickened_Faerie_Fire **** **** **** **** **** **** **** **** +8597 Archivist_Silent_Faerie_Fire **** **** **** **** **** **** **** **** +8598 Archivist_Still_Faerie_Fire **** **** **** **** **** **** **** **** +8599 Archivist_Grease **** **** **** **** **** **** **** **** +8600 Archivist_Exteneded_Grease **** **** **** **** **** **** **** **** +8601 Archivist_Quickened_Grease **** **** **** **** **** **** **** **** +8602 Archivist_Silent_Grease **** **** **** **** **** **** **** **** +8603 Archivist_Still_Grease **** **** **** **** **** **** **** **** +8604 Archivist_HEARTACHE **** **** **** **** **** **** **** **** +8605 Archivist_Exteneded_HEARTACHE **** **** **** **** **** **** **** **** +8606 Archivist_Quickened_HEARTACHE **** **** **** **** **** **** **** **** +8607 Archivist_Silent_HEARTACHE **** **** **** **** **** **** **** **** +8608 Archivist_Still_HEARTACHE **** **** **** **** **** **** **** **** +8609 Archivist_HideFromAnimals **** **** **** **** **** **** **** **** +8610 Archivist_Exteneded_HideFromAnimals **** **** **** **** **** **** **** **** +8611 Archivist_Quickened_HideFromAnimals **** **** **** **** **** **** **** **** +8612 Archivist_Still_HideFromAnimals **** **** **** **** **** **** **** **** +8613 Archivist_HideFromUndead **** **** **** **** **** **** **** **** +8614 Archivist_Exteneded_HideFromUndead **** **** **** **** **** **** **** **** +8615 Archivist_Quickened_HideFromUndead **** **** **** **** **** **** **** **** +8616 Archivist_Still_HideFromUndead **** **** **** **** **** **** **** **** +8617 Archivist_Identify **** **** **** **** **** **** **** **** +8618 Archivist_Exteneded_Identify **** **** **** **** **** **** **** **** +8619 Archivist_Quickened_Identify **** **** **** **** **** **** **** **** +8620 Archivist_Silent_Identify **** **** **** **** **** **** **** **** +8621 Archivist_Still_Identify **** **** **** **** **** **** **** **** +8622 Archivist_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8623 Archivist_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8624 Archivist_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8625 Archivist_Quickened_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8626 Archivist_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8627 Archivist_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +8628 Archivist_Spell_Jump **** **** **** **** **** **** **** **** +8629 Archivist_Exteneded_Spell_Jump **** **** **** **** **** **** **** **** +8630 Archivist_Quickened_Spell_Jump **** **** **** **** **** **** **** **** +8631 Archivist_Silent_Spell_Jump **** **** **** **** **** **** **** **** +8632 Archivist_Still_Spell_Jump **** **** **** **** **** **** **** **** +8633 Archivist_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8634 Archivist_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8635 Archivist_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8636 Archivist_Quickened_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8637 Archivist_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +8638 Archivist_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8639 Archivist_Empowered_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8640 Archivist_Exteneded_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8641 Archivist_Maximized_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8642 Archivist_Quickened_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8643 Archivist_Silent_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8644 Archivist_Still_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +8645 Archivist_Lesser_Vigor **** **** **** **** **** **** **** **** +8646 Archivist_Exteneded_Lesser_Vigor **** **** **** **** **** **** **** **** +8647 Archivist_Quickened_Lesser_Vigor **** **** **** **** **** **** **** **** +8648 Archivist_Silent_Lesser_Vigor **** **** **** **** **** **** **** **** +8649 Archivist_Still_Lesser_Vigor **** **** **** **** **** **** **** **** +8650 Archivist_Lionheart **** **** **** **** **** **** **** **** +8651 Archivist_Exteneded_Lionheart **** **** **** **** **** **** **** **** +8652 Archivist_Quickened_Lionheart **** **** **** **** **** **** **** **** +8653 Archivist_Silent_Lionheart **** **** **** **** **** **** **** **** +8654 Archivist_Still_Lionheart **** **** **** **** **** **** **** **** +8655 Archivist_Longstrider **** **** **** **** **** **** **** **** +8656 Archivist_Exteneded_Longstrider **** **** **** **** **** **** **** **** +8657 Archivist_Quickened_Longstrider **** **** **** **** **** **** **** **** +8658 Archivist_Silent_Longstrider **** **** **** **** **** **** **** **** +8659 Archivist_Still_Longstrider **** **** **** **** **** **** **** **** +8660 Archivist_Mage_Armor **** **** **** **** **** **** **** **** +8661 Archivist_Exteneded_Mage_Armor **** **** **** **** **** **** **** **** +8662 Archivist_Quickened_Mage_Armor **** **** **** **** **** **** **** **** +8663 Archivist_Silent_Mage_Armor **** **** **** **** **** **** **** **** +8664 Archivist_Still_Mage_Armor **** **** **** **** **** **** **** **** +8665 Archivist_Magic_Fang **** **** **** **** **** **** **** **** +8666 Archivist_Exteneded_Magic_Fang **** **** **** **** **** **** **** **** +8667 Archivist_Quickened_Magic_Fang **** **** **** **** **** **** **** **** +8668 Archivist_Silent_Magic_Fang **** **** **** **** **** **** **** **** +8669 Archivist_Still_Magic_Fang **** **** **** **** **** **** **** **** +8670 Archivist_Magic_Stone **** **** **** **** **** **** **** **** +8671 Archivist_Exteneded_Magic_Stone **** **** **** **** **** **** **** **** +8672 Archivist_Quickened_Magic_Stone **** **** **** **** **** **** **** **** +8673 Archivist_Silent_Magic_Stone **** **** **** **** **** **** **** **** +8674 Archivist_Still_Magic_Stone **** **** **** **** **** **** **** **** +8675 Archivist_Magic_Weapon **** **** **** **** **** **** **** **** +8676 Archivist_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +8677 Archivist_Quickened_Magic_Weapon **** **** **** **** **** **** **** **** +8678 Archivist_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +8679 Archivist_Still_Magic_Weapon **** **** **** **** **** **** **** **** +8680 Archivist_Necrotic_Awareness **** **** **** **** **** **** **** **** +8681 Archivist_Quickened_Necrotic_Awareness **** **** **** **** **** **** **** **** +8682 Archivist_Silent_Necrotic_Awareness **** **** **** **** **** **** **** **** +8683 Archivist_Still_Necrotic_Awareness **** **** **** **** **** **** **** **** +8684 Archivist_Obscuring_Mist **** **** **** **** **** **** **** **** +8685 Archivist_Exteneded_Obscuring_Mist **** **** **** **** **** **** **** **** +8686 Archivist_Quickened_Obscuring_Mist **** **** **** **** **** **** **** **** +8687 Archivist_Silent_Obscuring_Mist **** **** **** **** **** **** **** **** +8688 Archivist_Still_Obscuring_Mist **** **** **** **** **** **** **** **** +8689 Archivist_Protection_from_Chaos **** **** **** **** **** **** **** **** +8690 Archivist_Exteneded_Protection_from_Chaos **** **** **** **** **** **** **** **** +8691 Archivist_Quickened_Protection_from_Chaos **** **** **** **** **** **** **** **** +8692 Archivist_Silent_Protection_from_Chaos **** **** **** **** **** **** **** **** +8693 Archivist_Still_Protection_from_Chaos **** **** **** **** **** **** **** **** +8694 Archivist_Protection_from_Evil **** **** **** **** **** **** **** **** +8695 Archivist_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +8696 Archivist_Quickened_Protection_from_Evil **** **** **** **** **** **** **** **** +8697 Archivist_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +8698 Archivist_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +8699 Archivist_Protection_from_Good **** **** **** **** **** **** **** **** +8700 Archivist_Exteneded_Protection_from_Good **** **** **** **** **** **** **** **** +8701 Archivist_Quickened_Protection_from_Good **** **** **** **** **** **** **** **** +8702 Archivist_Silent_Protection_from_Good **** **** **** **** **** **** **** **** +8703 Archivist_Still_Protection_from_Good **** **** **** **** **** **** **** **** +8704 Archivist_Protection_from_Law **** **** **** **** **** **** **** **** +8705 Archivist_Exteneded_Protection_from_Law **** **** **** **** **** **** **** **** +8706 Archivist_Quickened_Protection_from_Law **** **** **** **** **** **** **** **** +8707 Archivist_Silent_Protection_from_Law **** **** **** **** **** **** **** **** +8708 Archivist_Still_Protection_from_Law **** **** **** **** **** **** **** **** +8709 Archivist_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8710 Archivist_Exteneded_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8711 Archivist_Quickened_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8712 Archivist_Silent_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8713 Archivist_Still_RAY_OF_HOPE **** **** **** **** **** **** **** **** +8714 Archivist_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8715 Archivist_Empowered_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8716 Archivist_Exteneded_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8717 Archivist_Maximized_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8718 Archivist_Quickened_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8719 Archivist_Silent_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8720 Archivist_Still_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +8721 Archivist_Remove_Fear **** **** **** **** **** **** **** **** +8722 Archivist_Exteneded_Remove_Fear **** **** **** **** **** **** **** **** +8723 Archivist_Quickened_Remove_Fear **** **** **** **** **** **** **** **** +8724 Archivist_Silent_Remove_Fear **** **** **** **** **** **** **** **** +8725 Archivist_Still_Remove_Fear **** **** **** **** **** **** **** **** +8726 Archivist_Sanctuary **** **** **** **** **** **** **** **** +8727 Archivist_Exteneded_Sanctuary **** **** **** **** **** **** **** **** +8728 Archivist_Quickened_Sanctuary **** **** **** **** **** **** **** **** +8729 Archivist_Silent_Sanctuary **** **** **** **** **** **** **** **** +8730 Archivist_Still_Sanctuary **** **** **** **** **** **** **** **** +8731 Archivist_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +8732 Archivist_Quickened_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +8733 Archivist_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +8734 Archivist_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +8735 Archivist_Shield **** **** **** **** **** **** **** **** +8736 Archivist_Exteneded_Shield **** **** **** **** **** **** **** **** +8737 Archivist_Quickened_Shield **** **** **** **** **** **** **** **** +8738 Archivist_Silent_Shield **** **** **** **** **** **** **** **** +8739 Archivist_Still_Shield **** **** **** **** **** **** **** **** +8740 Archivist_Shield_of_Faith **** **** **** **** **** **** **** **** +8741 Archivist_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +8742 Archivist_Quickened_Shield_of_Faith **** **** **** **** **** **** **** **** +8743 Archivist_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +8744 Archivist_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +8745 Archivist_Shillelagh **** **** **** **** **** **** **** **** +8746 Archivist_Exteneded_Shillelagh **** **** **** **** **** **** **** **** +8747 Archivist_Quickened_Shillelagh **** **** **** **** **** **** **** **** +8748 Archivist_Silent_Shillelagh **** **** **** **** **** **** **** **** +8749 Archivist_Still_Shillelagh **** **** **** **** **** **** **** **** +8750 Archivist_Sleep **** **** **** **** **** **** **** **** +8751 Archivist_Empowered_Sleep **** **** **** **** **** **** **** **** +8752 Archivist_Exteneded_Sleep **** **** **** **** **** **** **** **** +8753 Archivist_Maximized_Sleep **** **** **** **** **** **** **** **** +8754 Archivist_Quickened_Sleep **** **** **** **** **** **** **** **** +8755 Archivist_Silent_Sleep **** **** **** **** **** **** **** **** +8756 Archivist_Still_Sleep **** **** **** **** **** **** **** **** +8757 Archivist_Snillocs_Snowball **** **** **** **** **** **** **** **** +8758 Archivist_Empowered_Snillocs_Snowball **** **** **** **** **** **** **** **** +8759 Archivist_Maximized_Snillocs_Snowball **** **** **** **** **** **** **** **** +8760 Archivist_Quickened_Snillocs_Snowball **** **** **** **** **** **** **** **** +8761 Archivist_Silent_Snillocs_Snowball **** **** **** **** **** **** **** **** +8762 Archivist_Still_Snillocs_Snowball **** **** **** **** **** **** **** **** +8763 Archivist_SORROW **** **** **** **** **** **** **** **** +8764 Archivist_Quickened_SORROW **** **** **** **** **** **** **** **** +8765 Archivist_Silent_SORROW **** **** **** **** **** **** **** **** +8766 Archivist_Still_SORROW **** **** **** **** **** **** **** **** +8767 Archivist_Summon_Creature_I **** **** **** **** **** **** **** **** +8768 Archivist_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +8769 Archivist_Quickened_Summon_Creature_I **** **** **** **** **** **** **** **** +8770 Archivist_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +8771 Archivist_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +8772 Archivist_SummonUndeadI **** **** **** **** **** **** **** **** +8773 Archivist_Exteneded_SummonUndeadI **** **** **** **** **** **** **** **** +8774 Archivist_Quickened_SummonUndeadI **** **** **** **** **** **** **** **** +8775 Archivist_Silent_SummonUndeadI **** **** **** **** **** **** **** **** +8776 Archivist_Still_SummonUndeadI **** **** **** **** **** **** **** **** +8777 Archivist_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8778 Archivist_Exteneded_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8779 Archivist_Quickened_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8780 Archivist_Silent_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8781 Archivist_Still_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +8782 Archivist_ToweringOak **** **** **** **** **** **** **** **** +8783 Archivist_Exteneded_ToweringOak **** **** **** **** **** **** **** **** +8784 Archivist_Quickened_ToweringOak **** **** **** **** **** **** **** **** +8785 Archivist_Silent_ToweringOak **** **** **** **** **** **** **** **** +8786 Archivist_Still_ToweringOak **** **** **** **** **** **** **** **** +8787 Archivist_True_Strike **** **** **** **** **** **** **** **** +8788 Archivist_Quickened_True_Strike **** **** **** **** **** **** **** **** +8789 Archivist_Silent_True_Strike **** **** **** **** **** **** **** **** +8790 Archivist_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +8791 Archivist_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +8792 Archivist_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +8793 Archivist_VisionOfHeaven **** **** **** **** **** **** **** **** +8794 Archivist_Exteneded_VisionOfHeaven **** **** **** **** **** **** **** **** +8795 Archivist_Quickened_VisionOfHeaven **** **** **** **** **** **** **** **** +8796 Archivist_Silent_VisionOfHeaven **** **** **** **** **** **** **** **** +8797 Archivist_ADDICTION **** **** **** **** **** **** **** **** +8798 Archivist_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +8799 Archivist_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8800 Archivist_ADDICTION_VODARE **** **** **** **** **** **** **** **** +8801 Archivist_ADDICTION_AGONY **** **** **** **** **** **** **** **** +8802 Archivist_Quickened_ADDICTION **** **** **** **** **** **** **** **** +8803 Archivist_Quickened_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +8804 Archivist_Quickened_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8805 Archivist_Quickened_ADDICTION_VODARE **** **** **** **** **** **** **** **** +8806 Archivist_Quickened_ADDICTION_AGONY **** **** **** **** **** **** **** **** +8807 Archivist_Silent_ADDICTION **** **** **** **** **** **** **** **** +8808 Archivist_Silent_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +8809 Archivist_Silent_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8810 Archivist_Silent_ADDICTION_VODARE **** **** **** **** **** **** **** **** +8811 Archivist_Silent_ADDICTION_AGONY **** **** **** **** **** **** **** **** +8812 Archivist_Still_ADDICTION **** **** **** **** **** **** **** **** +8813 Archivist_Still_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +8814 Archivist_Still_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +8815 Archivist_Still_ADDICTION_VODARE **** **** **** **** **** **** **** **** +8816 Archivist_Still_ADDICTION_AGONY **** **** **** **** **** **** **** **** +8817 Archivist_Aid **** **** **** **** **** **** **** **** +8818 Archivist_Empowered_Aid **** **** **** **** **** **** **** **** +8819 Archivist_Exteneded_Aid **** **** **** **** **** **** **** **** +8820 Archivist_Maximized_Aid **** **** **** **** **** **** **** **** +8821 Archivist_Quickened_Aid **** **** **** **** **** **** **** **** +8822 Archivist_Silent_Aid **** **** **** **** **** **** **** **** +8823 Archivist_Still_Aid **** **** **** **** **** **** **** **** +8824 Archivist_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +8825 Archivist_Alter_Self_Learn **** **** **** **** **** **** **** **** +8826 Archivist_Alter_Self_Options **** **** **** **** **** **** **** **** +8827 Archivist_Alter_Self_QS1 **** **** **** **** **** **** **** **** +8828 Archivist_Alter_Self_QS2 **** **** **** **** **** **** **** **** +8829 Archivist_Alter_Self_QS3 **** **** **** **** **** **** **** **** +8830 Archivist_Exteneded_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +8831 Archivist_Exteneded_Alter_Self_Learn **** **** **** **** **** **** **** **** +8832 Archivist_Exteneded_Alter_Self_Options **** **** **** **** **** **** **** **** +8833 Archivist_Exteneded_Alter_Self_QS1 **** **** **** **** **** **** **** **** +8834 Archivist_Exteneded_Alter_Self_QS2 **** **** **** **** **** **** **** **** +8835 Archivist_Exteneded_Alter_Self_QS3 **** **** **** **** **** **** **** **** +8836 Archivist_Quickened_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +8837 Archivist_Quickened_Alter_Self_Learn **** **** **** **** **** **** **** **** +8838 Archivist_Quickened_Alter_Self_Options **** **** **** **** **** **** **** **** +8839 Archivist_Quickened_Alter_Self_QS1 **** **** **** **** **** **** **** **** +8840 Archivist_Quickened_Alter_Self_QS2 **** **** **** **** **** **** **** **** +8841 Archivist_Quickened_Alter_Self_QS3 **** **** **** **** **** **** **** **** +8842 Archivist_Silent_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +8843 Archivist_Silent_Alter_Self_Learn **** **** **** **** **** **** **** **** +8844 Archivist_Silent_Alter_Self_Options **** **** **** **** **** **** **** **** +8845 Archivist_Silent_Alter_Self_QS1 **** **** **** **** **** **** **** **** +8846 Archivist_Silent_Alter_Self_QS2 **** **** **** **** **** **** **** **** +8847 Archivist_Silent_Alter_Self_QS3 **** **** **** **** **** **** **** **** +8848 Archivist_Still_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +8849 Archivist_Still_Alter_Self_Learn **** **** **** **** **** **** **** **** +8850 Archivist_Still_Alter_Self_Options **** **** **** **** **** **** **** **** +8851 Archivist_Still_Alter_Self_QS1 **** **** **** **** **** **** **** **** +8852 Archivist_Still_Alter_Self_QS2 **** **** **** **** **** **** **** **** +8853 Archivist_Still_Alter_Self_QS3 **** **** **** **** **** **** **** **** +8854 Archivist_Animalistic_Power **** **** **** **** **** **** **** **** +8855 Archivist_Exteneded_Animalistic_Power **** **** **** **** **** **** **** **** +8856 Archivist_AuraOfGlory **** **** **** **** **** **** **** **** +8857 Archivist_Exteneded_AuraOfGlory **** **** **** **** **** **** **** **** +8858 Archivist_Quickened_AuraOfGlory **** **** **** **** **** **** **** **** +8859 Archivist_Silent_AuraOfGlory **** **** **** **** **** **** **** **** +8860 Archivist_Still_AuraOfGlory **** **** **** **** **** **** **** **** +8861 Archivist_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8862 Archivist_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8863 Archivist_Maximized_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8864 Archivist_Quickened_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8865 Archivist_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8866 Archivist_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +8867 Archivist_Barkskin **** **** **** **** **** **** **** **** +8868 Archivist_Exteneded_Barkskin **** **** **** **** **** **** **** **** +8869 Archivist_Quickened_Barkskin **** **** **** **** **** **** **** **** +8870 Archivist_Silent_Barkskin **** **** **** **** **** **** **** **** +8871 Archivist_Still_Barkskin **** **** **** **** **** **** **** **** +8872 Archivist_Benign_Transposition **** **** **** **** **** **** **** **** +8873 Archivist_Quickened_Benign_Transposition **** **** **** **** **** **** **** **** +8874 Archivist_Silent_Benign_Transposition **** **** **** **** **** **** **** **** +8875 Archivist_BladesOfFire **** **** **** **** **** **** **** **** +8876 Archivist_Exteneded_BladesOfFire **** **** **** **** **** **** **** **** +8877 Archivist_Quickened_BladesOfFire **** **** **** **** **** **** **** **** +8878 Archivist_Silent_BladesOfFire **** **** **** **** **** **** **** **** +8879 Archivist_Blood_Frenzy **** **** **** **** **** **** **** **** +8880 Archivist_Exteneded_Blood_Frenzy **** **** **** **** **** **** **** **** +8881 Archivist_Quickened_Blood_Frenzy **** **** **** **** **** **** **** **** +8882 Archivist_Silent_Blood_Frenzy **** **** **** **** **** **** **** **** +8883 Archivist_Still_Blood_Frenzy **** **** **** **** **** **** **** **** +8884 Archivist_Blur **** **** **** **** **** **** **** **** +8885 Archivist_Exteneded_Blur **** **** **** **** **** **** **** **** +8886 Archivist_Quickened_Blur **** **** **** **** **** **** **** **** +8887 Archivist_Silent_Blur **** **** **** **** **** **** **** **** +8888 Archivist_BONEBLAST **** **** **** **** **** **** **** **** +8889 Archivist_Quickened_BONEBLAST **** **** **** **** **** **** **** **** +8890 Archivist_Silent_BONEBLAST **** **** **** **** **** **** **** **** +8891 Archivist_Still_BONEBLAST **** **** **** **** **** **** **** **** +8892 Archivist_BrilliantEnergyArrows **** **** **** **** **** **** **** **** +8893 Archivist_Quickened_BrilliantEnergyArrows **** **** **** **** **** **** **** **** +8894 Archivist_Silent_BrilliantEnergyArrows **** **** **** **** **** **** **** **** +8895 Archivist_Bulls_Strength **** **** **** **** **** **** **** **** +8896 Archivist_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +8897 Archivist_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +8898 Archivist_Maximized_Bulls_Strength **** **** **** **** **** **** **** **** +8899 Archivist_Quickened_Bulls_Strength **** **** **** **** **** **** **** **** +8900 Archivist_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +8901 Archivist_Still_Bulls_Strength **** **** **** **** **** **** **** **** +8902 Archivist_Burning_Bolt **** **** **** **** **** **** **** **** +8903 Archivist_Empowered_Burning_Bolt **** **** **** **** **** **** **** **** +8904 Archivist_Maximized_Burning_Bolt **** **** **** **** **** **** **** **** +8905 Archivist_Quickened_Burning_Bolt **** **** **** **** **** **** **** **** +8906 Archivist_Silent_Burning_Bolt **** **** **** **** **** **** **** **** +8907 Archivist_Still_Burning_Bolt **** **** **** **** **** **** **** **** +8908 Archivist_Calm_Emotions **** **** **** **** **** **** **** **** +8909 Archivist_Exteneded_Calm_Emotions **** **** **** **** **** **** **** **** +8910 Archivist_Quickened_Calm_Emotions **** **** **** **** **** **** **** **** +8911 Archivist_Silent_Calm_Emotions **** **** **** **** **** **** **** **** +8912 Archivist_Still_Calm_Emotions **** **** **** **** **** **** **** **** +8913 Archivist_Cats_Grace **** **** **** **** **** **** **** **** +8914 Archivist_Empowered_Cats_Grace **** **** **** **** **** **** **** **** +8915 Archivist_Exteneded_Cats_Grace **** **** **** **** **** **** **** **** +8916 Archivist_Maximized_Cats_Grace **** **** **** **** **** **** **** **** +8917 Archivist_Quickened_Cats_Grace **** **** **** **** **** **** **** **** +8918 Archivist_Silent_Cats_Grace **** **** **** **** **** **** **** **** +8919 Archivist_Still_Cats_Grace **** **** **** **** **** **** **** **** +8920 Archivist_Charm_Person_or_Animal **** **** **** **** **** **** **** **** +8921 Archivist_Exteneded_Charm_Person_or_Animal **** **** **** **** **** **** **** **** +8922 Archivist_Quickened_Charm_Person_or_Animal **** **** **** **** **** **** **** **** +8923 Archivist_Silent_Charm_Person_or_Animal **** **** **** **** **** **** **** **** +8924 Archivist_Still_Charm_Person_or_Animal **** **** **** **** **** **** **** **** +8925 Archivist_Clarity_of_Mind **** **** **** **** **** **** **** **** +8926 Archivist_Exteneded_Clarity_of_Mind **** **** **** **** **** **** **** **** +8927 Archivist_Quickened_Clarity_of_Mind **** **** **** **** **** **** **** **** +8928 Archivist_Silent_Clarity_of_Mind **** **** **** **** **** **** **** **** +8929 Archivist_Still_Clarity_of_Mind **** **** **** **** **** **** **** **** +8930 Archivist_Consecrated_Aura **** **** **** **** **** **** **** **** +8931 Archivist_Exteneded_Consecrated_Aura **** **** **** **** **** **** **** **** +8932 Archivist_Quickened_Consecrated_Aura **** **** **** **** **** **** **** **** +8933 Archivist_Silent_Consecrated_Aura **** **** **** **** **** **** **** **** +8934 Archivist_Still_Consecrated_Aura **** **** **** **** **** **** **** **** +8935 Archivist_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8936 Archivist_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8937 Archivist_Maximized_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8938 Archivist_Quickened_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8939 Archivist_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8940 Archivist_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +8941 Archivist_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +8942 Archivist_Exteneded_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +8943 Archivist_Quickened_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +8944 Archivist_Silent_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +8945 Archivist_Still_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +8946 Archivist_Darkness **** **** **** **** **** **** **** **** +8947 Archivist_Exteneded_Darkness **** **** **** **** **** **** **** **** +8948 Archivist_Quickened_Darkness **** **** **** **** **** **** **** **** +8949 Archivist_Silent_Darkness **** **** **** **** **** **** **** **** +8950 Archivist_Death_Armor **** **** **** **** **** **** **** **** +8951 Archivist_Exteneded_Death_Armor **** **** **** **** **** **** **** **** +8952 Archivist_Quickened_Death_Armor **** **** **** **** **** **** **** **** +8953 Archivist_Silent_Death_Armor **** **** **** **** **** **** **** **** +8954 Archivist_Still_Death_Armor **** **** **** **** **** **** **** **** +8955 Archivist_Death_Knell **** **** **** **** **** **** **** **** +8956 Archivist_Empowered_Death_Knell **** **** **** **** **** **** **** **** +8957 Archivist_Exteneded_Death_Knell **** **** **** **** **** **** **** **** +8958 Archivist_Maximized_Death_Knell **** **** **** **** **** **** **** **** +8959 Archivist_Quickened_Death_Knell **** **** **** **** **** **** **** **** +8960 Archivist_Silent_Death_Knell **** **** **** **** **** **** **** **** +8961 Archivist_Still_Death_Knell **** **** **** **** **** **** **** **** +8962 Archivist_DEMONCALL **** **** **** **** **** **** **** **** +8963 Archivist_Quickened_DEMONCALL **** **** **** **** **** **** **** **** +8964 Archivist_Silent_DEMONCALL **** **** **** **** **** **** **** **** +8965 Archivist_Still_DEMONCALL **** **** **** **** **** **** **** **** +8966 Archivist_Divine_Protection **** **** **** **** **** **** **** **** +8967 Archivist_Exteneded_Divine_Protection **** **** **** **** **** **** **** **** +8968 Archivist_Quickened_Divine_Protection **** **** **** **** **** **** **** **** +8969 Archivist_Silent_Divine_Protection **** **** **** **** **** **** **** **** +8970 Archivist_Still_Divine_Protection **** **** **** **** **** **** **** **** +8971 Archivist_Eagle_Splendor **** **** **** **** **** **** **** **** +8972 Archivist_Empowered_Eagle_Splendor **** **** **** **** **** **** **** **** +8973 Archivist_Exteneded_Eagle_Splendor **** **** **** **** **** **** **** **** +8974 Archivist_Maximized_Eagle_Splendor **** **** **** **** **** **** **** **** +8975 Archivist_Quickened_Eagle_Splendor **** **** **** **** **** **** **** **** +8976 Archivist_Silent_Eagle_Splendor **** **** **** **** **** **** **** **** +8977 Archivist_Still_Eagle_Splendor **** **** **** **** **** **** **** **** +8978 Archivist_ELATION **** **** **** **** **** **** **** **** +8979 Archivist_Exteneded_ELATION **** **** **** **** **** **** **** **** +8980 Archivist_Quickened_ELATION **** **** **** **** **** **** **** **** +8981 Archivist_Silent_ELATION **** **** **** **** **** **** **** **** +8982 Archivist_Still_ELATION **** **** **** **** **** **** **** **** +8983 Archivist_Endurance **** **** **** **** **** **** **** **** +8984 Archivist_Empowered_Endurance **** **** **** **** **** **** **** **** +8985 Archivist_Exteneded_Endurance **** **** **** **** **** **** **** **** +8986 Archivist_Maximized_Endurance **** **** **** **** **** **** **** **** +8987 Archivist_Quickened_Endurance **** **** **** **** **** **** **** **** +8988 Archivist_Silent_Endurance **** **** **** **** **** **** **** **** +8989 Archivist_Still_Endurance **** **** **** **** **** **** **** **** +8990 Archivist_Find_Traps **** **** **** **** **** **** **** **** +8991 Archivist_Exteneded_Find_Traps **** **** **** **** **** **** **** **** +8992 Archivist_Quickened_Find_Traps **** **** **** **** **** **** **** **** +8993 Archivist_Silent_Find_Traps **** **** **** **** **** **** **** **** +8994 Archivist_Still_Find_Traps **** **** **** **** **** **** **** **** +8995 Archivist_FireTrap **** **** **** **** **** **** **** **** +8996 Archivist_Empowered_FireTrap **** **** **** **** **** **** **** **** +8997 Archivist_Maximized_FireTrap **** **** **** **** **** **** **** **** +8998 Archivist_Quickened_FireTrap **** **** **** **** **** **** **** **** +8999 Archivist_Silent_FireTrap **** **** **** **** **** **** **** **** +9000 Archivist_Still_FireTrap **** **** **** **** **** **** **** **** +9001 Archivist_Flame_Lash **** **** **** **** **** **** **** **** +9002 Archivist_Empowered_Flame_Lash **** **** **** **** **** **** **** **** +9003 Archivist_Maximized_Flame_Lash **** **** **** **** **** **** **** **** +9004 Archivist_Quickened_Flame_Lash **** **** **** **** **** **** **** **** +9005 Archivist_Silent_Flame_Lash **** **** **** **** **** **** **** **** +9006 Archivist_Still_Flame_Lash **** **** **** **** **** **** **** **** +9007 Archivist_FogCloud **** **** **** **** **** **** **** **** +9008 Archivist_Exteneded_FogCloud **** **** **** **** **** **** **** **** +9009 Archivist_Quickened_FogCloud **** **** **** **** **** **** **** **** +9010 Archivist_Silent_FogCloud **** **** **** **** **** **** **** **** +9011 Archivist_Foxs_Cunning **** **** **** **** **** **** **** **** +9012 Archivist_Empowered_Foxs_Cunning **** **** **** **** **** **** **** **** +9013 Archivist_Exteneded_Foxs_Cunning **** **** **** **** **** **** **** **** +9014 Archivist_Maximized_Foxs_Cunning **** **** **** **** **** **** **** **** +9015 Archivist_Quickened_Foxs_Cunning **** **** **** **** **** **** **** **** +9016 Archivist_Silent_Foxs_Cunning **** **** **** **** **** **** **** **** +9017 Archivist_Still_Foxs_Cunning **** **** **** **** **** **** **** **** +9018 Archivist_Ghoul_Touch **** **** **** **** **** **** **** **** +9019 Archivist_Exteneded_Ghoul_Touch **** **** **** **** **** **** **** **** +9020 Archivist_Quickened_Ghoul_Touch **** **** **** **** **** **** **** **** +9021 Archivist_Silent_Ghoul_Touch **** **** **** **** **** **** **** **** +9022 Archivist_Still_Ghoul_Touch **** **** **** **** **** **** **** **** +9023 Archivist_Hold_Animal **** **** **** **** **** **** **** **** +9024 Archivist_Exteneded_Hold_Animal **** **** **** **** **** **** **** **** +9025 Archivist_Quickened_Hold_Animal **** **** **** **** **** **** **** **** +9026 Archivist_Silent_Hold_Animal **** **** **** **** **** **** **** **** +9027 Archivist_Still_Hold_Animal **** **** **** **** **** **** **** **** +9028 Archivist_Hold_Person **** **** **** **** **** **** **** **** +9029 Archivist_Exteneded_Hold_Person **** **** **** **** **** **** **** **** +9030 Archivist_Quickened_Hold_Person **** **** **** **** **** **** **** **** +9031 Archivist_Silent_Hold_Person **** **** **** **** **** **** **** **** +9032 Archivist_Still_Hold_Person **** **** **** **** **** **** **** **** +9033 Archivist_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9034 Archivist_Empowered_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9035 Archivist_Maximized_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9036 Archivist_Quickened_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9037 Archivist_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9038 Archivist_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +9039 Archivist_Knock **** **** **** **** **** **** **** **** +9040 Archivist_Quickened_Knock **** **** **** **** **** **** **** **** +9041 Archivist_Still_Knock **** **** **** **** **** **** **** **** +9042 Archivist_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +9043 Archivist_Quickened_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +9044 Archivist_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +9045 Archivist_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +9046 Archivist_Lesser_Dispel **** **** **** **** **** **** **** **** +9047 Archivist_Silent_Lesser_Dispel **** **** **** **** **** **** **** **** +9048 Archivist_Still_Lesser_Dispel **** **** **** **** **** **** **** **** +9049 Archivist_Lesser_Restoration **** **** **** **** **** **** **** **** +9050 Archivist_Quickened_Lesser_Restoration **** **** **** **** **** **** **** **** +9051 Archivist_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +9052 Archivist_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +9053 Archivist_Living_Undeath **** **** **** **** **** **** **** **** +9054 Archivist_Exteneded_Living_Undeath **** **** **** **** **** **** **** **** +9055 Archivist_Quickened_Living_Undeath **** **** **** **** **** **** **** **** +9056 Archivist_Silent_Living_Undeath **** **** **** **** **** **** **** **** +9057 Archivist_Still_Living_Undeath **** **** **** **** **** **** **** **** +9058 Archivist_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9059 Archivist_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9060 Archivist_Quickened_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9061 Archivist_Magic_Missile **** **** **** **** **** **** **** **** +9062 Archivist_Empowered_Magic_Missile **** **** **** **** **** **** **** **** +9063 Archivist_Maximized_Magic_Missile **** **** **** **** **** **** **** **** +9064 Archivist_Quickened_Magic_Missile **** **** **** **** **** **** **** **** +9065 Archivist_Silent_Magic_Missile **** **** **** **** **** **** **** **** +9066 Archivist_Still_Magic_Missile **** **** **** **** **** **** **** **** +9067 Archivist_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9068 Archivist_Empowered_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9069 Archivist_Maximized_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9070 Archivist_Quickened_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9071 Archivist_Silent_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9072 Archivist_Still_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +9073 Archivist_Necrotic_Cyst **** **** **** **** **** **** **** **** +9074 Archivist_Quickened_Necrotic_Cyst **** **** **** **** **** **** **** **** +9075 Archivist_Silent_Necrotic_Cyst **** **** **** **** **** **** **** **** +9076 Archivist_Still_Necrotic_Cyst **** **** **** **** **** **** **** **** +9077 Archivist_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9078 Archivist_Empowered_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9079 Archivist_Maximized_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9080 Archivist_Quickened_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9081 Archivist_Silent_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9082 Archivist_Still_Negative_Energy_Ray **** **** **** **** **** **** **** **** +9083 Archivist_One_With_The_Land **** **** **** **** **** **** **** **** +9084 Archivist_Exteneded_One_With_The_Land **** **** **** **** **** **** **** **** +9085 Archivist_Quickened_One_With_The_Land **** **** **** **** **** **** **** **** +9086 Archivist_Silent_One_With_The_Land **** **** **** **** **** **** **** **** +9087 Archivist_Still_One_With_The_Land **** **** **** **** **** **** **** **** +9088 Archivist_Owls_Wisdom **** **** **** **** **** **** **** **** +9089 Archivist_Empowered_Owls_Wisdom **** **** **** **** **** **** **** **** +9090 Archivist_Exteneded_Owls_Wisdom **** **** **** **** **** **** **** **** +9091 Archivist_Maximized_Owls_Wisdom **** **** **** **** **** **** **** **** +9092 Archivist_Quickened_Owls_Wisdom **** **** **** **** **** **** **** **** +9093 Archivist_Silent_Owls_Wisdom **** **** **** **** **** **** **** **** +9094 Archivist_Still_Owls_Wisdom **** **** **** **** **** **** **** **** +9095 Archivist_Remove_Paralysis **** **** **** **** **** **** **** **** +9096 Archivist_Quickened_Remove_Paralysis **** **** **** **** **** **** **** **** +9097 Archivist_Silent_Remove_Paralysis **** **** **** **** **** **** **** **** +9098 Archivist_Still_Remove_Paralysis **** **** **** **** **** **** **** **** +9099 Archivist_Resist_Elements **** **** **** **** **** **** **** **** +9100 Archivist_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +9101 Archivist_Quickened_Resist_Elements **** **** **** **** **** **** **** **** +9102 Archivist_Silent_Resist_Elements **** **** **** **** **** **** **** **** +9103 Archivist_Still_Resist_Elements **** **** **** **** **** **** **** **** +9104 Archivist_ShieldOther **** **** **** **** **** **** **** **** +9105 Archivist_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +9106 Archivist_Quickened_ShieldOther **** **** **** **** **** **** **** **** +9107 Archivist_Silent_ShieldOther **** **** **** **** **** **** **** **** +9108 Archivist_Still_ShieldOther **** **** **** **** **** **** **** **** +9109 Archivist_Silence **** **** **** **** **** **** **** **** +9110 Archivist_Exteneded_Silence **** **** **** **** **** **** **** **** +9111 Archivist_Quickened_Silence **** **** **** **** **** **** **** **** +9112 Archivist_Silent_Silence **** **** **** **** **** **** **** **** +9113 Archivist_Still_Silence **** **** **** **** **** **** **** **** +9114 Archivist_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9115 Archivist_Empowered_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9116 Archivist_Maximized_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9117 Archivist_Quickened_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9118 Archivist_Silent_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9119 Archivist_Still_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +9120 Archivist_Sound_Burst **** **** **** **** **** **** **** **** +9121 Archivist_Maximized_Sound_Burst **** **** **** **** **** **** **** **** +9122 Archivist_Quickened_Sound_Burst **** **** **** **** **** **** **** **** +9123 Archivist_Silent_Sound_Burst **** **** **** **** **** **** **** **** +9124 Archivist_Still_Sound_Burst **** **** **** **** **** **** **** **** +9125 Archivist_SpellslayerArrow **** **** **** **** **** **** **** **** +9126 Archivist_Silent_SpellslayerArrow **** **** **** **** **** **** **** **** +9127 Archivist_Still_SpellslayerArrow **** **** **** **** **** **** **** **** +9128 Archivist_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9129 Archivist_Empowered_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9130 Archivist_Maximized_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9131 Archivist_Quickened_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9132 Archivist_Silent_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9133 Archivist_Still_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +9134 Archivist_Stone_Bones **** **** **** **** **** **** **** **** +9135 Archivist_Exteneded_Stone_Bones **** **** **** **** **** **** **** **** +9136 Archivist_Quickened_Stone_Bones **** **** **** **** **** **** **** **** +9137 Archivist_Silent_Stone_Bones **** **** **** **** **** **** **** **** +9138 Archivist_Still_Stone_Bones **** **** **** **** **** **** **** **** +9139 Archivist_Summon_Creature_II **** **** **** **** **** **** **** **** +9140 Archivist_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +9141 Archivist_Quickened_Summon_Creature_II **** **** **** **** **** **** **** **** +9142 Archivist_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +9143 Archivist_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +9144 Archivist_SummonUndeadII **** **** **** **** **** **** **** **** +9145 Archivist_Exteneded_SummonUndeadII **** **** **** **** **** **** **** **** +9146 Archivist_Quickened_SummonUndeadII **** **** **** **** **** **** **** **** +9147 Archivist_Silent_SummonUndeadII **** **** **** **** **** **** **** **** +9148 Archivist_Still_SummonUndeadII **** **** **** **** **** **** **** **** +9149 Archivist_Treeshape **** **** **** **** **** **** **** **** +9150 Archivist_Exteneded_Treeshape **** **** **** **** **** **** **** **** +9151 Archivist_Quickened_Treeshape **** **** **** **** **** **** **** **** +9152 Archivist_Silent_Treeshape **** **** **** **** **** **** **** **** +9153 Archivist_Still_Treeshape **** **** **** **** **** **** **** **** +9154 Archivist_Ultravision **** **** **** **** **** **** **** **** +9155 Archivist_Exteneded_Ultravision **** **** **** **** **** **** **** **** +9156 Archivist_Silent_Ultravision **** **** **** **** **** **** **** **** +9157 Archivist_Still_Ultravision **** **** **** **** **** **** **** **** +9158 Archivist_UndetectableAlignment **** **** **** **** **** **** **** **** +9159 Archivist_Exteneded_UndetectableAlignment **** **** **** **** **** **** **** **** +9160 Archivist_Quickened_UndetectableAlignment **** **** **** **** **** **** **** **** +9161 Archivist_Silent_UndetectableAlignment **** **** **** **** **** **** **** **** +9162 Archivist_Still_UndetectableAlignment **** **** **** **** **** **** **** **** +9163 Archivist_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +9164 Archivist_Exteneded_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +9165 Archivist_Quickened_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +9166 Archivist_Still_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +9167 Archivist_Web **** **** **** **** **** **** **** **** +9168 Archivist_Exteneded_Web **** **** **** **** **** **** **** **** +9169 Archivist_Quickened_Web **** **** **** **** **** **** **** **** +9170 Archivist_Silent_Web **** **** **** **** **** **** **** **** +9171 Archivist_Still_Web **** **** **** **** **** **** **** **** +9172 Archivist_Wolfskin **** **** **** **** **** **** **** **** +9173 Archivist_Exteneded_Wolfskin **** **** **** **** **** **** **** **** +9174 Archivist_Quickened_Wolfskin **** **** **** **** **** **** **** **** +9175 Archivist_Silent_Wolfskin **** **** **** **** **** **** **** **** +9176 Archivist_Still_Wolfskin **** **** **** **** **** **** **** **** +9177 Archivist_Animate_Dead **** **** **** **** **** **** **** **** +9178 Archivist_Exteneded_Animate_Dead **** **** **** **** **** **** **** **** +9179 Archivist_Quickened_Animate_Dead **** **** **** **** **** **** **** **** +9180 Archivist_Silent_Animate_Dead **** **** **** **** **** **** **** **** +9181 Archivist_Still_Animate_Dead **** **** **** **** **** **** **** **** +9182 Archivist_ArrowSplit **** **** **** **** **** **** **** **** +9183 Archivist_Silent_ArrowSplit **** **** **** **** **** **** **** **** +9184 Archivist_ArrowStorm **** **** **** **** **** **** **** **** +9185 Archivist_Silent_ArrowStorm **** **** **** **** **** **** **** **** +9186 Archivist_Bestow_Curse **** **** **** **** **** **** **** **** +9187 Archivist_Quickened_Bestow_Curse **** **** **** **** **** **** **** **** +9188 Archivist_Silent_Bestow_Curse **** **** **** **** **** **** **** **** +9189 Archivist_Still_Bestow_Curse **** **** **** **** **** **** **** **** +9190 Archivist_Blacklight **** **** **** **** **** **** **** **** +9191 Archivist_Exteneded_Blacklight **** **** **** **** **** **** **** **** +9192 Archivist_Quickened_Blacklight **** **** **** **** **** **** **** **** +9193 Archivist_Silent_Blacklight **** **** **** **** **** **** **** **** +9194 Archivist_Still_Blacklight **** **** **** **** **** **** **** **** +9195 Archivist_Blade_Thirst **** **** **** **** **** **** **** **** +9196 Archivist_Exteneded_Blade_Thirst **** **** **** **** **** **** **** **** +9197 Archivist_Quickened_Blade_Thirst **** **** **** **** **** **** **** **** +9198 Archivist_Silent_Blade_Thirst **** **** **** **** **** **** **** **** +9199 Archivist_Still_Blade_Thirst **** **** **** **** **** **** **** **** +9200 Archivist_Blessing_of_bahamut **** **** **** **** **** **** **** **** +9201 Archivist_Exteneded_Blessing_of_bahamut **** **** **** **** **** **** **** **** +9202 Archivist_Quickened_Blessing_of_bahamut **** **** **** **** **** **** **** **** +9203 Archivist_Silent_Blessing_of_bahamut **** **** **** **** **** **** **** **** +9204 Archivist_Still_Blessing_of_bahamut **** **** **** **** **** **** **** **** +9205 Archivist_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9206 Archivist_Exteneded_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9207 Archivist_Quickened_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9208 Archivist_Silent_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9209 Archivist_BONEBLADE **** **** **** **** **** **** **** **** +9210 Archivist_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +9211 Archivist_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +9212 Archivist_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +9213 Archivist_Exteneded_BONEBLADE **** **** **** **** **** **** **** **** +9214 Archivist_Exteneded_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +9215 Archivist_Exteneded_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +9216 Archivist_Exteneded_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +9217 Archivist_Quickened_BONEBLADE **** **** **** **** **** **** **** **** +9218 Archivist_Quickened_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +9219 Archivist_Quickened_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +9220 Archivist_Quickened_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +9221 Archivist_Silent_BONEBLADE **** **** **** **** **** **** **** **** +9222 Archivist_Silent_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +9223 Archivist_Silent_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +9224 Archivist_Silent_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +9225 Archivist_Still_BONEBLADE **** **** **** **** **** **** **** **** +9226 Archivist_Still_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +9227 Archivist_Still_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +9228 Archivist_Still_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +9229 Archivist_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +9230 Archivist_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +9231 Archivist_Quickened_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +9232 Archivist_Call_Lightning **** **** **** **** **** **** **** **** +9233 Archivist_Empowered_Call_Lightning **** **** **** **** **** **** **** **** +9234 Archivist_Maximized_Call_Lightning **** **** **** **** **** **** **** **** +9235 Archivist_Quickened_Call_Lightning **** **** **** **** **** **** **** **** +9236 Archivist_Silent_Call_Lightning **** **** **** **** **** **** **** **** +9237 Archivist_Still_Call_Lightning **** **** **** **** **** **** **** **** +9238 Archivist_Charm_Monster **** **** **** **** **** **** **** **** +9239 Archivist_Exteneded_Charm_Monster **** **** **** **** **** **** **** **** +9240 Archivist_Quickened_Charm_Monster **** **** **** **** **** **** **** **** +9241 Archivist_Silent_Charm_Monster **** **** **** **** **** **** **** **** +9242 Archivist_Still_Charm_Monster **** **** **** **** **** **** **** **** +9243 Archivist_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +9244 Archivist_Exteneded_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +9245 Archivist_Quickened_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +9246 Archivist_Silent_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +9247 Archivist_Still_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +9248 Archivist_Clarity **** **** **** **** **** **** **** **** +9249 Archivist_Exteneded_Clarity **** **** **** **** **** **** **** **** +9250 Archivist_Quickened_Clarity **** **** **** **** **** **** **** **** +9251 Archivist_Still_Clarity **** **** **** **** **** **** **** **** +9252 Archivist_Close_Wounds **** **** **** **** **** **** **** **** +9253 Archivist_Empowered_Close_Wounds **** **** **** **** **** **** **** **** +9254 Archivist_Maximized_Close_Wounds **** **** **** **** **** **** **** **** +9255 Archivist_Quickened_Close_Wounds **** **** **** **** **** **** **** **** +9256 Archivist_Silent_Close_Wounds **** **** **** **** **** **** **** **** +9257 Archivist_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +9258 Archivist_Quickened_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +9259 Archivist_Silent_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +9260 Archivist_Still_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +9261 Archivist_Contagion **** **** **** **** **** **** **** **** +9262 Archivist_Quickened_Contagion **** **** **** **** **** **** **** **** +9263 Archivist_Silent_Contagion **** **** **** **** **** **** **** **** +9264 Archivist_Still_Contagion **** **** **** **** **** **** **** **** +9265 Archivist_Continual_Flame **** **** **** **** **** **** **** **** +9266 Archivist_Quickened_Continual_Flame **** **** **** **** **** **** **** **** +9267 Archivist_Silent_Continual_Flame **** **** **** **** **** **** **** **** +9268 Archivist_Still_Continual_Flame **** **** **** **** **** **** **** **** +9269 Archivist_Crown_Might **** **** **** **** **** **** **** **** +9270 Archivist_Exteneded_Crown_Might **** **** **** **** **** **** **** **** +9271 Archivist_Quickened_Crown_Might **** **** **** **** **** **** **** **** +9272 Archivist_Silent_Crown_Might **** **** **** **** **** **** **** **** +9273 Archivist_Still_Crown_Might **** **** **** **** **** **** **** **** +9274 Archivist_Crown_Protection **** **** **** **** **** **** **** **** +9275 Archivist_Exteneded_Crown_Protection **** **** **** **** **** **** **** **** +9276 Archivist_Quickened_Crown_Protection **** **** **** **** **** **** **** **** +9277 Archivist_Silent_Crown_Protection **** **** **** **** **** **** **** **** +9278 Archivist_Still_Crown_Protection **** **** **** **** **** **** **** **** +9279 Archivist_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9280 Archivist_Empowered_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9281 Archivist_Maximized_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9282 Archivist_Quickened_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9283 Archivist_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9284 Archivist_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +9285 Archivist_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +9286 Archivist_Exteneded_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +9287 Archivist_Quickened_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +9288 Archivist_Silent_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +9289 Archivist_Still_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +9290 Archivist_Darkfire **** **** **** **** **** **** **** **** +9291 Archivist_Exteneded_Darkfire **** **** **** **** **** **** **** **** +9292 Archivist_Quickened_Darkfire **** **** **** **** **** **** **** **** +9293 Archivist_Silent_Darkfire **** **** **** **** **** **** **** **** +9294 Archivist_Still_Darkfire **** **** **** **** **** **** **** **** +9295 Archivist_DarkflameArrow **** **** **** **** **** **** **** **** +9296 Archivist_Silent_DarkflameArrow **** **** **** **** **** **** **** **** +9297 Archivist_Daylight **** **** **** **** **** **** **** **** +9298 Archivist_Exteneded_Daylight **** **** **** **** **** **** **** **** +9299 Archivist_Quickened_Daylight **** **** **** **** **** **** **** **** +9300 Archivist_Silent_Daylight **** **** **** **** **** **** **** **** +9301 Archivist_Still_Daylight **** **** **** **** **** **** **** **** +9302 Archivist_DeeperDarkness **** **** **** **** **** **** **** **** +9303 Archivist_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +9304 Archivist_Quickened_DeeperDarkness **** **** **** **** **** **** **** **** +9305 Archivist_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +9306 Archivist_DEVILS_EYE **** **** **** **** **** **** **** **** +9307 Archivist_Quickened_DEVILS_EYE **** **** **** **** **** **** **** **** +9308 Archivist_Silent_DEVILS_EYE **** **** **** **** **** **** **** **** +9309 Archivist_Still_DEVILS_EYE **** **** **** **** **** **** **** **** +9310 Archivist_Dispel_Magic **** **** **** **** **** **** **** **** +9311 Archivist_Quickened_Dispel_Magic **** **** **** **** **** **** **** **** +9312 Archivist_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +9313 Archivist_Still_Dispel_Magic **** **** **** **** **** **** **** **** +9314 Archivist_Dominate_Animal **** **** **** **** **** **** **** **** +9315 Archivist_Exteneded_Dominate_Animal **** **** **** **** **** **** **** **** +9316 Archivist_Quickened_Dominate_Animal **** **** **** **** **** **** **** **** +9317 Archivist_Silent_Dominate_Animal **** **** **** **** **** **** **** **** +9318 Archivist_Still_Dominate_Animal **** **** **** **** **** **** **** **** +9319 Archivist_ENERGIZE_POTION **** **** **** **** **** **** **** **** +9320 Archivist_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +9321 Archivist_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +9322 Archivist_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +9323 Archivist_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +9324 Archivist_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +9325 Archivist_Quickened_ENERGIZE_POTION **** **** **** **** **** **** **** **** +9326 Archivist_Quickened_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +9327 Archivist_Quickened_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +9328 Archivist_Quickened_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +9329 Archivist_Quickened_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +9330 Archivist_Quickened_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +9331 Archivist_Silent_ENERGIZE_POTION **** **** **** **** **** **** **** **** +9332 Archivist_Silent_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +9333 Archivist_Silent_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +9334 Archivist_Silent_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +9335 Archivist_Silent_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +9336 Archivist_Silent_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +9337 Archivist_Still_ENERGIZE_POTION **** **** **** **** **** **** **** **** +9338 Archivist_Still_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +9339 Archivist_Still_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +9340 Archivist_Still_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +9341 Archivist_Still_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +9342 Archivist_Still_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +9343 Archivist_Energy_Aegis **** **** **** **** **** **** **** **** +9344 Archivist_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +9345 Archivist_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +9346 Archivist_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +9347 Archivist_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +9348 Archivist_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +9349 Archivist_Exteneded_Energy_Aegis **** **** **** **** **** **** **** **** +9350 Archivist_Exteneded_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +9351 Archivist_Exteneded_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +9352 Archivist_Exteneded_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +9353 Archivist_Exteneded_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +9354 Archivist_Exteneded_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +9355 Archivist_Quickened_Energy_Aegis **** **** **** **** **** **** **** **** +9356 Archivist_Quickened_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +9357 Archivist_Quickened_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +9358 Archivist_Quickened_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +9359 Archivist_Quickened_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +9360 Archivist_Quickened_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +9361 Archivist_Silent_Energy_Aegis **** **** **** **** **** **** **** **** +9362 Archivist_Silent_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +9363 Archivist_Silent_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +9364 Archivist_Silent_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +9365 Archivist_Silent_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +9366 Archivist_Silent_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +9367 Archivist_Still_Energy_Aegis **** **** **** **** **** **** **** **** +9368 Archivist_Still_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +9369 Archivist_Still_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +9370 Archivist_Still_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +9371 Archivist_Still_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +9372 Archivist_Still_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +9373 Archivist_FLESH_RIPPER **** **** **** **** **** **** **** **** +9374 Archivist_Empowered_FLESH_RIPPER **** **** **** **** **** **** **** **** +9375 Archivist_Maximized_FLESH_RIPPER **** **** **** **** **** **** **** **** +9376 Archivist_Quickened_FLESH_RIPPER **** **** **** **** **** **** **** **** +9377 Archivist_Silent_FLESH_RIPPER **** **** **** **** **** **** **** **** +9378 Archivist_Still_FLESH_RIPPER **** **** **** **** **** **** **** **** +9379 Archivist_Forceblast **** **** **** **** **** **** **** **** +9380 Archivist_Empowered_Forceblast **** **** **** **** **** **** **** **** +9381 Archivist_Maximized_Forceblast **** **** **** **** **** **** **** **** +9382 Archivist_Quickened_Forceblast **** **** **** **** **** **** **** **** +9383 Archivist_Silent_Forceblast **** **** **** **** **** **** **** **** +9384 Archivist_Still_Forceblast **** **** **** **** **** **** **** **** +9385 Archivist_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9386 Archivist_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9387 Archivist_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9388 Archivist_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9389 Archivist_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9390 Archivist_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9391 Archivist_Empowered_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9392 Archivist_Empowered_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9393 Archivist_Empowered_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9394 Archivist_Empowered_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9395 Archivist_Empowered_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9396 Archivist_Empowered_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9397 Archivist_Exteneded_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9398 Archivist_Exteneded_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9399 Archivist_Exteneded_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9400 Archivist_Exteneded_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9401 Archivist_Exteneded_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9402 Archivist_Exteneded_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9403 Archivist_Maximized_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9404 Archivist_Maximized_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9405 Archivist_Maximized_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9406 Archivist_Maximized_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9407 Archivist_Maximized_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9408 Archivist_Maximized_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9409 Archivist_Quickened_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9410 Archivist_Quickened_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9411 Archivist_Quickened_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9412 Archivist_Quickened_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9413 Archivist_Quickened_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9414 Archivist_Quickened_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9415 Archivist_Silent_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9416 Archivist_Silent_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9417 Archivist_Silent_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9418 Archivist_Silent_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9419 Archivist_Silent_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9420 Archivist_Silent_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9421 Archivist_Still_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +9422 Archivist_Still_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +9423 Archivist_Still_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +9424 Archivist_Still_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +9425 Archivist_Still_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +9426 Archivist_Still_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +9427 Archivist_Greater_Magic_Fang **** **** **** **** **** **** **** **** +9428 Archivist_Exteneded_Greater_Magic_Fang **** **** **** **** **** **** **** **** +9429 Archivist_Quickened_Greater_Magic_Fang **** **** **** **** **** **** **** **** +9430 Archivist_Silent_Greater_Magic_Fang **** **** **** **** **** **** **** **** +9431 Archivist_Still_Greater_Magic_Fang **** **** **** **** **** **** **** **** +9432 Archivist_Greenfire **** **** **** **** **** **** **** **** +9433 Archivist_Empowered_Greenfire **** **** **** **** **** **** **** **** +9434 Archivist_Exteneded_Greenfire **** **** **** **** **** **** **** **** +9435 Archivist_Maximized_Greenfire **** **** **** **** **** **** **** **** +9436 Archivist_Quickened_Greenfire **** **** **** **** **** **** **** **** +9437 Archivist_Silent_Greenfire **** **** **** **** **** **** **** **** +9438 Archivist_Still_Greenfire **** **** **** **** **** **** **** **** +9439 Archivist_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9440 Archivist_Empowered_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9441 Archivist_Maximized_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9442 Archivist_Quickened_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9443 Archivist_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9444 Archivist_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +9445 Archivist_Healing_Sting **** **** **** **** **** **** **** **** +9446 Archivist_Empowered_Healing_Sting **** **** **** **** **** **** **** **** +9447 Archivist_Maximized_Healing_Sting **** **** **** **** **** **** **** **** +9448 Archivist_Quickened_Healing_Sting **** **** **** **** **** **** **** **** +9449 Archivist_Silent_Healing_Sting **** **** **** **** **** **** **** **** +9450 Archivist_Still_Healing_Sting **** **** **** **** **** **** **** **** +9451 Archivist_Heroism **** **** **** **** **** **** **** **** +9452 Archivist_Exteneded_Heroism **** **** **** **** **** **** **** **** +9453 Archivist_Quickened_Heroism **** **** **** **** **** **** **** **** +9454 Archivist_Silent_Heroism **** **** **** **** **** **** **** **** +9455 Archivist_Still_Heroism **** **** **** **** **** **** **** **** +9456 Archivist_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9457 Archivist_Empowered_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9458 Archivist_Exteneded_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9459 Archivist_Maximized_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9460 Archivist_Quickened_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9461 Archivist_Silent_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9462 Archivist_Still_Infestation_of_Maggots **** **** **** **** **** **** **** **** +9463 Archivist_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9464 Archivist_Empowered_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9465 Archivist_Maximized_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9466 Archivist_Quickened_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9467 Archivist_Silent_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9468 Archivist_Still_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +9469 Archivist_Invisibility **** **** **** **** **** **** **** **** +9470 Archivist_Exteneded_Invisibility **** **** **** **** **** **** **** **** +9471 Archivist_Quickened_Invisibility **** **** **** **** **** **** **** **** +9472 Archivist_Silent_Invisibility **** **** **** **** **** **** **** **** +9473 Archivist_Still_Invisibility **** **** **** **** **** **** **** **** +9474 Archivist_Invisibility_Purge **** **** **** **** **** **** **** **** +9475 Archivist_Exteneded_Invisibility_Purge **** **** **** **** **** **** **** **** +9476 Archivist_Quickened_Invisibility_Purge **** **** **** **** **** **** **** **** +9477 Archivist_Silent_Invisibility_Purge **** **** **** **** **** **** **** **** +9478 Archivist_Still_Invisibility_Purge **** **** **** **** **** **** **** **** +9479 Archivist_Invisibility_Sphere **** **** **** **** **** **** **** **** +9480 Archivist_Exteneded_Invisibility_Sphere **** **** **** **** **** **** **** **** +9481 Archivist_Quickened_Invisibility_Sphere **** **** **** **** **** **** **** **** +9482 Archivist_Silent_Invisibility_Sphere **** **** **** **** **** **** **** **** +9483 Archivist_Still_Invisibility_Sphere **** **** **** **** **** **** **** **** +9484 Archivist_Keen_Edge **** **** **** **** **** **** **** **** +9485 Archivist_Exteneded_Keen_Edge **** **** **** **** **** **** **** **** +9486 Archivist_Quickened_Keen_Edge **** **** **** **** **** **** **** **** +9487 Archivist_Silent_Keen_Edge **** **** **** **** **** **** **** **** +9488 Archivist_Still_Keen_Edge **** **** **** **** **** **** **** **** +9489 Archivist_Legions_Conviction **** **** **** **** **** **** **** **** +9490 Archivist_Exteneded_Legions_Conviction **** **** **** **** **** **** **** **** +9491 Archivist_Quickened_Legions_Conviction **** **** **** **** **** **** **** **** +9492 Archivist_Silent_Legions_Conviction **** **** **** **** **** **** **** **** +9493 Archivist_Still_Legions_Conviction **** **** **** **** **** **** **** **** +9494 Archivist_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +9495 Archivist_Exteneded_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +9496 Archivist_Quickened_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +9497 Archivist_Silent_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +9498 Archivist_Still_Legions_Curse_of_Impending_Blades **** **** **** **** **** **** **** **** +9499 Archivist_Lightning_Bolt **** **** **** **** **** **** **** **** +9500 Archivist_Empowered_Lightning_Bolt **** **** **** **** **** **** **** **** +9501 Archivist_Maximized_Lightning_Bolt **** **** **** **** **** **** **** **** +9502 Archivist_Quickened_Lightning_Bolt **** **** **** **** **** **** **** **** +9503 Archivist_Silent_Lightning_Bolt **** **** **** **** **** **** **** **** +9504 Archivist_Still_Lightning_Bolt **** **** **** **** **** **** **** **** +9505 Archivist_LocateObject **** **** **** **** **** **** **** **** +9506 Archivist_Exteneded_LocateObject **** **** **** **** **** **** **** **** +9507 Archivist_Quickened_LocateObject **** **** **** **** **** **** **** **** +9508 Archivist_Silent_LocateObject **** **** **** **** **** **** **** **** +9509 Archivist_Still_LocateObject **** **** **** **** **** **** **** **** +9510 Archivist_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +9511 Archivist_Exteneded_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +9512 Archivist_Quickened_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +9513 Archivist_Silent_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +9514 Archivist_Still_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +9515 Archivist_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +9516 Archivist_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +9517 Archivist_Quickened_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +9518 Archivist_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +9519 Archivist_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +9520 Archivist_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +9521 Archivist_Exteneded_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +9522 Archivist_Quickened_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +9523 Archivist_Silent_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +9524 Archivist_Still_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +9525 Archivist_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +9526 Archivist_Exteneded_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +9527 Archivist_Quickened_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +9528 Archivist_Silent_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +9529 Archivist_Still_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +9530 Archivist_Magic_Vestment **** **** **** **** **** **** **** **** +9531 Archivist_Exteneded_Magic_Vestment **** **** **** **** **** **** **** **** +9532 Archivist_Quickened_Magic_Vestment **** **** **** **** **** **** **** **** +9533 Archivist_Silent_Magic_Vestment **** **** **** **** **** **** **** **** +9534 Archivist_Still_Magic_Vestment **** **** **** **** **** **** **** **** +9535 Archivist_MASOCHISM **** **** **** **** **** **** **** **** +9536 Archivist_Exteneded_MASOCHISM **** **** **** **** **** **** **** **** +9537 Archivist_Mass_Aid **** **** **** **** **** **** **** **** +9538 Archivist_Empowered_Mass_Aid **** **** **** **** **** **** **** **** +9539 Archivist_Exteneded_Mass_Aid **** **** **** **** **** **** **** **** +9540 Archivist_Maximized_Mass_Aid **** **** **** **** **** **** **** **** +9541 Archivist_Quickened_Mass_Aid **** **** **** **** **** **** **** **** +9542 Archivist_Silent_Mass_Aid **** **** **** **** **** **** **** **** +9543 Archivist_Still_Mass_Aid **** **** **** **** **** **** **** **** +9544 Archivist_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +9545 Archivist_Exteneded_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +9546 Archivist_Quickened_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +9547 Archivist_Silent_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +9548 Archivist_Still_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +9549 Archivist_MirrorImage **** **** **** **** **** **** **** **** +9550 Archivist_Exteneded_MirrorImage **** **** **** **** **** **** **** **** +9551 Archivist_Quickened_MirrorImage **** **** **** **** **** **** **** **** +9552 Archivist_Silent_MirrorImage **** **** **** **** **** **** **** **** +9553 Archivist_Still_MirrorImage **** **** **** **** **** **** **** **** +9554 Archivist_Necrotic_Bloat **** **** **** **** **** **** **** **** +9555 Archivist_Empowered_Necrotic_Bloat **** **** **** **** **** **** **** **** +9556 Archivist_Maximized_Necrotic_Bloat **** **** **** **** **** **** **** **** +9557 Archivist_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9558 Archivist_Empowered_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9559 Archivist_Maximized_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9560 Archivist_Quickened_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9561 Archivist_Silent_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9562 Archivist_Still_Negative_Energy_Burst **** **** **** **** **** **** **** **** +9563 Archivist_Negative_Energy_Protection **** **** **** **** **** **** **** **** +9564 Archivist_Exteneded_Negative_Energy_Protection **** **** **** **** **** **** **** **** +9565 Archivist_Quickened_Negative_Energy_Protection **** **** **** **** **** **** **** **** +9566 Archivist_Silent_Negative_Energy_Protection **** **** **** **** **** **** **** **** +9567 Archivist_Still_Negative_Energy_Protection **** **** **** **** **** **** **** **** +9568 Archivist_ObscureObject **** **** **** **** **** **** **** **** +9569 Archivist_Exteneded_ObscureObject **** **** **** **** **** **** **** **** +9570 Archivist_Quickened_ObscureObject **** **** **** **** **** **** **** **** +9571 Archivist_Silent_ObscureObject **** **** **** **** **** **** **** **** +9572 Archivist_Still_ObscureObject **** **** **** **** **** **** **** **** +9573 Archivist_Prayer **** **** **** **** **** **** **** **** +9574 Archivist_Exteneded_Prayer **** **** **** **** **** **** **** **** +9575 Archivist_Quickened_Prayer **** **** **** **** **** **** **** **** +9576 Archivist_Silent_Prayer **** **** **** **** **** **** **** **** +9577 Archivist_Still_Prayer **** **** **** **** **** **** **** **** +9578 Archivist_Protection_from_Elements **** **** **** **** **** **** **** **** +9579 Archivist_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +9580 Archivist_Quickened_Protection_from_Elements **** **** **** **** **** **** **** **** +9581 Archivist_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +9582 Archivist_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +9583 Archivist_Quillfire **** **** **** **** **** **** **** **** +9584 Archivist_Empowered_Quillfire **** **** **** **** **** **** **** **** +9585 Archivist_Maximized_Quillfire **** **** **** **** **** **** **** **** +9586 Archivist_Quickened_Quillfire **** **** **** **** **** **** **** **** +9587 Archivist_Silent_Quillfire **** **** **** **** **** **** **** **** +9588 Archivist_Still_Quillfire **** **** **** **** **** **** **** **** +9589 Archivist_RED_FESTER **** **** **** **** **** **** **** **** +9590 Archivist_Quickened_RED_FESTER **** **** **** **** **** **** **** **** +9591 Archivist_Silent_RED_FESTER **** **** **** **** **** **** **** **** +9592 Archivist_Still_RED_FESTER **** **** **** **** **** **** **** **** +9593 Archivist_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9594 Archivist_Quickened_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9595 Archivist_Silent_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9596 Archivist_Still_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +9597 Archivist_Remove_Curse **** **** **** **** **** **** **** **** +9598 Archivist_Quickened_Remove_Curse **** **** **** **** **** **** **** **** +9599 Archivist_Silent_Remove_Curse **** **** **** **** **** **** **** **** +9600 Archivist_Still_Remove_Curse **** **** **** **** **** **** **** **** +9601 Archivist_Remove_Disease **** **** **** **** **** **** **** **** +9602 Archivist_Quickened_Remove_Disease **** **** **** **** **** **** **** **** +9603 Archivist_Silent_Remove_Disease **** **** **** **** **** **** **** **** +9604 Archivist_Still_Remove_Disease **** **** **** **** **** **** **** **** +9605 Archivist_RingOfBlades **** **** **** **** **** **** **** **** +9606 Archivist_Exteneded_RingOfBlades **** **** **** **** **** **** **** **** +9607 Archivist_Quickened_RingOfBlades **** **** **** **** **** **** **** **** +9608 Archivist_Silent_RingOfBlades **** **** **** **** **** **** **** **** +9609 Archivist_Still_RingOfBlades **** **** **** **** **** **** **** **** +9610 Archivist_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9611 Archivist_Empowered_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9612 Archivist_Maximized_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9613 Archivist_Quickened_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9614 Archivist_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9615 Archivist_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +9616 Archivist_Searing_Light **** **** **** **** **** **** **** **** +9617 Archivist_Empowered_Searing_Light **** **** **** **** **** **** **** **** +9618 Archivist_Maximized_Searing_Light **** **** **** **** **** **** **** **** +9619 Archivist_Quickened_Searing_Light **** **** **** **** **** **** **** **** +9620 Archivist_Silent_Searing_Light **** **** **** **** **** **** **** **** +9621 Archivist_Still_Searing_Light **** **** **** **** **** **** **** **** +9622 Archivist_SerpentArrows **** **** **** **** **** **** **** **** +9623 Archivist_Quickened_SerpentArrows **** **** **** **** **** **** **** **** +9624 Archivist_Silent_SerpentArrows **** **** **** **** **** **** **** **** +9625 Archivist_Still_SerpentArrows **** **** **** **** **** **** **** **** +9626 Archivist_Serpents_Sigh **** **** **** **** **** **** **** **** +9627 Archivist_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9628 Archivist_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9629 Archivist_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9630 Archivist_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9631 Archivist_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9632 Archivist_Empowered_Serpents_Sigh **** **** **** **** **** **** **** **** +9633 Archivist_Empowered_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9634 Archivist_Empowered_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9635 Archivist_Empowered_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9636 Archivist_Empowered_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9637 Archivist_Empowered_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9638 Archivist_Maximized_Serpents_Sigh **** **** **** **** **** **** **** **** +9639 Archivist_Maximized_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9640 Archivist_Maximized_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9641 Archivist_Maximized_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9642 Archivist_Maximized_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9643 Archivist_Maximized_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9644 Archivist_Quickened_Serpents_Sigh **** **** **** **** **** **** **** **** +9645 Archivist_Quickened_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9646 Archivist_Quickened_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9647 Archivist_Quickened_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9648 Archivist_Quickened_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9649 Archivist_Quickened_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9650 Archivist_Silent_Serpents_Sigh **** **** **** **** **** **** **** **** +9651 Archivist_Silent_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9652 Archivist_Silent_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9653 Archivist_Silent_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9654 Archivist_Silent_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9655 Archivist_Silent_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9656 Archivist_Still_Serpents_Sigh **** **** **** **** **** **** **** **** +9657 Archivist_Still_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +9658 Archivist_Still_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +9659 Archivist_Still_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +9660 Archivist_Still_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +9661 Archivist_Still_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +9662 Archivist_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9663 Archivist_Empowered_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9664 Archivist_Exteneded_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9665 Archivist_Maximized_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9666 Archivist_Quickened_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9667 Archivist_Silent_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9668 Archivist_Still_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +9669 Archivist_Shout **** **** **** **** **** **** **** **** +9670 Archivist_Empowered_Shout **** **** **** **** **** **** **** **** +9671 Archivist_Maximized_Shout **** **** **** **** **** **** **** **** +9672 Archivist_Quickened_Shout **** **** **** **** **** **** **** **** +9673 Archivist_Silent_Shout **** **** **** **** **** **** **** **** +9674 Archivist_SHRIVELING **** **** **** **** **** **** **** **** +9675 Archivist_Empowered_SHRIVELING **** **** **** **** **** **** **** **** +9676 Archivist_Maximized_SHRIVELING **** **** **** **** **** **** **** **** +9677 Archivist_Quickened_SHRIVELING **** **** **** **** **** **** **** **** +9678 Archivist_Silent_SHRIVELING **** **** **** **** **** **** **** **** +9679 Archivist_Still_SHRIVELING **** **** **** **** **** **** **** **** +9680 Archivist_Slashing_Darkness **** **** **** **** **** **** **** **** +9681 Archivist_Empowered_Slashing_Darkness **** **** **** **** **** **** **** **** +9682 Archivist_Maximized_Slashing_Darkness **** **** **** **** **** **** **** **** +9683 Archivist_Quickened_Slashing_Darkness **** **** **** **** **** **** **** **** +9684 Archivist_Silent_Slashing_Darkness **** **** **** **** **** **** **** **** +9685 Archivist_Still_Slashing_Darkness **** **** **** **** **** **** **** **** +9686 Archivist_SleetStorm **** **** **** **** **** **** **** **** +9687 Archivist_Exteneded_SleetStorm **** **** **** **** **** **** **** **** +9688 Archivist_Quickened_SleetStorm **** **** **** **** **** **** **** **** +9689 Archivist_Silent_SleetStorm **** **** **** **** **** **** **** **** +9690 Archivist_Still_SleetStorm **** **** **** **** **** **** **** **** +9691 Archivist_Snare **** **** **** **** **** **** **** **** +9692 Archivist_Quickened_Snare **** **** **** **** **** **** **** **** +9693 Archivist_Silent_Snare **** **** **** **** **** **** **** **** +9694 Archivist_Still_Snare **** **** **** **** **** **** **** **** +9695 Archivist_Spiderskin **** **** **** **** **** **** **** **** +9696 Archivist_Exteneded_Spiderskin **** **** **** **** **** **** **** **** +9697 Archivist_Quickened_Spiderskin **** **** **** **** **** **** **** **** +9698 Archivist_Silent_Spiderskin **** **** **** **** **** **** **** **** +9699 Archivist_Still_Spiderskin **** **** **** **** **** **** **** **** +9700 Archivist_Spike_Growth **** **** **** **** **** **** **** **** +9701 Archivist_Exteneded_Spike_Growth **** **** **** **** **** **** **** **** +9702 Archivist_Quickened_Spike_Growth **** **** **** **** **** **** **** **** +9703 Archivist_Silent_Spike_Growth **** **** **** **** **** **** **** **** +9704 Archivist_Still_Spike_Growth **** **** **** **** **** **** **** **** +9705 Archivist_Summon_Creature_III **** **** **** **** **** **** **** **** +9706 Archivist_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +9707 Archivist_Quickened_Summon_Creature_III **** **** **** **** **** **** **** **** +9708 Archivist_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +9709 Archivist_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +9710 Archivist_SummonUndeadIII **** **** **** **** **** **** **** **** +9711 Archivist_Exteneded_SummonUndeadIII **** **** **** **** **** **** **** **** +9712 Archivist_Quickened_SummonUndeadIII **** **** **** **** **** **** **** **** +9713 Archivist_Silent_SummonUndeadIII **** **** **** **** **** **** **** **** +9714 Archivist_Still_SummonUndeadIII **** **** **** **** **** **** **** **** +9715 Archivist_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +9716 Archivist_Quickened_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +9717 Archivist_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +9718 Archivist_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +9719 Archivist_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9720 Archivist_Empowered_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9721 Archivist_Maximized_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9722 Archivist_Quickened_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9723 Archivist_Silent_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9724 Archivist_Still_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +9725 Archivist_Vigor **** **** **** **** **** **** **** **** +9726 Archivist_Exteneded_Vigor **** **** **** **** **** **** **** **** +9727 Archivist_Quickened_Vigor **** **** **** **** **** **** **** **** +9728 Archivist_Silent_Vigor **** **** **** **** **** **** **** **** +9729 Archivist_Still_Vigor **** **** **** **** **** **** **** **** +9730 Archivist_WaterBreathing **** **** **** **** **** **** **** **** +9731 Archivist_Exteneded_WaterBreathing **** **** **** **** **** **** **** **** +9732 Archivist_Quickened_WaterBreathing **** **** **** **** **** **** **** **** +9733 Archivist_Silent_WaterBreathing **** **** **** **** **** **** **** **** +9734 Archivist_Still_WaterBreathing **** **** **** **** **** **** **** **** +9735 Archivist_WRACK **** **** **** **** **** **** **** **** +9736 Archivist_Exteneded_WRACK **** **** **** **** **** **** **** **** +9737 Archivist_Quickened_WRACK **** **** **** **** **** **** **** **** +9738 Archivist_Silent_WRACK **** **** **** **** **** **** **** **** +9739 Archivist_Still_WRACK **** **** **** **** **** **** **** **** +9740 Archivist_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +9741 Archivist_Exteneded_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +9742 Archivist_Quickened_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +9743 Archivist_Silent_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +9744 Archivist_Still_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +9745 Archivist_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9746 Archivist_Empowered_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9747 Archivist_Exteneded_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9748 Archivist_Quickened_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9749 Archivist_Silent_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9750 Archivist_Still_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +9751 Archivist_BloodfreezeArrow **** **** **** **** **** **** **** **** +9752 Archivist_Silent_BloodfreezeArrow **** **** **** **** **** **** **** **** +9753 Archivist_BloodOfTheMartyr **** **** **** **** **** **** **** **** +9754 Archivist_Quickened_BloodOfTheMartyr **** **** **** **** **** **** **** **** +9755 Archivist_Silent_BloodOfTheMartyr **** **** **** **** **** **** **** **** +9756 Archivist_Still_BloodOfTheMartyr **** **** **** **** **** **** **** **** +9757 Archivist_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9758 Archivist_Empowered_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9759 Archivist_Exteneded_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9760 Archivist_Quickened_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9761 Archivist_Silent_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9762 Archivist_Still_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +9763 Archivist_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9764 Archivist_Empowered_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9765 Archivist_Maximized_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9766 Archivist_Quickened_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9767 Archivist_Silent_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9768 Archivist_Still_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +9769 Archivist_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +9770 Archivist_Exteneded_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +9771 Archivist_Quickened_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +9772 Archivist_Silent_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +9773 Archivist_Darkness_Armor **** **** **** **** **** **** **** **** +9774 Archivist_Exteneded_Darkness_Armor **** **** **** **** **** **** **** **** +9775 Archivist_Quickened_Darkness_Armor **** **** **** **** **** **** **** **** +9776 Archivist_Silent_Darkness_Armor **** **** **** **** **** **** **** **** +9777 Archivist_Still_Darkness_Armor **** **** **** **** **** **** **** **** +9778 Archivist_Death_Ward **** **** **** **** **** **** **** **** +9779 Archivist_Exteneded_Death_Ward **** **** **** **** **** **** **** **** +9780 Archivist_Quickened_Death_Ward **** **** **** **** **** **** **** **** +9781 Archivist_Silent_Death_Ward **** **** **** **** **** **** **** **** +9782 Archivist_Still_Death_Ward **** **** **** **** **** **** **** **** +9783 Archivist_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9784 Archivist_Empowered_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9785 Archivist_Exteneded_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9786 Archivist_Maximized_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9787 Archivist_Quickened_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9788 Archivist_Silent_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9789 Archivist_Still_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +9790 Archivist_Dimensional_Anchor **** **** **** **** **** **** **** **** +9791 Archivist_Exteneded_Dimensional_Anchor **** **** **** **** **** **** **** **** +9792 Archivist_Quickened_Dimensional_Anchor **** **** **** **** **** **** **** **** +9793 Archivist_Silent_Dimensional_Anchor **** **** **** **** **** **** **** **** +9794 Archivist_Still_Dimensional_Anchor **** **** **** **** **** **** **** **** +9795 Archivist_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +9796 Archivist_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +9797 Archivist_DimensionDoor_Party **** **** **** **** **** **** **** **** +9798 Archivist_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +9799 Archivist_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +9800 Archivist_Quickened_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +9801 Archivist_Quickened_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +9802 Archivist_Quickened_DimensionDoor_Party **** **** **** **** **** **** **** **** +9803 Archivist_Quickened_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +9804 Archivist_Quickened_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +9805 Archivist_Silent_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +9806 Archivist_Silent_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +9807 Archivist_Silent_DimensionDoor_Party **** **** **** **** **** **** **** **** +9808 Archivist_Silent_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +9809 Archivist_Silent_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +9810 Archivist_Dismissal **** **** **** **** **** **** **** **** +9811 Archivist_Quickened_Dismissal **** **** **** **** **** **** **** **** +9812 Archivist_Silent_Dismissal **** **** **** **** **** **** **** **** +9813 Archivist_Still_Dismissal **** **** **** **** **** **** **** **** +9814 Archivist_Divine_Power **** **** **** **** **** **** **** **** +9815 Archivist_Exteneded_Divine_Power **** **** **** **** **** **** **** **** +9816 Archivist_Quickened_Divine_Power **** **** **** **** **** **** **** **** +9817 Archivist_Silent_Divine_Power **** **** **** **** **** **** **** **** +9818 Archivist_Still_Divine_Power **** **** **** **** **** **** **** **** +9819 Archivist_Dominate_Person **** **** **** **** **** **** **** **** +9820 Archivist_Exteneded_Dominate_Person **** **** **** **** **** **** **** **** +9821 Archivist_Quickened_Dominate_Person **** **** **** **** **** **** **** **** +9822 Archivist_Silent_Dominate_Person **** **** **** **** **** **** **** **** +9823 Archivist_Still_Dominate_Person **** **** **** **** **** **** **** **** +9824 Archivist_DoublestrikeArrow **** **** **** **** **** **** **** **** +9825 Archivist_Quickened_DoublestrikeArrow **** **** **** **** **** **** **** **** +9826 Archivist_Silent_DoublestrikeArrow **** **** **** **** **** **** **** **** +9827 Archivist_Still_DoublestrikeArrow **** **** **** **** **** **** **** **** +9828 Archivist_DraconicMight **** **** **** **** **** **** **** **** +9829 Archivist_Exteneded_DraconicMight **** **** **** **** **** **** **** **** +9830 Archivist_Quickened_DraconicMight **** **** **** **** **** **** **** **** +9831 Archivist_Silent_DraconicMight **** **** **** **** **** **** **** **** +9832 Archivist_Still_DraconicMight **** **** **** **** **** **** **** **** +9833 Archivist_Elemental_Shield **** **** **** **** **** **** **** **** +9834 Archivist_Exteneded_Elemental_Shield **** **** **** **** **** **** **** **** +9835 Archivist_Quickened_Elemental_Shield **** **** **** **** **** **** **** **** +9836 Archivist_Silent_Elemental_Shield **** **** **** **** **** **** **** **** +9837 Archivist_Still_Elemental_Shield **** **** **** **** **** **** **** **** +9838 Archivist_Enervation **** **** **** **** **** **** **** **** +9839 Archivist_Empowered_Enervation **** **** **** **** **** **** **** **** +9840 Archivist_Maximized_Enervation **** **** **** **** **** **** **** **** +9841 Archivist_Quickened_Enervation **** **** **** **** **** **** **** **** +9842 Archivist_Silent_Enervation **** **** **** **** **** **** **** **** +9843 Archivist_Still_Enervation **** **** **** **** **** **** **** **** +9844 Archivist_Fear **** **** **** **** **** **** **** **** +9845 Archivist_Exteneded_Fear **** **** **** **** **** **** **** **** +9846 Archivist_Quickened_Fear **** **** **** **** **** **** **** **** +9847 Archivist_Silent_Fear **** **** **** **** **** **** **** **** +9848 Archivist_Still_Fear **** **** **** **** **** **** **** **** +9849 Archivist_Fireball **** **** **** **** **** **** **** **** +9850 Archivist_Empowered_Fireball **** **** **** **** **** **** **** **** +9851 Archivist_Maximized_Fireball **** **** **** **** **** **** **** **** +9852 Archivist_Quickened_Fireball **** **** **** **** **** **** **** **** +9853 Archivist_Silent_Fireball **** **** **** **** **** **** **** **** +9854 Archivist_Still_Fireball **** **** **** **** **** **** **** **** +9855 Archivist_Freedom_of_Movement **** **** **** **** **** **** **** **** +9856 Archivist_Exteneded_Freedom_of_Movement **** **** **** **** **** **** **** **** +9857 Archivist_Quickened_Freedom_of_Movement **** **** **** **** **** **** **** **** +9858 Archivist_Silent_Freedom_of_Movement **** **** **** **** **** **** **** **** +9859 Archivist_Still_Freedom_of_Movement **** **** **** **** **** **** **** **** +9860 Archivist_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9861 Archivist_Exteneded_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9862 Archivist_Quickened_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +9863 Archivist_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +9864 Archivist_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +9865 Archivist_Quickened_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +9866 Archivist_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +9867 Archivist_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +9868 Archivist_Greater_Resistance **** **** **** **** **** **** **** **** +9869 Archivist_Exteneded_Greater_Resistance **** **** **** **** **** **** **** **** +9870 Archivist_Quickened_Greater_Resistance **** **** **** **** **** **** **** **** +9871 Archivist_Silent_Greater_Resistance **** **** **** **** **** **** **** **** +9872 Archivist_Still_Greater_Resistance **** **** **** **** **** **** **** **** +9873 Archivist_Gust_of_Wind **** **** **** **** **** **** **** **** +9874 Archivist_Quickened_Gust_of_Wind **** **** **** **** **** **** **** **** +9875 Archivist_Silent_Gust_of_Wind **** **** **** **** **** **** **** **** +9876 Archivist_Still_Gust_of_Wind **** **** **** **** **** **** **** **** +9877 Archivist_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9878 Archivist_Empowered_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9879 Archivist_Maximized_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9880 Archivist_Quickened_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9881 Archivist_Silent_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9882 Archivist_Still_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +9883 Archivist_Haste **** **** **** **** **** **** **** **** +9884 Archivist_Exteneded_Haste **** **** **** **** **** **** **** **** +9885 Archivist_Quickened_Haste **** **** **** **** **** **** **** **** +9886 Archivist_Silent_Haste **** **** **** **** **** **** **** **** +9887 Archivist_Still_Haste **** **** **** **** **** **** **** **** +9888 Archivist_Hold_Monster **** **** **** **** **** **** **** **** +9889 Archivist_Exteneded_Hold_Monster **** **** **** **** **** **** **** **** +9890 Archivist_Quickened_Hold_Monster **** **** **** **** **** **** **** **** +9891 Archivist_Silent_Hold_Monster **** **** **** **** **** **** **** **** +9892 Archivist_Still_Hold_Monster **** **** **** **** **** **** **** **** +9893 Archivist_Holy_Sword **** **** **** **** **** **** **** **** +9894 Archivist_Exteneded_Holy_Sword **** **** **** **** **** **** **** **** +9895 Archivist_Quickened_Holy_Sword **** **** **** **** **** **** **** **** +9896 Archivist_Silent_Holy_Sword **** **** **** **** **** **** **** **** +9897 Archivist_Still_Holy_Sword **** **** **** **** **** **** **** **** +9898 Archivist_Improved_Invisibility **** **** **** **** **** **** **** **** +9899 Archivist_Exteneded_Improved_Invisibility **** **** **** **** **** **** **** **** +9900 Archivist_Quickened_Improved_Invisibility **** **** **** **** **** **** **** **** +9901 Archivist_Silent_Improved_Invisibility **** **** **** **** **** **** **** **** +9902 Archivist_Still_Improved_Invisibility **** **** **** **** **** **** **** **** +9903 Archivist_Improved_Mage_Armor **** **** **** **** **** **** **** **** +9904 Archivist_Exteneded_Improved_Mage_Armor **** **** **** **** **** **** **** **** +9905 Archivist_Quickened_Improved_Mage_Armor **** **** **** **** **** **** **** **** +9906 Archivist_Silent_Improved_Mage_Armor **** **** **** **** **** **** **** **** +9907 Archivist_Still_Improved_Mage_Armor **** **** **** **** **** **** **** **** +9908 Archivist_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9909 Archivist_Empowered_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9910 Archivist_Maximized_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9911 Archivist_Quickened_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9912 Archivist_Silent_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9913 Archivist_Still_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +9914 Archivist_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +9915 Archivist_Exteneded_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +9916 Archivist_Quickened_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +9917 Archivist_Silent_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +9918 Archivist_Still_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +9919 Archivist_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +9920 Archivist_Exteneded_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +9921 Archivist_Quickened_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +9922 Archivist_Silent_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +9923 Archivist_Still_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +9924 Archivist_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +9925 Archivist_Exteneded_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +9926 Archivist_Quickened_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +9927 Archivist_Silent_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +9928 Archivist_Still_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +9929 Archivist_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +9930 Archivist_Quickened_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +9931 Archivist_Silent_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +9932 Archivist_Still_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +9933 Archivist_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +9934 Archivist_Exteneded_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +9935 Archivist_Silent_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +9936 Archivist_Still_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +9937 Archivist_Mass_Camoflage **** **** **** **** **** **** **** **** +9938 Archivist_Exteneded_Mass_Camoflage **** **** **** **** **** **** **** **** +9939 Archivist_Quickened_Mass_Camoflage **** **** **** **** **** **** **** **** +9940 Archivist_Silent_Mass_Camoflage **** **** **** **** **** **** **** **** +9941 Archivist_Still_Mass_Camoflage **** **** **** **** **** **** **** **** +9942 Archivist_Mass_Ultravision **** **** **** **** **** **** **** **** +9943 Archivist_Exteneded_Mass_Ultravision **** **** **** **** **** **** **** **** +9944 Archivist_Silent_Mass_Ultravision **** **** **** **** **** **** **** **** +9945 Archivist_Still_Mass_Ultravision **** **** **** **** **** **** **** **** +9946 Archivist_Necrotic_Domination **** **** **** **** **** **** **** **** +9947 Archivist_Exteneded_Necrotic_Domination **** **** **** **** **** **** **** **** +9948 Archivist_Quickened_Necrotic_Domination **** **** **** **** **** **** **** **** +9949 Archivist_Silent_Necrotic_Domination **** **** **** **** **** **** **** **** +9950 Archivist_Still_Necrotic_Domination **** **** **** **** **** **** **** **** +9951 Archivist_Neutralize_Poison **** **** **** **** **** **** **** **** +9952 Archivist_Quickened_Neutralize_Poison **** **** **** **** **** **** **** **** +9953 Archivist_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +9954 Archivist_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +9955 Archivist_NONDETECTION **** **** **** **** **** **** **** **** +9956 Archivist_Exteneded_NONDETECTION **** **** **** **** **** **** **** **** +9957 Archivist_Quickened_NONDETECTION **** **** **** **** **** **** **** **** +9958 Archivist_Silent_NONDETECTION **** **** **** **** **** **** **** **** +9959 Archivist_Still_NONDETECTION **** **** **** **** **** **** **** **** +9960 Archivist_Panacea **** **** **** **** **** **** **** **** +9961 Archivist_Empowered_Panacea **** **** **** **** **** **** **** **** +9962 Archivist_Maximized_Panacea **** **** **** **** **** **** **** **** +9963 Archivist_Quickened_Panacea **** **** **** **** **** **** **** **** +9964 Archivist_Silent_Panacea **** **** **** **** **** **** **** **** +9965 Archivist_Still_Panacea **** **** **** **** **** **** **** **** +9966 Archivist_Phantasmal_Killer **** **** **** **** **** **** **** **** +9967 Archivist_Empowered_Phantasmal_Killer **** **** **** **** **** **** **** **** +9968 Archivist_Maximized_Phantasmal_Killer **** **** **** **** **** **** **** **** +9969 Archivist_Quickened_Phantasmal_Killer **** **** **** **** **** **** **** **** +9970 Archivist_Silent_Phantasmal_Killer **** **** **** **** **** **** **** **** +9971 Archivist_Still_Phantasmal_Killer **** **** **** **** **** **** **** **** +9972 Archivist_Poison **** **** **** **** **** **** **** **** +9973 Archivist_Empowered_Poison **** **** **** **** **** **** **** **** +9974 Archivist_Maximized_Poison **** **** **** **** **** **** **** **** +9975 Archivist_Quickened_Poison **** **** **** **** **** **** **** **** +9976 Archivist_Silent_Poison **** **** **** **** **** **** **** **** +9977 Archivist_Still_Poison **** **** **** **** **** **** **** **** +9978 Archivist_Polymorph_Self **** **** **** **** **** **** **** **** +9979 Archivist_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +9980 Archivist_Polymorph_TROLL **** **** **** **** **** **** **** **** +9981 Archivist_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +9982 Archivist_Polymorph_PIXIE **** **** **** **** **** **** **** **** +9983 Archivist_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +9984 Archivist_Exteneded_Polymorph_Self **** **** **** **** **** **** **** **** +9985 Archivist_Exteneded_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +9986 Archivist_Exteneded_Polymorph_TROLL **** **** **** **** **** **** **** **** +9987 Archivist_Exteneded_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +9988 Archivist_Exteneded_Polymorph_PIXIE **** **** **** **** **** **** **** **** +9989 Archivist_Exteneded_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +9990 Archivist_Quickened_Polymorph_Self **** **** **** **** **** **** **** **** +9991 Archivist_Quickened_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +9992 Archivist_Quickened_Polymorph_TROLL **** **** **** **** **** **** **** **** +9993 Archivist_Quickened_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +9994 Archivist_Quickened_Polymorph_PIXIE **** **** **** **** **** **** **** **** +9995 Archivist_Quickened_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +9996 Archivist_Silent_Polymorph_Self **** **** **** **** **** **** **** **** +9997 Archivist_Silent_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +9998 Archivist_Silent_Polymorph_TROLL **** **** **** **** **** **** **** **** +9999 Archivist_Silent_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +10000 Archivist_Silent_Polymorph_PIXIE **** **** **** **** **** **** **** **** +10001 Archivist_Silent_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +10002 Archivist_Recitation **** **** **** **** **** **** **** **** +10003 Archivist_Exteneded_Recitation **** **** **** **** **** **** **** **** +10004 Archivist_Quickened_Recitation **** **** **** **** **** **** **** **** +10005 Archivist_Silent_Recitation **** **** **** **** **** **** **** **** +10006 Archivist_Still_Recitation **** **** **** **** **** **** **** **** +10007 Archivist_RepelVermin **** **** **** **** **** **** **** **** +10008 Archivist_Exteneded_RepelVermin **** **** **** **** **** **** **** **** +10009 Archivist_Quickened_RepelVermin **** **** **** **** **** **** **** **** +10010 Archivist_Silent_RepelVermin **** **** **** **** **** **** **** **** +10011 Archivist_Still_RepelVermin **** **** **** **** **** **** **** **** +10012 Archivist_Restoration **** **** **** **** **** **** **** **** +10013 Archivist_Quickened_Restoration **** **** **** **** **** **** **** **** +10014 Archivist_Silent_Restoration **** **** **** **** **** **** **** **** +10015 Archivist_Still_Restoration **** **** **** **** **** **** **** **** +10016 Archivist_ShadowArrow **** **** **** **** **** **** **** **** +10017 Archivist_Silent_ShadowArrow **** **** **** **** **** **** **** **** +10018 Archivist_Stoneskin **** **** **** **** **** **** **** **** +10019 Archivist_Exteneded_Stoneskin **** **** **** **** **** **** **** **** +10020 Archivist_Quickened_Stoneskin **** **** **** **** **** **** **** **** +10021 Archivist_Silent_Stoneskin **** **** **** **** **** **** **** **** +10022 Archivist_Still_Stoneskin **** **** **** **** **** **** **** **** +10023 Archivist_STOP_HEART **** **** **** **** **** **** **** **** +10024 Archivist_Quickened_STOP_HEART **** **** **** **** **** **** **** **** +10025 Archivist_Still_STOP_HEART **** **** **** **** **** **** **** **** +10026 Archivist_Summon_Creature_IV **** **** **** **** **** **** **** **** +10027 Archivist_Exteneded_Summon_Creature_IV **** **** **** **** **** **** **** **** +10028 Archivist_Quickened_Summon_Creature_IV **** **** **** **** **** **** **** **** +10029 Archivist_Silent_Summon_Creature_IV **** **** **** **** **** **** **** **** +10030 Archivist_Still_Summon_Creature_IV **** **** **** **** **** **** **** **** +10031 Archivist_SummonUndeadIV **** **** **** **** **** **** **** **** +10032 Archivist_Exteneded_SummonUndeadIV **** **** **** **** **** **** **** **** +10033 Archivist_Quickened_SummonUndeadIV **** **** **** **** **** **** **** **** +10034 Archivist_Silent_SummonUndeadIV **** **** **** **** **** **** **** **** +10035 Archivist_Still_SummonUndeadIV **** **** **** **** **** **** **** **** +10036 Archivist_SUNMANTLE **** **** **** **** **** **** **** **** +10037 Archivist_Exteneded_SUNMANTLE **** **** **** **** **** **** **** **** +10038 Archivist_Quickened_SUNMANTLE **** **** **** **** **** **** **** **** +10039 Archivist_Still_SUNMANTLE **** **** **** **** **** **** **** **** +10040 Archivist_SwordOfConscience **** **** **** **** **** **** **** **** +10041 Archivist_Quickened_SwordOfConscience **** **** **** **** **** **** **** **** +10042 Archivist_Silent_SwordOfConscience **** **** **** **** **** **** **** **** +10043 Archivist_Unholy_Sword **** **** **** **** **** **** **** **** +10044 Archivist_Exteneded_Unholy_Sword **** **** **** **** **** **** **** **** +10045 Archivist_Quickened_Unholy_Sword **** **** **** **** **** **** **** **** +10046 Archivist_Silent_Unholy_Sword **** **** **** **** **** **** **** **** +10047 Archivist_Still_Unholy_Sword **** **** **** **** **** **** **** **** +10048 Archivist_Awaken **** **** **** **** **** **** **** **** +10049 Archivist_Empowered_Awaken **** **** **** **** **** **** **** **** +10050 Archivist_Maximized_Awaken **** **** **** **** **** **** **** **** +10051 Archivist_Quickened_Awaken **** **** **** **** **** **** **** **** +10052 Archivist_Silent_Awaken **** **** **** **** **** **** **** **** +10053 Archivist_Still_Awaken **** **** **** **** **** **** **** **** +10054 Archivist_BalefulPolymorph **** **** **** **** **** **** **** **** +10055 Archivist_Quickened_BalefulPolymorph **** **** **** **** **** **** **** **** +10056 Archivist_Silent_BalefulPolymorph **** **** **** **** **** **** **** **** +10057 Archivist_Still_BalefulPolymorph **** **** **** **** **** **** **** **** +10058 Archivist_Battletide **** **** **** **** **** **** **** **** +10059 Archivist_Exteneded_Battletide **** **** **** **** **** **** **** **** +10060 Archivist_Quickened_Battletide **** **** **** **** **** **** **** **** +10061 Archivist_Silent_Battletide **** **** **** **** **** **** **** **** +10062 Archivist_Still_Battletide **** **** **** **** **** **** **** **** +10063 Archivist_BreakEnchantment **** **** **** **** **** **** **** **** +10064 Archivist_Quickened_BreakEnchantment **** **** **** **** **** **** **** **** +10065 Archivist_Silent_BreakEnchantment **** **** **** **** **** **** **** **** +10066 Archivist_Still_BreakEnchantment **** **** **** **** **** **** **** **** +10067 Archivist_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +10068 Archivist_Exteneded_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +10069 Archivist_Quickened_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +10070 Archivist_Silent_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +10071 Archivist_Circle_of_Doom **** **** **** **** **** **** **** **** +10072 Archivist_Empowered_Circle_of_Doom **** **** **** **** **** **** **** **** +10073 Archivist_Maximized_Circle_of_Doom **** **** **** **** **** **** **** **** +10074 Archivist_Quickened_Circle_of_Doom **** **** **** **** **** **** **** **** +10075 Archivist_Silent_Circle_of_Doom **** **** **** **** **** **** **** **** +10076 Archivist_Still_Circle_of_Doom **** **** **** **** **** **** **** **** +10077 Archivist_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +10078 Archivist_Exteneded_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +10079 Archivist_Quickened_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +10080 Archivist_Silent_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +10081 Archivist_Still_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +10082 Archivist_Cone_of_Cold **** **** **** **** **** **** **** **** +10083 Archivist_Empowered_Cone_of_Cold **** **** **** **** **** **** **** **** +10084 Archivist_Maximized_Cone_of_Cold **** **** **** **** **** **** **** **** +10085 Archivist_Quickened_Cone_of_Cold **** **** **** **** **** **** **** **** +10086 Archivist_Silent_Cone_of_Cold **** **** **** **** **** **** **** **** +10087 Archivist_Still_Cone_of_Cold **** **** **** **** **** **** **** **** +10088 Archivist_CONVERT_WAND **** **** **** **** **** **** **** **** +10089 Archivist_Exteneded_CONVERT_WAND **** **** **** **** **** **** **** **** +10090 Archivist_Quickened_CONVERT_WAND **** **** **** **** **** **** **** **** +10091 Archivist_Silent_CONVERT_WAND **** **** **** **** **** **** **** **** +10092 Archivist_Still_CONVERT_WAND **** **** **** **** **** **** **** **** +10093 Archivist_DANCING_WEB **** **** **** **** **** **** **** **** +10094 Archivist_Empowered_DANCING_WEB **** **** **** **** **** **** **** **** +10095 Archivist_Exteneded_DANCING_WEB **** **** **** **** **** **** **** **** +10096 Archivist_Maximized_DANCING_WEB **** **** **** **** **** **** **** **** +10097 Archivist_Quickened_DANCING_WEB **** **** **** **** **** **** **** **** +10098 Archivist_Silent_DANCING_WEB **** **** **** **** **** **** **** **** +10099 Archivist_Still_DANCING_WEB **** **** **** **** **** **** **** **** +10100 Archivist_DarkBolt **** **** **** **** **** **** **** **** +10101 Archivist_DarkBolt_all **** **** **** **** **** **** **** **** +10102 Archivist_DarkBolt_1 **** **** **** **** **** **** **** **** +10103 Archivist_Empowered_DarkBolt **** **** **** **** **** **** **** **** +10104 Archivist_Empowered_DarkBolt_all **** **** **** **** **** **** **** **** +10105 Archivist_Empowered_DarkBolt_1 **** **** **** **** **** **** **** **** +10106 Archivist_Maximized_DarkBolt **** **** **** **** **** **** **** **** +10107 Archivist_Maximized_DarkBolt_all **** **** **** **** **** **** **** **** +10108 Archivist_Maximized_DarkBolt_1 **** **** **** **** **** **** **** **** +10109 Archivist_Quickened_DarkBolt **** **** **** **** **** **** **** **** +10110 Archivist_Quickened_DarkBolt_all **** **** **** **** **** **** **** **** +10111 Archivist_Quickened_DarkBolt_1 **** **** **** **** **** **** **** **** +10112 Archivist_Silent_DarkBolt **** **** **** **** **** **** **** **** +10113 Archivist_Silent_DarkBolt_all **** **** **** **** **** **** **** **** +10114 Archivist_Silent_DarkBolt_1 **** **** **** **** **** **** **** **** +10115 Archivist_Still_DarkBolt **** **** **** **** **** **** **** **** +10116 Archivist_Still_DarkBolt_all **** **** **** **** **** **** **** **** +10117 Archivist_Still_DarkBolt_1 **** **** **** **** **** **** **** **** +10118 Archivist_Elemental_Strike **** **** **** **** **** **** **** **** +10119 Archivist_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10120 Archivist_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10121 Archivist_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10122 Archivist_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10123 Archivist_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10124 Archivist_Empowered_Elemental_Strike **** **** **** **** **** **** **** **** +10125 Archivist_Empowered_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10126 Archivist_Empowered_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10127 Archivist_Empowered_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10128 Archivist_Empowered_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10129 Archivist_Empowered_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10130 Archivist_Maximized_Elemental_Strike **** **** **** **** **** **** **** **** +10131 Archivist_Maximized_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10132 Archivist_Maximized_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10133 Archivist_Maximized_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10134 Archivist_Maximized_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10135 Archivist_Maximized_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10136 Archivist_Quickened_Elemental_Strike **** **** **** **** **** **** **** **** +10137 Archivist_Quickened_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10138 Archivist_Quickened_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10139 Archivist_Quickened_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10140 Archivist_Quickened_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10141 Archivist_Quickened_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10142 Archivist_Silent_Elemental_Strike **** **** **** **** **** **** **** **** +10143 Archivist_Silent_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10144 Archivist_Silent_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10145 Archivist_Silent_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10146 Archivist_Silent_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10147 Archivist_Silent_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10148 Archivist_Still_Elemental_Strike **** **** **** **** **** **** **** **** +10149 Archivist_Still_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +10150 Archivist_Still_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +10151 Archivist_Still_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +10152 Archivist_Still_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +10153 Archivist_Still_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +10154 Archivist_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10155 Archivist_Empowered_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10156 Archivist_Exteneded_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10157 Archivist_Maximized_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10158 Archivist_Quickened_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10159 Archivist_Silent_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10160 Archivist_Still_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +10161 Archivist_FireInTheBlood **** **** **** **** **** **** **** **** +10162 Archivist_Exteneded_FireInTheBlood **** **** **** **** **** **** **** **** +10163 Archivist_Quickened_FireInTheBlood **** **** **** **** **** **** **** **** +10164 Archivist_Silent_FireInTheBlood **** **** **** **** **** **** **** **** +10165 Archivist_Still_FireInTheBlood **** **** **** **** **** **** **** **** +10166 Archivist_Flame_Strike **** **** **** **** **** **** **** **** +10167 Archivist_Empowered_Flame_Strike **** **** **** **** **** **** **** **** +10168 Archivist_Maximized_Flame_Strike **** **** **** **** **** **** **** **** +10169 Archivist_Quickened_Flame_Strike **** **** **** **** **** **** **** **** +10170 Archivist_Silent_Flame_Strike **** **** **** **** **** **** **** **** +10171 Archivist_Still_Flame_Strike **** **** **** **** **** **** **** **** +10172 Archivist_Greater_Heroism **** **** **** **** **** **** **** **** +10173 Archivist_Exteneded_Greater_Heroism **** **** **** **** **** **** **** **** +10174 Archivist_Silent_Greater_Heroism **** **** **** **** **** **** **** **** +10175 Archivist_Still_Greater_Heroism **** **** **** **** **** **** **** **** +10176 Archivist_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +10177 Archivist_Exteneded_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +10178 Archivist_Quickened_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +10179 Archivist_Silent_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +10180 Archivist_Still_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +10181 Archivist_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +10182 Archivist_GreaterCommand_Approach **** **** **** **** **** **** **** **** +10183 Archivist_GreaterCommand_Drop **** **** **** **** **** **** **** **** +10184 Archivist_GreaterCommand_Fall **** **** **** **** **** **** **** **** +10185 Archivist_GreaterCommand_Flee **** **** **** **** **** **** **** **** +10186 Archivist_GreaterCommand_Halt **** **** **** **** **** **** **** **** +10187 Archivist_Exteneded_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +10188 Archivist_Exteneded_GreaterCommand_Approach **** **** **** **** **** **** **** **** +10189 Archivist_Exteneded_GreaterCommand_Drop **** **** **** **** **** **** **** **** +10190 Archivist_Exteneded_GreaterCommand_Fall **** **** **** **** **** **** **** **** +10191 Archivist_Exteneded_GreaterCommand_Flee **** **** **** **** **** **** **** **** +10192 Archivist_Exteneded_GreaterCommand_Halt **** **** **** **** **** **** **** **** +10193 Archivist_Quickened_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +10194 Archivist_Quickened_GreaterCommand_Approach **** **** **** **** **** **** **** **** +10195 Archivist_Quickened_GreaterCommand_Drop **** **** **** **** **** **** **** **** +10196 Archivist_Quickened_GreaterCommand_Fall **** **** **** **** **** **** **** **** +10197 Archivist_Quickened_GreaterCommand_Flee **** **** **** **** **** **** **** **** +10198 Archivist_Quickened_GreaterCommand_Halt **** **** **** **** **** **** **** **** +10199 Archivist_Silent_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +10200 Archivist_Silent_GreaterCommand_Approach **** **** **** **** **** **** **** **** +10201 Archivist_Silent_GreaterCommand_Drop **** **** **** **** **** **** **** **** +10202 Archivist_Silent_GreaterCommand_Fall **** **** **** **** **** **** **** **** +10203 Archivist_Silent_GreaterCommand_Flee **** **** **** **** **** **** **** **** +10204 Archivist_Silent_GreaterCommand_Halt **** **** **** **** **** **** **** **** +10205 Archivist_Still_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +10206 Archivist_Still_GreaterCommand_Approach **** **** **** **** **** **** **** **** +10207 Archivist_Still_GreaterCommand_Drop **** **** **** **** **** **** **** **** +10208 Archivist_Still_GreaterCommand_Fall **** **** **** **** **** **** **** **** +10209 Archivist_Still_GreaterCommand_Flee **** **** **** **** **** **** **** **** +10210 Archivist_Still_GreaterCommand_Halt **** **** **** **** **** **** **** **** +10211 Archivist_HealAnimalCompanion **** **** **** **** **** **** **** **** +10212 Archivist_Quickened_HealAnimalCompanion **** **** **** **** **** **** **** **** +10213 Archivist_Silent_HealAnimalCompanion **** **** **** **** **** **** **** **** +10214 Archivist_Still_HealAnimalCompanion **** **** **** **** **** **** **** **** +10215 Archivist_Healing_Circle **** **** **** **** **** **** **** **** +10216 Archivist_Empowered_Healing_Circle **** **** **** **** **** **** **** **** +10217 Archivist_Maximized_Healing_Circle **** **** **** **** **** **** **** **** +10218 Archivist_Quickened_Healing_Circle **** **** **** **** **** **** **** **** +10219 Archivist_Silent_Healing_Circle **** **** **** **** **** **** **** **** +10220 Archivist_Still_Healing_Circle **** **** **** **** **** **** **** **** +10221 Archivist_HEARTCLUTCH **** **** **** **** **** **** **** **** +10222 Archivist_Quickened_HEARTCLUTCH **** **** **** **** **** **** **** **** +10223 Archivist_Silent_HEARTCLUTCH **** **** **** **** **** **** **** **** +10224 Archivist_Still_HEARTCLUTCH **** **** **** **** **** **** **** **** +10225 Archivist_Ice_Storm **** **** **** **** **** **** **** **** +10226 Archivist_Empowered_Ice_Storm **** **** **** **** **** **** **** **** +10227 Archivist_Maximized_Ice_Storm **** **** **** **** **** **** **** **** +10228 Archivist_Quickened_Ice_Storm **** **** **** **** **** **** **** **** +10229 Archivist_Silent_Ice_Storm **** **** **** **** **** **** **** **** +10230 Archivist_Still_Ice_Storm **** **** **** **** **** **** **** **** +10231 Archivist_Inferno **** **** **** **** **** **** **** **** +10232 Archivist_Empowered_Inferno **** **** **** **** **** **** **** **** +10233 Archivist_Exteneded_Inferno **** **** **** **** **** **** **** **** +10234 Archivist_Maximized_Inferno **** **** **** **** **** **** **** **** +10235 Archivist_Quickened_Inferno **** **** **** **** **** **** **** **** +10236 Archivist_Silent_Inferno **** **** **** **** **** **** **** **** +10237 Archivist_Still_Inferno **** **** **** **** **** **** **** **** +10238 Archivist_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +10239 Archivist_Exteneded_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +10240 Archivist_Quickened_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +10241 Archivist_Silent_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +10242 Archivist_Still_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +10243 Archivist_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10244 Archivist_Empowered_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10245 Archivist_Exteneded_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10246 Archivist_Maximized_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10247 Archivist_Quickened_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10248 Archivist_Silent_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10249 Archivist_Still_Mass_Cats_Grace **** **** **** **** **** **** **** **** +10250 Archivist_Mass_Contagion **** **** **** **** **** **** **** **** +10251 Archivist_Quickened_Mass_Contagion **** **** **** **** **** **** **** **** +10252 Archivist_Silent_Mass_Contagion **** **** **** **** **** **** **** **** +10253 Archivist_Still_Mass_Contagion **** **** **** **** **** **** **** **** +10254 Archivist_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10255 Archivist_Empowered_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10256 Archivist_Maximized_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10257 Archivist_Quickened_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10258 Archivist_Silent_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10259 Archivist_Still_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +10260 Archivist_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10261 Archivist_Empowered_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10262 Archivist_Maximized_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10263 Archivist_Quickened_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10264 Archivist_Silent_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10265 Archivist_Still_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +10266 Archivist_MORALITY_UNDONE **** **** **** **** **** **** **** **** +10267 Archivist_Quickened_MORALITY_UNDONE **** **** **** **** **** **** **** **** +10268 Archivist_Silent_MORALITY_UNDONE **** **** **** **** **** **** **** **** +10269 Archivist_Still_MORALITY_UNDONE **** **** **** **** **** **** **** **** +10270 Archivist_Necrotic_Burst **** **** **** **** **** **** **** **** +10271 Archivist_Empowered_Necrotic_Burst **** **** **** **** **** **** **** **** +10272 Archivist_Maximized_Necrotic_Burst **** **** **** **** **** **** **** **** +10273 Archivist_Quickened_Necrotic_Burst **** **** **** **** **** **** **** **** +10274 Archivist_Silent_Necrotic_Burst **** **** **** **** **** **** **** **** +10275 Archivist_Still_Necrotic_Burst **** **** **** **** **** **** **** **** +10276 Archivist_Owls_Insight **** **** **** **** **** **** **** **** +10277 Archivist_Exteneded_Owls_Insight **** **** **** **** **** **** **** **** +10278 Archivist_Quickened_Owls_Insight **** **** **** **** **** **** **** **** +10279 Archivist_Silent_Owls_Insight **** **** **** **** **** **** **** **** +10280 Archivist_Still_Owls_Insight **** **** **** **** **** **** **** **** +10281 Archivist_POWER_LEECH **** **** **** **** **** **** **** **** +10282 Archivist_Exteneded_POWER_LEECH **** **** **** **** **** **** **** **** +10283 Archivist_Quickened_POWER_LEECH **** **** **** **** **** **** **** **** +10284 Archivist_Silent_POWER_LEECH **** **** **** **** **** **** **** **** +10285 Archivist_Still_POWER_LEECH **** **** **** **** **** **** **** **** +10286 Archivist_Raise_Dead **** **** **** **** **** **** **** **** +10287 Archivist_Quickened_Raise_Dead **** **** **** **** **** **** **** **** +10288 Archivist_Silent_Raise_Dead **** **** **** **** **** **** **** **** +10289 Archivist_Still_Raise_Dead **** **** **** **** **** **** **** **** +10290 Archivist_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +10291 Archivist_Exteneded_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +10292 Archivist_Quickened_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +10293 Archivist_Silent_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +10294 Archivist_Revivify **** **** **** **** **** **** **** **** +10295 Archivist_Quickened_Revivify **** **** **** **** **** **** **** **** +10296 Archivist_Silent_Revivify **** **** **** **** **** **** **** **** +10297 Archivist_Still_Revivify **** **** **** **** **** **** **** **** +10298 Archivist_Righteous_Might **** **** **** **** **** **** **** **** +10299 Archivist_Exteneded_Righteous_Might **** **** **** **** **** **** **** **** +10300 Archivist_Quickened_Righteous_Might **** **** **** **** **** **** **** **** +10301 Archivist_Silent_Righteous_Might **** **** **** **** **** **** **** **** +10302 Archivist_Still_Righteous_Might **** **** **** **** **** **** **** **** +10303 Archivist_Scrying **** **** **** **** **** **** **** **** +10304 Archivist_Exteneded_Scrying **** **** **** **** **** **** **** **** +10305 Archivist_Quickened_Scrying **** **** **** **** **** **** **** **** +10306 Archivist_Silent_Scrying **** **** **** **** **** **** **** **** +10307 Archivist_Still_Scrying **** **** **** **** **** **** **** **** +10308 Archivist_SICKEN_EVIL **** **** **** **** **** **** **** **** +10309 Archivist_Exteneded_SICKEN_EVIL **** **** **** **** **** **** **** **** +10310 Archivist_Quickened_SICKEN_EVIL **** **** **** **** **** **** **** **** +10311 Archivist_Silent_SICKEN_EVIL **** **** **** **** **** **** **** **** +10312 Archivist_Still_SICKEN_EVIL **** **** **** **** **** **** **** **** +10313 Archivist_Slay_Living **** **** **** **** **** **** **** **** +10314 Archivist_Empowered_Slay_Living **** **** **** **** **** **** **** **** +10315 Archivist_Maximized_Slay_Living **** **** **** **** **** **** **** **** +10316 Archivist_Quickened_Slay_Living **** **** **** **** **** **** **** **** +10317 Archivist_Silent_Slay_Living **** **** **** **** **** **** **** **** +10318 Archivist_Still_Slay_Living **** **** **** **** **** **** **** **** +10319 Archivist_Soulscour **** **** **** **** **** **** **** **** +10320 Archivist_Empowered_Soulscour **** **** **** **** **** **** **** **** +10321 Archivist_Maximized_Soulscour **** **** **** **** **** **** **** **** +10322 Archivist_Quickened_Soulscour **** **** **** **** **** **** **** **** +10323 Archivist_Silent_Soulscour **** **** **** **** **** **** **** **** +10324 Archivist_Still_Soulscour **** **** **** **** **** **** **** **** +10325 Archivist_Spell_Mantle **** **** **** **** **** **** **** **** +10326 Archivist_Empowered_Spell_Mantle **** **** **** **** **** **** **** **** +10327 Archivist_Exteneded_Spell_Mantle **** **** **** **** **** **** **** **** +10328 Archivist_Maximized_Spell_Mantle **** **** **** **** **** **** **** **** +10329 Archivist_Quickened_Spell_Mantle **** **** **** **** **** **** **** **** +10330 Archivist_Silent_Spell_Mantle **** **** **** **** **** **** **** **** +10331 Archivist_Still_Spell_Mantle **** **** **** **** **** **** **** **** +10332 Archivist_Spell_Resistance **** **** **** **** **** **** **** **** +10333 Archivist_Exteneded_Spell_Resistance **** **** **** **** **** **** **** **** +10334 Archivist_Quickened_Spell_Resistance **** **** **** **** **** **** **** **** +10335 Archivist_Silent_Spell_Resistance **** **** **** **** **** **** **** **** +10336 Archivist_Still_Spell_Resistance **** **** **** **** **** **** **** **** +10337 Archivist_Stone_to_flesh **** **** **** **** **** **** **** **** +10338 Archivist_Exteneded_Stone_to_flesh **** **** **** **** **** **** **** **** +10339 Archivist_Quickened_Stone_to_flesh **** **** **** **** **** **** **** **** +10340 Archivist_Silent_Stone_to_flesh **** **** **** **** **** **** **** **** +10341 Archivist_Still_Stone_to_flesh **** **** **** **** **** **** **** **** +10342 Archivist_Summon_Creature_V **** **** **** **** **** **** **** **** +10343 Archivist_Exteneded_Summon_Creature_V **** **** **** **** **** **** **** **** +10344 Archivist_Quickened_Summon_Creature_V **** **** **** **** **** **** **** **** +10345 Archivist_Silent_Summon_Creature_V **** **** **** **** **** **** **** **** +10346 Archivist_Still_Summon_Creature_V **** **** **** **** **** **** **** **** +10347 Archivist_SummonUndeadV **** **** **** **** **** **** **** **** +10348 Archivist_Exteneded_SummonUndeadV **** **** **** **** **** **** **** **** +10349 Archivist_Quickened_SummonUndeadV **** **** **** **** **** **** **** **** +10350 Archivist_Silent_SummonUndeadV **** **** **** **** **** **** **** **** +10351 Archivist_Still_SummonUndeadV **** **** **** **** **** **** **** **** +10352 Archivist_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10353 Archivist_Empowered_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10354 Archivist_Exteneded_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10355 Archivist_Maximized_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10356 Archivist_Quickened_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10357 Archivist_Silent_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10358 Archivist_Still_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +10359 Archivist_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10360 Archivist_Empowered_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10361 Archivist_Exteneded_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10362 Archivist_Maximized_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10363 Archivist_Quickened_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10364 Archivist_Silent_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10365 Archivist_Still_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +10366 Archivist_Teleport_RadialMaster **** **** **** **** **** **** **** **** +10367 Archivist_Teleport_SelfOnly **** **** **** **** **** **** **** **** +10368 Archivist_Teleport_Party **** **** **** **** **** **** **** **** +10369 Archivist_Quickened_Teleport_RadialMaster **** **** **** **** **** **** **** **** +10370 Archivist_Quickened_Teleport_SelfOnly **** **** **** **** **** **** **** **** +10371 Archivist_Quickened_Teleport_Party **** **** **** **** **** **** **** **** +10372 Archivist_Silent_Teleport_RadialMaster **** **** **** **** **** **** **** **** +10373 Archivist_Silent_Teleport_SelfOnly **** **** **** **** **** **** **** **** +10374 Archivist_Silent_Teleport_Party **** **** **** **** **** **** **** **** +10375 Archivist_True_Seeing **** **** **** **** **** **** **** **** +10376 Archivist_Exteneded_True_Seeing **** **** **** **** **** **** **** **** +10377 Archivist_Quickened_True_Seeing **** **** **** **** **** **** **** **** +10378 Archivist_Silent_True_Seeing **** **** **** **** **** **** **** **** +10379 Archivist_Still_True_Seeing **** **** **** **** **** **** **** **** +10380 Archivist_Vine_Mine **** **** **** **** **** **** **** **** +10381 Archivist_Vine_Mine_Entangle **** **** **** **** **** **** **** **** +10382 Archivist_Vine_Mine_Hamper_Movement **** **** **** **** **** **** **** **** +10383 Archivist_Vine_Mine_Camouflage **** **** **** **** **** **** **** **** +10384 Archivist_Exteneded_Vine_Mine **** **** **** **** **** **** **** **** +10385 Archivist_Exteneded_Vine_Mine_Entangle **** **** **** **** **** **** **** **** +10386 Archivist_Exteneded_Vine_Mine_Hamper_Movement **** **** **** **** **** **** **** **** +10387 Archivist_Exteneded_Vine_Mine_Camouflage **** **** **** **** **** **** **** **** +10388 Archivist_Quickened_Vine_Mine **** **** **** **** **** **** **** **** +10389 Archivist_Quickened_Vine_Mine_Entangle **** **** **** **** **** **** **** **** +10390 Archivist_Quickened_Vine_Mine_Hamper_Movement **** **** **** **** **** **** **** **** +10391 Archivist_Quickened_Vine_Mine_Camouflage **** **** **** **** **** **** **** **** +10392 Archivist_Silent_Vine_Mine **** **** **** **** **** **** **** **** +10393 Archivist_Silent_Vine_Mine_Entangle **** **** **** **** **** **** **** **** +10394 Archivist_Silent_Vine_Mine_Hamper_Movement **** **** **** **** **** **** **** **** +10395 Archivist_Silent_Vine_Mine_Camouflage **** **** **** **** **** **** **** **** +10396 Archivist_Still_Vine_Mine **** **** **** **** **** **** **** **** +10397 Archivist_Still_Vine_Mine_Entangle **** **** **** **** **** **** **** **** +10398 Archivist_Still_Vine_Mine_Hamper_Movement **** **** **** **** **** **** **** **** +10399 Archivist_Still_Vine_Mine_Camouflage **** **** **** **** **** **** **** **** +10400 Archivist_Viscid_Glob **** **** **** **** **** **** **** **** +10401 Archivist_Exteneded_Viscid_Glob **** **** **** **** **** **** **** **** +10402 Archivist_Quickened_Viscid_Glob **** **** **** **** **** **** **** **** +10403 Archivist_Silent_Viscid_Glob **** **** **** **** **** **** **** **** +10404 Archivist_Still_Viscid_Glob **** **** **** **** **** **** **** **** +10405 Archivist_Wall_of_Fire **** **** **** **** **** **** **** **** +10406 Archivist_Empowered_Wall_of_Fire **** **** **** **** **** **** **** **** +10407 Archivist_Exteneded_Wall_of_Fire **** **** **** **** **** **** **** **** +10408 Archivist_Maximized_Wall_of_Fire **** **** **** **** **** **** **** **** +10409 Archivist_Quickened_Wall_of_Fire **** **** **** **** **** **** **** **** +10410 Archivist_Silent_Wall_of_Fire **** **** **** **** **** **** **** **** +10411 Archivist_Still_Wall_of_Fire **** **** **** **** **** **** **** **** +10412 Archivist_Acid_Storm **** **** **** **** **** **** **** **** +10413 Archivist_Empowered_Acid_Storm **** **** **** **** **** **** **** **** +10414 Archivist_Maximized_Acid_Storm **** **** **** **** **** **** **** **** +10415 Archivist_Silent_Acid_Storm **** **** **** **** **** **** **** **** +10416 Archivist_Still_Acid_Storm **** **** **** **** **** **** **** **** +10417 Archivist_Animate_Object **** **** **** **** **** **** **** **** +10418 Archivist_Exteneded_Animate_Object **** **** **** **** **** **** **** **** +10419 Archivist_Banishment **** **** **** **** **** **** **** **** +10420 Archivist_Silent_Banishment **** **** **** **** **** **** **** **** +10421 Archivist_Still_Banishment **** **** **** **** **** **** **** **** +10422 Archivist_Blade_Barrier **** **** **** **** **** **** **** **** +10423 Archivist_Empowered_Blade_Barrier **** **** **** **** **** **** **** **** +10424 Archivist_Exteneded_Blade_Barrier **** **** **** **** **** **** **** **** +10425 Archivist_Maximized_Blade_Barrier **** **** **** **** **** **** **** **** +10426 Archivist_Silent_Blade_Barrier **** **** **** **** **** **** **** **** +10427 Archivist_Still_Blade_Barrier **** **** **** **** **** **** **** **** +10428 Archivist_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +10429 Archivist_Empowered_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +10430 Archivist_Maximized_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +10431 Archivist_Silent_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +10432 Archivist_Still_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +10433 Archivist_CELESTIAL_BLOOD **** **** **** **** **** **** **** **** +10434 Archivist_Silent_CELESTIAL_BLOOD **** **** **** **** **** **** **** **** +10435 Archivist_Still_CELESTIAL_BLOOD **** **** **** **** **** **** **** **** +10436 Archivist_Chain_Lightning **** **** **** **** **** **** **** **** +10437 Archivist_Empowered_Chain_Lightning **** **** **** **** **** **** **** **** +10438 Archivist_Maximized_Chain_Lightning **** **** **** **** **** **** **** **** +10439 Archivist_Silent_Chain_Lightning **** **** **** **** **** **** **** **** +10440 Archivist_Still_Chain_Lightning **** **** **** **** **** **** **** **** +10441 Archivist_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +10442 Archivist_Exteneded_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +10443 Archivist_Silent_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +10444 Archivist_Still_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +10445 Archivist_Control_Undead **** **** **** **** **** **** **** **** +10446 Archivist_Exteneded_Control_Undead **** **** **** **** **** **** **** **** +10447 Archivist_Silent_Control_Undead **** **** **** **** **** **** **** **** +10448 Archivist_Still_Control_Undead **** **** **** **** **** **** **** **** +10449 Archivist_Create_Undead **** **** **** **** **** **** **** **** +10450 Archivist_Exteneded_Create_Undead **** **** **** **** **** **** **** **** +10451 Archivist_Silent_Create_Undead **** **** **** **** **** **** **** **** +10452 Archivist_Still_Create_Undead **** **** **** **** **** **** **** **** +10453 Archivist_Crumble **** **** **** **** **** **** **** **** +10454 Archivist_Empowered_Crumble **** **** **** **** **** **** **** **** +10455 Archivist_Maximized_Crumble **** **** **** **** **** **** **** **** +10456 Archivist_Silent_Crumble **** **** **** **** **** **** **** **** +10457 Archivist_Still_Crumble **** **** **** **** **** **** **** **** +10458 Archivist_Drown **** **** **** **** **** **** **** **** +10459 Archivist_Silent_Drown **** **** **** **** **** **** **** **** +10460 Archivist_Still_Drown **** **** **** **** **** **** **** **** +10461 Archivist_Energy_Buffer **** **** **** **** **** **** **** **** +10462 Archivist_Exteneded_Energy_Buffer **** **** **** **** **** **** **** **** +10463 Archivist_Silent_Energy_Buffer **** **** **** **** **** **** **** **** +10464 Archivist_Still_Energy_Buffer **** **** **** **** **** **** **** **** +10465 Archivist_Energy_Immunity **** **** **** **** **** **** **** **** +10466 Archivist_EI_Acid **** **** **** **** **** **** **** **** +10467 Archivist_EI_Cold **** **** **** **** **** **** **** **** +10468 Archivist_EI_Elec **** **** **** **** **** **** **** **** +10469 Archivist_EI_Fire **** **** **** **** **** **** **** **** +10470 Archivist_EI_Sonic **** **** **** **** **** **** **** **** +10471 Archivist_Exteneded_Energy_Immunity **** **** **** **** **** **** **** **** +10472 Archivist_Exteneded_EI_Acid **** **** **** **** **** **** **** **** +10473 Archivist_Exteneded_EI_Cold **** **** **** **** **** **** **** **** +10474 Archivist_Exteneded_EI_Elec **** **** **** **** **** **** **** **** +10475 Archivist_Exteneded_EI_Fire **** **** **** **** **** **** **** **** +10476 Archivist_Exteneded_EI_Sonic **** **** **** **** **** **** **** **** +10477 Archivist_Silent_Energy_Immunity **** **** **** **** **** **** **** **** +10478 Archivist_Silent_EI_Acid **** **** **** **** **** **** **** **** +10479 Archivist_Silent_EI_Cold **** **** **** **** **** **** **** **** +10480 Archivist_Silent_EI_Elec **** **** **** **** **** **** **** **** +10481 Archivist_Silent_EI_Fire **** **** **** **** **** **** **** **** +10482 Archivist_Silent_EI_Sonic **** **** **** **** **** **** **** **** +10483 Archivist_Still_Energy_Immunity **** **** **** **** **** **** **** **** +10484 Archivist_Still_EI_Acid **** **** **** **** **** **** **** **** +10485 Archivist_Still_EI_Cold **** **** **** **** **** **** **** **** +10486 Archivist_Still_EI_Elec **** **** **** **** **** **** **** **** +10487 Archivist_Still_EI_Fire **** **** **** **** **** **** **** **** +10488 Archivist_Still_EI_Sonic **** **** **** **** **** **** **** **** +10489 Archivist_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +10490 Archivist_Exteneded_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +10491 Archivist_Silent_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +10492 Archivist_ExtractWaterElemental **** **** **** **** **** **** **** **** +10493 Archivist_Empowered_ExtractWaterElemental **** **** **** **** **** **** **** **** +10494 Archivist_Maximized_ExtractWaterElemental **** **** **** **** **** **** **** **** +10495 Archivist_Silent_ExtractWaterElemental **** **** **** **** **** **** **** **** +10496 Archivist_Still_ExtractWaterElemental **** **** **** **** **** **** **** **** +10497 Archivist_Greater_Dispelling **** **** **** **** **** **** **** **** +10498 Archivist_Silent_Greater_Dispelling **** **** **** **** **** **** **** **** +10499 Archivist_Still_Greater_Dispelling **** **** **** **** **** **** **** **** +10500 Archivist_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10501 Archivist_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10502 Archivist_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10503 Archivist_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10504 Archivist_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10505 Archivist_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10506 Archivist_Empowered_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10507 Archivist_Empowered_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10508 Archivist_Empowered_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10509 Archivist_Empowered_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10510 Archivist_Empowered_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10511 Archivist_Empowered_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10512 Archivist_Exteneded_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10513 Archivist_Exteneded_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10514 Archivist_Exteneded_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10515 Archivist_Exteneded_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10516 Archivist_Exteneded_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10517 Archivist_Exteneded_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10518 Archivist_Maximized_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10519 Archivist_Maximized_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10520 Archivist_Maximized_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10521 Archivist_Maximized_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10522 Archivist_Maximized_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10523 Archivist_Maximized_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10524 Archivist_Silent_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10525 Archivist_Silent_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10526 Archivist_Silent_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10527 Archivist_Silent_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10528 Archivist_Silent_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10529 Archivist_Silent_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10530 Archivist_Still_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +10531 Archivist_Still_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +10532 Archivist_Still_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +10533 Archivist_Still_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +10534 Archivist_Still_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +10535 Archivist_Still_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +10536 Archivist_Etherealness **** **** **** **** **** **** **** **** +10537 Archivist_Exteneded_Etherealness **** **** **** **** **** **** **** **** +10538 Archivist_Silent_Etherealness **** **** **** **** **** **** **** **** +10539 Archivist_Still_Etherealness **** **** **** **** **** **** **** **** +10540 Archivist_Greater_Stoneskin **** **** **** **** **** **** **** **** +10541 Archivist_Exteneded_Greater_Stoneskin **** **** **** **** **** **** **** **** +10542 Archivist_Silent_Greater_Stoneskin **** **** **** **** **** **** **** **** +10543 Archivist_Still_Greater_Stoneskin **** **** **** **** **** **** **** **** +10544 Archivist_Harm **** **** **** **** **** **** **** **** +10545 Archivist_Silent_Harm **** **** **** **** **** **** **** **** +10546 Archivist_Still_Harm **** **** **** **** **** **** **** **** +10547 Archivist_Heal **** **** **** **** **** **** **** **** +10548 Archivist_Silent_Heal **** **** **** **** **** **** **** **** +10549 Archivist_Still_Heal **** **** **** **** **** **** **** **** +10550 Archivist_Legend_Lore **** **** **** **** **** **** **** **** +10551 Archivist_Exteneded_Legend_Lore **** **** **** **** **** **** **** **** +10552 Archivist_Silent_Legend_Lore **** **** **** **** **** **** **** **** +10553 Archivist_Still_Legend_Lore **** **** **** **** **** **** **** **** +10554 Archivist_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10555 Archivist_Empowered_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10556 Archivist_Exteneded_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10557 Archivist_Maximized_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10558 Archivist_Silent_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10559 Archivist_Still_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +10560 Archivist_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +10561 Archivist_Empowered_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +10562 Archivist_Maximized_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +10563 Archivist_Silent_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +10564 Archivist_Still_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +10565 Archivist_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10566 Archivist_Empowered_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10567 Archivist_Exteneded_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10568 Archivist_Maximized_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10569 Archivist_Silent_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10570 Archivist_Still_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +10571 Archivist_Mass_Endurance **** **** **** **** **** **** **** **** +10572 Archivist_Empowered_Mass_Endurance **** **** **** **** **** **** **** **** +10573 Archivist_Exteneded_Mass_Endurance **** **** **** **** **** **** **** **** +10574 Archivist_Maximized_Mass_Endurance **** **** **** **** **** **** **** **** +10575 Archivist_Silent_Mass_Endurance **** **** **** **** **** **** **** **** +10576 Archivist_Still_Mass_Endurance **** **** **** **** **** **** **** **** +10577 Archivist_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10578 Archivist_Empowered_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10579 Archivist_Exteneded_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10580 Archivist_Maximized_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10581 Archivist_Silent_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10582 Archivist_Still_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +10583 Archivist_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +10584 Archivist_Empowered_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +10585 Archivist_Maximized_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +10586 Archivist_Silent_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +10587 Archivist_Still_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +10588 Archivist_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10589 Archivist_Empowered_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10590 Archivist_Exteneded_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10591 Archivist_Maximized_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10592 Archivist_Silent_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10593 Archivist_Still_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +10594 Archivist_Necrotic_Eruption **** **** **** **** **** **** **** **** +10595 Archivist_Empowered_Necrotic_Eruption **** **** **** **** **** **** **** **** +10596 Archivist_Maximized_Necrotic_Eruption **** **** **** **** **** **** **** **** +10597 Archivist_Silent_Necrotic_Eruption **** **** **** **** **** **** **** **** +10598 Archivist_Still_Necrotic_Eruption **** **** **** **** **** **** **** **** +10599 Archivist_Planar_Ally **** **** **** **** **** **** **** **** +10600 Archivist_Exteneded_Planar_Ally **** **** **** **** **** **** **** **** +10601 Archivist_Silent_Planar_Ally **** **** **** **** **** **** **** **** +10602 Archivist_Still_Planar_Ally **** **** **** **** **** **** **** **** +10603 Archivist_Planar_Binding **** **** **** **** **** **** **** **** +10604 Archivist_Exteneded_Planar_Binding **** **** **** **** **** **** **** **** +10605 Archivist_Silent_Planar_Binding **** **** **** **** **** **** **** **** +10606 Archivist_Still_Planar_Binding **** **** **** **** **** **** **** **** +10607 Archivist_Pox **** **** **** **** **** **** **** **** +10608 Archivist_Empowered_Pox **** **** **** **** **** **** **** **** +10609 Archivist_Maximized_Pox **** **** **** **** **** **** **** **** +10610 Archivist_Silent_Pox **** **** **** **** **** **** **** **** +10611 Archivist_Still_Pox **** **** **** **** **** **** **** **** +10612 Archivist_SarcophagusOfStone **** **** **** **** **** **** **** **** +10613 Archivist_Silent_SarcophagusOfStone **** **** **** **** **** **** **** **** +10614 Archivist_Still_SarcophagusOfStone **** **** **** **** **** **** **** **** +10615 Archivist_Stonehold **** **** **** **** **** **** **** **** +10616 Archivist_Empowered_Stonehold **** **** **** **** **** **** **** **** +10617 Archivist_Exteneded_Stonehold **** **** **** **** **** **** **** **** +10618 Archivist_Maximized_Stonehold **** **** **** **** **** **** **** **** +10619 Archivist_Silent_Stonehold **** **** **** **** **** **** **** **** +10620 Archivist_Still_Stonehold **** **** **** **** **** **** **** **** +10621 Archivist_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +10622 Archivist_Empowered_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +10623 Archivist_Maximized_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +10624 Archivist_Silent_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +10625 Archivist_Still_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +10626 Archivist_Summon_Creature_VI **** **** **** **** **** **** **** **** +10627 Archivist_Exteneded_Summon_Creature_VI **** **** **** **** **** **** **** **** +10628 Archivist_Silent_Summon_Creature_VI **** **** **** **** **** **** **** **** +10629 Archivist_Still_Summon_Creature_VI **** **** **** **** **** **** **** **** +10630 Archivist_Superior_Resistance **** **** **** **** **** **** **** **** +10631 Archivist_Exteneded_Superior_Resistance **** **** **** **** **** **** **** **** +10632 Archivist_Silent_Superior_Resistance **** **** **** **** **** **** **** **** +10633 Archivist_Still_Superior_Resistance **** **** **** **** **** **** **** **** +10634 Archivist_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10635 Archivist_Empowered_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10636 Archivist_Exteneded_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10637 Archivist_Maximized_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10638 Archivist_Silent_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10639 Archivist_Still_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +10640 Archivist_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10641 Archivist_Empowered_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10642 Archivist_Exteneded_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10643 Archivist_Maximized_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10644 Archivist_Silent_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10645 Archivist_Still_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +10646 Archivist_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10647 Archivist_Empowered_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10648 Archivist_Exteneded_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10649 Archivist_Maximized_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10650 Archivist_Silent_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10651 Archivist_Still_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +10652 Archivist_TransportViaPlants_RadialMaster **** **** **** **** **** **** **** **** +10653 Archivist_TransportViaPlants_SelfOnly **** **** **** **** **** **** **** **** +10654 Archivist_TransportViaPlants_Party **** **** **** **** **** **** **** **** +10655 Archivist_Silent_TransportViaPlants_RadialMaster **** **** **** **** **** **** **** **** +10656 Archivist_Silent_TransportViaPlants_SelfOnly **** **** **** **** **** **** **** **** +10657 Archivist_Silent_TransportViaPlants_Party **** **** **** **** **** **** **** **** +10658 Archivist_Undeath_to_Death **** **** **** **** **** **** **** **** +10659 Archivist_Empowered_Undeath_to_Death **** **** **** **** **** **** **** **** +10660 Archivist_Maximized_Undeath_to_Death **** **** **** **** **** **** **** **** +10661 Archivist_Silent_Undeath_to_Death **** **** **** **** **** **** **** **** +10662 Archivist_Still_Undeath_to_Death **** **** **** **** **** **** **** **** +10663 Archivist_Vigorous_Circle **** **** **** **** **** **** **** **** +10664 Archivist_Exteneded_Vigorous_Circle **** **** **** **** **** **** **** **** +10665 Archivist_Silent_Vigorous_Circle **** **** **** **** **** **** **** **** +10666 Archivist_Still_Vigorous_Circle **** **** **** **** **** **** **** **** +10667 Archivist_WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +10668 Archivist_WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +10669 Archivist_WordOfRecall_Party **** **** **** **** **** **** **** **** +10670 Archivist_Silent_WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +10671 Archivist_Silent_WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +10672 Archivist_Silent_WordOfRecall_Party **** **** **** **** **** **** **** **** +10673 Archivist_Aura_of_Vitality **** **** **** **** **** **** **** **** +10674 Archivist_Exteneded_Aura_of_Vitality **** **** **** **** **** **** **** **** +10675 Archivist_Silent_Aura_of_Vitality **** **** **** **** **** **** **** **** +10676 Archivist_Still_Aura_of_Vitality **** **** **** **** **** **** **** **** +10677 Archivist_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +10678 Archivist_Exteneded_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +10679 Archivist_Silent_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +10680 Archivist_Still_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +10681 Archivist_Blasphemy **** **** **** **** **** **** **** **** +10682 Archivist_Silent_Blasphemy **** **** **** **** **** **** **** **** +10683 Archivist_Still_Blasphemy **** **** **** **** **** **** **** **** +10684 Archivist_Control_Weather **** **** **** **** **** **** **** **** +10685 Archivist_CW_Rain **** **** **** **** **** **** **** **** +10686 Archivist_CW_Snow **** **** **** **** **** **** **** **** +10687 Archivist_CW_Clear **** **** **** **** **** **** **** **** +10688 Archivist_Exteneded_Control_Weather **** **** **** **** **** **** **** **** +10689 Archivist_Exteneded_CW_Rain **** **** **** **** **** **** **** **** +10690 Archivist_Exteneded_CW_Snow **** **** **** **** **** **** **** **** +10691 Archivist_Exteneded_CW_Clear **** **** **** **** **** **** **** **** +10692 Archivist_Silent_Control_Weather **** **** **** **** **** **** **** **** +10693 Archivist_Silent_CW_Rain **** **** **** **** **** **** **** **** +10694 Archivist_Silent_CW_Snow **** **** **** **** **** **** **** **** +10695 Archivist_Silent_CW_Clear **** **** **** **** **** **** **** **** +10696 Archivist_Still_Control_Weather **** **** **** **** **** **** **** **** +10697 Archivist_Still_CW_Rain **** **** **** **** **** **** **** **** +10698 Archivist_Still_CW_Snow **** **** **** **** **** **** **** **** +10699 Archivist_Still_CW_Clear **** **** **** **** **** **** **** **** +10700 Archivist_Creeping_Doom **** **** **** **** **** **** **** **** +10701 Archivist_Exteneded_Creeping_Doom **** **** **** **** **** **** **** **** +10702 Archivist_Silent_Creeping_Doom **** **** **** **** **** **** **** **** +10703 Archivist_Still_Creeping_Doom **** **** **** **** **** **** **** **** +10704 Archivist_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +10705 Archivist_Silent_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +10706 Archivist_Still_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +10707 Archivist_Destruction **** **** **** **** **** **** **** **** +10708 Archivist_Silent_Destruction **** **** **** **** **** **** **** **** +10709 Archivist_Still_Destruction **** **** **** **** **** **** **** **** +10710 Archivist_Dictum **** **** **** **** **** **** **** **** +10711 Archivist_Silent_Dictum **** **** **** **** **** **** **** **** +10712 Archivist_Still_Dictum **** **** **** **** **** **** **** **** +10713 Archivist_Disintegrate **** **** **** **** **** **** **** **** +10714 Archivist_Empowered_Disintegrate **** **** **** **** **** **** **** **** +10715 Archivist_Silent_Disintegrate **** **** **** **** **** **** **** **** +10716 Archivist_Still_Disintegrate **** **** **** **** **** **** **** **** +10717 Archivist_DRAGON_ALLY **** **** **** **** **** **** **** **** +10718 Archivist_Exteneded_DRAGON_ALLY **** **** **** **** **** **** **** **** +10719 Archivist_Silent_DRAGON_ALLY **** **** **** **** **** **** **** **** +10720 Archivist_Energy_Ebb **** **** **** **** **** **** **** **** +10721 Archivist_Exteneded_Energy_Ebb **** **** **** **** **** **** **** **** +10722 Archivist_Silent_Energy_Ebb **** **** **** **** **** **** **** **** +10723 Archivist_Still_Energy_Ebb **** **** **** **** **** **** **** **** +10724 Archivist_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +10725 Archivist_Silent_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +10726 Archivist_Still_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +10727 Archivist_Great_Thunderclap **** **** **** **** **** **** **** **** +10728 Archivist_Silent_Great_Thunderclap **** **** **** **** **** **** **** **** +10729 Archivist_Still_Great_Thunderclap **** **** **** **** **** **** **** **** +10730 Archivist_Greater_Harm **** **** **** **** **** **** **** **** +10731 Archivist_Silent_Greater_Harm **** **** **** **** **** **** **** **** +10732 Archivist_Still_Greater_Harm **** **** **** **** **** **** **** **** +10733 Archivist_Greater_Restoration **** **** **** **** **** **** **** **** +10734 Archivist_Silent_Greater_Restoration **** **** **** **** **** **** **** **** +10735 Archivist_Still_Greater_Restoration **** **** **** **** **** **** **** **** +10736 Archivist_GreaterScrying **** **** **** **** **** **** **** **** +10737 Archivist_Exteneded_GreaterScrying **** **** **** **** **** **** **** **** +10738 Archivist_Silent_GreaterScrying **** **** **** **** **** **** **** **** +10739 Archivist_Still_GreaterScrying **** **** **** **** **** **** **** **** +10740 Archivist_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +10741 Archivist_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +10742 Archivist_GreaterTeleport_Party **** **** **** **** **** **** **** **** +10743 Archivist_Silent_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +10744 Archivist_Silent_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +10745 Archivist_Silent_GreaterTeleport_Party **** **** **** **** **** **** **** **** +10746 Archivist_Holy_Word **** **** **** **** **** **** **** **** +10747 Archivist_Silent_Holy_Word **** **** **** **** **** **** **** **** +10748 Archivist_Still_Holy_Word **** **** **** **** **** **** **** **** +10749 Archivist_Mass_Charm **** **** **** **** **** **** **** **** +10750 Archivist_Exteneded_Mass_Charm **** **** **** **** **** **** **** **** +10751 Archivist_Silent_Mass_Charm **** **** **** **** **** **** **** **** +10752 Archivist_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +10753 Archivist_Empowered_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +10754 Archivist_Silent_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +10755 Archivist_Still_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +10756 Archivist_Mass_Haste **** **** **** **** **** **** **** **** +10757 Archivist_Exteneded_Mass_Haste **** **** **** **** **** **** **** **** +10758 Archivist_Silent_Mass_Haste **** **** **** **** **** **** **** **** +10759 Archivist_Still_Mass_Haste **** **** **** **** **** **** **** **** +10760 Archivist_Mass_Hold_Person **** **** **** **** **** **** **** **** +10761 Archivist_Exteneded_Mass_Hold_Person **** **** **** **** **** **** **** **** +10762 Archivist_Silent_Mass_Hold_Person **** **** **** **** **** **** **** **** +10763 Archivist_Still_Mass_Hold_Person **** **** **** **** **** **** **** **** +10764 Archivist_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +10765 Archivist_Empowered_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +10766 Archivist_Silent_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +10767 Archivist_Still_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +10768 Archivist_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +10769 Archivist_Exteneded_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +10770 Archivist_Silent_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +10771 Archivist_Still_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +10772 Archivist_PHOENIX_FIRE **** **** **** **** **** **** **** **** +10773 Archivist_Empowered_PHOENIX_FIRE **** **** **** **** **** **** **** **** +10774 Archivist_Silent_PHOENIX_FIRE **** **** **** **** **** **** **** **** +10775 Archivist_Still_PHOENIX_FIRE **** **** **** **** **** **** **** **** +10776 Archivist_Prismatic_Spray **** **** **** **** **** **** **** **** +10777 Archivist_Silent_Prismatic_Spray **** **** **** **** **** **** **** **** +10778 Archivist_Still_Prismatic_Spray **** **** **** **** **** **** **** **** +10779 Archivist_Protection_from_Spells **** **** **** **** **** **** **** **** +10780 Archivist_Exteneded_Protection_from_Spells **** **** **** **** **** **** **** **** +10781 Archivist_Silent_Protection_from_Spells **** **** **** **** **** **** **** **** +10782 Archivist_Still_Protection_from_Spells **** **** **** **** **** **** **** **** +10783 Archivist_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +10784 Archivist_Empowered_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +10785 Archivist_Exteneded_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +10786 Archivist_Silent_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +10787 Archivist_Still_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +10788 Archivist_RAIN_OF_ROSES **** **** **** **** **** **** **** **** +10789 Archivist_Exteneded_RAIN_OF_ROSES **** **** **** **** **** **** **** **** +10790 Archivist_Silent_RAIN_OF_ROSES **** **** **** **** **** **** **** **** +10791 Archivist_Still_RAIN_OF_ROSES **** **** **** **** **** **** **** **** +10792 Archivist_RAPTURE_OF_RUPTURE **** **** **** **** **** **** **** **** +10793 Archivist_Empowered_RAPTURE_OF_RUPTURE **** **** **** **** **** **** **** **** +10794 Archivist_Regenerate **** **** **** **** **** **** **** **** +10795 Archivist_Exteneded_Regenerate **** **** **** **** **** **** **** **** +10796 Archivist_Silent_Regenerate **** **** **** **** **** **** **** **** +10797 Archivist_Still_Regenerate **** **** **** **** **** **** **** **** +10798 Archivist_Repulsion **** **** **** **** **** **** **** **** +10799 Archivist_Exteneded_Repulsion **** **** **** **** **** **** **** **** +10800 Archivist_Silent_Repulsion **** **** **** **** **** **** **** **** +10801 Archivist_Still_Repulsion **** **** **** **** **** **** **** **** +10802 Archivist_Resurrection **** **** **** **** **** **** **** **** +10803 Archivist_Silent_Resurrection **** **** **** **** **** **** **** **** +10804 Archivist_Still_Resurrection **** **** **** **** **** **** **** **** +10805 Archivist_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +10806 Archivist_Empowered_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +10807 Archivist_Silent_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +10808 Archivist_Still_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +10809 Archivist_Spell_Turning **** **** **** **** **** **** **** **** +10810 Archivist_Empowered_Spell_Turning **** **** **** **** **** **** **** **** +10811 Archivist_Exteneded_Spell_Turning **** **** **** **** **** **** **** **** +10812 Archivist_Silent_Spell_Turning **** **** **** **** **** **** **** **** +10813 Archivist_Still_Spell_Turning **** **** **** **** **** **** **** **** +10814 Archivist_Summon_Creature_VII **** **** **** **** **** **** **** **** +10815 Archivist_Summon7Air **** **** **** **** **** **** **** **** +10816 Archivist_Summon7Earth **** **** **** **** **** **** **** **** +10817 Archivist_Summon7Fire **** **** **** **** **** **** **** **** +10818 Archivist_Summon7Water **** **** **** **** **** **** **** **** +10819 Archivist_Exteneded_Summon_Creature_VII **** **** **** **** **** **** **** **** +10820 Archivist_Exteneded_Summon7Air **** **** **** **** **** **** **** **** +10821 Archivist_Exteneded_Summon7Earth **** **** **** **** **** **** **** **** +10822 Archivist_Exteneded_Summon7Fire **** **** **** **** **** **** **** **** +10823 Archivist_Exteneded_Summon7Water **** **** **** **** **** **** **** **** +10824 Archivist_Silent_Summon_Creature_VII **** **** **** **** **** **** **** **** +10825 Archivist_Silent_Summon7Air **** **** **** **** **** **** **** **** +10826 Archivist_Silent_Summon7Earth **** **** **** **** **** **** **** **** +10827 Archivist_Silent_Summon7Fire **** **** **** **** **** **** **** **** +10828 Archivist_Silent_Summon7Water **** **** **** **** **** **** **** **** +10829 Archivist_Still_Summon_Creature_VII **** **** **** **** **** **** **** **** +10830 Archivist_Still_Summon7Air **** **** **** **** **** **** **** **** +10831 Archivist_Still_Summon7Earth **** **** **** **** **** **** **** **** +10832 Archivist_Still_Summon7Fire **** **** **** **** **** **** **** **** +10833 Archivist_Still_Summon7Water **** **** **** **** **** **** **** **** +10834 Archivist_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +10835 Archivist_Empowered_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +10836 Archivist_Exteneded_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +10837 Archivist_Silent_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +10838 Archivist_Still_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +10839 Archivist_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +10840 Archivist_Empowered_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +10841 Archivist_Exteneded_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +10842 Archivist_Silent_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +10843 Archivist_Still_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +10844 Archivist_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +10845 Archivist_Silent_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +10846 Archivist_Still_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +10847 Archivist_Word_of_Balance **** **** **** **** **** **** **** **** +10848 Archivist_Empowered_Word_of_Balance **** **** **** **** **** **** **** **** +10849 Archivist_Silent_Word_of_Balance **** **** **** **** **** **** **** **** +10850 Archivist_Word_of_Chaos **** **** **** **** **** **** **** **** +10851 Archivist_Silent_Word_of_Chaos **** **** **** **** **** **** **** **** +10852 Archivist_Still_Word_of_Chaos **** **** **** **** **** **** **** **** +10853 Archivist_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +10854 Archivist_Empowered_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +10855 Archivist_Silent_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +10856 Archivist_Still_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +10857 Archivist_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +10858 Archivist_Exteneded_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +10859 Archivist_Silent_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +10860 Archivist_Still_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +10861 Archivist_Aura_versus_Alignment **** **** **** **** **** **** **** **** +10862 Archivist_Unholy_Aura **** **** **** **** **** **** **** **** +10863 Archivist_Holy_Aura **** **** **** **** **** **** **** **** +10864 Archivist_Exteneded_Aura_versus_Alignment **** **** **** **** **** **** **** **** +10865 Archivist_Exteneded_Unholy_Aura **** **** **** **** **** **** **** **** +10866 Archivist_Exteneded_Holy_Aura **** **** **** **** **** **** **** **** +10867 Archivist_Silent_Aura_versus_Alignment **** **** **** **** **** **** **** **** +10868 Archivist_Silent_Unholy_Aura **** **** **** **** **** **** **** **** +10869 Archivist_Silent_Holy_Aura **** **** **** **** **** **** **** **** +10870 Archivist_Still_Aura_versus_Alignment **** **** **** **** **** **** **** **** +10871 Archivist_Still_Unholy_Aura **** **** **** **** **** **** **** **** +10872 Archivist_Still_Holy_Aura **** **** **** **** **** **** **** **** +10873 Archivist_Blackstaff **** **** **** **** **** **** **** **** +10874 Archivist_Exteneded_Blackstaff **** **** **** **** **** **** **** **** +10875 Archivist_Silent_Blackstaff **** **** **** **** **** **** **** **** +10876 Archivist_Still_Blackstaff **** **** **** **** **** **** **** **** +10877 Archivist_BODAK_BIRTH **** **** **** **** **** **** **** **** +10878 Archivist_Silent_BODAK_BIRTH **** **** **** **** **** **** **** **** +10879 Archivist_Still_BODAK_BIRTH **** **** **** **** **** **** **** **** +10880 Archivist_Bombardment **** **** **** **** **** **** **** **** +10881 Archivist_Silent_Bombardment **** **** **** **** **** **** **** **** +10882 Archivist_Still_Bombardment **** **** **** **** **** **** **** **** +10883 Archivist_Create_Greater_Undead **** **** **** **** **** **** **** **** +10884 Archivist_Exteneded_Create_Greater_Undead **** **** **** **** **** **** **** **** +10885 Archivist_Silent_Create_Greater_Undead **** **** **** **** **** **** **** **** +10886 Archivist_Still_Create_Greater_Undead **** **** **** **** **** **** **** **** +10887 Archivist_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +10888 Archivist_Exteneded_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +10889 Archivist_Silent_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +10890 Archivist_Still_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +10891 Archivist_Dimensional_Lock **** **** **** **** **** **** **** **** +10892 Archivist_Exteneded_Dimensional_Lock **** **** **** **** **** **** **** **** +10893 Archivist_Silent_Dimensional_Lock **** **** **** **** **** **** **** **** +10894 Archivist_Still_Dimensional_Lock **** **** **** **** **** **** **** **** +10895 Archivist_DiscernLocation **** **** **** **** **** **** **** **** +10896 Archivist_Exteneded_DiscernLocation **** **** **** **** **** **** **** **** +10897 Archivist_Silent_DiscernLocation **** **** **** **** **** **** **** **** +10898 Archivist_Still_DiscernLocation **** **** **** **** **** **** **** **** +10899 Archivist_Dominate_Monster **** **** **** **** **** **** **** **** +10900 Archivist_Exteneded_Dominate_Monster **** **** **** **** **** **** **** **** +10901 Archivist_Silent_Dominate_Monster **** **** **** **** **** **** **** **** +10902 Archivist_Still_Dominate_Monster **** **** **** **** **** **** **** **** +10903 Archivist_DRAGON_CLOUD **** **** **** **** **** **** **** **** +10904 Archivist_Silent_DRAGON_CLOUD **** **** **** **** **** **** **** **** +10905 Archivist_Still_DRAGON_CLOUD **** **** **** **** **** **** **** **** +10906 Archivist_Earthquake **** **** **** **** **** **** **** **** +10907 Archivist_Exteneded_Earthquake **** **** **** **** **** **** **** **** +10908 Archivist_Silent_Earthquake **** **** **** **** **** **** **** **** +10909 Archivist_Still_Earthquake **** **** **** **** **** **** **** **** +10910 Archivist_EVIL_WEATHER **** **** **** **** **** **** **** **** +10911 Archivist_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +10912 Archivist_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +10913 Archivist_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +10914 Archivist_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +10915 Archivist_Silent_EVIL_WEATHER **** **** **** **** **** **** **** **** +10916 Archivist_Silent_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +10917 Archivist_Silent_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +10918 Archivist_Silent_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +10919 Archivist_Silent_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +10920 Archivist_Still_EVIL_WEATHER **** **** **** **** **** **** **** **** +10921 Archivist_Still_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +10922 Archivist_Still_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +10923 Archivist_Still_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +10924 Archivist_Still_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +10925 Archivist_Finger_of_Death **** **** **** **** **** **** **** **** +10926 Archivist_Silent_Finger_of_Death **** **** **** **** **** **** **** **** +10927 Archivist_Still_Finger_of_Death **** **** **** **** **** **** **** **** +10928 Archivist_Fire_Storm **** **** **** **** **** **** **** **** +10929 Archivist_Silent_Fire_Storm **** **** **** **** **** **** **** **** +10930 Archivist_Still_Fire_Storm **** **** **** **** **** **** **** **** +10931 Archivist_Greater_Planar_Ally **** **** **** **** **** **** **** **** +10932 Archivist_Exteneded_Greater_Planar_Ally **** **** **** **** **** **** **** **** +10933 Archivist_Silent_Greater_Planar_Ally **** **** **** **** **** **** **** **** +10934 Archivist_Still_Greater_Planar_Ally **** **** **** **** **** **** **** **** +10935 Archivist_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +10936 Archivist_Exteneded_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +10937 Archivist_Silent_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +10938 Archivist_Still_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +10939 Archivist_Holy_Aura **** **** **** **** **** **** **** **** +10940 Archivist_Exteneded_Holy_Aura **** **** **** **** **** **** **** **** +10941 Archivist_Silent_Holy_Aura **** **** **** **** **** **** **** **** +10942 Archivist_Still_Holy_Aura **** **** **** **** **** **** **** **** +10943 Archivist_Horrid_Wilting **** **** **** **** **** **** **** **** +10944 Archivist_Silent_Horrid_Wilting **** **** **** **** **** **** **** **** +10945 Archivist_Still_Horrid_Wilting **** **** **** **** **** **** **** **** +10946 Archivist_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +10947 Archivist_Silent_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +10948 Archivist_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +10949 Archivist_Silent_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +10950 Archivist_Still_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +10951 Archivist_Mass_Heal **** **** **** **** **** **** **** **** +10952 Archivist_Silent_Mass_Heal **** **** **** **** **** **** **** **** +10953 Archivist_Still_Mass_Heal **** **** **** **** **** **** **** **** +10954 Archivist_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +10955 Archivist_Silent_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +10956 Archivist_Still_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +10957 Archivist_Natures_Balance **** **** **** **** **** **** **** **** +10958 Archivist_Silent_Natures_Balance **** **** **** **** **** **** **** **** +10959 Archivist_Still_Natures_Balance **** **** **** **** **** **** **** **** +10960 Archivist_Necrotic_Empowerment **** **** **** **** **** **** **** **** +10961 Archivist_Exteneded_Necrotic_Empowerment **** **** **** **** **** **** **** **** +10962 Archivist_Silent_Necrotic_Empowerment **** **** **** **** **** **** **** **** +10963 Archivist_Still_Necrotic_Empowerment **** **** **** **** **** **** **** **** +10964 Archivist_Pestilence **** **** **** **** **** **** **** **** +10965 Archivist_Silent_Pestilence **** **** **** **** **** **** **** **** +10966 Archivist_Still_Pestilence **** **** **** **** **** **** **** **** +10967 Archivist_Power_Word_Stun **** **** **** **** **** **** **** **** +10968 Archivist_Silent_Power_Word_Stun **** **** **** **** **** **** **** **** +10969 Archivist_Premonition **** **** **** **** **** **** **** **** +10970 Archivist_Exteneded_Premonition **** **** **** **** **** **** **** **** +10971 Archivist_Silent_Premonition **** **** **** **** **** **** **** **** +10972 Archivist_Still_Premonition **** **** **** **** **** **** **** **** +10973 Archivist_Shadow_Shield **** **** **** **** **** **** **** **** +10974 Archivist_Exteneded_Shadow_Shield **** **** **** **** **** **** **** **** +10975 Archivist_Silent_Shadow_Shield **** **** **** **** **** **** **** **** +10976 Archivist_Still_Shadow_Shield **** **** **** **** **** **** **** **** +10977 Archivist_Summon_Creature_VIII **** **** **** **** **** **** **** **** +10978 Archivist_Summon8Air **** **** **** **** **** **** **** **** +10979 Archivist_Summon8Earth **** **** **** **** **** **** **** **** +10980 Archivist_Summon8Fire **** **** **** **** **** **** **** **** +10981 Archivist_Summon8Water **** **** **** **** **** **** **** **** +10982 Archivist_Exteneded_Summon_Creature_VIII **** **** **** **** **** **** **** **** +10983 Archivist_Exteneded_Summon8Air **** **** **** **** **** **** **** **** +10984 Archivist_Exteneded_Summon8Earth **** **** **** **** **** **** **** **** +10985 Archivist_Exteneded_Summon8Fire **** **** **** **** **** **** **** **** +10986 Archivist_Exteneded_Summon8Water **** **** **** **** **** **** **** **** +10987 Archivist_Silent_Summon_Creature_VIII **** **** **** **** **** **** **** **** +10988 Archivist_Silent_Summon8Air **** **** **** **** **** **** **** **** +10989 Archivist_Silent_Summon8Earth **** **** **** **** **** **** **** **** +10990 Archivist_Silent_Summon8Fire **** **** **** **** **** **** **** **** +10991 Archivist_Silent_Summon8Water **** **** **** **** **** **** **** **** +10992 Archivist_Still_Summon_Creature_VIII **** **** **** **** **** **** **** **** +10993 Archivist_Still_Summon8Air **** **** **** **** **** **** **** **** +10994 Archivist_Still_Summon8Earth **** **** **** **** **** **** **** **** +10995 Archivist_Still_Summon8Fire **** **** **** **** **** **** **** **** +10996 Archivist_Still_Summon8Water **** **** **** **** **** **** **** **** +10997 Archivist_Sunbeam **** **** **** **** **** **** **** **** +10998 Archivist_Silent_Sunbeam **** **** **** **** **** **** **** **** +10999 Archivist_Still_Sunbeam **** **** **** **** **** **** **** **** +11000 Archivist_Sunburst **** **** **** **** **** **** **** **** +11001 Archivist_Silent_Sunburst **** **** **** **** **** **** **** **** +11002 Archivist_Still_Sunburst **** **** **** **** **** **** **** **** +11003 Archivist_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +11004 Archivist_Exteneded_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +11005 Archivist_Silent_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +11006 Archivist_Still_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +11007 Archivist_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +11008 Archivist_Exteneded_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +11009 Archivist_Silent_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +11010 Archivist_Still_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +11011 Archivist_APOCALYPSE_FROM_THE_SKY **** **** **** **** **** **** **** **** +11012 Archivist_APOCALYPSE_FROM_THE_SKY_FIRE **** **** **** **** **** **** **** **** +11013 Archivist_APOCALYPSE_FROM_THE_SKY_ACID **** **** **** **** **** **** **** **** +11014 Archivist_APOCALYPSE_FROM_THE_SKY_SONIC **** **** **** **** **** **** **** **** +11015 Archivist_DESPOIL **** **** **** **** **** **** **** **** +11016 Archivist_Elder_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +11017 Archivist_Elder_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +11018 Archivist_Elder_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +11019 Archivist_Elder_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +11020 Archivist_Elder_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +11021 Archivist_Elder_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +11022 Archivist_Elemental_Swarm **** **** **** **** **** **** **** **** +11023 Archivist_Energy_Drain **** **** **** **** **** **** **** **** +11024 Archivist_EXALTED_FURY **** **** **** **** **** **** **** **** +11025 Archivist_Foresight **** **** **** **** **** **** **** **** +11026 Archivist_Gate **** **** **** **** **** **** **** **** +11027 Archivist_Greater_Planar_Binding **** **** **** **** **** **** **** **** +11028 Archivist_Greater_Spell_Mantle **** **** **** **** **** **** **** **** +11029 Archivist_Implosion **** **** **** **** **** **** **** **** +11030 Archivist_Mantle_of_Eg_Might **** **** **** **** **** **** **** **** +11031 Archivist_Mass_Drown **** **** **** **** **** **** **** **** +11032 Archivist_Mass_Harm **** **** **** **** **** **** **** **** +11033 Archivist_Mass_Hold_Monster **** **** **** **** **** **** **** **** +11034 Archivist_Nature_Avatar **** **** **** **** **** **** **** **** +11035 Archivist_Necrotic_Termination **** **** **** **** **** **** **** **** +11036 Archivist_PlagueOfUndead **** **** **** **** **** **** **** **** +11037 Archivist_Power_Word_Kill **** **** **** **** **** **** **** **** +11038 Archivist_Power_Word_Blind **** **** **** **** **** **** **** **** +11039 Archivist_RAIN_OF_BLACK_TULIPS **** **** **** **** **** **** **** **** +11040 Archivist_Shapechange **** **** **** **** **** **** **** **** +11041 Archivist_Shapechange_RED_DRAGON **** **** **** **** **** **** **** **** +11042 Archivist_Shapechange_FIRE_GIANT **** **** **** **** **** **** **** **** +11043 Archivist_Shapechange_BALOR **** **** **** **** **** **** **** **** +11044 Archivist_Shapechange_DEATH_SLAAD **** **** **** **** **** **** **** **** +11045 Archivist_Shapechange_IRON_GOLEM **** **** **** **** **** **** **** **** +11046 Archivist_Sphere_of_Ultimate_Destruction **** **** **** **** **** **** **** **** +11047 Archivist_Storm_of_Vengeance **** **** **** **** **** **** **** **** +11048 Archivist_Summon_Creature_IX **** **** **** **** **** **** **** **** +11049 Archivist_Summon9Air **** **** **** **** **** **** **** **** +11050 Archivist_Summon9Earth **** **** **** **** **** **** **** **** +11051 Archivist_Summon9Fire **** **** **** **** **** **** **** **** +11052 Archivist_Summon9Water **** **** **** **** **** **** **** **** +11053 Archivist_True_Resurrection **** **** **** **** **** **** **** **** +11054 Archivist_Undeaths_Eternal_Foe **** **** **** **** **** **** **** **** +11055 Archivist_Unyielding_Roots **** **** **** **** **** **** **** **** +11056 Archivist_VileDeath **** **** **** **** **** **** **** **** +11057 Archivist_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +11058 Archivist_Weird **** **** **** **** **** **** **** **** +11059 ****_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11060 ****_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +11061 ****_Light **** **** **** **** **** **** **** **** +11062 ****_Read_Magic **** **** **** **** **** **** **** **** +11063 ****_Resistance **** **** **** **** **** **** **** **** +11064 ****_Virtue **** **** **** **** **** **** **** **** +11065 ****_Command_RadialMaster **** **** **** **** **** **** **** **** +11066 ****_Command_Approach **** **** **** **** **** **** **** **** +11067 ****_Command_Drop **** **** **** **** **** **** **** **** +11068 ****_Command_Fall **** **** **** **** **** **** **** **** +11069 ****_Command_Flee **** **** **** **** **** **** **** **** +11070 ****_Command_Halt **** **** **** **** **** **** **** **** +11071 ****_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11072 ****_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11073 ****_Divine_Favor **** **** **** **** **** **** **** **** +11074 ****_Doom **** **** **** **** **** **** **** **** +11075 ****_Endure_Elements **** **** **** **** **** **** **** **** +11076 ****_HideFromUndead **** **** **** **** **** **** **** **** +11077 ****_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11078 ****_Remove_Fear **** **** **** **** **** **** **** **** +11079 ****_Protection_from_Evil **** **** **** **** **** **** **** **** +11080 ****_Protection_from_Good **** **** **** **** **** **** **** **** +11081 ****_Shield_of_Faith **** **** **** **** **** **** **** **** +11082 ****_Endurance **** **** **** **** **** **** **** **** +11083 ****_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11084 ****_Hold_Person **** **** **** **** **** **** **** **** +11085 ****_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11086 ****_Remove_Paralysis **** **** **** **** **** **** **** **** +11087 ****_Resist_Elements **** **** **** **** **** **** **** **** +11088 ****_Lesser_Restoration **** **** **** **** **** **** **** **** +11089 ****_Silence **** **** **** **** **** **** **** **** +11090 ****_UndetectableAlignment **** **** **** **** **** **** **** **** +11091 ****_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11092 ****_Dispel_Magic **** **** **** **** **** **** **** **** +11093 ****_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +11094 ****_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +11095 ****_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +11096 ****_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +11097 ****_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +11098 ****_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +11099 ****_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11100 ****_Lightning_Bolt **** **** **** **** **** **** **** **** +11101 ****_LocateObject **** **** **** **** **** **** **** **** +11102 ****_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11103 ****_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11104 ****_Magic_Vestment **** **** **** **** **** **** **** **** +11105 ****_Protection_from_Elements **** **** **** **** **** **** **** **** +11106 ****_Remove_Disease **** **** **** **** **** **** **** **** +11107 ****_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +11108 ****_GreaterCommand_Approach **** **** **** **** **** **** **** **** +11109 ****_GreaterCommand_Drop **** **** **** **** **** **** **** **** +11110 ****_GreaterCommand_Fall **** **** **** **** **** **** **** **** +11111 ****_GreaterCommand_Flee **** **** **** **** **** **** **** **** +11112 ****_GreaterCommand_Halt **** **** **** **** **** **** **** **** +11113 ****_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11114 ****_Dimensional_Anchor **** **** **** **** **** **** **** **** +11115 ****_Freedom_of_Movement **** **** **** **** **** **** **** **** +11116 ****_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11117 ****_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +11118 ****_Neutralize_Poison **** **** **** **** **** **** **** **** +11119 ****_BreakEnchantment **** **** **** **** **** **** **** **** +11120 ****_Elemental_Strike **** **** **** **** **** **** **** **** +11121 ****_Elemental_Strike_Acid **** **** **** **** **** **** **** **** +11122 ****_Elemental_Strike_Cold **** **** **** **** **** **** **** **** +11123 ****_Elemental_Strike_Electricity **** **** **** **** **** **** **** **** +11124 ****_Elemental_Strike_Fire **** **** **** **** **** **** **** **** +11125 ****_Elemental_Strike_Sonic **** **** **** **** **** **** **** **** +11126 ****_Scrying **** **** **** **** **** **** **** **** +11127 ****_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +11128 ****_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +11129 ****_True_Seeing **** **** **** **** **** **** **** **** +11130 ****_Create_Undead **** **** **** **** **** **** **** **** +11131 ****_Greater_Dispelling **** **** **** **** **** **** **** **** +11132 ****_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +11133 ****_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +11134 ****_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +11135 ****_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +11136 ****_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +11137 ****_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +11138 ****_Raise_Dead **** **** **** **** **** **** **** **** +11139 ****_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +11140 ****_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +11141 ****_WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +11142 ****_WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +11143 ****_WordOfRecall_Party **** **** **** **** **** **** **** **** +11144 ****_GreaterScrying **** **** **** **** **** **** **** **** +11145 ****_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +11146 ****_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +11147 ****_Create_Greater_Undead **** **** **** **** **** **** **** **** +11148 ****_DiscernLocation **** **** **** **** **** **** **** **** +11149 ****_Finger_of_Death **** **** **** **** **** **** **** **** +11150 ****_Regenerate **** **** **** **** **** **** **** **** +11151 ****_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +11152 ****_Energy_Drain **** **** **** **** **** **** **** **** +11153 ****_Power_Word_Blind **** **** **** **** **** **** **** **** +11154 ****_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11155 ****_Dancing_Lights **** **** **** **** **** **** **** **** +11156 ****_Daze **** **** **** **** **** **** **** **** +11157 ****_Flare **** **** **** **** **** **** **** **** +11158 ****_Light **** **** **** **** **** **** **** **** +11159 ****_MAGE_HAND **** **** **** **** **** **** **** **** +11160 ****_Read_Magic **** **** **** **** **** **** **** **** +11161 ****_Resistance **** **** **** **** **** **** **** **** +11162 ****_Sobriety **** **** **** **** **** **** **** **** +11163 ****_Virtue **** **** **** **** **** **** **** **** +11164 ****_Cause_Fear **** **** **** **** **** **** **** **** +11165 ****_Charm_Person **** **** **** **** **** **** **** **** +11166 ****_Command_RadialMaster **** **** **** **** **** **** **** **** +11167 ****_Command_Approach **** **** **** **** **** **** **** **** +11168 ****_Command_Drop **** **** **** **** **** **** **** **** +11169 ****_Command_Fall **** **** **** **** **** **** **** **** +11170 ****_Command_Flee **** **** **** **** **** **** **** **** +11171 ****_Command_Halt **** **** **** **** **** **** **** **** +11172 ****_Crafters_Blessing **** **** **** **** **** **** **** **** +11173 ****_Crafters_Curse **** **** **** **** **** **** **** **** +11174 ****_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11175 ****_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +11176 ****_Disguise_Self_Learn **** **** **** **** **** **** **** **** +11177 ****_Disguise_Self_Options **** **** **** **** **** **** **** **** +11178 ****_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +11179 ****_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +11180 ****_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +11181 ****_Doom **** **** **** **** **** **** **** **** +11182 ****_Endure_Elements **** **** **** **** **** **** **** **** +11183 ****_Grease **** **** **** **** **** **** **** **** +11184 ****_Expeditious_Retreat **** **** **** **** **** **** **** **** +11185 ****_Faerie_Fire **** **** **** **** **** **** **** **** +11186 ****_Tashas_Hideous_Laughter **** **** **** **** **** **** **** **** +11187 ****_Identify **** **** **** **** **** **** **** **** +11188 ****_Spell_Jump **** **** **** **** **** **** **** **** +11189 ****_ObscureObject **** **** **** **** **** **** **** **** +11190 ****_Obscuring_Mist **** **** **** **** **** **** **** **** +11191 ****_Protection_from_Chaos **** **** **** **** **** **** **** **** +11192 ****_Protection_from_Evil **** **** **** **** **** **** **** **** +11193 ****_Protection_from_Good **** **** **** **** **** **** **** **** +11194 ****_Protection_from_Law **** **** **** **** **** **** **** **** +11195 ****_Remove_Fear **** **** **** **** **** **** **** **** +11196 ****_Sleep **** **** **** **** **** **** **** **** +11197 ****_Summon_Creature_I **** **** **** **** **** **** **** **** +11198 ****_UndetectableAlignment **** **** **** **** **** **** **** **** +11199 ****_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +11200 ****_Alter_Self_Learn **** **** **** **** **** **** **** **** +11201 ****_Alter_Self_Options **** **** **** **** **** **** **** **** +11202 ****_Alter_Self_QS1 **** **** **** **** **** **** **** **** +11203 ****_Alter_Self_QS2 **** **** **** **** **** **** **** **** +11204 ****_Alter_Self_QS3 **** **** **** **** **** **** **** **** +11205 ****_Endurance **** **** **** **** **** **** **** **** +11206 ****_Bulls_Strength **** **** **** **** **** **** **** **** +11207 ****_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11208 ****_Blur **** **** **** **** **** **** **** **** +11209 ****_Calm_Emotions **** **** **** **** **** **** **** **** +11210 ****_Cats_Grace **** **** **** **** **** **** **** **** +11211 ****_Continual_Flame **** **** **** **** **** **** **** **** +11212 ****_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11213 ****_Darkness **** **** **** **** **** **** **** **** +11214 ****_Daze_Monster **** **** **** **** **** **** **** **** +11215 ****_Eagle_Splendor **** **** **** **** **** **** **** **** +11216 ****_FogCloud **** **** **** **** **** **** **** **** +11217 ****_Foxs_Cunning **** **** **** **** **** **** **** **** +11218 ****_Heroism **** **** **** **** **** **** **** **** +11219 ****_Hold_Person **** **** **** **** **** **** **** **** +11220 ****_Invisibility **** **** **** **** **** **** **** **** +11221 ****_Lesser_Dispel **** **** **** **** **** **** **** **** +11222 ****_LocateObject **** **** **** **** **** **** **** **** +11223 ****_MirrorImage **** **** **** **** **** **** **** **** +11224 ****_Owls_Wisdom **** **** **** **** **** **** **** **** +11225 ****_ProtectionArrows **** **** **** **** **** **** **** **** +11226 ****_Pyrotechnics **** **** **** **** **** **** **** **** +11227 ****_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +11228 ****_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +11229 ****_Resist_Elements **** **** **** **** **** **** **** **** +11230 ****_Scare **** **** **** **** **** **** **** **** +11231 ****_Silence **** **** **** **** **** **** **** **** +11232 ****_Summon_Creature_II **** **** **** **** **** **** **** **** +11233 ****_TouchIdiocy **** **** **** **** **** **** **** **** +11234 ****_Ultravision **** **** **** **** **** **** **** **** +11235 ****_Bestow_Curse **** **** **** **** **** **** **** **** +11236 ****_Charm_Monster **** **** **** **** **** **** **** **** +11237 ****_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +11238 ****_Confusion **** **** **** **** **** **** **** **** +11239 ****_CrushingDespair **** **** **** **** **** **** **** **** +11240 ****_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11241 ****_Daylight **** **** **** **** **** **** **** **** +11242 ****_DeepSlumber **** **** **** **** **** **** **** **** +11243 ****_Dispel_Magic **** **** **** **** **** **** **** **** +11244 ****_Displacement **** **** **** **** **** **** **** **** +11245 ****_Fear **** **** **** **** **** **** **** **** +11246 ****_GLIBNESS **** **** **** **** **** **** **** **** +11247 ****_Haste **** **** **** **** **** **** **** **** +11248 ****_Invisibility_Sphere **** **** **** **** **** **** **** **** +11249 ****_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11250 ****_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11251 ****_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11252 ****_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11253 ****_Protection_from_Elements **** **** **** **** **** **** **** **** +11254 ****_RayofExhaustion **** **** **** **** **** **** **** **** +11255 ****_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11256 ****_Remove_Curse **** **** **** **** **** **** **** **** +11257 ****_Remove_Disease **** **** **** **** **** **** **** **** +11258 ****_Scrying **** **** **** **** **** **** **** **** +11259 ****_See_Invisibility **** **** **** **** **** **** **** **** +11260 ****_Slow **** **** **** **** **** **** **** **** +11261 ****_Spiderskin **** **** **** **** **** **** **** **** +11262 ****_Summon_Creature_III **** **** **** **** **** **** **** **** +11263 ****_WaterBreathing **** **** **** **** **** **** **** **** +11264 ****_Animate_Dead **** **** **** **** **** **** **** **** +11265 ****_ArcaneEye **** **** **** **** **** **** **** **** +11266 ****_BreakEnchantment **** **** **** **** **** **** **** **** +11267 ****_Contagion **** **** **** **** **** **** **** **** +11268 ****_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11269 ****_DetectScrying **** **** **** **** **** **** **** **** +11270 ****_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +11271 ****_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +11272 ****_DimensionDoor_Party **** **** **** **** **** **** **** **** +11273 ****_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +11274 ****_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +11275 ****_Dominate_Person **** **** **** **** **** **** **** **** +11276 ****_Freedom_of_Movement **** **** **** **** **** **** **** **** +11277 ****_Hold_Monster **** **** **** **** **** **** **** **** +11278 ****_Improved_Invisibility **** **** **** **** **** **** **** **** +11279 ****_Greater_Resistance **** **** **** **** **** **** **** **** +11280 ****_LocateCreature **** **** **** **** **** **** **** **** +11281 ****_Mass_Ultravision **** **** **** **** **** **** **** **** +11282 ****_Neutralize_Poison **** **** **** **** **** **** **** **** +11283 ****_Polymorph_Self **** **** **** **** **** **** **** **** +11284 ****_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +11285 ****_Polymorph_TROLL **** **** **** **** **** **** **** **** +11286 ****_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +11287 ****_Polymorph_PIXIE **** **** **** **** **** **** **** **** +11288 ****_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +11289 ****_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +11290 ****_RepelVermin **** **** **** **** **** **** **** **** +11291 ****_Shadow_Conjuration **** **** **** **** **** **** **** **** +11292 ****_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +11293 ****_SHADOW_CON_Darkness **** **** **** **** **** **** **** **** +11294 ****_SHADOW_CON_Inivsibility **** **** **** **** **** **** **** **** +11295 ****_SHADOW_CON_Mage_Armor **** **** **** **** **** **** **** **** +11296 ****_SHADOW_CON_Magic_Missile **** **** **** **** **** **** **** **** +11297 ****_Stoneskin **** **** **** **** **** **** **** **** +11298 ****_Summon_Creature_IV **** **** **** **** **** **** **** **** +11299 ****_BalefulPolymorph **** **** **** **** **** **** **** **** +11300 ****_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +11301 ****_GreaterCommand_Approach **** **** **** **** **** **** **** **** +11302 ****_GreaterCommand_Drop **** **** **** **** **** **** **** **** +11303 ****_GreaterCommand_Fall **** **** **** **** **** **** **** **** +11304 ****_GreaterCommand_Flee **** **** **** **** **** **** **** **** +11305 ****_GreaterCommand_Halt **** **** **** **** **** **** **** **** +11306 ****_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11307 ****_Greater_Dispelling **** **** **** **** **** **** **** **** +11308 ****_Energy_Buffer **** **** **** **** **** **** **** **** +11309 ****_Eternal_Charm_Person **** **** **** **** **** **** **** **** +11310 ****_Feeblemind **** **** **** **** **** **** **** **** +11311 ****_Greater_Heroism **** **** **** **** **** **** **** **** +11312 ****_Lesser_Planar_Binding **** **** **** **** **** **** **** **** +11313 ****_Mind_Fog **** **** **** **** **** **** **** **** +11314 ****_Mislead **** **** **** **** **** **** **** **** +11315 ****_Panacea **** **** **** **** **** **** **** **** +11316 ****_GreaterScrying **** **** **** **** **** **** **** **** +11317 ****_Summon_Creature_V **** **** **** **** **** **** **** **** +11318 ****_WavesofFatigue **** **** **** **** **** **** **** **** +11319 ****_Animate_Object **** **** **** **** **** **** **** **** +11320 ****_Mass_Endurance **** **** **** **** **** **** **** **** +11321 ****_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +11322 ****_Mass_Cats_Grace **** **** **** **** **** **** **** **** +11323 ****_Mass_Charm **** **** **** **** **** **** **** **** +11324 ****_Control_Weather **** **** **** **** **** **** **** **** +11325 ****_CW_Rain **** **** **** **** **** **** **** **** +11326 ****_CW_Snow **** **** **** **** **** **** **** **** +11327 ****_CW_Clear **** **** **** **** **** **** **** **** +11328 ****_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11329 ****_Mass_Contagion **** **** **** **** **** **** **** **** +11330 ****_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +11331 ****_Energy_Immunity **** **** **** **** **** **** **** **** +11332 ****_EI_Acid **** **** **** **** **** **** **** **** +11333 ****_EI_Cold **** **** **** **** **** **** **** **** +11334 ****_EI_Elec **** **** **** **** **** **** **** **** +11335 ****_EI_Fire **** **** **** **** **** **** **** **** +11336 ****_EI_Sonic **** **** **** **** **** **** **** **** +11337 ****_Eyebite **** **** **** **** **** **** **** **** +11338 ****_Flesh_to_stone **** **** **** **** **** **** **** **** +11339 ****_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +11340 ****_Greater_Stoneskin **** **** **** **** **** **** **** **** +11341 ****_Legend_Lore **** **** **** **** **** **** **** **** +11342 ****_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +11343 ****_Planar_Binding **** **** **** **** **** **** **** **** +11344 ****_Summon_Creature_VI **** **** **** **** **** **** **** **** +11345 ****_True_Seeing **** **** **** **** **** **** **** **** +11346 ****_Repulsion **** **** **** **** **** **** **** **** +11347 ****_Superior_Resistance **** **** **** **** **** **** **** **** +11348 ****_Tensers_Transformation **** **** **** **** **** **** **** **** +11349 ****_Creeping_Doom **** **** **** **** **** **** **** **** +11350 ****_Eternal_Charm_Monster **** **** **** **** **** **** **** **** +11351 ****_Finger_of_Death **** **** **** **** **** **** **** **** +11352 ****_Insanity **** **** **** **** **** **** **** **** +11353 ****_Sequester **** **** **** **** **** **** **** **** +11354 ****_Summon_Creature_VII **** **** **** **** **** **** **** **** +11355 ****_Summon7Air **** **** **** **** **** **** **** **** +11356 ****_Summon7Earth **** **** **** **** **** **** **** **** +11357 ****_Summon7Fire **** **** **** **** **** **** **** **** +11358 ****_Summon7Water **** **** **** **** **** **** **** **** +11359 ****_TransportViaPlants_RadialMaster **** **** **** **** **** **** **** **** +11360 ****_TransportViaPlants_SelfOnly **** **** **** **** **** **** **** **** +11361 ****_TransportViaPlants_Party **** **** **** **** **** **** **** **** +11362 ****_DiscernLocation **** **** **** **** **** **** **** **** +11363 ****_Horrid_Wilting **** **** **** **** **** **** **** **** +11364 ****_Protection_from_Spells **** **** **** **** **** **** **** **** +11365 ****_Greater_Planar_Binding **** **** **** **** **** **** **** **** +11366 ****_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +11367 ****_Shadow_Shield **** **** **** **** **** **** **** **** +11368 ****_Summon_Creature_VIII **** **** **** **** **** **** **** **** +11369 ****_Summon8Air **** **** **** **** **** **** **** **** +11370 ****_Summon8Earth **** **** **** **** **** **** **** **** +11371 ****_Summon8Fire **** **** **** **** **** **** **** **** +11372 ****_Summon8Water **** **** **** **** **** **** **** **** +11373 ****_Earthquake **** **** **** **** **** **** **** **** +11374 ****_Foresight **** **** **** **** **** **** **** **** +11375 ****_Gate **** **** **** **** **** **** **** **** +11376 ****_Mystic_Barrier **** **** **** **** **** **** **** **** +11377 ****_Shapechange **** **** **** **** **** **** **** **** +11378 ****_Shapechange_RED_DRAGON **** **** **** **** **** **** **** **** +11379 ****_Shapechange_FIRE_GIANT **** **** **** **** **** **** **** **** +11380 ****_Shapechange_BALOR **** **** **** **** **** **** **** **** +11381 ****_Shapechange_DEATH_SLAAD **** **** **** **** **** **** **** **** +11382 ****_Shapechange_IRON_GOLEM **** **** **** **** **** **** **** **** +11383 ****_Summon_Creature_IX **** **** **** **** **** **** **** **** +11384 ****_Summon9Air **** **** **** **** **** **** **** **** +11385 ****_Summon9Earth **** **** **** **** **** **** **** **** +11386 ****_Summon9Fire **** **** **** **** **** **** **** **** +11387 ****_Summon9Water **** **** **** **** **** **** **** **** +11388 ****_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +11389 ****_Weird **** **** **** **** **** **** **** **** +11390 OAShaman_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11391 OAShaman_Quickened_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11392 OAShaman_Silent_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11393 OAShaman_Still_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +11394 OAShaman_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +11395 OAShaman_Quickened_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +11396 OAShaman_Silent_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +11397 OAShaman_Still_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +11398 OAShaman_Light **** **** **** **** **** **** **** **** +11399 OAShaman_Exteneded_Light **** **** **** **** **** **** **** **** +11400 OAShaman_Quickened_Light **** **** **** **** **** **** **** **** +11401 OAShaman_Silent_Light **** **** **** **** **** **** **** **** +11402 OAShaman_Read_Magic **** **** **** **** **** **** **** **** +11403 OAShaman_Quickened_Read_Magic **** **** **** **** **** **** **** **** +11404 OAShaman_Silent_Read_Magic **** **** **** **** **** **** **** **** +11405 OAShaman_Still_Read_Magic **** **** **** **** **** **** **** **** +11406 OAShaman_Resistance **** **** **** **** **** **** **** **** +11407 OAShaman_Exteneded_Resistance **** **** **** **** **** **** **** **** +11408 OAShaman_Quickened_Resistance **** **** **** **** **** **** **** **** +11409 OAShaman_Silent_Resistance **** **** **** **** **** **** **** **** +11410 OAShaman_Still_Resistance **** **** **** **** **** **** **** **** +11411 OAShaman_Virtue **** **** **** **** **** **** **** **** +11412 OAShaman_Exteneded_Virtue **** **** **** **** **** **** **** **** +11413 OAShaman_Quickened_Virtue **** **** **** **** **** **** **** **** +11414 OAShaman_Silent_Virtue **** **** **** **** **** **** **** **** +11415 OAShaman_Still_Virtue **** **** **** **** **** **** **** **** +11416 OAShaman_Bane **** **** **** **** **** **** **** **** +11417 OAShaman_Exteneded_Bane **** **** **** **** **** **** **** **** +11418 OAShaman_Quickened_Bane **** **** **** **** **** **** **** **** +11419 OAShaman_Silent_Bane **** **** **** **** **** **** **** **** +11420 OAShaman_Still_Bane **** **** **** **** **** **** **** **** +11421 OAShaman_Bless **** **** **** **** **** **** **** **** +11422 OAShaman_Exteneded_Bless **** **** **** **** **** **** **** **** +11423 OAShaman_Quickened_Bless **** **** **** **** **** **** **** **** +11424 OAShaman_Silent_Bless **** **** **** **** **** **** **** **** +11425 OAShaman_Still_Bless **** **** **** **** **** **** **** **** +11426 OAShaman_Bless_Water **** **** **** **** **** **** **** **** +11427 OAShaman_Quickened_Bless_Water **** **** **** **** **** **** **** **** +11428 OAShaman_Silent_Bless_Water **** **** **** **** **** **** **** **** +11429 OAShaman_Still_Bless_Water **** **** **** **** **** **** **** **** +11430 OAShaman_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11431 OAShaman_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11432 OAShaman_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11433 OAShaman_Quickened_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11434 OAShaman_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11435 OAShaman_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +11436 OAShaman_Curse_Water **** **** **** **** **** **** **** **** +11437 OAShaman_Quickened_Curse_Water **** **** **** **** **** **** **** **** +11438 OAShaman_Silent_Curse_Water **** **** **** **** **** **** **** **** +11439 OAShaman_Still_Curse_Water **** **** **** **** **** **** **** **** +11440 OAShaman_Detect_Chaos **** **** **** **** **** **** **** **** +11441 OAShaman_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +11442 OAShaman_Quickened_Detect_Chaos **** **** **** **** **** **** **** **** +11443 OAShaman_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +11444 OAShaman_Still_Detect_Chaos **** **** **** **** **** **** **** **** +11445 OAShaman_Detect_Evil **** **** **** **** **** **** **** **** +11446 OAShaman_Exteneded_Detect_Evil **** **** **** **** **** **** **** **** +11447 OAShaman_Quickened_Detect_Evil **** **** **** **** **** **** **** **** +11448 OAShaman_Silent_Detect_Evil **** **** **** **** **** **** **** **** +11449 OAShaman_Still_Detect_Evil **** **** **** **** **** **** **** **** +11450 OAShaman_Detect_Good **** **** **** **** **** **** **** **** +11451 OAShaman_Exteneded_Detect_Good **** **** **** **** **** **** **** **** +11452 OAShaman_Quickened_Detect_Good **** **** **** **** **** **** **** **** +11453 OAShaman_Silent_Detect_Good **** **** **** **** **** **** **** **** +11454 OAShaman_Still_Detect_Good **** **** **** **** **** **** **** **** +11455 OAShaman_Detect_Law **** **** **** **** **** **** **** **** +11456 OAShaman_Exteneded_Detect_Law **** **** **** **** **** **** **** **** +11457 OAShaman_Quickened_Detect_Law **** **** **** **** **** **** **** **** +11458 OAShaman_Silent_Detect_Law **** **** **** **** **** **** **** **** +11459 OAShaman_Still_Detect_Law **** **** **** **** **** **** **** **** +11460 OAShaman_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11461 OAShaman_Exteneded_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11462 OAShaman_Quickened_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11463 OAShaman_Silent_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11464 OAShaman_Still_DETECT_UNDEAD **** **** **** **** **** **** **** **** +11465 OAShaman_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +11466 OAShaman_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +11467 OAShaman_Quickened_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +11468 OAShaman_Doom **** **** **** **** **** **** **** **** +11469 OAShaman_Exteneded_Doom **** **** **** **** **** **** **** **** +11470 OAShaman_Quickened_Doom **** **** **** **** **** **** **** **** +11471 OAShaman_Silent_Doom **** **** **** **** **** **** **** **** +11472 OAShaman_Still_Doom **** **** **** **** **** **** **** **** +11473 OAShaman_Endure_Elements **** **** **** **** **** **** **** **** +11474 OAShaman_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +11475 OAShaman_Quickened_Endure_Elements **** **** **** **** **** **** **** **** +11476 OAShaman_Silent_Endure_Elements **** **** **** **** **** **** **** **** +11477 OAShaman_Still_Endure_Elements **** **** **** **** **** **** **** **** +11478 OAShaman_Entropic_Shield **** **** **** **** **** **** **** **** +11479 OAShaman_Exteneded_Entropic_Shield **** **** **** **** **** **** **** **** +11480 OAShaman_Quickened_Entropic_Shield **** **** **** **** **** **** **** **** +11481 OAShaman_Silent_Entropic_Shield **** **** **** **** **** **** **** **** +11482 OAShaman_Still_Entropic_Shield **** **** **** **** **** **** **** **** +11483 OAShaman_HideFromUndead **** **** **** **** **** **** **** **** +11484 OAShaman_Exteneded_HideFromUndead **** **** **** **** **** **** **** **** +11485 OAShaman_Quickened_HideFromUndead **** **** **** **** **** **** **** **** +11486 OAShaman_Still_HideFromUndead **** **** **** **** **** **** **** **** +11487 OAShaman_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11488 OAShaman_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11489 OAShaman_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11490 OAShaman_Quickened_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11491 OAShaman_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11492 OAShaman_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +11493 OAShaman_Obscuring_Mist **** **** **** **** **** **** **** **** +11494 OAShaman_Exteneded_Obscuring_Mist **** **** **** **** **** **** **** **** +11495 OAShaman_Quickened_Obscuring_Mist **** **** **** **** **** **** **** **** +11496 OAShaman_Silent_Obscuring_Mist **** **** **** **** **** **** **** **** +11497 OAShaman_Still_Obscuring_Mist **** **** **** **** **** **** **** **** +11498 OAShaman_Protection_from_Chaos **** **** **** **** **** **** **** **** +11499 OAShaman_Exteneded_Protection_from_Chaos **** **** **** **** **** **** **** **** +11500 OAShaman_Quickened_Protection_from_Chaos **** **** **** **** **** **** **** **** +11501 OAShaman_Silent_Protection_from_Chaos **** **** **** **** **** **** **** **** +11502 OAShaman_Still_Protection_from_Chaos **** **** **** **** **** **** **** **** +11503 OAShaman_Protection_from_Evil **** **** **** **** **** **** **** **** +11504 OAShaman_Exteneded_Protection_from_Evil **** **** **** **** **** **** **** **** +11505 OAShaman_Quickened_Protection_from_Evil **** **** **** **** **** **** **** **** +11506 OAShaman_Silent_Protection_from_Evil **** **** **** **** **** **** **** **** +11507 OAShaman_Still_Protection_from_Evil **** **** **** **** **** **** **** **** +11508 OAShaman_Protection_from_Good **** **** **** **** **** **** **** **** +11509 OAShaman_Exteneded_Protection_from_Good **** **** **** **** **** **** **** **** +11510 OAShaman_Quickened_Protection_from_Good **** **** **** **** **** **** **** **** +11511 OAShaman_Silent_Protection_from_Good **** **** **** **** **** **** **** **** +11512 OAShaman_Still_Protection_from_Good **** **** **** **** **** **** **** **** +11513 OAShaman_Protection_from_Law **** **** **** **** **** **** **** **** +11514 OAShaman_Exteneded_Protection_from_Law **** **** **** **** **** **** **** **** +11515 OAShaman_Quickened_Protection_from_Law **** **** **** **** **** **** **** **** +11516 OAShaman_Silent_Protection_from_Law **** **** **** **** **** **** **** **** +11517 OAShaman_Still_Protection_from_Law **** **** **** **** **** **** **** **** +11518 OAShaman_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +11519 OAShaman_Quickened_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +11520 OAShaman_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +11521 OAShaman_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +11522 OAShaman_Shield_of_Faith **** **** **** **** **** **** **** **** +11523 OAShaman_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +11524 OAShaman_Quickened_Shield_of_Faith **** **** **** **** **** **** **** **** +11525 OAShaman_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +11526 OAShaman_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +11527 OAShaman_Summon_Creature_I **** **** **** **** **** **** **** **** +11528 OAShaman_Exteneded_Summon_Creature_I **** **** **** **** **** **** **** **** +11529 OAShaman_Quickened_Summon_Creature_I **** **** **** **** **** **** **** **** +11530 OAShaman_Silent_Summon_Creature_I **** **** **** **** **** **** **** **** +11531 OAShaman_Still_Summon_Creature_I **** **** **** **** **** **** **** **** +11532 OAShaman_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +11533 OAShaman_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +11534 OAShaman_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +11535 OAShaman_Aid **** **** **** **** **** **** **** **** +11536 OAShaman_Empowered_Aid **** **** **** **** **** **** **** **** +11537 OAShaman_Exteneded_Aid **** **** **** **** **** **** **** **** +11538 OAShaman_Maximized_Aid **** **** **** **** **** **** **** **** +11539 OAShaman_Quickened_Aid **** **** **** **** **** **** **** **** +11540 OAShaman_Silent_Aid **** **** **** **** **** **** **** **** +11541 OAShaman_Still_Aid **** **** **** **** **** **** **** **** +11542 OAShaman_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11543 OAShaman_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11544 OAShaman_Maximized_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11545 OAShaman_Quickened_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11546 OAShaman_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11547 OAShaman_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +11548 OAShaman_Bulls_Strength **** **** **** **** **** **** **** **** +11549 OAShaman_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +11550 OAShaman_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +11551 OAShaman_Maximized_Bulls_Strength **** **** **** **** **** **** **** **** +11552 OAShaman_Quickened_Bulls_Strength **** **** **** **** **** **** **** **** +11553 OAShaman_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +11554 OAShaman_Still_Bulls_Strength **** **** **** **** **** **** **** **** +11555 OAShaman_Calm_Emotions **** **** **** **** **** **** **** **** +11556 OAShaman_Exteneded_Calm_Emotions **** **** **** **** **** **** **** **** +11557 OAShaman_Quickened_Calm_Emotions **** **** **** **** **** **** **** **** +11558 OAShaman_Silent_Calm_Emotions **** **** **** **** **** **** **** **** +11559 OAShaman_Still_Calm_Emotions **** **** **** **** **** **** **** **** +11560 OAShaman_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11561 OAShaman_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11562 OAShaman_Maximized_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11563 OAShaman_Quickened_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11564 OAShaman_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11565 OAShaman_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +11566 OAShaman_Ghoul_Touch **** **** **** **** **** **** **** **** +11567 OAShaman_Exteneded_Ghoul_Touch **** **** **** **** **** **** **** **** +11568 OAShaman_Quickened_Ghoul_Touch **** **** **** **** **** **** **** **** +11569 OAShaman_Silent_Ghoul_Touch **** **** **** **** **** **** **** **** +11570 OAShaman_Still_Ghoul_Touch **** **** **** **** **** **** **** **** +11571 OAShaman_Hold_Person **** **** **** **** **** **** **** **** +11572 OAShaman_Exteneded_Hold_Person **** **** **** **** **** **** **** **** +11573 OAShaman_Quickened_Hold_Person **** **** **** **** **** **** **** **** +11574 OAShaman_Silent_Hold_Person **** **** **** **** **** **** **** **** +11575 OAShaman_Still_Hold_Person **** **** **** **** **** **** **** **** +11576 OAShaman_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11577 OAShaman_Empowered_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11578 OAShaman_Maximized_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11579 OAShaman_Quickened_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11580 OAShaman_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11581 OAShaman_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +11582 OAShaman_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +11583 OAShaman_Quickened_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +11584 OAShaman_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +11585 OAShaman_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +11586 OAShaman_Lesser_Restoration **** **** **** **** **** **** **** **** +11587 OAShaman_Quickened_Lesser_Restoration **** **** **** **** **** **** **** **** +11588 OAShaman_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +11589 OAShaman_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +11590 OAShaman_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11591 OAShaman_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11592 OAShaman_Quickened_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11593 OAShaman_Remove_Paralysis **** **** **** **** **** **** **** **** +11594 OAShaman_Quickened_Remove_Paralysis **** **** **** **** **** **** **** **** +11595 OAShaman_Silent_Remove_Paralysis **** **** **** **** **** **** **** **** +11596 OAShaman_Still_Remove_Paralysis **** **** **** **** **** **** **** **** +11597 OAShaman_Summon_Creature_II **** **** **** **** **** **** **** **** +11598 OAShaman_Exteneded_Summon_Creature_II **** **** **** **** **** **** **** **** +11599 OAShaman_Quickened_Summon_Creature_II **** **** **** **** **** **** **** **** +11600 OAShaman_Silent_Summon_Creature_II **** **** **** **** **** **** **** **** +11601 OAShaman_Still_Summon_Creature_II **** **** **** **** **** **** **** **** +11602 OAShaman_Bestow_Curse **** **** **** **** **** **** **** **** +11603 OAShaman_Quickened_Bestow_Curse **** **** **** **** **** **** **** **** +11604 OAShaman_Silent_Bestow_Curse **** **** **** **** **** **** **** **** +11605 OAShaman_Still_Bestow_Curse **** **** **** **** **** **** **** **** +11606 OAShaman_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11607 OAShaman_Exteneded_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11608 OAShaman_Quickened_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11609 OAShaman_Silent_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11610 OAShaman_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +11611 OAShaman_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +11612 OAShaman_Quickened_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +11613 OAShaman_Contagion **** **** **** **** **** **** **** **** +11614 OAShaman_Quickened_Contagion **** **** **** **** **** **** **** **** +11615 OAShaman_Silent_Contagion **** **** **** **** **** **** **** **** +11616 OAShaman_Still_Contagion **** **** **** **** **** **** **** **** +11617 OAShaman_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11618 OAShaman_Empowered_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11619 OAShaman_Maximized_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11620 OAShaman_Quickened_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11621 OAShaman_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11622 OAShaman_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +11623 OAShaman_Dispel_Magic **** **** **** **** **** **** **** **** +11624 OAShaman_Quickened_Dispel_Magic **** **** **** **** **** **** **** **** +11625 OAShaman_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +11626 OAShaman_Still_Dispel_Magic **** **** **** **** **** **** **** **** +11627 OAShaman_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11628 OAShaman_Empowered_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11629 OAShaman_Maximized_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11630 OAShaman_Quickened_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11631 OAShaman_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11632 OAShaman_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +11633 OAShaman_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11634 OAShaman_Empowered_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11635 OAShaman_Maximized_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11636 OAShaman_Quickened_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11637 OAShaman_Silent_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11638 OAShaman_Still_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +11639 OAShaman_LocateObject **** **** **** **** **** **** **** **** +11640 OAShaman_Exteneded_LocateObject **** **** **** **** **** **** **** **** +11641 OAShaman_Quickened_LocateObject **** **** **** **** **** **** **** **** +11642 OAShaman_Silent_LocateObject **** **** **** **** **** **** **** **** +11643 OAShaman_Still_LocateObject **** **** **** **** **** **** **** **** +11644 OAShaman_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11645 OAShaman_Exteneded_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11646 OAShaman_Quickened_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11647 OAShaman_Silent_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11648 OAShaman_Still_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +11649 OAShaman_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11650 OAShaman_Exteneded_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11651 OAShaman_Quickened_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11652 OAShaman_Silent_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11653 OAShaman_Still_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +11654 OAShaman_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11655 OAShaman_Exteneded_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11656 OAShaman_Quickened_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11657 OAShaman_Silent_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11658 OAShaman_Still_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +11659 OAShaman_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11660 OAShaman_Exteneded_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11661 OAShaman_Quickened_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11662 OAShaman_Silent_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11663 OAShaman_Still_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +11664 OAShaman_Magic_Vestment **** **** **** **** **** **** **** **** +11665 OAShaman_Exteneded_Magic_Vestment **** **** **** **** **** **** **** **** +11666 OAShaman_Quickened_Magic_Vestment **** **** **** **** **** **** **** **** +11667 OAShaman_Silent_Magic_Vestment **** **** **** **** **** **** **** **** +11668 OAShaman_Still_Magic_Vestment **** **** **** **** **** **** **** **** +11669 OAShaman_Prayer **** **** **** **** **** **** **** **** +11670 OAShaman_Exteneded_Prayer **** **** **** **** **** **** **** **** +11671 OAShaman_Quickened_Prayer **** **** **** **** **** **** **** **** +11672 OAShaman_Silent_Prayer **** **** **** **** **** **** **** **** +11673 OAShaman_Still_Prayer **** **** **** **** **** **** **** **** +11674 OAShaman_Protection_from_Elements **** **** **** **** **** **** **** **** +11675 OAShaman_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +11676 OAShaman_Quickened_Protection_from_Elements **** **** **** **** **** **** **** **** +11677 OAShaman_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +11678 OAShaman_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +11679 OAShaman_RED_FESTER **** **** **** **** **** **** **** **** +11680 OAShaman_Quickened_RED_FESTER **** **** **** **** **** **** **** **** +11681 OAShaman_Silent_RED_FESTER **** **** **** **** **** **** **** **** +11682 OAShaman_Still_RED_FESTER **** **** **** **** **** **** **** **** +11683 OAShaman_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11684 OAShaman_Quickened_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11685 OAShaman_Silent_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11686 OAShaman_Still_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +11687 OAShaman_Remove_Curse **** **** **** **** **** **** **** **** +11688 OAShaman_Quickened_Remove_Curse **** **** **** **** **** **** **** **** +11689 OAShaman_Silent_Remove_Curse **** **** **** **** **** **** **** **** +11690 OAShaman_Still_Remove_Curse **** **** **** **** **** **** **** **** +11691 OAShaman_Remove_Disease **** **** **** **** **** **** **** **** +11692 OAShaman_Quickened_Remove_Disease **** **** **** **** **** **** **** **** +11693 OAShaman_Silent_Remove_Disease **** **** **** **** **** **** **** **** +11694 OAShaman_Still_Remove_Disease **** **** **** **** **** **** **** **** +11695 OAShaman_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11696 OAShaman_Empowered_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11697 OAShaman_Maximized_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11698 OAShaman_Quickened_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11699 OAShaman_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11700 OAShaman_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +11701 OAShaman_Summon_Creature_III **** **** **** **** **** **** **** **** +11702 OAShaman_Exteneded_Summon_Creature_III **** **** **** **** **** **** **** **** +11703 OAShaman_Quickened_Summon_Creature_III **** **** **** **** **** **** **** **** +11704 OAShaman_Silent_Summon_Creature_III **** **** **** **** **** **** **** **** +11705 OAShaman_Still_Summon_Creature_III **** **** **** **** **** **** **** **** +11706 OAShaman_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +11707 OAShaman_Quickened_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +11708 OAShaman_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +11709 OAShaman_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +11710 OAShaman_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +11711 OAShaman_Exteneded_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +11712 OAShaman_Quickened_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +11713 OAShaman_Silent_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +11714 OAShaman_Still_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +11715 OAShaman_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11716 OAShaman_Empowered_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11717 OAShaman_Maximized_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11718 OAShaman_Quickened_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11719 OAShaman_Silent_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11720 OAShaman_Still_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +11721 OAShaman_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11722 OAShaman_Empowered_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11723 OAShaman_Maximized_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11724 OAShaman_Quickened_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11725 OAShaman_Silent_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11726 OAShaman_Still_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +11727 OAShaman_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11728 OAShaman_Empowered_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11729 OAShaman_Exteneded_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11730 OAShaman_Maximized_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11731 OAShaman_Quickened_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11732 OAShaman_Silent_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11733 OAShaman_Still_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +11734 OAShaman_Dismissal **** **** **** **** **** **** **** **** +11735 OAShaman_Quickened_Dismissal **** **** **** **** **** **** **** **** +11736 OAShaman_Silent_Dismissal **** **** **** **** **** **** **** **** +11737 OAShaman_Still_Dismissal **** **** **** **** **** **** **** **** +11738 OAShaman_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11739 OAShaman_Exteneded_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11740 OAShaman_Quickened_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +11741 OAShaman_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11742 OAShaman_Empowered_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11743 OAShaman_Maximized_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11744 OAShaman_Quickened_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11745 OAShaman_Silent_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11746 OAShaman_Still_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +11747 OAShaman_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +11748 OAShaman_Exteneded_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +11749 OAShaman_Quickened_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +11750 OAShaman_Silent_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +11751 OAShaman_Still_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +11752 OAShaman_Neutralize_Poison **** **** **** **** **** **** **** **** +11753 OAShaman_Quickened_Neutralize_Poison **** **** **** **** **** **** **** **** +11754 OAShaman_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +11755 OAShaman_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +11756 OAShaman_Polymorph_Self **** **** **** **** **** **** **** **** +11757 OAShaman_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +11758 OAShaman_Polymorph_TROLL **** **** **** **** **** **** **** **** +11759 OAShaman_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +11760 OAShaman_Polymorph_PIXIE **** **** **** **** **** **** **** **** +11761 OAShaman_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +11762 OAShaman_Exteneded_Polymorph_Self **** **** **** **** **** **** **** **** +11763 OAShaman_Exteneded_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +11764 OAShaman_Exteneded_Polymorph_TROLL **** **** **** **** **** **** **** **** +11765 OAShaman_Exteneded_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +11766 OAShaman_Exteneded_Polymorph_PIXIE **** **** **** **** **** **** **** **** +11767 OAShaman_Exteneded_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +11768 OAShaman_Quickened_Polymorph_Self **** **** **** **** **** **** **** **** +11769 OAShaman_Quickened_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +11770 OAShaman_Quickened_Polymorph_TROLL **** **** **** **** **** **** **** **** +11771 OAShaman_Quickened_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +11772 OAShaman_Quickened_Polymorph_PIXIE **** **** **** **** **** **** **** **** +11773 OAShaman_Quickened_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +11774 OAShaman_Silent_Polymorph_Self **** **** **** **** **** **** **** **** +11775 OAShaman_Silent_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +11776 OAShaman_Silent_Polymorph_TROLL **** **** **** **** **** **** **** **** +11777 OAShaman_Silent_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +11778 OAShaman_Silent_Polymorph_PIXIE **** **** **** **** **** **** **** **** +11779 OAShaman_Silent_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +11780 OAShaman_Restoration **** **** **** **** **** **** **** **** +11781 OAShaman_Quickened_Restoration **** **** **** **** **** **** **** **** +11782 OAShaman_Silent_Restoration **** **** **** **** **** **** **** **** +11783 OAShaman_Still_Restoration **** **** **** **** **** **** **** **** +11784 OAShaman_Summon_Creature_IV **** **** **** **** **** **** **** **** +11785 OAShaman_Exteneded_Summon_Creature_IV **** **** **** **** **** **** **** **** +11786 OAShaman_Quickened_Summon_Creature_IV **** **** **** **** **** **** **** **** +11787 OAShaman_Silent_Summon_Creature_IV **** **** **** **** **** **** **** **** +11788 OAShaman_Still_Summon_Creature_IV **** **** **** **** **** **** **** **** +11789 OAShaman_SUNMANTLE **** **** **** **** **** **** **** **** +11790 OAShaman_Exteneded_SUNMANTLE **** **** **** **** **** **** **** **** +11791 OAShaman_Quickened_SUNMANTLE **** **** **** **** **** **** **** **** +11792 OAShaman_Still_SUNMANTLE **** **** **** **** **** **** **** **** +11793 OAShaman_BreakEnchantment **** **** **** **** **** **** **** **** +11794 OAShaman_Quickened_BreakEnchantment **** **** **** **** **** **** **** **** +11795 OAShaman_Silent_BreakEnchantment **** **** **** **** **** **** **** **** +11796 OAShaman_Still_BreakEnchantment **** **** **** **** **** **** **** **** +11797 OAShaman_Circle_of_Doom **** **** **** **** **** **** **** **** +11798 OAShaman_Empowered_Circle_of_Doom **** **** **** **** **** **** **** **** +11799 OAShaman_Maximized_Circle_of_Doom **** **** **** **** **** **** **** **** +11800 OAShaman_Quickened_Circle_of_Doom **** **** **** **** **** **** **** **** +11801 OAShaman_Silent_Circle_of_Doom **** **** **** **** **** **** **** **** +11802 OAShaman_Still_Circle_of_Doom **** **** **** **** **** **** **** **** +11803 OAShaman_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +11804 OAShaman_Exteneded_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +11805 OAShaman_Quickened_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +11806 OAShaman_Silent_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +11807 OAShaman_Still_CLAWS_OF_THE_BEBILITH **** **** **** **** **** **** **** **** +11808 OAShaman_Etherealness **** **** **** **** **** **** **** **** +11809 OAShaman_Exteneded_Etherealness **** **** **** **** **** **** **** **** +11810 OAShaman_Quickened_Etherealness **** **** **** **** **** **** **** **** +11811 OAShaman_Silent_Etherealness **** **** **** **** **** **** **** **** +11812 OAShaman_Still_Etherealness **** **** **** **** **** **** **** **** +11813 OAShaman_Healing_Circle **** **** **** **** **** **** **** **** +11814 OAShaman_Empowered_Healing_Circle **** **** **** **** **** **** **** **** +11815 OAShaman_Maximized_Healing_Circle **** **** **** **** **** **** **** **** +11816 OAShaman_Quickened_Healing_Circle **** **** **** **** **** **** **** **** +11817 OAShaman_Silent_Healing_Circle **** **** **** **** **** **** **** **** +11818 OAShaman_Still_Healing_Circle **** **** **** **** **** **** **** **** +11819 OAShaman_POWER_LEECH **** **** **** **** **** **** **** **** +11820 OAShaman_Exteneded_POWER_LEECH **** **** **** **** **** **** **** **** +11821 OAShaman_Quickened_POWER_LEECH **** **** **** **** **** **** **** **** +11822 OAShaman_Silent_POWER_LEECH **** **** **** **** **** **** **** **** +11823 OAShaman_Still_POWER_LEECH **** **** **** **** **** **** **** **** +11824 OAShaman_Raise_Dead **** **** **** **** **** **** **** **** +11825 OAShaman_Quickened_Raise_Dead **** **** **** **** **** **** **** **** +11826 OAShaman_Silent_Raise_Dead **** **** **** **** **** **** **** **** +11827 OAShaman_Still_Raise_Dead **** **** **** **** **** **** **** **** +11828 OAShaman_Scrying **** **** **** **** **** **** **** **** +11829 OAShaman_Exteneded_Scrying **** **** **** **** **** **** **** **** +11830 OAShaman_Quickened_Scrying **** **** **** **** **** **** **** **** +11831 OAShaman_Silent_Scrying **** **** **** **** **** **** **** **** +11832 OAShaman_Still_Scrying **** **** **** **** **** **** **** **** +11833 OAShaman_SICKEN_EVIL **** **** **** **** **** **** **** **** +11834 OAShaman_Exteneded_SICKEN_EVIL **** **** **** **** **** **** **** **** +11835 OAShaman_Quickened_SICKEN_EVIL **** **** **** **** **** **** **** **** +11836 OAShaman_Silent_SICKEN_EVIL **** **** **** **** **** **** **** **** +11837 OAShaman_Still_SICKEN_EVIL **** **** **** **** **** **** **** **** +11838 OAShaman_Slay_Living **** **** **** **** **** **** **** **** +11839 OAShaman_Empowered_Slay_Living **** **** **** **** **** **** **** **** +11840 OAShaman_Maximized_Slay_Living **** **** **** **** **** **** **** **** +11841 OAShaman_Quickened_Slay_Living **** **** **** **** **** **** **** **** +11842 OAShaman_Silent_Slay_Living **** **** **** **** **** **** **** **** +11843 OAShaman_Still_Slay_Living **** **** **** **** **** **** **** **** +11844 OAShaman_Summon_Creature_V **** **** **** **** **** **** **** **** +11845 OAShaman_Exteneded_Summon_Creature_V **** **** **** **** **** **** **** **** +11846 OAShaman_Quickened_Summon_Creature_V **** **** **** **** **** **** **** **** +11847 OAShaman_Silent_Summon_Creature_V **** **** **** **** **** **** **** **** +11848 OAShaman_Still_Summon_Creature_V **** **** **** **** **** **** **** **** +11849 OAShaman_True_Seeing **** **** **** **** **** **** **** **** +11850 OAShaman_Exteneded_True_Seeing **** **** **** **** **** **** **** **** +11851 OAShaman_Quickened_True_Seeing **** **** **** **** **** **** **** **** +11852 OAShaman_Silent_True_Seeing **** **** **** **** **** **** **** **** +11853 OAShaman_Still_True_Seeing **** **** **** **** **** **** **** **** +11854 OAShaman_Animate_Object **** **** **** **** **** **** **** **** +11855 OAShaman_Exteneded_Animate_Object **** **** **** **** **** **** **** **** +11856 OAShaman_Planar_Ally **** **** **** **** **** **** **** **** +11857 OAShaman_Exteneded_Planar_Ally **** **** **** **** **** **** **** **** +11858 OAShaman_Silent_Planar_Ally **** **** **** **** **** **** **** **** +11859 OAShaman_Still_Planar_Ally **** **** **** **** **** **** **** **** +11860 OAShaman_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +11861 OAShaman_Exteneded_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +11862 OAShaman_Silent_EXALTED_RAIMENT **** **** **** **** **** **** **** **** +11863 OAShaman_Greater_Dispelling **** **** **** **** **** **** **** **** +11864 OAShaman_Silent_Greater_Dispelling **** **** **** **** **** **** **** **** +11865 OAShaman_Still_Greater_Dispelling **** **** **** **** **** **** **** **** +11866 OAShaman_Harm **** **** **** **** **** **** **** **** +11867 OAShaman_Silent_Harm **** **** **** **** **** **** **** **** +11868 OAShaman_Still_Harm **** **** **** **** **** **** **** **** +11869 OAShaman_Heal **** **** **** **** **** **** **** **** +11870 OAShaman_Silent_Heal **** **** **** **** **** **** **** **** +11871 OAShaman_Still_Heal **** **** **** **** **** **** **** **** +11872 OAShaman_Planar_Ally **** **** **** **** **** **** **** **** +11873 OAShaman_Exteneded_Planar_Ally **** **** **** **** **** **** **** **** +11874 OAShaman_Silent_Planar_Ally **** **** **** **** **** **** **** **** +11875 OAShaman_Still_Planar_Ally **** **** **** **** **** **** **** **** +11876 OAShaman_Stoneskin **** **** **** **** **** **** **** **** +11877 OAShaman_Exteneded_Stoneskin **** **** **** **** **** **** **** **** +11878 OAShaman_Silent_Stoneskin **** **** **** **** **** **** **** **** +11879 OAShaman_Still_Stoneskin **** **** **** **** **** **** **** **** +11880 OAShaman_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +11881 OAShaman_Empowered_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +11882 OAShaman_Maximized_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +11883 OAShaman_Silent_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +11884 OAShaman_Still_STORM_OF_SHARDS **** **** **** **** **** **** **** **** +11885 OAShaman_Summon_Creature_VI **** **** **** **** **** **** **** **** +11886 OAShaman_Exteneded_Summon_Creature_VI **** **** **** **** **** **** **** **** +11887 OAShaman_Silent_Summon_Creature_VI **** **** **** **** **** **** **** **** +11888 OAShaman_Still_Summon_Creature_VI **** **** **** **** **** **** **** **** +11889 OAShaman_Blasphemy **** **** **** **** **** **** **** **** +11890 OAShaman_Silent_Blasphemy **** **** **** **** **** **** **** **** +11891 OAShaman_Still_Blasphemy **** **** **** **** **** **** **** **** +11892 OAShaman_Control_Weather **** **** **** **** **** **** **** **** +11893 OAShaman_CW_Rain **** **** **** **** **** **** **** **** +11894 OAShaman_CW_Snow **** **** **** **** **** **** **** **** +11895 OAShaman_CW_Clear **** **** **** **** **** **** **** **** +11896 OAShaman_Exteneded_Control_Weather **** **** **** **** **** **** **** **** +11897 OAShaman_Exteneded_CW_Rain **** **** **** **** **** **** **** **** +11898 OAShaman_Exteneded_CW_Snow **** **** **** **** **** **** **** **** +11899 OAShaman_Exteneded_CW_Clear **** **** **** **** **** **** **** **** +11900 OAShaman_Silent_Control_Weather **** **** **** **** **** **** **** **** +11901 OAShaman_Silent_CW_Rain **** **** **** **** **** **** **** **** +11902 OAShaman_Silent_CW_Snow **** **** **** **** **** **** **** **** +11903 OAShaman_Silent_CW_Clear **** **** **** **** **** **** **** **** +11904 OAShaman_Still_Control_Weather **** **** **** **** **** **** **** **** +11905 OAShaman_Still_CW_Rain **** **** **** **** **** **** **** **** +11906 OAShaman_Still_CW_Snow **** **** **** **** **** **** **** **** +11907 OAShaman_Still_CW_Clear **** **** **** **** **** **** **** **** +11908 OAShaman_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +11909 OAShaman_Silent_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +11910 OAShaman_Still_DEATH_BY_THORNS **** **** **** **** **** **** **** **** +11911 OAShaman_Dictum **** **** **** **** **** **** **** **** +11912 OAShaman_Silent_Dictum **** **** **** **** **** **** **** **** +11913 OAShaman_Still_Dictum **** **** **** **** **** **** **** **** +11914 OAShaman_Greater_Restoration **** **** **** **** **** **** **** **** +11915 OAShaman_Silent_Greater_Restoration **** **** **** **** **** **** **** **** +11916 OAShaman_Still_Greater_Restoration **** **** **** **** **** **** **** **** +11917 OAShaman_GreaterScrying **** **** **** **** **** **** **** **** +11918 OAShaman_Exteneded_GreaterScrying **** **** **** **** **** **** **** **** +11919 OAShaman_Silent_GreaterScrying **** **** **** **** **** **** **** **** +11920 OAShaman_Still_GreaterScrying **** **** **** **** **** **** **** **** +11921 OAShaman_Holy_Word **** **** **** **** **** **** **** **** +11922 OAShaman_Silent_Holy_Word **** **** **** **** **** **** **** **** +11923 OAShaman_Still_Holy_Word **** **** **** **** **** **** **** **** +11924 OAShaman_PHOENIX_FIRE **** **** **** **** **** **** **** **** +11925 OAShaman_Empowered_PHOENIX_FIRE **** **** **** **** **** **** **** **** +11926 OAShaman_Silent_PHOENIX_FIRE **** **** **** **** **** **** **** **** +11927 OAShaman_Still_PHOENIX_FIRE **** **** **** **** **** **** **** **** +11928 OAShaman_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +11929 OAShaman_Empowered_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +11930 OAShaman_Exteneded_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +11931 OAShaman_Silent_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +11932 OAShaman_Still_RAIN_OF_EMBERS **** **** **** **** **** **** **** **** +11933 OAShaman_RAPTURE_OF_RUPTURE **** **** **** **** **** **** **** **** +11934 OAShaman_Empowered_RAPTURE_OF_RUPTURE **** **** **** **** **** **** **** **** +11935 OAShaman_Regenerate **** **** **** **** **** **** **** **** +11936 OAShaman_Exteneded_Regenerate **** **** **** **** **** **** **** **** +11937 OAShaman_Silent_Regenerate **** **** **** **** **** **** **** **** +11938 OAShaman_Still_Regenerate **** **** **** **** **** **** **** **** +11939 OAShaman_Repulsion **** **** **** **** **** **** **** **** +11940 OAShaman_Exteneded_Repulsion **** **** **** **** **** **** **** **** +11941 OAShaman_Silent_Repulsion **** **** **** **** **** **** **** **** +11942 OAShaman_Still_Repulsion **** **** **** **** **** **** **** **** +11943 OAShaman_Resurrection **** **** **** **** **** **** **** **** +11944 OAShaman_Silent_Resurrection **** **** **** **** **** **** **** **** +11945 OAShaman_Still_Resurrection **** **** **** **** **** **** **** **** +11946 OAShaman_Summon_Creature_VII **** **** **** **** **** **** **** **** +11947 OAShaman_Summon7Air **** **** **** **** **** **** **** **** +11948 OAShaman_Summon7Earth **** **** **** **** **** **** **** **** +11949 OAShaman_Summon7Fire **** **** **** **** **** **** **** **** +11950 OAShaman_Summon7Water **** **** **** **** **** **** **** **** +11951 OAShaman_Exteneded_Summon_Creature_VII **** **** **** **** **** **** **** **** +11952 OAShaman_Exteneded_Summon7Air **** **** **** **** **** **** **** **** +11953 OAShaman_Exteneded_Summon7Earth **** **** **** **** **** **** **** **** +11954 OAShaman_Exteneded_Summon7Fire **** **** **** **** **** **** **** **** +11955 OAShaman_Exteneded_Summon7Water **** **** **** **** **** **** **** **** +11956 OAShaman_Silent_Summon_Creature_VII **** **** **** **** **** **** **** **** +11957 OAShaman_Silent_Summon7Air **** **** **** **** **** **** **** **** +11958 OAShaman_Silent_Summon7Earth **** **** **** **** **** **** **** **** +11959 OAShaman_Silent_Summon7Fire **** **** **** **** **** **** **** **** +11960 OAShaman_Silent_Summon7Water **** **** **** **** **** **** **** **** +11961 OAShaman_Still_Summon_Creature_VII **** **** **** **** **** **** **** **** +11962 OAShaman_Still_Summon7Air **** **** **** **** **** **** **** **** +11963 OAShaman_Still_Summon7Earth **** **** **** **** **** **** **** **** +11964 OAShaman_Still_Summon7Fire **** **** **** **** **** **** **** **** +11965 OAShaman_Still_Summon7Water **** **** **** **** **** **** **** **** +11966 OAShaman_Sunbeam **** **** **** **** **** **** **** **** +11967 OAShaman_Silent_Sunbeam **** **** **** **** **** **** **** **** +11968 OAShaman_Still_Sunbeam **** **** **** **** **** **** **** **** +11969 OAShaman_Word_of_Chaos **** **** **** **** **** **** **** **** +11970 OAShaman_Silent_Word_of_Chaos **** **** **** **** **** **** **** **** +11971 OAShaman_Still_Word_of_Chaos **** **** **** **** **** **** **** **** +11972 OAShaman_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +11973 OAShaman_Exteneded_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +11974 OAShaman_Silent_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +11975 OAShaman_Still_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +11976 OAShaman_Aura_versus_Alignment **** **** **** **** **** **** **** **** +11977 OAShaman_Unholy_Aura **** **** **** **** **** **** **** **** +11978 OAShaman_Holy_Aura **** **** **** **** **** **** **** **** +11979 OAShaman_Exteneded_Aura_versus_Alignment **** **** **** **** **** **** **** **** +11980 OAShaman_Exteneded_Unholy_Aura **** **** **** **** **** **** **** **** +11981 OAShaman_Exteneded_Holy_Aura **** **** **** **** **** **** **** **** +11982 OAShaman_Silent_Aura_versus_Alignment **** **** **** **** **** **** **** **** +11983 OAShaman_Silent_Unholy_Aura **** **** **** **** **** **** **** **** +11984 OAShaman_Silent_Holy_Aura **** **** **** **** **** **** **** **** +11985 OAShaman_Still_Aura_versus_Alignment **** **** **** **** **** **** **** **** +11986 OAShaman_Still_Unholy_Aura **** **** **** **** **** **** **** **** +11987 OAShaman_Still_Holy_Aura **** **** **** **** **** **** **** **** +11988 OAShaman_DiscernLocation **** **** **** **** **** **** **** **** +11989 OAShaman_Exteneded_DiscernLocation **** **** **** **** **** **** **** **** +11990 OAShaman_Silent_DiscernLocation **** **** **** **** **** **** **** **** +11991 OAShaman_Still_DiscernLocation **** **** **** **** **** **** **** **** +11992 OAShaman_DRAGON_CLOUD **** **** **** **** **** **** **** **** +11993 OAShaman_Silent_DRAGON_CLOUD **** **** **** **** **** **** **** **** +11994 OAShaman_Still_DRAGON_CLOUD **** **** **** **** **** **** **** **** +11995 OAShaman_Earthquake **** **** **** **** **** **** **** **** +11996 OAShaman_Exteneded_Earthquake **** **** **** **** **** **** **** **** +11997 OAShaman_Silent_Earthquake **** **** **** **** **** **** **** **** +11998 OAShaman_Still_Earthquake **** **** **** **** **** **** **** **** +11999 OAShaman_EVIL_WEATHER **** **** **** **** **** **** **** **** +12000 OAShaman_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +12001 OAShaman_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +12002 OAShaman_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +12003 OAShaman_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +12004 OAShaman_Silent_EVIL_WEATHER **** **** **** **** **** **** **** **** +12005 OAShaman_Silent_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +12006 OAShaman_Silent_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +12007 OAShaman_Silent_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +12008 OAShaman_Silent_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +12009 OAShaman_Still_EVIL_WEATHER **** **** **** **** **** **** **** **** +12010 OAShaman_Still_EVIL_WEATHER_RAIN_OF_BLOOD **** **** **** **** **** **** **** **** +12011 OAShaman_Still_EVIL_WEATHER_VIOLET_RAIN **** **** **** **** **** **** **** **** +12012 OAShaman_Still_EVIL_WEATHER_GREEN_FOG **** **** **** **** **** **** **** **** +12013 OAShaman_Still_EVIL_WEATHER_RAIN_OF_FISH **** **** **** **** **** **** **** **** +12014 OAShaman_Greater_Planar_Ally **** **** **** **** **** **** **** **** +12015 OAShaman_Exteneded_Greater_Planar_Ally **** **** **** **** **** **** **** **** +12016 OAShaman_Silent_Greater_Planar_Ally **** **** **** **** **** **** **** **** +12017 OAShaman_Still_Greater_Planar_Ally **** **** **** **** **** **** **** **** +12018 OAShaman_Holy_Aura **** **** **** **** **** **** **** **** +12019 OAShaman_Exteneded_Holy_Aura **** **** **** **** **** **** **** **** +12020 OAShaman_Silent_Holy_Aura **** **** **** **** **** **** **** **** +12021 OAShaman_Still_Holy_Aura **** **** **** **** **** **** **** **** +12022 OAShaman_Mass_Heal **** **** **** **** **** **** **** **** +12023 OAShaman_Silent_Mass_Heal **** **** **** **** **** **** **** **** +12024 OAShaman_Still_Mass_Heal **** **** **** **** **** **** **** **** +12025 OAShaman_Summon_Creature_VIII **** **** **** **** **** **** **** **** +12026 OAShaman_Summon8Air **** **** **** **** **** **** **** **** +12027 OAShaman_Summon8Earth **** **** **** **** **** **** **** **** +12028 OAShaman_Summon8Fire **** **** **** **** **** **** **** **** +12029 OAShaman_Summon8Water **** **** **** **** **** **** **** **** +12030 OAShaman_Exteneded_Summon_Creature_VIII **** **** **** **** **** **** **** **** +12031 OAShaman_Exteneded_Summon8Air **** **** **** **** **** **** **** **** +12032 OAShaman_Exteneded_Summon8Earth **** **** **** **** **** **** **** **** +12033 OAShaman_Exteneded_Summon8Fire **** **** **** **** **** **** **** **** +12034 OAShaman_Exteneded_Summon8Water **** **** **** **** **** **** **** **** +12035 OAShaman_Silent_Summon_Creature_VIII **** **** **** **** **** **** **** **** +12036 OAShaman_Silent_Summon8Air **** **** **** **** **** **** **** **** +12037 OAShaman_Silent_Summon8Earth **** **** **** **** **** **** **** **** +12038 OAShaman_Silent_Summon8Fire **** **** **** **** **** **** **** **** +12039 OAShaman_Silent_Summon8Water **** **** **** **** **** **** **** **** +12040 OAShaman_Still_Summon_Creature_VIII **** **** **** **** **** **** **** **** +12041 OAShaman_Still_Summon8Air **** **** **** **** **** **** **** **** +12042 OAShaman_Still_Summon8Earth **** **** **** **** **** **** **** **** +12043 OAShaman_Still_Summon8Fire **** **** **** **** **** **** **** **** +12044 OAShaman_Still_Summon8Water **** **** **** **** **** **** **** **** +12045 OAShaman_APOCALYPSE_FROM_THE_SKY **** **** **** **** **** **** **** **** +12046 OAShaman_APOCALYPSE_FROM_THE_SKY_FIRE **** **** **** **** **** **** **** **** +12047 OAShaman_APOCALYPSE_FROM_THE_SKY_ACID **** **** **** **** **** **** **** **** +12048 OAShaman_APOCALYPSE_FROM_THE_SKY_SONIC **** **** **** **** **** **** **** **** +12049 OAShaman_EXALTED_FURY **** **** **** **** **** **** **** **** +12050 OAShaman_Gate **** **** **** **** **** **** **** **** +12051 OAShaman_Summon_Creature_IX **** **** **** **** **** **** **** **** +12052 OAShaman_Summon9Air **** **** **** **** **** **** **** **** +12053 OAShaman_Summon9Earth **** **** **** **** **** **** **** **** +12054 OAShaman_Summon9Fire **** **** **** **** **** **** **** **** +12055 OAShaman_Summon9Water **** **** **** **** **** **** **** **** +12056 OAShaman_True_Resurrection **** **** **** **** **** **** **** **** +12057 SlayerOfDomiel_Bless_Weapon **** **** **** **** **** **** **** **** +12058 SlayerOfDomiel_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +12059 SlayerOfDomiel_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +12060 SlayerOfDomiel_Still_Bless_Weapon **** **** **** **** **** **** **** **** +12061 SlayerOfDomiel_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12062 SlayerOfDomiel_Alter_Self_Learn **** **** **** **** **** **** **** **** +12063 SlayerOfDomiel_Alter_Self_Options **** **** **** **** **** **** **** **** +12064 SlayerOfDomiel_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12065 SlayerOfDomiel_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12066 SlayerOfDomiel_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12067 SlayerOfDomiel_Exteneded_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12068 SlayerOfDomiel_Exteneded_Alter_Self_Learn **** **** **** **** **** **** **** **** +12069 SlayerOfDomiel_Exteneded_Alter_Self_Options **** **** **** **** **** **** **** **** +12070 SlayerOfDomiel_Exteneded_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12071 SlayerOfDomiel_Exteneded_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12072 SlayerOfDomiel_Exteneded_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12073 SlayerOfDomiel_Silent_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12074 SlayerOfDomiel_Silent_Alter_Self_Learn **** **** **** **** **** **** **** **** +12075 SlayerOfDomiel_Silent_Alter_Self_Options **** **** **** **** **** **** **** **** +12076 SlayerOfDomiel_Silent_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12077 SlayerOfDomiel_Silent_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12078 SlayerOfDomiel_Silent_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12079 SlayerOfDomiel_Still_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12080 SlayerOfDomiel_Still_Alter_Self_Learn **** **** **** **** **** **** **** **** +12081 SlayerOfDomiel_Still_Alter_Self_Options **** **** **** **** **** **** **** **** +12082 SlayerOfDomiel_Still_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12083 SlayerOfDomiel_Still_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12084 SlayerOfDomiel_Still_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12085 SlayerOfDomiel_Divine_Favor **** **** **** **** **** **** **** **** +12086 SlayerOfDomiel_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +12087 SlayerOfDomiel_Silent_Divine_Favor **** **** **** **** **** **** **** **** +12088 SlayerOfDomiel_Still_Divine_Favor **** **** **** **** **** **** **** **** +12089 SlayerOfDomiel_Obscuring_Mist **** **** **** **** **** **** **** **** +12090 SlayerOfDomiel_Exteneded_Obscuring_Mist **** **** **** **** **** **** **** **** +12091 SlayerOfDomiel_Silent_Obscuring_Mist **** **** **** **** **** **** **** **** +12092 SlayerOfDomiel_Still_Obscuring_Mist **** **** **** **** **** **** **** **** +12093 SlayerOfDomiel_VisionOfHeaven **** **** **** **** **** **** **** **** +12094 SlayerOfDomiel_Exteneded_VisionOfHeaven **** **** **** **** **** **** **** **** +12095 SlayerOfDomiel_Silent_VisionOfHeaven **** **** **** **** **** **** **** **** +12096 SlayerOfDomiel_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +12097 SlayerOfDomiel_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +12098 SlayerOfDomiel_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12099 SlayerOfDomiel_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12100 SlayerOfDomiel_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12101 SlayerOfDomiel_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12102 SlayerOfDomiel_Empowered_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12103 SlayerOfDomiel_Maximized_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12104 SlayerOfDomiel_Still_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12105 SlayerOfDomiel_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12106 SlayerOfDomiel_Alter_Self_Learn **** **** **** **** **** **** **** **** +12107 SlayerOfDomiel_Alter_Self_Options **** **** **** **** **** **** **** **** +12108 SlayerOfDomiel_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12109 SlayerOfDomiel_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12110 SlayerOfDomiel_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12111 SlayerOfDomiel_Exteneded_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12112 SlayerOfDomiel_Exteneded_Alter_Self_Learn **** **** **** **** **** **** **** **** +12113 SlayerOfDomiel_Exteneded_Alter_Self_Options **** **** **** **** **** **** **** **** +12114 SlayerOfDomiel_Exteneded_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12115 SlayerOfDomiel_Exteneded_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12116 SlayerOfDomiel_Exteneded_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12117 SlayerOfDomiel_Silent_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12118 SlayerOfDomiel_Silent_Alter_Self_Learn **** **** **** **** **** **** **** **** +12119 SlayerOfDomiel_Silent_Alter_Self_Options **** **** **** **** **** **** **** **** +12120 SlayerOfDomiel_Silent_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12121 SlayerOfDomiel_Silent_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12122 SlayerOfDomiel_Silent_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12123 SlayerOfDomiel_Still_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12124 SlayerOfDomiel_Still_Alter_Self_Learn **** **** **** **** **** **** **** **** +12125 SlayerOfDomiel_Still_Alter_Self_Options **** **** **** **** **** **** **** **** +12126 SlayerOfDomiel_Still_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12127 SlayerOfDomiel_Still_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12128 SlayerOfDomiel_Still_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12129 SlayerOfDomiel_Darkness **** **** **** **** **** **** **** **** +12130 SlayerOfDomiel_Exteneded_Darkness **** **** **** **** **** **** **** **** +12131 SlayerOfDomiel_Silent_Darkness **** **** **** **** **** **** **** **** +12132 SlayerOfDomiel_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12133 SlayerOfDomiel_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12134 SlayerOfDomiel_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12135 SlayerOfDomiel_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12136 SlayerOfDomiel_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12137 SlayerOfDomiel_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12138 SlayerOfDomiel_DeeperDarkness **** **** **** **** **** **** **** **** +12139 SlayerOfDomiel_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +12140 SlayerOfDomiel_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +12141 SlayerOfDomiel_Invisibility **** **** **** **** **** **** **** **** +12142 SlayerOfDomiel_Exteneded_Invisibility **** **** **** **** **** **** **** **** +12143 SlayerOfDomiel_Silent_Invisibility **** **** **** **** **** **** **** **** +12144 SlayerOfDomiel_Still_Invisibility **** **** **** **** **** **** **** **** +12145 SlayerOfDomiel_NONDETECTION **** **** **** **** **** **** **** **** +12146 SlayerOfDomiel_Exteneded_NONDETECTION **** **** **** **** **** **** **** **** +12147 SlayerOfDomiel_Silent_NONDETECTION **** **** **** **** **** **** **** **** +12148 SlayerOfDomiel_Still_NONDETECTION **** **** **** **** **** **** **** **** +12149 SlayerOfDomiel_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +12150 SlayerOfDomiel_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +12151 SlayerOfDomiel_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12152 SlayerOfDomiel_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12153 SlayerOfDomiel_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12154 SlayerOfDomiel_Death_Ward **** **** **** **** **** **** **** **** +12155 SlayerOfDomiel_DimensionDoor_RadialMaster **** **** **** **** **** **** **** **** +12156 SlayerOfDomiel_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +12157 SlayerOfDomiel_DimensionDoor_Party **** **** **** **** **** **** **** **** +12158 SlayerOfDomiel_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +12159 SlayerOfDomiel_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +12160 SlayerOfDomiel_Freedom_of_Movement **** **** **** **** **** **** **** **** +12161 SlayerOfDomiel_Holy_Sword **** **** **** **** **** **** **** **** +12162 SlayerOfDomiel_Improved_Invisibility **** **** **** **** **** **** **** **** +12163 SlayerOfDomiel_SwordOfConscience **** **** **** **** **** **** **** **** +12164 SlayerOfDomiel_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +12165 SlayerOfDomiel_SUNMANTLE **** **** **** **** **** **** **** **** +12166 SlayerOfDomiel_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12167 Suel_Archanamach_ABERRATE **** **** **** **** **** **** **** **** +12168 Suel_Archanamach_BESTOW_WOUND **** **** **** **** **** **** **** **** +12169 Suel_Archanamach_Burning_Hands **** **** **** **** **** **** **** **** +12170 Suel_Archanamach_Color_Spray **** **** **** **** **** **** **** **** +12171 Suel_Archanamach_DETECT_UNDEAD **** **** **** **** **** **** **** **** +12172 Suel_Archanamach_Disguise_Self_Radial_Master **** **** **** **** **** **** **** **** +12173 Suel_Archanamach_Disguise_Self_Learn **** **** **** **** **** **** **** **** +12174 Suel_Archanamach_Disguise_Self_Options **** **** **** **** **** **** **** **** +12175 Suel_Archanamach_Disguise_Self_QS1 **** **** **** **** **** **** **** **** +12176 Suel_Archanamach_Disguise_Self_QS2 **** **** **** **** **** **** **** **** +12177 Suel_Archanamach_Disguise_Self_QS3 **** **** **** **** **** **** **** **** +12178 Suel_Archanamach_Endure_Elements **** **** **** **** **** **** **** **** +12179 Suel_Archanamach_ENLARGE_PERSON **** **** **** **** **** **** **** **** +12180 Suel_Archanamach_Expeditious_Retreat **** **** **** **** **** **** **** **** +12181 Suel_Archanamach_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +12182 Suel_Archanamach_FistOfStone **** **** **** **** **** **** **** **** +12183 Suel_Archanamach_Identify **** **** **** **** **** **** **** **** +12184 Suel_Archanamach_Ironguts **** **** **** **** **** **** **** **** +12185 Suel_Archanamach_Lesser_Deflect **** **** **** **** **** **** **** **** +12186 Suel_Archanamach_Magic_Weapon **** **** **** **** **** **** **** **** +12187 Suel_Archanamach_Protection_from_Chaos **** **** **** **** **** **** **** **** +12188 Suel_Archanamach_Protection_from_Evil **** **** **** **** **** **** **** **** +12189 Suel_Archanamach_Protection_from_Good **** **** **** **** **** **** **** **** +12190 Suel_Archanamach_Protection_from_Law **** **** **** **** **** **** **** **** +12191 Suel_Archanamach_REDUCE_PERSON **** **** **** **** **** **** **** **** +12192 Suel_Archanamach_Shield **** **** **** **** **** **** **** **** +12193 Suel_Archanamach_Spell_Jump **** **** **** **** **** **** **** **** +12194 Suel_Archanamach_True_Casting **** **** **** **** **** **** **** **** +12195 Suel_Archanamach_True_Strike **** **** **** **** **** **** **** **** +12196 Suel_Archanamach_Alter_Self_Radial_Master **** **** **** **** **** **** **** **** +12197 Suel_Archanamach_Alter_Self_Learn **** **** **** **** **** **** **** **** +12198 Suel_Archanamach_Alter_Self_Options **** **** **** **** **** **** **** **** +12199 Suel_Archanamach_Alter_Self_QS1 **** **** **** **** **** **** **** **** +12200 Suel_Archanamach_Alter_Self_QS2 **** **** **** **** **** **** **** **** +12201 Suel_Archanamach_Alter_Self_QS3 **** **** **** **** **** **** **** **** +12202 Suel_Archanamach_Animalistic_Power **** **** **** **** **** **** **** **** +12203 Suel_Archanamach_AugmentFamiliar **** **** **** **** **** **** **** **** +12204 Suel_Archanamach_BalagarnsIronHorn **** **** **** **** **** **** **** **** +12205 Suel_Archanamach_Blur **** **** **** **** **** **** **** **** +12206 Suel_Archanamach_Bulls_Strength **** **** **** **** **** **** **** **** +12207 Suel_Archanamach_Cats_Grace **** **** **** **** **** **** **** **** +12208 Suel_Archanamach_Continual_Flame **** **** **** **** **** **** **** **** +12209 Suel_Archanamach_Deflect **** **** **** **** **** **** **** **** +12210 Suel_Archanamach_Dispelling_Touch **** **** **** **** **** **** **** **** +12211 Suel_Archanamach_Eagle_Splendor **** **** **** **** **** **** **** **** +12212 Suel_Archanamach_Endurance **** **** **** **** **** **** **** **** +12213 Suel_Archanamach_ENERGIZE_POTION **** **** **** **** **** **** **** **** +12214 Suel_Archanamach_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +12215 Suel_Archanamach_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +12216 Suel_Archanamach_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +12217 Suel_Archanamach_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +12218 Suel_Archanamach_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +12219 Suel_Archanamach_Foxs_Cunning **** **** **** **** **** **** **** **** +12220 Suel_Archanamach_Ghostly_Visage **** **** **** **** **** **** **** **** +12221 Suel_Archanamach_Invisibility **** **** **** **** **** **** **** **** +12222 Suel_Archanamach_Knock **** **** **** **** **** **** **** **** +12223 Suel_Archanamach_Lesser_Dispel **** **** **** **** **** **** **** **** +12224 Suel_Archanamach_LocateObject **** **** **** **** **** **** **** **** +12225 Suel_Archanamach_MirrorImage **** **** **** **** **** **** **** **** +12226 Suel_Archanamach_ObscureObject **** **** **** **** **** **** **** **** +12227 Suel_Archanamach_Owls_Wisdom **** **** **** **** **** **** **** **** +12228 Suel_Archanamach_ProtectionArrows **** **** **** **** **** **** **** **** +12229 Suel_Archanamach_Pyrotechnics **** **** **** **** **** **** **** **** +12230 Suel_Archanamach_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +12231 Suel_Archanamach_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +12232 Suel_Archanamach_Resist_Elements **** **** **** **** **** **** **** **** +12233 Suel_Archanamach_See_Invisibility **** **** **** **** **** **** **** **** +12234 Suel_Archanamach_Shadow_Spray **** **** **** **** **** **** **** **** +12235 Suel_Archanamach_Stone_Bones **** **** **** **** **** **** **** **** +12236 Suel_Archanamach_Sure_Strike **** **** **** **** **** **** **** **** +12237 Suel_Archanamach_Ultravision **** **** **** **** **** **** **** **** +12238 Suel_Archanamach_UNHEAVENED **** **** **** **** **** **** **** **** +12239 Suel_Archanamach_WhirlingBlade **** **** **** **** **** **** **** **** +12240 Suel_Archanamach_Clairaudience_and_Clairvoyance **** **** **** **** **** **** **** **** +12241 Suel_Archanamach_Clarity **** **** **** **** **** **** **** **** +12242 Suel_Archanamach_Crown_Might **** **** **** **** **** **** **** **** +12243 Suel_Archanamach_Crown_Protection **** **** **** **** **** **** **** **** +12244 Suel_Archanamach_CURSE_OF_THE_PUTRID_HUSK **** **** **** **** **** **** **** **** +12245 Suel_Archanamach_DEVILS_EYE **** **** **** **** **** **** **** **** +12246 Suel_Archanamach_Dispel_Magic **** **** **** **** **** **** **** **** +12247 Suel_Archanamach_Displacement **** **** **** **** **** **** **** **** +12248 Suel_Archanamach_Energy_Aegis **** **** **** **** **** **** **** **** +12249 Suel_Archanamach_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +12250 Suel_Archanamach_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +12251 Suel_Archanamach_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +12252 Suel_Archanamach_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +12253 Suel_Archanamach_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +12254 Suel_Archanamach_Energy_Surge **** **** **** **** **** **** **** **** +12255 Suel_Archanamach_Energy_Surge_Acid **** **** **** **** **** **** **** **** +12256 Suel_Archanamach_Energy_Surge_Cold **** **** **** **** **** **** **** **** +12257 Suel_Archanamach_Energy_Surge_Elec **** **** **** **** **** **** **** **** +12258 Suel_Archanamach_Energy_Surge_Fire **** **** **** **** **** **** **** **** +12259 Suel_Archanamach_Energy_Surge_Sonic **** **** **** **** **** **** **** **** +12260 Suel_Archanamach_Find_Traps **** **** **** **** **** **** **** **** +12261 Suel_Archanamach_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12262 Suel_Archanamach_Halt **** **** **** **** **** **** **** **** +12263 Suel_Archanamach_Haste **** **** **** **** **** **** **** **** +12264 Suel_Archanamach_Invisibility_Sphere **** **** **** **** **** **** **** **** +12265 Suel_Archanamach_Keen_Edge **** **** **** **** **** **** **** **** +12266 Suel_Archanamach_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12267 Suel_Archanamach_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +12268 Suel_Archanamach_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +12269 Suel_Archanamach_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +12270 Suel_Archanamach_NONDETECTION **** **** **** **** **** **** **** **** +12271 Suel_Archanamach_Protection_from_Elements **** **** **** **** **** **** **** **** +12272 Suel_Archanamach_REALITY_BLIND **** **** **** **** **** **** **** **** +12273 Suel_Archanamach_Slow **** **** **** **** **** **** **** **** +12274 Suel_Archanamach_Spiderskin **** **** **** **** **** **** **** **** +12275 Suel_Archanamach_WaterBreathing **** **** **** **** **** **** **** **** +12276 Suel_Archanamach_Weapon_of_Impact **** **** **** **** **** **** **** **** +12277 Suel_Archanamach_ArcaneEye **** **** **** **** **** **** **** **** +12278 Suel_Archanamach_Bestow_Curse **** **** **** **** **** **** **** **** +12279 Suel_Archanamach_DetectScrying **** **** **** **** **** **** **** **** +12280 Suel_Archanamach_Dimensional_Anchor **** **** **** **** **** **** **** **** +12281 Suel_Archanamach_FireTrap **** **** **** **** **** **** **** **** +12282 Suel_Archanamach_Greater_Resistance **** **** **** **** **** **** **** **** +12283 Suel_Archanamach_Ilyykurs_Mantle **** **** **** **** **** **** **** **** +12284 Suel_Archanamach_Improved_Invisibility **** **** **** **** **** **** **** **** +12285 Suel_Archanamach_Lesser_Spell_Breach **** **** **** **** **** **** **** **** +12286 Suel_Archanamach_LocateCreature **** **** **** **** **** **** **** **** +12287 Suel_Archanamach_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +12288 Suel_Archanamach_MASS_ENLARGE_PERSON **** **** **** **** **** **** **** **** +12289 Suel_Archanamach_MASS_REDUCE_PERSON **** **** **** **** **** **** **** **** +12290 Suel_Archanamach_Mass_Ultravision **** **** **** **** **** **** **** **** +12291 Suel_Archanamach_Minor_Globe_of_Invulnerability **** **** **** **** **** **** **** **** +12292 Suel_Archanamach_Phantasmal_Killer **** **** **** **** **** **** **** **** +12293 Suel_Archanamach_Polymorph_Self **** **** **** **** **** **** **** **** +12294 Suel_Archanamach_Polymorph_GIANT_SPIDER **** **** **** **** **** **** **** **** +12295 Suel_Archanamach_Polymorph_TROLL **** **** **** **** **** **** **** **** +12296 Suel_Archanamach_Polymorph_UMBER_HULK **** **** **** **** **** **** **** **** +12297 Suel_Archanamach_Polymorph_PIXIE **** **** **** **** **** **** **** **** +12298 Suel_Archanamach_Polymorph_ZOMBIE **** **** **** **** **** **** **** **** +12299 Suel_Archanamach_RAINBOW_PATTERN **** **** **** **** **** **** **** **** +12300 Suel_Archanamach_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +12301 Suel_Archanamach_Remove_Curse **** **** **** **** **** **** **** **** +12302 Suel_Archanamach_Scrying **** **** **** **** **** **** **** **** +12303 Suel_Archanamach_SerpentArrows **** **** **** **** **** **** **** **** +12304 Suel_Archanamach_Shadow_Conjuration **** **** **** **** **** **** **** **** +12305 Suel_Archanamach_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +12306 Suel_Archanamach_SHADOW_CON_Darkness **** **** **** **** **** **** **** **** +12307 Suel_Archanamach_SHADOW_CON_Inivsibility **** **** **** **** **** **** **** **** +12308 Suel_Archanamach_SHADOW_CON_Mage_Armor **** **** **** **** **** **** **** **** +12309 Suel_Archanamach_SHADOW_CON_Magic_Missile **** **** **** **** **** **** **** **** +12310 Suel_Archanamach_Slashing_Dispel **** **** **** **** **** **** **** **** +12311 Suel_Archanamach_Stoneskin **** **** **** **** **** **** **** **** +12312 Suel_Archanamach_BalefulPolymorph **** **** **** **** **** **** **** **** +12313 Suel_Archanamach_BreakEnchantment **** **** **** **** **** **** **** **** +12314 Suel_Archanamach_Dismissal **** **** **** **** **** **** **** **** +12315 Suel_Archanamach_DraconicMight **** **** **** **** **** **** **** **** +12316 Suel_Archanamach_Energy_Buffer **** **** **** **** **** **** **** **** +12317 Suel_Archanamach_Feeblemind **** **** **** **** **** **** **** **** +12318 Suel_Archanamach_Greater_Shadow_Conjuration **** **** **** **** **** **** **** **** +12319 Suel_Archanamach_GR_SHADOW_CON_Summon_Shadow **** **** **** **** **** **** **** **** +12320 Suel_Archanamach_GR_SHADOW_CON_Acid_Arrow **** **** **** **** **** **** **** **** +12321 Suel_Archanamach_GR_SHADOW_CON_Ghostly_Visage **** **** **** **** **** **** **** **** +12322 Suel_Archanamach_GR_SHADOW_CON_Web **** **** **** **** **** **** **** **** +12323 Suel_Archanamach_GR_SHADOW_CON_Minor_Globe **** **** **** **** **** **** **** **** +12324 Suel_Archanamach_Lesser_Mind_Blank **** **** **** **** **** **** **** **** +12325 Suel_Archanamach_Lesser_Spell_Mantle **** **** **** **** **** **** **** **** +12326 Suel_Archanamach_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +12327 Favoured_Soul_Cure_Minor_Wounds **** **** **** **** **** **** **** **** +12328 Favoured_Soul_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +12329 Favoured_Soul_Light **** **** **** **** **** **** **** **** +12330 Favoured_Soul_Read_Magic **** **** **** **** **** **** **** **** +12331 Favoured_Soul_Resistance **** **** **** **** **** **** **** **** +12332 Favoured_Soul_Virtue **** **** **** **** **** **** **** **** +12333 Favoured_Soul_ANGRY_ACHE **** **** **** **** **** **** **** **** +12334 Favoured_Soul_Bane **** **** **** **** **** **** **** **** +12335 Favoured_Soul_Blade_of_Blood **** **** **** **** **** **** **** **** +12336 Favoured_Soul_Blade_of_Blood_1d6 **** **** **** **** **** **** **** **** +12337 Favoured_Soul_Blade_of_Blood_3d6 **** **** **** **** **** **** **** **** +12338 Favoured_Soul_Bless **** **** **** **** **** **** **** **** +12339 Favoured_Soul_Bless_Water **** **** **** **** **** **** **** **** +12340 Favoured_Soul_Cause_Fear **** **** **** **** **** **** **** **** +12341 Favoured_Soul_Command_RadialMaster **** **** **** **** **** **** **** **** +12342 Favoured_Soul_Command_Approach **** **** **** **** **** **** **** **** +12343 Favoured_Soul_Command_Drop **** **** **** **** **** **** **** **** +12344 Favoured_Soul_Command_Fall **** **** **** **** **** **** **** **** +12345 Favoured_Soul_Command_Flee **** **** **** **** **** **** **** **** +12346 Favoured_Soul_Command_Halt **** **** **** **** **** **** **** **** +12347 Favoured_Soul_Conviction **** **** **** **** **** **** **** **** +12348 Favoured_Soul_Crafters_Blessing **** **** **** **** **** **** **** **** +12349 Favoured_Soul_Crafters_Curse **** **** **** **** **** **** **** **** +12350 Favoured_Soul_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12351 Favoured_Soul_Curse_Water **** **** **** **** **** **** **** **** +12352 Favoured_Soul_Detect_Chaos **** **** **** **** **** **** **** **** +12353 Favoured_Soul_Detect_Evil **** **** **** **** **** **** **** **** +12354 Favoured_Soul_Detect_Good **** **** **** **** **** **** **** **** +12355 Favoured_Soul_Detect_Law **** **** **** **** **** **** **** **** +12356 Favoured_Soul_DETECT_UNDEAD **** **** **** **** **** **** **** **** +12357 Favoured_Soul_Divine_Favor **** **** **** **** **** **** **** **** +12358 Favoured_Soul_Doom **** **** **** **** **** **** **** **** +12359 Favoured_Soul_DRUG_RESISTANCE **** **** **** **** **** **** **** **** +12360 Favoured_Soul_Endure_Elements **** **** **** **** **** **** **** **** +12361 Favoured_Soul_Entropic_Shield **** **** **** **** **** **** **** **** +12362 Favoured_Soul_EXTRACT_DRUG **** **** **** **** **** **** **** **** +12363 Favoured_Soul_EXTRACT_BACCARAN **** **** **** **** **** **** **** **** +12364 Favoured_Soul_EXTRACT_VODARE **** **** **** **** **** **** **** **** +12365 Favoured_Soul_EXTRACT_SANNISH **** **** **** **** **** **** **** **** +12366 Favoured_Soul_EXTRACT_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +12367 Favoured_Soul_EYES_OF_THE_AVORAL **** **** **** **** **** **** **** **** +12368 Favoured_Soul_HEARTACHE **** **** **** **** **** **** **** **** +12369 Favoured_Soul_HideFromUndead **** **** **** **** **** **** **** **** +12370 Favoured_Soul_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +12371 Favoured_Soul_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12372 Favoured_Soul_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +12373 Favoured_Soul_Lesser_Vigor **** **** **** **** **** **** **** **** +12374 Favoured_Soul_Magic_Stone **** **** **** **** **** **** **** **** +12375 Favoured_Soul_Magic_Weapon **** **** **** **** **** **** **** **** +12376 Favoured_Soul_Necrotic_Awareness **** **** **** **** **** **** **** **** +12377 Favoured_Soul_Obscuring_Mist **** **** **** **** **** **** **** **** +12378 Favoured_Soul_Protection_from_Chaos **** **** **** **** **** **** **** **** +12379 Favoured_Soul_Protection_from_Evil **** **** **** **** **** **** **** **** +12380 Favoured_Soul_Protection_from_Good **** **** **** **** **** **** **** **** +12381 Favoured_Soul_Protection_from_Law **** **** **** **** **** **** **** **** +12382 Favoured_Soul_RAY_OF_HOPE **** **** **** **** **** **** **** **** +12383 Favoured_Soul_Remove_Fear **** **** **** **** **** **** **** **** +12384 Favoured_Soul_Sanctuary **** **** **** **** **** **** **** **** +12385 Favoured_Soul_Shield_of_Faith **** **** **** **** **** **** **** **** +12386 Favoured_Soul_SORROW **** **** **** **** **** **** **** **** +12387 Favoured_Soul_Summon_Creature_I **** **** **** **** **** **** **** **** +12388 Favoured_Soul_SummonUndeadI **** **** **** **** **** **** **** **** +12389 Favoured_Soul_TONGUE_OF_BAALZEBUL **** **** **** **** **** **** **** **** +12390 Favoured_Soul_VisionOfHeaven **** **** **** **** **** **** **** **** +12391 Favoured_Soul_ADDICTION **** **** **** **** **** **** **** **** +12392 Favoured_Soul_ADDICTION_TERRAN_BRANDY **** **** **** **** **** **** **** **** +12393 Favoured_Soul_ADDICTION_MUSHROOM_POWDER **** **** **** **** **** **** **** **** +12394 Favoured_Soul_ADDICTION_VODARE **** **** **** **** **** **** **** **** +12395 Favoured_Soul_ADDICTION_AGONY **** **** **** **** **** **** **** **** +12396 Favoured_Soul_Aid **** **** **** **** **** **** **** **** +12397 Favoured_Soul_Animalistic_Power **** **** **** **** **** **** **** **** +12398 Favoured_Soul_BONEBLAST **** **** **** **** **** **** **** **** +12399 Favoured_Soul_Bulls_Strength **** **** **** **** **** **** **** **** +12400 Favoured_Soul_Calm_Emotions **** **** **** **** **** **** **** **** +12401 Favoured_Soul_Consecrated_Aura **** **** **** **** **** **** **** **** +12402 Favoured_Soul_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +12403 Favoured_Soul_Darkness **** **** **** **** **** **** **** **** +12404 Favoured_Soul_Death_Knell **** **** **** **** **** **** **** **** +12405 Favoured_Soul_Divine_Protection **** **** **** **** **** **** **** **** +12406 Favoured_Soul_Eagle_Splendor **** **** **** **** **** **** **** **** +12407 Favoured_Soul_ELATION **** **** **** **** **** **** **** **** +12408 Favoured_Soul_Endurance **** **** **** **** **** **** **** **** +12409 Favoured_Soul_Find_Traps **** **** **** **** **** **** **** **** +12410 Favoured_Soul_Foxs_Cunning **** **** **** **** **** **** **** **** +12411 Favoured_Soul_Hold_Person **** **** **** **** **** **** **** **** +12412 Favoured_Soul_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +12413 Favoured_Soul_Lesser_Dispel **** **** **** **** **** **** **** **** +12414 Favoured_Soul_Lesser_Restoration **** **** **** **** **** **** **** **** +12415 Favoured_Soul_Living_Undeath **** **** **** **** **** **** **** **** +12416 Favoured_Soul_Necrotic_Cyst **** **** **** **** **** **** **** **** +12417 Favoured_Soul_Negative_Energy_Ray **** **** **** **** **** **** **** **** +12418 Favoured_Soul_Owls_Wisdom **** **** **** **** **** **** **** **** +12419 Favoured_Soul_Remove_Paralysis **** **** **** **** **** **** **** **** +12420 Favoured_Soul_Resist_Elements **** **** **** **** **** **** **** **** +12421 Favoured_Soul_ShieldOther **** **** **** **** **** **** **** **** +12422 Favoured_Soul_Silence **** **** **** **** **** **** **** **** +12423 Favoured_Soul_Sound_Burst **** **** **** **** **** **** **** **** +12424 Favoured_Soul_SPORES_OF_THE_VROCK **** **** **** **** **** **** **** **** +12425 Favoured_Soul_Stone_Bones **** **** **** **** **** **** **** **** +12426 Favoured_Soul_Summon_Creature_II **** **** **** **** **** **** **** **** +12427 Favoured_Soul_SummonUndeadII **** **** **** **** **** **** **** **** +12428 Favoured_Soul_Ultravision **** **** **** **** **** **** **** **** +12429 Favoured_Soul_UndetectableAlignment **** **** **** **** **** **** **** **** +12430 Favoured_Soul_WAVE_OF_GRIEF **** **** **** **** **** **** **** **** +12431 Favoured_Soul_Animate_Dead **** **** **** **** **** **** **** **** +12432 Favoured_Soul_Bestow_Curse **** **** **** **** **** **** **** **** +12433 Favoured_Soul_Blindness_and_Deafness **** **** **** **** **** **** **** **** +12434 Favoured_Soul_BONEBLADE **** **** **** **** **** **** **** **** +12435 Favoured_Soul_BONEBLADE_GREATSWORD **** **** **** **** **** **** **** **** +12436 Favoured_Soul_BONEBLADE_LONGSWORD **** **** **** **** **** **** **** **** +12437 Favoured_Soul_BONEBLADE_SHORTSWORD **** **** **** **** **** **** **** **** +12438 Favoured_Soul_Clarity **** **** **** **** **** **** **** **** +12439 Favoured_Soul_Close_Wounds **** **** **** **** **** **** **** **** +12440 Favoured_Soul_CLUTCH_OF_ORCUS **** **** **** **** **** **** **** **** +12441 Favoured_Soul_Contagion **** **** **** **** **** **** **** **** +12442 Favoured_Soul_Continual_Flame **** **** **** **** **** **** **** **** +12443 Favoured_Soul_Crown_Might **** **** **** **** **** **** **** **** +12444 Favoured_Soul_Crown_Protection **** **** **** **** **** **** **** **** +12445 Favoured_Soul_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +12446 Favoured_Soul_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +12447 Favoured_Soul_Darkfire **** **** **** **** **** **** **** **** +12448 Favoured_Soul_Daylight **** **** **** **** **** **** **** **** +12449 Favoured_Soul_DeeperDarkness **** **** **** **** **** **** **** **** +12450 Favoured_Soul_DEVILS_EYE **** **** **** **** **** **** **** **** +12451 Favoured_Soul_Dispel_Magic **** **** **** **** **** **** **** **** +12452 Favoured_Soul_ENERGIZE_POTION **** **** **** **** **** **** **** **** +12453 Favoured_Soul_ENERGIZE_POTION_ACID **** **** **** **** **** **** **** **** +12454 Favoured_Soul_ENERGIZE_POTION_COLD **** **** **** **** **** **** **** **** +12455 Favoured_Soul_ENERGIZE_POTION_ELECTRICITY **** **** **** **** **** **** **** **** +12456 Favoured_Soul_ENERGIZE_POTION_FIRE **** **** **** **** **** **** **** **** +12457 Favoured_Soul_ENERGIZE_POTION_SONIC **** **** **** **** **** **** **** **** +12458 Favoured_Soul_Energy_Aegis **** **** **** **** **** **** **** **** +12459 Favoured_Soul_Energy_Aegis_Acid **** **** **** **** **** **** **** **** +12460 Favoured_Soul_Energy_Aegis_Cold **** **** **** **** **** **** **** **** +12461 Favoured_Soul_Energy_Aegis_Elec **** **** **** **** **** **** **** **** +12462 Favoured_Soul_Energy_Aegis_Fire **** **** **** **** **** **** **** **** +12463 Favoured_Soul_Energy_Aegis_Sonic **** **** **** **** **** **** **** **** +12464 Favoured_Soul_FLESH_RIPPER **** **** **** **** **** **** **** **** +12465 Favoured_Soul_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +12466 Favoured_Soul_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +12467 Favoured_Soul_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +12468 Favoured_Soul_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +12469 Favoured_Soul_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +12470 Favoured_Soul_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +12471 Favoured_Soul_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +12472 Favoured_Soul_Invisibility_Purge **** **** **** **** **** **** **** **** +12473 Favoured_Soul_Legions_Conviction **** **** **** **** **** **** **** **** +12474 Favoured_Soul_LocateObject **** **** **** **** **** **** **** **** +12475 Favoured_Soul_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12476 Favoured_Soul_Magic_Circle_against_Evil **** **** **** **** **** **** **** **** +12477 Favoured_Soul_Magic_Circle_against_Good **** **** **** **** **** **** **** **** +12478 Favoured_Soul_Magic_Circle_against_Law **** **** **** **** **** **** **** **** +12479 Favoured_Soul_Magic_Vestment **** **** **** **** **** **** **** **** +12480 Favoured_Soul_MASOCHISM **** **** **** **** **** **** **** **** +12481 Favoured_Soul_Mass_Aid **** **** **** **** **** **** **** **** +12482 Favoured_Soul_Mass_Lesser_Vigor **** **** **** **** **** **** **** **** +12483 Favoured_Soul_Necrotic_Bloat **** **** **** **** **** **** **** **** +12484 Favoured_Soul_Negative_Energy_Protection **** **** **** **** **** **** **** **** +12485 Favoured_Soul_ObscureObject **** **** **** **** **** **** **** **** +12486 Favoured_Soul_Prayer **** **** **** **** **** **** **** **** +12487 Favoured_Soul_Protection_from_Elements **** **** **** **** **** **** **** **** +12488 Favoured_Soul_Remove_Blindness_and_Deafness **** **** **** **** **** **** **** **** +12489 Favoured_Soul_Remove_Curse **** **** **** **** **** **** **** **** +12490 Favoured_Soul_Remove_Disease **** **** **** **** **** **** **** **** +12491 Favoured_Soul_RingOfBlades **** **** **** **** **** **** **** **** +12492 Favoured_Soul_Searing_Light **** **** **** **** **** **** **** **** +12493 Favoured_Soul_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +12494 Favoured_Soul_SHRIVELING **** **** **** **** **** **** **** **** +12495 Favoured_Soul_Slashing_Darkness **** **** **** **** **** **** **** **** +12496 Favoured_Soul_Summon_Creature_III **** **** **** **** **** **** **** **** +12497 Favoured_Soul_SummonUndeadIII **** **** **** **** **** **** **** **** +12498 Favoured_Soul_UNLIVING_WEAPON **** **** **** **** **** **** **** **** +12499 Favoured_Soul_Vigor **** **** **** **** **** **** **** **** +12500 Favoured_Soul_WaterBreathing **** **** **** **** **** **** **** **** +12501 Favoured_Soul_WRACK **** **** **** **** **** **** **** **** +12502 Favoured_Soul_ABYSSAL_MIGHT **** **** **** **** **** **** **** **** +12503 Favoured_Soul_BloodOfTheMartyr **** **** **** **** **** **** **** **** +12504 Favoured_Soul_CLAWS_OF_THE_SAVAGE **** **** **** **** **** **** **** **** +12505 Favoured_Soul_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +12506 Favoured_Soul_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +12507 Favoured_Soul_Death_Ward **** **** **** **** **** **** **** **** +12508 Favoured_Soul_Dimensional_Anchor **** **** **** **** **** **** **** **** +12509 Favoured_Soul_Dismissal **** **** **** **** **** **** **** **** +12510 Favoured_Soul_Divine_Power **** **** **** **** **** **** **** **** +12511 Favoured_Soul_Freedom_of_Movement **** **** **** **** **** **** **** **** +12512 Favoured_Soul_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12513 Favoured_Soul_Greater_Resistance **** **** **** **** **** **** **** **** +12514 Favoured_Soul_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +12515 Favoured_Soul_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +12516 Favoured_Soul_Legions_Shield_of_Faith **** **** **** **** **** **** **** **** +12517 Favoured_Soul_Lesser_Planar_Ally **** **** **** **** **** **** **** **** +12518 Favoured_Soul_Lower_Spell_Resistance **** **** **** **** **** **** **** **** +12519 Favoured_Soul_Mass_Ultravision **** **** **** **** **** **** **** **** +12520 Favoured_Soul_Necrotic_Domination **** **** **** **** **** **** **** **** +12521 Favoured_Soul_Neutralize_Poison **** **** **** **** **** **** **** **** +12522 Favoured_Soul_Panacea **** **** **** **** **** **** **** **** +12523 Favoured_Soul_Poison **** **** **** **** **** **** **** **** +12524 Favoured_Soul_Recitation **** **** **** **** **** **** **** **** +12525 Favoured_Soul_RepelVermin **** **** **** **** **** **** **** **** +12526 Favoured_Soul_Restoration **** **** **** **** **** **** **** **** +12527 Favoured_Soul_STOP_HEART **** **** **** **** **** **** **** **** +12528 Favoured_Soul_Summon_Creature_IV **** **** **** **** **** **** **** **** +12529 Favoured_Soul_SummonUndeadIV **** **** **** **** **** **** **** **** +12530 Favoured_Soul_SwordOfConscience **** **** **** **** **** **** **** **** +12531 Favoured_Soul_Battletide **** **** **** **** **** **** **** **** +12532 Favoured_Soul_BreakEnchantment **** **** **** **** **** **** **** **** +12533 Favoured_Soul_CHAAVS_LAUGH **** **** **** **** **** **** **** **** +12534 Favoured_Soul_Circle_of_Doom **** **** **** **** **** **** **** **** +12535 Favoured_Soul_CONVERT_WAND **** **** **** **** **** **** **** **** +12536 Favoured_Soul_DANCING_WEB **** **** **** **** **** **** **** **** +12537 Favoured_Soul_FireInTheBlood **** **** **** **** **** **** **** **** +12538 Favoured_Soul_Flame_Strike **** **** **** **** **** **** **** **** +12539 Favoured_Soul_Greater_Vigor(Monstrous_Regeneration) **** **** **** **** **** **** **** **** +12540 Favoured_Soul_GreaterCommand_RadialMaster **** **** **** **** **** **** **** **** +12541 Favoured_Soul_GreaterCommand_Approach **** **** **** **** **** **** **** **** +12542 Favoured_Soul_GreaterCommand_Drop **** **** **** **** **** **** **** **** +12543 Favoured_Soul_GreaterCommand_Fall **** **** **** **** **** **** **** **** +12544 Favoured_Soul_GreaterCommand_Flee **** **** **** **** **** **** **** **** +12545 Favoured_Soul_GreaterCommand_Halt **** **** **** **** **** **** **** **** +12546 Favoured_Soul_Healing_Circle **** **** **** **** **** **** **** **** +12547 Favoured_Soul_HEARTCLUTCH **** **** **** **** **** **** **** **** +12548 Favoured_Soul_Legions_Curse_of_Petty_Failing **** **** **** **** **** **** **** **** +12549 Favoured_Soul_Mass_Contagion **** **** **** **** **** **** **** **** +12550 Favoured_Soul_Mass_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12551 Favoured_Soul_Mass_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +12552 Favoured_Soul_MORALITY_UNDONE **** **** **** **** **** **** **** **** +12553 Favoured_Soul_Necrotic_Burst **** **** **** **** **** **** **** **** +12554 Favoured_Soul_Raise_Dead **** **** **** **** **** **** **** **** +12555 Favoured_Soul_RESONATING_RESISTANCE **** **** **** **** **** **** **** **** +12556 Favoured_Soul_Revivify **** **** **** **** **** **** **** **** +12557 Favoured_Soul_Righteous_Might **** **** **** **** **** **** **** **** +12558 Favoured_Soul_Scrying **** **** **** **** **** **** **** **** +12559 Favoured_Soul_Slay_Living **** **** **** **** **** **** **** **** +12560 Favoured_Soul_Soulscour **** **** **** **** **** **** **** **** +12561 Favoured_Soul_Spell_Resistance **** **** **** **** **** **** **** **** +12562 Favoured_Soul_Summon_Creature_V **** **** **** **** **** **** **** **** +12563 Favoured_Soul_SummonUndeadV **** **** **** **** **** **** **** **** +12564 Favoured_Soul_SYMBOL_OF_PAIN **** **** **** **** **** **** **** **** +12565 Favoured_Soul_SYMBOL_OF_SLEEP **** **** **** **** **** **** **** **** +12566 Favoured_Soul_True_Seeing **** **** **** **** **** **** **** **** +12567 Favoured_Soul_Animate_Object **** **** **** **** **** **** **** **** +12568 Favoured_Soul_Banishment **** **** **** **** **** **** **** **** +12569 Favoured_Soul_Blade_Barrier **** **** **** **** **** **** **** **** +12570 Favoured_Soul_CALL_FAITHFUL_SERVANTS **** **** **** **** **** **** **** **** +12571 Favoured_Soul_CELESTIAL_BLOOD **** **** **** **** **** **** **** **** +12572 Favoured_Soul_CLOUD_OF_THE_ACHAIERAI **** **** **** **** **** **** **** **** +12573 Favoured_Soul_Control_Undead **** **** **** **** **** **** **** **** +12574 Favoured_Soul_Create_Undead **** **** **** **** **** **** **** **** +12575 Favoured_Soul_Energy_Immunity **** **** **** **** **** **** **** **** +12576 Favoured_Soul_EI_Acid **** **** **** **** **** **** **** **** +12577 Favoured_Soul_EI_Cold **** **** **** **** **** **** **** **** +12578 Favoured_Soul_EI_Elec **** **** **** **** **** **** **** **** +12579 Favoured_Soul_EI_Fire **** **** **** **** **** **** **** **** +12580 Favoured_Soul_EI_Sonic **** **** **** **** **** **** **** **** +12581 Favoured_Soul_Etherealness **** **** **** **** **** **** **** **** +12582 Favoured_Soul_Greater_Dispelling **** **** **** **** **** **** **** **** +12583 Favoured_Soul_Greater_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +12584 Favoured_Soul_Greater_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +12585 Favoured_Soul_Greater_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +12586 Favoured_Soul_Greater_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +12587 Favoured_Soul_Greater_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +12588 Favoured_Soul_Greater_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +12589 Favoured_Soul_Harm **** **** **** **** **** **** **** **** +12590 Favoured_Soul_Heal **** **** **** **** **** **** **** **** +12591 Favoured_Soul_Mass_Bulls_Strength **** **** **** **** **** **** **** **** +12592 Favoured_Soul_Mass_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +12593 Favoured_Soul_Mass_Eagle_Splendor **** **** **** **** **** **** **** **** +12594 Favoured_Soul_Mass_Endurance **** **** **** **** **** **** **** **** +12595 Favoured_Soul_Mass_Foxs_Cunning **** **** **** **** **** **** **** **** +12596 Favoured_Soul_Mass_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +12597 Favoured_Soul_Mass_Owls_Wisdom **** **** **** **** **** **** **** **** +12598 Favoured_Soul_Necrotic_Eruption **** **** **** **** **** **** **** **** +12599 Favoured_Soul_Planar_Ally **** **** **** **** **** **** **** **** +12600 Favoured_Soul_SarcophagusOfStone **** **** **** **** **** **** **** **** +12601 Favoured_Soul_Summon_Creature_VI **** **** **** **** **** **** **** **** +12602 Favoured_Soul_Superior_Resistance **** **** **** **** **** **** **** **** +12603 Favoured_Soul_SYMBOL_OF_FEAR **** **** **** **** **** **** **** **** +12604 Favoured_Soul_SYMBOL_OF_PERSUASION **** **** **** **** **** **** **** **** +12605 Favoured_Soul_THOUSAND_NEEDLES **** **** **** **** **** **** **** **** +12606 Favoured_Soul_Undeath_to_Death **** **** **** **** **** **** **** **** +12607 Favoured_Soul_Vigorous_Circle **** **** **** **** **** **** **** **** +12608 Favoured_Soul_WordOfRecall_RadialMaster **** **** **** **** **** **** **** **** +12609 Favoured_Soul_WordOfRecall_SelfOnly **** **** **** **** **** **** **** **** +12610 Favoured_Soul_WordOfRecall_Party **** **** **** **** **** **** **** **** +12611 Favoured_Soul_Blasphemy **** **** **** **** **** **** **** **** +12612 Favoured_Soul_Control_Weather **** **** **** **** **** **** **** **** +12613 Favoured_Soul_CW_Rain **** **** **** **** **** **** **** **** +12614 Favoured_Soul_CW_Snow **** **** **** **** **** **** **** **** +12615 Favoured_Soul_CW_Clear **** **** **** **** **** **** **** **** +12616 Favoured_Soul_Destruction **** **** **** **** **** **** **** **** +12617 Favoured_Soul_Dictum **** **** **** **** **** **** **** **** +12618 Favoured_Soul_Energy_Ebb **** **** **** **** **** **** **** **** +12619 Favoured_Soul_FIENDISH_CLARITY **** **** **** **** **** **** **** **** +12620 Favoured_Soul_Greater_Harm **** **** **** **** **** **** **** **** +12621 Favoured_Soul_Greater_Restoration **** **** **** **** **** **** **** **** +12622 Favoured_Soul_GreaterScrying **** **** **** **** **** **** **** **** +12623 Favoured_Soul_Holy_Word **** **** **** **** **** **** **** **** +12624 Favoured_Soul_Mass_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +12625 Favoured_Soul_Mass_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +12626 Favoured_Soul_Mass_Spell_Resistance **** **** **** **** **** **** **** **** +12627 Favoured_Soul_Regenerate **** **** **** **** **** **** **** **** +12628 Favoured_Soul_Repulsion **** **** **** **** **** **** **** **** +12629 Favoured_Soul_Resurrection **** **** **** **** **** **** **** **** +12630 Favoured_Soul_RIGHTEOUS_SMITE **** **** **** **** **** **** **** **** +12631 Favoured_Soul_Summon_Creature_VII **** **** **** **** **** **** **** **** +12632 Favoured_Soul_Summon7Air **** **** **** **** **** **** **** **** +12633 Favoured_Soul_Summon7Earth **** **** **** **** **** **** **** **** +12634 Favoured_Soul_Summon7Fire **** **** **** **** **** **** **** **** +12635 Favoured_Soul_Summon7Water **** **** **** **** **** **** **** **** +12636 Favoured_Soul_SYMBOL_OF_STUNING **** **** **** **** **** **** **** **** +12637 Favoured_Soul_SYMBOL_OF_WEAKNESS **** **** **** **** **** **** **** **** +12638 Favoured_Soul_TOMB_OF_LIGHT **** **** **** **** **** **** **** **** +12639 Favoured_Soul_Word_of_Chaos **** **** **** **** **** **** **** **** +12640 Favoured_Soul_WRETCHED_BLIGHT **** **** **** **** **** **** **** **** +12641 Favoured_Soul_ANTIMAGIC_FIELD **** **** **** **** **** **** **** **** +12642 Favoured_Soul_Aura_versus_Alignment **** **** **** **** **** **** **** **** +12643 Favoured_Soul_Unholy_Aura **** **** **** **** **** **** **** **** +12644 Favoured_Soul_Holy_Aura **** **** **** **** **** **** **** **** +12645 Favoured_Soul_BODAK_BIRTH **** **** **** **** **** **** **** **** +12646 Favoured_Soul_Create_Greater_Undead **** **** **** **** **** **** **** **** +12647 Favoured_Soul_Dimensional_Lock **** **** **** **** **** **** **** **** +12648 Favoured_Soul_DiscernLocation **** **** **** **** **** **** **** **** +12649 Favoured_Soul_Earthquake **** **** **** **** **** **** **** **** +12650 Favoured_Soul_Fire_Storm **** **** **** **** **** **** **** **** +12651 Favoured_Soul_Greater_Planar_Ally **** **** **** **** **** **** **** **** +12652 Favoured_Soul_Greater_Wall_of_Dispel_Magic **** **** **** **** **** **** **** **** +12653 Favoured_Soul_Holy_Aura **** **** **** **** **** **** **** **** +12654 Favoured_Soul_LAST_JUDGEMENT **** **** **** **** **** **** **** **** +12655 Favoured_Soul_Mass_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +12656 Favoured_Soul_Mass_Heal **** **** **** **** **** **** **** **** +12657 Favoured_Soul_Mass_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +12658 Favoured_Soul_Necrotic_Empowerment **** **** **** **** **** **** **** **** +12659 Favoured_Soul_Pestilence **** **** **** **** **** **** **** **** +12660 Favoured_Soul_Summon_Creature_VIII **** **** **** **** **** **** **** **** +12661 Favoured_Soul_Summon8Air **** **** **** **** **** **** **** **** +12662 Favoured_Soul_Summon8Earth **** **** **** **** **** **** **** **** +12663 Favoured_Soul_Summon8Fire **** **** **** **** **** **** **** **** +12664 Favoured_Soul_Summon8Water **** **** **** **** **** **** **** **** +12665 Favoured_Soul_Sunbeam **** **** **** **** **** **** **** **** +12666 Favoured_Soul_SYMBOL_OF_DEATH **** **** **** **** **** **** **** **** +12667 Favoured_Soul_SYMBOL_OF_INSANITY **** **** **** **** **** **** **** **** +12668 Favoured_Soul_DESPOIL **** **** **** **** **** **** **** **** +12669 Favoured_Soul_Elder_Glyph_of_Warding_Master **** **** **** **** **** **** **** **** +12670 Favoured_Soul_Elder_Glyph_of_Warding_Acid **** **** **** **** **** **** **** **** +12671 Favoured_Soul_Elder_Glyph_of_Warding_Cold **** **** **** **** **** **** **** **** +12672 Favoured_Soul_Elder_Glyph_of_Warding_Electricity **** **** **** **** **** **** **** **** +12673 Favoured_Soul_Elder_Glyph_of_Warding_Fire **** **** **** **** **** **** **** **** +12674 Favoured_Soul_Elder_Glyph_of_Warding_Sonic **** **** **** **** **** **** **** **** +12675 Favoured_Soul_Energy_Drain **** **** **** **** **** **** **** **** +12676 Favoured_Soul_Gate **** **** **** **** **** **** **** **** +12677 Favoured_Soul_Implosion **** **** **** **** **** **** **** **** +12678 Favoured_Soul_Mass_Harm **** **** **** **** **** **** **** **** +12679 Favoured_Soul_Necrotic_Termination **** **** **** **** **** **** **** **** +12680 Favoured_Soul_PlagueOfUndead **** **** **** **** **** **** **** **** +12681 Favoured_Soul_Storm_of_Vengeance **** **** **** **** **** **** **** **** +12682 Favoured_Soul_Summon_Creature_IX **** **** **** **** **** **** **** **** +12683 Favoured_Soul_Summon9Air **** **** **** **** **** **** **** **** +12684 Favoured_Soul_Summon9Earth **** **** **** **** **** **** **** **** +12685 Favoured_Soul_Summon9Fire **** **** **** **** **** **** **** **** +12686 Favoured_Soul_Summon9Water **** **** **** **** **** **** **** **** +12687 Favoured_Soul_True_Resurrection **** **** **** **** **** **** **** **** +12688 Favoured_Soul_Undeaths_Eternal_Foe **** **** **** **** **** **** **** **** +12689 Favoured_Soul_VileDeath **** **** **** **** **** **** **** **** +12690 Sohei_Bane **** **** **** **** **** **** **** **** +12691 Sohei_Exteneded_Bane **** **** **** **** **** **** **** **** +12692 Sohei_Silent_Bane **** **** **** **** **** **** **** **** +12693 Sohei_Still_Bane **** **** **** **** **** **** **** **** +12694 Sohei_Bless **** **** **** **** **** **** **** **** +12695 Sohei_Exteneded_Bless **** **** **** **** **** **** **** **** +12696 Sohei_Silent_Bless **** **** **** **** **** **** **** **** +12697 Sohei_Still_Bless **** **** **** **** **** **** **** **** +12698 Sohei_Bless_Weapon **** **** **** **** **** **** **** **** +12699 Sohei_Exteneded_Bless_Weapon **** **** **** **** **** **** **** **** +12700 Sohei_Silent_Bless_Weapon **** **** **** **** **** **** **** **** +12701 Sohei_Still_Bless_Weapon **** **** **** **** **** **** **** **** +12702 Sohei_Detect_Chaos **** **** **** **** **** **** **** **** +12703 Sohei_Exteneded_Detect_Chaos **** **** **** **** **** **** **** **** +12704 Sohei_Silent_Detect_Chaos **** **** **** **** **** **** **** **** +12705 Sohei_Still_Detect_Chaos **** **** **** **** **** **** **** **** +12706 Sohei_Detect_Law **** **** **** **** **** **** **** **** +12707 Sohei_Exteneded_Detect_Law **** **** **** **** **** **** **** **** +12708 Sohei_Silent_Detect_Law **** **** **** **** **** **** **** **** +12709 Sohei_Still_Detect_Law **** **** **** **** **** **** **** **** +12710 Sohei_Divine_Favor **** **** **** **** **** **** **** **** +12711 Sohei_Exteneded_Divine_Favor **** **** **** **** **** **** **** **** +12712 Sohei_Silent_Divine_Favor **** **** **** **** **** **** **** **** +12713 Sohei_Still_Divine_Favor **** **** **** **** **** **** **** **** +12714 Sohei_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +12715 Sohei_Exteneded_DIVINE_INSPIRATION **** **** **** **** **** **** **** **** +12716 Sohei_Doom **** **** **** **** **** **** **** **** +12717 Sohei_Exteneded_Doom **** **** **** **** **** **** **** **** +12718 Sohei_Silent_Doom **** **** **** **** **** **** **** **** +12719 Sohei_Still_Doom **** **** **** **** **** **** **** **** +12720 Sohei_Endure_Elements **** **** **** **** **** **** **** **** +12721 Sohei_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +12722 Sohei_Silent_Endure_Elements **** **** **** **** **** **** **** **** +12723 Sohei_Still_Endure_Elements **** **** **** **** **** **** **** **** +12724 Sohei_Magic_Weapon **** **** **** **** **** **** **** **** +12725 Sohei_Exteneded_Magic_Weapon **** **** **** **** **** **** **** **** +12726 Sohei_Silent_Magic_Weapon **** **** **** **** **** **** **** **** +12727 Sohei_Still_Magic_Weapon **** **** **** **** **** **** **** **** +12728 Sohei_Protection_from_Chaos **** **** **** **** **** **** **** **** +12729 Sohei_Exteneded_Protection_from_Chaos **** **** **** **** **** **** **** **** +12730 Sohei_Silent_Protection_from_Chaos **** **** **** **** **** **** **** **** +12731 Sohei_Still_Protection_from_Chaos **** **** **** **** **** **** **** **** +12732 Sohei_Resistance **** **** **** **** **** **** **** **** +12733 Sohei_Exteneded_Resistance **** **** **** **** **** **** **** **** +12734 Sohei_Silent_Resistance **** **** **** **** **** **** **** **** +12735 Sohei_Still_Resistance **** **** **** **** **** **** **** **** +12736 Sohei_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +12737 Sohei_Silent_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +12738 Sohei_Still_SEETHING_EYEBANE **** **** **** **** **** **** **** **** +12739 Sohei_Shield_of_Faith **** **** **** **** **** **** **** **** +12740 Sohei_Exteneded_Shield_of_Faith **** **** **** **** **** **** **** **** +12741 Sohei_Silent_Shield_of_Faith **** **** **** **** **** **** **** **** +12742 Sohei_Still_Shield_of_Faith **** **** **** **** **** **** **** **** +12743 Sohei_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12744 Sohei_Exteneded_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12745 Sohei_Silent_TWILIGHT_LUCK **** **** **** **** **** **** **** **** +12746 Sohei_Virtue **** **** **** **** **** **** **** **** +12747 Sohei_Exteneded_Virtue **** **** **** **** **** **** **** **** +12748 Sohei_Silent_Virtue **** **** **** **** **** **** **** **** +12749 Sohei_Still_Virtue **** **** **** **** **** **** **** **** +12750 Sohei_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12751 Sohei_Empowered_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12752 Sohei_Silent_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12753 Sohei_Still_AYAILLAS_RADIANT_BURST **** **** **** **** **** **** **** **** +12754 Sohei_Bulls_Strength **** **** **** **** **** **** **** **** +12755 Sohei_Empowered_Bulls_Strength **** **** **** **** **** **** **** **** +12756 Sohei_Exteneded_Bulls_Strength **** **** **** **** **** **** **** **** +12757 Sohei_Silent_Bulls_Strength **** **** **** **** **** **** **** **** +12758 Sohei_Still_Bulls_Strength **** **** **** **** **** **** **** **** +12759 Sohei_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +12760 Sohei_Silent_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +12761 Sohei_Still_LAHMS_FINGER_DARTS **** **** **** **** **** **** **** **** +12762 Sohei_Lesser_Restoration **** **** **** **** **** **** **** **** +12763 Sohei_Silent_Lesser_Restoration **** **** **** **** **** **** **** **** +12764 Sohei_Still_Lesser_Restoration **** **** **** **** **** **** **** **** +12765 Sohei_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12766 Sohei_Exteneded_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12767 Sohei_Remove_Paralysis **** **** **** **** **** **** **** **** +12768 Sohei_Silent_Remove_Paralysis **** **** **** **** **** **** **** **** +12769 Sohei_Still_Remove_Paralysis **** **** **** **** **** **** **** **** +12770 Sohei_Resist_Elements **** **** **** **** **** **** **** **** +12771 Sohei_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +12772 Sohei_Silent_Resist_Elements **** **** **** **** **** **** **** **** +12773 Sohei_Still_Resist_Elements **** **** **** **** **** **** **** **** +12774 Sohei_ShieldOther **** **** **** **** **** **** **** **** +12775 Sohei_Exteneded_ShieldOther **** **** **** **** **** **** **** **** +12776 Sohei_Silent_ShieldOther **** **** **** **** **** **** **** **** +12777 Sohei_Still_ShieldOther **** **** **** **** **** **** **** **** +12778 Sohei_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +12779 Sohei_Exteneded_BRILLIANT_EMANATION **** **** **** **** **** **** **** **** +12780 Sohei_Dispel_Magic **** **** **** **** **** **** **** **** +12781 Sohei_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +12782 Sohei_Still_Dispel_Magic **** **** **** **** **** **** **** **** +12783 Sohei_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12784 Sohei_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12785 Sohei_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12786 Sohei_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +12787 Sohei_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12788 Sohei_Silent_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12789 Sohei_Still_HAMMER_OF_RIGHTEOUSNESS **** **** **** **** **** **** **** **** +12790 Sohei_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12791 Sohei_Exteneded_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12792 Sohei_Silent_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12793 Sohei_Still_Magic_Circle_against_Chaos **** **** **** **** **** **** **** **** +12794 Sohei_Prayer **** **** **** **** **** **** **** **** +12795 Sohei_Exteneded_Prayer **** **** **** **** **** **** **** **** +12796 Sohei_Silent_Prayer **** **** **** **** **** **** **** **** +12797 Sohei_Still_Prayer **** **** **** **** **** **** **** **** +12798 Sohei_Protection_from_Elements **** **** **** **** **** **** **** **** +12799 Sohei_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +12800 Sohei_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +12801 Sohei_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +12802 Sohei_RED_FESTER **** **** **** **** **** **** **** **** +12803 Sohei_Silent_RED_FESTER **** **** **** **** **** **** **** **** +12804 Sohei_Still_RED_FESTER **** **** **** **** **** **** **** **** +12805 Sohei_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +12806 Sohei_Silent_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +12807 Sohei_Still_ROTTING_CURSE_OF_URFESTRA **** **** **** **** **** **** **** **** +12808 Sohei_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +12809 Sohei_Silent_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +12810 Sohei_Still_TOUCH_OF_JUIBLEX **** **** **** **** **** **** **** **** +12811 Sohei_ABSORB_STRENGTH **** **** **** **** **** **** **** **** +12812 Sohei_Death_Ward **** **** **** **** **** **** **** **** +12813 Sohei_DIAMOND_SPRAY **** **** **** **** **** **** **** **** +12814 Sohei_Divine_Power **** **** **** **** **** **** **** **** +12815 Sohei_Freedom_of_Movement **** **** **** **** **** **** **** **** +12816 Sohei_GREATER_LUMINOUS_ARMOR **** **** **** **** **** **** **** **** +12817 Sohei_Hammer_of_the_Gods **** **** **** **** **** **** **** **** +12818 Sohei_Neutralize_Poison **** **** **** **** **** **** **** **** +12819 Sohei_Restoration **** **** **** **** **** **** **** **** +12820 Sohei_SUNMANTLE **** **** **** **** **** **** **** **** +12821 Warmage_Acid_Splash **** **** **** **** **** **** **** **** +12822 Warmage_Dancing_Lights **** **** **** **** **** **** **** **** +12823 Warmage_DisruptUndead **** **** **** **** **** **** **** **** +12824 Warmage_Electric_Jolt **** **** **** **** **** **** **** **** +12825 Warmage_Flare **** **** **** **** **** **** **** **** +12826 Warmage_Light **** **** **** **** **** **** **** **** +12827 Warmage_Ray_of_Frost **** **** **** **** **** **** **** **** +12828 Warmage_Bigbys_Tripping_Hand **** **** **** **** **** **** **** **** +12829 Warmage_Burning_Bolt **** **** **** **** **** **** **** **** +12830 Warmage_Burning_Hands **** **** **** **** **** **** **** **** +12831 Warmage_Chill_Touch **** **** **** **** **** **** **** **** +12832 Warmage_FistOfStone **** **** **** **** **** **** **** **** +12833 Warmage_Hail_of_Stone **** **** **** **** **** **** **** **** +12834 Warmage_Horizikauls_Boom **** **** **** **** **** **** **** **** +12835 Warmage_Ice_Dagger **** **** **** **** **** **** **** **** +12836 Warmage_Kelgores_Fire_Bolt **** **** **** **** **** **** **** **** +12837 Warmage_LANTERN_LIGHT **** **** **** **** **** **** **** **** +12838 Warmage_Lesser_Acid_Orb **** **** **** **** **** **** **** **** +12839 Warmage_Lesser_Cold_Orb **** **** **** **** **** **** **** **** +12840 Warmage_Lesser_Electric_Orb **** **** **** **** **** **** **** **** +12841 Warmage_Lesser_Fire_Orb **** **** **** **** **** **** **** **** +12842 Warmage_LESSER_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +12843 Warmage_Lesser_Sonic_Orb **** **** **** **** **** **** **** **** +12844 Warmage_Magic_Missile **** **** **** **** **** **** **** **** +12845 Warmage_Shelgarns_Persistent_Blade **** **** **** **** **** **** **** **** +12846 Warmage_ShockingGrasp **** **** **** **** **** **** **** **** +12847 Warmage_Snillocs_Snowball **** **** **** **** **** **** **** **** +12848 Warmage_TensersFloatingDisk **** **** **** **** **** **** **** **** +12849 Warmage_True_Strike **** **** **** **** **** **** **** **** +12850 Warmage_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +12851 Warmage_Bigbys_Striking_Fist **** **** **** **** **** **** **** **** +12852 Warmage_BladesOfFire **** **** **** **** **** **** **** **** +12853 Warmage_Cloud_of_Bewilderment **** **** **** **** **** **** **** **** +12854 Warmage_Combust **** **** **** **** **** **** **** **** +12855 Warmage_Continual_Flame **** **** **** **** **** **** **** **** +12856 Warmage_Darkness **** **** **** **** **** **** **** **** +12857 Warmage_Fireburst **** **** **** **** **** **** **** **** +12858 Warmage_FireTrap **** **** **** **** **** **** **** **** +12859 Warmage_Flame_Weapon **** **** **** **** **** **** **** **** +12860 Warmage_Gedlees_Electric_Loop **** **** **** **** **** **** **** **** +12861 Warmage_IceKnife **** **** **** **** **** **** **** **** +12862 Warmage_Melfs_Acid_Arrow **** **** **** **** **** **** **** **** +12863 Warmage_Pyrotechnics **** **** **** **** **** **** **** **** +12864 Warmage_Pyrotechnics_Fireworks **** **** **** **** **** **** **** **** +12865 Warmage_Pyrotechnics_Smoke **** **** **** **** **** **** **** **** +12866 Warmage_ScorchingRay **** **** **** **** **** **** **** **** +12867 Warmage_Seeking_Ray **** **** **** **** **** **** **** **** +12868 Warmage_Snillocs_Snowball_Swarm **** **** **** **** **** **** **** **** +12869 Warmage_WhirlingBlade **** **** **** **** **** **** **** **** +12870 Warmage_Daylight **** **** **** **** **** **** **** **** +12871 Warmage_DREAD_WORD **** **** **** **** **** **** **** **** +12872 Warmage_Elemental_Shield **** **** **** **** **** **** **** **** +12873 Warmage_Fireball **** **** **** **** **** **** **** **** +12874 Warmage_Flame_Arrow **** **** **** **** **** **** **** **** +12875 Warmage_Flashburst **** **** **** **** **** **** **** **** +12876 Warmage_Forceblast **** **** **** **** **** **** **** **** +12877 Warmage_Gust_of_Wind **** **** **** **** **** **** **** **** +12878 Warmage_Ice_Burst **** **** **** **** **** **** **** **** +12879 Warmage_Ice_Storm **** **** **** **** **** **** **** **** +12880 Warmage_Lightning_Bolt **** **** **** **** **** **** **** **** +12881 Warmage_PnP_FireShield **** **** **** **** **** **** **** **** +12882 Warmage_PnP_FireShieldRed **** **** **** **** **** **** **** **** +12883 Warmage_PnPFireShieldBlue **** **** **** **** **** **** **** **** +12884 Warmage_Poison **** **** **** **** **** **** **** **** +12885 Warmage_RainbowBlast **** **** **** **** **** **** **** **** +12886 Warmage_RingOfBlades **** **** **** **** **** **** **** **** +12887 Warmage_Scintillating_Sphere **** **** **** **** **** **** **** **** +12888 Warmage_Serpents_Sigh **** **** **** **** **** **** **** **** +12889 Warmage_SS_Bolt_of_Acid **** **** **** **** **** **** **** **** +12890 Warmage_SS_Bolt_of_Lightning **** **** **** **** **** **** **** **** +12891 Warmage_SS_Cone_of_Acid **** **** **** **** **** **** **** **** +12892 Warmage_SS_Cone_of_Cold **** **** **** **** **** **** **** **** +12893 Warmage_SS_Cone_of_Fire **** **** **** **** **** **** **** **** +12894 Warmage_SHIVERING_TOUCH **** **** **** **** **** **** **** **** +12895 Warmage_SleetStorm **** **** **** **** **** **** **** **** +12896 Warmage_Stinking_Cloud **** **** **** **** **** **** **** **** +12897 Warmage_Acid_Orb **** **** **** **** **** **** **** **** +12898 Warmage_Blast_of_Flame **** **** **** **** **** **** **** **** +12899 Warmage_Channeled_Pyroburst **** **** **** **** **** **** **** **** +12900 Warmage_Channeled_Pyroburst_Swift **** **** **** **** **** **** **** **** +12901 Warmage_Channeled_Pyroburst_Standard **** **** **** **** **** **** **** **** +12902 Warmage_Channeled_Pyroburst_Full **** **** **** **** **** **** **** **** +12903 Warmage_Channeled_Pyroburst_Two **** **** **** **** **** **** **** **** +12904 Warmage_Cold_Orb **** **** **** **** **** **** **** **** +12905 Warmage_Contagion **** **** **** **** **** **** **** **** +12906 Warmage_DAMNING_DARKNESS **** **** **** **** **** **** **** **** +12907 Warmage_DANCING_WEB **** **** **** **** **** **** **** **** +12908 Warmage_Electric_Orb **** **** **** **** **** **** **** **** +12909 Warmage_Evards_Black_Tentacles **** **** **** **** **** **** **** **** +12910 Warmage_Fire_Orb **** **** **** **** **** **** **** **** +12911 Warmage_Isaacs_Lesser_Missile_Storm **** **** **** **** **** **** **** **** +12912 Warmage_OrbOfForce **** **** **** **** **** **** **** **** +12913 Warmage_Otilukes_Resilient_Sphere **** **** **** **** **** **** **** **** +12914 Warmage_Phantasmal_Killer **** **** **** **** **** **** **** **** +12915 Warmage_Shout **** **** **** **** **** **** **** **** +12916 Warmage_Sonic_Orb **** **** **** **** **** **** **** **** +12917 Warmage_Wall_of_Fire **** **** **** **** **** **** **** **** +12918 Warmage_Ball_Lightning **** **** **** **** **** **** **** **** +12919 Warmage_Bigbys_Interposing_Hand **** **** **** **** **** **** **** **** +12920 Warmage_Cloudkill **** **** **** **** **** **** **** **** +12921 Warmage_Cone_of_Cold **** **** **** **** **** **** **** **** +12922 Warmage_Firebrand **** **** **** **** **** **** **** **** +12923 Warmage_Flame_Strike **** **** **** **** **** **** **** **** +12924 Warmage_Greater_Fireburst **** **** **** **** **** **** **** **** +12925 Warmage_Magic_Missile **** **** **** **** **** **** **** **** +12926 Warmage_MassFireShield **** **** **** **** **** **** **** **** +12927 Warmage_MassFireShieldRed **** **** **** **** **** **** **** **** +12928 Warmage_MassFireShieldBlue **** **** **** **** **** **** **** **** +12929 Warmage_PrismaticRay **** **** **** **** **** **** **** **** +12930 Warmage_Sonic_Shield **** **** **** **** **** **** **** **** +12931 Warmage_Acid_Fog **** **** **** **** **** **** **** **** +12932 Warmage_Acid_Storm **** **** **** **** **** **** **** **** +12933 Warmage_Bigbys_Forceful_Hand **** **** **** **** **** **** **** **** +12934 Warmage_Blade_Barrier **** **** **** **** **** **** **** **** +12935 Warmage_Chain_Lightning **** **** **** **** **** **** **** **** +12936 Warmage_Circle_of_Death **** **** **** **** **** **** **** **** +12937 Warmage_Disintegrate **** **** **** **** **** **** **** **** +12938 Warmage_Isaacs_Greater_Missile_Storm **** **** **** **** **** **** **** **** +12939 Warmage_OtilukesFreezingSphere **** **** **** **** **** **** **** **** +12940 Warmage_Tensers_Transformation **** **** **** **** **** **** **** **** +12941 Warmage_AMBER_SARCOPHAGUS **** **** **** **** **** **** **** **** +12942 Warmage_Bigbys_Grasping_Hand **** **** **** **** **** **** **** **** +12943 Warmage_Delayed_Blast_Fireball **** **** **** **** **** **** **** **** +12944 Warmage_Earthquake **** **** **** **** **** **** **** **** +12945 Warmage_Finger_of_Death **** **** **** **** **** **** **** **** +12946 Warmage_Fire_Storm **** **** **** **** **** **** **** **** +12947 Warmage_Great_Thunderclap **** **** **** **** **** **** **** **** +12948 Warmage_Prismatic_Spray **** **** **** **** **** **** **** **** +12949 Warmage_Sunbeam **** **** **** **** **** **** **** **** +12950 Warmage_WavesOfExhaustion **** **** **** **** **** **** **** **** +12951 Warmage_Bigbys_Clenched_Fist **** **** **** **** **** **** **** **** +12952 Warmage_Flensing **** **** **** **** **** **** **** **** +12953 Warmage_Greater_Shout **** **** **** **** **** **** **** **** +12954 Warmage_Horrid_Wilting **** **** **** **** **** **** **** **** +12955 Warmage_Incendiary_Cloud **** **** **** **** **** **** **** **** +12956 Warmage_PolarRay **** **** **** **** **** **** **** **** +12957 Warmage_PrismaticWall **** **** **** **** **** **** **** **** +12958 Warmage_ScintillatingPattern **** **** **** **** **** **** **** **** +12959 Warmage_Sunburst **** **** **** **** **** **** **** **** +12960 Warmage_Bigbys_Crushing_Hand **** **** **** **** **** **** **** **** +12961 Warmage_CRUSHING_FIST_OF_SPITE **** **** **** **** **** **** **** **** +12962 Warmage_Elemental_Swarm **** **** **** **** **** **** **** **** +12963 Warmage_Implosion **** **** **** **** **** **** **** **** +12964 Warmage_Meteor_Swarm **** **** **** **** **** **** **** **** +12965 Warmage_PrismaticSphere **** **** **** **** **** **** **** **** +12966 Warmage_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +12967 Warmage_Weird **** **** **** **** **** **** **** **** +12968 NentyarHunter_Barkskin **** **** **** **** **** **** **** **** +12969 NentyarHunter_Exteneded_Barkskin **** **** **** **** **** **** **** **** +12970 NentyarHunter_Quickened_Barkskin **** **** **** **** **** **** **** **** +12971 NentyarHunter_Silent_Barkskin **** **** **** **** **** **** **** **** +12972 NentyarHunter_Still_Barkskin **** **** **** **** **** **** **** **** +12973 NentyarHunter_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12974 NentyarHunter_Empowered_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12975 NentyarHunter_Maximized_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12976 NentyarHunter_Quickened_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12977 NentyarHunter_Silent_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12978 NentyarHunter_Still_Cure_Light_Wounds **** **** **** **** **** **** **** **** +12979 NentyarHunter_Entangle **** **** **** **** **** **** **** **** +12980 NentyarHunter_Exteneded_Entangle **** **** **** **** **** **** **** **** +12981 NentyarHunter_Quickened_Entangle **** **** **** **** **** **** **** **** +12982 NentyarHunter_Silent_Entangle **** **** **** **** **** **** **** **** +12983 NentyarHunter_Still_Entangle **** **** **** **** **** **** **** **** +12984 NentyarHunter_Spell_Jump **** **** **** **** **** **** **** **** +12985 NentyarHunter_Exteneded_Spell_Jump **** **** **** **** **** **** **** **** +12986 NentyarHunter_Quickened_Spell_Jump **** **** **** **** **** **** **** **** +12987 NentyarHunter_Silent_Spell_Jump **** **** **** **** **** **** **** **** +12988 NentyarHunter_Still_Spell_Jump **** **** **** **** **** **** **** **** +12989 NentyarHunter_Light **** **** **** **** **** **** **** **** +12990 NentyarHunter_Exteneded_Light **** **** **** **** **** **** **** **** +12991 NentyarHunter_Quickened_Light **** **** **** **** **** **** **** **** +12992 NentyarHunter_Silent_Light **** **** **** **** **** **** **** **** +12993 NentyarHunter_Magic_Missile **** **** **** **** **** **** **** **** +12994 NentyarHunter_Empowered_Magic_Missile **** **** **** **** **** **** **** **** +12995 NentyarHunter_Maximized_Magic_Missile **** **** **** **** **** **** **** **** +12996 NentyarHunter_Quickened_Magic_Missile **** **** **** **** **** **** **** **** +12997 NentyarHunter_Silent_Magic_Missile **** **** **** **** **** **** **** **** +12998 NentyarHunter_Still_Magic_Missile **** **** **** **** **** **** **** **** +12999 NentyarHunter_Snare **** **** **** **** **** **** **** **** +13000 NentyarHunter_Quickened_Snare **** **** **** **** **** **** **** **** +13001 NentyarHunter_Silent_Snare **** **** **** **** **** **** **** **** +13002 NentyarHunter_Still_Snare **** **** **** **** **** **** **** **** +13003 NentyarHunter_True_Strike **** **** **** **** **** **** **** **** +13004 NentyarHunter_Quickened_True_Strike **** **** **** **** **** **** **** **** +13005 NentyarHunter_Silent_True_Strike **** **** **** **** **** **** **** **** +13006 NentyarHunter_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +13007 NentyarHunter_Empowered_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +13008 NentyarHunter_Maximized_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +13009 NentyarHunter_Silent_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +13010 NentyarHunter_Still_Agnazzars_Scorcher **** **** **** **** **** **** **** **** +13011 NentyarHunter_Blur **** **** **** **** **** **** **** **** +13012 NentyarHunter_Exteneded_Blur **** **** **** **** **** **** **** **** +13013 NentyarHunter_Silent_Blur **** **** **** **** **** **** **** **** +13014 NentyarHunter_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +13015 NentyarHunter_Empowered_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +13016 NentyarHunter_Maximized_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +13017 NentyarHunter_Silent_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +13018 NentyarHunter_Still_Cure_Moderate_Wounds **** **** **** **** **** **** **** **** +13019 NentyarHunter_Gust_of_Wind **** **** **** **** **** **** **** **** +13020 NentyarHunter_Silent_Gust_of_Wind **** **** **** **** **** **** **** **** +13021 NentyarHunter_Still_Gust_of_Wind **** **** **** **** **** **** **** **** +13022 NentyarHunter_Neutralize_Poison **** **** **** **** **** **** **** **** +13023 NentyarHunter_Silent_Neutralize_Poison **** **** **** **** **** **** **** **** +13024 NentyarHunter_Still_Neutralize_Poison **** **** **** **** **** **** **** **** +13025 NentyarHunter_Remove_Disease **** **** **** **** **** **** **** **** +13026 NentyarHunter_Silent_Remove_Disease **** **** **** **** **** **** **** **** +13027 NentyarHunter_Still_Remove_Disease **** **** **** **** **** **** **** **** +13028 NentyarHunter_Resist_Elements **** **** **** **** **** **** **** **** +13029 NentyarHunter_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +13030 NentyarHunter_Silent_Resist_Elements **** **** **** **** **** **** **** **** +13031 NentyarHunter_Still_Resist_Elements **** **** **** **** **** **** **** **** +13032 NentyarHunter_Treeshape **** **** **** **** **** **** **** **** +13033 NentyarHunter_Exteneded_Treeshape **** **** **** **** **** **** **** **** +13034 NentyarHunter_Silent_Treeshape **** **** **** **** **** **** **** **** +13035 NentyarHunter_Still_Treeshape **** **** **** **** **** **** **** **** +13036 NentyarHunter_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +13037 NentyarHunter_Empowered_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +13038 NentyarHunter_Silent_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +13039 NentyarHunter_Still_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +13040 NentyarHunter_Freedom_of_Movement **** **** **** **** **** **** **** **** +13041 NentyarHunter_Exteneded_Freedom_of_Movement **** **** **** **** **** **** **** **** +13042 NentyarHunter_Silent_Freedom_of_Movement **** **** **** **** **** **** **** **** +13043 NentyarHunter_Still_Freedom_of_Movement **** **** **** **** **** **** **** **** +13044 NentyarHunter_Greenfire **** **** **** **** **** **** **** **** +13045 NentyarHunter_Empowered_Greenfire **** **** **** **** **** **** **** **** +13046 NentyarHunter_Exteneded_Greenfire **** **** **** **** **** **** **** **** +13047 NentyarHunter_Silent_Greenfire **** **** **** **** **** **** **** **** +13048 NentyarHunter_Still_Greenfire **** **** **** **** **** **** **** **** +13049 NentyarHunter_Invisibility **** **** **** **** **** **** **** **** +13050 NentyarHunter_Exteneded_Invisibility **** **** **** **** **** **** **** **** +13051 NentyarHunter_Silent_Invisibility **** **** **** **** **** **** **** **** +13052 NentyarHunter_Still_Invisibility **** **** **** **** **** **** **** **** +13053 NentyarHunter_Keen_Edge **** **** **** **** **** **** **** **** +13054 NentyarHunter_Exteneded_Keen_Edge **** **** **** **** **** **** **** **** +13055 NentyarHunter_Silent_Keen_Edge **** **** **** **** **** **** **** **** +13056 NentyarHunter_Still_Keen_Edge **** **** **** **** **** **** **** **** +13057 NentyarHunter_See_Invisibility **** **** **** **** **** **** **** **** +13058 NentyarHunter_Exteneded_See_Invisibility **** **** **** **** **** **** **** **** +13059 NentyarHunter_Silent_See_Invisibility **** **** **** **** **** **** **** **** +13060 NentyarHunter_Still_See_Invisibility **** **** **** **** **** **** **** **** +13061 NentyarHunter_BreakEnchantment **** **** **** **** **** **** **** **** +13062 NentyarHunter_Silent_BreakEnchantment **** **** **** **** **** **** **** **** +13063 NentyarHunter_Still_BreakEnchantment **** **** **** **** **** **** **** **** +13064 NentyarHunter_OrbOfForce **** **** **** **** **** **** **** **** +13065 NentyarHunter_Silent_OrbOfForce **** **** **** **** **** **** **** **** +13066 NentyarHunter_Still_OrbOfForce **** **** **** **** **** **** **** **** +13067 NentyarHunter_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +13068 NentyarHunter_Exteneded_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +13069 NentyarHunter_Silent_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +13070 NentyarHunter_Still_Greater_Magic_Weapon **** **** **** **** **** **** **** **** +13071 NentyarHunter_Flame_Strike **** **** **** **** **** **** **** **** +13072 NentyarHunter_Healing_Circle **** **** **** **** **** **** **** **** +13073 NentyarHunter_Righteous_Might **** **** **** **** **** **** **** **** +13074 Blighter_Flare **** **** **** **** **** **** **** **** +13075 Blighter_Exteneded_Flare **** **** **** **** **** **** **** **** +13076 Blighter_Quickened_Flare **** **** **** **** **** **** **** **** +13077 Blighter_Silent_Flare **** **** **** **** **** **** **** **** +13078 Blighter_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +13079 Blighter_Quickened_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +13080 Blighter_Silent_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +13081 Blighter_Still_Inflict_Minor_Wounds **** **** **** **** **** **** **** **** +13082 Blighter_Read_Magic **** **** **** **** **** **** **** **** +13083 Blighter_Quickened_Read_Magic **** **** **** **** **** **** **** **** +13084 Blighter_Silent_Read_Magic **** **** **** **** **** **** **** **** +13085 Blighter_Still_Read_Magic **** **** **** **** **** **** **** **** +13086 Blighter_Bane **** **** **** **** **** **** **** **** +13087 Blighter_Exteneded_Bane **** **** **** **** **** **** **** **** +13088 Blighter_Quickened_Bane **** **** **** **** **** **** **** **** +13089 Blighter_Silent_Bane **** **** **** **** **** **** **** **** +13090 Blighter_Still_Bane **** **** **** **** **** **** **** **** +13091 Blighter_Burning_Hands **** **** **** **** **** **** **** **** +13092 Blighter_Empowered_Burning_Hands **** **** **** **** **** **** **** **** +13093 Blighter_Maximized_Burning_Hands **** **** **** **** **** **** **** **** +13094 Blighter_Quickened_Burning_Hands **** **** **** **** **** **** **** **** +13095 Blighter_Silent_Burning_Hands **** **** **** **** **** **** **** **** +13096 Blighter_Still_Burning_Hands **** **** **** **** **** **** **** **** +13097 Blighter_DETECT_UNDEAD **** **** **** **** **** **** **** **** +13098 Blighter_Exteneded_DETECT_UNDEAD **** **** **** **** **** **** **** **** +13099 Blighter_Quickened_DETECT_UNDEAD **** **** **** **** **** **** **** **** +13100 Blighter_Silent_DETECT_UNDEAD **** **** **** **** **** **** **** **** +13101 Blighter_Still_DETECT_UNDEAD **** **** **** **** **** **** **** **** +13102 Blighter_Doom **** **** **** **** **** **** **** **** +13103 Blighter_Exteneded_Doom **** **** **** **** **** **** **** **** +13104 Blighter_Quickened_Doom **** **** **** **** **** **** **** **** +13105 Blighter_Silent_Doom **** **** **** **** **** **** **** **** +13106 Blighter_Still_Doom **** **** **** **** **** **** **** **** +13107 Blighter_Endure_Elements **** **** **** **** **** **** **** **** +13108 Blighter_Exteneded_Endure_Elements **** **** **** **** **** **** **** **** +13109 Blighter_Quickened_Endure_Elements **** **** **** **** **** **** **** **** +13110 Blighter_Silent_Endure_Elements **** **** **** **** **** **** **** **** +13111 Blighter_Still_Endure_Elements **** **** **** **** **** **** **** **** +13112 Blighter_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13113 Blighter_Empowered_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13114 Blighter_Exteneded_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13115 Blighter_Maximized_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13116 Blighter_Quickened_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13117 Blighter_Silent_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13118 Blighter_Still_Ray_of_Enfeeblement **** **** **** **** **** **** **** **** +13119 Blighter_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13120 Blighter_Empowered_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13121 Blighter_Maximized_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13122 Blighter_Quickened_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13123 Blighter_Silent_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13124 Blighter_Still_Inflict_Light_Wounds **** **** **** **** **** **** **** **** +13125 Blighter_Chill_Touch **** **** **** **** **** **** **** **** +13126 Blighter_Empowered_Chill_Touch **** **** **** **** **** **** **** **** +13127 Blighter_Exteneded_Chill_Touch **** **** **** **** **** **** **** **** +13128 Blighter_Maximized_Chill_Touch **** **** **** **** **** **** **** **** +13129 Blighter_Quickened_Chill_Touch **** **** **** **** **** **** **** **** +13130 Blighter_Silent_Chill_Touch **** **** **** **** **** **** **** **** +13131 Blighter_Still_Chill_Touch **** **** **** **** **** **** **** **** +13132 Blighter_Darkness **** **** **** **** **** **** **** **** +13133 Blighter_Exteneded_Darkness **** **** **** **** **** **** **** **** +13134 Blighter_Quickened_Darkness **** **** **** **** **** **** **** **** +13135 Blighter_Silent_Darkness **** **** **** **** **** **** **** **** +13136 Blighter_Death_Knell **** **** **** **** **** **** **** **** +13137 Blighter_Empowered_Death_Knell **** **** **** **** **** **** **** **** +13138 Blighter_Exteneded_Death_Knell **** **** **** **** **** **** **** **** +13139 Blighter_Maximized_Death_Knell **** **** **** **** **** **** **** **** +13140 Blighter_Quickened_Death_Knell **** **** **** **** **** **** **** **** +13141 Blighter_Silent_Death_Knell **** **** **** **** **** **** **** **** +13142 Blighter_Still_Death_Knell **** **** **** **** **** **** **** **** +13143 Blighter_FireTrap **** **** **** **** **** **** **** **** +13144 Blighter_Empowered_FireTrap **** **** **** **** **** **** **** **** +13145 Blighter_Maximized_FireTrap **** **** **** **** **** **** **** **** +13146 Blighter_Quickened_FireTrap **** **** **** **** **** **** **** **** +13147 Blighter_Silent_FireTrap **** **** **** **** **** **** **** **** +13148 Blighter_Still_FireTrap **** **** **** **** **** **** **** **** +13149 Blighter_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13150 Blighter_Empowered_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13151 Blighter_Maximized_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13152 Blighter_Quickened_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13153 Blighter_Silent_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13154 Blighter_Still_Inflict_Moderate_Wounds **** **** **** **** **** **** **** **** +13155 Blighter_Resist_Elements **** **** **** **** **** **** **** **** +13156 Blighter_Exteneded_Resist_Elements **** **** **** **** **** **** **** **** +13157 Blighter_Quickened_Resist_Elements **** **** **** **** **** **** **** **** +13158 Blighter_Silent_Resist_Elements **** **** **** **** **** **** **** **** +13159 Blighter_Still_Resist_Elements **** **** **** **** **** **** **** **** +13160 Blighter_Contagion **** **** **** **** **** **** **** **** +13161 Blighter_Quickened_Contagion **** **** **** **** **** **** **** **** +13162 Blighter_Silent_Contagion **** **** **** **** **** **** **** **** +13163 Blighter_Still_Contagion **** **** **** **** **** **** **** **** +13164 Blighter_DeeperDarkness **** **** **** **** **** **** **** **** +13165 Blighter_Exteneded_DeeperDarkness **** **** **** **** **** **** **** **** +13166 Blighter_Quickened_DeeperDarkness **** **** **** **** **** **** **** **** +13167 Blighter_Silent_DeeperDarkness **** **** **** **** **** **** **** **** +13168 Blighter_Dispel_Magic **** **** **** **** **** **** **** **** +13169 Blighter_Quickened_Dispel_Magic **** **** **** **** **** **** **** **** +13170 Blighter_Silent_Dispel_Magic **** **** **** **** **** **** **** **** +13171 Blighter_Still_Dispel_Magic **** **** **** **** **** **** **** **** +13172 Blighter_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13173 Blighter_Empowered_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13174 Blighter_Maximized_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13175 Blighter_Quickened_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13176 Blighter_Silent_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13177 Blighter_Still_Inflict_Serious_Wounds **** **** **** **** **** **** **** **** +13178 Blighter_Poison **** **** **** **** **** **** **** **** +13179 Blighter_Empowered_Poison **** **** **** **** **** **** **** **** +13180 Blighter_Maximized_Poison **** **** **** **** **** **** **** **** +13181 Blighter_Quickened_Poison **** **** **** **** **** **** **** **** +13182 Blighter_Silent_Poison **** **** **** **** **** **** **** **** +13183 Blighter_Still_Poison **** **** **** **** **** **** **** **** +13184 Blighter_Protection_from_Elements **** **** **** **** **** **** **** **** +13185 Blighter_Exteneded_Protection_from_Elements **** **** **** **** **** **** **** **** +13186 Blighter_Quickened_Protection_from_Elements **** **** **** **** **** **** **** **** +13187 Blighter_Silent_Protection_from_Elements **** **** **** **** **** **** **** **** +13188 Blighter_Still_Protection_from_Elements **** **** **** **** **** **** **** **** +13189 Blighter_Stinking_Cloud **** **** **** **** **** **** **** **** +13190 Blighter_Exteneded_Stinking_Cloud **** **** **** **** **** **** **** **** +13191 Blighter_Quickened_Stinking_Cloud **** **** **** **** **** **** **** **** +13192 Blighter_Silent_Stinking_Cloud **** **** **** **** **** **** **** **** +13193 Blighter_Still_Stinking_Cloud **** **** **** **** **** **** **** **** +13194 Blighter_Vampiric_Touch **** **** **** **** **** **** **** **** +13195 Blighter_Empowered_Vampiric_Touch **** **** **** **** **** **** **** **** +13196 Blighter_Maximized_Vampiric_Touch **** **** **** **** **** **** **** **** +13197 Blighter_Quickened_Vampiric_Touch **** **** **** **** **** **** **** **** +13198 Blighter_Silent_Vampiric_Touch **** **** **** **** **** **** **** **** +13199 Blighter_Still_Vampiric_Touch **** **** **** **** **** **** **** **** +13200 Blighter_Animate_Dead **** **** **** **** **** **** **** **** +13201 Blighter_Exteneded_Animate_Dead **** **** **** **** **** **** **** **** +13202 Blighter_Quickened_Animate_Dead **** **** **** **** **** **** **** **** +13203 Blighter_Silent_Animate_Dead **** **** **** **** **** **** **** **** +13204 Blighter_Still_Animate_Dead **** **** **** **** **** **** **** **** +13205 Blighter_ContagiousTouch **** **** **** **** **** **** **** **** +13206 Blighter_Quickened_ContagiousTouch **** **** **** **** **** **** **** **** +13207 Blighter_Silent_ContagiousTouch **** **** **** **** **** **** **** **** +13208 Blighter_Still_ContagiousTouch **** **** **** **** **** **** **** **** +13209 Blighter_Death_Ward **** **** **** **** **** **** **** **** +13210 Blighter_Exteneded_Death_Ward **** **** **** **** **** **** **** **** +13211 Blighter_Quickened_Death_Ward **** **** **** **** **** **** **** **** +13212 Blighter_Silent_Death_Ward **** **** **** **** **** **** **** **** +13213 Blighter_Still_Death_Ward **** **** **** **** **** **** **** **** +13214 Blighter_Flame_Strike **** **** **** **** **** **** **** **** +13215 Blighter_Empowered_Flame_Strike **** **** **** **** **** **** **** **** +13216 Blighter_Maximized_Flame_Strike **** **** **** **** **** **** **** **** +13217 Blighter_Quickened_Flame_Strike **** **** **** **** **** **** **** **** +13218 Blighter_Silent_Flame_Strike **** **** **** **** **** **** **** **** +13219 Blighter_Still_Flame_Strike **** **** **** **** **** **** **** **** +13220 Blighter_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13221 Blighter_Empowered_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13222 Blighter_Maximized_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13223 Blighter_Quickened_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13224 Blighter_Silent_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13225 Blighter_Still_Inflict_Critical_Wounds **** **** **** **** **** **** **** **** +13226 Blighter_RepelVermin **** **** **** **** **** **** **** **** +13227 Blighter_Exteneded_RepelVermin **** **** **** **** **** **** **** **** +13228 Blighter_Quickened_RepelVermin **** **** **** **** **** **** **** **** +13229 Blighter_Silent_RepelVermin **** **** **** **** **** **** **** **** +13230 Blighter_Still_RepelVermin **** **** **** **** **** **** **** **** +13231 Blighter_Wall_of_Fire **** **** **** **** **** **** **** **** +13232 Blighter_Empowered_Wall_of_Fire **** **** **** **** **** **** **** **** +13233 Blighter_Exteneded_Wall_of_Fire **** **** **** **** **** **** **** **** +13234 Blighter_Maximized_Wall_of_Fire **** **** **** **** **** **** **** **** +13235 Blighter_Quickened_Wall_of_Fire **** **** **** **** **** **** **** **** +13236 Blighter_Silent_Wall_of_Fire **** **** **** **** **** **** **** **** +13237 Blighter_Still_Wall_of_Fire **** **** **** **** **** **** **** **** +13238 Blighter_Create_Undead **** **** **** **** **** **** **** **** +13239 Blighter_Exteneded_Create_Undead **** **** **** **** **** **** **** **** +13240 Blighter_Quickened_Create_Undead **** **** **** **** **** **** **** **** +13241 Blighter_Silent_Create_Undead **** **** **** **** **** **** **** **** +13242 Blighter_Still_Create_Undead **** **** **** **** **** **** **** **** +13243 Blighter_WavesofFatigue **** **** **** **** **** **** **** **** +13244 Blighter_Quickened_WavesofFatigue **** **** **** **** **** **** **** **** +13245 Blighter_Silent_WavesofFatigue **** **** **** **** **** **** **** **** +13246 Blighter_Still_WavesofFatigue **** **** **** **** **** **** **** **** +13247 Blighter_Acid_Fog **** **** **** **** **** **** **** **** +13248 Blighter_Empowered_Acid_Fog **** **** **** **** **** **** **** **** +13249 Blighter_Exteneded_Acid_Fog **** **** **** **** **** **** **** **** +13250 Blighter_Maximized_Acid_Fog **** **** **** **** **** **** **** **** +13251 Blighter_Silent_Acid_Fog **** **** **** **** **** **** **** **** +13252 Blighter_Still_Acid_Fog **** **** **** **** **** **** **** **** +13253 Blighter_Circle_of_Death **** **** **** **** **** **** **** **** +13254 Blighter_Empowered_Circle_of_Death **** **** **** **** **** **** **** **** +13255 Blighter_Maximized_Circle_of_Death **** **** **** **** **** **** **** **** +13256 Blighter_Silent_Circle_of_Death **** **** **** **** **** **** **** **** +13257 Blighter_Still_Circle_of_Death **** **** **** **** **** **** **** **** +13258 Blighter_Finger_of_Death **** **** **** **** **** **** **** **** +13259 Blighter_Empowered_Finger_of_Death **** **** **** **** **** **** **** **** +13260 Blighter_Maximized_Finger_of_Death **** **** **** **** **** **** **** **** +13261 Blighter_Silent_Finger_of_Death **** **** **** **** **** **** **** **** +13262 Blighter_Still_Finger_of_Death **** **** **** **** **** **** **** **** +13263 Blighter_Greater_Dispelling **** **** **** **** **** **** **** **** +13264 Blighter_Silent_Greater_Dispelling **** **** **** **** **** **** **** **** +13265 Blighter_Still_Greater_Dispelling **** **** **** **** **** **** **** **** +13266 Blighter_Harm **** **** **** **** **** **** **** **** +13267 Blighter_Silent_Harm **** **** **** **** **** **** **** **** +13268 Blighter_Still_Harm **** **** **** **** **** **** **** **** +13269 Blighter_Control_Undead **** **** **** **** **** **** **** **** +13270 Blighter_Exteneded_Control_Undead **** **** **** **** **** **** **** **** +13271 Blighter_Silent_Control_Undead **** **** **** **** **** **** **** **** +13272 Blighter_Still_Control_Undead **** **** **** **** **** **** **** **** +13273 Blighter_Control_Weather **** **** **** **** **** **** **** **** +13274 Blighter_CW_Rain **** **** **** **** **** **** **** **** +13275 Blighter_CW_Snow **** **** **** **** **** **** **** **** +13276 Blighter_CW_Clear **** **** **** **** **** **** **** **** +13277 Blighter_Exteneded_Control_Weather **** **** **** **** **** **** **** **** +13278 Blighter_Exteneded_CW_Rain **** **** **** **** **** **** **** **** +13279 Blighter_Exteneded_CW_Snow **** **** **** **** **** **** **** **** +13280 Blighter_Exteneded_CW_Clear **** **** **** **** **** **** **** **** +13281 Blighter_Silent_Control_Weather **** **** **** **** **** **** **** **** +13282 Blighter_Silent_CW_Rain **** **** **** **** **** **** **** **** +13283 Blighter_Silent_CW_Snow **** **** **** **** **** **** **** **** +13284 Blighter_Silent_CW_Clear **** **** **** **** **** **** **** **** +13285 Blighter_Still_Control_Weather **** **** **** **** **** **** **** **** +13286 Blighter_Still_CW_Rain **** **** **** **** **** **** **** **** +13287 Blighter_Still_CW_Snow **** **** **** **** **** **** **** **** +13288 Blighter_Still_CW_Clear **** **** **** **** **** **** **** **** +13289 Blighter_Earthquake **** **** **** **** **** **** **** **** +13290 Blighter_Exteneded_Earthquake **** **** **** **** **** **** **** **** +13291 Blighter_Silent_Earthquake **** **** **** **** **** **** **** **** +13292 Blighter_Still_Earthquake **** **** **** **** **** **** **** **** +13293 Blighter_Fire_Storm **** **** **** **** **** **** **** **** +13294 Blighter_Empowered_Fire_Storm **** **** **** **** **** **** **** **** +13295 Blighter_Silent_Fire_Storm **** **** **** **** **** **** **** **** +13296 Blighter_Still_Fire_Storm **** **** **** **** **** **** **** **** +13297 Blighter_Repulsion **** **** **** **** **** **** **** **** +13298 Blighter_Exteneded_Repulsion **** **** **** **** **** **** **** **** +13299 Blighter_Silent_Repulsion **** **** **** **** **** **** **** **** +13300 Blighter_Still_Repulsion **** **** **** **** **** **** **** **** +13301 Blighter_Horrid_Wilting **** **** **** **** **** **** **** **** +13302 Blighter_Silent_Horrid_Wilting **** **** **** **** **** **** **** **** +13303 Blighter_Still_Horrid_Wilting **** **** **** **** **** **** **** **** +13304 Blighter_Mind_Blank **** **** **** **** **** **** **** **** +13305 Blighter_Exteneded_Mind_Blank **** **** **** **** **** **** **** **** +13306 Blighter_Silent_Mind_Blank **** **** **** **** **** **** **** **** +13307 Blighter_Still_Mind_Blank **** **** **** **** **** **** **** **** +13308 Blighter_WavesOfExhaustion **** **** **** **** **** **** **** **** +13309 Blighter_Silent_WavesOfExhaustion **** **** **** **** **** **** **** **** +13310 Blighter_Still_WavesOfExhaustion **** **** **** **** **** **** **** **** +13311 Blighter_Foresight **** **** **** **** **** **** **** **** +13312 Blighter_Implosion **** **** **** **** **** **** **** **** +13313 Blighter_Incendiary_Cloud **** **** **** **** **** **** **** **** +13314 Blighter_Storm_of_Vengeance **** **** **** **** **** **** **** **** +13315 **** **** **** **** **** **** **** **** **** +13316 **** **** **** **** **** **** **** **** **** +13317 **** **** **** **** **** **** **** **** **** +13318 **** **** **** **** **** **** **** **** **** +13319 **** **** **** **** **** **** **** **** **** +13320 **** **** **** **** **** **** **** **** **** +13321 **** **** **** **** **** **** **** **** **** +13322 **** **** **** **** **** **** **** **** **** +13323 **** **** **** **** **** **** **** **** **** +13324 **** **** **** **** **** **** **** **** **** +13325 **** **** **** **** **** **** **** **** **** +13326 **** **** **** **** **** **** **** **** **** +13327 **** **** **** **** **** **** **** **** **** +13328 **** **** **** **** **** **** **** **** **** +13329 **** **** **** **** **** **** **** **** **** +13330 **** **** **** **** **** **** **** **** **** +13331 **** **** **** **** **** **** **** **** **** +13332 **** **** **** **** **** **** **** **** **** +13333 **** **** **** **** **** **** **** **** **** +13334 **** **** **** **** **** **** **** **** **** +13335 **** **** **** **** **** **** **** **** **** +13336 **** **** **** **** **** **** **** **** **** +13337 **** **** **** **** **** **** **** **** **** +13338 **** **** **** **** **** **** **** **** **** +13339 **** **** **** **** **** **** **** **** **** +13340 **** **** **** **** **** **** **** **** **** +13341 **** **** **** **** **** **** **** **** **** +13342 **** **** **** **** **** **** **** **** **** +13343 **** **** **** **** **** **** **** **** **** +13344 **** **** **** **** **** **** **** **** **** +13345 **** **** **** **** **** **** **** **** **** +13346 **** **** **** **** **** **** **** **** **** +13347 **** **** **** **** **** **** **** **** **** +13348 **** **** **** **** **** **** **** **** **** +13349 **** **** **** **** **** **** **** **** **** +13350 **** **** **** **** **** **** **** **** **** +13351 **** **** **** **** **** **** **** **** **** +13352 **** **** **** **** **** **** **** **** **** +13353 **** **** **** **** **** **** **** **** **** +13354 **** **** **** **** **** **** **** **** **** +13355 **** **** **** **** **** **** **** **** **** +13356 **** **** **** **** **** **** **** **** **** +13357 **** **** **** **** **** **** **** **** **** +13358 **** **** **** **** **** **** **** **** **** +13359 **** **** **** **** **** **** **** **** **** +13360 **** **** **** **** **** **** **** **** **** +13361 **** **** **** **** **** **** **** **** **** +13362 **** **** **** **** **** **** **** **** **** +13363 **** **** **** **** **** **** **** **** **** +13364 **** **** **** **** **** **** **** **** **** +13365 **** **** **** **** **** **** **** **** **** +13366 **** **** **** **** **** **** **** **** **** +13367 **** **** **** **** **** **** **** **** **** +13368 **** **** **** **** **** **** **** **** **** +13369 **** **** **** **** **** **** **** **** **** +13370 **** **** **** **** **** **** **** **** **** +13371 **** **** **** **** **** **** **** **** **** +13372 **** **** **** **** **** **** **** **** **** +13373 **** **** **** **** **** **** **** **** **** +13374 **** **** **** **** **** **** **** **** **** +13375 **** **** **** **** **** **** **** **** **** +13376 **** **** **** **** **** **** **** **** **** +13377 **** **** **** **** **** **** **** **** **** +13378 **** **** **** **** **** **** **** **** **** +13379 **** **** **** **** **** **** **** **** **** +13380 **** **** **** **** **** **** **** **** **** +13381 **** **** **** **** **** **** **** **** **** +13382 **** **** **** **** **** **** **** **** **** +13383 **** **** **** **** **** **** **** **** **** +13384 **** **** **** **** **** **** **** **** **** +13385 **** **** **** **** **** **** **** **** **** +13386 **** **** **** **** **** **** **** **** **** +13387 **** **** **** **** **** **** **** **** **** +13388 **** **** **** **** **** **** **** **** **** +13389 **** **** **** **** **** **** **** **** **** +13390 **** **** **** **** **** **** **** **** **** +13391 **** **** **** **** **** **** **** **** **** +13392 **** **** **** **** **** **** **** **** **** +13393 **** **** **** **** **** **** **** **** **** +13394 **** **** **** **** **** **** **** **** **** +13395 **** **** **** **** **** **** **** **** **** +13396 **** **** **** **** **** **** **** **** **** +13397 **** **** **** **** **** **** **** **** **** +13398 **** **** **** **** **** **** **** **** **** +13399 **** **** **** **** **** **** **** **** **** +13400 **** **** **** **** **** **** **** **** **** +13401 **** **** **** **** **** **** **** **** **** +13402 **** **** **** **** **** **** **** **** **** +13403 **** **** **** **** **** **** **** **** **** +13404 **** **** **** **** **** **** **** **** **** +13405 **** **** **** **** **** **** **** **** **** +13406 **** **** **** **** **** **** **** **** **** +13407 **** **** **** **** **** **** **** **** **** +13408 **** **** **** **** **** **** **** **** **** +13409 **** **** **** **** **** **** **** **** **** +13410 **** **** **** **** **** **** **** **** **** +13411 **** **** **** **** **** **** **** **** **** +13412 **** **** **** **** **** **** **** **** **** +13413 **** **** **** **** **** **** **** **** **** +13414 **** **** **** **** **** **** **** **** **** +13415 **** **** **** **** **** **** **** **** **** +13416 **** **** **** **** **** **** **** **** **** +13417 **** **** **** **** **** **** **** **** **** +13418 **** **** **** **** **** **** **** **** **** +13419 **** **** **** **** **** **** **** **** **** +13420 **** **** **** **** **** **** **** **** **** +13421 **** **** **** **** **** **** **** **** **** +13422 **** **** **** **** **** **** **** **** **** +13423 **** **** **** **** **** **** **** **** **** +13424 **** **** **** **** **** **** **** **** **** +13425 **** **** **** **** **** **** **** **** **** +13426 **** **** **** **** **** **** **** **** **** +13427 **** **** **** **** **** **** **** **** **** +13428 **** **** **** **** **** **** **** **** **** +13429 **** **** **** **** **** **** **** **** **** +13430 **** **** **** **** **** **** **** **** **** +13431 **** **** **** **** **** **** **** **** **** +13432 **** **** **** **** **** **** **** **** **** +13433 **** **** **** **** **** **** **** **** **** +13434 **** **** **** **** **** **** **** **** **** +13435 **** **** **** **** **** **** **** **** **** +13436 **** **** **** **** **** **** **** **** **** +13437 **** **** **** **** **** **** **** **** **** +13438 **** **** **** **** **** **** **** **** **** +13439 **** **** **** **** **** **** **** **** **** +13440 **** **** **** **** **** **** **** **** **** +13441 **** **** **** **** **** **** **** **** **** +13442 **** **** **** **** **** **** **** **** **** +13443 **** **** **** **** **** **** **** **** **** +13444 **** **** **** **** **** **** **** **** **** +13445 **** **** **** **** **** **** **** **** **** +13446 **** **** **** **** **** **** **** **** **** +13447 **** **** **** **** **** **** **** **** **** +13448 **** **** **** **** **** **** **** **** **** +13449 **** **** **** **** **** **** **** **** **** +13450 **** **** **** **** **** **** **** **** **** +13451 **** **** **** **** **** **** **** **** **** +13452 **** **** **** **** **** **** **** **** **** +13453 **** **** **** **** **** **** **** **** **** +13454 **** **** **** **** **** **** **** **** **** +13455 **** **** **** **** **** **** **** **** **** +13456 **** **** **** **** **** **** **** **** **** +13457 **** **** **** **** **** **** **** **** **** +13458 **** **** **** **** **** **** **** **** **** +13459 **** **** **** **** **** **** **** **** **** +13460 **** **** **** **** **** **** **** **** **** +13461 **** **** **** **** **** **** **** **** **** +13462 **** **** **** **** **** **** **** **** **** +13463 **** **** **** **** **** **** **** **** **** +13464 **** **** **** **** **** **** **** **** **** +13465 **** **** **** **** **** **** **** **** **** +13466 **** **** **** **** **** **** **** **** **** +13467 **** **** **** **** **** **** **** **** **** +13468 **** **** **** **** **** **** **** **** **** +13469 **** **** **** **** **** **** **** **** **** +13470 **** **** **** **** **** **** **** **** **** +13471 **** **** **** **** **** **** **** **** **** +13472 **** **** **** **** **** **** **** **** **** +13473 **** **** **** **** **** **** **** **** **** +13474 **** **** **** **** **** **** **** **** **** +13475 **** **** **** **** **** **** **** **** **** +13476 **** **** **** **** **** **** **** **** **** +13477 **** **** **** **** **** **** **** **** **** +13478 **** **** **** **** **** **** **** **** **** +13479 **** **** **** **** **** **** **** **** **** +13480 **** **** **** **** **** **** **** **** **** +13481 **** **** **** **** **** **** **** **** **** +13482 **** **** **** **** **** **** **** **** **** +13483 **** **** **** **** **** **** **** **** **** +13484 **** **** **** **** **** **** **** **** **** +13485 **** **** **** **** **** **** **** **** **** +13486 **** **** **** **** **** **** **** **** **** +13487 **** **** **** **** **** **** **** **** **** +13488 **** **** **** **** **** **** **** **** **** +13489 **** **** **** **** **** **** **** **** **** +13490 **** **** **** **** **** **** **** **** **** +13491 **** **** **** **** **** **** **** **** **** +13492 **** **** **** **** **** **** **** **** **** +13493 **** **** **** **** **** **** **** **** **** +13494 **** **** **** **** **** **** **** **** **** +13495 **** **** **** **** **** **** **** **** **** +13496 **** **** **** **** **** **** **** **** **** +13497 **** **** **** **** **** **** **** **** **** +13498 **** **** **** **** **** **** **** **** **** +13499 **** **** **** **** **** **** **** **** **** +13500 ####END_OF_NEW_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +13501 ###START_ACP_4_RESERVE **** **** **** **** **** **** **** **** +13502 ACP_Fighting_Stance_QUICK **** **** **** **** **** **** **** **** +13503 ACP_Fighting_Stance_KENSAI **** **** **** **** **** **** **** **** +13504 ACP_Fighting_Stance_ASSASSIN **** **** **** **** **** **** **** **** +13505 ACP_Fighting_Stance_ARCANE **** **** **** **** **** **** **** **** +13506 ACP_Fighting_Stance_FENCING **** **** **** **** **** **** **** **** +13507 ACP_Fighting_Stance_NORMAL **** **** **** **** **** **** **** **** +13508 ACP_Fighting_Stance_HEAVY **** **** **** **** **** **** **** **** +13509 ACP_Fighting_Stance_BARBARIAN **** **** **** **** **** **** **** **** +13510 ACP_Fighting_Stance_DEMONBLADE **** **** **** **** **** **** **** **** +13511 ACP_Fighting_Stance_WARRIOR **** **** **** **** **** **** **** **** +13512 ACP_Fighting_Stance_NORMAL **** **** **** **** **** **** **** **** +13513 ACP_Fighting_Stance_UNARMED **** **** **** **** **** **** **** **** +13514 ACP_Fighting_Stance_TIGERFANG **** **** **** **** **** **** **** **** +13515 ACP_Fighting_Stance_SUNFIST **** **** **** **** **** **** **** **** +13516 ACP_Fighting_Stance_DRAGONPALM **** **** **** **** **** **** **** **** +13517 ACP_Fighting_Stance_BEARCLAW **** **** **** **** **** **** **** **** +13518 ACP_Fighting_Stance_NORMAL **** **** **** **** **** **** **** **** +13519 **** **** **** **** **** **** **** **** **** +13520 **** **** **** **** **** **** **** **** **** +13521 **** **** **** **** **** **** **** **** **** +13522 **** **** **** **** **** **** **** **** **** +13523 **** **** **** **** **** **** **** **** **** +13524 **** **** **** **** **** **** **** **** **** +13525 **** **** **** **** **** **** **** **** **** +13526 **** **** **** **** **** **** **** **** **** +13527 **** **** **** **** **** **** **** **** **** +13528 **** **** **** **** **** **** **** **** **** +13529 **** **** **** **** **** **** **** **** **** +13530 **** **** **** **** **** **** **** **** **** +13531 **** **** **** **** **** **** **** **** **** +13532 **** **** **** **** **** **** **** **** **** +13533 **** **** **** **** **** **** **** **** **** +13534 **** **** **** **** **** **** **** **** **** +13535 **** **** **** **** **** **** **** **** **** +13536 **** **** **** **** **** **** **** **** **** +13537 **** **** **** **** **** **** **** **** **** +13538 **** **** **** **** **** **** **** **** **** +13539 **** **** **** **** **** **** **** **** **** +13540 **** **** **** **** **** **** **** **** **** +13541 **** **** **** **** **** **** **** **** **** +13542 **** **** **** **** **** **** **** **** **** +13543 **** **** **** **** **** **** **** **** **** +13544 **** **** **** **** **** **** **** **** **** +13545 **** **** **** **** **** **** **** **** **** +13546 **** **** **** **** **** **** **** **** **** +13547 **** **** **** **** **** **** **** **** **** +13548 **** **** **** **** **** **** **** **** **** +13549 **** **** **** **** **** **** **** **** **** +13550 **** **** **** **** **** **** **** **** **** +13551 **** **** **** **** **** **** **** **** **** +13552 **** **** **** **** **** **** **** **** **** +13553 **** **** **** **** **** **** **** **** **** +13554 **** **** **** **** **** **** **** **** **** +13555 **** **** **** **** **** **** **** **** **** +13556 **** **** **** **** **** **** **** **** **** +13557 **** **** **** **** **** **** **** **** **** +13558 **** **** **** **** **** **** **** **** **** +13559 **** **** **** **** **** **** **** **** **** +13560 **** **** **** **** **** **** **** **** **** +13561 **** **** **** **** **** **** **** **** **** +13562 **** **** **** **** **** **** **** **** **** +13563 **** **** **** **** **** **** **** **** **** +13564 **** **** **** **** **** **** **** **** **** +13565 **** **** **** **** **** **** **** **** **** +13566 **** **** **** **** **** **** **** **** **** +13567 **** **** **** **** **** **** **** **** **** +13568 **** **** **** **** **** **** **** **** **** +13569 **** **** **** **** **** **** **** **** **** +13570 **** **** **** **** **** **** **** **** **** +13571 **** **** **** **** **** **** **** **** **** +13572 **** **** **** **** **** **** **** **** **** +13573 **** **** **** **** **** **** **** **** **** +13574 **** **** **** **** **** **** **** **** **** +13575 **** **** **** **** **** **** **** **** **** +13576 **** **** **** **** **** **** **** **** **** +13577 **** **** **** **** **** **** **** **** **** +13578 **** **** **** **** **** **** **** **** **** +13579 **** **** **** **** **** **** **** **** **** +13580 **** **** **** **** **** **** **** **** **** +13581 **** **** **** **** **** **** **** **** **** +13582 **** **** **** **** **** **** **** **** **** +13583 **** **** **** **** **** **** **** **** **** +13584 **** **** **** **** **** **** **** **** **** +13585 **** **** **** **** **** **** **** **** **** +13586 **** **** **** **** **** **** **** **** **** +13587 **** **** **** **** **** **** **** **** **** +13588 **** **** **** **** **** **** **** **** **** +13589 **** **** **** **** **** **** **** **** **** +13590 **** **** **** **** **** **** **** **** **** +13591 **** **** **** **** **** **** **** **** **** +13592 **** **** **** **** **** **** **** **** **** +13593 **** **** **** **** **** **** **** **** **** +13594 **** **** **** **** **** **** **** **** **** +13595 **** **** **** **** **** **** **** **** **** +13596 **** **** **** **** **** **** **** **** **** +13597 **** **** **** **** **** **** **** **** **** +13598 **** **** **** **** **** **** **** **** **** +13599 **** **** **** **** **** **** **** **** **** +13600 **** **** **** **** **** **** **** **** **** +13601 **** **** **** **** **** **** **** **** **** +13602 **** **** **** **** **** **** **** **** **** +13603 **** **** **** **** **** **** **** **** **** +13604 **** **** **** **** **** **** **** **** **** +13605 **** **** **** **** **** **** **** **** **** +13606 **** **** **** **** **** **** **** **** **** +13607 **** **** **** **** **** **** **** **** **** +13608 **** **** **** **** **** **** **** **** **** +13609 **** **** **** **** **** **** **** **** **** +13610 **** **** **** **** **** **** **** **** **** +13611 **** **** **** **** **** **** **** **** **** +13612 **** **** **** **** **** **** **** **** **** +13613 **** **** **** **** **** **** **** **** **** +13614 **** **** **** **** **** **** **** **** **** +13615 **** **** **** **** **** **** **** **** **** +13616 **** **** **** **** **** **** **** **** **** +13617 **** **** **** **** **** **** **** **** **** +13618 **** **** **** **** **** **** **** **** **** +13619 **** **** **** **** **** **** **** **** **** +13620 **** **** **** **** **** **** **** **** **** +13621 **** **** **** **** **** **** **** **** **** +13622 **** **** **** **** **** **** **** **** **** +13623 **** **** **** **** **** **** **** **** **** +13624 **** **** **** **** **** **** **** **** **** +13625 **** **** **** **** **** **** **** **** **** +13626 **** **** **** **** **** **** **** **** **** +13627 **** **** **** **** **** **** **** **** **** +13628 **** **** **** **** **** **** **** **** **** +13629 **** **** **** **** **** **** **** **** **** +13630 **** **** **** **** **** **** **** **** **** +13631 **** **** **** **** **** **** **** **** **** +13632 **** **** **** **** **** **** **** **** **** +13633 **** **** **** **** **** **** **** **** **** +13634 **** **** **** **** **** **** **** **** **** +13635 **** **** **** **** **** **** **** **** **** +13636 **** **** **** **** **** **** **** **** **** +13637 **** **** **** **** **** **** **** **** **** +13638 **** **** **** **** **** **** **** **** **** +13639 **** **** **** **** **** **** **** **** **** +13640 **** **** **** **** **** **** **** **** **** +13641 **** **** **** **** **** **** **** **** **** +13642 **** **** **** **** **** **** **** **** **** +13643 **** **** **** **** **** **** **** **** **** +13644 **** **** **** **** **** **** **** **** **** +13645 **** **** **** **** **** **** **** **** **** +13646 **** **** **** **** **** **** **** **** **** +13647 **** **** **** **** **** **** **** **** **** +13648 **** **** **** **** **** **** **** **** **** +13649 **** **** **** **** **** **** **** **** **** +13650 **** **** **** **** **** **** **** **** **** +13651 **** **** **** **** **** **** **** **** **** +13652 **** **** **** **** **** **** **** **** **** +13653 **** **** **** **** **** **** **** **** **** +13654 **** **** **** **** **** **** **** **** **** +13655 **** **** **** **** **** **** **** **** **** +13656 **** **** **** **** **** **** **** **** **** +13657 **** **** **** **** **** **** **** **** **** +13658 **** **** **** **** **** **** **** **** **** +13659 **** **** **** **** **** **** **** **** **** +13660 **** **** **** **** **** **** **** **** **** +13661 **** **** **** **** **** **** **** **** **** +13662 **** **** **** **** **** **** **** **** **** +13663 **** **** **** **** **** **** **** **** **** +13664 **** **** **** **** **** **** **** **** **** +13665 **** **** **** **** **** **** **** **** **** +13666 **** **** **** **** **** **** **** **** **** +13667 **** **** **** **** **** **** **** **** **** +13668 **** **** **** **** **** **** **** **** **** +13669 **** **** **** **** **** **** **** **** **** +13670 **** **** **** **** **** **** **** **** **** +13671 **** **** **** **** **** **** **** **** **** +13672 **** **** **** **** **** **** **** **** **** +13673 **** **** **** **** **** **** **** **** **** +13674 **** **** **** **** **** **** **** **** **** +13675 **** **** **** **** **** **** **** **** **** +13676 **** **** **** **** **** **** **** **** **** +13677 **** **** **** **** **** **** **** **** **** +13678 **** **** **** **** **** **** **** **** **** +13679 **** **** **** **** **** **** **** **** **** +13680 **** **** **** **** **** **** **** **** **** +13681 **** **** **** **** **** **** **** **** **** +13682 **** **** **** **** **** **** **** **** **** +13683 **** **** **** **** **** **** **** **** **** +13684 **** **** **** **** **** **** **** **** **** +13685 **** **** **** **** **** **** **** **** **** +13686 **** **** **** **** **** **** **** **** **** +13687 **** **** **** **** **** **** **** **** **** +13688 **** **** **** **** **** **** **** **** **** +13689 **** **** **** **** **** **** **** **** **** +13690 **** **** **** **** **** **** **** **** **** +13691 **** **** **** **** **** **** **** **** **** +13692 **** **** **** **** **** **** **** **** **** +13693 **** **** **** **** **** **** **** **** **** +13694 **** **** **** **** **** **** **** **** **** +13695 **** **** **** **** **** **** **** **** **** +13696 **** **** **** **** **** **** **** **** **** +13697 **** **** **** **** **** **** **** **** **** +13698 **** **** **** **** **** **** **** **** **** +13699 **** **** **** **** **** **** **** **** **** +13700 **** **** **** **** **** **** **** **** **** +13701 **** **** **** **** **** **** **** **** **** +13702 **** **** **** **** **** **** **** **** **** +13703 **** **** **** **** **** **** **** **** **** +13704 **** **** **** **** **** **** **** **** **** +13705 **** **** **** **** **** **** **** **** **** +13706 **** **** **** **** **** **** **** **** **** +13707 **** **** **** **** **** **** **** **** **** +13708 **** **** **** **** **** **** **** **** **** +13709 **** **** **** **** **** **** **** **** **** +13710 **** **** **** **** **** **** **** **** **** +13711 **** **** **** **** **** **** **** **** **** +13712 **** **** **** **** **** **** **** **** **** +13713 **** **** **** **** **** **** **** **** **** +13714 **** **** **** **** **** **** **** **** **** +13715 **** **** **** **** **** **** **** **** **** +13716 **** **** **** **** **** **** **** **** **** +13717 **** **** **** **** **** **** **** **** **** +13718 **** **** **** **** **** **** **** **** **** +13719 **** **** **** **** **** **** **** **** **** +13720 **** **** **** **** **** **** **** **** **** +13721 **** **** **** **** **** **** **** **** **** +13722 **** **** **** **** **** **** **** **** **** +13723 **** **** **** **** **** **** **** **** **** +13724 **** **** **** **** **** **** **** **** **** +13725 **** **** **** **** **** **** **** **** **** +13726 **** **** **** **** **** **** **** **** **** +13727 **** **** **** **** **** **** **** **** **** +13728 **** **** **** **** **** **** **** **** **** +13729 **** **** **** **** **** **** **** **** **** +13730 **** **** **** **** **** **** **** **** **** +13731 **** **** **** **** **** **** **** **** **** +13732 **** **** **** **** **** **** **** **** **** +13733 **** **** **** **** **** **** **** **** **** +13734 **** **** **** **** **** **** **** **** **** +13735 **** **** **** **** **** **** **** **** **** +13736 **** **** **** **** **** **** **** **** **** +13737 **** **** **** **** **** **** **** **** **** +13738 **** **** **** **** **** **** **** **** **** +13739 **** **** **** **** **** **** **** **** **** +13740 **** **** **** **** **** **** **** **** **** +13741 **** **** **** **** **** **** **** **** **** +13742 **** **** **** **** **** **** **** **** **** +13743 **** **** **** **** **** **** **** **** **** +13744 **** **** **** **** **** **** **** **** **** +13745 **** **** **** **** **** **** **** **** **** +13746 **** **** **** **** **** **** **** **** **** +13747 **** **** **** **** **** **** **** **** **** +13748 **** **** **** **** **** **** **** **** **** +13749 **** **** **** **** **** **** **** **** **** +13750 **** **** **** **** **** **** **** **** **** +13751 **** **** **** **** **** **** **** **** **** +13752 **** **** **** **** **** **** **** **** **** +13753 **** **** **** **** **** **** **** **** **** +13754 **** **** **** **** **** **** **** **** **** +13755 **** **** **** **** **** **** **** **** **** +13756 **** **** **** **** **** **** **** **** **** +13757 **** **** **** **** **** **** **** **** **** +13758 **** **** **** **** **** **** **** **** **** +13759 **** **** **** **** **** **** **** **** **** +13760 **** **** **** **** **** **** **** **** **** +13761 **** **** **** **** **** **** **** **** **** +13762 **** **** **** **** **** **** **** **** **** +13763 **** **** **** **** **** **** **** **** **** +13764 **** **** **** **** **** **** **** **** **** +13765 **** **** **** **** **** **** **** **** **** +13766 **** **** **** **** **** **** **** **** **** +13767 **** **** **** **** **** **** **** **** **** +13768 **** **** **** **** **** **** **** **** **** +13769 **** **** **** **** **** **** **** **** **** +13770 **** **** **** **** **** **** **** **** **** +13771 **** **** **** **** **** **** **** **** **** +13772 **** **** **** **** **** **** **** **** **** +13773 **** **** **** **** **** **** **** **** **** +13774 **** **** **** **** **** **** **** **** **** +13775 **** **** **** **** **** **** **** **** **** +13776 **** **** **** **** **** **** **** **** **** +13777 **** **** **** **** **** **** **** **** **** +13778 **** **** **** **** **** **** **** **** **** +13779 **** **** **** **** **** **** **** **** **** +13780 **** **** **** **** **** **** **** **** **** +13781 **** **** **** **** **** **** **** **** **** +13782 **** **** **** **** **** **** **** **** **** +13783 **** **** **** **** **** **** **** **** **** +13784 **** **** **** **** **** **** **** **** **** +13785 **** **** **** **** **** **** **** **** **** +13786 **** **** **** **** **** **** **** **** **** +13787 **** **** **** **** **** **** **** **** **** +13788 **** **** **** **** **** **** **** **** **** +13789 **** **** **** **** **** **** **** **** **** +13790 **** **** **** **** **** **** **** **** **** +13791 **** **** **** **** **** **** **** **** **** +13792 **** **** **** **** **** **** **** **** **** +13793 **** **** **** **** **** **** **** **** **** +13794 **** **** **** **** **** **** **** **** **** +13795 **** **** **** **** **** **** **** **** **** +13796 **** **** **** **** **** **** **** **** **** +13797 **** **** **** **** **** **** **** **** **** +13798 **** **** **** **** **** **** **** **** **** +13799 **** **** **** **** **** **** **** **** **** +13800 **** **** **** **** **** **** **** **** **** +13801 **** **** **** **** **** **** **** **** **** +13802 **** **** **** **** **** **** **** **** **** +13803 **** **** **** **** **** **** **** **** **** +13804 **** **** **** **** **** **** **** **** **** +13805 **** **** **** **** **** **** **** **** **** +13806 **** **** **** **** **** **** **** **** **** +13807 **** **** **** **** **** **** **** **** **** +13808 **** **** **** **** **** **** **** **** **** +13809 **** **** **** **** **** **** **** **** **** +13810 **** **** **** **** **** **** **** **** **** +13811 **** **** **** **** **** **** **** **** **** +13812 **** **** **** **** **** **** **** **** **** +13813 **** **** **** **** **** **** **** **** **** +13814 **** **** **** **** **** **** **** **** **** +13815 **** **** **** **** **** **** **** **** **** +13816 **** **** **** **** **** **** **** **** **** +13817 **** **** **** **** **** **** **** **** **** +13818 **** **** **** **** **** **** **** **** **** +13819 **** **** **** **** **** **** **** **** **** +13820 **** **** **** **** **** **** **** **** **** +13821 **** **** **** **** **** **** **** **** **** +13822 **** **** **** **** **** **** **** **** **** +13823 **** **** **** **** **** **** **** **** **** +13824 **** **** **** **** **** **** **** **** **** +13825 **** **** **** **** **** **** **** **** **** +13826 **** **** **** **** **** **** **** **** **** +13827 **** **** **** **** **** **** **** **** **** +13828 **** **** **** **** **** **** **** **** **** +13829 **** **** **** **** **** **** **** **** **** +13830 **** **** **** **** **** **** **** **** **** +13831 **** **** **** **** **** **** **** **** **** +13832 **** **** **** **** **** **** **** **** **** +13833 **** **** **** **** **** **** **** **** **** +13834 **** **** **** **** **** **** **** **** **** +13835 **** **** **** **** **** **** **** **** **** +13836 **** **** **** **** **** **** **** **** **** +13837 **** **** **** **** **** **** **** **** **** +13838 **** **** **** **** **** **** **** **** **** +13839 **** **** **** **** **** **** **** **** **** +13840 **** **** **** **** **** **** **** **** **** +13841 **** **** **** **** **** **** **** **** **** +13842 **** **** **** **** **** **** **** **** **** +13843 **** **** **** **** **** **** **** **** **** +13844 **** **** **** **** **** **** **** **** **** +13845 **** **** **** **** **** **** **** **** **** +13846 **** **** **** **** **** **** **** **** **** +13847 **** **** **** **** **** **** **** **** **** +13848 **** **** **** **** **** **** **** **** **** +13849 **** **** **** **** **** **** **** **** **** +13850 **** **** **** **** **** **** **** **** **** +13851 **** **** **** **** **** **** **** **** **** +13852 **** **** **** **** **** **** **** **** **** +13853 **** **** **** **** **** **** **** **** **** +13854 **** **** **** **** **** **** **** **** **** +13855 **** **** **** **** **** **** **** **** **** +13856 **** **** **** **** **** **** **** **** **** +13857 **** **** **** **** **** **** **** **** **** +13858 **** **** **** **** **** **** **** **** **** +13859 **** **** **** **** **** **** **** **** **** +13860 **** **** **** **** **** **** **** **** **** +13861 **** **** **** **** **** **** **** **** **** +13862 **** **** **** **** **** **** **** **** **** +13863 **** **** **** **** **** **** **** **** **** +13864 **** **** **** **** **** **** **** **** **** +13865 **** **** **** **** **** **** **** **** **** +13866 **** **** **** **** **** **** **** **** **** +13867 **** **** **** **** **** **** **** **** **** +13868 **** **** **** **** **** **** **** **** **** +13869 **** **** **** **** **** **** **** **** **** +13870 **** **** **** **** **** **** **** **** **** +13871 **** **** **** **** **** **** **** **** **** +13872 **** **** **** **** **** **** **** **** **** +13873 **** **** **** **** **** **** **** **** **** +13874 **** **** **** **** **** **** **** **** **** +13875 **** **** **** **** **** **** **** **** **** +13876 **** **** **** **** **** **** **** **** **** +13877 **** **** **** **** **** **** **** **** **** +13878 **** **** **** **** **** **** **** **** **** +13879 **** **** **** **** **** **** **** **** **** +13880 **** **** **** **** **** **** **** **** **** +13881 **** **** **** **** **** **** **** **** **** +13882 **** **** **** **** **** **** **** **** **** +13883 **** **** **** **** **** **** **** **** **** +13884 **** **** **** **** **** **** **** **** **** +13885 **** **** **** **** **** **** **** **** **** +13886 **** **** **** **** **** **** **** **** **** +13887 **** **** **** **** **** **** **** **** **** +13888 **** **** **** **** **** **** **** **** **** +13889 **** **** **** **** **** **** **** **** **** +13890 **** **** **** **** **** **** **** **** **** +13891 **** **** **** **** **** **** **** **** **** +13892 **** **** **** **** **** **** **** **** **** +13893 **** **** **** **** **** **** **** **** **** +13894 **** **** **** **** **** **** **** **** **** +13895 **** **** **** **** **** **** **** **** **** +13896 **** **** **** **** **** **** **** **** **** +13897 **** **** **** **** **** **** **** **** **** +13898 **** **** **** **** **** **** **** **** **** +13899 **** **** **** **** **** **** **** **** **** +13900 **** **** **** **** **** **** **** **** **** +13901 **** **** **** **** **** **** **** **** **** +13902 **** **** **** **** **** **** **** **** **** +13903 **** **** **** **** **** **** **** **** **** +13904 **** **** **** **** **** **** **** **** **** +13905 **** **** **** **** **** **** **** **** **** +13906 **** **** **** **** **** **** **** **** **** +13907 **** **** **** **** **** **** **** **** **** +13908 **** **** **** **** **** **** **** **** **** +13909 **** **** **** **** **** **** **** **** **** +13910 **** **** **** **** **** **** **** **** **** +13911 **** **** **** **** **** **** **** **** **** +13912 **** **** **** **** **** **** **** **** **** +13913 **** **** **** **** **** **** **** **** **** +13914 **** **** **** **** **** **** **** **** **** +13915 **** **** **** **** **** **** **** **** **** +13916 **** **** **** **** **** **** **** **** **** +13917 **** **** **** **** **** **** **** **** **** +13918 **** **** **** **** **** **** **** **** **** +13919 **** **** **** **** **** **** **** **** **** +13920 **** **** **** **** **** **** **** **** **** +13921 **** **** **** **** **** **** **** **** **** +13922 **** **** **** **** **** **** **** **** **** +13923 **** **** **** **** **** **** **** **** **** +13924 **** **** **** **** **** **** **** **** **** +13925 **** **** **** **** **** **** **** **** **** +13926 **** **** **** **** **** **** **** **** **** +13927 **** **** **** **** **** **** **** **** **** +13928 **** **** **** **** **** **** **** **** **** +13929 **** **** **** **** **** **** **** **** **** +13930 **** **** **** **** **** **** **** **** **** +13931 **** **** **** **** **** **** **** **** **** +13932 **** **** **** **** **** **** **** **** **** +13933 **** **** **** **** **** **** **** **** **** +13934 **** **** **** **** **** **** **** **** **** +13935 **** **** **** **** **** **** **** **** **** +13936 **** **** **** **** **** **** **** **** **** +13937 **** **** **** **** **** **** **** **** **** +13938 **** **** **** **** **** **** **** **** **** +13939 **** **** **** **** **** **** **** **** **** +13940 **** **** **** **** **** **** **** **** **** +13941 **** **** **** **** **** **** **** **** **** +13942 **** **** **** **** **** **** **** **** **** +13943 **** **** **** **** **** **** **** **** **** +13944 **** **** **** **** **** **** **** **** **** +13945 **** **** **** **** **** **** **** **** **** +13946 **** **** **** **** **** **** **** **** **** +13947 **** **** **** **** **** **** **** **** **** +13948 **** **** **** **** **** **** **** **** **** +13949 **** **** **** **** **** **** **** **** **** +13950 **** **** **** **** **** **** **** **** **** +13951 **** **** **** **** **** **** **** **** **** +13952 **** **** **** **** **** **** **** **** **** +13953 **** **** **** **** **** **** **** **** **** +13954 **** **** **** **** **** **** **** **** **** +13955 **** **** **** **** **** **** **** **** **** +13956 **** **** **** **** **** **** **** **** **** +13957 **** **** **** **** **** **** **** **** **** +13958 **** **** **** **** **** **** **** **** **** +13959 **** **** **** **** **** **** **** **** **** +13960 **** **** **** **** **** **** **** **** **** +13961 **** **** **** **** **** **** **** **** **** +13962 **** **** **** **** **** **** **** **** **** +13963 **** **** **** **** **** **** **** **** **** +13964 **** **** **** **** **** **** **** **** **** +13965 **** **** **** **** **** **** **** **** **** +13966 **** **** **** **** **** **** **** **** **** +13967 **** **** **** **** **** **** **** **** **** +13968 **** **** **** **** **** **** **** **** **** +13969 **** **** **** **** **** **** **** **** **** +13970 **** **** **** **** **** **** **** **** **** +13971 **** **** **** **** **** **** **** **** **** +13972 **** **** **** **** **** **** **** **** **** +13973 **** **** **** **** **** **** **** **** **** +13974 **** **** **** **** **** **** **** **** **** +13975 **** **** **** **** **** **** **** **** **** +13976 **** **** **** **** **** **** **** **** **** +13977 **** **** **** **** **** **** **** **** **** +13978 **** **** **** **** **** **** **** **** **** +13979 **** **** **** **** **** **** **** **** **** +13980 **** **** **** **** **** **** **** **** **** +13981 **** **** **** **** **** **** **** **** **** +13982 **** **** **** **** **** **** **** **** **** +13983 **** **** **** **** **** **** **** **** **** +13984 **** **** **** **** **** **** **** **** **** +13985 **** **** **** **** **** **** **** **** **** +13986 **** **** **** **** **** **** **** **** **** +13987 **** **** **** **** **** **** **** **** **** +13988 **** **** **** **** **** **** **** **** **** +13989 **** **** **** **** **** **** **** **** **** +13990 **** **** **** **** **** **** **** **** **** +13991 **** **** **** **** **** **** **** **** **** +13992 **** **** **** **** **** **** **** **** **** +13993 **** **** **** **** **** **** **** **** **** +13994 **** **** **** **** **** **** **** **** **** +13995 **** **** **** **** **** **** **** **** **** +13996 **** **** **** **** **** **** **** **** **** +13997 **** **** **** **** **** **** **** **** **** +13998 **** **** **** **** **** **** **** **** **** +13999 ####END_OF_NEW_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +14000 **Psionic_Powers** **** **** **** **** **** **** **** **** +14001 Bolt **** **** **** **** **** **** **** **** +14002 CallToMind **** **** **** **** **** **** **** **** +14003 CharmPerson **** **** **** **** **** **** **** **** +14004 CrystalShard **** **** **** **** **** **** **** **** +14005 Daze **** **** **** **** **** **** **** **** +14006 Deceleration **** **** **** **** **** **** **** **** +14007 DefPrecog **** **** **** **** **** **** **** **** +14008 Demoralize **** **** **** **** **** **** **** **** +14009 Disable **** **** **** **** **** **** **** **** +14010 DissipatingTouch **** **** **** **** **** **** **** **** +14011 Distract **** **** **** **** **** **** **** **** +14012 EmptyMind **** **** **** **** **** **** **** **** +14013 Conceal_Thoughts **** **** **** **** **** **** **** **** +14014 EnergyRay_Cold **** **** **** **** **** **** **** **** +14015 EnergyRay_Elec **** **** **** **** **** **** **** **** +14016 EnergyRay_Fire **** **** **** **** **** **** **** **** +14017 EnergyRay_Sonic **** **** **** **** **** **** **** **** +14018 EntanglingEctoplasm **** **** **** **** **** **** **** **** +14019 ForceScreen **** **** **** **** **** **** **** **** +14020 Grease **** **** **** **** **** **** **** **** +14021 Hammer **** **** **** **** **** **** **** **** +14022 InertialArmour **** **** **** **** **** **** **** **** +14023 MindThrust **** **** **** **** **** **** **** **** +14024 MyLight **** **** **** **** **** **** **** **** +14025 OffPrecog **** **** **** **** **** **** **** **** +14026 OffPresc **** **** **** **** **** **** **** **** +14027 Stomp **** **** **** **** **** **** **** **** +14028 Synesthete **** **** **** **** **** **** **** **** +14029 ThickSkin **** **** **** **** **** **** **** **** +14030 Vigor **** **** **** **** **** **** **** **** +14031 Empathy **** **** **** **** **** **** **** **** +14032 Far_Hand **** **** **** **** **** **** **** **** +14033 Matter_Agitation **** **** **** **** **** **** **** **** +14034 Skate **** **** **** **** **** **** **** **** +14035 Telempathic_Projection **** **** **** **** **** **** **** **** +14036 AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +14037 AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +14038 AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +14039 AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +14040 AstralConstruct_Conversation **** **** **** **** **** **** **** **** +14041 Burst **** **** **** **** **** **** **** **** +14042 DestinyDissonance **** **** **** **** **** **** **** **** +14043 PrecognitionMain **** **** **** **** **** **** **** **** +14044 PrecognitionAttack **** **** **** **** **** **** **** **** +14045 PrecognitionDamage **** **** **** **** **** **** **** **** +14046 PrecognitionSaves **** **** **** **** **** **** **** **** +14047 PrecognitionSkills **** **** **** **** **** **** **** **** +14048 BiteOfTheWolf **** **** **** **** **** **** **** **** +14049 ClawsOfTheBeast **** **** **** **** **** **** **** **** +14050 CreateSound **** **** **** **** **** **** **** **** +14051 BestowPower **** **** **** **** **** **** **** **** +14052 Biofeedback **** **** **** **** **** **** **** **** +14053 BrainLock **** **** **** **** **** **** **** **** +14054 ConcBlast **** **** **** **** **** **** **** **** +14055 ConcealAmorpha **** **** **** **** **** **** **** **** +14056 SwarmOfCrystals **** **** **** **** **** **** **** **** +14057 DissolvingTouch **** **** **** **** **** **** **** **** +14058 EgoWhip **** **** **** **** **** **** **** **** +14059 ElfSight **** **** **** **** **** **** **** **** +14060 EnergyAdaptAcid **** **** **** **** **** **** **** **** +14061 EnergyAdaptCold **** **** **** **** **** **** **** **** +14062 EnergyAdaptElec **** **** **** **** **** **** **** **** +14063 EnergyAdaptFire **** **** **** **** **** **** **** **** +14064 EnergyAdaptSonic **** **** **** **** **** **** **** **** +14065 Body_Equilibrium **** **** **** **** **** **** **** **** +14066 PainfulStrike **** **** **** **** **** **** **** **** +14067 EnergyPush_Cold **** **** **** **** **** **** **** **** +14068 EnergyPush_Elec **** **** **** **** **** **** **** **** +14069 EnergyPush_Fire **** **** **** **** **** **** **** **** +14070 EnergyPush_Sonic **** **** **** **** **** **** **** **** +14071 Lock **** **** **** **** **** **** **** **** +14072 EnergyStun_Cold **** **** **** **** **** **** **** **** +14073 EnergyStun_Elec **** **** **** **** **** **** **** **** +14074 EnergyStun_Fire **** **** **** **** **** **** **** **** +14075 EnergyStun_Sonic **** **** **** **** **** **** **** **** +14076 Identify **** **** **** **** **** **** **** **** +14077 IdInsinuation **** **** **** **** **** **** **** **** +14078 InflictPain **** **** **** **** **** **** **** **** +14079 Knock **** **** **** **** **** **** **** **** +14080 MindDisrupt **** **** **** **** **** **** **** **** +14081 RecallAgony **** **** **** **** **** **** **** **** +14082 ThoughtShield **** **** **** **** **** **** **** **** +14083 Dissolving_Weapon **** **** **** **** **** **** **** **** +14084 SharePain **** **** **** **** **** **** **** **** +14085 ControlAir **** **** **** **** **** **** **** **** +14086 ControlSound **** **** **** **** **** **** **** **** +14087 RepairDamage **** **** **** **** **** **** **** **** +14088 Aversion **** **** **** **** **** **** **** **** +14089 DimensionSwap **** **** **** **** **** **** **** **** +14090 EmpathicTransfer **** **** **** **** **** **** **** **** +14091 Energy_Missile_Cold **** **** **** **** **** **** **** **** +14092 Energy_Missile_Elec **** **** **** **** **** **** **** **** +14093 Energy_Missile_Fire **** **** **** **** **** **** **** **** +14094 Energy_Missile_Sonic **** **** **** **** **** **** **** **** +14095 AnimalAffinity **** **** **** **** **** **** **** **** +14096 StrengthOfMyEnemy **** **** **** **** **** **** **** **** +14097 Chameleon **** **** **** **** **** **** **** **** +14098 ClairvoyantSense **** **** **** **** **** **** **** **** +14099 Cloud_Mind **** **** **** **** **** **** **** **** +14100 BodyAdjustment **** **** **** **** **** **** **** **** +14101 Greater_Amorpha **** **** **** **** **** **** **** **** +14102 Darkvision **** **** **** **** **** **** **** **** +14103 Psiblast **** **** **** **** **** **** **** **** +14104 Danger_Sense **** **** **** **** **** **** **** **** +14105 Energy_Bolt_Cold **** **** **** **** **** **** **** **** +14106 Energy_Bolt_Elec **** **** **** **** **** **** **** **** +14107 Energy_Bolt_Fire **** **** **** **** **** **** **** **** +14108 Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +14109 Energy_Burst_Cold **** **** **** **** **** **** **** **** +14110 Energy_Burst_Elec **** **** **** **** **** **** **** **** +14111 Energy_Burst_Fire **** **** **** **** **** **** **** **** +14112 Energy_Burst_Sonic **** **** **** **** **** **** **** **** +14113 Energy_Retort_Cold **** **** **** **** **** **** **** **** +14114 Energy_Retort_Elec **** **** **** **** **** **** **** **** +14115 Energy_Retort_Fire **** **** **** **** **** **** **** **** +14116 Energy_Retort_Sonic **** **** **** **** **** **** **** **** +14117 Exhale_BlackDrag **** **** **** **** **** **** **** **** +14118 Eradicate_Invisibility **** **** **** **** **** **** **** **** +14119 SharePainForced **** **** **** **** **** **** **** **** +14120 Keen_Edge **** **** **** **** **** **** **** **** +14121 MentalBarrier **** **** **** **** **** **** **** **** +14122 Mindtrap **** **** **** **** **** **** **** **** +14123 Touchsight **** **** **** **** **** **** **** **** +14124 BodyPurification **** **** **** **** **** **** **** **** +14125 Dispel_Psionics **** **** **** **** **** **** **** **** +14126 Energy_Wall_Cold **** **** **** **** **** **** **** **** +14127 Energy_Wall_Elec **** **** **** **** **** **** **** **** +14128 Energy_Wall_Fire **** **** **** **** **** **** **** **** +14129 Energy_Wall_Sonic **** **** **** **** **** **** **** **** +14130 Hustle **** **** **** **** **** **** **** **** +14131 TimeHop **** **** **** **** **** **** **** **** +14132 UbiqVision **** **** **** **** **** **** **** **** +14133 EctoCocoon **** **** **** **** **** **** **** **** +14134 CrisisBreath **** **** **** **** **** **** **** **** +14135 EmpathicTransferHostile **** **** **** **** **** **** **** **** +14136 FateLink **** **** **** **** **** **** **** **** +14137 DimensionSlide **** **** **** **** **** **** **** **** +14138 EctoplasmicForm **** **** **** **** **** **** **** **** +14139 EnergyCone_Cold **** **** **** **** **** **** **** **** +14140 EnergyCone_Elec **** **** **** **** **** **** **** **** +14141 EnergyCone_Fire **** **** **** **** **** **** **** **** +14142 EnergyCone_Sonic **** **** **** **** **** **** **** **** +14143 ClawOfTheVampire **** **** **** **** **** **** **** **** +14144 DuodimensionalClaw **** **** **** **** **** **** **** **** +14145 VampiricWeapon **** **** **** **** **** **** **** **** +14146 EscapeDetection **** **** **** **** **** **** **** **** +14147 InertialBar **** **** **** **** **** **** **** **** +14148 SteadfastPercep **** **** **** **** **** **** **** **** +14149 DetectRemoteViewing **** **** **** **** **** **** **** **** +14150 EmpathicFeedback **** **** **** **** **** **** **** **** +14151 EnergyAdaption **** **** **** **** **** **** **** **** +14152 Freedom_of_Movement **** **** **** **** **** **** **** **** +14153 Mindwipe **** **** **** **** **** **** **** **** +14154 PowerLeech **** **** **** **** **** **** **** **** +14155 PsychicReformation **** **** **** **** **** **** **** **** +14156 TelekineticManeuver **** **** **** **** **** **** **** **** +14157 DimensionalAnchor **** **** **** **** **** **** **** **** +14158 Dismissal **** **** **** **** **** **** **** **** +14159 DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +14160 DimensionDoor_Party **** **** **** **** **** **** **** **** +14161 Dominate_Psionic **** **** **** **** **** **** **** **** +14162 DimensionDoor_Master **** **** **** **** **** **** **** **** +14163 DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +14164 DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +14165 EnergyBall_Cold **** **** **** **** **** **** **** **** +14166 EnergyBall_Elec **** **** **** **** **** **** **** **** +14167 EnergyBall_Fire **** **** **** **** **** **** **** **** +14168 EnergyBall_Sonic **** **** **** **** **** **** **** **** +14169 PsychicVampire **** **** **** **** **** **** **** **** +14170 ClawofEnergyCold **** **** **** **** **** **** **** **** +14171 ClawofEnergyElec **** **** **** **** **** **** **** **** +14172 ClawofEnergyFire **** **** **** **** **** **** **** **** +14173 Immovability **** **** **** **** **** **** **** **** +14174 Truevenom **** **** **** **** **** **** **** **** +14175 TruevenomWeapon **** **** **** **** **** **** **** **** +14176 WeaponofEnergyCold **** **** **** **** **** **** **** **** +14177 WeaponofEnergyElec **** **** **** **** **** **** **** **** +14178 WeaponofEnergyFire **** **** **** **** **** **** **** **** +14179 IntellectFortress **** **** **** **** **** **** **** **** +14180 RemoteViewing **** **** **** **** **** **** **** **** +14181 BaleTeleport **** **** **** **** **** **** **** **** +14182 EctoplasmicShambler **** **** **** **** **** **** **** **** +14183 Power_Resistance **** **** **** **** **** **** **** **** +14184 PsychicCrush **** **** **** **** **** **** **** **** +14185 TowerIronWill **** **** **** **** **** **** **** **** +14186 True_Seeing **** **** **** **** **** **** **** **** +14187 Catapsi **** **** **** **** **** **** **** **** +14188 ShatterMindBlank **** **** **** **** **** **** **** **** +14189 HailCrystals **** **** **** **** **** **** **** **** +14190 SecondChance **** **** **** **** **** **** **** **** +14191 Teleport_SelfOnly **** **** **** **** **** **** **** **** +14192 Teleport_Party **** **** **** **** **** **** **** **** +14193 EnergyCurrent_Cold **** **** **** **** **** **** **** **** +14194 EnergyCurrent_Elec **** **** **** **** **** **** **** **** +14195 EnergyCurrent_Fire **** **** **** **** **** **** **** **** +14196 EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +14197 PsionicRevivify **** **** **** **** **** **** **** **** +14198 Psychofeedback **** **** **** **** **** **** **** **** +14199 ClairtangentHand **** **** **** **** **** **** **** **** +14200 BreathBlackDragon **** **** **** **** **** **** **** **** +14201 Disintegrate **** **** **** **** **** **** **** **** +14202 Crystallize **** **** **** **** **** **** **** **** +14203 FuseFlesh **** **** **** **** **** **** **** **** +14204 Retrieve **** **** **** **** **** **** **** **** +14205 TemporalAcceleration **** **** **** **** **** **** **** **** +14206 Banishment **** **** **** **** **** **** **** **** +14207 GreatPrecognitionMain **** **** **** **** **** **** **** **** +14208 GreatPrecognitionAttack **** **** **** **** **** **** **** **** +14209 GreatPrecognitionDamage **** **** **** **** **** **** **** **** +14210 GreatPrecognitionSaves **** **** **** **** **** **** **** **** +14211 GreatPrecognitionSkills **** **** **** **** **** **** **** **** +14212 RestorationPsionic **** **** **** **** **** **** **** **** +14213 DispellingBuffer **** **** **** **** **** **** **** **** +14214 FormOfDoom **** **** **** **** **** **** **** **** +14215 NullPsionicsField **** **** **** **** **** **** **** **** +14216 RemoteViewTrap **** **** **** **** **** **** **** **** +14217 Cloud_Mind_Mass **** **** **** **** **** **** **** **** +14218 CrisisLife **** **** **** **** **** **** **** **** +14219 Decerebrate **** **** **** **** **** **** **** **** +14220 EnergyWaveCold **** **** **** **** **** **** **** **** +14221 EnergyWaveElec **** **** **** **** **** **** **** **** +14222 EnergyWaveFire **** **** **** **** **** **** **** **** +14223 EnergyWaveSonic **** **** **** **** **** **** **** **** +14224 Insanity **** **** **** **** **** **** **** **** +14225 Mind_BlankPersonal **** **** **** **** **** **** **** **** +14226 OakBody **** **** **** **** **** **** **** **** +14227 Ultrablast **** **** **** **** **** **** **** **** +14228 EvadeBurst **** **** **** **** **** **** **** **** +14229 MomentOfPrescienceAttack **** **** **** **** **** **** **** **** +14230 MomentOfPrescienceArmour **** **** **** **** **** **** **** **** +14231 MomentOfPrescienceSaves **** **** **** **** **** **** **** **** +14232 MomentOfPrescienceSkills **** **** **** **** **** **** **** **** +14233 EctoCocoonMass **** **** **** **** **** **** **** **** +14234 EtherealJaunt **** **** **** **** **** **** **** **** +14235 Reddopsi **** **** **** **** **** **** **** **** +14236 Sequester **** **** **** **** **** **** **** **** +14237 RecallDeath **** **** **** **** **** **** **** **** +14238 IronBody **** **** **** **** **** **** **** **** +14239 PsionicMind_Blank **** **** **** **** **** **** **** **** +14240 TrueMetabolism **** **** **** **** **** **** **** **** +14241 Shadow_Body **** **** **** **** **** **** **** **** +14242 AstralSeed **** **** **** **** **** **** **** **** +14243 TimeHopMass **** **** **** **** **** **** **** **** +14244 Hypercognition **** **** **** **** **** **** **** **** +14245 GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +14246 GreaterTeleport_Party **** **** **** **** **** **** **** **** +14247 Assimilate **** **** **** **** **** **** **** **** +14248 Etherealness **** **** **** **** **** **** **** **** +14249 Microcosm **** **** **** **** **** **** **** **** +14250 TimelessBody **** **** **** **** **** **** **** **** +14251 Genesis **** **** **** **** **** **** **** **** +14252 PsychicChirurgery_Repair **** **** **** **** **** **** **** **** +14253 TeleportationCircle_Visible **** **** **** **** **** **** **** **** +14254 TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +14255 PsychicChirurgery_Transfer_TODO **** **** **** **** **** **** **** **** +14256 TornadoBlast **** **** **** **** **** **** **** **** +14257 CallWeaponry **** **** **** **** **** **** **** **** +14258 Compression **** **** **** **** **** **** **** **** +14259 Expansion **** **** **** **** **** **** **** **** +14260 ControlObject **** **** **** **** **** **** **** **** +14261 MetaphysicalClaw **** **** **** **** **** **** **** **** +14262 MetaphysicalWeapon **** **** **** **** **** **** **** **** +14263 Prevenom **** **** **** **** **** **** **** **** +14264 PrevenomWeapon **** **** **** **** **** **** **** **** +14265 GripOfIron **** **** **** **** **** **** **** **** +14266 PsionicLionsCharge **** **** **** **** **** **** **** **** +14267 **** **** **** **** **** **** **** **** **** +14268 **** **** **** **** **** **** **** **** **** +14269 **** **** **** **** **** **** **** **** **** +14270 **** **** **** **** **** **** **** **** **** +14271 **** **** **** **** **** **** **** **** **** +14272 **** **** **** **** **** **** **** **** **** +14273 **** **** **** **** **** **** **** **** **** +14274 **** **** **** **** **** **** **** **** **** +14275 **** **** **** **** **** **** **** **** **** +14276 **** **** **** **** **** **** **** **** **** +14277 **** **** **** **** **** **** **** **** **** +14278 **** **** **** **** **** **** **** **** **** +14279 **** **** **** **** **** **** **** **** **** +14280 **** **** **** **** **** **** **** **** **** +14281 **** **** **** **** **** **** **** **** **** +14282 **** **** **** **** **** **** **** **** **** +14283 **** **** **** **** **** **** **** **** **** +14284 **** **** **** **** **** **** **** **** **** +14285 **** **** **** **** **** **** **** **** **** +14286 **** **** **** **** **** **** **** **** **** +14287 **** **** **** **** **** **** **** **** **** +14288 **** **** **** **** **** **** **** **** **** +14289 **** **** **** **** **** **** **** **** **** +14290 **** **** **** **** **** **** **** **** **** +14291 **** **** **** **** **** **** **** **** **** +14292 **** **** **** **** **** **** **** **** **** +14293 **** **** **** **** **** **** **** **** **** +14294 **** **** **** **** **** **** **** **** **** +14295 **** **** **** **** **** **** **** **** **** +14296 **** **** **** **** **** **** **** **** **** +14297 **** **** **** **** **** **** **** **** **** +14298 **** **** **** **** **** **** **** **** **** +14299 **** **** **** **** **** **** **** **** **** +14300 **** **** **** **** **** **** **** **** **** +14301 **** **** **** **** **** **** **** **** **** +14302 **** **** **** **** **** **** **** **** **** +14303 **** **** **** **** **** **** **** **** **** +14304 **** **** **** **** **** **** **** **** **** +14305 **** **** **** **** **** **** **** **** **** +14306 **** **** **** **** **** **** **** **** **** +14307 **** **** **** **** **** **** **** **** **** +14308 **** **** **** **** **** **** **** **** **** +14309 **** **** **** **** **** **** **** **** **** +14310 **** **** **** **** **** **** **** **** **** +14311 **** **** **** **** **** **** **** **** **** +14312 **** **** **** **** **** **** **** **** **** +14313 **** **** **** **** **** **** **** **** **** +14314 **** **** **** **** **** **** **** **** **** +14315 **** **** **** **** **** **** **** **** **** +14316 **** **** **** **** **** **** **** **** **** +14317 **** **** **** **** **** **** **** **** **** +14318 **** **** **** **** **** **** **** **** **** +14319 **** **** **** **** **** **** **** **** **** +14320 **** **** **** **** **** **** **** **** **** +14321 **** **** **** **** **** **** **** **** **** +14322 **** **** **** **** **** **** **** **** **** +14323 **** **** **** **** **** **** **** **** **** +14324 **** **** **** **** **** **** **** **** **** +14325 **** **** **** **** **** **** **** **** **** +14326 **** **** **** **** **** **** **** **** **** +14327 **** **** **** **** **** **** **** **** **** +14328 **** **** **** **** **** **** **** **** **** +14329 **** **** **** **** **** **** **** **** **** +14330 AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +14331 EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +14332 Precognition_RadialMaster **** **** **** **** **** **** **** **** +14333 EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +14334 EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +14335 EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +14336 Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +14337 EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +14338 EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +14339 EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +14340 EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +14341 Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +14342 EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +14343 Teleport_RadialMaster **** **** **** **** **** **** **** **** +14344 EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +14345 GreatPrecognition_RadialMaster **** **** **** **** **** **** **** **** +14346 EnergyWave_RadialMaster **** **** **** **** **** **** **** **** +14347 MomentOfPrescience_RadialMaster **** **** **** **** **** **** **** **** +14348 GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +14349 TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +14350 ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14351 WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14352 **** **** **** **** **** **** **** **** **** +14353 **** **** **** **** **** **** **** **** **** +14354 **** **** **** **** **** **** **** **** **** +14355 **** **** **** **** **** **** **** **** **** +14356 **** **** **** **** **** **** **** **** **** +14357 **** **** **** **** **** **** **** **** **** +14358 **** **** **** **** **** **** **** **** **** +14359 **** **** **** **** **** **** **** **** **** +14360 ####START_OF_PSI_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +14361 Psychic_Rogue_Bolt **** **** **** **** **** **** **** **** +14362 Psychic_Rogue_Burst **** **** **** **** **** **** **** **** +14363 Psychic_Rogue_Compression **** **** **** **** **** **** **** **** +14364 Psychic_Rogue_Conceal_Thoughts **** **** **** **** **** **** **** **** +14365 Psychic_Rogue_ControlObject **** **** **** **** **** **** **** **** +14366 Psychic_Rogue_CreateSound **** **** **** **** **** **** **** **** +14367 Psychic_Rogue_DefPrecog **** **** **** **** **** **** **** **** +14368 Psychic_Rogue_Disable **** **** **** **** **** **** **** **** +14369 Psychic_Rogue_Distract **** **** **** **** **** **** **** **** +14370 Psychic_Rogue_ElfSight **** **** **** **** **** **** **** **** +14371 Psychic_Rogue_Empathy **** **** **** **** **** **** **** **** +14372 Psychic_Rogue_EmptyMind **** **** **** **** **** **** **** **** +14373 Psychic_Rogue_EntanglingEctoplasm **** **** **** **** **** **** **** **** +14374 Psychic_Rogue_Far_Hand **** **** **** **** **** **** **** **** +14375 Psychic_Rogue_ForceScreen **** **** **** **** **** **** **** **** +14376 Psychic_Rogue_MyLight **** **** **** **** **** **** **** **** +14377 Psychic_Rogue_OffPrecog **** **** **** **** **** **** **** **** +14378 Psychic_Rogue_OffPresc **** **** **** **** **** **** **** **** +14379 Psychic_Rogue_Skate **** **** **** **** **** **** **** **** +14380 Psychic_Rogue_Vigor **** **** **** **** **** **** **** **** +14381 Psychic_Rogue_AnimalAffinity **** **** **** **** **** **** **** **** +14382 Psychic_Rogue_Aversion **** **** **** **** **** **** **** **** +14383 Psychic_Rogue_Body_Equilibrium **** **** **** **** **** **** **** **** +14384 Psychic_Rogue_Chameleon **** **** **** **** **** **** **** **** +14385 Psychic_Rogue_Cloud_Mind **** **** **** **** **** **** **** **** +14386 Psychic_Rogue_ConcealAmorpha **** **** **** **** **** **** **** **** +14387 Psychic_Rogue_ControlObject **** **** **** **** **** **** **** **** +14388 Psychic_Rogue_ControlSound **** **** **** **** **** **** **** **** +14389 Psychic_Rogue_Darkvision **** **** **** **** **** **** **** **** +14390 Psychic_Rogue_Knock **** **** **** **** **** **** **** **** +14391 Psychic_Rogue_ThoughtShield **** **** **** **** **** **** **** **** +14392 Psychic_Rogue_BodyAdjustment **** **** **** **** **** **** **** **** +14393 Psychic_Rogue_BodyPurification **** **** **** **** **** **** **** **** +14394 Psychic_Rogue_ControlAir **** **** **** **** **** **** **** **** +14395 Psychic_Rogue_DimensionSlide **** **** **** **** **** **** **** **** +14396 Psychic_Rogue_EscapeDetection **** **** **** **** **** **** **** **** +14397 Psychic_Rogue_Greater_Amorpha **** **** **** **** **** **** **** **** +14398 Psychic_Rogue_Hustle **** **** **** **** **** **** **** **** +14399 Psychic_Rogue_Keen_Edge **** **** **** **** **** **** **** **** +14400 Psychic_Rogue_MentalBarrier **** **** **** **** **** **** **** **** +14401 Psychic_Rogue_UbiqVision **** **** **** **** **** **** **** **** +14402 Psychic_Rogue_DimensionDoor_Master **** **** **** **** **** **** **** **** +14403 Psychic_Rogue_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +14404 Psychic_Rogue_DimensionDoor_Party **** **** **** **** **** **** **** **** +14405 Psychic_Rogue_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +14406 Psychic_Rogue_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +14407 Psychic_Rogue_Freedom_of_Movement **** **** **** **** **** **** **** **** +14408 Psychic_Rogue_SteadfastPercep **** **** **** **** **** **** **** **** +14409 Psychic_Rogue_TelekineticManeuver **** **** **** **** **** **** **** **** +14410 Psychic_Rogue_Power_Resistance **** **** **** **** **** **** **** **** +14411 Psychic_Rogue_RemoteViewing **** **** **** **** **** **** **** **** +14412 Psychic_Rogue_Retrieve **** **** **** **** **** **** **** **** +14413 Psychic_Rogue_PsionicRevivify **** **** **** **** **** **** **** **** +14414 Psychic_Rogue_True_Seeing **** **** **** **** **** **** **** **** +14415 Psion_AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +14416 Psion_AstralConstruct_Conversation **** **** **** **** **** **** **** **** +14417 Psion_AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +14418 Psion_AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +14419 Psion_AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +14420 Psion_AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +14421 Psion_BiteOfTheWolf **** **** **** **** **** **** **** **** +14422 Psion_Bolt **** **** **** **** **** **** **** **** +14423 Psion_Burst **** **** **** **** **** **** **** **** +14424 Psion_CallToMind **** **** **** **** **** **** **** **** +14425 Psion_CallWeaponry **** **** **** **** **** **** **** **** +14426 Psion_CharmPerson **** **** **** **** **** **** **** **** +14427 Psion_ClawsOfTheBeast **** **** **** **** **** **** **** **** +14428 Psion_Compression **** **** **** **** **** **** **** **** +14429 Psion_Conceal_Thoughts **** **** **** **** **** **** **** **** +14430 Psion_ControlObject **** **** **** **** **** **** **** **** +14431 Psion_CreateSound **** **** **** **** **** **** **** **** +14432 Psion_CrystalShard **** **** **** **** **** **** **** **** +14433 Psion_Daze **** **** **** **** **** **** **** **** +14434 Psion_Deceleration **** **** **** **** **** **** **** **** +14435 Psion_DefPrecog **** **** **** **** **** **** **** **** +14436 Psion_Demoralize **** **** **** **** **** **** **** **** +14437 Psion_DestinyDissonance **** **** **** **** **** **** **** **** +14438 Psion_Disable **** **** **** **** **** **** **** **** +14439 Psion_DissipatingTouch **** **** **** **** **** **** **** **** +14440 Psion_Distract **** **** **** **** **** **** **** **** +14441 Psion_Empathy **** **** **** **** **** **** **** **** +14442 Psion_EmptyMind **** **** **** **** **** **** **** **** +14443 Psion_EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +14444 Psion_EnergyRay_Cold **** **** **** **** **** **** **** **** +14445 Psion_EnergyRay_Elec **** **** **** **** **** **** **** **** +14446 Psion_EnergyRay_Fire **** **** **** **** **** **** **** **** +14447 Psion_EnergyRay_Sonic **** **** **** **** **** **** **** **** +14448 Psion_EntanglingEctoplasm **** **** **** **** **** **** **** **** +14449 Psion_Expansion **** **** **** **** **** **** **** **** +14450 Psion_Far_Hand **** **** **** **** **** **** **** **** +14451 Psion_ForceScreen **** **** **** **** **** **** **** **** +14452 Psion_Grease **** **** **** **** **** **** **** **** +14453 Psion_Hammer **** **** **** **** **** **** **** **** +14454 Psion_InertialArmour **** **** **** **** **** **** **** **** +14455 Psion_Matter_Agitation **** **** **** **** **** **** **** **** +14456 Psion_MetaphysicalClaw **** **** **** **** **** **** **** **** +14457 Psion_MetaphysicalWeapon **** **** **** **** **** **** **** **** +14458 Psion_MindThrust **** **** **** **** **** **** **** **** +14459 Psion_MyLight **** **** **** **** **** **** **** **** +14460 Psion_OffPrecog **** **** **** **** **** **** **** **** +14461 Psion_OffPresc **** **** **** **** **** **** **** **** +14462 Psion_Precognition_RadialMaster **** **** **** **** **** **** **** **** +14463 Psion_PrecognitionMain **** **** **** **** **** **** **** **** +14464 Psion_PrecognitionAttack **** **** **** **** **** **** **** **** +14465 Psion_PrecognitionDamage **** **** **** **** **** **** **** **** +14466 Psion_PrecognitionSaves **** **** **** **** **** **** **** **** +14467 Psion_PrecognitionSkills **** **** **** **** **** **** **** **** +14468 Psion_Prevenom **** **** **** **** **** **** **** **** +14469 Psion_PrevenomWeapon **** **** **** **** **** **** **** **** +14470 Psion_Skate **** **** **** **** **** **** **** **** +14471 Psion_Stomp **** **** **** **** **** **** **** **** +14472 Psion_Synesthete **** **** **** **** **** **** **** **** +14473 Psion_Telempathic_Projection **** **** **** **** **** **** **** **** +14474 Psion_ThickSkin **** **** **** **** **** **** **** **** +14475 Psion_Vigor **** **** **** **** **** **** **** **** +14476 Psion_AnimalAffinity **** **** **** **** **** **** **** **** +14477 Psion_Aversion **** **** **** **** **** **** **** **** +14478 Psion_BestowPower **** **** **** **** **** **** **** **** +14479 Psion_Biofeedback **** **** **** **** **** **** **** **** +14480 Psion_Body_Equilibrium **** **** **** **** **** **** **** **** +14481 Psion_BrainLock **** **** **** **** **** **** **** **** +14482 Psion_Chameleon **** **** **** **** **** **** **** **** +14483 Psion_ClairvoyantSense **** **** **** **** **** **** **** **** +14484 Psion_Cloud_Mind **** **** **** **** **** **** **** **** +14485 Psion_ConcBlast **** **** **** **** **** **** **** **** +14486 Psion_ConcealAmorpha **** **** **** **** **** **** **** **** +14487 Psion_ControlAir **** **** **** **** **** **** **** **** +14488 Psion_ControlSound **** **** **** **** **** **** **** **** +14489 Psion_SwarmOfCrystals **** **** **** **** **** **** **** **** +14490 Psion_DimensionSwap **** **** **** **** **** **** **** **** +14491 Psion_DissolvingTouch **** **** **** **** **** **** **** **** +14492 Psion_Dissolving_Weapon **** **** **** **** **** **** **** **** +14493 Psion_EgoWhip **** **** **** **** **** **** **** **** +14494 Psion_ElfSight **** **** **** **** **** **** **** **** +14495 Psion_EmpathicTransfer **** **** **** **** **** **** **** **** +14496 Psion_EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +14497 Psion_EnergyAdaptAcid **** **** **** **** **** **** **** **** +14498 Psion_EnergyAdaptCold **** **** **** **** **** **** **** **** +14499 Psion_EnergyAdaptElec **** **** **** **** **** **** **** **** +14500 Psion_EnergyAdaptFire **** **** **** **** **** **** **** **** +14501 Psion_EnergyAdaptSonic **** **** **** **** **** **** **** **** +14502 Psion_Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +14503 Psion_Energy_Missile_Cold **** **** **** **** **** **** **** **** +14504 Psion_Energy_Missile_Elec **** **** **** **** **** **** **** **** +14505 Psion_Energy_Missile_Fire **** **** **** **** **** **** **** **** +14506 Psion_Energy_Missile_Sonic **** **** **** **** **** **** **** **** +14507 Psion_EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +14508 Psion_EnergyPush_Cold **** **** **** **** **** **** **** **** +14509 Psion_EnergyPush_Elec **** **** **** **** **** **** **** **** +14510 Psion_EnergyPush_Fire **** **** **** **** **** **** **** **** +14511 Psion_EnergyPush_Sonic **** **** **** **** **** **** **** **** +14512 Psion_EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +14513 Psion_EnergyStun_Cold **** **** **** **** **** **** **** **** +14514 Psion_EnergyStun_Elec **** **** **** **** **** **** **** **** +14515 Psion_EnergyStun_Fire **** **** **** **** **** **** **** **** +14516 Psion_EnergyStun_Sonic **** **** **** **** **** **** **** **** +14517 Psion_Identify **** **** **** **** **** **** **** **** +14518 Psion_IdInsinuation **** **** **** **** **** **** **** **** +14519 Psion_InflictPain **** **** **** **** **** **** **** **** +14520 Psion_Knock **** **** **** **** **** **** **** **** +14521 Psion_Lock **** **** **** **** **** **** **** **** +14522 Psion_MindDisrupt **** **** **** **** **** **** **** **** +14523 Psion_PainfulStrike **** **** **** **** **** **** **** **** +14524 Psion_RecallAgony **** **** **** **** **** **** **** **** +14525 Psion_RepairDamage **** **** **** **** **** **** **** **** +14526 Psion_SharePain **** **** **** **** **** **** **** **** +14527 Psion_StrengthOfMyEnemy **** **** **** **** **** **** **** **** +14528 Psion_ThoughtShield **** **** **** **** **** **** **** **** +14529 Psion_BodyAdjustment **** **** **** **** **** **** **** **** +14530 Psion_BodyPurification **** **** **** **** **** **** **** **** +14531 Psion_ClawOfTheVampire **** **** **** **** **** **** **** **** +14532 Psion_CrisisBreath **** **** **** **** **** **** **** **** +14533 Psion_Danger_Sense **** **** **** **** **** **** **** **** +14534 Psion_Darkvision **** **** **** **** **** **** **** **** +14535 Psion_DimensionSlide **** **** **** **** **** **** **** **** +14536 Psion_Dispel_Psionics **** **** **** **** **** **** **** **** +14537 Psion_DuodimensionalClaw **** **** **** **** **** **** **** **** +14538 Psion_EctoCocoon **** **** **** **** **** **** **** **** +14539 Psion_EctoplasmicForm **** **** **** **** **** **** **** **** +14540 Psion_EmpathicTransferHostile **** **** **** **** **** **** **** **** +14541 Psion_EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +14542 Psion_Energy_Bolt_Cold **** **** **** **** **** **** **** **** +14543 Psion_Energy_Bolt_Elec **** **** **** **** **** **** **** **** +14544 Psion_Energy_Bolt_Fire **** **** **** **** **** **** **** **** +14545 Psion_Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +14546 Psion_EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +14547 Psion_Energy_Burst_Cold **** **** **** **** **** **** **** **** +14548 Psion_Energy_Burst_Elec **** **** **** **** **** **** **** **** +14549 Psion_Energy_Burst_Fire **** **** **** **** **** **** **** **** +14550 Psion_Energy_Burst_Sonic **** **** **** **** **** **** **** **** +14551 Psion_Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +14552 Psion_EnergyCone_Cold **** **** **** **** **** **** **** **** +14553 Psion_EnergyCone_Elec **** **** **** **** **** **** **** **** +14554 Psion_EnergyCone_Fire **** **** **** **** **** **** **** **** +14555 Psion_EnergyCone_Sonic **** **** **** **** **** **** **** **** +14556 Psion_EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +14557 Psion_Energy_Retort_Cold **** **** **** **** **** **** **** **** +14558 Psion_Energy_Retort_Elec **** **** **** **** **** **** **** **** +14559 Psion_Energy_Retort_Fire **** **** **** **** **** **** **** **** +14560 Psion_Energy_Retort_Sonic **** **** **** **** **** **** **** **** +14561 Psion_EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +14562 Psion_Energy_Wall_Cold **** **** **** **** **** **** **** **** +14563 Psion_Energy_Wall_Elec **** **** **** **** **** **** **** **** +14564 Psion_Energy_Wall_Fire **** **** **** **** **** **** **** **** +14565 Psion_Energy_Wall_Sonic **** **** **** **** **** **** **** **** +14566 Psion_Eradicate_Invisibility **** **** **** **** **** **** **** **** +14567 Psion_EscapeDetection **** **** **** **** **** **** **** **** +14568 Psion_Exhale_BlackDrag **** **** **** **** **** **** **** **** +14569 Psion_FateLink **** **** **** **** **** **** **** **** +14570 Psion_Greater_Amorpha **** **** **** **** **** **** **** **** +14571 Psion_Hustle **** **** **** **** **** **** **** **** +14572 Psion_Keen_Edge **** **** **** **** **** **** **** **** +14573 Psion_MentalBarrier **** **** **** **** **** **** **** **** +14574 Psion_Mindtrap **** **** **** **** **** **** **** **** +14575 Psion_Psiblast **** **** **** **** **** **** **** **** +14576 Psion_SharePainForced **** **** **** **** **** **** **** **** +14577 Psion_TimeHop **** **** **** **** **** **** **** **** +14578 Psion_Touchsight **** **** **** **** **** **** **** **** +14579 Psion_UbiqVision **** **** **** **** **** **** **** **** +14580 Psion_VampiricWeapon **** **** **** **** **** **** **** **** +14581 Psion_ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14582 Psion_ClawofEnergyCold **** **** **** **** **** **** **** **** +14583 Psion_ClawofEnergyElec **** **** **** **** **** **** **** **** +14584 Psion_ClawofEnergyFire **** **** **** **** **** **** **** **** +14585 Psion_DetectRemoteViewing **** **** **** **** **** **** **** **** +14586 Psion_DimensionalAnchor **** **** **** **** **** **** **** **** +14587 Psion_DimensionDoor_Master **** **** **** **** **** **** **** **** +14588 Psion_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +14589 Psion_DimensionDoor_Party **** **** **** **** **** **** **** **** +14590 Psion_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +14591 Psion_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +14592 Psion_Dismissal **** **** **** **** **** **** **** **** +14593 Psion_EmpathicFeedback **** **** **** **** **** **** **** **** +14594 Psion_EnergyAdaption **** **** **** **** **** **** **** **** +14595 Psion_EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +14596 Psion_EnergyBall_Cold **** **** **** **** **** **** **** **** +14597 Psion_EnergyBall_Elec **** **** **** **** **** **** **** **** +14598 Psion_EnergyBall_Fire **** **** **** **** **** **** **** **** +14599 Psion_EnergyBall_Sonic **** **** **** **** **** **** **** **** +14600 Psion_Freedom_of_Movement **** **** **** **** **** **** **** **** +14601 Psion_Immovability **** **** **** **** **** **** **** **** +14602 Psion_InertialBar **** **** **** **** **** **** **** **** +14603 Psion_IntellectFortress **** **** **** **** **** **** **** **** +14604 Psion_Mindwipe **** **** **** **** **** **** **** **** +14605 Psion_PowerLeech **** **** **** **** **** **** **** **** +14606 Psion_Dominate_Psionic **** **** **** **** **** **** **** **** +14607 Psion_PsychicReformation **** **** **** **** **** **** **** **** +14608 Psion_PsychicVampire **** **** **** **** **** **** **** **** +14609 Psion_RemoteViewing **** **** **** **** **** **** **** **** +14610 Psion_SteadfastPercep **** **** **** **** **** **** **** **** +14611 Psion_TelekineticManeuver **** **** **** **** **** **** **** **** +14612 Psion_Truevenom **** **** **** **** **** **** **** **** +14613 Psion_TruevenomWeapon **** **** **** **** **** **** **** **** +14614 Psion_WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14615 Psion_WeaponofEnergyCold **** **** **** **** **** **** **** **** +14616 Psion_WeaponofEnergyElec **** **** **** **** **** **** **** **** +14617 Psion_WeaponofEnergyFire **** **** **** **** **** **** **** **** +14618 Psion_BaleTeleport **** **** **** **** **** **** **** **** +14619 Psion_Catapsi **** **** **** **** **** **** **** **** +14620 Psion_ClairtangentHand **** **** **** **** **** **** **** **** +14621 Psion_EctoplasmicShambler **** **** **** **** **** **** **** **** +14622 Psion_EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +14623 Psion_EnergyCurrent_Cold **** **** **** **** **** **** **** **** +14624 Psion_EnergyCurrent_Elec **** **** **** **** **** **** **** **** +14625 Psion_EnergyCurrent_Fire **** **** **** **** **** **** **** **** +14626 Psion_EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +14627 Psion_HailCrystals **** **** **** **** **** **** **** **** +14628 Psion_Power_Resistance **** **** **** **** **** **** **** **** +14629 Psion_PsionicRevivify **** **** **** **** **** **** **** **** +14630 Psion_PsychicCrush **** **** **** **** **** **** **** **** +14631 Psion_Psychofeedback **** **** **** **** **** **** **** **** +14632 Psion_SecondChance **** **** **** **** **** **** **** **** +14633 Psion_ShatterMindBlank **** **** **** **** **** **** **** **** +14634 Psion_Teleport_RadialMaster **** **** **** **** **** **** **** **** +14635 Psion_Teleport_SelfOnly **** **** **** **** **** **** **** **** +14636 Psion_Teleport_Party **** **** **** **** **** **** **** **** +14637 Psion_TowerIronWill **** **** **** **** **** **** **** **** +14638 Psion_True_Seeing **** **** **** **** **** **** **** **** +14639 Psion_Banishment **** **** **** **** **** **** **** **** +14640 Psion_BreathBlackDragon **** **** **** **** **** **** **** **** +14641 Psion_Cloud_Mind_Mass **** **** **** **** **** **** **** **** +14642 Psion_Crystallize **** **** **** **** **** **** **** **** +14643 Psion_Disintegrate **** **** **** **** **** **** **** **** +14644 Psion_DispellingBuffer **** **** **** **** **** **** **** **** +14645 Psion_FormOfDoom **** **** **** **** **** **** **** **** +14646 Psion_FuseFlesh **** **** **** **** **** **** **** **** +14647 Psion_GreatPrecognition_RadialMaster **** **** **** **** **** **** **** **** +14648 Psion_GreatPrecognitionMain **** **** **** **** **** **** **** **** +14649 Psion_GreatPrecognitionAttack **** **** **** **** **** **** **** **** +14650 Psion_GreatPrecognitionDamage **** **** **** **** **** **** **** **** +14651 Psion_GreatPrecognitionSaves **** **** **** **** **** **** **** **** +14652 Psion_GreatPrecognitionSkills **** **** **** **** **** **** **** **** +14653 Psion_NullPsionicsField **** **** **** **** **** **** **** **** +14654 Psion_RemoteViewTrap **** **** **** **** **** **** **** **** +14655 Psion_RestorationPsionic **** **** **** **** **** **** **** **** +14656 Psion_Retrieve **** **** **** **** **** **** **** **** +14657 Psion_TemporalAcceleration **** **** **** **** **** **** **** **** +14658 Psion_CrisisLife **** **** **** **** **** **** **** **** +14659 Psion_Decerebrate **** **** **** **** **** **** **** **** +14660 Psion_EctoCocoonMass **** **** **** **** **** **** **** **** +14661 Psion_EnergyWave_RadialMaster **** **** **** **** **** **** **** **** +14662 Psion_EnergyWaveCold **** **** **** **** **** **** **** **** +14663 Psion_EnergyWaveElec **** **** **** **** **** **** **** **** +14664 Psion_EnergyWaveFire **** **** **** **** **** **** **** **** +14665 Psion_EnergyWaveSonic **** **** **** **** **** **** **** **** +14666 Psion_EtherealJaunt **** **** **** **** **** **** **** **** +14667 Psion_EvadeBurst **** **** **** **** **** **** **** **** +14668 Psion_Insanity **** **** **** **** **** **** **** **** +14669 Psion_Mind_BlankPersonal **** **** **** **** **** **** **** **** +14670 Psion_MomentOfPrescience_RadialMaster **** **** **** **** **** **** **** **** +14671 Psion_MomentOfPrescienceAttack **** **** **** **** **** **** **** **** +14672 Psion_MomentOfPrescienceArmour **** **** **** **** **** **** **** **** +14673 Psion_MomentOfPrescienceSaves **** **** **** **** **** **** **** **** +14674 Psion_MomentOfPrescienceSkills **** **** **** **** **** **** **** **** +14675 Psion_OakBody **** **** **** **** **** **** **** **** +14676 Psion_Reddopsi **** **** **** **** **** **** **** **** +14677 Psion_Sequester **** **** **** **** **** **** **** **** +14678 Psion_Ultrablast **** **** **** **** **** **** **** **** +14679 Psion_AstralSeed **** **** **** **** **** **** **** **** +14680 Psion_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +14681 Psion_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +14682 Psion_GreaterTeleport_Party **** **** **** **** **** **** **** **** +14683 Psion_Hypercognition **** **** **** **** **** **** **** **** +14684 Psion_IronBody **** **** **** **** **** **** **** **** +14685 Psion_PsionicMind_Blank **** **** **** **** **** **** **** **** +14686 Psion_RecallDeath **** **** **** **** **** **** **** **** +14687 Psion_Shadow_Body **** **** **** **** **** **** **** **** +14688 Psion_TimeHopMass **** **** **** **** **** **** **** **** +14689 Psion_TrueMetabolism **** **** **** **** **** **** **** **** +14690 Psion_Assimilate **** **** **** **** **** **** **** **** +14691 Psion_Etherealness **** **** **** **** **** **** **** **** +14692 Psion_Genesis **** **** **** **** **** **** **** **** +14693 Psion_Microcosm **** **** **** **** **** **** **** **** +14694 Psion_PsychicChirurgery_Repair **** **** **** **** **** **** **** **** +14695 Psion_TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +14696 Psion_TeleportationCircle_Visible **** **** **** **** **** **** **** **** +14697 Psion_TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +14698 Psion_TimelessBody **** **** **** **** **** **** **** **** +14699 Psion_TornadoBlast **** **** **** **** **** **** **** **** +14700 Psychic_Warrior_AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +14701 Psychic_Warrior_AstralConstruct_Conversation **** **** **** **** **** **** **** **** +14702 Psychic_Warrior_AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +14703 Psychic_Warrior_AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +14704 Psychic_Warrior_AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +14705 Psychic_Warrior_AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +14706 Psychic_Warrior_Biofeedback **** **** **** **** **** **** **** **** +14707 Psychic_Warrior_BiteOfTheWolf **** **** **** **** **** **** **** **** +14708 Psychic_Warrior_Bolt **** **** **** **** **** **** **** **** +14709 Psychic_Warrior_Burst **** **** **** **** **** **** **** **** +14710 Psychic_Warrior_CallToMind **** **** **** **** **** **** **** **** +14711 Psychic_Warrior_CallWeaponry **** **** **** **** **** **** **** **** +14712 Psychic_Warrior_Chameleon **** **** **** **** **** **** **** **** +14713 Psychic_Warrior_CharmPerson **** **** **** **** **** **** **** **** +14714 Psychic_Warrior_ClawsOfTheBeast **** **** **** **** **** **** **** **** +14715 Psychic_Warrior_Compression **** **** **** **** **** **** **** **** +14716 Psychic_Warrior_Conceal_Thoughts **** **** **** **** **** **** **** **** +14717 Psychic_Warrior_ControlObject **** **** **** **** **** **** **** **** +14718 Psychic_Warrior_CreateSound **** **** **** **** **** **** **** **** +14719 Psychic_Warrior_CrystalShard **** **** **** **** **** **** **** **** +14720 Psychic_Warrior_Daze **** **** **** **** **** **** **** **** +14721 Psychic_Warrior_Deceleration **** **** **** **** **** **** **** **** +14722 Psychic_Warrior_DefPrecog **** **** **** **** **** **** **** **** +14723 Psychic_Warrior_Demoralize **** **** **** **** **** **** **** **** +14724 Psychic_Warrior_DestinyDissonance **** **** **** **** **** **** **** **** +14725 Psychic_Warrior_Disable **** **** **** **** **** **** **** **** +14726 Psychic_Warrior_DissipatingTouch **** **** **** **** **** **** **** **** +14727 Psychic_Warrior_Distract **** **** **** **** **** **** **** **** +14728 Psychic_Warrior_ElfSight **** **** **** **** **** **** **** **** +14729 Psychic_Warrior_Empathy **** **** **** **** **** **** **** **** +14730 Psychic_Warrior_EmptyMind **** **** **** **** **** **** **** **** +14731 Psychic_Warrior_EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +14732 Psychic_Warrior_EnergyRay_Cold **** **** **** **** **** **** **** **** +14733 Psychic_Warrior_EnergyRay_Elec **** **** **** **** **** **** **** **** +14734 Psychic_Warrior_EnergyRay_Fire **** **** **** **** **** **** **** **** +14735 Psychic_Warrior_EnergyRay_Sonic **** **** **** **** **** **** **** **** +14736 Psychic_Warrior_EntanglingEctoplasm **** **** **** **** **** **** **** **** +14737 Psychic_Warrior_Expansion **** **** **** **** **** **** **** **** +14738 Psychic_Warrior_Far_Hand **** **** **** **** **** **** **** **** +14739 Psychic_Warrior_ForceScreen **** **** **** **** **** **** **** **** +14740 Psychic_Warrior_Grease **** **** **** **** **** **** **** **** +14741 Psychic_Warrior_Hammer **** **** **** **** **** **** **** **** +14742 Psychic_Warrior_InertialArmour **** **** **** **** **** **** **** **** +14743 Psychic_Warrior_Matter_Agitation **** **** **** **** **** **** **** **** +14744 Psychic_Warrior_MetaphysicalClaw **** **** **** **** **** **** **** **** +14745 Psychic_Warrior_MetaphysicalWeapon **** **** **** **** **** **** **** **** +14746 Psychic_Warrior_MindThrust **** **** **** **** **** **** **** **** +14747 Psychic_Warrior_MyLight **** **** **** **** **** **** **** **** +14748 Psychic_Warrior_OffPrecog **** **** **** **** **** **** **** **** +14749 Psychic_Warrior_OffPresc **** **** **** **** **** **** **** **** +14750 Psychic_Warrior_Precognition_RadialMaster **** **** **** **** **** **** **** **** +14751 Psychic_Warrior_PrecognitionMain **** **** **** **** **** **** **** **** +14752 Psychic_Warrior_PrecognitionAttack **** **** **** **** **** **** **** **** +14753 Psychic_Warrior_PrecognitionDamage **** **** **** **** **** **** **** **** +14754 Psychic_Warrior_PrecognitionSaves **** **** **** **** **** **** **** **** +14755 Psychic_Warrior_PrecognitionSkills **** **** **** **** **** **** **** **** +14756 Psychic_Warrior_Prevenom **** **** **** **** **** **** **** **** +14757 Psychic_Warrior_PrevenomWeapon **** **** **** **** **** **** **** **** +14758 Psychic_Warrior_Skate **** **** **** **** **** **** **** **** +14759 Psychic_Warrior_Stomp **** **** **** **** **** **** **** **** +14760 Psychic_Warrior_Synesthete **** **** **** **** **** **** **** **** +14761 Psychic_Warrior_Telempathic_Projection **** **** **** **** **** **** **** **** +14762 Psychic_Warrior_ThickSkin **** **** **** **** **** **** **** **** +14763 Psychic_Warrior_Vigor **** **** **** **** **** **** **** **** +14764 Psychic_Warrior_AnimalAffinity **** **** **** **** **** **** **** **** +14765 Psychic_Warrior_Aversion **** **** **** **** **** **** **** **** +14766 Psychic_Warrior_BestowPower **** **** **** **** **** **** **** **** +14767 Psychic_Warrior_BodyAdjustment **** **** **** **** **** **** **** **** +14768 Psychic_Warrior_Body_Equilibrium **** **** **** **** **** **** **** **** +14769 Psychic_Warrior_BodyPurification **** **** **** **** **** **** **** **** +14770 Psychic_Warrior_BrainLock **** **** **** **** **** **** **** **** +14771 Psychic_Warrior_ClairvoyantSense **** **** **** **** **** **** **** **** +14772 Psychic_Warrior_Cloud_Mind **** **** **** **** **** **** **** **** +14773 Psychic_Warrior_ConcBlast **** **** **** **** **** **** **** **** +14774 Psychic_Warrior_ConcealAmorpha **** **** **** **** **** **** **** **** +14775 Psychic_Warrior_ControlAir **** **** **** **** **** **** **** **** +14776 Psychic_Warrior_ControlSound **** **** **** **** **** **** **** **** +14777 Psychic_Warrior_SwarmOfCrystals **** **** **** **** **** **** **** **** +14778 Psychic_Warrior_Darkvision **** **** **** **** **** **** **** **** +14779 Psychic_Warrior_DimensionSwap **** **** **** **** **** **** **** **** +14780 Psychic_Warrior_DissolvingTouch **** **** **** **** **** **** **** **** +14781 Psychic_Warrior_Dissolving_Weapon **** **** **** **** **** **** **** **** +14782 Psychic_Warrior_EgoWhip **** **** **** **** **** **** **** **** +14783 Psychic_Warrior_EmpathicTransfer **** **** **** **** **** **** **** **** +14784 Psychic_Warrior_EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +14785 Psychic_Warrior_EnergyAdaptAcid **** **** **** **** **** **** **** **** +14786 Psychic_Warrior_EnergyAdaptCold **** **** **** **** **** **** **** **** +14787 Psychic_Warrior_EnergyAdaptElec **** **** **** **** **** **** **** **** +14788 Psychic_Warrior_EnergyAdaptFire **** **** **** **** **** **** **** **** +14789 Psychic_Warrior_EnergyAdaptSonic **** **** **** **** **** **** **** **** +14790 Psychic_Warrior_Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +14791 Psychic_Warrior_Energy_Missile_Cold **** **** **** **** **** **** **** **** +14792 Psychic_Warrior_Energy_Missile_Elec **** **** **** **** **** **** **** **** +14793 Psychic_Warrior_Energy_Missile_Fire **** **** **** **** **** **** **** **** +14794 Psychic_Warrior_Energy_Missile_Sonic **** **** **** **** **** **** **** **** +14795 Psychic_Warrior_EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +14796 Psychic_Warrior_EnergyPush_Cold **** **** **** **** **** **** **** **** +14797 Psychic_Warrior_EnergyPush_Elec **** **** **** **** **** **** **** **** +14798 Psychic_Warrior_EnergyPush_Fire **** **** **** **** **** **** **** **** +14799 Psychic_Warrior_EnergyPush_Sonic **** **** **** **** **** **** **** **** +14800 Psychic_Warrior_EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +14801 Psychic_Warrior_EnergyStun_Cold **** **** **** **** **** **** **** **** +14802 Psychic_Warrior_EnergyStun_Elec **** **** **** **** **** **** **** **** +14803 Psychic_Warrior_EnergyStun_Fire **** **** **** **** **** **** **** **** +14804 Psychic_Warrior_EnergyStun_Sonic **** **** **** **** **** **** **** **** +14805 Psychic_Warrior_Hustle **** **** **** **** **** **** **** **** +14806 Psychic_Warrior_Identify **** **** **** **** **** **** **** **** +14807 Psychic_Warrior_IdInsinuation **** **** **** **** **** **** **** **** +14808 Psychic_Warrior_InflictPain **** **** **** **** **** **** **** **** +14809 Psychic_Warrior_Knock **** **** **** **** **** **** **** **** +14810 Psychic_Warrior_Lock **** **** **** **** **** **** **** **** +14811 Psychic_Warrior_MindDisrupt **** **** **** **** **** **** **** **** +14812 Psychic_Warrior_PainfulStrike **** **** **** **** **** **** **** **** +14813 Psychic_Warrior_RecallAgony **** **** **** **** **** **** **** **** +14814 Psychic_Warrior_RepairDamage **** **** **** **** **** **** **** **** +14815 Psychic_Warrior_SharePain **** **** **** **** **** **** **** **** +14816 Psychic_Warrior_StrengthOfMyEnemy **** **** **** **** **** **** **** **** +14817 Psychic_Warrior_ThoughtShield **** **** **** **** **** **** **** **** +14818 Psychic_Warrior_ClawOfTheVampire **** **** **** **** **** **** **** **** +14819 Psychic_Warrior_CrisisBreath **** **** **** **** **** **** **** **** +14820 Psychic_Warrior_Danger_Sense **** **** **** **** **** **** **** **** +14821 Psychic_Warrior_DimensionSlide **** **** **** **** **** **** **** **** +14822 Psychic_Warrior_Dispel_Psionics **** **** **** **** **** **** **** **** +14823 Psychic_Warrior_DuodimensionalClaw **** **** **** **** **** **** **** **** +14824 Psychic_Warrior_EctoCocoon **** **** **** **** **** **** **** **** +14825 Psychic_Warrior_EctoplasmicForm **** **** **** **** **** **** **** **** +14826 Psychic_Warrior_EmpathicFeedback **** **** **** **** **** **** **** **** +14827 Psychic_Warrior_EmpathicTransferHostile **** **** **** **** **** **** **** **** +14828 Psychic_Warrior_EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +14829 Psychic_Warrior_Energy_Bolt_Cold **** **** **** **** **** **** **** **** +14830 Psychic_Warrior_Energy_Bolt_Elec **** **** **** **** **** **** **** **** +14831 Psychic_Warrior_Energy_Bolt_Fire **** **** **** **** **** **** **** **** +14832 Psychic_Warrior_Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +14833 Psychic_Warrior_EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +14834 Psychic_Warrior_Energy_Burst_Cold **** **** **** **** **** **** **** **** +14835 Psychic_Warrior_Energy_Burst_Elec **** **** **** **** **** **** **** **** +14836 Psychic_Warrior_Energy_Burst_Fire **** **** **** **** **** **** **** **** +14837 Psychic_Warrior_Energy_Burst_Sonic **** **** **** **** **** **** **** **** +14838 Psychic_Warrior_Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +14839 Psychic_Warrior_EnergyCone_Cold **** **** **** **** **** **** **** **** +14840 Psychic_Warrior_EnergyCone_Elec **** **** **** **** **** **** **** **** +14841 Psychic_Warrior_EnergyCone_Fire **** **** **** **** **** **** **** **** +14842 Psychic_Warrior_EnergyCone_Sonic **** **** **** **** **** **** **** **** +14843 Psychic_Warrior_EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +14844 Psychic_Warrior_Energy_Retort_Cold **** **** **** **** **** **** **** **** +14845 Psychic_Warrior_Energy_Retort_Elec **** **** **** **** **** **** **** **** +14846 Psychic_Warrior_Energy_Retort_Fire **** **** **** **** **** **** **** **** +14847 Psychic_Warrior_Energy_Retort_Sonic **** **** **** **** **** **** **** **** +14848 Psychic_Warrior_EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +14849 Psychic_Warrior_Energy_Wall_Cold **** **** **** **** **** **** **** **** +14850 Psychic_Warrior_Energy_Wall_Elec **** **** **** **** **** **** **** **** +14851 Psychic_Warrior_Energy_Wall_Fire **** **** **** **** **** **** **** **** +14852 Psychic_Warrior_Energy_Wall_Sonic **** **** **** **** **** **** **** **** +14853 Psychic_Warrior_Eradicate_Invisibility **** **** **** **** **** **** **** **** +14854 Psychic_Warrior_EscapeDetection **** **** **** **** **** **** **** **** +14855 Psychic_Warrior_EvadeBurst **** **** **** **** **** **** **** **** +14856 Psychic_Warrior_Exhale_BlackDrag **** **** **** **** **** **** **** **** +14857 Psychic_Warrior_FateLink **** **** **** **** **** **** **** **** +14858 Psychic_Warrior_Greater_Amorpha **** **** **** **** **** **** **** **** +14859 Psychic_Warrior_Keen_Edge **** **** **** **** **** **** **** **** +14860 Psychic_Warrior_MentalBarrier **** **** **** **** **** **** **** **** +14861 Psychic_Warrior_Mindtrap **** **** **** **** **** **** **** **** +14862 Psychic_Warrior_Psiblast **** **** **** **** **** **** **** **** +14863 Psychic_Warrior_SharePainForced **** **** **** **** **** **** **** **** +14864 Psychic_Warrior_TimeHop **** **** **** **** **** **** **** **** +14865 Psychic_Warrior_Touchsight **** **** **** **** **** **** **** **** +14866 Psychic_Warrior_UbiqVision **** **** **** **** **** **** **** **** +14867 Psychic_Warrior_VampiricWeapon **** **** **** **** **** **** **** **** +14868 Psychic_Warrior_ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14869 Psychic_Warrior_ClawofEnergyCold **** **** **** **** **** **** **** **** +14870 Psychic_Warrior_ClawofEnergyElec **** **** **** **** **** **** **** **** +14871 Psychic_Warrior_ClawofEnergyFire **** **** **** **** **** **** **** **** +14872 Psychic_Warrior_DetectRemoteViewing **** **** **** **** **** **** **** **** +14873 Psychic_Warrior_DimensionalAnchor **** **** **** **** **** **** **** **** +14874 Psychic_Warrior_DimensionDoor_Master **** **** **** **** **** **** **** **** +14875 Psychic_Warrior_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +14876 Psychic_Warrior_DimensionDoor_Party **** **** **** **** **** **** **** **** +14877 Psychic_Warrior_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +14878 Psychic_Warrior_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +14879 Psychic_Warrior_Dismissal **** **** **** **** **** **** **** **** +14880 Psychic_Warrior_EnergyAdaption **** **** **** **** **** **** **** **** +14881 Psychic_Warrior_EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +14882 Psychic_Warrior_EnergyBall_Cold **** **** **** **** **** **** **** **** +14883 Psychic_Warrior_EnergyBall_Elec **** **** **** **** **** **** **** **** +14884 Psychic_Warrior_EnergyBall_Fire **** **** **** **** **** **** **** **** +14885 Psychic_Warrior_EnergyBall_Sonic **** **** **** **** **** **** **** **** +14886 Psychic_Warrior_Freedom_of_Movement **** **** **** **** **** **** **** **** +14887 Psychic_Warrior_Immovability **** **** **** **** **** **** **** **** +14888 Psychic_Warrior_InertialBar **** **** **** **** **** **** **** **** +14889 Psychic_Warrior_IntellectFortress **** **** **** **** **** **** **** **** +14890 Psychic_Warrior_Mindwipe **** **** **** **** **** **** **** **** +14891 Psychic_Warrior_PowerLeech **** **** **** **** **** **** **** **** +14892 Psychic_Warrior_Dominate_Psionic **** **** **** **** **** **** **** **** +14893 Psychic_Warrior_PsychicReformation **** **** **** **** **** **** **** **** +14894 Psychic_Warrior_PsychicVampire **** **** **** **** **** **** **** **** +14895 Psychic_Warrior_RemoteViewing **** **** **** **** **** **** **** **** +14896 Psychic_Warrior_SteadfastPercep **** **** **** **** **** **** **** **** +14897 Psychic_Warrior_TelekineticManeuver **** **** **** **** **** **** **** **** +14898 Psychic_Warrior_Truevenom **** **** **** **** **** **** **** **** +14899 Psychic_Warrior_TruevenomWeapon **** **** **** **** **** **** **** **** +14900 Psychic_Warrior_WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +14901 Psychic_Warrior_WeaponofEnergyCold **** **** **** **** **** **** **** **** +14902 Psychic_Warrior_WeaponofEnergyElec **** **** **** **** **** **** **** **** +14903 Psychic_Warrior_WeaponofEnergyFire **** **** **** **** **** **** **** **** +14904 Psychic_Warrior_BaleTeleport **** **** **** **** **** **** **** **** +14905 Psychic_Warrior_Catapsi **** **** **** **** **** **** **** **** +14906 Psychic_Warrior_ClairtangentHand **** **** **** **** **** **** **** **** +14907 Psychic_Warrior_EctoplasmicShambler **** **** **** **** **** **** **** **** +14908 Psychic_Warrior_EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +14909 Psychic_Warrior_EnergyCurrent_Cold **** **** **** **** **** **** **** **** +14910 Psychic_Warrior_EnergyCurrent_Elec **** **** **** **** **** **** **** **** +14911 Psychic_Warrior_EnergyCurrent_Fire **** **** **** **** **** **** **** **** +14912 Psychic_Warrior_EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +14913 Psychic_Warrior_HailCrystals **** **** **** **** **** **** **** **** +14914 Psychic_Warrior_OakBody **** **** **** **** **** **** **** **** +14915 Psychic_Warrior_Power_Resistance **** **** **** **** **** **** **** **** +14916 Psychic_Warrior_PsionicRevivify **** **** **** **** **** **** **** **** +14917 Psychic_Warrior_PsychicCrush **** **** **** **** **** **** **** **** +14918 Psychic_Warrior_Psychofeedback **** **** **** **** **** **** **** **** +14919 Psychic_Warrior_SecondChance **** **** **** **** **** **** **** **** +14920 Psychic_Warrior_ShatterMindBlank **** **** **** **** **** **** **** **** +14921 Psychic_Warrior_Teleport_RadialMaster **** **** **** **** **** **** **** **** +14922 Psychic_Warrior_Teleport_SelfOnly **** **** **** **** **** **** **** **** +14923 Psychic_Warrior_Teleport_Party **** **** **** **** **** **** **** **** +14924 Psychic_Warrior_TowerIronWill **** **** **** **** **** **** **** **** +14925 Psychic_Warrior_True_Seeing **** **** **** **** **** **** **** **** +14926 Psychic_Warrior_Banishment **** **** **** **** **** **** **** **** +14927 Psychic_Warrior_BreathBlackDragon **** **** **** **** **** **** **** **** +14928 Psychic_Warrior_Cloud_Mind_Mass **** **** **** **** **** **** **** **** +14929 Psychic_Warrior_Crystallize **** **** **** **** **** **** **** **** +14930 Psychic_Warrior_Disintegrate **** **** **** **** **** **** **** **** +14931 Psychic_Warrior_DispellingBuffer **** **** **** **** **** **** **** **** +14932 Psychic_Warrior_FormOfDoom **** **** **** **** **** **** **** **** +14933 Psychic_Warrior_FuseFlesh **** **** **** **** **** **** **** **** +14934 Psychic_Warrior_GreatPrecognition_RadialMaster **** **** **** **** **** **** **** **** +14935 Psychic_Warrior_GreatPrecognitionMain **** **** **** **** **** **** **** **** +14936 Psychic_Warrior_GreatPrecognitionAttack **** **** **** **** **** **** **** **** +14937 Psychic_Warrior_GreatPrecognitionDamage **** **** **** **** **** **** **** **** +14938 Psychic_Warrior_GreatPrecognitionSaves **** **** **** **** **** **** **** **** +14939 Psychic_Warrior_GreatPrecognitionSkills **** **** **** **** **** **** **** **** +14940 Psychic_Warrior_Mind_BlankPersonal **** **** **** **** **** **** **** **** +14941 Psychic_Warrior_NullPsionicsField **** **** **** **** **** **** **** **** +14942 Psychic_Warrior_RemoteViewTrap **** **** **** **** **** **** **** **** +14943 Psychic_Warrior_RestorationPsionic **** **** **** **** **** **** **** **** +14944 Psychic_Warrior_Retrieve **** **** **** **** **** **** **** **** +14945 Psychic_Warrior_TemporalAcceleration **** **** **** **** **** **** **** **** +14946 Wilder_AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +14947 Wilder_AstralConstruct_Conversation **** **** **** **** **** **** **** **** +14948 Wilder_AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +14949 Wilder_AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +14950 Wilder_AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +14951 Wilder_AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +14952 Wilder_BiteOfTheWolf **** **** **** **** **** **** **** **** +14953 Wilder_Bolt **** **** **** **** **** **** **** **** +14954 Wilder_Burst **** **** **** **** **** **** **** **** +14955 Wilder_CallToMind **** **** **** **** **** **** **** **** +14956 Wilder_CallWeaponry **** **** **** **** **** **** **** **** +14957 Wilder_CharmPerson **** **** **** **** **** **** **** **** +14958 Wilder_ClawsOfTheBeast **** **** **** **** **** **** **** **** +14959 Wilder_Compression **** **** **** **** **** **** **** **** +14960 Wilder_Conceal_Thoughts **** **** **** **** **** **** **** **** +14961 Wilder_ControlObject **** **** **** **** **** **** **** **** +14962 Wilder_CreateSound **** **** **** **** **** **** **** **** +14963 Wilder_CrystalShard **** **** **** **** **** **** **** **** +14964 Wilder_Daze **** **** **** **** **** **** **** **** +14965 Wilder_Deceleration **** **** **** **** **** **** **** **** +14966 Wilder_DefPrecog **** **** **** **** **** **** **** **** +14967 Wilder_Demoralize **** **** **** **** **** **** **** **** +14968 Wilder_DestinyDissonance **** **** **** **** **** **** **** **** +14969 Wilder_Disable **** **** **** **** **** **** **** **** +14970 Wilder_DissipatingTouch **** **** **** **** **** **** **** **** +14971 Wilder_Distract **** **** **** **** **** **** **** **** +14972 Wilder_Empathy **** **** **** **** **** **** **** **** +14973 Wilder_EmptyMind **** **** **** **** **** **** **** **** +14974 Wilder_EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +14975 Wilder_EnergyRay_Cold **** **** **** **** **** **** **** **** +14976 Wilder_EnergyRay_Elec **** **** **** **** **** **** **** **** +14977 Wilder_EnergyRay_Fire **** **** **** **** **** **** **** **** +14978 Wilder_EnergyRay_Sonic **** **** **** **** **** **** **** **** +14979 Wilder_EntanglingEctoplasm **** **** **** **** **** **** **** **** +14980 Wilder_Expansion **** **** **** **** **** **** **** **** +14981 Wilder_Far_Hand **** **** **** **** **** **** **** **** +14982 Wilder_ForceScreen **** **** **** **** **** **** **** **** +14983 Wilder_Grease **** **** **** **** **** **** **** **** +14984 Wilder_Hammer **** **** **** **** **** **** **** **** +14985 Wilder_InertialArmour **** **** **** **** **** **** **** **** +14986 Wilder_Matter_Agitation **** **** **** **** **** **** **** **** +14987 Wilder_MetaphysicalClaw **** **** **** **** **** **** **** **** +14988 Wilder_MetaphysicalWeapon **** **** **** **** **** **** **** **** +14989 Wilder_MindThrust **** **** **** **** **** **** **** **** +14990 Wilder_MyLight **** **** **** **** **** **** **** **** +14991 Wilder_OffPrecog **** **** **** **** **** **** **** **** +14992 Wilder_OffPresc **** **** **** **** **** **** **** **** +14993 Wilder_Precognition_RadialMaster **** **** **** **** **** **** **** **** +14994 Wilder_PrecognitionMain **** **** **** **** **** **** **** **** +14995 Wilder_PrecognitionAttack **** **** **** **** **** **** **** **** +14996 Wilder_PrecognitionDamage **** **** **** **** **** **** **** **** +14997 Wilder_PrecognitionSaves **** **** **** **** **** **** **** **** +14998 Wilder_PrecognitionSkills **** **** **** **** **** **** **** **** +14999 Wilder_Prevenom **** **** **** **** **** **** **** **** +15000 Wilder_PrevenomWeapon **** **** **** **** **** **** **** **** +15001 Wilder_Skate **** **** **** **** **** **** **** **** +15002 Wilder_Stomp **** **** **** **** **** **** **** **** +15003 Wilder_Synesthete **** **** **** **** **** **** **** **** +15004 Wilder_Telempathic_Projection **** **** **** **** **** **** **** **** +15005 Wilder_ThickSkin **** **** **** **** **** **** **** **** +15006 Wilder_Vigor **** **** **** **** **** **** **** **** +15007 Wilder_AnimalAffinity **** **** **** **** **** **** **** **** +15008 Wilder_Aversion **** **** **** **** **** **** **** **** +15009 Wilder_BestowPower **** **** **** **** **** **** **** **** +15010 Wilder_Biofeedback **** **** **** **** **** **** **** **** +15011 Wilder_Body_Equilibrium **** **** **** **** **** **** **** **** +15012 Wilder_BrainLock **** **** **** **** **** **** **** **** +15013 Wilder_Chameleon **** **** **** **** **** **** **** **** +15014 Wilder_ClairvoyantSense **** **** **** **** **** **** **** **** +15015 Wilder_Cloud_Mind **** **** **** **** **** **** **** **** +15016 Wilder_ConcBlast **** **** **** **** **** **** **** **** +15017 Wilder_ConcealAmorpha **** **** **** **** **** **** **** **** +15018 Wilder_ControlAir **** **** **** **** **** **** **** **** +15019 Wilder_ControlSound **** **** **** **** **** **** **** **** +15020 Wilder_SwarmOfCrystals **** **** **** **** **** **** **** **** +15021 Wilder_DimensionSwap **** **** **** **** **** **** **** **** +15022 Wilder_DissolvingTouch **** **** **** **** **** **** **** **** +15023 Wilder_Dissolving_Weapon **** **** **** **** **** **** **** **** +15024 Wilder_EgoWhip **** **** **** **** **** **** **** **** +15025 Wilder_ElfSight **** **** **** **** **** **** **** **** +15026 Wilder_EmpathicTransfer **** **** **** **** **** **** **** **** +15027 Wilder_EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +15028 Wilder_EnergyAdaptAcid **** **** **** **** **** **** **** **** +15029 Wilder_EnergyAdaptCold **** **** **** **** **** **** **** **** +15030 Wilder_EnergyAdaptElec **** **** **** **** **** **** **** **** +15031 Wilder_EnergyAdaptFire **** **** **** **** **** **** **** **** +15032 Wilder_EnergyAdaptSonic **** **** **** **** **** **** **** **** +15033 Wilder_Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +15034 Wilder_Energy_Missile_Cold **** **** **** **** **** **** **** **** +15035 Wilder_Energy_Missile_Elec **** **** **** **** **** **** **** **** +15036 Wilder_Energy_Missile_Fire **** **** **** **** **** **** **** **** +15037 Wilder_Energy_Missile_Sonic **** **** **** **** **** **** **** **** +15038 Wilder_EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +15039 Wilder_EnergyPush_Cold **** **** **** **** **** **** **** **** +15040 Wilder_EnergyPush_Elec **** **** **** **** **** **** **** **** +15041 Wilder_EnergyPush_Fire **** **** **** **** **** **** **** **** +15042 Wilder_EnergyPush_Sonic **** **** **** **** **** **** **** **** +15043 Wilder_EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +15044 Wilder_EnergyStun_Cold **** **** **** **** **** **** **** **** +15045 Wilder_EnergyStun_Elec **** **** **** **** **** **** **** **** +15046 Wilder_EnergyStun_Fire **** **** **** **** **** **** **** **** +15047 Wilder_EnergyStun_Sonic **** **** **** **** **** **** **** **** +15048 Wilder_Identify **** **** **** **** **** **** **** **** +15049 Wilder_IdInsinuation **** **** **** **** **** **** **** **** +15050 Wilder_InflictPain **** **** **** **** **** **** **** **** +15051 Wilder_Knock **** **** **** **** **** **** **** **** +15052 Wilder_Lock **** **** **** **** **** **** **** **** +15053 Wilder_MindDisrupt **** **** **** **** **** **** **** **** +15054 Wilder_PainfulStrike **** **** **** **** **** **** **** **** +15055 Wilder_RecallAgony **** **** **** **** **** **** **** **** +15056 Wilder_RepairDamage **** **** **** **** **** **** **** **** +15057 Wilder_SharePain **** **** **** **** **** **** **** **** +15058 Wilder_StrengthOfMyEnemy **** **** **** **** **** **** **** **** +15059 Wilder_ThoughtShield **** **** **** **** **** **** **** **** +15060 Wilder_BodyAdjustment **** **** **** **** **** **** **** **** +15061 Wilder_BodyPurification **** **** **** **** **** **** **** **** +15062 Wilder_ClawOfTheVampire **** **** **** **** **** **** **** **** +15063 Wilder_CrisisBreath **** **** **** **** **** **** **** **** +15064 Wilder_Danger_Sense **** **** **** **** **** **** **** **** +15065 Wilder_Darkvision **** **** **** **** **** **** **** **** +15066 Wilder_DimensionSlide **** **** **** **** **** **** **** **** +15067 Wilder_Dispel_Psionics **** **** **** **** **** **** **** **** +15068 Wilder_DuodimensionalClaw **** **** **** **** **** **** **** **** +15069 Wilder_EctoCocoon **** **** **** **** **** **** **** **** +15070 Wilder_EctoplasmicForm **** **** **** **** **** **** **** **** +15071 Wilder_EmpathicTransferHostile **** **** **** **** **** **** **** **** +15072 Wilder_EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +15073 Wilder_Energy_Bolt_Cold **** **** **** **** **** **** **** **** +15074 Wilder_Energy_Bolt_Elec **** **** **** **** **** **** **** **** +15075 Wilder_Energy_Bolt_Fire **** **** **** **** **** **** **** **** +15076 Wilder_Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +15077 Wilder_EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +15078 Wilder_Energy_Burst_Cold **** **** **** **** **** **** **** **** +15079 Wilder_Energy_Burst_Elec **** **** **** **** **** **** **** **** +15080 Wilder_Energy_Burst_Fire **** **** **** **** **** **** **** **** +15081 Wilder_Energy_Burst_Sonic **** **** **** **** **** **** **** **** +15082 Wilder_Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +15083 Wilder_EnergyCone_Cold **** **** **** **** **** **** **** **** +15084 Wilder_EnergyCone_Elec **** **** **** **** **** **** **** **** +15085 Wilder_EnergyCone_Fire **** **** **** **** **** **** **** **** +15086 Wilder_EnergyCone_Sonic **** **** **** **** **** **** **** **** +15087 Wilder_EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +15088 Wilder_Energy_Retort_Cold **** **** **** **** **** **** **** **** +15089 Wilder_Energy_Retort_Elec **** **** **** **** **** **** **** **** +15090 Wilder_Energy_Retort_Fire **** **** **** **** **** **** **** **** +15091 Wilder_Energy_Retort_Sonic **** **** **** **** **** **** **** **** +15092 Wilder_EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +15093 Wilder_Energy_Wall_Cold **** **** **** **** **** **** **** **** +15094 Wilder_Energy_Wall_Elec **** **** **** **** **** **** **** **** +15095 Wilder_Energy_Wall_Fire **** **** **** **** **** **** **** **** +15096 Wilder_Energy_Wall_Sonic **** **** **** **** **** **** **** **** +15097 Wilder_Eradicate_Invisibility **** **** **** **** **** **** **** **** +15098 Wilder_EscapeDetection **** **** **** **** **** **** **** **** +15099 Wilder_Exhale_BlackDrag **** **** **** **** **** **** **** **** +15100 Wilder_FateLink **** **** **** **** **** **** **** **** +15101 Wilder_Greater_Amorpha **** **** **** **** **** **** **** **** +15102 Wilder_Hustle **** **** **** **** **** **** **** **** +15103 Wilder_Keen_Edge **** **** **** **** **** **** **** **** +15104 Wilder_MentalBarrier **** **** **** **** **** **** **** **** +15105 Wilder_Mindtrap **** **** **** **** **** **** **** **** +15106 Wilder_Psiblast **** **** **** **** **** **** **** **** +15107 Wilder_SharePainForced **** **** **** **** **** **** **** **** +15108 Wilder_TimeHop **** **** **** **** **** **** **** **** +15109 Wilder_Touchsight **** **** **** **** **** **** **** **** +15110 Wilder_UbiqVision **** **** **** **** **** **** **** **** +15111 Wilder_VampiricWeapon **** **** **** **** **** **** **** **** +15112 Wilder_ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15113 Wilder_ClawofEnergyCold **** **** **** **** **** **** **** **** +15114 Wilder_ClawofEnergyElec **** **** **** **** **** **** **** **** +15115 Wilder_ClawofEnergyFire **** **** **** **** **** **** **** **** +15116 Wilder_DetectRemoteViewing **** **** **** **** **** **** **** **** +15117 Wilder_DimensionalAnchor **** **** **** **** **** **** **** **** +15118 Wilder_DimensionDoor_Master **** **** **** **** **** **** **** **** +15119 Wilder_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +15120 Wilder_DimensionDoor_Party **** **** **** **** **** **** **** **** +15121 Wilder_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +15122 Wilder_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +15123 Wilder_Dismissal **** **** **** **** **** **** **** **** +15124 Wilder_EmpathicFeedback **** **** **** **** **** **** **** **** +15125 Wilder_EnergyAdaption **** **** **** **** **** **** **** **** +15126 Wilder_EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +15127 Wilder_EnergyBall_Cold **** **** **** **** **** **** **** **** +15128 Wilder_EnergyBall_Elec **** **** **** **** **** **** **** **** +15129 Wilder_EnergyBall_Fire **** **** **** **** **** **** **** **** +15130 Wilder_EnergyBall_Sonic **** **** **** **** **** **** **** **** +15131 Wilder_Freedom_of_Movement **** **** **** **** **** **** **** **** +15132 Wilder_Immovability **** **** **** **** **** **** **** **** +15133 Wilder_InertialBar **** **** **** **** **** **** **** **** +15134 Wilder_IntellectFortress **** **** **** **** **** **** **** **** +15135 Wilder_Mindwipe **** **** **** **** **** **** **** **** +15136 Wilder_PowerLeech **** **** **** **** **** **** **** **** +15137 Wilder_Dominate_Psionic **** **** **** **** **** **** **** **** +15138 Wilder_PsychicReformation **** **** **** **** **** **** **** **** +15139 Wilder_PsychicVampire **** **** **** **** **** **** **** **** +15140 Wilder_RemoteViewing **** **** **** **** **** **** **** **** +15141 Wilder_SteadfastPercep **** **** **** **** **** **** **** **** +15142 Wilder_TelekineticManeuver **** **** **** **** **** **** **** **** +15143 Wilder_Truevenom **** **** **** **** **** **** **** **** +15144 Wilder_TruevenomWeapon **** **** **** **** **** **** **** **** +15145 Wilder_WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15146 Wilder_WeaponofEnergyCold **** **** **** **** **** **** **** **** +15147 Wilder_WeaponofEnergyElec **** **** **** **** **** **** **** **** +15148 Wilder_WeaponofEnergyFire **** **** **** **** **** **** **** **** +15149 Wilder_BaleTeleport **** **** **** **** **** **** **** **** +15150 Wilder_Catapsi **** **** **** **** **** **** **** **** +15151 Wilder_ClairtangentHand **** **** **** **** **** **** **** **** +15152 Wilder_EctoplasmicShambler **** **** **** **** **** **** **** **** +15153 Wilder_EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +15154 Wilder_EnergyCurrent_Cold **** **** **** **** **** **** **** **** +15155 Wilder_EnergyCurrent_Elec **** **** **** **** **** **** **** **** +15156 Wilder_EnergyCurrent_Fire **** **** **** **** **** **** **** **** +15157 Wilder_EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +15158 Wilder_HailCrystals **** **** **** **** **** **** **** **** +15159 Wilder_Power_Resistance **** **** **** **** **** **** **** **** +15160 Wilder_PsionicRevivify **** **** **** **** **** **** **** **** +15161 Wilder_PsychicCrush **** **** **** **** **** **** **** **** +15162 Wilder_Psychofeedback **** **** **** **** **** **** **** **** +15163 Wilder_SecondChance **** **** **** **** **** **** **** **** +15164 Wilder_ShatterMindBlank **** **** **** **** **** **** **** **** +15165 Wilder_Teleport_RadialMaster **** **** **** **** **** **** **** **** +15166 Wilder_Teleport_SelfOnly **** **** **** **** **** **** **** **** +15167 Wilder_Teleport_Party **** **** **** **** **** **** **** **** +15168 Wilder_TowerIronWill **** **** **** **** **** **** **** **** +15169 Wilder_True_Seeing **** **** **** **** **** **** **** **** +15170 Wilder_Banishment **** **** **** **** **** **** **** **** +15171 Wilder_BreathBlackDragon **** **** **** **** **** **** **** **** +15172 Wilder_Cloud_Mind_Mass **** **** **** **** **** **** **** **** +15173 Wilder_Crystallize **** **** **** **** **** **** **** **** +15174 Wilder_Disintegrate **** **** **** **** **** **** **** **** +15175 Wilder_DispellingBuffer **** **** **** **** **** **** **** **** +15176 Wilder_FormOfDoom **** **** **** **** **** **** **** **** +15177 Wilder_FuseFlesh **** **** **** **** **** **** **** **** +15178 Wilder_GreatPrecognition_RadialMaster **** **** **** **** **** **** **** **** +15179 Wilder_GreatPrecognitionMain **** **** **** **** **** **** **** **** +15180 Wilder_GreatPrecognitionAttack **** **** **** **** **** **** **** **** +15181 Wilder_GreatPrecognitionDamage **** **** **** **** **** **** **** **** +15182 Wilder_GreatPrecognitionSaves **** **** **** **** **** **** **** **** +15183 Wilder_GreatPrecognitionSkills **** **** **** **** **** **** **** **** +15184 Wilder_NullPsionicsField **** **** **** **** **** **** **** **** +15185 Wilder_RemoteViewTrap **** **** **** **** **** **** **** **** +15186 Wilder_RestorationPsionic **** **** **** **** **** **** **** **** +15187 Wilder_Retrieve **** **** **** **** **** **** **** **** +15188 Wilder_TemporalAcceleration **** **** **** **** **** **** **** **** +15189 Wilder_CrisisLife **** **** **** **** **** **** **** **** +15190 Wilder_Decerebrate **** **** **** **** **** **** **** **** +15191 Wilder_EctoCocoonMass **** **** **** **** **** **** **** **** +15192 Wilder_EnergyWave_RadialMaster **** **** **** **** **** **** **** **** +15193 Wilder_EnergyWaveCold **** **** **** **** **** **** **** **** +15194 Wilder_EnergyWaveElec **** **** **** **** **** **** **** **** +15195 Wilder_EnergyWaveFire **** **** **** **** **** **** **** **** +15196 Wilder_EnergyWaveSonic **** **** **** **** **** **** **** **** +15197 Wilder_EtherealJaunt **** **** **** **** **** **** **** **** +15198 Wilder_EvadeBurst **** **** **** **** **** **** **** **** +15199 Wilder_Insanity **** **** **** **** **** **** **** **** +15200 Wilder_Mind_BlankPersonal **** **** **** **** **** **** **** **** +15201 Wilder_MomentOfPrescience_RadialMaster **** **** **** **** **** **** **** **** +15202 Wilder_MomentOfPrescienceAttack **** **** **** **** **** **** **** **** +15203 Wilder_MomentOfPrescienceArmour **** **** **** **** **** **** **** **** +15204 Wilder_MomentOfPrescienceSaves **** **** **** **** **** **** **** **** +15205 Wilder_MomentOfPrescienceSkills **** **** **** **** **** **** **** **** +15206 Wilder_OakBody **** **** **** **** **** **** **** **** +15207 Wilder_Reddopsi **** **** **** **** **** **** **** **** +15208 Wilder_Sequester **** **** **** **** **** **** **** **** +15209 Wilder_Ultrablast **** **** **** **** **** **** **** **** +15210 Wilder_AstralSeed **** **** **** **** **** **** **** **** +15211 Wilder_GreaterTeleport_RadialMaster **** **** **** **** **** **** **** **** +15212 Wilder_GreaterTeleport_SelfOnly **** **** **** **** **** **** **** **** +15213 Wilder_GreaterTeleport_Party **** **** **** **** **** **** **** **** +15214 Wilder_Hypercognition **** **** **** **** **** **** **** **** +15215 Wilder_IronBody **** **** **** **** **** **** **** **** +15216 Wilder_PsionicMind_Blank **** **** **** **** **** **** **** **** +15217 Wilder_RecallDeath **** **** **** **** **** **** **** **** +15218 Wilder_Shadow_Body **** **** **** **** **** **** **** **** +15219 Wilder_TimeHopMass **** **** **** **** **** **** **** **** +15220 Wilder_TrueMetabolism **** **** **** **** **** **** **** **** +15221 Wilder_Assimilate **** **** **** **** **** **** **** **** +15222 Wilder_Etherealness **** **** **** **** **** **** **** **** +15223 Wilder_Genesis **** **** **** **** **** **** **** **** +15224 Wilder_Microcosm **** **** **** **** **** **** **** **** +15225 Wilder_PsychicChirurgery_Repair **** **** **** **** **** **** **** **** +15226 Wilder_TeleportationCircle_RadialMaster **** **** **** **** **** **** **** **** +15227 Wilder_TeleportationCircle_Visible **** **** **** **** **** **** **** **** +15228 Wilder_TeleportationCircle_Hidden **** **** **** **** **** **** **** **** +15229 Wilder_TimelessBody **** **** **** **** **** **** **** **** +15230 Wilder_TornadoBlast **** **** **** **** **** **** **** **** +15231 FistOfZouken_AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +15232 FistOfZouken_AstralConstruct_Conversation **** **** **** **** **** **** **** **** +15233 FistOfZouken_AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +15234 FistOfZouken_AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +15235 FistOfZouken_AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +15236 FistOfZouken_AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +15237 FistOfZouken_Biofeedback **** **** **** **** **** **** **** **** +15238 FistOfZouken_BiteOfTheWolf **** **** **** **** **** **** **** **** +15239 FistOfZouken_Bolt **** **** **** **** **** **** **** **** +15240 FistOfZouken_Burst **** **** **** **** **** **** **** **** +15241 FistOfZouken_CallToMind **** **** **** **** **** **** **** **** +15242 FistOfZouken_CallWeaponry **** **** **** **** **** **** **** **** +15243 FistOfZouken_Chameleon **** **** **** **** **** **** **** **** +15244 FistOfZouken_CharmPerson **** **** **** **** **** **** **** **** +15245 FistOfZouken_ClawsOfTheBeast **** **** **** **** **** **** **** **** +15246 FistOfZouken_Compression **** **** **** **** **** **** **** **** +15247 FistOfZouken_Conceal_Thoughts **** **** **** **** **** **** **** **** +15248 FistOfZouken_ControlObject **** **** **** **** **** **** **** **** +15249 FistOfZouken_CreateSound **** **** **** **** **** **** **** **** +15250 FistOfZouken_CrystalShard **** **** **** **** **** **** **** **** +15251 FistOfZouken_Daze **** **** **** **** **** **** **** **** +15252 FistOfZouken_Deceleration **** **** **** **** **** **** **** **** +15253 FistOfZouken_DefPrecog **** **** **** **** **** **** **** **** +15254 FistOfZouken_Demoralize **** **** **** **** **** **** **** **** +15255 FistOfZouken_DestinyDissonance **** **** **** **** **** **** **** **** +15256 FistOfZouken_Disable **** **** **** **** **** **** **** **** +15257 FistOfZouken_DissipatingTouch **** **** **** **** **** **** **** **** +15258 FistOfZouken_Distract **** **** **** **** **** **** **** **** +15259 FistOfZouken_ElfSight **** **** **** **** **** **** **** **** +15260 FistOfZouken_Empathy **** **** **** **** **** **** **** **** +15261 FistOfZouken_EmptyMind **** **** **** **** **** **** **** **** +15262 FistOfZouken_EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +15263 FistOfZouken_EnergyRay_Cold **** **** **** **** **** **** **** **** +15264 FistOfZouken_EnergyRay_Elec **** **** **** **** **** **** **** **** +15265 FistOfZouken_EnergyRay_Fire **** **** **** **** **** **** **** **** +15266 FistOfZouken_EnergyRay_Sonic **** **** **** **** **** **** **** **** +15267 FistOfZouken_EntanglingEctoplasm **** **** **** **** **** **** **** **** +15268 FistOfZouken_Expansion **** **** **** **** **** **** **** **** +15269 FistOfZouken_Far_Hand **** **** **** **** **** **** **** **** +15270 FistOfZouken_ForceScreen **** **** **** **** **** **** **** **** +15271 FistOfZouken_Grease **** **** **** **** **** **** **** **** +15272 FistOfZouken_Hammer **** **** **** **** **** **** **** **** +15273 FistOfZouken_InertialArmour **** **** **** **** **** **** **** **** +15274 FistOfZouken_Matter_Agitation **** **** **** **** **** **** **** **** +15275 FistOfZouken_MetaphysicalClaw **** **** **** **** **** **** **** **** +15276 FistOfZouken_MetaphysicalWeapon **** **** **** **** **** **** **** **** +15277 FistOfZouken_MindThrust **** **** **** **** **** **** **** **** +15278 FistOfZouken_MyLight **** **** **** **** **** **** **** **** +15279 FistOfZouken_OffPrecog **** **** **** **** **** **** **** **** +15280 FistOfZouken_OffPresc **** **** **** **** **** **** **** **** +15281 FistOfZouken_Precognition_RadialMaster **** **** **** **** **** **** **** **** +15282 FistOfZouken_PrecognitionMain **** **** **** **** **** **** **** **** +15283 FistOfZouken_PrecognitionAttack **** **** **** **** **** **** **** **** +15284 FistOfZouken_PrecognitionDamage **** **** **** **** **** **** **** **** +15285 FistOfZouken_PrecognitionSaves **** **** **** **** **** **** **** **** +15286 FistOfZouken_PrecognitionSkills **** **** **** **** **** **** **** **** +15287 FistOfZouken_Prevenom **** **** **** **** **** **** **** **** +15288 FistOfZouken_PrevenomWeapon **** **** **** **** **** **** **** **** +15289 FistOfZouken_Skate **** **** **** **** **** **** **** **** +15290 FistOfZouken_Stomp **** **** **** **** **** **** **** **** +15291 FistOfZouken_Synesthete **** **** **** **** **** **** **** **** +15292 FistOfZouken_Telempathic_Projection **** **** **** **** **** **** **** **** +15293 FistOfZouken_ThickSkin **** **** **** **** **** **** **** **** +15294 FistOfZouken_Vigor **** **** **** **** **** **** **** **** +15295 FistOfZouken_AnimalAffinity **** **** **** **** **** **** **** **** +15296 FistOfZouken_Aversion **** **** **** **** **** **** **** **** +15297 FistOfZouken_BestowPower **** **** **** **** **** **** **** **** +15298 FistOfZouken_BodyAdjustment **** **** **** **** **** **** **** **** +15299 FistOfZouken_Body_Equilibrium **** **** **** **** **** **** **** **** +15300 FistOfZouken_BodyPurification **** **** **** **** **** **** **** **** +15301 FistOfZouken_BrainLock **** **** **** **** **** **** **** **** +15302 FistOfZouken_ClairvoyantSense **** **** **** **** **** **** **** **** +15303 FistOfZouken_Cloud_Mind **** **** **** **** **** **** **** **** +15304 FistOfZouken_ConcBlast **** **** **** **** **** **** **** **** +15305 FistOfZouken_ConcealAmorpha **** **** **** **** **** **** **** **** +15306 FistOfZouken_ControlAir **** **** **** **** **** **** **** **** +15307 FistOfZouken_ControlSound **** **** **** **** **** **** **** **** +15308 FistOfZouken_SwarmOfCrystals **** **** **** **** **** **** **** **** +15309 FistOfZouken_Darkvision **** **** **** **** **** **** **** **** +15310 FistOfZouken_DimensionSwap **** **** **** **** **** **** **** **** +15311 FistOfZouken_DissolvingTouch **** **** **** **** **** **** **** **** +15312 FistOfZouken_Dissolving_Weapon **** **** **** **** **** **** **** **** +15313 FistOfZouken_EgoWhip **** **** **** **** **** **** **** **** +15314 FistOfZouken_EmpathicTransfer **** **** **** **** **** **** **** **** +15315 FistOfZouken_EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +15316 FistOfZouken_EnergyAdaptAcid **** **** **** **** **** **** **** **** +15317 FistOfZouken_EnergyAdaptCold **** **** **** **** **** **** **** **** +15318 FistOfZouken_EnergyAdaptElec **** **** **** **** **** **** **** **** +15319 FistOfZouken_EnergyAdaptFire **** **** **** **** **** **** **** **** +15320 FistOfZouken_EnergyAdaptSonic **** **** **** **** **** **** **** **** +15321 FistOfZouken_Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +15322 FistOfZouken_Energy_Missile_Cold **** **** **** **** **** **** **** **** +15323 FistOfZouken_Energy_Missile_Elec **** **** **** **** **** **** **** **** +15324 FistOfZouken_Energy_Missile_Fire **** **** **** **** **** **** **** **** +15325 FistOfZouken_Energy_Missile_Sonic **** **** **** **** **** **** **** **** +15326 FistOfZouken_EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +15327 FistOfZouken_EnergyPush_Cold **** **** **** **** **** **** **** **** +15328 FistOfZouken_EnergyPush_Elec **** **** **** **** **** **** **** **** +15329 FistOfZouken_EnergyPush_Fire **** **** **** **** **** **** **** **** +15330 FistOfZouken_EnergyPush_Sonic **** **** **** **** **** **** **** **** +15331 FistOfZouken_EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +15332 FistOfZouken_EnergyStun_Cold **** **** **** **** **** **** **** **** +15333 FistOfZouken_EnergyStun_Elec **** **** **** **** **** **** **** **** +15334 FistOfZouken_EnergyStun_Fire **** **** **** **** **** **** **** **** +15335 FistOfZouken_EnergyStun_Sonic **** **** **** **** **** **** **** **** +15336 FistOfZouken_Hustle **** **** **** **** **** **** **** **** +15337 FistOfZouken_Identify **** **** **** **** **** **** **** **** +15338 FistOfZouken_IdInsinuation **** **** **** **** **** **** **** **** +15339 FistOfZouken_InflictPain **** **** **** **** **** **** **** **** +15340 FistOfZouken_Knock **** **** **** **** **** **** **** **** +15341 FistOfZouken_Lock **** **** **** **** **** **** **** **** +15342 FistOfZouken_MindDisrupt **** **** **** **** **** **** **** **** +15343 FistOfZouken_PainfulStrike **** **** **** **** **** **** **** **** +15344 FistOfZouken_RecallAgony **** **** **** **** **** **** **** **** +15345 FistOfZouken_RepairDamage **** **** **** **** **** **** **** **** +15346 FistOfZouken_SharePain **** **** **** **** **** **** **** **** +15347 FistOfZouken_StrengthOfMyEnemy **** **** **** **** **** **** **** **** +15348 FistOfZouken_ThoughtShield **** **** **** **** **** **** **** **** +15349 FistOfZouken_ClawOfTheVampire **** **** **** **** **** **** **** **** +15350 FistOfZouken_CrisisBreath **** **** **** **** **** **** **** **** +15351 FistOfZouken_Danger_Sense **** **** **** **** **** **** **** **** +15352 FistOfZouken_DimensionSlide **** **** **** **** **** **** **** **** +15353 FistOfZouken_Dispel_Psionics **** **** **** **** **** **** **** **** +15354 FistOfZouken_DuodimensionalClaw **** **** **** **** **** **** **** **** +15355 FistOfZouken_EctoCocoon **** **** **** **** **** **** **** **** +15356 FistOfZouken_EctoplasmicForm **** **** **** **** **** **** **** **** +15357 FistOfZouken_EmpathicFeedback **** **** **** **** **** **** **** **** +15358 FistOfZouken_EmpathicTransferHostile **** **** **** **** **** **** **** **** +15359 FistOfZouken_EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +15360 FistOfZouken_Energy_Bolt_Cold **** **** **** **** **** **** **** **** +15361 FistOfZouken_Energy_Bolt_Elec **** **** **** **** **** **** **** **** +15362 FistOfZouken_Energy_Bolt_Fire **** **** **** **** **** **** **** **** +15363 FistOfZouken_Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +15364 FistOfZouken_EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +15365 FistOfZouken_Energy_Burst_Cold **** **** **** **** **** **** **** **** +15366 FistOfZouken_Energy_Burst_Elec **** **** **** **** **** **** **** **** +15367 FistOfZouken_Energy_Burst_Fire **** **** **** **** **** **** **** **** +15368 FistOfZouken_Energy_Burst_Sonic **** **** **** **** **** **** **** **** +15369 FistOfZouken_Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +15370 FistOfZouken_EnergyCone_Cold **** **** **** **** **** **** **** **** +15371 FistOfZouken_EnergyCone_Elec **** **** **** **** **** **** **** **** +15372 FistOfZouken_EnergyCone_Fire **** **** **** **** **** **** **** **** +15373 FistOfZouken_EnergyCone_Sonic **** **** **** **** **** **** **** **** +15374 FistOfZouken_EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +15375 FistOfZouken_Energy_Retort_Cold **** **** **** **** **** **** **** **** +15376 FistOfZouken_Energy_Retort_Elec **** **** **** **** **** **** **** **** +15377 FistOfZouken_Energy_Retort_Fire **** **** **** **** **** **** **** **** +15378 FistOfZouken_Energy_Retort_Sonic **** **** **** **** **** **** **** **** +15379 FistOfZouken_EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +15380 FistOfZouken_Energy_Wall_Cold **** **** **** **** **** **** **** **** +15381 FistOfZouken_Energy_Wall_Elec **** **** **** **** **** **** **** **** +15382 FistOfZouken_Energy_Wall_Fire **** **** **** **** **** **** **** **** +15383 FistOfZouken_Energy_Wall_Sonic **** **** **** **** **** **** **** **** +15384 FistOfZouken_Eradicate_Invisibility **** **** **** **** **** **** **** **** +15385 FistOfZouken_EscapeDetection **** **** **** **** **** **** **** **** +15386 FistOfZouken_EvadeBurst **** **** **** **** **** **** **** **** +15387 FistOfZouken_Exhale_BlackDrag **** **** **** **** **** **** **** **** +15388 FistOfZouken_FateLink **** **** **** **** **** **** **** **** +15389 FistOfZouken_Greater_Amorpha **** **** **** **** **** **** **** **** +15390 FistOfZouken_Keen_Edge **** **** **** **** **** **** **** **** +15391 FistOfZouken_MentalBarrier **** **** **** **** **** **** **** **** +15392 FistOfZouken_Mindtrap **** **** **** **** **** **** **** **** +15393 FistOfZouken_Psiblast **** **** **** **** **** **** **** **** +15394 FistOfZouken_SharePainForced **** **** **** **** **** **** **** **** +15395 FistOfZouken_TimeHop **** **** **** **** **** **** **** **** +15396 FistOfZouken_Touchsight **** **** **** **** **** **** **** **** +15397 FistOfZouken_UbiqVision **** **** **** **** **** **** **** **** +15398 FistOfZouken_VampiricWeapon **** **** **** **** **** **** **** **** +15399 FistOfZouken_ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15400 FistOfZouken_ClawofEnergyCold **** **** **** **** **** **** **** **** +15401 FistOfZouken_ClawofEnergyElec **** **** **** **** **** **** **** **** +15402 FistOfZouken_ClawofEnergyFire **** **** **** **** **** **** **** **** +15403 FistOfZouken_DetectRemoteViewing **** **** **** **** **** **** **** **** +15404 FistOfZouken_DimensionalAnchor **** **** **** **** **** **** **** **** +15405 FistOfZouken_DimensionDoor_Master **** **** **** **** **** **** **** **** +15406 FistOfZouken_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +15407 FistOfZouken_DimensionDoor_Party **** **** **** **** **** **** **** **** +15408 FistOfZouken_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +15409 FistOfZouken_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +15410 FistOfZouken_Dismissal **** **** **** **** **** **** **** **** +15411 FistOfZouken_EnergyAdaption **** **** **** **** **** **** **** **** +15412 FistOfZouken_EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +15413 FistOfZouken_EnergyBall_Cold **** **** **** **** **** **** **** **** +15414 FistOfZouken_EnergyBall_Elec **** **** **** **** **** **** **** **** +15415 FistOfZouken_EnergyBall_Fire **** **** **** **** **** **** **** **** +15416 FistOfZouken_EnergyBall_Sonic **** **** **** **** **** **** **** **** +15417 FistOfZouken_Freedom_of_Movement **** **** **** **** **** **** **** **** +15418 FistOfZouken_Immovability **** **** **** **** **** **** **** **** +15419 FistOfZouken_InertialBar **** **** **** **** **** **** **** **** +15420 FistOfZouken_IntellectFortress **** **** **** **** **** **** **** **** +15421 FistOfZouken_Mindwipe **** **** **** **** **** **** **** **** +15422 FistOfZouken_PowerLeech **** **** **** **** **** **** **** **** +15423 FistOfZouken_Dominate_Psionic **** **** **** **** **** **** **** **** +15424 FistOfZouken_PsychicReformation **** **** **** **** **** **** **** **** +15425 FistOfZouken_PsychicVampire **** **** **** **** **** **** **** **** +15426 FistOfZouken_RemoteViewing **** **** **** **** **** **** **** **** +15427 FistOfZouken_SteadfastPercep **** **** **** **** **** **** **** **** +15428 FistOfZouken_TelekineticManeuver **** **** **** **** **** **** **** **** +15429 FistOfZouken_Truevenom **** **** **** **** **** **** **** **** +15430 FistOfZouken_TruevenomWeapon **** **** **** **** **** **** **** **** +15431 FistOfZouken_WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15432 FistOfZouken_WeaponofEnergyCold **** **** **** **** **** **** **** **** +15433 FistOfZouken_WeaponofEnergyElec **** **** **** **** **** **** **** **** +15434 FistOfZouken_WeaponofEnergyFire **** **** **** **** **** **** **** **** +15435 FistOfZouken_BaleTeleport **** **** **** **** **** **** **** **** +15436 FistOfZouken_Catapsi **** **** **** **** **** **** **** **** +15437 FistOfZouken_ClairtangentHand **** **** **** **** **** **** **** **** +15438 FistOfZouken_EctoplasmicShambler **** **** **** **** **** **** **** **** +15439 FistOfZouken_EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +15440 FistOfZouken_EnergyCurrent_Cold **** **** **** **** **** **** **** **** +15441 FistOfZouken_EnergyCurrent_Elec **** **** **** **** **** **** **** **** +15442 FistOfZouken_EnergyCurrent_Fire **** **** **** **** **** **** **** **** +15443 FistOfZouken_EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +15444 FistOfZouken_HailCrystals **** **** **** **** **** **** **** **** +15445 FistOfZouken_OakBody **** **** **** **** **** **** **** **** +15446 FistOfZouken_Power_Resistance **** **** **** **** **** **** **** **** +15447 FistOfZouken_PsionicRevivify **** **** **** **** **** **** **** **** +15448 FistOfZouken_PsychicCrush **** **** **** **** **** **** **** **** +15449 FistOfZouken_Psychofeedback **** **** **** **** **** **** **** **** +15450 FistOfZouken_SecondChance **** **** **** **** **** **** **** **** +15451 FistOfZouken_ShatterMindBlank **** **** **** **** **** **** **** **** +15452 FistOfZouken_Teleport_RadialMaster **** **** **** **** **** **** **** **** +15453 FistOfZouken_Teleport_SelfOnly **** **** **** **** **** **** **** **** +15454 FistOfZouken_Teleport_Party **** **** **** **** **** **** **** **** +15455 FistOfZouken_TowerIronWill **** **** **** **** **** **** **** **** +15456 FistOfZouken_True_Seeing **** **** **** **** **** **** **** **** +15457 Warmind_AstralConstruct_RadialMaster **** **** **** **** **** **** **** **** +15458 Warmind_AstralConstruct_Conversation **** **** **** **** **** **** **** **** +15459 Warmind_AstralConstruct_Slot1 **** **** **** **** **** **** **** **** +15460 Warmind_AstralConstruct_Slot2 **** **** **** **** **** **** **** **** +15461 Warmind_AstralConstruct_Slot3 **** **** **** **** **** **** **** **** +15462 Warmind_AstralConstruct_Slot4 **** **** **** **** **** **** **** **** +15463 Warmind_Biofeedback **** **** **** **** **** **** **** **** +15464 Warmind_BiteOfTheWolf **** **** **** **** **** **** **** **** +15465 Warmind_Bolt **** **** **** **** **** **** **** **** +15466 Warmind_Burst **** **** **** **** **** **** **** **** +15467 Warmind_CallToMind **** **** **** **** **** **** **** **** +15468 Warmind_CallWeaponry **** **** **** **** **** **** **** **** +15469 Warmind_Chameleon **** **** **** **** **** **** **** **** +15470 Warmind_CharmPerson **** **** **** **** **** **** **** **** +15471 Warmind_ClawsOfTheBeast **** **** **** **** **** **** **** **** +15472 Warmind_Compression **** **** **** **** **** **** **** **** +15473 Warmind_Conceal_Thoughts **** **** **** **** **** **** **** **** +15474 Warmind_ControlObject **** **** **** **** **** **** **** **** +15475 Warmind_CreateSound **** **** **** **** **** **** **** **** +15476 Warmind_CrystalShard **** **** **** **** **** **** **** **** +15477 Warmind_Daze **** **** **** **** **** **** **** **** +15478 Warmind_Deceleration **** **** **** **** **** **** **** **** +15479 Warmind_DefPrecog **** **** **** **** **** **** **** **** +15480 Warmind_Demoralize **** **** **** **** **** **** **** **** +15481 Warmind_DestinyDissonance **** **** **** **** **** **** **** **** +15482 Warmind_Disable **** **** **** **** **** **** **** **** +15483 Warmind_DissipatingTouch **** **** **** **** **** **** **** **** +15484 Warmind_Distract **** **** **** **** **** **** **** **** +15485 Warmind_ElfSight **** **** **** **** **** **** **** **** +15486 Warmind_Empathy **** **** **** **** **** **** **** **** +15487 Warmind_EmptyMind **** **** **** **** **** **** **** **** +15488 Warmind_EnergyRay_RadialMaster **** **** **** **** **** **** **** **** +15489 Warmind_EnergyRay_Cold **** **** **** **** **** **** **** **** +15490 Warmind_EnergyRay_Elec **** **** **** **** **** **** **** **** +15491 Warmind_EnergyRay_Fire **** **** **** **** **** **** **** **** +15492 Warmind_EnergyRay_Sonic **** **** **** **** **** **** **** **** +15493 Warmind_EntanglingEctoplasm **** **** **** **** **** **** **** **** +15494 Warmind_Expansion **** **** **** **** **** **** **** **** +15495 Warmind_Far_Hand **** **** **** **** **** **** **** **** +15496 Warmind_ForceScreen **** **** **** **** **** **** **** **** +15497 Warmind_Grease **** **** **** **** **** **** **** **** +15498 Warmind_Hammer **** **** **** **** **** **** **** **** +15499 Warmind_InertialArmour **** **** **** **** **** **** **** **** +15500 Warmind_Matter_Agitation **** **** **** **** **** **** **** **** +15501 Warmind_MetaphysicalClaw **** **** **** **** **** **** **** **** +15502 Warmind_MetaphysicalWeapon **** **** **** **** **** **** **** **** +15503 Warmind_MindThrust **** **** **** **** **** **** **** **** +15504 Warmind_MyLight **** **** **** **** **** **** **** **** +15505 Warmind_OffPrecog **** **** **** **** **** **** **** **** +15506 Warmind_OffPresc **** **** **** **** **** **** **** **** +15507 Warmind_Precognition_RadialMaster **** **** **** **** **** **** **** **** +15508 Warmind_PrecognitionMain **** **** **** **** **** **** **** **** +15509 Warmind_PrecognitionAttack **** **** **** **** **** **** **** **** +15510 Warmind_PrecognitionDamage **** **** **** **** **** **** **** **** +15511 Warmind_PrecognitionSaves **** **** **** **** **** **** **** **** +15512 Warmind_PrecognitionSkills **** **** **** **** **** **** **** **** +15513 Warmind_Prevenom **** **** **** **** **** **** **** **** +15514 Warmind_PrevenomWeapon **** **** **** **** **** **** **** **** +15515 Warmind_Skate **** **** **** **** **** **** **** **** +15516 Warmind_Stomp **** **** **** **** **** **** **** **** +15517 Warmind_Synesthete **** **** **** **** **** **** **** **** +15518 Warmind_Telempathic_Projection **** **** **** **** **** **** **** **** +15519 Warmind_ThickSkin **** **** **** **** **** **** **** **** +15520 Warmind_Vigor **** **** **** **** **** **** **** **** +15521 Warmind_AnimalAffinity **** **** **** **** **** **** **** **** +15522 Warmind_Aversion **** **** **** **** **** **** **** **** +15523 Warmind_BestowPower **** **** **** **** **** **** **** **** +15524 Warmind_BodyAdjustment **** **** **** **** **** **** **** **** +15525 Warmind_Body_Equilibrium **** **** **** **** **** **** **** **** +15526 Warmind_BodyPurification **** **** **** **** **** **** **** **** +15527 Warmind_BrainLock **** **** **** **** **** **** **** **** +15528 Warmind_ClairvoyantSense **** **** **** **** **** **** **** **** +15529 Warmind_Cloud_Mind **** **** **** **** **** **** **** **** +15530 Warmind_ConcBlast **** **** **** **** **** **** **** **** +15531 Warmind_ConcealAmorpha **** **** **** **** **** **** **** **** +15532 Warmind_ControlAir **** **** **** **** **** **** **** **** +15533 Warmind_ControlSound **** **** **** **** **** **** **** **** +15534 Warmind_SwarmOfCrystals **** **** **** **** **** **** **** **** +15535 Warmind_Darkvision **** **** **** **** **** **** **** **** +15536 Warmind_DimensionSwap **** **** **** **** **** **** **** **** +15537 Warmind_DissolvingTouch **** **** **** **** **** **** **** **** +15538 Warmind_Dissolving_Weapon **** **** **** **** **** **** **** **** +15539 Warmind_EgoWhip **** **** **** **** **** **** **** **** +15540 Warmind_EmpathicTransfer **** **** **** **** **** **** **** **** +15541 Warmind_EnergyAdaptSpec_RadialMaster **** **** **** **** **** **** **** **** +15542 Warmind_EnergyAdaptAcid **** **** **** **** **** **** **** **** +15543 Warmind_EnergyAdaptCold **** **** **** **** **** **** **** **** +15544 Warmind_EnergyAdaptElec **** **** **** **** **** **** **** **** +15545 Warmind_EnergyAdaptFire **** **** **** **** **** **** **** **** +15546 Warmind_EnergyAdaptSonic **** **** **** **** **** **** **** **** +15547 Warmind_Energy_Missile_RadialMaster **** **** **** **** **** **** **** **** +15548 Warmind_Energy_Missile_Cold **** **** **** **** **** **** **** **** +15549 Warmind_Energy_Missile_Elec **** **** **** **** **** **** **** **** +15550 Warmind_Energy_Missile_Fire **** **** **** **** **** **** **** **** +15551 Warmind_Energy_Missile_Sonic **** **** **** **** **** **** **** **** +15552 Warmind_EnergyPush_RadialMaster **** **** **** **** **** **** **** **** +15553 Warmind_EnergyPush_Cold **** **** **** **** **** **** **** **** +15554 Warmind_EnergyPush_Elec **** **** **** **** **** **** **** **** +15555 Warmind_EnergyPush_Fire **** **** **** **** **** **** **** **** +15556 Warmind_EnergyPush_Sonic **** **** **** **** **** **** **** **** +15557 Warmind_EnergyStun_RadialMaster **** **** **** **** **** **** **** **** +15558 Warmind_EnergyStun_Cold **** **** **** **** **** **** **** **** +15559 Warmind_EnergyStun_Elec **** **** **** **** **** **** **** **** +15560 Warmind_EnergyStun_Fire **** **** **** **** **** **** **** **** +15561 Warmind_EnergyStun_Sonic **** **** **** **** **** **** **** **** +15562 Warmind_Hustle **** **** **** **** **** **** **** **** +15563 Warmind_Identify **** **** **** **** **** **** **** **** +15564 Warmind_IdInsinuation **** **** **** **** **** **** **** **** +15565 Warmind_InflictPain **** **** **** **** **** **** **** **** +15566 Warmind_Knock **** **** **** **** **** **** **** **** +15567 Warmind_Lock **** **** **** **** **** **** **** **** +15568 Warmind_MindDisrupt **** **** **** **** **** **** **** **** +15569 Warmind_PainfulStrike **** **** **** **** **** **** **** **** +15570 Warmind_RecallAgony **** **** **** **** **** **** **** **** +15571 Warmind_RepairDamage **** **** **** **** **** **** **** **** +15572 Warmind_SharePain **** **** **** **** **** **** **** **** +15573 Warmind_StrengthOfMyEnemy **** **** **** **** **** **** **** **** +15574 Warmind_ThoughtShield **** **** **** **** **** **** **** **** +15575 Warmind_ClawOfTheVampire **** **** **** **** **** **** **** **** +15576 Warmind_CrisisBreath **** **** **** **** **** **** **** **** +15577 Warmind_Danger_Sense **** **** **** **** **** **** **** **** +15578 Warmind_DimensionSlide **** **** **** **** **** **** **** **** +15579 Warmind_Dispel_Psionics **** **** **** **** **** **** **** **** +15580 Warmind_DuodimensionalClaw **** **** **** **** **** **** **** **** +15581 Warmind_EctoCocoon **** **** **** **** **** **** **** **** +15582 Warmind_EctoplasmicForm **** **** **** **** **** **** **** **** +15583 Warmind_EmpathicFeedback **** **** **** **** **** **** **** **** +15584 Warmind_EmpathicTransferHostile **** **** **** **** **** **** **** **** +15585 Warmind_EnergyBolt_RadialMaster **** **** **** **** **** **** **** **** +15586 Warmind_Energy_Bolt_Cold **** **** **** **** **** **** **** **** +15587 Warmind_Energy_Bolt_Elec **** **** **** **** **** **** **** **** +15588 Warmind_Energy_Bolt_Fire **** **** **** **** **** **** **** **** +15589 Warmind_Energy_Bolt_Sonic **** **** **** **** **** **** **** **** +15590 Warmind_EnergyBurst_RadialMaster **** **** **** **** **** **** **** **** +15591 Warmind_Energy_Burst_Cold **** **** **** **** **** **** **** **** +15592 Warmind_Energy_Burst_Elec **** **** **** **** **** **** **** **** +15593 Warmind_Energy_Burst_Fire **** **** **** **** **** **** **** **** +15594 Warmind_Energy_Burst_Sonic **** **** **** **** **** **** **** **** +15595 Warmind_Energy_Cone_RadialMaster **** **** **** **** **** **** **** **** +15596 Warmind_EnergyCone_Cold **** **** **** **** **** **** **** **** +15597 Warmind_EnergyCone_Elec **** **** **** **** **** **** **** **** +15598 Warmind_EnergyCone_Fire **** **** **** **** **** **** **** **** +15599 Warmind_EnergyCone_Sonic **** **** **** **** **** **** **** **** +15600 Warmind_EnergyRetort_RadialMaster **** **** **** **** **** **** **** **** +15601 Warmind_Energy_Retort_Cold **** **** **** **** **** **** **** **** +15602 Warmind_Energy_Retort_Elec **** **** **** **** **** **** **** **** +15603 Warmind_Energy_Retort_Fire **** **** **** **** **** **** **** **** +15604 Warmind_Energy_Retort_Sonic **** **** **** **** **** **** **** **** +15605 Warmind_EnergyWall_RadialMaster **** **** **** **** **** **** **** **** +15606 Warmind_Energy_Wall_Cold **** **** **** **** **** **** **** **** +15607 Warmind_Energy_Wall_Elec **** **** **** **** **** **** **** **** +15608 Warmind_Energy_Wall_Fire **** **** **** **** **** **** **** **** +15609 Warmind_Energy_Wall_Sonic **** **** **** **** **** **** **** **** +15610 Warmind_Eradicate_Invisibility **** **** **** **** **** **** **** **** +15611 Warmind_EscapeDetection **** **** **** **** **** **** **** **** +15612 Warmind_EvadeBurst **** **** **** **** **** **** **** **** +15613 Warmind_Exhale_BlackDrag **** **** **** **** **** **** **** **** +15614 Warmind_FateLink **** **** **** **** **** **** **** **** +15615 Warmind_Greater_Amorpha **** **** **** **** **** **** **** **** +15616 Warmind_Keen_Edge **** **** **** **** **** **** **** **** +15617 Warmind_MentalBarrier **** **** **** **** **** **** **** **** +15618 Warmind_Mindtrap **** **** **** **** **** **** **** **** +15619 Warmind_Psiblast **** **** **** **** **** **** **** **** +15620 Warmind_SharePainForced **** **** **** **** **** **** **** **** +15621 Warmind_TimeHop **** **** **** **** **** **** **** **** +15622 Warmind_Touchsight **** **** **** **** **** **** **** **** +15623 Warmind_UbiqVision **** **** **** **** **** **** **** **** +15624 Warmind_VampiricWeapon **** **** **** **** **** **** **** **** +15625 Warmind_ClawOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15626 Warmind_ClawofEnergyCold **** **** **** **** **** **** **** **** +15627 Warmind_ClawofEnergyElec **** **** **** **** **** **** **** **** +15628 Warmind_ClawofEnergyFire **** **** **** **** **** **** **** **** +15629 Warmind_DetectRemoteViewing **** **** **** **** **** **** **** **** +15630 Warmind_DimensionalAnchor **** **** **** **** **** **** **** **** +15631 Warmind_DimensionDoor_Master **** **** **** **** **** **** **** **** +15632 Warmind_DimensionDoor_SelfOnly **** **** **** **** **** **** **** **** +15633 Warmind_DimensionDoor_Party **** **** **** **** **** **** **** **** +15634 Warmind_DimensionDoor_DirDist_SelfOnly **** **** **** **** **** **** **** **** +15635 Warmind_DimensionDoor_DirDist_Party **** **** **** **** **** **** **** **** +15636 Warmind_Dismissal **** **** **** **** **** **** **** **** +15637 Warmind_EnergyAdaption **** **** **** **** **** **** **** **** +15638 Warmind_EnergyBall_RadialMaster **** **** **** **** **** **** **** **** +15639 Warmind_EnergyBall_Cold **** **** **** **** **** **** **** **** +15640 Warmind_EnergyBall_Elec **** **** **** **** **** **** **** **** +15641 Warmind_EnergyBall_Fire **** **** **** **** **** **** **** **** +15642 Warmind_EnergyBall_Sonic **** **** **** **** **** **** **** **** +15643 Warmind_Freedom_of_Movement **** **** **** **** **** **** **** **** +15644 Warmind_Immovability **** **** **** **** **** **** **** **** +15645 Warmind_InertialBar **** **** **** **** **** **** **** **** +15646 Warmind_IntellectFortress **** **** **** **** **** **** **** **** +15647 Warmind_Mindwipe **** **** **** **** **** **** **** **** +15648 Warmind_PowerLeech **** **** **** **** **** **** **** **** +15649 Warmind_Dominate_Psionic **** **** **** **** **** **** **** **** +15650 Warmind_PsychicReformation **** **** **** **** **** **** **** **** +15651 Warmind_PsychicVampire **** **** **** **** **** **** **** **** +15652 Warmind_RemoteViewing **** **** **** **** **** **** **** **** +15653 Warmind_SteadfastPercep **** **** **** **** **** **** **** **** +15654 Warmind_TelekineticManeuver **** **** **** **** **** **** **** **** +15655 Warmind_Truevenom **** **** **** **** **** **** **** **** +15656 Warmind_TruevenomWeapon **** **** **** **** **** **** **** **** +15657 Warmind_WeaponOfEnergy_RadialMaster **** **** **** **** **** **** **** **** +15658 Warmind_WeaponofEnergyCold **** **** **** **** **** **** **** **** +15659 Warmind_WeaponofEnergyElec **** **** **** **** **** **** **** **** +15660 Warmind_WeaponofEnergyFire **** **** **** **** **** **** **** **** +15661 Warmind_BaleTeleport **** **** **** **** **** **** **** **** +15662 Warmind_Catapsi **** **** **** **** **** **** **** **** +15663 Warmind_ClairtangentHand **** **** **** **** **** **** **** **** +15664 Warmind_EctoplasmicShambler **** **** **** **** **** **** **** **** +15665 Warmind_EnergyCurrent_RadialMaster **** **** **** **** **** **** **** **** +15666 Warmind_EnergyCurrent_Cold **** **** **** **** **** **** **** **** +15667 Warmind_EnergyCurrent_Elec **** **** **** **** **** **** **** **** +15668 Warmind_EnergyCurrent_Fire **** **** **** **** **** **** **** **** +15669 Warmind_EnergyCurrent_Sonic **** **** **** **** **** **** **** **** +15670 Warmind_HailCrystals **** **** **** **** **** **** **** **** +15671 Warmind_OakBody **** **** **** **** **** **** **** **** +15672 Warmind_Power_Resistance **** **** **** **** **** **** **** **** +15673 Warmind_PsionicRevivify **** **** **** **** **** **** **** **** +15674 Warmind_PsychicCrush **** **** **** **** **** **** **** **** +15675 Warmind_Psychofeedback **** **** **** **** **** **** **** **** +15676 Warmind_SecondChance **** **** **** **** **** **** **** **** +15677 Warmind_ShatterMindBlank **** **** **** **** **** **** **** **** +15678 Warmind_Teleport_RadialMaster **** **** **** **** **** **** **** **** +15679 Warmind_Teleport_SelfOnly **** **** **** **** **** **** **** **** +15680 Warmind_Teleport_Party **** **** **** **** **** **** **** **** +15681 Warmind_TowerIronWill **** **** **** **** **** **** **** **** +15682 Warmind_True_Seeing **** **** **** **** **** **** **** **** +15683 PsychicWarrior_GripOfIron **** **** **** **** **** **** **** **** +15684 FistOfZuoken_GripOfIron **** **** **** **** **** **** **** **** +15685 Warmind_GripOfIron **** **** **** **** **** **** **** **** +15686 Psion_GripOfIron **** **** **** **** **** **** **** **** +15687 Wilder_GripOfIron **** **** **** **** **** **** **** **** +15688 PsychicRogue_GripOfIron **** **** **** **** **** **** **** **** +15689 **** **** **** **** **** **** **** **** **** +15690 **** **** **** **** **** **** **** **** **** +15691 **** **** **** **** **** **** **** **** **** +15692 **** **** **** **** **** **** **** **** **** +15693 **** **** **** **** **** **** **** **** **** +15694 **** **** **** **** **** **** **** **** **** +15695 **** **** **** **** **** **** **** **** **** +15696 **** **** **** **** **** **** **** **** **** +15697 **** **** **** **** **** **** **** **** **** +15698 **** **** **** **** **** **** **** **** **** +15699 **** **** **** **** **** **** **** **** **** +15700 **** **** **** **** **** **** **** **** **** +15701 **** **** **** **** **** **** **** **** **** +15702 **** **** **** **** **** **** **** **** **** +15703 **** **** **** **** **** **** **** **** **** +15704 **** **** **** **** **** **** **** **** **** +15705 **** **** **** **** **** **** **** **** **** +15706 **** **** **** **** **** **** **** **** **** +15707 **** **** **** **** **** **** **** **** **** +15708 **** **** **** **** **** **** **** **** **** +15709 **** **** **** **** **** **** **** **** **** +15710 **** **** **** **** **** **** **** **** **** +15711 **** **** **** **** **** **** **** **** **** +15712 **** **** **** **** **** **** **** **** **** +15713 **** **** **** **** **** **** **** **** **** +15714 **** **** **** **** **** **** **** **** **** +15715 **** **** **** **** **** **** **** **** **** +15716 **** **** **** **** **** **** **** **** **** +15717 **** **** **** **** **** **** **** **** **** +15718 **** **** **** **** **** **** **** **** **** +15719 **** **** **** **** **** **** **** **** **** +15720 **** **** **** **** **** **** **** **** **** +15721 **** **** **** **** **** **** **** **** **** +15722 **** **** **** **** **** **** **** **** **** +15723 **** **** **** **** **** **** **** **** **** +15724 **** **** **** **** **** **** **** **** **** +15725 **** **** **** **** **** **** **** **** **** +15726 **** **** **** **** **** **** **** **** **** +15727 **** **** **** **** **** **** **** **** **** +15728 **** **** **** **** **** **** **** **** **** +15729 **** **** **** **** **** **** **** **** **** +15730 **** **** **** **** **** **** **** **** **** +15731 **** **** **** **** **** **** **** **** **** +15732 **** **** **** **** **** **** **** **** **** +15733 **** **** **** **** **** **** **** **** **** +15734 **** **** **** **** **** **** **** **** **** +15735 **** **** **** **** **** **** **** **** **** +15736 **** **** **** **** **** **** **** **** **** +15737 **** **** **** **** **** **** **** **** **** +15738 **** **** **** **** **** **** **** **** **** +15739 **** **** **** **** **** **** **** **** **** +15740 **** **** **** **** **** **** **** **** **** +15741 **** **** **** **** **** **** **** **** **** +15742 **** **** **** **** **** **** **** **** **** +15743 **** **** **** **** **** **** **** **** **** +15744 **** **** **** **** **** **** **** **** **** +15745 **** **** **** **** **** **** **** **** **** +15746 **** **** **** **** **** **** **** **** **** +15747 **** **** **** **** **** **** **** **** **** +15748 **** **** **** **** **** **** **** **** **** +15749 **** **** **** **** **** **** **** **** **** +15750 **** **** **** **** **** **** **** **** **** +15751 **** **** **** **** **** **** **** **** **** +15752 **** **** **** **** **** **** **** **** **** +15753 **** **** **** **** **** **** **** **** **** +15754 **** **** **** **** **** **** **** **** **** +15755 **** **** **** **** **** **** **** **** **** +15756 **** **** **** **** **** **** **** **** **** +15757 **** **** **** **** **** **** **** **** **** +15758 **** **** **** **** **** **** **** **** **** +15759 **** **** **** **** **** **** **** **** **** +15760 **** **** **** **** **** **** **** **** **** +15761 **** **** **** **** **** **** **** **** **** +15762 **** **** **** **** **** **** **** **** **** +15763 **** **** **** **** **** **** **** **** **** +15764 **** **** **** **** **** **** **** **** **** +15765 **** **** **** **** **** **** **** **** **** +15766 **** **** **** **** **** **** **** **** **** +15767 **** **** **** **** **** **** **** **** **** +15768 **** **** **** **** **** **** **** **** **** +15769 **** **** **** **** **** **** **** **** **** +15770 **** **** **** **** **** **** **** **** **** +15771 **** **** **** **** **** **** **** **** **** +15772 **** **** **** **** **** **** **** **** **** +15773 **** **** **** **** **** **** **** **** **** +15774 **** **** **** **** **** **** **** **** **** +15775 **** **** **** **** **** **** **** **** **** +15776 **** **** **** **** **** **** **** **** **** +15777 **** **** **** **** **** **** **** **** **** +15778 **** **** **** **** **** **** **** **** **** +15779 **** **** **** **** **** **** **** **** **** +15780 **** **** **** **** **** **** **** **** **** +15781 **** **** **** **** **** **** **** **** **** +15782 **** **** **** **** **** **** **** **** **** +15783 **** **** **** **** **** **** **** **** **** +15784 **** **** **** **** **** **** **** **** **** +15785 **** **** **** **** **** **** **** **** **** +15786 **** **** **** **** **** **** **** **** **** +15787 **** **** **** **** **** **** **** **** **** +15788 **** **** **** **** **** **** **** **** **** +15789 **** **** **** **** **** **** **** **** **** +15790 **** **** **** **** **** **** **** **** **** +15791 **** **** **** **** **** **** **** **** **** +15792 **** **** **** **** **** **** **** **** **** +15793 **** **** **** **** **** **** **** **** **** +15794 **** **** **** **** **** **** **** **** **** +15795 **** **** **** **** **** **** **** **** **** +15796 **** **** **** **** **** **** **** **** **** +15797 **** **** **** **** **** **** **** **** **** +15798 **** **** **** **** **** **** **** **** **** +15799 ####END_OF_PSI_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +15800 ####START_OF_TOB_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +15801 Crusader_BlisteringFlourish **** **** **** **** **** **** **** **** +15802 Crusader_BurningBlade **** **** **** **** **** **** **** **** +15803 Crusader_BurningBrand **** **** **** **** **** **** **** **** +15804 Crusader_DeathMark **** **** **** **** **** **** **** **** +15805 Crusader_DesertTempest **** **** **** **** **** **** **** **** +15806 Crusader_DistractingEmber **** **** **** **** **** **** **** **** +15807 Crusader_DragonsFlame **** **** **** **** **** **** **** **** +15808 Crusader_FanTheFlames **** **** **** **** **** **** **** **** +15809 Crusader_FieryAssault **** **** **** **** **** **** **** **** +15810 Crusader_FireRiposte **** **** **** **** **** **** **** **** +15811 Crusader_Firesnake **** **** **** **** **** **** **** **** +15812 Crusader_FlamesBlessing **** **** **** **** **** **** **** **** +15813 Crusader_FlashingSun **** **** **** **** **** **** **** **** +15814 Crusader_HatchlingsFlame **** **** **** **** **** **** **** **** +15815 Crusader_HolocaustCloak **** **** **** **** **** **** **** **** +15816 Crusader_InfernoBlade **** **** **** **** **** **** **** **** +15817 Crusader_InfernoBlast **** **** **** **** **** **** **** **** +15818 Crusader_LeapingFlame **** **** **** **** **** **** **** **** +15819 Crusader_LingeringInferno **** **** **** **** **** **** **** **** +15820 Crusader_RingOfFire **** **** **** **** **** **** **** **** +15821 Crusader_RisingPhoenix **** **** **** **** **** **** **** **** +15822 Crusader_SalamanderCharge **** **** **** **** **** **** **** **** +15823 Crusader_SearingBlade **** **** **** **** **** **** **** **** +15824 Crusader_SearingCharge **** **** **** **** **** **** **** **** +15825 Crusader_WindStride **** **** **** **** **** **** **** **** +15826 Crusader_WyrmsFlame **** **** **** **** **** **** **** **** +15827 Crusader_ZephyrDance **** **** **** **** **** **** **** **** +15828 Crusader_AuraOfChaos **** **** **** **** **** **** **** **** +15829 Crusader_AuraOfPerfectOrder **** **** **** **** **** **** **** **** +15830 Crusader_AuraOfTriumph **** **** **** **** **** **** **** **** +15831 Crusader_AuraOfTyranny **** **** **** **** **** **** **** **** +15832 Crusader_CastigatingStrike **** **** **** **** **** **** **** **** +15833 Crusader_CrusadersStrike **** **** **** **** **** **** **** **** +15834 Crusader_DauntingStrike **** **** **** **** **** **** **** **** +15835 Crusader_DefensiveRebuke **** **** **** **** **** **** **** **** +15836 Crusader_DivineSurge **** **** **** **** **** **** **** **** +15837 Crusader_DivineSurgeGreater **** **** **** **** **** **** **** **** +15838 Crusader_DivineSurgeGreaterSub1 **** **** **** **** **** **** **** **** +15839 Crusader_DivineSurgeGreaterSub2 **** **** **** **** **** **** **** **** +15840 Crusader_DivineSurgeGreaterSub3 **** **** **** **** **** **** **** **** +15841 Crusader_DoomCharge **** **** **** **** **** **** **** **** +15842 Crusader_EntanglingBlade **** **** **** **** **** **** **** **** +15843 Crusader_Foehammer **** **** **** **** **** **** **** **** +15844 Crusader_ImmortalFortitude **** **** **** **** **** **** **** **** +15845 Crusader_IronGuardsGlare **** **** **** **** **** **** **** **** +15846 Crusader_LawBearer **** **** **** **** **** **** **** **** +15847 Crusader_MartialSpirit **** **** **** **** **** **** **** **** +15848 Crusader_RadiantCharge **** **** **** **** **** **** **** **** +15849 Crusader_RallyingStrike **** **** **** **** **** **** **** **** +15850 Crusader_RevitalizingStrike **** **** **** **** **** **** **** **** +15851 Crusader_ShieldBlock **** **** **** **** **** **** **** **** +15852 Crusader_ShieldCounter **** **** **** **** **** **** **** **** +15853 Crusader_StrikeOfRighteousVitality **** **** **** **** **** **** **** **** +15854 Crusader_ThicketOfBlades **** **** **** **** **** **** **** **** +15855 Crusader_TideOfChaos **** **** **** **** **** **** **** **** +15856 Crusader_VanguardStrike **** **** **** **** **** **** **** **** +15857 Crusader_ActionBeforeThought **** **** **** **** **** **** **** **** +15858 Crusader_AvalancheOfBlades **** **** **** **** **** **** **** **** +15859 Crusader_BoundingAssault **** **** **** **** **** **** **** **** +15860 Crusader_DiamondDefense **** **** **** **** **** **** **** **** +15861 Crusader_DiamondNightmareBlade **** **** **** **** **** **** **** **** +15862 Crusader_DisruptingBlow **** **** **** **** **** **** **** **** +15863 Crusader_EmeraldRazor **** **** **** **** **** **** **** **** +15864 Crusader_HearingTheAir **** **** **** **** **** **** **** **** +15865 Crusader_InsightfulStrike **** **** **** **** **** **** **** **** +15866 Crusader_InsightfulStrikeGreater **** **** **** **** **** **** **** **** +15867 Crusader_MindOverBody **** **** **** **** **** **** **** **** +15868 Crusader_MindStrike **** **** **** **** **** **** **** **** +15869 Crusader_MomentOfAlacrity **** **** **** **** **** **** **** **** +15870 Crusader_MomentOfPerfectMind **** **** **** **** **** **** **** **** +15871 Crusader_PearlOfBlackDoubt **** **** **** **** **** **** **** **** +15872 Crusader_QuicksilverMotion **** **** **** **** **** **** **** **** +15873 Crusader_RapidCounter **** **** **** **** **** **** **** **** +15874 Crusader_RubyNightmareBlade **** **** **** **** **** **** **** **** +15875 Crusader_SapphireNightmareBlade **** **** **** **** **** **** **** **** +15876 Crusader_StanceOfAlacrity **** **** **** **** **** **** **** **** +15877 Crusader_StanceOfClarity **** **** **** **** **** **** **** **** +15878 Crusader_TimeStandsStill **** **** **** **** **** **** **** **** +15879 Crusader_AbsoluteSteel **** **** **** **** **** **** **** **** +15880 Crusader_AdamantineHurricane **** **** **** **** **** **** **** **** +15881 Crusader_DancingBladeForm **** **** **** **** **** **** **** **** +15882 Crusader_DazingStrike **** **** **** **** **** **** **** **** +15883 Crusader_DisarmingStrike **** **** **** **** **** **** **** **** +15884 Crusader_ExorcismOfSteel **** **** **** **** **** **** **** **** +15885 Crusader_FinishingMove **** **** **** **** **** **** **** **** +15886 Crusader_IronHeartEndurance **** **** **** **** **** **** **** **** +15887 Crusader_IronHeartFocus **** **** **** **** **** **** **** **** +15888 Crusader_IronHeartSurge **** **** **** **** **** **** **** **** +15889 Crusader_LightningRecovery **** **** **** **** **** **** **** **** +15890 Crusader_LightningThrow **** **** **** **** **** **** **** **** +15891 Crusader_ManticoreParry **** **** **** **** **** **** **** **** +15892 Crusader_MithralTornado **** **** **** **** **** **** **** **** +15893 Crusader_PunishingStance **** **** **** **** **** **** **** **** +15894 Crusader_ScythingBlade **** **** **** **** **** **** **** **** +15895 Crusader_SteelWind **** **** **** **** **** **** **** **** +15896 Crusader_SteelyStrike **** **** **** **** **** **** **** **** +15897 Crusader_StrikeOfPerfectClarity **** **** **** **** **** **** **** **** +15898 Crusader_SupremeBladeParry **** **** **** **** **** **** **** **** +15899 Crusader_WallOfBlades **** **** **** **** **** **** **** **** +15900 Crusader_BafflingDefense **** **** **** **** **** **** **** **** +15901 Crusader_BallistaThrow **** **** **** **** **** **** **** **** +15902 Crusader_CleverPositioning **** **** **** **** **** **** **** **** +15903 Crusader_CometThrow **** **** **** **** **** **** **** **** +15904 Crusader_CounterCharge **** **** **** **** **** **** **** **** +15905 Crusader_DevastatingThrow **** **** **** **** **** **** **** **** +15906 Crusader_FeignedOpening **** **** **** **** **** **** **** **** +15907 Crusader_FoolsStrike **** **** **** **** **** **** **** **** +15908 Crusader_GhostlyDefense **** **** **** **** **** **** **** **** +15909 Crusader_GiantKillingStyle **** **** **** **** **** **** **** **** +15910 Crusader_HydraSlayingStrike **** **** **** **** **** **** **** **** +15911 Crusader_MightyThrow **** **** **** **** **** **** **** **** +15912 Crusader_MirroredPursuit **** **** **** **** **** **** **** **** +15913 Crusader_ScorpionParry **** **** **** **** **** **** **** **** +15914 Crusader_ShiftingDefense **** **** **** **** **** **** **** **** +15915 Crusader_SoaringThrow **** **** **** **** **** **** **** **** +15916 Crusader_StalkingShadow **** **** **** **** **** **** **** **** +15917 Crusader_StepOfTheWind **** **** **** **** **** **** **** **** +15918 Crusader_StrikeOfTheBrokenShield **** **** **** **** **** **** **** **** +15919 Crusader_TornadoThrow **** **** **** **** **** **** **** **** +15920 Crusader_AssassinsStance **** **** **** **** **** **** **** **** +15921 Crusader_BalanceOnTheSky **** **** **** **** **** **** **** **** +15922 Crusader_BloodlettingStrike **** **** **** **** **** **** **** **** +15923 Crusader_ChildOfShadow **** **** **** **** **** **** **** **** +15924 Crusader_ClingingShadowStrike **** **** **** **** **** **** **** **** +15925 Crusader_CloakOfDeception **** **** **** **** **** **** **** **** +15926 Crusader_DanceOfTheSpider **** **** **** **** **** **** **** **** +15927 Crusader_DeathInTheDark **** **** **** **** **** **** **** **** +15928 Crusader_DrainVitality **** **** **** **** **** **** **** **** +15929 Crusader_EnervatingShadowStrike **** **** **** **** **** **** **** **** +15930 Crusader_FiveShadowCreepingIceEnervationStrike **** **** **** **** **** **** **** **** +15931 Crusader_GhostBlade **** **** **** **** **** **** **** **** +15932 Crusader_HandOfDeath **** **** **** **** **** **** **** **** +15933 Crusader_IslandOfBlades **** **** **** **** **** **** **** **** +15934 Crusader_ObscuringShadowVeil **** **** **** **** **** **** **** **** +15935 Crusader_OneWithShadow **** **** **** **** **** **** **** **** +15936 Crusader_ShadowBladeTechnique **** **** **** **** **** **** **** **** +15937 Crusader_ShadowBlink **** **** **** **** **** **** **** **** +15938 Crusader_ShadowGarrote **** **** **** **** **** **** **** **** +15939 Crusader_ShadowJaunt **** **** **** **** **** **** **** **** +15940 Crusader_ShadowNoose **** **** **** **** **** **** **** **** +15941 Crusader_ShadowStride **** **** **** **** **** **** **** **** +15942 Crusader_StalkerInTheNight **** **** **** **** **** **** **** **** +15943 Crusader_StepOfTheDancingMoth **** **** **** **** **** **** **** **** +15944 Crusader_StrengthDrainingStrike **** **** **** **** **** **** **** **** +15945 Crusader_AdamantineBones **** **** **** **** **** **** **** **** +15946 Crusader_AncientMountainHammer **** **** **** **** **** **** **** **** +15947 Crusader_BonesplittingStrike **** **** **** **** **** **** **** **** +15948 Crusader_Bonecrusher **** **** **** **** **** **** **** **** +15949 Crusader_BoulderRoll **** **** **** **** **** **** **** **** +15950 Crusader_ChargingMinotaur **** **** **** **** **** **** **** **** +15951 Crusader_ColossusStrike **** **** **** **** **** **** **** **** +15952 Crusader_CrushingVise **** **** **** **** **** **** **** **** +15953 Crusader_CrushingWeightOfTheMountain **** **** **** **** **** **** **** **** +15954 Crusader_EarthstrikeQuake **** **** **** **** **** **** **** **** +15955 Crusader_ElderMountainHammer **** **** **** **** **** **** **** **** +15956 Crusader_GiantsStance **** **** **** **** **** **** **** **** +15957 Crusader_IronBones **** **** **** **** **** **** **** **** +15958 Crusader_IrresistibleMountainStrike **** **** **** **** **** **** **** **** +15959 Crusader_MountainAvalanche **** **** **** **** **** **** **** **** +15960 Crusader_MountainHammer **** **** **** **** **** **** **** **** +15961 Crusader_MountainTombstoneStrike **** **** **** **** **** **** **** **** +15962 Crusader_OverwhelmingMountainStrike **** **** **** **** **** **** **** **** +15963 Crusader_RootsOfTheMountain **** **** **** **** **** **** **** **** +15964 Crusader_StoneBones **** **** **** **** **** **** **** **** +15965 Crusader_StoneDragonsFury **** **** **** **** **** **** **** **** +15966 Crusader_StoneVise **** **** **** **** **** **** **** **** +15967 Crusader_StonefootStance **** **** **** **** **** **** **** **** +15968 Crusader_StrengthOfStone **** **** **** **** **** **** **** **** +15969 Crusader_BloodInTheWater **** **** **** **** **** **** **** **** +15970 Crusader_ClawAtTheMoon **** **** **** **** **** **** **** **** +15971 Crusader_DancingMongoose **** **** **** **** **** **** **** **** +15972 Crusader_DeathFromAbove **** **** **** **** **** **** **** **** +15973 Crusader_FeralDeathBlow **** **** **** **** **** **** **** **** +15974 Crusader_FleshRipper **** **** **** **** **** **** **** **** +15975 Crusader_FountainOfBlood **** **** **** **** **** **** **** **** +15976 Crusader_GirallonWindmillFleshRip **** **** **** **** **** **** **** **** +15977 Crusader_HamstringAttack **** **** **** **** **** **** **** **** +15978 Crusader_HuntersSense **** **** **** **** **** **** **** **** +15979 Crusader_LeapingDragonStance **** **** **** **** **** **** **** **** +15980 Crusader_PouncingCharge **** **** **** **** **** **** **** **** +15981 Crusader_PreyOnTheWeak **** **** **** **** **** **** **** **** +15982 Crusader_RabidBearStrike **** **** **** **** **** **** **** **** +15983 Crusader_RabidWolfStrike **** **** **** **** **** **** **** **** +15984 Crusader_RagingMongoose **** **** **** **** **** **** **** **** +15985 Crusader_SoaringRaptorStrike **** **** **** **** **** **** **** **** +15986 Crusader_SuddenLeap **** **** **** **** **** **** **** **** +15987 Crusader_SwoopingDragonStrike **** **** **** **** **** **** **** **** +15988 Crusader_WolfClimbsTheMountain **** **** **** **** **** **** **** **** +15989 Crusader_WolfFangStrike **** **** **** **** **** **** **** **** +15990 Crusader_WolfPackTactics **** **** **** **** **** **** **** **** +15991 Crusader_WolverineStance **** **** **** **** **** **** **** **** +15992 Crusader_BattleLeadersCharge **** **** **** **** **** **** **** **** +15993 Crusader_BolsteringVoice **** **** **** **** **** **** **** **** +15994 Crusader_ClarionCall **** **** **** **** **** **** **** **** +15995 Crusader_CoveringStrike **** **** **** **** **** **** **** **** +15996 Crusader_DouseTheFlames **** **** **** **** **** **** **** **** +15997 Crusader_FlankingManeuver **** **** **** **** **** **** **** **** +15998 Crusader_LeadingTheAttack **** **** **** **** **** **** **** **** +15999 Crusader_LeadingTheCharge **** **** **** **** **** **** **** **** +16000 Crusader_LionsRoar **** **** **** **** **** **** **** **** +16001 Crusader_OrderForgedFromChaos **** **** **** **** **** **** **** **** +16002 Crusader_PressTheAdvantage **** **** **** **** **** **** **** **** +16003 Crusader_SwarmTactics **** **** **** **** **** **** **** **** +16004 Crusader_SwarmingAssault **** **** **** **** **** **** **** **** +16005 Crusader_TacticalStrike **** **** **** **** **** **** **** **** +16006 Crusader_TacticsOfTheWolf **** **** **** **** **** **** **** **** +16007 Crusader_WarLeadersCharge **** **** **** **** **** **** **** **** +16008 Crusader_WarMastersCharge **** **** **** **** **** **** **** **** +16009 Crusader_WhiteRavenHammer **** **** **** **** **** **** **** **** +16010 Crusader_WhiteRavenStrike **** **** **** **** **** **** **** **** +16011 Crusader_WhiteRavenTactics **** **** **** **** **** **** **** **** +16012 Swordsage_BlisteringFlourish **** **** **** **** **** **** **** **** +16013 Swordsage_BurningBlade **** **** **** **** **** **** **** **** +16014 Swordsage_BurningBrand **** **** **** **** **** **** **** **** +16015 Swordsage_DeathMark **** **** **** **** **** **** **** **** +16016 Swordsage_DesertTempest **** **** **** **** **** **** **** **** +16017 Swordsage_DistractingEmber **** **** **** **** **** **** **** **** +16018 Swordsage_DragonsFlame **** **** **** **** **** **** **** **** +16019 Swordsage_FanTheFlames **** **** **** **** **** **** **** **** +16020 Swordsage_FieryAssault **** **** **** **** **** **** **** **** +16021 Swordsage_FireRiposte **** **** **** **** **** **** **** **** +16022 Swordsage_Firesnake **** **** **** **** **** **** **** **** +16023 Swordsage_FlamesBlessing **** **** **** **** **** **** **** **** +16024 Swordsage_FlashingSun **** **** **** **** **** **** **** **** +16025 Swordsage_HatchlingsFlame **** **** **** **** **** **** **** **** +16026 Swordsage_HolocaustCloak **** **** **** **** **** **** **** **** +16027 Swordsage_InfernoBlade **** **** **** **** **** **** **** **** +16028 Swordsage_InfernoBlast **** **** **** **** **** **** **** **** +16029 Swordsage_LeapingFlame **** **** **** **** **** **** **** **** +16030 Swordsage_LingeringInferno **** **** **** **** **** **** **** **** +16031 Swordsage_RingOfFire **** **** **** **** **** **** **** **** +16032 Swordsage_RisingPhoenix **** **** **** **** **** **** **** **** +16033 Swordsage_SalamanderCharge **** **** **** **** **** **** **** **** +16034 Swordsage_SearingBlade **** **** **** **** **** **** **** **** +16035 Swordsage_SearingCharge **** **** **** **** **** **** **** **** +16036 Swordsage_WindStride **** **** **** **** **** **** **** **** +16037 Swordsage_WyrmsFlame **** **** **** **** **** **** **** **** +16038 Swordsage_ZephyrDance **** **** **** **** **** **** **** **** +16039 Swordsage_AuraOfChaos **** **** **** **** **** **** **** **** +16040 Swordsage_AuraOfPerfectOrder **** **** **** **** **** **** **** **** +16041 Swordsage_AuraOfTriumph **** **** **** **** **** **** **** **** +16042 Swordsage_AuraOfTyranny **** **** **** **** **** **** **** **** +16043 Swordsage_CastigatingStrike **** **** **** **** **** **** **** **** +16044 Swordsage_CrusadersStrike **** **** **** **** **** **** **** **** +16045 Swordsage_DauntingStrike **** **** **** **** **** **** **** **** +16046 Swordsage_DefensiveRebuke **** **** **** **** **** **** **** **** +16047 Swordsage_DivineSurge **** **** **** **** **** **** **** **** +16048 Swordsage_DivineSurgeGreater **** **** **** **** **** **** **** **** +16049 Swordsage_DivineSurgeGreaterSub1 **** **** **** **** **** **** **** **** +16050 Swordsage_DivineSurgeGreaterSub2 **** **** **** **** **** **** **** **** +16051 Swordsage_DivineSurgeGreaterSub3 **** **** **** **** **** **** **** **** +16052 Swordsage_DoomCharge **** **** **** **** **** **** **** **** +16053 Swordsage_EntanglingBlade **** **** **** **** **** **** **** **** +16054 Swordsage_Foehammer **** **** **** **** **** **** **** **** +16055 Swordsage_ImmortalFortitude **** **** **** **** **** **** **** **** +16056 Swordsage_IronGuardsGlare **** **** **** **** **** **** **** **** +16057 Swordsage_LawBearer **** **** **** **** **** **** **** **** +16058 Swordsage_MartialSpirit **** **** **** **** **** **** **** **** +16059 Swordsage_RadiantCharge **** **** **** **** **** **** **** **** +16060 Swordsage_RallyingStrike **** **** **** **** **** **** **** **** +16061 Swordsage_RevitalizingStrike **** **** **** **** **** **** **** **** +16062 Swordsage_ShieldBlock **** **** **** **** **** **** **** **** +16063 Swordsage_ShieldCounter **** **** **** **** **** **** **** **** +16064 Swordsage_StrikeOfRighteousVitality **** **** **** **** **** **** **** **** +16065 Swordsage_ThicketOfBlades **** **** **** **** **** **** **** **** +16066 Swordsage_TideOfChaos **** **** **** **** **** **** **** **** +16067 Swordsage_VanguardStrike **** **** **** **** **** **** **** **** +16068 Swordsage_ActionBeforeThought **** **** **** **** **** **** **** **** +16069 Swordsage_AvalancheOfBlades **** **** **** **** **** **** **** **** +16070 Swordsage_BoundingAssault **** **** **** **** **** **** **** **** +16071 Swordsage_DiamondDefense **** **** **** **** **** **** **** **** +16072 Swordsage_DiamondNightmareBlade **** **** **** **** **** **** **** **** +16073 Swordsage_DisruptingBlow **** **** **** **** **** **** **** **** +16074 Swordsage_EmeraldRazor **** **** **** **** **** **** **** **** +16075 Swordsage_HearingTheAir **** **** **** **** **** **** **** **** +16076 Swordsage_InsightfulStrike **** **** **** **** **** **** **** **** +16077 Swordsage_InsightfulStrikeGreater **** **** **** **** **** **** **** **** +16078 Swordsage_MindOverBody **** **** **** **** **** **** **** **** +16079 Swordsage_MindStrike **** **** **** **** **** **** **** **** +16080 Swordsage_MomentOfAlacrity **** **** **** **** **** **** **** **** +16081 Swordsage_MomentOfPerfectMind **** **** **** **** **** **** **** **** +16082 Swordsage_PearlOfBlackDoubt **** **** **** **** **** **** **** **** +16083 Swordsage_QuicksilverMotion **** **** **** **** **** **** **** **** +16084 Swordsage_RapidCounter **** **** **** **** **** **** **** **** +16085 Swordsage_RubyNightmareBlade **** **** **** **** **** **** **** **** +16086 Swordsage_SapphireNightmareBlade **** **** **** **** **** **** **** **** +16087 Swordsage_StanceOfAlacrity **** **** **** **** **** **** **** **** +16088 Swordsage_StanceOfClarity **** **** **** **** **** **** **** **** +16089 Swordsage_TimeStandsStill **** **** **** **** **** **** **** **** +16090 Swordsage_AbsoluteSteel **** **** **** **** **** **** **** **** +16091 Swordsage_AdamantineHurricane **** **** **** **** **** **** **** **** +16092 Swordsage_DancingBladeForm **** **** **** **** **** **** **** **** +16093 Swordsage_DazingStrike **** **** **** **** **** **** **** **** +16094 Swordsage_DisarmingStrike **** **** **** **** **** **** **** **** +16095 Swordsage_ExorcismOfSteel **** **** **** **** **** **** **** **** +16096 Swordsage_FinishingMove **** **** **** **** **** **** **** **** +16097 Swordsage_IronHeartEndurance **** **** **** **** **** **** **** **** +16098 Swordsage_IronHeartFocus **** **** **** **** **** **** **** **** +16099 Swordsage_IronHeartSurge **** **** **** **** **** **** **** **** +16100 Swordsage_LightningRecovery **** **** **** **** **** **** **** **** +16101 Swordsage_LightningThrow **** **** **** **** **** **** **** **** +16102 Swordsage_ManticoreParry **** **** **** **** **** **** **** **** +16103 Swordsage_MithralTornado **** **** **** **** **** **** **** **** +16104 Swordsage_PunishingStance **** **** **** **** **** **** **** **** +16105 Swordsage_ScythingBlade **** **** **** **** **** **** **** **** +16106 Swordsage_SteelWind **** **** **** **** **** **** **** **** +16107 Swordsage_SteelyStrike **** **** **** **** **** **** **** **** +16108 Swordsage_StrikeOfPerfectClarity **** **** **** **** **** **** **** **** +16109 Swordsage_SupremeBladeParry **** **** **** **** **** **** **** **** +16110 Swordsage_WallOfBlades **** **** **** **** **** **** **** **** +16111 Swordsage_BafflingDefense **** **** **** **** **** **** **** **** +16112 Swordsage_BallistaThrow **** **** **** **** **** **** **** **** +16113 Swordsage_CleverPositioning **** **** **** **** **** **** **** **** +16114 Swordsage_CometThrow **** **** **** **** **** **** **** **** +16115 Swordsage_CounterCharge **** **** **** **** **** **** **** **** +16116 Swordsage_DevastatingThrow **** **** **** **** **** **** **** **** +16117 Swordsage_FeignedOpening **** **** **** **** **** **** **** **** +16118 Swordsage_FoolsStrike **** **** **** **** **** **** **** **** +16119 Swordsage_GhostlyDefense **** **** **** **** **** **** **** **** +16120 Swordsage_GiantKillingStyle **** **** **** **** **** **** **** **** +16121 Swordsage_HydraSlayingStrike **** **** **** **** **** **** **** **** +16122 Swordsage_MightyThrow **** **** **** **** **** **** **** **** +16123 Swordsage_MirroredPursuit **** **** **** **** **** **** **** **** +16124 Swordsage_ScorpionParry **** **** **** **** **** **** **** **** +16125 Swordsage_ShiftingDefense **** **** **** **** **** **** **** **** +16126 Swordsage_SoaringThrow **** **** **** **** **** **** **** **** +16127 Swordsage_StalkingShadow **** **** **** **** **** **** **** **** +16128 Swordsage_StepOfTheWind **** **** **** **** **** **** **** **** +16129 Swordsage_StrikeOfTheBrokenShield **** **** **** **** **** **** **** **** +16130 Swordsage_TornadoThrow **** **** **** **** **** **** **** **** +16131 Swordsage_AssassinsStance **** **** **** **** **** **** **** **** +16132 Swordsage_BalanceOnTheSky **** **** **** **** **** **** **** **** +16133 Swordsage_BloodlettingStrike **** **** **** **** **** **** **** **** +16134 Swordsage_ChildOfShadow **** **** **** **** **** **** **** **** +16135 Swordsage_ClingingShadowStrike **** **** **** **** **** **** **** **** +16136 Swordsage_CloakOfDeception **** **** **** **** **** **** **** **** +16137 Swordsage_DanceOfTheSpider **** **** **** **** **** **** **** **** +16138 Swordsage_DeathInTheDark **** **** **** **** **** **** **** **** +16139 Swordsage_DrainVitality **** **** **** **** **** **** **** **** +16140 Swordsage_EnervatingShadowStrike **** **** **** **** **** **** **** **** +16141 Swordsage_FiveShadowCreepingIceEnervationStrike **** **** **** **** **** **** **** **** +16142 Swordsage_GhostBlade **** **** **** **** **** **** **** **** +16143 Swordsage_HandOfDeath **** **** **** **** **** **** **** **** +16144 Swordsage_IslandOfBlades **** **** **** **** **** **** **** **** +16145 Swordsage_ObscuringShadowVeil **** **** **** **** **** **** **** **** +16146 Swordsage_OneWithShadow **** **** **** **** **** **** **** **** +16147 Swordsage_ShadowBladeTechnique **** **** **** **** **** **** **** **** +16148 Swordsage_ShadowBlink **** **** **** **** **** **** **** **** +16149 Swordsage_ShadowGarrote **** **** **** **** **** **** **** **** +16150 Swordsage_ShadowJaunt **** **** **** **** **** **** **** **** +16151 Swordsage_ShadowNoose **** **** **** **** **** **** **** **** +16152 Swordsage_ShadowStride **** **** **** **** **** **** **** **** +16153 Swordsage_StalkerInTheNight **** **** **** **** **** **** **** **** +16154 Swordsage_StepOfTheDancingMoth **** **** **** **** **** **** **** **** +16155 Swordsage_StrengthDrainingStrike **** **** **** **** **** **** **** **** +16156 Swordsage_AdamantineBones **** **** **** **** **** **** **** **** +16157 Swordsage_AncientMountainHammer **** **** **** **** **** **** **** **** +16158 Swordsage_BonesplittingStrike **** **** **** **** **** **** **** **** +16159 Swordsage_Bonecrusher **** **** **** **** **** **** **** **** +16160 Swordsage_BoulderRoll **** **** **** **** **** **** **** **** +16161 Swordsage_ChargingMinotaur **** **** **** **** **** **** **** **** +16162 Swordsage_ColossusStrike **** **** **** **** **** **** **** **** +16163 Swordsage_CrushingVise **** **** **** **** **** **** **** **** +16164 Swordsage_CrushingWeightOfTheMountain **** **** **** **** **** **** **** **** +16165 Swordsage_EarthstrikeQuake **** **** **** **** **** **** **** **** +16166 Swordsage_ElderMountainHammer **** **** **** **** **** **** **** **** +16167 Swordsage_GiantsStance **** **** **** **** **** **** **** **** +16168 Swordsage_IronBones **** **** **** **** **** **** **** **** +16169 Swordsage_IrresistibleMountainStrike **** **** **** **** **** **** **** **** +16170 Swordsage_MountainAvalanche **** **** **** **** **** **** **** **** +16171 Swordsage_MountainHammer **** **** **** **** **** **** **** **** +16172 Swordsage_MountainTombstoneStrike **** **** **** **** **** **** **** **** +16173 Swordsage_OverwhelmingMountainStrike **** **** **** **** **** **** **** **** +16174 Swordsage_RootsOfTheMountain **** **** **** **** **** **** **** **** +16175 Swordsage_StoneBones **** **** **** **** **** **** **** **** +16176 Swordsage_StoneDragonsFury **** **** **** **** **** **** **** **** +16177 Swordsage_StoneVise **** **** **** **** **** **** **** **** +16178 Swordsage_StonefootStance **** **** **** **** **** **** **** **** +16179 Swordsage_StrengthOfStone **** **** **** **** **** **** **** **** +16180 Swordsage_BloodInTheWater **** **** **** **** **** **** **** **** +16181 Swordsage_ClawAtTheMoon **** **** **** **** **** **** **** **** +16182 Swordsage_DancingMongoose **** **** **** **** **** **** **** **** +16183 Swordsage_DeathFromAbove **** **** **** **** **** **** **** **** +16184 Swordsage_FeralDeathBlow **** **** **** **** **** **** **** **** +16185 Swordsage_FleshRipper **** **** **** **** **** **** **** **** +16186 Swordsage_FountainOfBlood **** **** **** **** **** **** **** **** +16187 Swordsage_GirallonWindmillFleshRip **** **** **** **** **** **** **** **** +16188 Swordsage_HamstringAttack **** **** **** **** **** **** **** **** +16189 Swordsage_HuntersSense **** **** **** **** **** **** **** **** +16190 Swordsage_LeapingDragonStance **** **** **** **** **** **** **** **** +16191 Swordsage_PouncingCharge **** **** **** **** **** **** **** **** +16192 Swordsage_PreyOnTheWeak **** **** **** **** **** **** **** **** +16193 Swordsage_RabidBearStrike **** **** **** **** **** **** **** **** +16194 Swordsage_RabidWolfStrike **** **** **** **** **** **** **** **** +16195 Swordsage_RagingMongoose **** **** **** **** **** **** **** **** +16196 Swordsage_SoaringRaptorStrike **** **** **** **** **** **** **** **** +16197 Swordsage_SuddenLeap **** **** **** **** **** **** **** **** +16198 Swordsage_SwoopingDragonStrike **** **** **** **** **** **** **** **** +16199 Swordsage_WolfClimbsTheMountain **** **** **** **** **** **** **** **** +16200 Swordsage_WolfFangStrike **** **** **** **** **** **** **** **** +16201 Swordsage_WolfPackTactics **** **** **** **** **** **** **** **** +16202 Swordsage_WolverineStance **** **** **** **** **** **** **** **** +16203 Swordsage_BattleLeadersCharge **** **** **** **** **** **** **** **** +16204 Swordsage_BolsteringVoice **** **** **** **** **** **** **** **** +16205 Swordsage_ClarionCall **** **** **** **** **** **** **** **** +16206 Swordsage_CoveringStrike **** **** **** **** **** **** **** **** +16207 Swordsage_DouseTheFlames **** **** **** **** **** **** **** **** +16208 Swordsage_FlankingManeuver **** **** **** **** **** **** **** **** +16209 Swordsage_LeadingTheAttack **** **** **** **** **** **** **** **** +16210 Swordsage_LeadingTheCharge **** **** **** **** **** **** **** **** +16211 Swordsage_LionsRoar **** **** **** **** **** **** **** **** +16212 Swordsage_OrderForgedFromChaos **** **** **** **** **** **** **** **** +16213 Swordsage_PressTheAdvantage **** **** **** **** **** **** **** **** +16214 Swordsage_SwarmTactics **** **** **** **** **** **** **** **** +16215 Swordsage_SwarmingAssault **** **** **** **** **** **** **** **** +16216 Swordsage_TacticalStrike **** **** **** **** **** **** **** **** +16217 Swordsage_TacticsOfTheWolf **** **** **** **** **** **** **** **** +16218 Swordsage_WarLeadersCharge **** **** **** **** **** **** **** **** +16219 Swordsage_WarMastersCharge **** **** **** **** **** **** **** **** +16220 Swordsage_WhiteRavenHammer **** **** **** **** **** **** **** **** +16221 Swordsage_WhiteRavenStrike **** **** **** **** **** **** **** **** +16222 Swordsage_WhiteRavenTactics **** **** **** **** **** **** **** **** +16223 Warblade_BlisteringFlourish **** **** **** **** **** **** **** **** +16224 Warblade_BurningBlade **** **** **** **** **** **** **** **** +16225 Warblade_BurningBrand **** **** **** **** **** **** **** **** +16226 Warblade_DeathMark **** **** **** **** **** **** **** **** +16227 Warblade_DesertTempest **** **** **** **** **** **** **** **** +16228 Warblade_DistractingEmber **** **** **** **** **** **** **** **** +16229 Warblade_DragonsFlame **** **** **** **** **** **** **** **** +16230 Warblade_FanTheFlames **** **** **** **** **** **** **** **** +16231 Warblade_FieryAssault **** **** **** **** **** **** **** **** +16232 Warblade_FireRiposte **** **** **** **** **** **** **** **** +16233 Warblade_Firesnake **** **** **** **** **** **** **** **** +16234 Warblade_FlamesBlessing **** **** **** **** **** **** **** **** +16235 Warblade_FlashingSun **** **** **** **** **** **** **** **** +16236 Warblade_HatchlingsFlame **** **** **** **** **** **** **** **** +16237 Warblade_HolocaustCloak **** **** **** **** **** **** **** **** +16238 Warblade_InfernoBlade **** **** **** **** **** **** **** **** +16239 Warblade_InfernoBlast **** **** **** **** **** **** **** **** +16240 Warblade_LeapingFlame **** **** **** **** **** **** **** **** +16241 Warblade_LingeringInferno **** **** **** **** **** **** **** **** +16242 Warblade_RingOfFire **** **** **** **** **** **** **** **** +16243 Warblade_RisingPhoenix **** **** **** **** **** **** **** **** +16244 Warblade_SalamanderCharge **** **** **** **** **** **** **** **** +16245 Warblade_SearingBlade **** **** **** **** **** **** **** **** +16246 Warblade_SearingCharge **** **** **** **** **** **** **** **** +16247 Warblade_WindStride **** **** **** **** **** **** **** **** +16248 Warblade_WyrmsFlame **** **** **** **** **** **** **** **** +16249 Warblade_ZephyrDance **** **** **** **** **** **** **** **** +16250 Warblade_AuraOfChaos **** **** **** **** **** **** **** **** +16251 Warblade_AuraOfPerfectOrder **** **** **** **** **** **** **** **** +16252 Warblade_AuraOfTriumph **** **** **** **** **** **** **** **** +16253 Warblade_AuraOfTyranny **** **** **** **** **** **** **** **** +16254 Warblade_CastigatingStrike **** **** **** **** **** **** **** **** +16255 Warblade_CrusadersStrike **** **** **** **** **** **** **** **** +16256 Warblade_DauntingStrike **** **** **** **** **** **** **** **** +16257 Warblade_DefensiveRebuke **** **** **** **** **** **** **** **** +16258 Warblade_DivineSurge **** **** **** **** **** **** **** **** +16259 Warblade_DivineSurgeGreater **** **** **** **** **** **** **** **** +16260 Warblade_DivineSurgeGreaterSub1 **** **** **** **** **** **** **** **** +16261 Warblade_DivineSurgeGreaterSub2 **** **** **** **** **** **** **** **** +16262 Warblade_DivineSurgeGreaterSub3 **** **** **** **** **** **** **** **** +16263 Warblade_DoomCharge **** **** **** **** **** **** **** **** +16264 Warblade_EntanglingBlade **** **** **** **** **** **** **** **** +16265 Warblade_Foehammer **** **** **** **** **** **** **** **** +16266 Warblade_ImmortalFortitude **** **** **** **** **** **** **** **** +16267 Warblade_IronGuardsGlare **** **** **** **** **** **** **** **** +16268 Warblade_LawBearer **** **** **** **** **** **** **** **** +16269 Warblade_MartialSpirit **** **** **** **** **** **** **** **** +16270 Warblade_RadiantCharge **** **** **** **** **** **** **** **** +16271 Warblade_RallyingStrike **** **** **** **** **** **** **** **** +16272 Warblade_RevitalizingStrike **** **** **** **** **** **** **** **** +16273 Warblade_ShieldBlock **** **** **** **** **** **** **** **** +16274 Warblade_ShieldCounter **** **** **** **** **** **** **** **** +16275 Warblade_StrikeOfRighteousVitality **** **** **** **** **** **** **** **** +16276 Warblade_ThicketOfBlades **** **** **** **** **** **** **** **** +16277 Warblade_TideOfChaos **** **** **** **** **** **** **** **** +16278 Warblade_VanguardStrike **** **** **** **** **** **** **** **** +16279 Warblade_ActionBeforeThought **** **** **** **** **** **** **** **** +16280 Warblade_AvalancheOfBlades **** **** **** **** **** **** **** **** +16281 Warblade_BoundingAssault **** **** **** **** **** **** **** **** +16282 Warblade_DiamondDefense **** **** **** **** **** **** **** **** +16283 Warblade_DiamondNightmareBlade **** **** **** **** **** **** **** **** +16284 Warblade_DisruptingBlow **** **** **** **** **** **** **** **** +16285 Warblade_EmeraldRazor **** **** **** **** **** **** **** **** +16286 Warblade_HearingTheAir **** **** **** **** **** **** **** **** +16287 Warblade_InsightfulStrike **** **** **** **** **** **** **** **** +16288 Warblade_InsightfulStrikeGreater **** **** **** **** **** **** **** **** +16289 Warblade_MindOverBody **** **** **** **** **** **** **** **** +16290 Warblade_MindStrike **** **** **** **** **** **** **** **** +16291 Warblade_MomentOfAlacrity **** **** **** **** **** **** **** **** +16292 Warblade_MomentOfPerfectMind **** **** **** **** **** **** **** **** +16293 Warblade_PearlOfBlackDoubt **** **** **** **** **** **** **** **** +16294 Warblade_QuicksilverMotion **** **** **** **** **** **** **** **** +16295 Warblade_RapidCounter **** **** **** **** **** **** **** **** +16296 Warblade_RubyNightmareBlade **** **** **** **** **** **** **** **** +16297 Warblade_SapphireNightmareBlade **** **** **** **** **** **** **** **** +16298 Warblade_StanceOfAlacrity **** **** **** **** **** **** **** **** +16299 ####END_OF_TOB_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +16300 Templates_16300-16999 **** **** **** **** **** **** **** **** +16301 Celestial_Smite_Evil **** **** **** **** **** **** **** **** +16302 Fiendish_Smite_Good **** **** **** **** **** **** **** **** +16303 Half_Celestial_Smite_Evil **** **** **** **** **** **** **** **** +16304 Half_Celestial_Protection_from_Evil **** **** **** **** **** **** **** **** +16305 Half_Celestial_Bless **** **** **** **** **** **** **** **** +16306 Half_Celestial_Aid **** **** **** **** **** **** **** **** +16307 Half_Celestial_Detect_Evil **** **** **** **** **** **** **** **** +16308 Half_Celestial_Cure_Serious_Wounds **** **** **** **** **** **** **** **** +16309 Half_Celestial_Neutralize_Poison **** **** **** **** **** **** **** **** +16310 Half_Celestial_HolySmite **** **** **** **** **** **** **** **** +16311 Half_Celestial_Remove_Disease **** **** **** **** **** **** **** **** +16312 Half_Celestial_DispelEvil **** **** **** **** **** **** **** **** +16313 Half_Celestial_Holy_Word **** **** **** **** **** **** **** **** +16314 Half_Celestial_HolyAura **** **** **** **** **** **** **** **** +16315 Half_Celestial_Hallow **** **** **** **** **** **** **** **** +16316 Half_Celestial_Mass_Charm **** **** **** **** **** **** **** **** +16317 Half_Celestial_Summon_Creature_IX **** **** **** **** **** **** **** **** +16318 Half_Celestial_Summon_Creature_IX_Air **** **** **** **** **** **** **** **** +16319 Half_Celestial_Summon_Creature_IX_Earth **** **** **** **** **** **** **** **** +16320 Half_Celestial_Summon_Creature_IX_Fire **** **** **** **** **** **** **** **** +16321 Half_Celestial_Summon_Creature_IX_Water **** **** **** **** **** **** **** **** +16322 Half_Celestial_Resurrection **** **** **** **** **** **** **** **** +16323 Half_Celestial_Daylight **** **** **** **** **** **** **** **** +16324 Half_Fiendish_Smite_Good **** **** **** **** **** **** **** **** +16325 Half_Fiendish_Darkness **** **** **** **** **** **** **** **** +16326 Half_Fiendish_Desecrate **** **** **** **** **** **** **** **** +16327 Half_Fiendish_Unholy_Blight **** **** **** **** **** **** **** **** +16328 Half_Fiendish_Poison **** **** **** **** **** **** **** **** +16329 Half_Fiendish_Contagion **** **** **** **** **** **** **** **** +16330 Half_Fiendish_Blasphemy **** **** **** **** **** **** **** **** +16331 Half_Fiendish_Unholy_Aura **** **** **** **** **** **** **** **** +16332 Half_Fiendish_Unhallow **** **** **** **** **** **** **** **** +16333 Half_Fiendish_Horrid_Wilting **** **** **** **** **** **** **** **** +16334 Half_Fiendish_Summon_Creature_IX **** **** **** **** **** **** **** **** +16335 Half_Fiendish_Summon_Creature_IX_Air **** **** **** **** **** **** **** **** +16336 Half_Fiendish_Summon_Creature_IX_Earth **** **** **** **** **** **** **** **** +16337 Half_Fiendish_Summon_Creature_IX_Fire **** **** **** **** **** **** **** **** +16338 Half_Fiendish_Summon_Creature_IX_Water **** **** **** **** **** **** **** **** +16339 Half_Fiendish_Destruction **** **** **** **** **** **** **** **** +16340 Lich_Fear_Aura **** **** **** **** **** **** **** **** +16341 Lich_Paralyzing_Touch **** **** **** **** **** **** **** **** +16342 Lich_Appearance **** **** **** **** **** **** **** **** +16343 Demilich_Alter_Self **** **** **** **** **** **** **** **** +16344 Demilich_Alter_Self_Learn **** **** **** **** **** **** **** **** +16345 Demilich_Alter_Self_Options **** **** **** **** **** **** **** **** +16346 Demilich_Alter_Self_QS1 **** **** **** **** **** **** **** **** +16347 Demilich_Alter_Self_QS2 **** **** **** **** **** **** **** **** +16348 Demilich_Alter_Self_QS3 **** **** **** **** **** **** **** **** +16349 Demilich_Astral_Projection **** **** **** **** **** **** **** **** +16350 Demilich_Create_Greater_Undead **** **** **** **** **** **** **** **** +16351 Demilich_Create_Undead **** **** **** **** **** **** **** **** +16352 Demilich_Death_Knell **** **** **** **** **** **** **** **** +16353 Demilich_Enervation **** **** **** **** **** **** **** **** +16354 Demilich_Greater_Dispel_Magic **** **** **** **** **** **** **** **** +16355 Demilich_Harm **** **** **** **** **** **** **** **** +16356 Demilich_Summon_Creature_I **** **** **** **** **** **** **** **** +16357 Demilich_Summon_Creature_II **** **** **** **** **** **** **** **** +16358 Demilich_Summon_Creature_III **** **** **** **** **** **** **** **** +16359 Demilich_Summon_Creature_IV **** **** **** **** **** **** **** **** +16360 Demilich_Summon_Creature_V **** **** **** **** **** **** **** **** +16361 Demilich_Summon_Creature_VI **** **** **** **** **** **** **** **** +16362 Demilich_Summon_Creature_VII **** **** **** **** **** **** **** **** +16363 Demilich_Summon_Creature_VII_Air **** **** **** **** **** **** **** **** +16364 Demilich_Summon_Creature_VII_Earth **** **** **** **** **** **** **** **** +16365 Demilich_Summon_Creature_VII_Fire **** **** **** **** **** **** **** **** +16366 Demilich_Summon_Creature_VII_Water **** **** **** **** **** **** **** **** +16367 Demilich_Summon_Creature_VIII **** **** **** **** **** **** **** **** +16368 Demilich_Summon_Creature_VIII_Air **** **** **** **** **** **** **** **** +16369 Demilich_Summon_Creature_VIII_Earth **** **** **** **** **** **** **** **** +16370 Demilich_Summon_Creature_VIII_Fire **** **** **** **** **** **** **** **** +16371 Demilich_Summon_Creature_VIII_Water **** **** **** **** **** **** **** **** +16372 Demilich_Summon_Creature_IX **** **** **** **** **** **** **** **** +16373 Demilich_Summon_Creature_IX_Air **** **** **** **** **** **** **** **** +16374 Demilich_Summon_Creature_IX_Earth **** **** **** **** **** **** **** **** +16375 Demilich_Summon_Creature_IX_Fire **** **** **** **** **** **** **** **** +16376 Demilich_Summon_Creature_IX_Water **** **** **** **** **** **** **** **** +16377 Demilich_Telekinesis **** **** **** **** **** **** **** **** +16378 Demilich_Weird **** **** **** **** **** **** **** **** +16379 Demilich_Greater_Planar_Ally **** **** **** **** **** **** **** **** +16380 HalfDragon_Breath_Weapon **** **** **** **** **** **** **** **** +16381 Archlich_Turn_Undead **** **** **** **** **** **** **** **** +16382 Saint_Bless **** **** **** **** **** **** **** **** +16383 Saint_Guidance_Placeholder **** **** **** **** **** **** **** **** +16384 Saint_Resistance **** **** **** **** **** **** **** **** +16385 Saint_Virtue **** **** **** **** **** **** **** **** +16386 Saint_Protective_Aura **** **** **** **** **** **** **** **** +16387 **** **** **** **** **** **** **** **** **** +16388 **** **** **** **** **** **** **** **** **** +16389 **WeaponsOfLegacy** **** **** **** **** **** **** **** **** +16390 BBB_Darkvision **** **** **** **** **** **** **** **** +16391 BBB_Longstrider **** **** **** **** **** **** **** **** +16392 BBB_Lesser_Restoration **** **** **** **** **** **** **** **** +16393 BBB_Teleport_SelfOnly **** **** **** **** **** **** **** **** +16394 BBB_Protection_from_Evil **** **** **** **** **** **** **** **** +16395 BBB_Drowseeker **** **** **** **** **** **** **** **** +16396 BBB_ShockingShot **** **** **** **** **** **** **** **** +16397 BBB_PierceTheBlackHeart **** **** **** **** **** **** **** **** +16398 Steadfast_vigor **** **** **** **** **** **** **** **** +16399 Steadfast_slow **** **** **** **** **** **** **** **** +16400 Flay_SnakeSting **** **** **** **** **** **** **** **** +16401 Flay_WhipWrap **** **** **** **** **** **** **** **** +16402 CrimsonRuination_FrozenFate **** **** **** **** **** **** **** **** +16403 Devious_DetectThoughts **** **** **** **** **** **** **** **** +16404 SimpleBow_TrueSeeing **** **** **** **** **** **** **** **** +16405 SimpleBow_Prescience **** **** **** **** **** **** **** **** +16406 SimpleBow_Focus **** **** **** **** **** **** **** **** +16407 Aradros_Extend **** **** **** **** **** **** **** **** +16408 Aradros_Survive_Master **** **** **** **** **** **** **** **** +16409 Aradros_Survive_Acid **** **** **** **** **** **** **** **** +16410 Aradros_Survive_Cold **** **** **** **** **** **** **** **** +16411 Aradros_Survive_Elec **** **** **** **** **** **** **** **** +16412 Aradros_Survive_Fire **** **** **** **** **** **** **** **** +16413 Aradros_Survive_Sonic **** **** **** **** **** **** **** **** +16414 Guurgal_Force **** **** **** **** **** **** **** **** +16415 Guurgal_Rage **** **** **** **** **** **** **** **** +16416 DivSpark_Fear **** **** **** **** **** **** **** **** +16417 DivSpark_Light **** **** **** **** **** **** **** **** +16418 Wargirds_Haste **** **** **** **** **** **** **** **** +16419 Wargirds_Stoneskin **** **** **** **** **** **** **** **** +16420 DesertWind_FierySlash **** **** **** **** **** **** **** **** +16421 DesertWind_HowlingWind **** **** **** **** **** **** **** **** +16422 DesertWind_FanFlames **** **** **** **** **** **** **** **** +16423 DesertWind_DustDesert **** **** **** **** **** **** **** **** +16424 Mindsplinter_VirtueDenied **** **** **** **** **** **** **** **** +16425 Mindsplinter_KissOfDeath **** **** **** **** **** **** **** **** +16426 Mindsplinter_BattleShriek **** **** **** **** **** **** **** **** +16427 Mindsplinter_RuinousHowl **** **** **** **** **** **** **** **** +16428 NotchedSpear_ParliamentOfFishes **** **** **** **** **** **** **** **** +16429 NotchedSpear_ConcealmentKraken **** **** **** **** **** **** **** **** +16430 NotchedSpear_ScionSea **** **** **** **** **** **** **** **** +16431 NotchedSpear_CommandSeaChildren **** **** **** **** **** **** **** **** +16432 Ur_SwiftStride **** **** **** **** **** **** **** **** +16433 Ur_HealingTotem **** **** **** **** **** **** **** **** +16434 Ur_SavageTransformation **** **** **** **** **** **** **** **** +16435 FlamecastersBolt_MarkTarget **** **** **** **** **** **** **** **** +16436 FlamecastersBolt_Morale **** **** **** **** **** **** **** **** +16437 FlamecastersBolt_Fireball **** **** **** **** **** **** **** **** +16438 StalkersBow_StalkersInsight **** **** **** **** **** **** **** **** +16439 StalkersBow_Ethereal **** **** **** **** **** **** **** **** +16440 Exordius_Guidance **** **** **** **** **** **** **** **** +16441 Exordius_Cure **** **** **** **** **** **** **** **** +16442 Exordius_Dismissal **** **** **** **** **** **** **** **** +16443 Caladbolg_Imprison **** **** **** **** **** **** **** **** +16444 HammerWitches_Detect **** **** **** **** **** **** **** **** +16445 HammerWitches_Spellbreaker **** **** **** **** **** **** **** **** +16446 HammerWitches_AMF **** **** **** **** **** **** **** **** +16447 HammerWitches_Dispel **** **** **** **** **** **** **** **** +16448 HammerWitches_Mantle **** **** **** **** **** **** **** **** +16449 SlingOfTheDireWind_StunningStone **** **** **** **** **** **** **** **** +16450 SlingOfTheDireWind_GustOfWind **** **** **** **** **** **** **** **** +16451 SlingOfTheDireWind_WindWall **** **** **** **** **** **** **** **** +16452 Treebrother_Shillelagh **** **** **** **** **** **** **** **** +16453 Treebrother_Charm_Plant **** **** **** **** **** **** **** **** +16454 Treebrother_Entangle **** **** **** **** **** **** **** **** +16455 Treebrother_Owls_Insight **** **** **** **** **** **** **** **** +16456 Treebrother_Changestaff **** **** **** **** **** **** **** **** +16457 FullMoonsTrick_Rage **** **** **** **** **** **** **** **** +16458 FullMoonsTrick_Invis **** **** **** **** **** **** **** **** +16459 FiendkillersFlail_Darkvis **** **** **** **** **** **** **** **** +16460 FiendkillersFlail_Detect **** **** **** **** **** **** **** **** +16461 ScalesBalance_Detect **** **** **** **** **** **** **** **** +16462 ScalesBalance_Cure **** **** **** **** **** **** **** **** +16463 ScalesBalance_Knell **** **** **** **** **** **** **** **** +16464 ScalesBalance_Enerv **** **** **** **** **** **** **** **** +16465 ScalesBalance_Heal **** **** **** **** **** **** **** **** +16466 ScalesBalance_Finger **** **** **** **** **** **** **** **** +16467 ShishiO_Charm **** **** **** **** **** **** **** **** +16468 ShishiO_Summon **** **** **** **** **** **** **** **** +16469 ShishiO_Poly **** **** **** **** **** **** **** **** +16470 ShishiO_Shout **** **** **** **** **** **** **** **** +16471 Dymondheart_ShedBolts **** **** **** **** **** **** **** **** +16472 Dymondheart_Deflect **** **** **** **** **** **** **** **** +16473 Dymondheart_Daylight **** **** **** **** **** **** **** **** +16474 Dymondheart_Cure **** **** **** **** **** **** **** **** +16475 Dymondheart_Banish **** **** **** **** **** **** **** **** +16476 Sunsword_Daylight **** **** **** **** **** **** **** **** +16477 Sunsword_Death_Ward **** **** **** **** **** **** **** **** +16478 Sunsword_Banish **** **** **** **** **** **** **** **** +16479 Sunsword_Undeath_to_Death **** **** **** **** **** **** **** **** +16480 Blackrazor_Detect **** **** **** **** **** **** **** **** +16481 Blackrazor_Knell **** **** **** **** **** **** **** **** +16482 Blackrazor_Haste **** **** **** **** **** **** **** **** +16483 Ramethene_Detect **** **** **** **** **** **** **** **** +16484 Ramethene_Smite **** **** **** **** **** **** **** **** +16485 Ramethene_Resist_Elements **** **** **** **** **** **** **** **** +16486 Ramethene_Cloudkill **** **** **** **** **** **** **** **** +16487 Ramethene_SuddenMaximize **** **** **** **** **** **** **** **** +16488 Ramethene_Horrid_Wilting **** **** **** **** **** **** **** **** +16489 Wyrmbane_Cause_Fear **** **** **** **** **** **** **** **** +16490 Wyrmbane_Lightning_Bolt **** **** **** **** **** **** **** **** +16491 Wyrmbane_Sudden_Emp **** **** **** **** **** **** **** **** +16492 Wyrmbane_Breath_Lightning **** **** **** **** **** **** **** **** +16493 Whelm_Detect_Giant **** **** **** **** **** **** **** **** +16494 Whelm_Locate_Object **** **** **** **** **** **** **** **** +16495 Whelm_Detect_Goblin **** **** **** **** **** **** **** **** +16496 Ravenkind_Dancing_Lights **** **** **** **** **** **** **** **** +16497 Ravenkind_Light **** **** **** **** **** **** **** **** +16498 Ravenkind_Flare **** **** **** **** **** **** **** **** +16499 Ravenkind_Detect_Undead **** **** **** **** **** **** **** **** +16500 Ravenkind_Halt_Undead **** **** **** **** **** **** **** **** +16501 Ravenkind_Cure_Light_Wounds **** **** **** **** **** **** **** **** +16502 Ravenkind_Daylight **** **** **** **** **** **** **** **** +16503 Ravenkind_Death_Ward **** **** **** **** **** **** **** **** +16504 Ravenkind_Break_Enchantment **** **** **** **** **** **** **** **** +16505 Ravenkind_Mass_Heal **** **** **** **** **** **** **** **** +16506 LastCitadel_LeadingTheAttack **** **** **** **** **** **** **** **** +16507 LastCitadel_Prayer **** **** **** **** **** **** **** **** +16508 LastCitadel_Remove_Fear **** **** **** **** **** **** **** **** +16509 LastCitadel_Cure_Critical_Wounds **** **** **** **** **** **** **** **** +16510 LastCitadel_Blade_Barrier **** **** **** **** **** **** **** **** +16511 LastCitadel_Heal **** **** **** **** **** **** **** **** +16512 Unfettered_ChargingMinotaur **** **** **** **** **** **** **** **** +16513 Unfettered_ENLARGE_PERSON **** **** **** **** **** **** **** **** +16514 Unfettered_Etherealness **** **** **** **** **** **** **** **** +16515 Unfettered_Stoneskin **** **** **** **** **** **** **** **** +16516 Unfettered_Mordenkainens_Sword **** **** **** **** **** **** **** **** +16517 Hillcrusher_Earthen_Might **** **** **** **** **** **** **** **** +16518 Hillcrusher_Soften_Earth **** **** **** **** **** **** **** **** +16519 Hillcrusher_Fangs_of_Stone **** **** **** **** **** **** **** **** +16520 Hillcrusher_Raise_the_Earth **** **** **** **** **** **** **** **** +16521 Hillcrusher_Shake_the_Earth **** **** **** **** **** **** **** **** +16522 DesertWindToB_BurningBlade **** **** **** **** **** **** **** **** +16523 DesertWindToB_FanTheFlames **** **** **** **** **** **** **** **** +16524 DesertWindToB_WyrmsFlame **** **** **** **** **** **** **** **** +16525 Faithful_FaithfulStrike **** **** **** **** **** **** **** **** +16526 Faithful_Detect_Evil **** **** **** **** **** **** **** **** +16527 Faithful_Lesser_Restoration **** **** **** **** **** **** **** **** +16528 Faithful_Restoration **** **** **** **** **** **** **** **** +16529 Faithful_Resiliency **** **** **** **** **** **** **** **** +16530 Faithful_ImmortalFortitude **** **** **** **** **** **** **** **** +16531 SupernalClarity_SapphireNightmareBlade **** **** **** **** **** **** **** **** +16532 SupernalClarity_PsychicPoise **** **** **** **** **** **** **** **** +16533 SupernalClarity_Haste **** **** **** **** **** **** **** **** +16534 SupernalClarity_Freeeeeedom **** **** **** **** **** **** **** **** +16535 SupernalClarity_Time_Stop **** **** **** **** **** **** **** **** +16536 Kamate_SteelWind **** **** **** **** **** **** **** **** +16537 Kamate_ShockingGrasp **** **** **** **** **** **** **** **** +16538 Kamate_Lightning_Bolt **** **** **** **** **** **** **** **** +16539 Kamate_Chain_Lightning **** **** **** **** **** **** **** **** +16540 Kamate_True_Strike **** **** **** **** **** **** **** **** +16541 Eventide_CometThrow **** **** **** **** **** **** **** **** +16542 Eventide_BafflingDefense **** **** **** **** **** **** **** **** +16543 Eventide_Improved_Invisibility **** **** **** **** **** **** **** **** +16544 Umbral_Invisibility **** **** **** **** **** **** **** **** +16545 Umbral_Shadowstep **** **** **** **** **** **** **** **** +16546 Umbral_SpeedWeapon **** **** **** **** **** **** **** **** +16547 TigerFang_FrenziedCharge **** **** **** **** **** **** **** **** +16548 TigerFang_BattleFever **** **** **** **** **** **** **** **** +16549 TigerFang_Haste **** **** **** **** **** **** **** **** +16550 Bullybasher_KnockSilly **** **** **** **** **** **** **** **** +16551 Bullybasher_StoneGathering **** **** **** **** **** **** **** **** +16552 Bullybasher_LightningPunch **** **** **** **** **** **** **** **** +16553 Bullybasher_GiantBearing **** **** **** **** **** **** **** **** +16554 Lorestealer_Read_Magic **** **** **** **** **** **** **** **** +16555 Lorestealer_DetectMagic **** **** **** **** **** **** **** **** +16556 Lorestealer_Axecasting **** **** **** **** **** **** **** **** +16557 Durindana_Daylight **** **** **** **** **** **** **** **** +16558 Durindana_Death_Ward **** **** **** **** **** **** **** **** +16559 Durindana_Hallow **** **** **** **** **** **** **** **** +16560 Durindana_Dazzle **** **** **** **** **** **** **** **** +16561 Thaas_Detect_Demon **** **** **** **** **** **** **** **** +16562 Thaas_ObstructSummoning **** **** **** **** **** **** **** **** +16563 Thaas_Banishment **** **** **** **** **** **** **** **** +16564 Thaas_Teleport **** **** **** **** **** **** **** **** +16565 Quickspur_Entropic_Shield **** **** **** **** **** **** **** **** +16566 Quickspur_Resist_Elements **** **** **** **** **** **** **** **** +16567 Quickspur_PhantomSteed **** **** **** **** **** **** **** **** +16568 Quickspur_Blur **** **** **** **** **** **** **** **** +16569 Quickspur_Stoneskin **** **** **** **** **** **** **** **** +16570 BES_FIRE_OF_THE_HEART **** **** **** **** **** **** **** **** +16571 BES_ENTHRALLING_LIGHT **** **** **** **** **** **** **** **** +16572 BES_COLOR_SPRAY **** **** **** **** **** **** **** **** +16573 BES_BLINDING_FLASH **** **** **** **** **** **** **** **** +16574 BES_SHOOTING_STARS **** **** **** **** **** **** **** **** +16575 BES_GLITTERING_MOTES **** **** **** **** **** **** **** **** +16576 BES_TWINKLE **** **** **** **** **** **** **** **** +16577 BES_SILVER_STARLIGHT **** **** **** **** **** **** **** **** +16578 BES_STARLIGHT_DISPELLING **** **** **** **** **** **** **** **** +16579 BES_TALES_IN_THE_SKY **** **** **** **** **** **** **** **** +16580 BES_CALL_DOWN_A_STAR **** **** **** **** **** **** **** **** +16581 **** **** **** **** **** **** **** **** **** +16582 **** **** **** **** **** **** **** **** **** +16583 **** **** **** **** **** **** **** **** **** +16584 **** **** **** **** **** **** **** **** **** +16585 **** **** **** **** **** **** **** **** **** +16586 **** **** **** **** **** **** **** **** **** +16587 **** **** **** **** **** **** **** **** **** +16588 **** **** **** **** **** **** **** **** **** +16589 **** **** **** **** **** **** **** **** **** +16590 Templates_16300-16999 **** **** **** **** **** **** **** **** +16591 **** **** **** **** **** **** **** **** **** +16592 **** **** **** **** **** **** **** **** **** +16593 **** **** **** **** **** **** **** **** **** +16594 **** **** **** **** **** **** **** **** **** +16595 **** **** **** **** **** **** **** **** **** +16596 **** **** **** **** **** **** **** **** **** +16597 **** **** **** **** **** **** **** **** **** +16598 **** **** **** **** **** **** **** **** **** +16599 **** **** **** **** **** **** **** **** **** +16600 Templates_16300-16999 **** **** **** **** **** **** **** **** +16601 **** **** **** **** **** **** **** **** **** +16602 **** **** **** **** **** **** **** **** **** +16603 **** **** **** **** **** **** **** **** **** +16604 **** **** **** **** **** **** **** **** **** +16605 **** **** **** **** **** **** **** **** **** +16606 **** **** **** **** **** **** **** **** **** +16607 **** **** **** **** **** **** **** **** **** +16608 **** **** **** **** **** **** **** **** **** +16609 **** **** **** **** **** **** **** **** **** +16610 Templates_16300-16999 **** **** **** **** **** **** **** **** +16611 **** **** **** **** **** **** **** **** **** +16612 **** **** **** **** **** **** **** **** **** +16613 **** **** **** **** **** **** **** **** **** +16614 **** **** **** **** **** **** **** **** **** +16615 **** **** **** **** **** **** **** **** **** +16616 **** **** **** **** **** **** **** **** **** +16617 **** **** **** **** **** **** **** **** **** +16618 **** **** **** **** **** **** **** **** **** +16619 **** **** **** **** **** **** **** **** **** +16620 Templates_16300-16999 **** **** **** **** **** **** **** **** +16621 **** **** **** **** **** **** **** **** **** +16622 **** **** **** **** **** **** **** **** **** +16623 **** **** **** **** **** **** **** **** **** +16624 **** **** **** **** **** **** **** **** **** +16625 **** **** **** **** **** **** **** **** **** +16626 **** **** **** **** **** **** **** **** **** +16627 **** **** **** **** **** **** **** **** **** +16628 **** **** **** **** **** **** **** **** **** +16629 **** **** **** **** **** **** **** **** **** +16630 Templates_16300-16999 **** **** **** **** **** **** **** **** +16631 **** **** **** **** **** **** **** **** **** +16632 **** **** **** **** **** **** **** **** **** +16633 **** **** **** **** **** **** **** **** **** +16634 **** **** **** **** **** **** **** **** **** +16635 **** **** **** **** **** **** **** **** **** +16636 **** **** **** **** **** **** **** **** **** +16637 **** **** **** **** **** **** **** **** **** +16638 **** **** **** **** **** **** **** **** **** +16639 **** **** **** **** **** **** **** **** **** +16640 Templates_16300-16999 **** **** **** **** **** **** **** **** +16641 **** **** **** **** **** **** **** **** **** +16642 **** **** **** **** **** **** **** **** **** +16643 **** **** **** **** **** **** **** **** **** +16644 **** **** **** **** **** **** **** **** **** +16645 **** **** **** **** **** **** **** **** **** +16646 **** **** **** **** **** **** **** **** **** +16647 **** **** **** **** **** **** **** **** **** +16648 **** **** **** **** **** **** **** **** **** +16649 **** **** **** **** **** **** **** **** **** +16650 Templates_16300-16999 **** **** **** **** **** **** **** **** +16651 **** **** **** **** **** **** **** **** **** +16652 **** **** **** **** **** **** **** **** **** +16653 **** **** **** **** **** **** **** **** **** +16654 **** **** **** **** **** **** **** **** **** +16655 **** **** **** **** **** **** **** **** **** +16656 **** **** **** **** **** **** **** **** **** +16657 **** **** **** **** **** **** **** **** **** +16658 **** **** **** **** **** **** **** **** **** +16659 **** **** **** **** **** **** **** **** **** +16660 Templates_16300-16999 **** **** **** **** **** **** **** **** +16661 **** **** **** **** **** **** **** **** **** +16662 **** **** **** **** **** **** **** **** **** +16663 **** **** **** **** **** **** **** **** **** +16664 **** **** **** **** **** **** **** **** **** +16665 **** **** **** **** **** **** **** **** **** +16666 **** **** **** **** **** **** **** **** **** +16667 **** **** **** **** **** **** **** **** **** +16668 **** **** **** **** **** **** **** **** **** +16669 **** **** **** **** **** **** **** **** **** +16670 Templates_16300-16999 **** **** **** **** **** **** **** **** +16671 **** **** **** **** **** **** **** **** **** +16672 **** **** **** **** **** **** **** **** **** +16673 **** **** **** **** **** **** **** **** **** +16674 **** **** **** **** **** **** **** **** **** +16675 **** **** **** **** **** **** **** **** **** +16676 **** **** **** **** **** **** **** **** **** +16677 **** **** **** **** **** **** **** **** **** +16678 **** **** **** **** **** **** **** **** **** +16679 **** **** **** **** **** **** **** **** **** +16680 Templates_16300-16999 **** **** **** **** **** **** **** **** +16681 **** **** **** **** **** **** **** **** **** +16682 **** **** **** **** **** **** **** **** **** +16683 **** **** **** **** **** **** **** **** **** +16684 **** **** **** **** **** **** **** **** **** +16685 **** **** **** **** **** **** **** **** **** +16686 **** **** **** **** **** **** **** **** **** +16687 **** **** **** **** **** **** **** **** **** +16688 **** **** **** **** **** **** **** **** **** +16689 **** **** **** **** **** **** **** **** **** +16690 Templates_16300-16999 **** **** **** **** **** **** **** **** +16691 **** **** **** **** **** **** **** **** **** +16692 **** **** **** **** **** **** **** **** **** +16693 **** **** **** **** **** **** **** **** **** +16694 **** **** **** **** **** **** **** **** **** +16695 **** **** **** **** **** **** **** **** **** +16696 **** **** **** **** **** **** **** **** **** +16697 **** **** **** **** **** **** **** **** **** +16698 **** **** **** **** **** **** **** **** **** +16699 **** **** **** **** **** **** **** **** **** +16700 Templates_16300-16999 **** **** **** **** **** **** **** **** +16701 **** **** **** **** **** **** **** **** **** +16702 **** **** **** **** **** **** **** **** **** +16703 **** **** **** **** **** **** **** **** **** +16704 **** **** **** **** **** **** **** **** **** +16705 **** **** **** **** **** **** **** **** **** +16706 **** **** **** **** **** **** **** **** **** +16707 **** **** **** **** **** **** **** **** **** +16708 **** **** **** **** **** **** **** **** **** +16709 **** **** **** **** **** **** **** **** **** +16710 Templates_16300-16999 **** **** **** **** **** **** **** **** +16711 **** **** **** **** **** **** **** **** **** +16712 **** **** **** **** **** **** **** **** **** +16713 **** **** **** **** **** **** **** **** **** +16714 **** **** **** **** **** **** **** **** **** +16715 **** **** **** **** **** **** **** **** **** +16716 **** **** **** **** **** **** **** **** **** +16717 **** **** **** **** **** **** **** **** **** +16718 **** **** **** **** **** **** **** **** **** +16719 **** **** **** **** **** **** **** **** **** +16720 Templates_16300-16999 **** **** **** **** **** **** **** **** +16721 **** **** **** **** **** **** **** **** **** +16722 **** **** **** **** **** **** **** **** **** +16723 **** **** **** **** **** **** **** **** **** +16724 **** **** **** **** **** **** **** **** **** +16725 **** **** **** **** **** **** **** **** **** +16726 **** **** **** **** **** **** **** **** **** +16727 **** **** **** **** **** **** **** **** **** +16728 **** **** **** **** **** **** **** **** **** +16729 **** **** **** **** **** **** **** **** **** +16730 Templates_16300-16999 **** **** **** **** **** **** **** **** +16731 **** **** **** **** **** **** **** **** **** +16732 **** **** **** **** **** **** **** **** **** +16733 **** **** **** **** **** **** **** **** **** +16734 **** **** **** **** **** **** **** **** **** +16735 **** **** **** **** **** **** **** **** **** +16736 **** **** **** **** **** **** **** **** **** +16737 **** **** **** **** **** **** **** **** **** +16738 **** **** **** **** **** **** **** **** **** +16739 **** **** **** **** **** **** **** **** **** +16740 Templates_16300-16999 **** **** **** **** **** **** **** **** +16741 **** **** **** **** **** **** **** **** **** +16742 **** **** **** **** **** **** **** **** **** +16743 **** **** **** **** **** **** **** **** **** +16744 **** **** **** **** **** **** **** **** **** +16745 **** **** **** **** **** **** **** **** **** +16746 **** **** **** **** **** **** **** **** **** +16747 **** **** **** **** **** **** **** **** **** +16748 **** **** **** **** **** **** **** **** **** +16749 **** **** **** **** **** **** **** **** **** +16750 Templates_16300-16999 **** **** **** **** **** **** **** **** +16751 **** **** **** **** **** **** **** **** **** +16752 **** **** **** **** **** **** **** **** **** +16753 **** **** **** **** **** **** **** **** **** +16754 **** **** **** **** **** **** **** **** **** +16755 **** **** **** **** **** **** **** **** **** +16756 **** **** **** **** **** **** **** **** **** +16757 **** **** **** **** **** **** **** **** **** +16758 **** **** **** **** **** **** **** **** **** +16759 **** **** **** **** **** **** **** **** **** +16760 Templates_16300-16999 **** **** **** **** **** **** **** **** +16761 **** **** **** **** **** **** **** **** **** +16762 **** **** **** **** **** **** **** **** **** +16763 **** **** **** **** **** **** **** **** **** +16764 **** **** **** **** **** **** **** **** **** +16765 **** **** **** **** **** **** **** **** **** +16766 **** **** **** **** **** **** **** **** **** +16767 **** **** **** **** **** **** **** **** **** +16768 **** **** **** **** **** **** **** **** **** +16769 **** **** **** **** **** **** **** **** **** +16770 Templates_16300-16999 **** **** **** **** **** **** **** **** +16771 **** **** **** **** **** **** **** **** **** +16772 **** **** **** **** **** **** **** **** **** +16773 **** **** **** **** **** **** **** **** **** +16774 **** **** **** **** **** **** **** **** **** +16775 **** **** **** **** **** **** **** **** **** +16776 **** **** **** **** **** **** **** **** **** +16777 **** **** **** **** **** **** **** **** **** +16778 **** **** **** **** **** **** **** **** **** +16779 **** **** **** **** **** **** **** **** **** +16780 Templates_16300-16999 **** **** **** **** **** **** **** **** +16781 **** **** **** **** **** **** **** **** **** +16782 **** **** **** **** **** **** **** **** **** +16783 **** **** **** **** **** **** **** **** **** +16784 **** **** **** **** **** **** **** **** **** +16785 **** **** **** **** **** **** **** **** **** +16786 **** **** **** **** **** **** **** **** **** +16787 **** **** **** **** **** **** **** **** **** +16788 **** **** **** **** **** **** **** **** **** +16789 **** **** **** **** **** **** **** **** **** +16790 Templates_16300-16999 **** **** **** **** **** **** **** **** +16791 **** **** **** **** **** **** **** **** **** +16792 **** **** **** **** **** **** **** **** **** +16793 **** **** **** **** **** **** **** **** **** +16794 **** **** **** **** **** **** **** **** **** +16795 **** **** **** **** **** **** **** **** **** +16796 **** **** **** **** **** **** **** **** **** +16797 **** **** **** **** **** **** **** **** **** +16798 **** **** **** **** **** **** **** **** **** +16799 **** **** **** **** **** **** **** **** **** +16800 Templates_16300-16999 **** **** **** **** **** **** **** **** +16801 **** **** **** **** **** **** **** **** **** +16802 **** **** **** **** **** **** **** **** **** +16803 **** **** **** **** **** **** **** **** **** +16804 **** **** **** **** **** **** **** **** **** +16805 **** **** **** **** **** **** **** **** **** +16806 **** **** **** **** **** **** **** **** **** +16807 **** **** **** **** **** **** **** **** **** +16808 **** **** **** **** **** **** **** **** **** +16809 **** **** **** **** **** **** **** **** **** +16810 Templates_16300-16999 **** **** **** **** **** **** **** **** +16811 **** **** **** **** **** **** **** **** **** +16812 **** **** **** **** **** **** **** **** **** +16813 **** **** **** **** **** **** **** **** **** +16814 **** **** **** **** **** **** **** **** **** +16815 **** **** **** **** **** **** **** **** **** +16816 **** **** **** **** **** **** **** **** **** +16817 **** **** **** **** **** **** **** **** **** +16818 **** **** **** **** **** **** **** **** **** +16819 **** **** **** **** **** **** **** **** **** +16820 Templates_16300-16999 **** **** **** **** **** **** **** **** +16821 **** **** **** **** **** **** **** **** **** +16822 **** **** **** **** **** **** **** **** **** +16823 **** **** **** **** **** **** **** **** **** +16824 **** **** **** **** **** **** **** **** **** +16825 **** **** **** **** **** **** **** **** **** +16826 **** **** **** **** **** **** **** **** **** +16827 **** **** **** **** **** **** **** **** **** +16828 **** **** **** **** **** **** **** **** **** +16829 **** **** **** **** **** **** **** **** **** +16830 Templates_16300-16999 **** **** **** **** **** **** **** **** +16831 **** **** **** **** **** **** **** **** **** +16832 **** **** **** **** **** **** **** **** **** +16833 **** **** **** **** **** **** **** **** **** +16834 **** **** **** **** **** **** **** **** **** +16835 **** **** **** **** **** **** **** **** **** +16836 **** **** **** **** **** **** **** **** **** +16837 **** **** **** **** **** **** **** **** **** +16838 **** **** **** **** **** **** **** **** **** +16839 **** **** **** **** **** **** **** **** **** +16840 Templates_16300-16999 **** **** **** **** **** **** **** **** +16841 **** **** **** **** **** **** **** **** **** +16842 **** **** **** **** **** **** **** **** **** +16843 **** **** **** **** **** **** **** **** **** +16844 **** **** **** **** **** **** **** **** **** +16845 **** **** **** **** **** **** **** **** **** +16846 **** **** **** **** **** **** **** **** **** +16847 **** **** **** **** **** **** **** **** **** +16848 **** **** **** **** **** **** **** **** **** +16849 **** **** **** **** **** **** **** **** **** +16850 Templates_16300-16999 **** **** **** **** **** **** **** **** +16851 **** **** **** **** **** **** **** **** **** +16852 **** **** **** **** **** **** **** **** **** +16853 **** **** **** **** **** **** **** **** **** +16854 **** **** **** **** **** **** **** **** **** +16855 **** **** **** **** **** **** **** **** **** +16856 **** **** **** **** **** **** **** **** **** +16857 **** **** **** **** **** **** **** **** **** +16858 **** **** **** **** **** **** **** **** **** +16859 **** **** **** **** **** **** **** **** **** +16860 Templates_16300-16999 **** **** **** **** **** **** **** **** +16861 **** **** **** **** **** **** **** **** **** +16862 **** **** **** **** **** **** **** **** **** +16863 **** **** **** **** **** **** **** **** **** +16864 **** **** **** **** **** **** **** **** **** +16865 **** **** **** **** **** **** **** **** **** +16866 **** **** **** **** **** **** **** **** **** +16867 **** **** **** **** **** **** **** **** **** +16868 **** **** **** **** **** **** **** **** **** +16869 **** **** **** **** **** **** **** **** **** +16870 Templates_16300-16999 **** **** **** **** **** **** **** **** +16871 **** **** **** **** **** **** **** **** **** +16872 **** **** **** **** **** **** **** **** **** +16873 **** **** **** **** **** **** **** **** **** +16874 **** **** **** **** **** **** **** **** **** +16875 **** **** **** **** **** **** **** **** **** +16876 **** **** **** **** **** **** **** **** **** +16877 **** **** **** **** **** **** **** **** **** +16878 **** **** **** **** **** **** **** **** **** +16879 **** **** **** **** **** **** **** **** **** +16880 Templates_16300-16999 **** **** **** **** **** **** **** **** +16881 **** **** **** **** **** **** **** **** **** +16882 **** **** **** **** **** **** **** **** **** +16883 **** **** **** **** **** **** **** **** **** +16884 **** **** **** **** **** **** **** **** **** +16885 **** **** **** **** **** **** **** **** **** +16886 **** **** **** **** **** **** **** **** **** +16887 **** **** **** **** **** **** **** **** **** +16888 **** **** **** **** **** **** **** **** **** +16889 **** **** **** **** **** **** **** **** **** +16890 Templates_16300-16999 **** **** **** **** **** **** **** **** +16891 **** **** **** **** **** **** **** **** **** +16892 **** **** **** **** **** **** **** **** **** +16893 **** **** **** **** **** **** **** **** **** +16894 **** **** **** **** **** **** **** **** **** +16895 **** **** **** **** **** **** **** **** **** +16896 **** **** **** **** **** **** **** **** **** +16897 **** **** **** **** **** **** **** **** **** +16898 **** **** **** **** **** **** **** **** **** +16899 **** **** **** **** **** **** **** **** **** +16900 Templates_16300-16999 **** **** **** **** **** **** **** **** +16901 **** **** **** **** **** **** **** **** **** +16902 **** **** **** **** **** **** **** **** **** +16903 **** **** **** **** **** **** **** **** **** +16904 **** **** **** **** **** **** **** **** **** +16905 **** **** **** **** **** **** **** **** **** +16906 **** **** **** **** **** **** **** **** **** +16907 **** **** **** **** **** **** **** **** **** +16908 **** **** **** **** **** **** **** **** **** +16909 **** **** **** **** **** **** **** **** **** +16910 Templates_16300-16999 **** **** **** **** **** **** **** **** +16911 **** **** **** **** **** **** **** **** **** +16912 **** **** **** **** **** **** **** **** **** +16913 **** **** **** **** **** **** **** **** **** +16914 **** **** **** **** **** **** **** **** **** +16915 **** **** **** **** **** **** **** **** **** +16916 **** **** **** **** **** **** **** **** **** +16917 **** **** **** **** **** **** **** **** **** +16918 **** **** **** **** **** **** **** **** **** +16919 **** **** **** **** **** **** **** **** **** +16920 Templates_16300-16999 **** **** **** **** **** **** **** **** +16921 **** **** **** **** **** **** **** **** **** +16922 **** **** **** **** **** **** **** **** **** +16923 **** **** **** **** **** **** **** **** **** +16924 **** **** **** **** **** **** **** **** **** +16925 **** **** **** **** **** **** **** **** **** +16926 **** **** **** **** **** **** **** **** **** +16927 **** **** **** **** **** **** **** **** **** +16928 **** **** **** **** **** **** **** **** **** +16929 **** **** **** **** **** **** **** **** **** +16930 Templates_16300-16999 **** **** **** **** **** **** **** **** +16931 **** **** **** **** **** **** **** **** **** +16932 **** **** **** **** **** **** **** **** **** +16933 **** **** **** **** **** **** **** **** **** +16934 **** **** **** **** **** **** **** **** **** +16935 **** **** **** **** **** **** **** **** **** +16936 **** **** **** **** **** **** **** **** **** +16937 **** **** **** **** **** **** **** **** **** +16938 **** **** **** **** **** **** **** **** **** +16939 **** **** **** **** **** **** **** **** **** +16940 Templates_16300-16999 **** **** **** **** **** **** **** **** +16941 **** **** **** **** **** **** **** **** **** +16942 **** **** **** **** **** **** **** **** **** +16943 **** **** **** **** **** **** **** **** **** +16944 **** **** **** **** **** **** **** **** **** +16945 **** **** **** **** **** **** **** **** **** +16946 **** **** **** **** **** **** **** **** **** +16947 **** **** **** **** **** **** **** **** **** +16948 **** **** **** **** **** **** **** **** **** +16949 **** **** **** **** **** **** **** **** **** +16950 Templates_16300-16999 **** **** **** **** **** **** **** **** +16951 **** **** **** **** **** **** **** **** **** +16952 **** **** **** **** **** **** **** **** **** +16953 **** **** **** **** **** **** **** **** **** +16954 **** **** **** **** **** **** **** **** **** +16955 **** **** **** **** **** **** **** **** **** +16956 **** **** **** **** **** **** **** **** **** +16957 **** **** **** **** **** **** **** **** **** +16958 **** **** **** **** **** **** **** **** **** +16959 **** **** **** **** **** **** **** **** **** +16960 Templates_16300-16999 **** **** **** **** **** **** **** **** +16961 **** **** **** **** **** **** **** **** **** +16962 **** **** **** **** **** **** **** **** **** +16963 **** **** **** **** **** **** **** **** **** +16964 **** **** **** **** **** **** **** **** **** +16965 **** **** **** **** **** **** **** **** **** +16966 **** **** **** **** **** **** **** **** **** +16967 **** **** **** **** **** **** **** **** **** +16968 **** **** **** **** **** **** **** **** **** +16969 **** **** **** **** **** **** **** **** **** +16970 Templates_16300-16999 **** **** **** **** **** **** **** **** +16971 **** **** **** **** **** **** **** **** **** +16972 **** **** **** **** **** **** **** **** **** +16973 **** **** **** **** **** **** **** **** **** +16974 **** **** **** **** **** **** **** **** **** +16975 **** **** **** **** **** **** **** **** **** +16976 **** **** **** **** **** **** **** **** **** +16977 **** **** **** **** **** **** **** **** **** +16978 **** **** **** **** **** **** **** **** **** +16979 **** **** **** **** **** **** **** **** **** +16980 Templates_16300-16999 **** **** **** **** **** **** **** **** +16981 **** **** **** **** **** **** **** **** **** +16982 **** **** **** **** **** **** **** **** **** +16983 **** **** **** **** **** **** **** **** **** +16984 **** **** **** **** **** **** **** **** **** +16985 **** **** **** **** **** **** **** **** **** +16986 **** **** **** **** **** **** **** **** **** +16987 **** **** **** **** **** **** **** **** **** +16988 **** **** **** **** **** **** **** **** **** +16989 **** **** **** **** **** **** **** **** **** +16990 Templates_16300-16999 **** **** **** **** **** **** **** **** +16991 **** **** **** **** **** **** **** **** **** +16992 **** **** **** **** **** **** **** **** **** +16993 **** **** **** **** **** **** **** **** **** +16994 **** **** **** **** **** **** **** **** **** +16995 **** **** **** **** **** **** **** **** **** +16996 **** **** **** **** **** **** **** **** **** +16997 **** **** **** **** **** **** **** **** **** +16998 **** **** **** **** **** **** **** **** **** +16999 Templates_16300-16999 **** **** **** **** **** **** **** **** +17000 **** **** **** **** **** **** **** **** **** +17001 **** **** **** **** **** **** **** **** **** +17002 **** **** **** **** **** **** **** **** **** +17003 **** **** **** **** **** **** **** **** **** +17004 **** **** **** **** **** **** **** **** **** +17005 **** **** **** **** **** **** **** **** **** +17006 **** **** **** **** **** **** **** **** **** +17007 **** **** **** **** **** **** **** **** **** +17008 **** **** **** **** **** **** **** **** **** +17009 **** **** **** **** **** **** **** **** **** +17010 **** **** **** **** **** **** **** **** **** +17011 **** **** **** **** **** **** **** **** **** +17012 **** **** **** **** **** **** **** **** **** +17013 **** **** **** **** **** **** **** **** **** +17014 **** **** **** **** **** **** **** **** **** +17015 **** **** **** **** **** **** **** **** **** +17016 **** **** **** **** **** **** **** **** **** +17017 **** **** **** **** **** **** **** **** **** +17018 **** **** **** **** **** **** **** **** **** +17019 **** **** **** **** **** **** **** **** **** +17020 **** **** **** **** **** **** **** **** **** +17021 **** **** **** **** **** **** **** **** **** +17022 **** **** **** **** **** **** **** **** **** +17023 **** **** **** **** **** **** **** **** **** +17024 **** **** **** **** **** **** **** **** **** +17025 **** **** **** **** **** **** **** **** **** +17026 **** **** **** **** **** **** **** **** **** +17027 **** **** **** **** **** **** **** **** **** +17028 **** **** **** **** **** **** **** **** **** +17029 **** **** **** **** **** **** **** **** **** +17030 **** **** **** **** **** **** **** **** **** +17031 **** **** **** **** **** **** **** **** **** +17032 **** **** **** **** **** **** **** **** **** +17033 **** **** **** **** **** **** **** **** **** +17034 **** **** **** **** **** **** **** **** **** +17035 **** **** **** **** **** **** **** **** **** +17036 **** **** **** **** **** **** **** **** **** +17037 **** **** **** **** **** **** **** **** **** +17038 **** **** **** **** **** **** **** **** **** +17039 **** **** **** **** **** **** **** **** **** +17040 **** **** **** **** **** **** **** **** **** +17041 **** **** **** **** **** **** **** **** **** +17042 **** **** **** **** **** **** **** **** **** +17043 **** **** **** **** **** **** **** **** **** +17044 **** **** **** **** **** **** **** **** **** +17045 **** **** **** **** **** **** **** **** **** +17046 **** **** **** **** **** **** **** **** **** +17047 **** **** **** **** **** **** **** **** **** +17048 **** **** **** **** **** **** **** **** **** +17049 **** **** **** **** **** **** **** **** **** +17050 **** **** **** **** **** **** **** **** **** +17051 **** **** **** **** **** **** **** **** **** +17052 **** **** **** **** **** **** **** **** **** +17053 **** **** **** **** **** **** **** **** **** +17054 **** **** **** **** **** **** **** **** **** +17055 **** **** **** **** **** **** **** **** **** +17056 **** **** **** **** **** **** **** **** **** +17057 **** **** **** **** **** **** **** **** **** +17058 **** **** **** **** **** **** **** **** **** +17059 **** **** **** **** **** **** **** **** **** +17060 **** **** **** **** **** **** **** **** **** +17061 **** **** **** **** **** **** **** **** **** +17062 **** **** **** **** **** **** **** **** **** +17063 **** **** **** **** **** **** **** **** **** +17064 **** **** **** **** **** **** **** **** **** +17065 **** **** **** **** **** **** **** **** **** +17066 **** **** **** **** **** **** **** **** **** +17067 **** **** **** **** **** **** **** **** **** +17068 **** **** **** **** **** **** **** **** **** +17069 **** **** **** **** **** **** **** **** **** +17070 **** **** **** **** **** **** **** **** **** +17071 **** **** **** **** **** **** **** **** **** +17072 **** **** **** **** **** **** **** **** **** +17073 **** **** **** **** **** **** **** **** **** +17074 **** **** **** **** **** **** **** **** **** +17075 **** **** **** **** **** **** **** **** **** +17076 **** **** **** **** **** **** **** **** **** +17077 **** **** **** **** **** **** **** **** **** +17078 **** **** **** **** **** **** **** **** **** +17079 **** **** **** **** **** **** **** **** **** +17080 **** **** **** **** **** **** **** **** **** +17081 **** **** **** **** **** **** **** **** **** +17082 **** **** **** **** **** **** **** **** **** +17083 **** **** **** **** **** **** **** **** **** +17084 **** **** **** **** **** **** **** **** **** +17085 **** **** **** **** **** **** **** **** **** +17086 **** **** **** **** **** **** **** **** **** +17087 **** **** **** **** **** **** **** **** **** +17088 **** **** **** **** **** **** **** **** **** +17089 **** **** **** **** **** **** **** **** **** +17090 **** **** **** **** **** **** **** **** **** +17091 **** **** **** **** **** **** **** **** **** +17092 **** **** **** **** **** **** **** **** **** +17093 **** **** **** **** **** **** **** **** **** +17094 **** **** **** **** **** **** **** **** **** +17095 **** **** **** **** **** **** **** **** **** +17096 **** **** **** **** **** **** **** **** **** +17097 **** **** **** **** **** **** **** **** **** +17098 **** **** **** **** **** **** **** **** **** +17099 **** **** **** **** **** **** **** **** **** +17100 **** **** **** **** **** **** **** **** **** +17101 **** **** **** **** **** **** **** **** **** +17102 **** **** **** **** **** **** **** **** **** +17103 **** **** **** **** **** **** **** **** **** +17104 **** **** **** **** **** **** **** **** **** +17105 **** **** **** **** **** **** **** **** **** +17106 **** **** **** **** **** **** **** **** **** +17107 **** **** **** **** **** **** **** **** **** +17108 **** **** **** **** **** **** **** **** **** +17109 **** **** **** **** **** **** **** **** **** +17110 **** **** **** **** **** **** **** **** **** +17111 **** **** **** **** **** **** **** **** **** +17112 **** **** **** **** **** **** **** **** **** +17113 **** **** **** **** **** **** **** **** **** +17114 **** **** **** **** **** **** **** **** **** +17115 **** **** **** **** **** **** **** **** **** +17116 **** **** **** **** **** **** **** **** **** +17117 **** **** **** **** **** **** **** **** **** +17118 **** **** **** **** **** **** **** **** **** +17119 **** **** **** **** **** **** **** **** **** +17120 **** **** **** **** **** **** **** **** **** +17121 **** **** **** **** **** **** **** **** **** +17122 **** **** **** **** **** **** **** **** **** +17123 **** **** **** **** **** **** **** **** **** +17124 **** **** **** **** **** **** **** **** **** +17125 **** **** **** **** **** **** **** **** **** +17126 **** **** **** **** **** **** **** **** **** +17127 **** **** **** **** **** **** **** **** **** +17128 **** **** **** **** **** **** **** **** **** +17129 **** **** **** **** **** **** **** **** **** +17130 **** **** **** **** **** **** **** **** **** +17131 **** **** **** **** **** **** **** **** **** +17132 **** **** **** **** **** **** **** **** **** +17133 **** **** **** **** **** **** **** **** **** +17134 **** **** **** **** **** **** **** **** **** +17135 **** **** **** **** **** **** **** **** **** +17136 **** **** **** **** **** **** **** **** **** +17137 **** **** **** **** **** **** **** **** **** +17138 **** **** **** **** **** **** **** **** **** +17139 **** **** **** **** **** **** **** **** **** +17140 **** **** **** **** **** **** **** **** **** +17141 **** **** **** **** **** **** **** **** **** +17142 **** **** **** **** **** **** **** **** **** +17143 **** **** **** **** **** **** **** **** **** +17144 **** **** **** **** **** **** **** **** **** +17145 **** **** **** **** **** **** **** **** **** +17146 **** **** **** **** **** **** **** **** **** +17147 **** **** **** **** **** **** **** **** **** +17148 **** **** **** **** **** **** **** **** **** +17149 **** **** **** **** **** **** **** **** **** +17150 **** **** **** **** **** **** **** **** **** +17151 **** **** **** **** **** **** **** **** **** +17152 **** **** **** **** **** **** **** **** **** +17153 **** **** **** **** **** **** **** **** **** +17154 **** **** **** **** **** **** **** **** **** +17155 **** **** **** **** **** **** **** **** **** +17156 **** **** **** **** **** **** **** **** **** +17157 **** **** **** **** **** **** **** **** **** +17158 **** **** **** **** **** **** **** **** **** +17159 **** **** **** **** **** **** **** **** **** +17160 **** **** **** **** **** **** **** **** **** +17161 **** **** **** **** **** **** **** **** **** +17162 **** **** **** **** **** **** **** **** **** +17163 **** **** **** **** **** **** **** **** **** +17164 **** **** **** **** **** **** **** **** **** +17165 **** **** **** **** **** **** **** **** **** +17166 **** **** **** **** **** **** **** **** **** +17167 **** **** **** **** **** **** **** **** **** +17168 **** **** **** **** **** **** **** **** **** +17169 **** **** **** **** **** **** **** **** **** +17170 **** **** **** **** **** **** **** **** **** +17171 **** **** **** **** **** **** **** **** **** +17172 **** **** **** **** **** **** **** **** **** +17173 **** **** **** **** **** **** **** **** **** +17174 **** **** **** **** **** **** **** **** **** +17175 **** **** **** **** **** **** **** **** **** +17176 **** **** **** **** **** **** **** **** **** +17177 **** **** **** **** **** **** **** **** **** +17178 **** **** **** **** **** **** **** **** **** +17179 **** **** **** **** **** **** **** **** **** +17180 **** **** **** **** **** **** **** **** **** +17181 **** **** **** **** **** **** **** **** **** +17182 **** **** **** **** **** **** **** **** **** +17183 **** **** **** **** **** **** **** **** **** +17184 **** **** **** **** **** **** **** **** **** +17185 **** **** **** **** **** **** **** **** **** +17186 **** **** **** **** **** **** **** **** **** +17187 **** **** **** **** **** **** **** **** **** +17188 **** **** **** **** **** **** **** **** **** +17189 **** **** **** **** **** **** **** **** **** +17190 **** **** **** **** **** **** **** **** **** +17191 **** **** **** **** **** **** **** **** **** +17192 **** **** **** **** **** **** **** **** **** +17193 **** **** **** **** **** **** **** **** **** +17194 **** **** **** **** **** **** **** **** **** +17195 **** **** **** **** **** **** **** **** **** +17196 **** **** **** **** **** **** **** **** **** +17197 **** **** **** **** **** **** **** **** **** +17198 **** **** **** **** **** **** **** **** **** +17199 **** **** **** **** **** **** **** **** **** +17200 **** **** **** **** **** **** **** **** **** +17201 **** **** **** **** **** **** **** **** **** +17202 **** **** **** **** **** **** **** **** **** +17203 **** **** **** **** **** **** **** **** **** +17204 **** **** **** **** **** **** **** **** **** +17205 **** **** **** **** **** **** **** **** **** +17206 **** **** **** **** **** **** **** **** **** +17207 **** **** **** **** **** **** **** **** **** +17208 **** **** **** **** **** **** **** **** **** +17209 **** **** **** **** **** **** **** **** **** +17210 **** **** **** **** **** **** **** **** **** +17211 **** **** **** **** **** **** **** **** **** +17212 **** **** **** **** **** **** **** **** **** +17213 **** **** **** **** **** **** **** **** **** +17214 **** **** **** **** **** **** **** **** **** +17215 **** **** **** **** **** **** **** **** **** +17216 **** **** **** **** **** **** **** **** **** +17217 **** **** **** **** **** **** **** **** **** +17218 **** **** **** **** **** **** **** **** **** +17219 **** **** **** **** **** **** **** **** **** +17220 **** **** **** **** **** **** **** **** **** +17221 **** **** **** **** **** **** **** **** **** +17222 **** **** **** **** **** **** **** **** **** +17223 **** **** **** **** **** **** **** **** **** +17224 **** **** **** **** **** **** **** **** **** +17225 **** **** **** **** **** **** **** **** **** +17226 **** **** **** **** **** **** **** **** **** +17227 **** **** **** **** **** **** **** **** **** +17228 **** **** **** **** **** **** **** **** **** +17229 **** **** **** **** **** **** **** **** **** +17230 **** **** **** **** **** **** **** **** **** +17231 **** **** **** **** **** **** **** **** **** +17232 **** **** **** **** **** **** **** **** **** +17233 **** **** **** **** **** **** **** **** **** +17234 **** **** **** **** **** **** **** **** **** +17235 **** **** **** **** **** **** **** **** **** +17236 **** **** **** **** **** **** **** **** **** +17237 **** **** **** **** **** **** **** **** **** +17238 **** **** **** **** **** **** **** **** **** +17239 **** **** **** **** **** **** **** **** **** +17240 **** **** **** **** **** **** **** **** **** +17241 **** **** **** **** **** **** **** **** **** +17242 **** **** **** **** **** **** **** **** **** +17243 SPELL_REGEN_LIGHT_WOUNDS **** **** **** **** **** **** **** **** +17244 SPELL_REGEN_MODERATE_WOUNDS **** **** **** **** **** **** **** **** +17245 SPELL_REGEN_SERIOUS_WOUNDS **** **** **** **** **** **** **** **** +17246 SPELL_REGEN_CRITICAL_WOUNDS **** **** **** **** **** **** **** **** +17247 SPELL_SPEED_WIND **** **** **** **** **** **** **** **** +17248 SPELL_SPIRIT_WORM **** **** **** **** **** **** **** **** +17249 SPELL_SPIRITUAL_WEAPON **** **** **** **** **** **** **** **** +17250 SPELL_TORTISE_SHELL **** **** **** **** **** **** **** **** +17251 BattleBlessing **** **** **** **** **** **** **** **** +17252 TN_Wail_of_the_Banshee **** **** **** **** **** **** **** **** +17253 TN_Horrid_Wilting **** **** **** **** **** **** **** **** +17254 Spontaneous_Summoning **** **** **** **** **** **** **** **** +17255 Troglodyte_Stench **** **** **** **** **** **** **** **** +17256 FEAT_PRC_HIPS **** **** **** **** **** **** **** **** +17257 Hexblade_SwiftCast **** **** **** **** **** **** **** **** +17258 ET_GTEATREACH_BLAST **** **** **** **** **** **** **** **** +17259 ET_GTEATREACH_BLAST_CONVO **** **** **** **** **** **** **** **** +17260 ET_GTEATREACH_BLAST_QUICK1 **** **** **** **** **** **** **** **** +17261 ET_GTEATREACH_BLAST_QUICK2 **** **** **** **** **** **** **** **** +17262 ET_GTEATREACH_BLAST_QUICK3 **** **** **** **** **** **** **** **** +17263 ET_GTEATREACH_BLAST_QUICK4 **** **** **** **** **** **** **** **** +17264 ET_SPELLBLAST **** **** **** **** **** **** **** **** +17265 ET_SPELLBLAST_CONVO **** **** **** **** **** **** **** **** +17266 ET_SPELLBLAST_QUICK1 **** **** **** **** **** **** **** **** +17267 ET_SPELLBLAST_QUICK2 **** **** **** **** **** **** **** **** +17268 ET_SPELLBLAST_QUICK3 **** **** **** **** **** **** **** **** +17269 ET_SPELLBLAST_QUICK4 **** **** **** **** **** **** **** **** +17270 ED_CORRUPTING_BLAST **** **** **** **** **** **** **** **** +17271 ED_DAMAGE_REDUCTION **** **** **** **** **** **** **** **** +17272 ED_FEARFUL_GLARE **** **** **** **** **** **** **** **** +17273 ED_FIENDISH_RESISTANCE **** **** **** **** **** **** **** **** +17274 ED_HEALING_BLAST **** **** **** **** **** **** **** **** +17275 ED_PROTECTIVE_AURA **** **** **** **** **** **** **** **** +17276 ED_STRENGTH_OF_WILL **** **** **** **** **** **** **** **** +17277 ED_WILD_FRENZY **** **** **** **** **** **** **** **** +17278 Eldritch_Spellweave **** **** **** **** **** **** **** **** +17279 DivineMetamagic_Empower **** **** **** **** **** **** **** **** +17280 DivineMetamagic_Extend **** **** **** **** **** **** **** **** +17281 DivineMetamagic_Maximize **** **** **** **** **** **** **** **** +17282 Hellfire_Blast **** **** **** **** **** **** **** **** +17283 Hellfire_Spear **** **** **** **** **** **** **** **** +17284 Hellfire_Glaive **** **** **** **** **** **** **** **** +17285 Hellfire_Blow **** **** **** **** **** **** **** **** +17286 Hellfire_Chain **** **** **** **** **** **** **** **** +17287 Hellfire_Cone **** **** **** **** **** **** **** **** +17288 Hellfire_Line **** **** **** **** **** **** **** **** +17289 Hellfire_Doom **** **** **** **** **** **** **** **** +17290 Hellfire_Infusion **** **** **** **** **** **** **** **** +17291 Hellfire_Infusion_Extend **** **** **** **** **** **** **** **** +17292 Hellfire_Infusion_Empower **** **** **** **** **** **** **** **** +17293 Hellfire_Infusion_Widen **** **** **** **** **** **** **** **** +17294 Hellfire_Infusion_Maximize **** **** **** **** **** **** **** **** +17295 Hellfire_Shield **** **** **** **** **** **** **** **** +17296 Secular_Authority **** **** **** **** **** **** **** **** +17297 KotMC_TrueStrike **** **** **** **** **** **** **** **** +17298 Shifter_LearnShape **** **** **** **** **** **** **** **** +17299 FEAT_HEXTOR_BSTRIKE_MODE **** **** **** **** **** **** **** **** +17300 **** **** **** **** **** **** **** **** **** +17301 BlisteringFlourish **** **** **** **** **** **** **** **** +17302 BurningBlade **** **** **** **** **** **** **** **** +17303 BurningBrand **** **** **** **** **** **** **** **** +17304 DeathMark **** **** **** **** **** **** **** **** +17305 DesertTempest **** **** **** **** **** **** **** **** +17306 DistractingEmber **** **** **** **** **** **** **** **** +17307 DragonsFlame **** **** **** **** **** **** **** **** +17308 FanTheFlames **** **** **** **** **** **** **** **** +17309 FieryAssault **** **** **** **** **** **** **** **** +17310 FireRiposte **** **** **** **** **** **** **** **** +17311 Firesnake **** **** **** **** **** **** **** **** +17312 FlamesBlessing **** **** **** **** **** **** **** **** +17313 FlashingSun **** **** **** **** **** **** **** **** +17314 HatchlingsFlame **** **** **** **** **** **** **** **** +17315 HolocaustCloak **** **** **** **** **** **** **** **** +17316 InfernoBlade **** **** **** **** **** **** **** **** +17317 InfernoBlast **** **** **** **** **** **** **** **** +17318 LeapingFlame **** **** **** **** **** **** **** **** +17319 LingeringInferno **** **** **** **** **** **** **** **** +17320 RingOfFire **** **** **** **** **** **** **** **** +17321 RisingPhoenix **** **** **** **** **** **** **** **** +17322 SalamanderCharge **** **** **** **** **** **** **** **** +17323 SearingBlade **** **** **** **** **** **** **** **** +17324 SearingCharge **** **** **** **** **** **** **** **** +17325 WindStride **** **** **** **** **** **** **** **** +17326 WyrmsFlame **** **** **** **** **** **** **** **** +17327 ZephyrDance **** **** **** **** **** **** **** **** +17328 AuraOfChaos **** **** **** **** **** **** **** **** +17329 AuraOfPerfectOrder **** **** **** **** **** **** **** **** +17330 AuraOfTriumph **** **** **** **** **** **** **** **** +17331 AuraOfTyranny **** **** **** **** **** **** **** **** +17332 CastigatingStrike **** **** **** **** **** **** **** **** +17333 CrusadersStrike **** **** **** **** **** **** **** **** +17334 DauntingStrike **** **** **** **** **** **** **** **** +17335 DefensiveRebuke **** **** **** **** **** **** **** **** +17336 DivineSurge **** **** **** **** **** **** **** **** +17337 DivineSurgeGreater **** **** **** **** **** **** **** **** +17338 DoomCharge **** **** **** **** **** **** **** **** +17339 EntanglingBlade **** **** **** **** **** **** **** **** +17340 Foehammer **** **** **** **** **** **** **** **** +17341 ImmortalFortitude **** **** **** **** **** **** **** **** +17342 IronGuardsGlare **** **** **** **** **** **** **** **** +17343 LawBearer **** **** **** **** **** **** **** **** +17344 MartialSpirit **** **** **** **** **** **** **** **** +17345 RadiantCharge **** **** **** **** **** **** **** **** +17346 RallyingStrike **** **** **** **** **** **** **** **** +17347 RevitalizingStrike **** **** **** **** **** **** **** **** +17348 ShieldBlock **** **** **** **** **** **** **** **** +17349 ShieldCounter **** **** **** **** **** **** **** **** +17350 StrikeOfRighteousVitality **** **** **** **** **** **** **** **** +17351 ThicketOfBlades **** **** **** **** **** **** **** **** +17352 TideOfChaos **** **** **** **** **** **** **** **** +17353 VanguardStrike **** **** **** **** **** **** **** **** +17354 ActionBeforeThought **** **** **** **** **** **** **** **** +17355 AvalancheOfBlades **** **** **** **** **** **** **** **** +17356 BoundingAssault **** **** **** **** **** **** **** **** +17357 DiamondDefense **** **** **** **** **** **** **** **** +17358 DiamondNightmareBlade **** **** **** **** **** **** **** **** +17359 DisruptingBlow **** **** **** **** **** **** **** **** +17360 EmeraldRazor **** **** **** **** **** **** **** **** +17361 HearingTheAir **** **** **** **** **** **** **** **** +17362 InsightfulStrike **** **** **** **** **** **** **** **** +17363 InsightfulStrikeGreater **** **** **** **** **** **** **** **** +17364 MindOverBody **** **** **** **** **** **** **** **** +17365 MindStrike **** **** **** **** **** **** **** **** +17366 MomentOfAlacrity **** **** **** **** **** **** **** **** +17367 MomentOfPerfectMind **** **** **** **** **** **** **** **** +17368 PearlOfBlackDoubt **** **** **** **** **** **** **** **** +17369 QuicksilverMotion **** **** **** **** **** **** **** **** +17370 RapidCounter **** **** **** **** **** **** **** **** +17371 RubyNightmareBlade **** **** **** **** **** **** **** **** +17372 SapphireNightmareBlade **** **** **** **** **** **** **** **** +17373 StanceOfAlacrity **** **** **** **** **** **** **** **** +17374 StanceOfClarity **** **** **** **** **** **** **** **** +17375 TimeStandsStill **** **** **** **** **** **** **** **** +17376 AbsoluteSteel **** **** **** **** **** **** **** **** +17377 AdamantineHurricane **** **** **** **** **** **** **** **** +17378 DancingBladeForm **** **** **** **** **** **** **** **** +17379 DazingStrike **** **** **** **** **** **** **** **** +17380 DisarmingStrike **** **** **** **** **** **** **** **** +17381 ExorcismOfSteel **** **** **** **** **** **** **** **** +17382 FinishingMove **** **** **** **** **** **** **** **** +17383 IronHeartEndurance **** **** **** **** **** **** **** **** +17384 IronHeartFocus **** **** **** **** **** **** **** **** +17385 IronHeartSurge **** **** **** **** **** **** **** **** +17386 LightningRecovery **** **** **** **** **** **** **** **** +17387 LightningThrow **** **** **** **** **** **** **** **** +17388 ManticoreParry **** **** **** **** **** **** **** **** +17389 MithralTornado **** **** **** **** **** **** **** **** +17390 PunishingStance **** **** **** **** **** **** **** **** +17391 ScythingBlade **** **** **** **** **** **** **** **** +17392 SteelWind **** **** **** **** **** **** **** **** +17393 SteelyStrike **** **** **** **** **** **** **** **** +17394 StrikeOfPerfectClarity **** **** **** **** **** **** **** **** +17395 SupremeBladeParry **** **** **** **** **** **** **** **** +17396 WallOfBlades **** **** **** **** **** **** **** **** +17397 BafflingDefense **** **** **** **** **** **** **** **** +17398 BallistaThrow **** **** **** **** **** **** **** **** +17399 CleverPositioning **** **** **** **** **** **** **** **** +17400 CometThrow **** **** **** **** **** **** **** **** +17401 CounterCharge **** **** **** **** **** **** **** **** +17402 DevastatingThrow **** **** **** **** **** **** **** **** +17403 FeignedOpening **** **** **** **** **** **** **** **** +17404 FoolsStrike **** **** **** **** **** **** **** **** +17405 GhostlyDefense **** **** **** **** **** **** **** **** +17406 GiantKillingStyle **** **** **** **** **** **** **** **** +17407 HydraSlayingStrike **** **** **** **** **** **** **** **** +17408 MightyThrow **** **** **** **** **** **** **** **** +17409 MirroredPursuit **** **** **** **** **** **** **** **** +17410 ScorpionParry **** **** **** **** **** **** **** **** +17411 ShiftingDefense **** **** **** **** **** **** **** **** +17412 SoaringThrow **** **** **** **** **** **** **** **** +17413 StalkingShadow **** **** **** **** **** **** **** **** +17414 StepOfTheWind **** **** **** **** **** **** **** **** +17415 StrikeOfTheBrokenShield **** **** **** **** **** **** **** **** +17416 TornadoThrow **** **** **** **** **** **** **** **** +17417 AssassinsStance **** **** **** **** **** **** **** **** +17418 BalanceOnTheSky **** **** **** **** **** **** **** **** +17419 BloodlettingStrike **** **** **** **** **** **** **** **** +17420 ChildOfShadow **** **** **** **** **** **** **** **** +17421 ClingingShadowStrike **** **** **** **** **** **** **** **** +17422 CloakOfDeception **** **** **** **** **** **** **** **** +17423 DanceOfTheSpider **** **** **** **** **** **** **** **** +17424 DeathInTheDark **** **** **** **** **** **** **** **** +17425 DrainVitality **** **** **** **** **** **** **** **** +17426 EnervatingShadowStrike **** **** **** **** **** **** **** **** +17427 FiveShadowCreepingIceEnervationStrike **** **** **** **** **** **** **** **** +17428 GhostBlade **** **** **** **** **** **** **** **** +17429 HandOfDeath **** **** **** **** **** **** **** **** +17430 IslandOfBlades **** **** **** **** **** **** **** **** +17431 ObscuringShadowVeil **** **** **** **** **** **** **** **** +17432 OneWithShadow **** **** **** **** **** **** **** **** +17433 ShadowBladeTechnique **** **** **** **** **** **** **** **** +17434 ShadowBlink **** **** **** **** **** **** **** **** +17435 ShadowGarrote **** **** **** **** **** **** **** **** +17436 ShadowJaunt **** **** **** **** **** **** **** **** +17437 ShadowNoose **** **** **** **** **** **** **** **** +17438 ShadowStride **** **** **** **** **** **** **** **** +17439 StalkerInTheNight **** **** **** **** **** **** **** **** +17440 StepOfTheDancingMoth **** **** **** **** **** **** **** **** +17441 StrengthDrainingStrike **** **** **** **** **** **** **** **** +17442 AdamantineBones **** **** **** **** **** **** **** **** +17443 AncientMountainHammer **** **** **** **** **** **** **** **** +17444 BonesplittingStrike **** **** **** **** **** **** **** **** +17445 Bonecrusher **** **** **** **** **** **** **** **** +17446 BoulderRoll **** **** **** **** **** **** **** **** +17447 ChargingMinotaur **** **** **** **** **** **** **** **** +17448 ColossusStrike **** **** **** **** **** **** **** **** +17449 CrushingVise **** **** **** **** **** **** **** **** +17450 CrushingWeightOfTheMountain **** **** **** **** **** **** **** **** +17451 EarthstrikeQuake **** **** **** **** **** **** **** **** +17452 ElderMountainHammer **** **** **** **** **** **** **** **** +17453 GiantsStance **** **** **** **** **** **** **** **** +17454 IronBones **** **** **** **** **** **** **** **** +17455 IrresistibleMountainStrike **** **** **** **** **** **** **** **** +17456 MountainAvalanche **** **** **** **** **** **** **** **** +17457 MountainHammer **** **** **** **** **** **** **** **** +17458 MountainTombstoneStrike **** **** **** **** **** **** **** **** +17459 OverwhelmingMountainStrike **** **** **** **** **** **** **** **** +17460 RootsOfTheMountain **** **** **** **** **** **** **** **** +17461 StoneBones **** **** **** **** **** **** **** **** +17462 StoneDragonsFury **** **** **** **** **** **** **** **** +17463 StoneVise **** **** **** **** **** **** **** **** +17464 StonefootStance **** **** **** **** **** **** **** **** +17465 RisingPhoenix_FullAttack **** **** **** **** **** **** **** **** +17466 **** **** **** **** **** **** **** **** **** +17467 **** **** **** **** **** **** **** **** **** +17468 StrengthOfStone **** **** **** **** **** **** **** **** +17469 BloodInTheWater **** **** **** **** **** **** **** **** +17470 ClawAtTheMoon **** **** **** **** **** **** **** **** +17471 DancingMongoose **** **** **** **** **** **** **** **** +17472 DeathFromAbove **** **** **** **** **** **** **** **** +17473 FeralDeathBlow **** **** **** **** **** **** **** **** +17474 FleshRipper **** **** **** **** **** **** **** **** +17475 FountainOfBlood **** **** **** **** **** **** **** **** +17476 GirallonWindmillFleshRip **** **** **** **** **** **** **** **** +17477 HamstringAttack **** **** **** **** **** **** **** **** +17478 HuntersSense **** **** **** **** **** **** **** **** +17479 LeapingDragonStance **** **** **** **** **** **** **** **** +17480 PouncingCharge **** **** **** **** **** **** **** **** +17481 PreyOnTheWeak **** **** **** **** **** **** **** **** +17482 RabidBearStrike **** **** **** **** **** **** **** **** +17483 RabidWolfStrike **** **** **** **** **** **** **** **** +17484 RagingMongoose **** **** **** **** **** **** **** **** +17485 SoaringRaptorStrike **** **** **** **** **** **** **** **** +17486 SuddenLeap **** **** **** **** **** **** **** **** +17487 SwoopingDragonStrike **** **** **** **** **** **** **** **** +17488 WolfClimbsTheMountain **** **** **** **** **** **** **** **** +17489 WolfFangStrike **** **** **** **** **** **** **** **** +17490 WolfPackTactics **** **** **** **** **** **** **** **** +17491 WolverineStance **** **** **** **** **** **** **** **** +17492 BattleLeadersCharge **** **** **** **** **** **** **** **** +17493 BolsteringVoice **** **** **** **** **** **** **** **** +17494 ClarionCall **** **** **** **** **** **** **** **** +17495 CoveringStrike **** **** **** **** **** **** **** **** +17496 DouseTheFlames **** **** **** **** **** **** **** **** +17497 FlankingManeuver **** **** **** **** **** **** **** **** +17498 LeadingTheAttack **** **** **** **** **** **** **** **** +17499 LeadingTheCharge **** **** **** **** **** **** **** **** +17500 LionsRoar **** **** **** **** **** **** **** **** +17501 OrderForgedFromChaos **** **** **** **** **** **** **** **** +17502 PressTheAdvantage **** **** **** **** **** **** **** **** +17503 SwarmTactics **** **** **** **** **** **** **** **** +17504 SwarmingAssault **** **** **** **** **** **** **** **** +17505 TacticalStrike **** **** **** **** **** **** **** **** +17506 TacticsOfTheWolf **** **** **** **** **** **** **** **** +17507 WarLeadersCharge **** **** **** **** **** **** **** **** +17508 WarMastersCharge **** **** **** **** **** **** **** **** +17509 WhiteRavenHammer **** **** **** **** **** **** **** **** +17510 WhiteRavenStrike **** **** **** **** **** **** **** **** +17511 WhiteRavenTactics **** **** **** **** **** **** **** **** +17512 **** **** **** **** **** **** **** **** **** +17513 **** **** **** **** **** **** **** **** **** +17514 **** **** **** **** **** **** **** **** **** +17515 **** **** **** **** **** **** **** **** **** +17516 **** **** **** **** **** **** **** **** **** +17517 **** **** **** **** **** **** **** **** **** +17518 **** **** **** **** **** **** **** **** **** +17519 **** **** **** **** **** **** **** **** **** +17520 ####START_OF_TOB_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +17521 Warblade_StanceOfClarity **** **** **** **** **** **** **** **** +17522 Warblade_TimeStandsStill **** **** **** **** **** **** **** **** +17523 Warblade_AbsoluteSteel **** **** **** **** **** **** **** **** +17524 Warblade_AdamantineHurricane **** **** **** **** **** **** **** **** +17525 Warblade_DancingBladeForm **** **** **** **** **** **** **** **** +17526 Warblade_DazingStrike **** **** **** **** **** **** **** **** +17527 Warblade_DisarmingStrike **** **** **** **** **** **** **** **** +17528 Warblade_ExorcismOfSteel **** **** **** **** **** **** **** **** +17529 Warblade_FinishingMove **** **** **** **** **** **** **** **** +17530 Warblade_IronHeartEndurance **** **** **** **** **** **** **** **** +17531 Warblade_IronHeartFocus **** **** **** **** **** **** **** **** +17532 Warblade_IronHeartSurge **** **** **** **** **** **** **** **** +17533 Warblade_LightningRecovery **** **** **** **** **** **** **** **** +17534 Warblade_LightningThrow **** **** **** **** **** **** **** **** +17535 Warblade_ManticoreParry **** **** **** **** **** **** **** **** +17536 Warblade_MithralTornado **** **** **** **** **** **** **** **** +17537 Warblade_PunishingStance **** **** **** **** **** **** **** **** +17538 Warblade_ScythingBlade **** **** **** **** **** **** **** **** +17539 Warblade_SteelWind **** **** **** **** **** **** **** **** +17540 Warblade_SteelyStrike **** **** **** **** **** **** **** **** +17541 Warblade_StrikeOfPerfectClarity **** **** **** **** **** **** **** **** +17542 Warblade_SupremeBladeParry **** **** **** **** **** **** **** **** +17543 Warblade_WallOfBlades **** **** **** **** **** **** **** **** +17544 Warblade_BafflingDefense **** **** **** **** **** **** **** **** +17545 Warblade_BallistaThrow **** **** **** **** **** **** **** **** +17546 Warblade_CleverPositioning **** **** **** **** **** **** **** **** +17547 Warblade_CometThrow **** **** **** **** **** **** **** **** +17548 Warblade_CounterCharge **** **** **** **** **** **** **** **** +17549 Warblade_DevastatingThrow **** **** **** **** **** **** **** **** +17550 Warblade_FeignedOpening **** **** **** **** **** **** **** **** +17551 Warblade_FoolsStrike **** **** **** **** **** **** **** **** +17552 Warblade_GhostlyDefense **** **** **** **** **** **** **** **** +17553 Warblade_GiantKillingStyle **** **** **** **** **** **** **** **** +17554 Warblade_HydraSlayingStrike **** **** **** **** **** **** **** **** +17555 Warblade_MightyThrow **** **** **** **** **** **** **** **** +17556 Warblade_MirroredPursuit **** **** **** **** **** **** **** **** +17557 Warblade_ScorpionParry **** **** **** **** **** **** **** **** +17558 Warblade_ShiftingDefense **** **** **** **** **** **** **** **** +17559 Warblade_SoaringThrow **** **** **** **** **** **** **** **** +17560 Warblade_StalkingShadow **** **** **** **** **** **** **** **** +17561 Warblade_StepOfTheWind **** **** **** **** **** **** **** **** +17562 Warblade_StrikeOfTheBrokenShield **** **** **** **** **** **** **** **** +17563 Warblade_TornadoThrow **** **** **** **** **** **** **** **** +17564 Warblade_AssassinsStance **** **** **** **** **** **** **** **** +17565 Warblade_BalanceOnTheSky **** **** **** **** **** **** **** **** +17566 Warblade_BloodlettingStrike **** **** **** **** **** **** **** **** +17567 Warblade_ChildOfShadow **** **** **** **** **** **** **** **** +17568 Warblade_ClingingShadowStrike **** **** **** **** **** **** **** **** +17569 Warblade_CloakOfDeception **** **** **** **** **** **** **** **** +17570 Warblade_DanceOfTheSpider **** **** **** **** **** **** **** **** +17571 Warblade_DeathInTheDark **** **** **** **** **** **** **** **** +17572 Warblade_DrainVitality **** **** **** **** **** **** **** **** +17573 Warblade_EnervatingShadowStrike **** **** **** **** **** **** **** **** +17574 Warblade_FiveShadowCreepingIceEnervationStrike **** **** **** **** **** **** **** **** +17575 Warblade_GhostBlade **** **** **** **** **** **** **** **** +17576 Warblade_HandOfDeath **** **** **** **** **** **** **** **** +17577 Warblade_IslandOfBlades **** **** **** **** **** **** **** **** +17578 Warblade_ObscuringShadowVeil **** **** **** **** **** **** **** **** +17579 Warblade_OneWithShadow **** **** **** **** **** **** **** **** +17580 Warblade_ShadowBladeTechnique **** **** **** **** **** **** **** **** +17581 Warblade_ShadowBlink **** **** **** **** **** **** **** **** +17582 Warblade_ShadowGarrote **** **** **** **** **** **** **** **** +17583 Warblade_ShadowJaunt **** **** **** **** **** **** **** **** +17584 Warblade_ShadowNoose **** **** **** **** **** **** **** **** +17585 Warblade_ShadowStride **** **** **** **** **** **** **** **** +17586 Warblade_StalkerInTheNight **** **** **** **** **** **** **** **** +17587 Warblade_StepOfTheDancingMoth **** **** **** **** **** **** **** **** +17588 Warblade_StrengthDrainingStrike **** **** **** **** **** **** **** **** +17589 Warblade_AdamantineBones **** **** **** **** **** **** **** **** +17590 Warblade_AncientMountainHammer **** **** **** **** **** **** **** **** +17591 Warblade_BonesplittingStrike **** **** **** **** **** **** **** **** +17592 Warblade_Bonecrusher **** **** **** **** **** **** **** **** +17593 Warblade_BoulderRoll **** **** **** **** **** **** **** **** +17594 Warblade_ChargingMinotaur **** **** **** **** **** **** **** **** +17595 Warblade_ColossusStrike **** **** **** **** **** **** **** **** +17596 Warblade_CrushingVise **** **** **** **** **** **** **** **** +17597 Warblade_CrushingWeightOfTheMountain **** **** **** **** **** **** **** **** +17598 Warblade_EarthstrikeQuake **** **** **** **** **** **** **** **** +17599 Warblade_ElderMountainHammer **** **** **** **** **** **** **** **** +17600 Warblade_GiantsStance **** **** **** **** **** **** **** **** +17601 Warblade_IronBones **** **** **** **** **** **** **** **** +17602 Warblade_IrresistibleMountainStrike **** **** **** **** **** **** **** **** +17603 Warblade_MountainAvalanche **** **** **** **** **** **** **** **** +17604 Warblade_MountainHammer **** **** **** **** **** **** **** **** +17605 Warblade_MountainTombstoneStrike **** **** **** **** **** **** **** **** +17606 Warblade_OverwhelmingMountainStrike **** **** **** **** **** **** **** **** +17607 Warblade_RootsOfTheMountain **** **** **** **** **** **** **** **** +17608 Warblade_StoneBones **** **** **** **** **** **** **** **** +17609 Warblade_StoneDragonsFury **** **** **** **** **** **** **** **** +17610 Warblade_StoneVise **** **** **** **** **** **** **** **** +17611 Warblade_StonefootStance **** **** **** **** **** **** **** **** +17612 Warblade_StrengthOfStone **** **** **** **** **** **** **** **** +17613 Warblade_BloodInTheWater **** **** **** **** **** **** **** **** +17614 Warblade_ClawAtTheMoon **** **** **** **** **** **** **** **** +17615 Warblade_DancingMongoose **** **** **** **** **** **** **** **** +17616 Warblade_DeathFromAbove **** **** **** **** **** **** **** **** +17617 Warblade_FeralDeathBlow **** **** **** **** **** **** **** **** +17618 Warblade_FleshRipper **** **** **** **** **** **** **** **** +17619 Warblade_FountainOfBlood **** **** **** **** **** **** **** **** +17620 Warblade_GirallonWindmillFleshRip **** **** **** **** **** **** **** **** +17621 Warblade_HamstringAttack **** **** **** **** **** **** **** **** +17622 Warblade_HuntersSense **** **** **** **** **** **** **** **** +17623 Warblade_LeapingDragonStance **** **** **** **** **** **** **** **** +17624 Warblade_PouncingCharge **** **** **** **** **** **** **** **** +17625 Warblade_PreyOnTheWeak **** **** **** **** **** **** **** **** +17626 Warblade_RabidBearStrike **** **** **** **** **** **** **** **** +17627 Warblade_RabidWolfStrike **** **** **** **** **** **** **** **** +17628 Warblade_RagingMongoose **** **** **** **** **** **** **** **** +17629 Warblade_SoaringRaptorStrike **** **** **** **** **** **** **** **** +17630 Warblade_SuddenLeap **** **** **** **** **** **** **** **** +17631 Warblade_SwoopingDragonStrike **** **** **** **** **** **** **** **** +17632 Warblade_WolfClimbsTheMountain **** **** **** **** **** **** **** **** +17633 Warblade_WolfFangStrike **** **** **** **** **** **** **** **** +17634 Warblade_WolfPackTactics **** **** **** **** **** **** **** **** +17635 Warblade_WolverineStance **** **** **** **** **** **** **** **** +17636 Warblade_BattleLeadersCharge **** **** **** **** **** **** **** **** +17637 Warblade_BolsteringVoice **** **** **** **** **** **** **** **** +17638 Warblade_ClarionCall **** **** **** **** **** **** **** **** +17639 Warblade_CoveringStrike **** **** **** **** **** **** **** **** +17640 Warblade_DouseTheFlames **** **** **** **** **** **** **** **** +17641 Warblade_FlankingManeuver **** **** **** **** **** **** **** **** +17642 Warblade_LeadingTheAttack **** **** **** **** **** **** **** **** +17643 Warblade_LeadingTheCharge **** **** **** **** **** **** **** **** +17644 Warblade_LionsRoar **** **** **** **** **** **** **** **** +17645 Warblade_OrderForgedFromChaos **** **** **** **** **** **** **** **** +17646 Warblade_PressTheAdvantage **** **** **** **** **** **** **** **** +17647 Warblade_SwarmTactics **** **** **** **** **** **** **** **** +17648 Warblade_SwarmingAssault **** **** **** **** **** **** **** **** +17649 Warblade_TacticalStrike **** **** **** **** **** **** **** **** +17650 Warblade_TacticsOfTheWolf **** **** **** **** **** **** **** **** +17651 Warblade_WarLeadersCharge **** **** **** **** **** **** **** **** +17652 Warblade_WarMastersCharge **** **** **** **** **** **** **** **** +17653 Warblade_WhiteRavenHammer **** **** **** **** **** **** **** **** +17654 Warblade_WhiteRavenStrike **** **** **** **** **** **** **** **** +17655 Warblade_WhiteRavenTactics **** **** **** **** **** **** **** **** +17656 **** **** **** **** **** **** **** **** **** +17657 **** **** **** **** **** **** **** **** **** +17658 **** **** **** **** **** **** **** **** **** +17659 **** **** **** **** **** **** **** **** **** +17660 **** **** **** **** **** **** **** **** **** +17661 **** **** **** **** **** **** **** **** **** +17662 **** **** **** **** **** **** **** **** **** +17663 **** **** **** **** **** **** **** **** **** +17664 **** **** **** **** **** **** **** **** **** +17665 **** **** **** **** **** **** **** **** **** +17666 **** **** **** **** **** **** **** **** **** +17667 **** **** **** **** **** **** **** **** **** +17668 **** **** **** **** **** **** **** **** **** +17669 **** **** **** **** **** **** **** **** **** +17670 **** **** **** **** **** **** **** **** **** +17671 **** **** **** **** **** **** **** **** **** +17672 **** **** **** **** **** **** **** **** **** +17673 **** **** **** **** **** **** **** **** **** +17674 **** **** **** **** **** **** **** **** **** +17675 **** **** **** **** **** **** **** **** **** +17676 **** **** **** **** **** **** **** **** **** +17677 **** **** **** **** **** **** **** **** **** +17678 **** **** **** **** **** **** **** **** **** +17679 **** **** **** **** **** **** **** **** **** +17680 **** **** **** **** **** **** **** **** **** +17681 **** **** **** **** **** **** **** **** **** +17682 **** **** **** **** **** **** **** **** **** +17683 **** **** **** **** **** **** **** **** **** +17684 **** **** **** **** **** **** **** **** **** +17685 **** **** **** **** **** **** **** **** **** +17686 **** **** **** **** **** **** **** **** **** +17687 **** **** **** **** **** **** **** **** **** +17688 **** **** **** **** **** **** **** **** **** +17689 **** **** **** **** **** **** **** **** **** +17690 **** **** **** **** **** **** **** **** **** +17691 **** **** **** **** **** **** **** **** **** +17692 **** **** **** **** **** **** **** **** **** +17693 **** **** **** **** **** **** **** **** **** +17694 **** **** **** **** **** **** **** **** **** +17695 **** **** **** **** **** **** **** **** **** +17696 **** **** **** **** **** **** **** **** **** +17697 **** **** **** **** **** **** **** **** **** +17698 **** **** **** **** **** **** **** **** **** +17699 **** **** **** **** **** **** **** **** **** +17700 **** **** **** **** **** **** **** **** **** +17701 **** **** **** **** **** **** **** **** **** +17702 **** **** **** **** **** **** **** **** **** +17703 **** **** **** **** **** **** **** **** **** +17704 **** **** **** **** **** **** **** **** **** +17705 **** **** **** **** **** **** **** **** **** +17706 **** **** **** **** **** **** **** **** **** +17707 **** **** **** **** **** **** **** **** **** +17708 **** **** **** **** **** **** **** **** **** +17709 **** **** **** **** **** **** **** **** **** +17710 **** **** **** **** **** **** **** **** **** +17711 **** **** **** **** **** **** **** **** **** +17712 **** **** **** **** **** **** **** **** **** +17713 **** **** **** **** **** **** **** **** **** +17714 **** **** **** **** **** **** **** **** **** +17715 **** **** **** **** **** **** **** **** **** +17716 **** **** **** **** **** **** **** **** **** +17717 **** **** **** **** **** **** **** **** **** +17718 **** **** **** **** **** **** **** **** **** +17719 **** **** **** **** **** **** **** **** **** +17720 **** **** **** **** **** **** **** **** **** +17721 **** **** **** **** **** **** **** **** **** +17722 **** **** **** **** **** **** **** **** **** +17723 **** **** **** **** **** **** **** **** **** +17724 **** **** **** **** **** **** **** **** **** +17725 **** **** **** **** **** **** **** **** **** +17726 **** **** **** **** **** **** **** **** **** +17727 **** **** **** **** **** **** **** **** **** +17728 **** **** **** **** **** **** **** **** **** +17729 **** **** **** **** **** **** **** **** **** +17730 **** **** **** **** **** **** **** **** **** +17731 **** **** **** **** **** **** **** **** **** +17732 **** **** **** **** **** **** **** **** **** +17733 **** **** **** **** **** **** **** **** **** +17734 **** **** **** **** **** **** **** **** **** +17735 **** **** **** **** **** **** **** **** **** +17736 **** **** **** **** **** **** **** **** **** +17737 **** **** **** **** **** **** **** **** **** +17738 **** **** **** **** **** **** **** **** **** +17739 **** **** **** **** **** **** **** **** **** +17740 **** **** **** **** **** **** **** **** **** +17741 **** **** **** **** **** **** **** **** **** +17742 **** **** **** **** **** **** **** **** **** +17743 **** **** **** **** **** **** **** **** **** +17744 **** **** **** **** **** **** **** **** **** +17745 **** **** **** **** **** **** **** **** **** +17746 **** **** **** **** **** **** **** **** **** +17747 **** **** **** **** **** **** **** **** **** +17748 **** **** **** **** **** **** **** **** **** +17749 **** **** **** **** **** **** **** **** **** +17750 **** **** **** **** **** **** **** **** **** +17751 **** **** **** **** **** **** **** **** **** +17752 **** **** **** **** **** **** **** **** **** +17753 **** **** **** **** **** **** **** **** **** +17754 **** **** **** **** **** **** **** **** **** +17755 **** **** **** **** **** **** **** **** **** +17756 **** **** **** **** **** **** **** **** **** +17757 **** **** **** **** **** **** **** **** **** +17758 **** **** **** **** **** **** **** **** **** +17759 **** **** **** **** **** **** **** **** **** +17760 **** **** **** **** **** **** **** **** **** +17761 **** **** **** **** **** **** **** **** **** +17762 **** **** **** **** **** **** **** **** **** +17763 **** **** **** **** **** **** **** **** **** +17764 **** **** **** **** **** **** **** **** **** +17765 **** **** **** **** **** **** **** **** **** +17766 **** **** **** **** **** **** **** **** **** +17767 **** **** **** **** **** **** **** **** **** +17768 **** **** **** **** **** **** **** **** **** +17769 **** **** **** **** **** **** **** **** **** +17770 **** **** **** **** **** **** **** **** **** +17771 **** **** **** **** **** **** **** **** **** +17772 **** **** **** **** **** **** **** **** **** +17773 **** **** **** **** **** **** **** **** **** +17774 **** **** **** **** **** **** **** **** **** +17775 **** **** **** **** **** **** **** **** **** +17776 **** **** **** **** **** **** **** **** **** +17777 **** **** **** **** **** **** **** **** **** +17778 **** **** **** **** **** **** **** **** **** +17779 **** **** **** **** **** **** **** **** **** +17780 **** **** **** **** **** **** **** **** **** +17781 **** **** **** **** **** **** **** **** **** +17782 **** **** **** **** **** **** **** **** **** +17783 **** **** **** **** **** **** **** **** **** +17784 **** **** **** **** **** **** **** **** **** +17785 **** **** **** **** **** **** **** **** **** +17786 **** **** **** **** **** **** **** **** **** +17787 **** **** **** **** **** **** **** **** **** +17788 **** **** **** **** **** **** **** **** **** +17789 **** **** **** **** **** **** **** **** **** +17790 **** **** **** **** **** **** **** **** **** +17791 **** **** **** **** **** **** **** **** **** +17792 **** **** **** **** **** **** **** **** **** +17793 **** **** **** **** **** **** **** **** **** +17794 **** **** **** **** **** **** **** **** **** +17795 **** **** **** **** **** **** **** **** **** +17796 **** **** **** **** **** **** **** **** **** +17797 **** **** **** **** **** **** **** **** **** +17798 **** **** **** **** **** **** **** **** **** +17799 **** **** **** **** **** **** **** **** **** +17800 **** **** **** **** **** **** **** **** **** +17801 **** **** **** **** **** **** **** **** **** +17802 **** **** **** **** **** **** **** **** **** +17803 **** **** **** **** **** **** **** **** **** +17804 **** **** **** **** **** **** **** **** **** +17805 **** **** **** **** **** **** **** **** **** +17806 **** **** **** **** **** **** **** **** **** +17807 **** **** **** **** **** **** **** **** **** +17808 **** **** **** **** **** **** **** **** **** +17809 **** **** **** **** **** **** **** **** **** +17810 **** **** **** **** **** **** **** **** **** +17811 **** **** **** **** **** **** **** **** **** +17812 **** **** **** **** **** **** **** **** **** +17813 **** **** **** **** **** **** **** **** **** +17814 **** **** **** **** **** **** **** **** **** +17815 **** **** **** **** **** **** **** **** **** +17816 **** **** **** **** **** **** **** **** **** +17817 **** **** **** **** **** **** **** **** **** +17818 **** **** **** **** **** **** **** **** **** +17819 **** **** **** **** **** **** **** **** **** +17820 **** **** **** **** **** **** **** **** **** +17821 **** **** **** **** **** **** **** **** **** +17822 **** **** **** **** **** **** **** **** **** +17823 **** **** **** **** **** **** **** **** **** +17824 **** **** **** **** **** **** **** **** **** +17825 **** **** **** **** **** **** **** **** **** +17826 **** **** **** **** **** **** **** **** **** +17827 **** **** **** **** **** **** **** **** **** +17828 **** **** **** **** **** **** **** **** **** +17829 **** **** **** **** **** **** **** **** **** +17830 **** **** **** **** **** **** **** **** **** +17831 **** **** **** **** **** **** **** **** **** +17832 **** **** **** **** **** **** **** **** **** +17833 **** **** **** **** **** **** **** **** **** +17834 **** **** **** **** **** **** **** **** **** +17835 **** **** **** **** **** **** **** **** **** +17836 **** **** **** **** **** **** **** **** **** +17837 **** **** **** **** **** **** **** **** **** +17838 **** **** **** **** **** **** **** **** **** +17839 **** **** **** **** **** **** **** **** **** +17840 **** **** **** **** **** **** **** **** **** +17841 **** **** **** **** **** **** **** **** **** +17842 **** **** **** **** **** **** **** **** **** +17843 **** **** **** **** **** **** **** **** **** +17844 **** **** **** **** **** **** **** **** **** +17845 **** **** **** **** **** **** **** **** **** +17846 **** **** **** **** **** **** **** **** **** +17847 **** **** **** **** **** **** **** **** **** +17848 **** **** **** **** **** **** **** **** **** +17849 **** **** **** **** **** **** **** **** **** +17850 **** **** **** **** **** **** **** **** **** +17851 **** **** **** **** **** **** **** **** **** +17852 **** **** **** **** **** **** **** **** **** +17853 **** **** **** **** **** **** **** **** **** +17854 **** **** **** **** **** **** **** **** **** +17855 **** **** **** **** **** **** **** **** **** +17856 **** **** **** **** **** **** **** **** **** +17857 **** **** **** **** **** **** **** **** **** +17858 **** **** **** **** **** **** **** **** **** +17859 **** **** **** **** **** **** **** **** **** +17860 **** **** **** **** **** **** **** **** **** +17861 **** **** **** **** **** **** **** **** **** +17862 **** **** **** **** **** **** **** **** **** +17863 **** **** **** **** **** **** **** **** **** +17864 **** **** **** **** **** **** **** **** **** +17865 **** **** **** **** **** **** **** **** **** +17866 **** **** **** **** **** **** **** **** **** +17867 **** **** **** **** **** **** **** **** **** +17868 **** **** **** **** **** **** **** **** **** +17869 **** **** **** **** **** **** **** **** **** +17870 **** **** **** **** **** **** **** **** **** +17871 **** **** **** **** **** **** **** **** **** +17872 **** **** **** **** **** **** **** **** **** +17873 **** **** **** **** **** **** **** **** **** +17874 **** **** **** **** **** **** **** **** **** +17875 **** **** **** **** **** **** **** **** **** +17876 **** **** **** **** **** **** **** **** **** +17877 **** **** **** **** **** **** **** **** **** +17878 **** **** **** **** **** **** **** **** **** +17879 **** **** **** **** **** **** **** **** **** +17880 **** **** **** **** **** **** **** **** **** +17881 **** **** **** **** **** **** **** **** **** +17882 **** **** **** **** **** **** **** **** **** +17883 **** **** **** **** **** **** **** **** **** +17884 **** **** **** **** **** **** **** **** **** +17885 **** **** **** **** **** **** **** **** **** +17886 **** **** **** **** **** **** **** **** **** +17887 **** **** **** **** **** **** **** **** **** +17888 **** **** **** **** **** **** **** **** **** +17889 **** **** **** **** **** **** **** **** **** +17890 **** **** **** **** **** **** **** **** **** +17891 **** **** **** **** **** **** **** **** **** +17892 **** **** **** **** **** **** **** **** **** +17893 **** **** **** **** **** **** **** **** **** +17894 **** **** **** **** **** **** **** **** **** +17895 **** **** **** **** **** **** **** **** **** +17896 **** **** **** **** **** **** **** **** **** +17897 **** **** **** **** **** **** **** **** **** +17898 **** **** **** **** **** **** **** **** **** +17899 **** **** **** **** **** **** **** **** **** +17900 **** **** **** **** **** **** **** **** **** +17901 **** **** **** **** **** **** **** **** **** +17902 **** **** **** **** **** **** **** **** **** +17903 **** **** **** **** **** **** **** **** **** +17904 **** **** **** **** **** **** **** **** **** +17905 **** **** **** **** **** **** **** **** **** +17906 **** **** **** **** **** **** **** **** **** +17907 **** **** **** **** **** **** **** **** **** +17908 **** **** **** **** **** **** **** **** **** +17909 **** **** **** **** **** **** **** **** **** +17910 **** **** **** **** **** **** **** **** **** +17911 **** **** **** **** **** **** **** **** **** +17912 **** **** **** **** **** **** **** **** **** +17913 **** **** **** **** **** **** **** **** **** +17914 **** **** **** **** **** **** **** **** **** +17915 **** **** **** **** **** **** **** **** **** +17916 **** **** **** **** **** **** **** **** **** +17917 **** **** **** **** **** **** **** **** **** +17918 **** **** **** **** **** **** **** **** **** +17919 **** **** **** **** **** **** **** **** **** +17920 **** **** **** **** **** **** **** **** **** +17921 **** **** **** **** **** **** **** **** **** +17922 **** **** **** **** **** **** **** **** **** +17923 **** **** **** **** **** **** **** **** **** +17924 **** **** **** **** **** **** **** **** **** +17925 **** **** **** **** **** **** **** **** **** +17926 **** **** **** **** **** **** **** **** **** +17927 **** **** **** **** **** **** **** **** **** +17928 **** **** **** **** **** **** **** **** **** +17929 **** **** **** **** **** **** **** **** **** +17930 **** **** **** **** **** **** **** **** **** +17931 **** **** **** **** **** **** **** **** **** +17932 **** **** **** **** **** **** **** **** **** +17933 **** **** **** **** **** **** **** **** **** +17934 **** **** **** **** **** **** **** **** **** +17935 **** **** **** **** **** **** **** **** **** +17936 **** **** **** **** **** **** **** **** **** +17937 **** **** **** **** **** **** **** **** **** +17938 **** **** **** **** **** **** **** **** **** +17939 **** **** **** **** **** **** **** **** **** +17940 **** **** **** **** **** **** **** **** **** +17941 **** **** **** **** **** **** **** **** **** +17942 **** **** **** **** **** **** **** **** **** +17943 **** **** **** **** **** **** **** **** **** +17944 **** **** **** **** **** **** **** **** **** +17945 **** **** **** **** **** **** **** **** **** +17946 **** **** **** **** **** **** **** **** **** +17947 **** **** **** **** **** **** **** **** **** +17948 **** **** **** **** **** **** **** **** **** +17949 **** **** **** **** **** **** **** **** **** +17950 **** **** **** **** **** **** **** **** **** +17951 **** **** **** **** **** **** **** **** **** +17952 **** **** **** **** **** **** **** **** **** +17953 **** **** **** **** **** **** **** **** **** +17954 **** **** **** **** **** **** **** **** **** +17955 **** **** **** **** **** **** **** **** **** +17956 **** **** **** **** **** **** **** **** **** +17957 **** **** **** **** **** **** **** **** **** +17958 **** **** **** **** **** **** **** **** **** +17959 **** **** **** **** **** **** **** **** **** +17960 **** **** **** **** **** **** **** **** **** +17961 **** **** **** **** **** **** **** **** **** +17962 **** **** **** **** **** **** **** **** **** +17963 **** **** **** **** **** **** **** **** **** +17964 **** **** **** **** **** **** **** **** **** +17965 **** **** **** **** **** **** **** **** **** +17966 **** **** **** **** **** **** **** **** **** +17967 **** **** **** **** **** **** **** **** **** +17968 **** **** **** **** **** **** **** **** **** +17969 **** **** **** **** **** **** **** **** **** +17970 **** **** **** **** **** **** **** **** **** +17971 **** **** **** **** **** **** **** **** **** +17972 **** **** **** **** **** **** **** **** **** +17973 **** **** **** **** **** **** **** **** **** +17974 **** **** **** **** **** **** **** **** **** +17975 **** **** **** **** **** **** **** **** **** +17976 **** **** **** **** **** **** **** **** **** +17977 **** **** **** **** **** **** **** **** **** +17978 **** **** **** **** **** **** **** **** **** +17979 **** **** **** **** **** **** **** **** **** +17980 **** **** **** **** **** **** **** **** **** +17981 **** **** **** **** **** **** **** **** **** +17982 **** **** **** **** **** **** **** **** **** +17983 **** **** **** **** **** **** **** **** **** +17984 **** **** **** **** **** **** **** **** **** +17985 **** **** **** **** **** **** **** **** **** +17986 **** **** **** **** **** **** **** **** **** +17987 **** **** **** **** **** **** **** **** **** +17988 **** **** **** **** **** **** **** **** **** +17989 **** **** **** **** **** **** **** **** **** +17990 **** **** **** **** **** **** **** **** **** +17991 **** **** **** **** **** **** **** **** **** +17992 **** **** **** **** **** **** **** **** **** +17993 **** **** **** **** **** **** **** **** **** +17994 **** **** **** **** **** **** **** **** **** +17995 **** **** **** **** **** **** **** **** **** +17996 **** **** **** **** **** **** **** **** **** +17997 **** **** **** **** **** **** **** **** **** +17998 **** **** **** **** **** **** **** **** **** +17999 ####END_OF_TOB_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +18000 **BEGIN_INVOCATIONS** **** **** **** **** **** **** **** **** +18001 BeguilingInfluence **** **** **** **** **** **** **** **** +18002 BreathOfTheNight **** **** **** **** **** **** **** **** +18003 Darkness **** **** **** **** **** **** **** **** +18004 DeafeningRoar **** **** **** **** **** **** **** **** +18005 DraconicKnowledge **** **** **** **** **** **** **** **** +18006 EndureExposure **** **** **** **** **** **** **** **** +18007 MagicInsight **** **** **** **** **** **** **** **** +18008 ScaldingGust **** **** **** **** **** **** **** **** +18009 SeeTheUnseen **** **** **** **** **** **** **** **** +18010 Charm **** **** **** **** **** **** **** **** +18011 EnergyResistance **** **** **** **** **** **** **** **** +18012 EnergyResistanceAcid **** **** **** **** **** **** **** **** +18013 EnergyResistanceCold **** **** **** **** **** **** **** **** +18014 EnergyResistanceElectric **** **** **** **** **** **** **** **** +18015 EnergyResistanceFire **** **** **** **** **** **** **** **** +18016 EnergyResistanceSonic **** **** **** **** **** **** **** **** +18017 FrightfulPresence **** **** **** **** **** **** **** **** +18018 HumanoidShape **** **** **** **** **** **** **** **** +18019 HumanoidShape_Select_Form **** **** **** **** **** **** **** **** +18020 HumanoidShape_Options **** **** **** **** **** **** **** **** +18021 HumanoidShape_True_Form **** **** **** **** **** **** **** **** +18022 HumanoidShape_Quickslot_1 **** **** **** **** **** **** **** **** +18023 HumanoidShape_Quickslot_2 **** **** **** **** **** **** **** **** +18024 Voidsense **** **** **** **** **** **** **** **** +18025 VoraciousDispelling **** **** **** **** **** **** **** **** +18026 WalkUnseen **** **** **** **** **** **** **** **** +18027 AuraOfFlame **** **** **** **** **** **** **** **** +18028 ChillingFog **** **** **** **** **** **** **** **** +18029 DevourMagic **** **** **** **** **** **** **** **** +18030 DraconicToughness **** **** **** **** **** **** **** **** +18031 TerrifyingRoar **** **** **** **** **** **** **** **** +18032 EnergyImmunity **** **** **** **** **** **** **** **** +18033 EnergyImmunityAcid **** **** **** **** **** **** **** **** +18034 EnergyImmunityCold **** **** **** **** **** **** **** **** +18035 EnergyImmunityElectric **** **** **** **** **** **** **** **** +18036 EnergyImmunityFire **** **** **** **** **** **** **** **** +18037 EnergyImmunitySonic **** **** **** **** **** **** **** **** +18038 InstillVulnerability **** **** **** **** **** **** **** **** +18039 InstillVulnerability_Acid **** **** **** **** **** **** **** **** +18040 InstillVulnerability_Cold **** **** **** **** **** **** **** **** +18041 InstillVulnerability_Elec **** **** **** **** **** **** **** **** +18042 InstillVulnerability_Fire **** **** **** **** **** **** **** **** +18043 InstillVulnerability_Sonic **** **** **** **** **** **** **** **** +18044 **Warlock_Invocations** **** **** **** **** **** **** **** **** +18045 AllSeeingEyes **** **** **** **** **** **** **** **** +18046 BalefulUtterance **** **** **** **** **** **** **** **** +18047 CallOfTheBeast **** **** **** **** **** **** **** **** +18048 CocoonOfRefuse **** **** **** **** **** **** **** **** +18049 DarkOnesOwnLuck **** **** **** **** **** **** **** **** +18050 DarkOnesOwnLuck_Fort **** **** **** **** **** **** **** **** +18051 DarkOnesOwnLuck_Reflex **** **** **** **** **** **** **** **** +18052 DarkOnesOwnLuck_Will **** **** **** **** **** **** **** **** +18053 DevilsSight **** **** **** **** **** **** **** **** +18054 **Drain_Incarnum** **** **** **** **** **** **** **** **** +18055 EarthenGrasp **** **** **** **** **** **** **** **** +18056 EldritchGlaive **** **** **** **** **** **** **** **** +18057 EldritchGlaiveOnHit **** **** **** **** **** **** **** **** +18058 EldritchSpear **** **** **** **** **** **** **** **** +18059 EntropicWarding **** **** **** **** **** **** **** **** +18060 FrightfulBlast **** **** **** **** **** **** **** **** +18061 HammerBlast **** **** **** **** **** **** **** **** +18062 HideousBlow **** **** **** **** **** **** **** **** +18063 LeapsAndBounds **** **** **** **** **** **** **** **** +18064 MiasmicCloud **** **** **** **** **** **** **** **** +18065 OtherworldlyWhispers **** **** **** **** **** **** **** **** +18066 SerpentsTongue **** **** **** **** **** **** **** **** +18067 SickeningBlast **** **** **** **** **** **** **** **** +18068 SoulreavingAura **** **** **** **** **** **** **** **** +18069 SummonSwarm **** **** **** **** **** **** **** **** +18070 SummonSwarm_Rat **** **** **** **** **** **** **** **** +18071 SummonSwarm_Bat **** **** **** **** **** **** **** **** +18072 SwimmingTheStyx **** **** **** **** **** **** **** **** +18073 BanefulBlastAbberation **** **** **** **** **** **** **** **** +18074 BanefulBlastBeast **** **** **** **** **** **** **** **** +18075 BanefulBlastConstruct **** **** **** **** **** **** **** **** +18076 BanefulBlastDragon **** **** **** **** **** **** **** **** +18077 BanefulBlastDwarf **** **** **** **** **** **** **** **** +18078 BanefulBlastElemental **** **** **** **** **** **** **** **** +18079 BanefulBlastElf **** **** **** **** **** **** **** **** +18080 BanefulBlastFey **** **** **** **** **** **** **** **** +18081 BanefulBlastGiant **** **** **** **** **** **** **** **** +18082 BanefulBlastGoblinoid **** **** **** **** **** **** **** **** +18083 BanefulBlastGnome **** **** **** **** **** **** **** **** +18084 BanefulBlastHalfling **** **** **** **** **** **** **** **** +18085 BanefulBlastHuman **** **** **** **** **** **** **** **** +18086 BanefulBlastMonsterous **** **** **** **** **** **** **** **** +18087 BanefulBlastOrc **** **** **** **** **** **** **** **** +18088 BanefulBlastOutsider **** **** **** **** **** **** **** **** +18089 BanefulBlastPlant **** **** **** **** **** **** **** **** +18090 BanefulBlastReptilian **** **** **** **** **** **** **** **** +18091 BanefulBlastShapechanger **** **** **** **** **** **** **** **** +18092 BanefulBlastUndead **** **** **** **** **** **** **** **** +18093 BanefulBlastVermin **** **** **** **** **** **** **** **** +18094 BeshadowedBlast **** **** **** **** **** **** **** **** +18095 BrimstoneBlast **** **** **** **** **** **** **** **** +18096 ColdComfort **** **** **** **** **** **** **** **** +18097 CurseOfDespair **** **** **** **** **** **** **** **** +18098 DreadSeizure **** **** **** **** **** **** **** **** +18099 EldritchChain **** **** **** **** **** **** **** **** +18100 FleeTheScene **** **** **** **** **** **** **** **** +18101 FleeTheScene_Selected **** **** **** **** **** **** **** **** +18102 FleeTheScene_Direction_and_Distance **** **** **** **** **** **** **** **** +18103 HellrimeBlast **** **** **** **** **** **** **** **** +18104 HungryDarkness **** **** **** **** **** **** **** **** +18105 IgnoreThePyre **** **** **** **** **** **** **** **** +18106 IgnoreThePyreAcid **** **** **** **** **** **** **** **** +18107 IgnoreThePyreCold **** **** **** **** **** **** **** **** +18108 IgnoreThePyreElec **** **** **** **** **** **** **** **** +18109 IgnoreThePyreFire **** **** **** **** **** **** **** **** +18110 IgnoreThePyreSonic **** **** **** **** **** **** **** **** +18111 MaskOfFlesh **** **** **** **** **** **** **** **** +18112 MaskOfFleshFriendly **** **** **** **** **** **** **** **** +18113 MaskOfFleshHostile **** **** **** **** **** **** **** **** +18114 RelentlessDispelling **** **** **** **** **** **** **** **** +18115 SpiderShape **** **** **** **** **** **** **** **** +18116 **Steal_Incarnum** **** **** **** **** **** **** **** **** +18117 StonyGrasp **** **** **** **** **** **** **** **** +18118 TheDeadWalk **** **** **** **** **** **** **** **** +18119 WallOfGloom **** **** **** **** **** **** **** **** +18120 WitchwoodStep **** **** **** **** **** **** **** **** +18121 BewitchingBlast **** **** **** **** **** **** **** **** +18122 CausticMire **** **** **** **** **** **** **** **** +18123 ChillingTentacles **** **** **** **** **** **** **** **** +18124 DragonWard **** **** **** **** **** **** **** **** +18125 EldritchCone **** **** **** **** **** **** **** **** +18126 EldritchLine **** **** **** **** **** **** **** **** +18127 EnervatingShadow **** **** **** **** **** **** **** **** +18128 HellspawnedGrace **** **** **** **** **** **** **** **** +18129 HinderingBlast **** **** **** **** **** **** **** **** +18130 **Incarnum_Blast** **** **** **** **** **** **** **** **** +18131 NightmaresMadeReal **** **** **** **** **** **** **** **** +18132 NoxiousBlast **** **** **** **** **** **** **** **** +18133 PainfulSlumberOfTheAges **** **** **** **** **** **** **** **** +18134 PenetratingBlast **** **** **** **** **** **** **** **** +18135 TenaciousPlague **** **** **** **** **** **** **** **** +18136 VitriolicBlast **** **** **** **** **** **** **** **** +18137 WallOfPerilousFlame **** **** **** **** **** **** **** **** +18138 BindingBlast **** **** **** **** **** **** **** **** +18139 CastersLament **** **** **** **** **** **** **** **** +18140 DarkDiscorporation **** **** **** **** **** **** **** **** +18141 DarkForesight **** **** **** **** **** **** **** **** +18142 EldritchDoom **** **** **** **** **** **** **** **** +18143 **Incarnum_Shroud** **** **** **** **** **** **** **** **** +18144 PathOfShadow **** **** **** **** **** **** **** **** +18145 PathOfShadowSelf **** **** **** **** **** **** **** **** +18146 PathOfShadowParty **** **** **** **** **** **** **** **** +18147 RetributiveInvisibility **** **** **** **** **** **** **** **** +18148 StealSummoning **** **** **** **** **** **** **** **** +18149 UtterdarkBlast **** **** **** **** **** **** **** **** +18150 WordOfChanging **** **** **** **** **** **** **** **** +18151 **Enlightened_Spirit_Invocations** **** **** **** **** **** **** **** **** +18152 **** **** **** **** **** **** **** **** **** +18153 **** **** **** **** **** **** **** **** **** +18154 **** **** **** **** **** **** **** **** **** +18155 **** **** **** **** **** **** **** **** **** +18156 **** **** **** **** **** **** **** **** **** +18157 **** **** **** **** **** **** **** **** **** +18158 ####START_OF_INV_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +18159 Warlock_AllSeeingEyes **** **** **** **** **** **** **** **** +18160 Warlock_BalefulUtterance **** **** **** **** **** **** **** **** +18161 Warlock_BeguilingInfluence **** **** **** **** **** **** **** **** +18162 Warlock_BreathOfTheNight **** **** **** **** **** **** **** **** +18163 Warlock_CallOfTheBeast **** **** **** **** **** **** **** **** +18164 Warlock_CocoonOfRefuse **** **** **** **** **** **** **** **** +18165 Warlock_Darkness **** **** **** **** **** **** **** **** +18166 Warlock_DarkOnesOwnLuck **** **** **** **** **** **** **** **** +18167 Warlock_DarkOnesOwnLuck_Fort **** **** **** **** **** **** **** **** +18168 Warlock_DarkOnesOwnLuck_Reflex **** **** **** **** **** **** **** **** +18169 Warlock_DarkOnesOwnLuck_Will **** **** **** **** **** **** **** **** +18170 Warlock_DevilsSight **** **** **** **** **** **** **** **** +18171 Warlock_EarthenGrasp **** **** **** **** **** **** **** **** +18172 Warlock_EldritchGlaive **** **** **** **** **** **** **** **** +18173 Warlock_EldritchSpear **** **** **** **** **** **** **** **** +18174 Warlock_EntropicWarding **** **** **** **** **** **** **** **** +18175 Warlock_FrightfulBlast **** **** **** **** **** **** **** **** +18176 Warlock_HammerBlast **** **** **** **** **** **** **** **** +18177 Warlock_HideousBlow **** **** **** **** **** **** **** **** +18178 Warlock_LeapsAndBounds **** **** **** **** **** **** **** **** +18179 Warlock_MiasmicCloud **** **** **** **** **** **** **** **** +18180 Warlock_OtherworldlyWhispers **** **** **** **** **** **** **** **** +18181 Warlock_SeeTheUnseen **** **** **** **** **** **** **** **** +18182 Warlock_SerpentsTongue **** **** **** **** **** **** **** **** +18183 Warlock_SickeningBlast **** **** **** **** **** **** **** **** +18184 Warlock_SoulreavingAura **** **** **** **** **** **** **** **** +18185 Warlock_SummonSwarm **** **** **** **** **** **** **** **** +18186 Warlock_SummonSwarm_Rat **** **** **** **** **** **** **** **** +18187 Warlock_SummonSwarm_Bat **** **** **** **** **** **** **** **** +18188 Warlock_SwimmingTheStyx **** **** **** **** **** **** **** **** +18189 Warlock_BanefulBlastAbberation **** **** **** **** **** **** **** **** +18190 Warlock_BanefulBlastBeast **** **** **** **** **** **** **** **** +18191 Warlock_BanefulBlastConstruct **** **** **** **** **** **** **** **** +18192 Warlock_BanefulBlastDragon **** **** **** **** **** **** **** **** +18193 Warlock_BanefulBlastDwarf **** **** **** **** **** **** **** **** +18194 Warlock_BanefulBlastElemental **** **** **** **** **** **** **** **** +18195 Warlock_BanefulBlastElf **** **** **** **** **** **** **** **** +18196 Warlock_BanefulBlastFey **** **** **** **** **** **** **** **** +18197 Warlock_BanefulBlastGiant **** **** **** **** **** **** **** **** +18198 Warlock_BanefulBlastGoblinoid **** **** **** **** **** **** **** **** +18199 Warlock_BanefulBlastGnome **** **** **** **** **** **** **** **** +18200 Warlock_BanefulBlastHalfling **** **** **** **** **** **** **** **** +18201 Warlock_BanefulBlastHuman **** **** **** **** **** **** **** **** +18202 Warlock_BanefulBlastMonsterous **** **** **** **** **** **** **** **** +18203 Warlock_BanefulBlastOrc **** **** **** **** **** **** **** **** +18204 Warlock_BanefulBlastOutsider **** **** **** **** **** **** **** **** +18205 Warlock_BanefulBlastPlant **** **** **** **** **** **** **** **** +18206 Warlock_BanefulBlastReptilian **** **** **** **** **** **** **** **** +18207 Warlock_BanefulBlastShapechanger **** **** **** **** **** **** **** **** +18208 Warlock_BanefulBlastUndead **** **** **** **** **** **** **** **** +18209 Warlock_BanefulBlastVermin **** **** **** **** **** **** **** **** +18210 Warlock_BeshadowedBlast **** **** **** **** **** **** **** **** +18211 Warlock_BrimstoneBlast **** **** **** **** **** **** **** **** +18212 Warlock_Charm **** **** **** **** **** **** **** **** +18213 Warlock_ColdComfort **** **** **** **** **** **** **** **** +18214 Warlock_CurseOfDespair **** **** **** **** **** **** **** **** +18215 Warlock_DreadSeizure **** **** **** **** **** **** **** **** +18216 Warlock_EldritchChain **** **** **** **** **** **** **** **** +18217 Warlock_FleeTheScene **** **** **** **** **** **** **** **** +18218 Warlock_FleeTheScene_Selected **** **** **** **** **** **** **** **** +18219 Warlock_FleeTheScene_Direction_and_Distance **** **** **** **** **** **** **** **** +18220 Warlock_HellrimeBlast **** **** **** **** **** **** **** **** +18221 Warlock_HungryDarkness **** **** **** **** **** **** **** **** +18222 Warlock_IgnoreThePyre **** **** **** **** **** **** **** **** +18223 Warlock_IgnoreThePyreAcid **** **** **** **** **** **** **** **** +18224 Warlock_IgnoreThePyreCold **** **** **** **** **** **** **** **** +18225 Warlock_IgnoreThePyreElec **** **** **** **** **** **** **** **** +18226 Warlock_IgnoreThePyreFire **** **** **** **** **** **** **** **** +18227 Warlock_IgnoreThePyreSonic **** **** **** **** **** **** **** **** +18228 Warlock_MaskOfFlesh **** **** **** **** **** **** **** **** +18229 Warlock_MaskOfFleshFriendly **** **** **** **** **** **** **** **** +18230 Warlock_MaskOfFleshHostile **** **** **** **** **** **** **** **** +18231 Warlock_RelentlessDispelling **** **** **** **** **** **** **** **** +18232 Warlock_SpiderShape **** **** **** **** **** **** **** **** +18233 Warlock_StonyGrasp **** **** **** **** **** **** **** **** +18234 Warlock_TheDeadWalk **** **** **** **** **** **** **** **** +18235 Warlock_Voidsense **** **** **** **** **** **** **** **** +18236 Warlock_VoraciousDispelling **** **** **** **** **** **** **** **** +18237 Warlock_WalkUnseen **** **** **** **** **** **** **** **** +18238 Warlock_WallOfGloom **** **** **** **** **** **** **** **** +18239 Warlock_WitchwoodStep **** **** **** **** **** **** **** **** +18240 Warlock_BewitchingBlast **** **** **** **** **** **** **** **** +18241 Warlock_CausticMire **** **** **** **** **** **** **** **** +18242 Warlock_ChillingTentacles **** **** **** **** **** **** **** **** +18243 Warlock_DevourMagic **** **** **** **** **** **** **** **** +18244 Warlock_DragonWard **** **** **** **** **** **** **** **** +18245 Warlock_EldritchCone **** **** **** **** **** **** **** **** +18246 Warlock_EldritchLine **** **** **** **** **** **** **** **** +18247 Warlock_EnervatingShadow **** **** **** **** **** **** **** **** +18248 Warlock_HellspawnedGrace **** **** **** **** **** **** **** **** +18249 Warlock_HinderingBlast **** **** **** **** **** **** **** **** +18250 Warlock_NightmaresMadeReal **** **** **** **** **** **** **** **** +18251 Warlock_NoxiousBlast **** **** **** **** **** **** **** **** +18252 Warlock_PainfulSlumberOfTheAges **** **** **** **** **** **** **** **** +18253 Warlock_PenetratingBlast **** **** **** **** **** **** **** **** +18254 Warlock_TenaciousPlague **** **** **** **** **** **** **** **** +18255 Warlock_VitriolicBlast **** **** **** **** **** **** **** **** +18256 Warlock_WallOfPerilousFlame **** **** **** **** **** **** **** **** +18257 Warlock_BindingBlast **** **** **** **** **** **** **** **** +18258 Warlock_CastersLament **** **** **** **** **** **** **** **** +18259 Warlock_DarkDiscorporation **** **** **** **** **** **** **** **** +18260 Warlock_DarkForesight **** **** **** **** **** **** **** **** +18261 Warlock_EldritchDoom **** **** **** **** **** **** **** **** +18262 Warlock_PathOfShadow **** **** **** **** **** **** **** **** +18263 Warlock_PathOfShadowSelf **** **** **** **** **** **** **** **** +18264 Warlock_PathOfShadowParty **** **** **** **** **** **** **** **** +18265 Warlock_RetributiveInvisibility **** **** **** **** **** **** **** **** +18266 Warlock_StealSummoning **** **** **** **** **** **** **** **** +18267 Warlock_UtterdarkBlast **** **** **** **** **** **** **** **** +18268 Warlock_WordOfChanging **** **** **** **** **** **** **** **** +18269 DragonShaman_BeguilingInfluence **** **** **** **** **** **** **** **** +18270 DragonShaman_BreathOfTheNight **** **** **** **** **** **** **** **** +18271 DragonShaman_Darkness **** **** **** **** **** **** **** **** +18272 DragonShaman_DeafeningRoar **** **** **** **** **** **** **** **** +18273 DragonShaman_DraconicKnowledge **** **** **** **** **** **** **** **** +18274 DragonShaman_EndureExposure **** **** **** **** **** **** **** **** +18275 DragonShaman_MagicInsight **** **** **** **** **** **** **** **** +18276 DragonShaman_ScaldingGust **** **** **** **** **** **** **** **** +18277 DragonShaman_SeeTheUnseen **** **** **** **** **** **** **** **** +18278 Dragonfire_Adept_BeguilingInfluence **** **** **** **** **** **** **** **** +18279 Dragonfire_Adept_BreathOfTheNight **** **** **** **** **** **** **** **** +18280 Dragonfire_Adept_Darkness **** **** **** **** **** **** **** **** +18281 Dragonfire_Adept_DeafeningRoar **** **** **** **** **** **** **** **** +18282 Dragonfire_Adept_DraconicKnowledge **** **** **** **** **** **** **** **** +18283 Dragonfire_Adept_EndureExposure **** **** **** **** **** **** **** **** +18284 Dragonfire_Adept_MagicInsight **** **** **** **** **** **** **** **** +18285 Dragonfire_Adept_ScaldingGust **** **** **** **** **** **** **** **** +18286 Dragonfire_Adept_SeeTheUnseen **** **** **** **** **** **** **** **** +18287 Dragonfire_Adept_Charm **** **** **** **** **** **** **** **** +18288 Dragonfire_Adept_EnergyResistance **** **** **** **** **** **** **** **** +18289 Dragonfire_Adept_EnergyResistanceAcid **** **** **** **** **** **** **** **** +18290 Dragonfire_Adept_EnergyResistanceCold **** **** **** **** **** **** **** **** +18291 Dragonfire_Adept_EnergyResistanceElectric **** **** **** **** **** **** **** **** +18292 Dragonfire_Adept_EnergyResistanceFire **** **** **** **** **** **** **** **** +18293 Dragonfire_Adept_EnergyResistanceSonic **** **** **** **** **** **** **** **** +18294 Dragonfire_Adept_FrightfulPresence **** **** **** **** **** **** **** **** +18295 Dragonfire_Adept_HumanoidShape **** **** **** **** **** **** **** **** +18296 Dragonfire_Adept_HumanoidShape_Select_Form **** **** **** **** **** **** **** **** +18297 Dragonfire_Adept_HumanoidShape_Options **** **** **** **** **** **** **** **** +18298 Dragonfire_Adept_HumanoidShape_True_Form **** **** **** **** **** **** **** **** +18299 Dragonfire_Adept_HumanoidShape_Quickslot_1 **** **** **** **** **** **** **** **** +18300 Dragonfire_Adept_HumanoidShape_Quickslot_2 **** **** **** **** **** **** **** **** +18301 Dragonfire_Adept_Voidsense **** **** **** **** **** **** **** **** +18302 Dragonfire_Adept_VoraciousDispelling **** **** **** **** **** **** **** **** +18303 Dragonfire_Adept_WalkUnseen **** **** **** **** **** **** **** **** +18304 Dragonfire_Adept_AuraOfFlame **** **** **** **** **** **** **** **** +18305 Dragonfire_Adept_ChillingFog **** **** **** **** **** **** **** **** +18306 Dragonfire_Adept_DevourMagic **** **** **** **** **** **** **** **** +18307 Dragonfire_Adept_DraconicToughness **** **** **** **** **** **** **** **** +18308 Dragonfire_Adept_TerrifyingRoar **** **** **** **** **** **** **** **** +18309 Dragonfire_Adept_EnergyImmunity **** **** **** **** **** **** **** **** +18310 Dragonfire_Adept_EnergyImmunityAcid **** **** **** **** **** **** **** **** +18311 Dragonfire_Adept_EnergyImmunityCold **** **** **** **** **** **** **** **** +18312 Dragonfire_Adept_EnergyImmunityElectric **** **** **** **** **** **** **** **** +18313 Dragonfire_Adept_EnergyImmunityFire **** **** **** **** **** **** **** **** +18314 Dragonfire_Adept_EnergyImmunitySonic **** **** **** **** **** **** **** **** +18315 Dragonfire_Adept_InstillVulnerability **** **** **** **** **** **** **** **** +18316 Dragonfire_Adept_InstillVulnerability_Acid **** **** **** **** **** **** **** **** +18317 Dragonfire_Adept_InstillVulnerability_Cold **** **** **** **** **** **** **** **** +18318 Dragonfire_Adept_InstillVulnerability_Elec **** **** **** **** **** **** **** **** +18319 Dragonfire_Adept_InstillVulnerability_Fire **** **** **** **** **** **** **** **** +18320 Dragonfire_Adept_InstillVulnerability_Sonic **** **** **** **** **** **** **** **** +18321 **** **** **** **** **** **** **** **** **** +18322 **** **** **** **** **** **** **** **** **** +18323 **** **** **** **** **** **** **** **** **** +18324 **** **** **** **** **** **** **** **** **** +18325 **** **** **** **** **** **** **** **** **** +18326 **** **** **** **** **** **** **** **** **** +18327 **** **** **** **** **** **** **** **** **** +18328 **** **** **** **** **** **** **** **** **** +18329 **** **** **** **** **** **** **** **** **** +18330 **** **** **** **** **** **** **** **** **** +18331 **** **** **** **** **** **** **** **** **** +18332 **** **** **** **** **** **** **** **** **** +18333 **** **** **** **** **** **** **** **** **** +18334 **** **** **** **** **** **** **** **** **** +18335 **** **** **** **** **** **** **** **** **** +18336 **** **** **** **** **** **** **** **** **** +18337 **** **** **** **** **** **** **** **** **** +18338 **** **** **** **** **** **** **** **** **** +18339 **** **** **** **** **** **** **** **** **** +18340 **** **** **** **** **** **** **** **** **** +18341 **** **** **** **** **** **** **** **** **** +18342 **** **** **** **** **** **** **** **** **** +18343 **** **** **** **** **** **** **** **** **** +18344 **** **** **** **** **** **** **** **** **** +18345 **** **** **** **** **** **** **** **** **** +18346 **** **** **** **** **** **** **** **** **** +18347 **** **** **** **** **** **** **** **** **** +18348 **** **** **** **** **** **** **** **** **** +18349 **** **** **** **** **** **** **** **** **** +18350 ####END_OF_INV_SPELLBOOK_RESERVE **** **** **** **** **** **** **** **** +18351 ####START_OF_SHADOW_MAGIC_RESERVE **** **** **** **** **** **** **** **** +18352 BendPerspective **** **** **** **** **** **** **** **** +18353 CarpetShadow **** **** **** **** **** **** **** **** +18354 DuskAndDawn_Dusk **** **** **** **** **** **** **** **** +18355 DuskAndDawn_Dawn **** **** **** **** **** **** **** **** +18356 LifeFades **** **** **** **** **** **** **** **** +18357 MesmerizingShade **** **** **** **** **** **** **** **** +18358 SteelShadows **** **** **** **** **** **** **** **** +18359 VoiceOfShadow_Approach **** **** **** **** **** **** **** **** +18360 VoiceOfShadow_Drop **** **** **** **** **** **** **** **** +18361 VoiceOfShadow_Fall **** **** **** **** **** **** **** **** +18362 VoiceOfShadow_Flee **** **** **** **** **** **** **** **** +18363 VoiceOfShadow_Halt **** **** **** **** **** **** **** **** +18364 BlackFire **** **** **** **** **** **** **** **** +18365 CongressShadows **** **** **** **** **** **** **** **** +18366 FleshFails_Str **** **** **** **** **** **** **** **** +18367 FleshFails_Dex **** **** **** **** **** **** **** **** +18368 FleshFails_Con **** **** **** **** **** **** **** **** +18369 PiercingSight **** **** **** **** **** **** **** **** +18370 ShadowSkin **** **** **** **** **** **** **** **** +18371 SightEclipsed **** **** **** **** **** **** **** **** +18372 ThoughtsShadow_Int **** **** **** **** **** **** **** **** +18373 ThoughtsShadow_Wis **** **** **** **** **** **** **** **** +18374 ThoughtsShadow_Cha **** **** **** **** **** **** **** **** +18375 AfraidOfTheDark **** **** **** **** **** **** **** **** +18376 ClingingDarkness **** **** **** **** **** **** **** **** +18377 DancingShadows **** **** **** **** **** **** **** **** +18378 Flicker **** **** **** **** **** **** **** **** +18379 KillingShadows **** **** **** **** **** **** **** **** +18380 SharpShadows **** **** **** **** **** **** **** **** +18381 UmbralTouch **** **** **** **** **** **** **** **** +18382 AuraOfShade **** **** **** **** **** **** **** **** +18383 Bolster **** **** **** **** **** **** **** **** +18384 ShadowEvocation **** **** **** **** **** **** **** **** +18385 ShadowEvocation_Conv **** **** **** **** **** **** **** **** +18386 ShadowVision **** **** **** **** **** **** **** **** +18387 ShadowsFade **** **** **** **** **** **** **** **** +18388 StepIntoShadow_Self **** **** **** **** **** **** **** **** +18389 StepIntoShadow_Party **** **** **** **** **** **** **** **** +18390 WarpSpell **** **** **** **** **** **** **** **** +18391 CurtainShadows **** **** **** **** **** **** **** **** +18392 DarkAir **** **** **** **** **** **** **** **** +18393 EchoSpell **** **** **** **** **** **** **** **** +18394 FeignLife **** **** **** **** **** **** **** **** +18395 Languor_Slow **** **** **** **** **** **** **** **** +18396 Languor_Hold **** **** **** **** **** **** **** **** +18397 PassShadow_Self **** **** **** **** **** **** **** **** +18398 PassShadow_Party **** **** **** **** **** **** **** **** +18399 UnravelDweomer **** **** **** **** **** **** **** **** +18400 FloodShadows **** **** **** **** **** **** **** **** +18401 GreaterShadowEvocation **** **** **** **** **** **** **** **** +18402 GreaterShadowEvocation_Conv **** **** **** **** **** **** **** **** +18403 ShadowInvestiture **** **** **** **** **** **** **** **** +18404 ShadowStorm **** **** **** **** **** **** **** **** +18405 ShadowsFade_Greater **** **** **** **** **** **** **** **** +18406 Unveil **** **** **** **** **** **** **** **** +18407 VoyageShadow_Self **** **** **** **** **** **** **** **** +18408 VoyageShadow_Party **** **** **** **** **** **** **** **** +18409 DarkSoul **** **** **** **** **** **** **** **** +18410 EphemeralImage **** **** **** **** **** **** **** **** +18411 LifeFadesGreater **** **** **** **** **** **** **** **** +18412 PrisonNight **** **** **** **** **** **** **** **** +18413 UmbralServant **** **** **** **** **** **** **** **** +18414 TruthRevealed **** **** **** **** **** **** **** **** +18415 FarSight **** **** **** **** **** **** **** **** +18416 GrFleshFails_Str **** **** **** **** **** **** **** **** +18417 GrFleshFails_Dex **** **** **** **** **** **** **** **** +18418 GrFleshFails_Con **** **** **** **** **** **** **** **** +18419 ShadowPlague **** **** **** **** **** **** **** **** +18420 SoulPuppet **** **** **** **** **** **** **** **** +18421 TombNight **** **** **** **** **** **** **** **** +18422 UmbralBody **** **** **** **** **** **** **** **** +18423 ArmyShadow **** **** **** **** **** **** **** **** +18424 ConsumeEssence **** **** **** **** **** **** **** **** +18425 EphemeralStorm **** **** **** **** **** **** **** **** +18426 Reflections **** **** **** **** **** **** **** **** +18427 ShadowSurge **** **** **** **** **** **** **** **** +18428 ShadowTime **** **** **** **** **** **** **** **** +18429 **Class_Mysteries** **** **** **** **** **** **** **** **** +18430 Shadowcaster_BendPerspective **** **** **** **** **** **** **** **** +18431 Shadowcaster_CarpetShadow **** **** **** **** **** **** **** **** +18432 Shadowcaster_DuskAndDawn_RadialMaster **** **** **** **** **** **** **** **** +18433 Shadowcaster_DuskAndDawn_Dusk **** **** **** **** **** **** **** **** +18434 Shadowcaster_DuskAndDawn_Dawn **** **** **** **** **** **** **** **** +18435 Shadowcaster_LifeFades **** **** **** **** **** **** **** **** +18436 Shadowcaster_MesmerizingShade **** **** **** **** **** **** **** **** +18437 Shadowcaster_SteelShadows **** **** **** **** **** **** **** **** +18438 Shadowcaster_VoiceOfShadow_RadialMaster **** **** **** **** **** **** **** **** +18439 Shadowcaster_VoiceOfShadow_Approach **** **** **** **** **** **** **** **** +18440 Shadowcaster_VoiceOfShadow_Drop **** **** **** **** **** **** **** **** +18441 Shadowcaster_VoiceOfShadow_Fall **** **** **** **** **** **** **** **** +18442 Shadowcaster_VoiceOfShadow_Flee **** **** **** **** **** **** **** **** +18443 Shadowcaster_VoiceOfShadow_Halt **** **** **** **** **** **** **** **** +18444 Shadowcaster_BlackFire **** **** **** **** **** **** **** **** +18445 Shadowcaster_CongressShadows **** **** **** **** **** **** **** **** +18446 Shadowcaster_FleshFails_RadialMaster **** **** **** **** **** **** **** **** +18447 Shadowcaster_FleshFails_Str **** **** **** **** **** **** **** **** +18448 Shadowcaster_FleshFails_Dex **** **** **** **** **** **** **** **** +18449 Shadowcaster_FleshFails_Con **** **** **** **** **** **** **** **** +18450 Shadowcaster_PiercingSight **** **** **** **** **** **** **** **** +18451 Shadowcaster_ShadowSkin **** **** **** **** **** **** **** **** +18452 Shadowcaster_SightEclipsed **** **** **** **** **** **** **** **** +18453 Shadowcaster_ThoughtsShadow_RadialMaster **** **** **** **** **** **** **** **** +18454 Shadowcaster_ThoughtsShadow_Int **** **** **** **** **** **** **** **** +18455 Shadowcaster_ThoughtsShadow_Wis **** **** **** **** **** **** **** **** +18456 Shadowcaster_ThoughtsShadow_Cha **** **** **** **** **** **** **** **** +18457 Shadowcaster_AfraidOfTheDark **** **** **** **** **** **** **** **** +18458 Shadowcaster_ClingingDarkness **** **** **** **** **** **** **** **** +18459 Shadowcaster_DancingShadows **** **** **** **** **** **** **** **** +18460 Shadowcaster_Flicker **** **** **** **** **** **** **** **** +18461 Shadowcaster_KillingShadows **** **** **** **** **** **** **** **** +18462 Shadowcaster_SharpShadows **** **** **** **** **** **** **** **** +18463 Shadowcaster_UmbralTouch **** **** **** **** **** **** **** **** +18464 Shadowcaster_AuraOfShade **** **** **** **** **** **** **** **** +18465 Shadowcaster_Bolster **** **** **** **** **** **** **** **** +18466 Shadowcaster_ShadowEvocation_RadialMaster **** **** **** **** **** **** **** **** +18467 Shadowcaster_ShadowEvocation **** **** **** **** **** **** **** **** +18468 Shadowcaster_ShadowEvocation_Conv **** **** **** **** **** **** **** **** +18469 Shadowcaster_ShadowVision **** **** **** **** **** **** **** **** +18470 Shadowcaster_ShadowsFade **** **** **** **** **** **** **** **** +18471 Shadowcaster_StepIntoShadow_RadialMaster **** **** **** **** **** **** **** **** +18472 Shadowcaster_StepIntoShadow_Self **** **** **** **** **** **** **** **** +18473 Shadowcaster_StepIntoShadow_Party **** **** **** **** **** **** **** **** +18474 Shadowcaster_WarpSpell **** **** **** **** **** **** **** **** +18475 Shadowcaster_CurtainShadows **** **** **** **** **** **** **** **** +18476 Shadowcaster_DarkAir **** **** **** **** **** **** **** **** +18477 Shadowcaster_EchoSpell **** **** **** **** **** **** **** **** +18478 Shadowcaster_FeignLife **** **** **** **** **** **** **** **** +18479 Shadowcaster_Languor_RadialMaster **** **** **** **** **** **** **** **** +18480 Shadowcaster_Languor_Slow **** **** **** **** **** **** **** **** +18481 Shadowcaster_Languor_Hold **** **** **** **** **** **** **** **** +18482 Shadowcaster_PassIntoShadow_RadialMaster **** **** **** **** **** **** **** **** +18483 Shadowcaster_PassShadow_Self **** **** **** **** **** **** **** **** +18484 Shadowcaster_PassShadow_Party **** **** **** **** **** **** **** **** +18485 Shadowcaster_UnravelDweomer **** **** **** **** **** **** **** **** +18486 Shadowcaster_FloodShadows **** **** **** **** **** **** **** **** +18487 Shadowcaster_GreaterShadowEvocation_RadialMaster **** **** **** **** **** **** **** **** +18488 Shadowcaster_GreaterShadowEvocation **** **** **** **** **** **** **** **** +18489 Shadowcaster_GreaterShadowEvocation_Conv **** **** **** **** **** **** **** **** +18490 Shadowcaster_ShadowInvestiture **** **** **** **** **** **** **** **** +18491 Shadowcaster_ShadowStorm **** **** **** **** **** **** **** **** +18492 Shadowcaster_ShadowsFade_Greater **** **** **** **** **** **** **** **** +18493 Shadowcaster_Unveil **** **** **** **** **** **** **** **** +18494 Shadowcaster_VoyageShadow_RadialMaster **** **** **** **** **** **** **** **** +18495 Shadowcaster_VoyageShadow_Self **** **** **** **** **** **** **** **** +18496 Shadowcaster_VoyageShadow_Party **** **** **** **** **** **** **** **** +18497 Shadowcaster_DarkSoul **** **** **** **** **** **** **** **** +18498 Shadowcaster_EphemeralImage **** **** **** **** **** **** **** **** +18499 Shadowcaster_LifeFadesGreater **** **** **** **** **** **** **** **** +18500 Shadowcaster_PrisonNight **** **** **** **** **** **** **** **** +18501 Shadowcaster_UmbralServant **** **** **** **** **** **** **** **** +18502 Shadowcaster_TruthRevealed **** **** **** **** **** **** **** **** +18503 Shadowcaster_FarSight **** **** **** **** **** **** **** **** +18504 Shadowcaster_GrFleshFails_RadialMaster **** **** **** **** **** **** **** **** +18505 Shadowcaster_GrFleshFails_Str **** **** **** **** **** **** **** **** +18506 Shadowcaster_GrFleshFails_Dex **** **** **** **** **** **** **** **** +18507 Shadowcaster_GrFleshFails_Con **** **** **** **** **** **** **** **** +18508 Shadowcaster_ShadowPlague **** **** **** **** **** **** **** **** +18509 Shadowcaster_SoulPuppet **** **** **** **** **** **** **** **** +18510 Shadowcaster_TombNight **** **** **** **** **** **** **** **** +18511 Shadowcaster_UmbralBody **** **** **** **** **** **** **** **** +18512 Shadowcaster_ArmyShadow **** **** **** **** **** **** **** **** +18513 Shadowcaster_ConsumeEssence **** **** **** **** **** **** **** **** +18514 Shadowcaster_EphemeralStorm **** **** **** **** **** **** **** **** +18515 Shadowcaster_Reflections **** **** **** **** **** **** **** **** +18516 Shadowcaster_ShadowSurge **** **** **** **** **** **** **** **** +18517 Shadowcaster_ShadowTime **** **** **** **** **** **** **** **** +18518 **Shadowcasting_Feats** **** **** **** **** **** **** **** **** +18519 Flicker_Feat **** **** **** **** **** **** **** **** +18520 DarkSoul_Feat **** **** **** **** **** **** **** **** +18521 ArrowDusk **** **** **** **** **** **** **** **** +18522 BlackCandle_Master **** **** **** **** **** **** **** **** +18523 BlackCandle_Light **** **** **** **** **** **** **** **** +18524 BlackCandle_Dark **** **** **** **** **** **** **** **** +18525 CaulShadow **** **** **** **** **** **** **** **** +18526 MysticReflections **** **** **** **** **** **** **** **** +18527 SightObscured **** **** **** **** **** **** **** **** +18528 ShadowHood **** **** **** **** **** **** **** **** +18529 UmbralHand **** **** **** **** **** **** **** **** +18530 WidenedEyes **** **** **** **** **** **** **** **** +18531 EmpowerMystery **** **** **** **** **** **** **** **** +18532 ExtendMystery **** **** **** **** **** **** **** **** +18533 MaximizeMystery **** **** **** **** **** **** **** **** +18534 QuickenMystery **** **** **** **** **** **** **** **** +18535 StillMystery **** **** **** **** **** **** **** **** +18536 CloakShadows **** **** **** **** **** **** **** **** +18537 DancingShadows **** **** **** **** **** **** **** **** +18538 NightForm **** **** **** **** **** **** **** **** +18539 MastersBidding_Heal **** **** **** **** **** **** **** **** +18540 MastersBidding_Attack **** **** **** **** **** **** **** **** +18541 MastersBidding_Cold **** **** **** **** **** **** **** **** +18542 MastersBidding_DR **** **** **** **** **** **** **** **** +18543 MastersBidding_Speed **** **** **** **** **** **** **** **** +18544 InnateCounterspell **** **** **** **** **** **** **** **** +18545 EldritchDisruption **** **** **** **** **** **** **** **** +18546 EldritchVortex **** **** **** **** **** **** **** **** +18547 Shadowsmith_BendPerspective **** **** **** **** **** **** **** **** +18548 Shadowsmith_CarpetShadow **** **** **** **** **** **** **** **** +18549 Shadowsmith_DuskAndDawn_RadialMaster **** **** **** **** **** **** **** **** +18550 Shadowsmith_DuskAndDawn_Dusk **** **** **** **** **** **** **** **** +18551 Shadowsmith_DuskAndDawn_Dawn **** **** **** **** **** **** **** **** +18552 Shadowsmith_LifeFades **** **** **** **** **** **** **** **** +18553 Shadowsmith_MesmerizingShade **** **** **** **** **** **** **** **** +18554 Shadowsmith_SteelShadows **** **** **** **** **** **** **** **** +18555 Shadowsmith_VoiceOfShadow_RadialMaster **** **** **** **** **** **** **** **** +18556 Shadowsmith_VoiceOfShadow_Approach **** **** **** **** **** **** **** **** +18557 Shadowsmith_VoiceOfShadow_Drop **** **** **** **** **** **** **** **** +18558 Shadowsmith_VoiceOfShadow_Fall **** **** **** **** **** **** **** **** +18559 Shadowsmith_VoiceOfShadow_Flee **** **** **** **** **** **** **** **** +18560 Shadowsmith_VoiceOfShadow_Halt **** **** **** **** **** **** **** **** +18561 Shadowsmith_BlackFire **** **** **** **** **** **** **** **** +18562 Shadowsmith_CongressShadows **** **** **** **** **** **** **** **** +18563 Shadowsmith_FleshFails_RadialMaster **** **** **** **** **** **** **** **** +18564 Shadowsmith_FleshFails_Str **** **** **** **** **** **** **** **** +18565 Shadowsmith_FleshFails_Dex **** **** **** **** **** **** **** **** +18566 Shadowsmith_FleshFails_Con **** **** **** **** **** **** **** **** +18567 Shadowsmith_PiercingSight **** **** **** **** **** **** **** **** +18568 Shadowsmith_ShadowSkin **** **** **** **** **** **** **** **** +18569 Shadowsmith_SightEclipsed **** **** **** **** **** **** **** **** +18570 Shadowsmith_ThoughtsShadow_RadialMaster **** **** **** **** **** **** **** **** +18571 Shadowsmith_ThoughtsShadow_Int **** **** **** **** **** **** **** **** +18572 Shadowsmith_ThoughtsShadow_Wis **** **** **** **** **** **** **** **** +18573 Shadowsmith_ThoughtsShadow_Cha **** **** **** **** **** **** **** **** +18574 TouchOfShadow **** **** **** **** **** **** **** **** +18575 ShroudOfShadow **** **** **** **** **** **** **** **** +18576 ShadowCraft **** **** **** **** **** **** **** **** +18577 ArmorOfShadow **** **** **** **** **** **** **** **** +18578 WidenShroud **** **** **** **** **** **** **** **** +18579 **Web_Enhancement** **** **** **** **** **** **** **** **** +18580 QuickerThanTheEye **** **** **** **** **** **** **** **** +18581 TrailOfHaze **** **** **** **** **** **** **** **** +18582 UmbralFist **** **** **** **** **** **** **** **** +18583 FearfulGloom **** **** **** **** **** **** **** **** +18584 SickeningShadows **** **** **** **** **** **** **** **** +18585 DeadlyShade_Absorb **** **** **** **** **** **** **** **** +18586 DeadlyShade_Deal **** **** **** **** **** **** **** **** +18587 GraspingShadows **** **** **** **** **** **** **** **** +18588 MenagerieOfDarkness **** **** **** **** **** **** **** **** +18589 BlackLabyrinth **** **** **** **** **** **** **** **** +18590 **** **** **** **** **** **** **** **** **** +18591 Shadowcaster_QuickerThanTheEye **** **** **** **** **** **** **** **** +18592 Shadowcaster_TrailOfHaze **** **** **** **** **** **** **** **** +18593 Shadowcaster_UmbralFist **** **** **** **** **** **** **** **** +18594 Shadowcaster_FearfulGloom **** **** **** **** **** **** **** **** +18595 Shadowcaster_SickeningShadows **** **** **** **** **** **** **** **** +18596 Shadowcaster_DeadlyShade_RadialMaster **** **** **** **** **** **** **** **** +18597 Shadowcaster_DeadlyShade_Absorb **** **** **** **** **** **** **** **** +18598 Shadowcaster_DeadlyShade_Deal **** **** **** **** **** **** **** **** +18599 Shadowcaster_GraspingShadows **** **** **** **** **** **** **** **** +18600 Shadowcaster_MenagerieOfDarkness **** **** **** **** **** **** **** **** +18601 Shadowcaster_BlackLabyrinth **** **** **** **** **** **** **** **** +18602 Shadowsmith_QuickerThanTheEye **** **** **** **** **** **** **** **** +18603 Shadowsmith_TrailOfHaze **** **** **** **** **** **** **** **** +18604 **** **** **** **** **** **** **** **** **** +18605 UmbralFist_RadialMaster **** **** **** **** **** **** **** **** +18606 UmbralFist_BullRush **** **** **** **** **** **** **** **** +18607 UmbralFist_Disarm **** **** **** **** **** **** **** **** +18608 UmbralFist_Trip **** **** **** **** **** **** **** **** +18609 **** **** **** **** **** **** **** **** **** +18610 **** **** **** **** **** **** **** **** **** +18611 **** **** **** **** **** **** **** **** **** +18612 **** **** **** **** **** **** **** **** **** +18613 **** **** **** **** **** **** **** **** **** +18614 **** **** **** **** **** **** **** **** **** +18615 **** **** **** **** **** **** **** **** **** +18616 **** **** **** **** **** **** **** **** **** +18617 **** **** **** **** **** **** **** **** **** +18618 **** **** **** **** **** **** **** **** **** +18619 **** **** **** **** **** **** **** **** **** +18620 **** **** **** **** **** **** **** **** **** +18621 **** **** **** **** **** **** **** **** **** +18622 **** **** **** **** **** **** **** **** **** +18623 **** **** **** **** **** **** **** **** **** +18624 **** **** **** **** **** **** **** **** **** +18625 **** **** **** **** **** **** **** **** **** +18626 **** **** **** **** **** **** **** **** **** +18627 **** **** **** **** **** **** **** **** **** +18628 **** **** **** **** **** **** **** **** **** +18629 **** **** **** **** **** **** **** **** **** +18630 **** **** **** **** **** **** **** **** **** +18631 **** **** **** **** **** **** **** **** **** +18632 OpenSoulChakra **** **** **** **** **** **** **** **** +18633 Meldshield_Invest **** **** **** **** **** **** **** **** +18634 Meldshield **** **** **** **** **** **** **** **** +18635 DispellingOrb_Invest **** **** **** **** **** **** **** **** +18636 DispellingOrb **** **** **** **** **** **** **** **** +18637 MageShackles_Invest **** **** **** **** **** **** **** **** +18638 MageShackles **** **** **** **** **** **** **** **** +18639 Abrogation_Invest **** **** **** **** **** **** **** **** +18640 Abrogation **** **** **** **** **** **** **** **** +18641 SpiritFlay_Invest **** **** **** **** **** **** **** **** +18642 SpiritFlay **** **** **** **** **** **** **** **** +18643 Integument_Invest **** **** **** **** **** **** **** **** +18644 Integument **** **** **** **** **** **** **** **** +18645 Blademeld_Rebind **** **** **** **** **** **** **** **** +18646 Blademeld_Throat_Shout **** **** **** **** **** **** **** **** +18647 BladeMeld_Crown **** **** **** **** **** **** **** **** +18648 BladeMeld_Feet **** **** **** **** **** **** **** **** +18649 BladeMeld_Hands **** **** **** **** **** **** **** **** +18650 BladeMeld_Arms **** **** **** **** **** **** **** **** +18651 BladeMeld_Brow **** **** **** **** **** **** **** **** +18652 BladeMeld_Shoulders **** **** **** **** **** **** **** **** +18653 BladeMeld_Throat **** **** **** **** **** **** **** **** +18654 BladeMeld_Waist **** **** **** **** **** **** **** **** +18655 BladeMeld_Heart **** **** **** **** **** **** **** **** +18656 BladeMeld_Soul **** **** **** **** **** **** **** **** +18657 Necrocarnate_Harvest **** **** **** **** **** **** **** **** +18658 Necrocarnate_Soulshield **** **** **** **** **** **** **** **** +18659 Incandescent_Aura_Yes_Its_Blank **** **** **** **** **** **** **** **** +18660 Incandescent_Transcendence **** **** **** **** **** **** **** **** +18661 Incandescent_Aura_Invest **** **** **** **** **** **** **** **** +18662 Incandescent_Ray_Invest **** **** **** **** **** **** **** **** +18663 Incandescent_Ray **** **** **** **** **** **** **** **** +18664 Incandescent_Overload **** **** **** **** **** **** **** **** +18665 Incandescent_Countenance_Invest **** **** **** **** **** **** **** **** +18666 Incandescent_Countenance **** **** **** **** **** **** **** **** +18667 Incandescent_Heal_Invest **** **** **** **** **** **** **** **** +18668 Incandescent_Heal **** **** **** **** **** **** **** **** +18669 Incandescent_Strike_Invest **** **** **** **** **** **** **** **** +18670 Incandescent_Strike **** **** **** **** **** **** **** **** +18671 PRC_Attack **** **** **** **** **** **** **** **** +18672 Umbral_KissShadows_Invest **** **** **** **** **** **** **** **** +18673 Umbral_KissShadows **** **** **** **** **** **** **** **** +18674 Umbral_Soulchilling_Invest **** **** **** **** **** **** **** **** +18675 Umbral_Soulchilling **** **** **** **** **** **** **** **** +18676 Umbral_SightEyeless_Invest **** **** **** **** **** **** **** **** +18677 Umbral_SightEyeless **** **** **** **** **** **** **** **** +18678 Umbral_EmbraceShadow_Invest **** **** **** **** **** **** **** **** +18679 Umbral_EmbraceShadow **** **** **** **** **** **** **** **** +18680 Umbral_StepBodiless_Invest **** **** **** **** **** **** **** **** +18681 Umbral_StepBodiless **** **** **** **** **** **** **** **** +18682 Ironsoul_WeaponBond_Invest **** **** **** **** **** **** **** **** +18683 Ironsoul_WeaponBond **** **** **** **** **** **** **** **** +18684 Ironsoul_ArmorBond_Invest **** **** **** **** **** **** **** **** +18685 Ironsoul_ArmorBond **** **** **** **** **** **** **** **** +18686 Ironsoul_ShieldBond_Invest **** **** **** **** **** **** **** **** +18687 Ironsoul_ShieldBond **** **** **** **** **** **** **** **** +18688 Soulcaster_Distill **** **** **** **** **** **** **** **** +18689 SapphireHierarch_Smite **** **** **** **** **** **** **** **** +18690 Spinemeld_SpineEnhancement_Invest **** **** **** **** **** **** **** **** +18691 Spinemeld_SpineEnhancement **** **** **** **** **** **** **** **** +18692 Totemist_ReshapeTotemSoulmeld **** **** **** **** **** **** **** **** +18693 Totemist_TotemEmbodiment **** **** **** **** **** **** **** **** +18694 Soulborn_ShareDefence **** **** **** **** **** **** **** **** +18695 Soulborn_Smite **** **** **** **** **** **** **** **** +18696 Incarnate_PerfectMeldshaper **** **** **** **** **** **** **** **** +18697 Incarnate_RapidMeldshaping **** **** **** **** **** **** **** **** +18698 Incarnate_IncarnumRadiance **** **** **** **** **** **** **** **** +18699 Incarnate_DetectOpposition **** **** **** **** **** **** **** **** +18700 **INCARNUM** **** **** **** **** **** **** **** **** +18701 AcrobatBoots **** **** **** **** **** **** **** **** +18702 AdamantPauldrons **** **** **** **** **** **** **** **** +18703 CrystalHelm **** **** **** **** **** **** **** **** +18704 AnkhegBreastplate **** **** **** **** **** **** **** **** +18705 ApparitionRibbon **** **** **** **** **** **** **** **** +18706 ArcaneFocus **** **** **** **** **** **** **** **** +18707 ArmguardsofDisruption **** **** **** **** **** **** **** **** +18708 BasiliskMask **** **** **** **** **** **** **** **** +18709 BeastTamerCirclet **** **** **** **** **** **** **** **** +18710 BehirGorget **** **** **** **** **** **** **** **** +18711 BlinkShirt **** **** **** **** **** **** **** **** +18712 Bloodtalons **** **** **** **** **** **** **** **** +18713 BloodwarGauntlets **** **** **** **** **** **** **** **** +18714 BluesteelBracers **** **** **** **** **** **** **** **** +18715 BrassMane **** **** **** **** **** **** **** **** +18716 CeruleanSandals **** **** **** **** **** **** **** **** +18717 DiademofPurelight **** **** **** **** **** **** **** **** +18718 DisenchanterMask **** **** **** **** **** **** **** **** +18719 DisplacerMantle **** **** **** **** **** **** **** **** +18720 DissolvingSpittle **** **** **** **** **** **** **** **** +18721 DreadCarapace **** **** **** **** **** **** **** **** +18722 EnigmaHelm **** **** **** **** **** **** **** **** +18723 FearsomeMask **** **** **** **** **** **** **** **** +18724 FellmistRobe **** **** **** **** **** **** **** **** +18725 FlameCincture **** **** **** **** **** **** **** **** +18726 FrostHelm **** **** **** **** **** **** **** **** +18727 GirallonArms **** **** **** **** **** **** **** **** +18728 GlovesofthePoisonedSoul **** **** **** **** **** **** **** **** +18729 GorgonMask **** **** **** **** **** **** **** **** +18730 GreatRaptorMask **** **** **** **** **** **** **** **** +18731 HeartofFire **** **** **** **** **** **** **** **** +18732 HuntersCirclet **** **** **** **** **** **** **** **** +18733 IllusionVeil **** **** **** **** **** **** **** **** +18734 ImpulseBoots **** **** **** **** **** **** **** **** +18735 IncarnateAvatar **** **** **** **** **** **** **** **** +18736 IncarnateWeapon **** **** **** **** **** **** **** **** +18737 KeeneyeLenses **** **** **** **** **** **** **** **** +18738 KrakenMantle **** **** **** **** **** **** **** **** +18739 KrensharMask **** **** **** **** **** **** **** **** +18740 KruthikClaws **** **** **** **** **** **** **** **** +18741 LamiaBelt **** **** **** **** **** **** **** **** +18742 LammasuMantle **** **** **** **** **** **** **** **** +18743 LandsharkBoots **** **** **** **** **** **** **** **** +18744 LifebondVestments **** **** **** **** **** **** **** **** +18745 LightningGauntlets **** **** **** **** **** **** **** **** +18746 LuckyDice **** **** **** **** **** **** **** **** +18747 MagesSpectacles **** **** **** **** **** **** **** **** +18748 ManticoreBelt **** **** **** **** **** **** **** **** +18749 MantleofFlame **** **** **** **** **** **** **** **** +18750 MaulingGauntlets **** **** **** **** **** **** **** **** +18751 NecrocarnumCirclet **** **** **** **** **** **** **** **** +18752 NecrocarnumMantle **** **** **** **** **** **** **** **** +18753 NecrocarnumShroud **** **** **** **** **** **** **** **** +18754 NecrocarnumTouch **** **** **** **** **** **** **** **** +18755 NecrocarnumVestments **** **** **** **** **** **** **** **** +18756 NecrocarnumWeapon **** **** **** **** **** **** **** **** +18757 PauldronsofHealth **** **** **** **** **** **** **** **** +18758 PegasusCloak **** **** **** **** **** **** **** **** +18759 PhaseCloak **** **** **** **** **** **** **** **** +18760 PhoenixBelt **** **** **** **** **** **** **** **** +18761 PlanarChasuble **** **** **** **** **** **** **** **** +18762 PlanarWard **** **** **** **** **** **** **** **** +18763 Rageclaws **** **** **** **** **** **** **** **** +18764 RidingBracers **** **** **** **** **** **** **** **** +18765 SailorsBracers **** **** **** **** **** **** **** **** +18766 ShadowMantle **** **** **** **** **** **** **** **** +18767 SheduCrown **** **** **** **** **** **** **** **** +18768 SightingGloves **** **** **** **** **** **** **** **** +18769 SilvertongueMask **** **** **** **** **** **** **** **** +18770 SoulsparkFamiliar **** **** **** **** **** **** **** **** +18771 SoulspeakerCirclet **** **** **** **** **** **** **** **** +18772 SpellwardShirt **** **** **** **** **** **** **** **** +18773 SphinxClaws **** **** **** **** **** **** **** **** +18774 StrongheartVest **** **** **** **** **** **** **** **** +18775 TheftGloves **** **** **** **** **** **** **** **** +18776 TherapeuticMantle **** **** **** **** **** **** **** **** +18777 ThreefoldMaskoftheChimera **** **** **** **** **** **** **** **** +18778 ThunderstepBoots **** **** **** **** **** **** **** **** +18779 TotemAvatar **** **** **** **** **** **** **** **** +18780 TruthseekerGoggles **** **** **** **** **** **** **** **** +18781 UnicornHorn **** **** **** **** **** **** **** **** +18782 UrskanGreaves **** **** **** **** **** **** **** **** +18783 VitalityBelt **** **** **** **** **** **** **** **** +18784 WindCloak **** **** **** **** **** **** **** **** +18785 WinterMask **** **** **** **** **** **** **** **** +18786 WorgPelt **** **** **** **** **** **** **** **** +18787 WormtailBelt **** **** **** **** **** **** **** **** +18788 YrthakMask **** **** **** **** **** **** **** **** +18789 AstralVambraces **** **** **** **** **** **** **** **** +18790 CharmingVeil **** **** **** **** **** **** **** **** +18791 PsionsEyes **** **** **** **** **** **** **** **** +18792 PsionKillerMask **** **** **** **** **** **** **** **** +18793 PsychicFocus **** **** **** **** **** **** **** **** +18794 ClawsOfTheWyrm **** **** **** **** **** **** **** **** +18795 DragonMantle **** **** **** **** **** **** **** **** +18796 DragonTail **** **** **** **** **** **** **** **** +18797 DragonfireMask **** **** **** **** **** **** **** **** +18798 ElderSpirit **** **** **** **** **** **** **** **** +18799 **** **** **** **** **** **** **** **** **** +18800 AcrobatBoots **** **** **** **** **** **** **** **** +18801 AdamantPauldrons **** **** **** **** **** **** **** **** +18802 CrystalHelm **** **** **** **** **** **** **** **** +18803 AnkhegBreastplate **** **** **** **** **** **** **** **** +18804 ApparitionRibbon **** **** **** **** **** **** **** **** +18805 ArcaneFocus **** **** **** **** **** **** **** **** +18806 ArmguardsofDisruption **** **** **** **** **** **** **** **** +18807 BasiliskMask **** **** **** **** **** **** **** **** +18808 BeastTamerCirclet **** **** **** **** **** **** **** **** +18809 BehirGorget **** **** **** **** **** **** **** **** +18810 BlinkShirt **** **** **** **** **** **** **** **** +18811 Bloodtalons **** **** **** **** **** **** **** **** +18812 BloodwarGauntlets **** **** **** **** **** **** **** **** +18813 BluesteelBracers **** **** **** **** **** **** **** **** +18814 BrassMane **** **** **** **** **** **** **** **** +18815 CeruleanSandals **** **** **** **** **** **** **** **** +18816 DiademofPurelight **** **** **** **** **** **** **** **** +18817 DisenchanterMask **** **** **** **** **** **** **** **** +18818 DisplacerMantle **** **** **** **** **** **** **** **** +18819 DissolvingSpittle **** **** **** **** **** **** **** **** +18820 DreadCarapace **** **** **** **** **** **** **** **** +18821 EnigmaHelm **** **** **** **** **** **** **** **** +18822 FearsomeMask **** **** **** **** **** **** **** **** +18823 FellmistRobe **** **** **** **** **** **** **** **** +18824 FlameCincture **** **** **** **** **** **** **** **** +18825 FrostHelm **** **** **** **** **** **** **** **** +18826 GirallonArms **** **** **** **** **** **** **** **** +18827 GlovesofthePoisonedSoul **** **** **** **** **** **** **** **** +18828 GorgonMask **** **** **** **** **** **** **** **** +18829 GreatRaptorMask **** **** **** **** **** **** **** **** +18830 HeartofFire **** **** **** **** **** **** **** **** +18831 HuntersCirclet **** **** **** **** **** **** **** **** +18832 IllusionVeil **** **** **** **** **** **** **** **** +18833 ImpulseBoots **** **** **** **** **** **** **** **** +18834 IncarnateAvatar **** **** **** **** **** **** **** **** +18835 IncarnateWeapon **** **** **** **** **** **** **** **** +18836 KeeneyeLenses **** **** **** **** **** **** **** **** +18837 KrakenMantle **** **** **** **** **** **** **** **** +18838 KrensharMask **** **** **** **** **** **** **** **** +18839 KruthikClaws **** **** **** **** **** **** **** **** +18840 LamiaBelt **** **** **** **** **** **** **** **** +18841 LammasuMantle **** **** **** **** **** **** **** **** +18842 LandsharkBoots **** **** **** **** **** **** **** **** +18843 LifebondVestments **** **** **** **** **** **** **** **** +18844 LightningGauntlets **** **** **** **** **** **** **** **** +18845 LuckyDice **** **** **** **** **** **** **** **** +18846 MagesSpectacles **** **** **** **** **** **** **** **** +18847 ManticoreBelt **** **** **** **** **** **** **** **** +18848 MantleofFlame **** **** **** **** **** **** **** **** +18849 MaulingGauntlets **** **** **** **** **** **** **** **** +18850 NecrocarnumCirclet **** **** **** **** **** **** **** **** +18851 NecrocarnumMantle **** **** **** **** **** **** **** **** +18852 NecrocarnumShroud **** **** **** **** **** **** **** **** +18853 NecrocarnumTouch **** **** **** **** **** **** **** **** +18854 NecrocarnumVestments **** **** **** **** **** **** **** **** +18855 NecrocarnumWeapon **** **** **** **** **** **** **** **** +18856 PauldronsofHealth **** **** **** **** **** **** **** **** +18857 PegasusCloak **** **** **** **** **** **** **** **** +18858 PhaseCloak **** **** **** **** **** **** **** **** +18859 PhoenixBelt **** **** **** **** **** **** **** **** +18860 PlanarChasuble **** **** **** **** **** **** **** **** +18861 PlanarWard **** **** **** **** **** **** **** **** +18862 Rageclaws **** **** **** **** **** **** **** **** +18863 RidingBracers **** **** **** **** **** **** **** **** +18864 SailorsBracers **** **** **** **** **** **** **** **** +18865 ShadowMantle **** **** **** **** **** **** **** **** +18866 SheduCrown **** **** **** **** **** **** **** **** +18867 SightingGloves **** **** **** **** **** **** **** **** +18868 SilvertongueMask **** **** **** **** **** **** **** **** +18869 SoulsparkFamiliar **** **** **** **** **** **** **** **** +18870 SoulspeakerCirclet **** **** **** **** **** **** **** **** +18871 SpellwardShirt **** **** **** **** **** **** **** **** +18872 SphinxClaws **** **** **** **** **** **** **** **** +18873 StrongheartVest **** **** **** **** **** **** **** **** +18874 TheftGloves **** **** **** **** **** **** **** **** +18875 TherapeuticMantle **** **** **** **** **** **** **** **** +18876 ThreefoldMaskoftheChimera **** **** **** **** **** **** **** **** +18877 ThunderstepBoots **** **** **** **** **** **** **** **** +18878 TotemAvatar **** **** **** **** **** **** **** **** +18879 TruthseekerGoggles **** **** **** **** **** **** **** **** +18880 UnicornHorn **** **** **** **** **** **** **** **** +18881 UrskanGreaves **** **** **** **** **** **** **** **** +18882 VitalityBelt **** **** **** **** **** **** **** **** +18883 WindCloak **** **** **** **** **** **** **** **** +18884 WinterMask **** **** **** **** **** **** **** **** +18885 WorgPelt **** **** **** **** **** **** **** **** +18886 WormtailBelt **** **** **** **** **** **** **** **** +18887 YrthakMask **** **** **** **** **** **** **** **** +18888 AstralVambraces **** **** **** **** **** **** **** **** +18889 CharmingVeil **** **** **** **** **** **** **** **** +18890 PsionsEyes **** **** **** **** **** **** **** **** +18891 PsionKillerMask **** **** **** **** **** **** **** **** +18892 PsychicFocus **** **** **** **** **** **** **** **** +18893 ClawsOfTheWyrm **** **** **** **** **** **** **** **** +18894 DragonMantle **** **** **** **** **** **** **** **** +18895 DragonTail **** **** **** **** **** **** **** **** +18896 DragonfireMask **** **** **** **** **** **** **** **** +18897 ElderSpirit **** **** **** **** **** **** **** **** +18898 **** **** **** **** **** **** **** **** **** +18899 **** **** **** **** **** **** **** **** **** +18900 InvestEssentiaConversation **** **** **** **** **** **** **** **** +18901 AnkhegBreastplateThroatBind **** **** **** **** **** **** **** **** +18902 ApparitionRibbonThroatBind **** **** **** **** **** **** **** **** +18903 ArmguardsDisruptionArmsBind **** **** **** **** **** **** **** **** +18904 BasiliskMaskTotemBind **** **** **** **** **** **** **** **** +18905 BeastTamerCircletCrownBind **** **** **** **** **** **** **** **** +18906 BeastTamerCircletTotemBind **** **** **** **** **** **** **** **** +18907 BehirGorgetThroatBind **** **** **** **** **** **** **** **** +18908 BlinkShirtDimensionDoor_St **** **** **** **** **** **** **** **** +18909 BlinkShirtHeartBind **** **** **** **** **** **** **** **** +18910 BlinkShirtDimensionDoor_Mv **** **** **** **** **** **** **** **** +18911 BloodwarGauntletsArmBind **** **** **** **** **** **** **** **** +18912 BrassManeThroatBind **** **** **** **** **** **** **** **** +18913 CeruleanSandalsFeetBind **** **** **** **** **** **** **** **** +18914 DisenchanterMaskDetectMagic **** **** **** **** **** **** **** **** +18915 DisenchanterMaskTotemBind **** **** **** **** **** **** **** **** +18916 DisplacerMantleTotemBind **** **** **** **** **** **** **** **** +18917 DissolvingSpittleSpitAcid **** **** **** **** **** **** **** **** +18918 DreadCarapaceFootBind **** **** **** **** **** **** **** **** +18919 FlameCinctureWaistBind **** **** **** **** **** **** **** **** +18920 FrostHelmCrownBind **** **** **** **** **** **** **** **** +18921 FrostHelmTotemBind **** **** **** **** **** **** **** **** +18922 GlovesOfThePoisonedHandAbilityDamage **** **** **** **** **** **** **** **** +18923 GorgonMaskThroatBind **** **** **** **** **** **** **** **** +18924 GorgonMaskTotemBind **** **** **** **** **** **** **** **** +18925 IncarnateWeaponArmsBind **** **** **** **** **** **** **** **** +18926 KrensharMaskTotemBind **** **** **** **** **** **** **** **** +18927 LammasuMantleTotemBind **** **** **** **** **** **** **** **** +18928 LandsharkBootsFeetBind **** **** **** **** **** **** **** **** +18929 LandsharkBootsTotemBind **** **** **** **** **** **** **** **** +18930 LifebondVestmentsHeal **** **** **** **** **** **** **** **** +18931 LifebondVestmentsArmsBind **** **** **** **** **** **** **** **** +18932 LightningGauntletsZap **** **** **** **** **** **** **** **** +18933 LightningGauntletsHandsBind **** **** **** **** **** **** **** **** +18934 LuckyDice_RadialMaster **** **** **** **** **** **** **** **** +18935 LuckyDice_AttackDamage **** **** **** **** **** **** **** **** +18936 LuckyDice_SavingThrows **** **** **** **** **** **** **** **** +18937 LuckyDice_SkillAbilities **** **** **** **** **** **** **** **** +18938 MagesSpectaclesBrowBind **** **** **** **** **** **** **** **** +18939 ManticoreBeltTotemBind **** **** **** **** **** **** **** **** +18940 MantleOfFlameShouldersBind **** **** **** **** **** **** **** **** +18941 PhoenixBeltTotemBind **** **** **** **** **** **** **** **** +18942 PlanarChasubleSoulBind **** **** **** **** **** **** **** **** +18943 ShadowMantleShouldersBind **** **** **** **** **** **** **** **** +18944 SheduCrownHeartBind **** **** **** **** **** **** **** **** +18945 SilvertongueMaskThroatBind **** **** **** **** **** **** **** **** +18946 UnicornHornBrowBind **** **** **** **** **** **** **** **** +18947 WinterMaskColdTouch **** **** **** **** **** **** **** **** +18948 WinterMaskThroatBind **** **** **** **** **** **** **** **** +18949 WormtailBeltTotemBind **** **** **** **** **** **** **** **** +18950 YrthakMaskBrowBind **** **** **** **** **** **** **** **** +18951 YrthakMaskTotemBind **** **** **** **** **** **** **** **** +18952 NecrocarnumCircletCrownBind **** **** **** **** **** **** **** **** +18953 NecrocarnumShroudSoulBind **** **** **** **** **** **** **** **** +18954 NecrocarnumTouchEssentia **** **** **** **** **** **** **** **** +18955 NecrocarnumTouchArmsBind **** **** **** **** **** **** **** **** +18956 SoulsparkFamiliar_Attack **** **** **** **** **** **** **** **** +18957 SoulsparkFamiliar_Essentia **** **** **** **** **** **** **** **** +18958 PsionsEyesBrowBind **** **** **** **** **** **** **** **** +18959 PsionKillerMaskDetectMagic **** **** **** **** **** **** **** **** +18960 PsionKillerMaskTotemBind **** **** **** **** **** **** **** **** +18961 DragonTailSlam **** **** **** **** **** **** **** **** +18962 DragonTailTotemBind **** **** **** **** **** **** **** **** +18963 DragonfireMaskThroatBind **** **** **** **** **** **** **** **** +18964 DragonfireMaskTotemBind **** **** **** **** **** **** **** **** +18965 **** **** **** **** **** **** **** **** **** +18966 **** **** **** **** **** **** **** **** **** +18967 **** **** **** **** **** **** **** **** **** +18968 **** **** **** **** **** **** **** **** **** +18969 **** **** **** **** **** **** **** **** **** +18970 HealingSoul **** **** **** **** **** **** **** **** +18971 MidnightAugmentation **** **** **** **** **** **** **** **** +18972 PsycarnumBlade **** **** **** **** **** **** **** **** +18973 DusklingSpeed **** **** **** **** **** **** **** **** +18974 DivineSoultouch **** **** **** **** **** **** **** **** +18975 PsycarnumInfusion **** **** **** **** **** **** **** **** +18976 Epic_RapidMeldshaping **** **** **** **** **** **** **** **** +18977 Epic_RebindSoulmeld_Crown **** **** **** **** **** **** **** **** +18978 Epic_RebindSoulmeld_Feet **** **** **** **** **** **** **** **** +18979 Epic_RebindSoulmeld_Hands **** **** **** **** **** **** **** **** +18980 Epic_RebindSoulmeld_Arms **** **** **** **** **** **** **** **** +18981 Epic_RebindSoulmeld_Brow **** **** **** **** **** **** **** **** +18982 Epic_RebindSoulmeld_Shoulders **** **** **** **** **** **** **** **** +18983 Epic_RebindSoulmeld_Throat **** **** **** **** **** **** **** **** +18984 Epic_RebindSoulmeld_Waist **** **** **** **** **** **** **** **** +18985 Epic_RebindSoulmeld_Heart **** **** **** **** **** **** **** **** +18986 Epic_RebindSoulmeld_Soul **** **** **** **** **** **** **** **** +18987 Epic_RebindSoulmeld_Totem **** **** **** **** **** **** **** **** +18988 **** **** **** **** **** **** **** **** **** +18989 **** **** **** **** **** **** **** **** **** +18990 **** **** **** **** **** **** **** **** **** +18991 **** **** **** **** **** **** **** **** **** +18992 **** **** **** **** **** **** **** **** **** +18993 **** **** **** **** **** **** **** **** **** +18994 **** **** **** **** **** **** **** **** **** +18995 **** **** **** **** **** **** **** **** **** +18996 **** **** **** **** **** **** **** **** **** +18997 **** **** **** **** **** **** **** **** **** +18998 **** **** **** **** **** **** **** **** **** +18999 **** **** **** **** **** **** **** **** **** +19000 ####END_OF_SHADOW_MAGIC_RESERVE **** **** **** **** **** **** **** **** +19001 Spell_Rage **** **** **** **** **** **** **** **** +19002 Warrior_Cry **** **** **** **** **** **** **** **** +19003 Spell_Fury **** **** **** **** **** **** **** **** +19004 DK_Tactics **** **** **** **** **** **** **** **** +19005 DK_Puissance **** **** **** **** **** **** **** **** +19006 DK_Foe **** **** **** **** **** **** **** **** +19007 DK_DreadSecret **** **** **** **** **** **** **** **** +19008 DK_Foreknowledge **** **** **** **** **** **** **** **** +19009 Archivist_LearnSpell **** **** **** **** **** **** **** **** +19010 Witch_LearnSpell **** **** **** **** **** **** **** **** +19011 ArkamoiStrengthFromMagic **** **** **** **** **** **** **** **** +19012 LashemoiLesserStrengthFromPain **** **** **** **** **** **** **** **** +19013 TurlemoiStrengthFromPain **** **** **** **** **** **** **** **** +19014 HadrimoiSpeedFromPain **** **** **** **** **** **** **** **** +19015 GlouraUnearthlyGrace **** **** **** **** **** **** **** **** +19016 **** **** **** **** **** **** **** **** **** +19017 **** **** **** **** **** **** **** **** **** +19018 **** **** **** **** **** **** **** **** **** +19019 ####START_OF_BINDING **** **** **** **** **** **** **** **** +19020 Amon **** **** **** **** **** **** **** **** +19021 Aym **** **** **** **** **** **** **** **** +19022 Leraje **** **** **** **** **** **** **** **** +19023 Naberius **** **** **** **** **** **** **** **** +19024 Ronove **** **** **** **** **** **** **** **** +19025 DahlverNar **** **** **** **** **** **** **** **** +19026 Haagenti **** **** **** **** **** **** **** **** +19027 Malphas **** **** **** **** **** **** **** **** +19028 Savnok **** **** **** **** **** **** **** **** +19029 Andromalius **** **** **** **** **** **** **** **** +19030 Focalor **** **** **** **** **** **** **** **** +19031 Karsus **** **** **** **** **** **** **** **** +19032 Paimon **** **** **** **** **** **** **** **** +19033 Agares **** **** **** **** **** **** **** **** +19034 Andras **** **** **** **** **** **** **** **** +19035 Buer **** **** **** **** **** **** **** **** +19036 Eurynome **** **** **** **** **** **** **** **** +19037 Tenebrous **** **** **** **** **** **** **** **** +19038 Arete **** **** **** **** **** **** **** **** +19039 Astaroth **** **** **** **** **** **** **** **** +19040 Acererak **** **** **** **** **** **** **** **** +19041 Balam **** **** **** **** **** **** **** **** +19042 Dantalion **** **** **** **** **** **** **** **** +19043 Geryon **** **** **** **** **** **** **** **** +19044 Otiax **** **** **** **** **** **** **** **** +19045 Chupoclops **** **** **** **** **** **** **** **** +19046 Haures **** **** **** **** **** **** **** **** +19047 Ipos **** **** **** **** **** **** **** **** +19048 Shax **** **** **** **** **** **** **** **** +19049 Zagan **** **** **** **** **** **** **** **** +19050 Vanus **** **** **** **** **** **** **** **** +19051 TheTriad **** **** **** **** **** **** **** **** +19052 Desharis **** **** **** **** **** **** **** **** +19053 Zceryll **** **** **** **** **** **** **** **** +19054 Eligor **** **** **** **** **** **** **** **** +19055 Marchosias **** **** **** **** **** **** **** **** +19056 Ashardalon **** **** **** **** **** **** **** **** +19057 Halphax **** **** **** **** **** **** **** **** +19058 Orthos **** **** **** **** **** **** **** **** +19059 Abysm **** **** **** **** **** **** **** **** +19060 **** **** **** **** **** **** **** **** **** +19061 **** **** **** **** **** **** **** **** **** +19062 **** **** **** **** **** **** **** **** **** +19063 **** **** **** **** **** **** **** **** **** +19064 **** **** **** **** **** **** **** **** **** +19065 **** **** **** **** **** **** **** **** **** +19066 **** **** **** **** **** **** **** **** **** +19067 **** **** **** **** **** **** **** **** **** +19068 **** **** **** **** **** **** **** **** **** +19069 **** **** **** **** **** **** **** **** **** +19070 AmonFireBreath **** **** **** **** **** **** **** **** +19071 AymHaloOfFire **** **** **** **** **** **** **** **** +19072 LerajeRicochet **** **** **** **** **** **** **** **** +19073 NaberiusDisguise_Self_Radial_Master **** **** **** **** **** **** **** **** +19074 NaberiusDisguise_Self_Learn **** **** **** **** **** **** **** **** +19075 NaberiusDisguise_Self_Options **** **** **** **** **** **** **** **** +19076 NaberiusDisguise_Self_QS1 **** **** **** **** **** **** **** **** +19077 NaberiusDisguise_Self_QS2 **** **** **** **** **** **** **** **** +19078 NaberiusDisguise_Self_QS3 **** **** **** **** **** **** **** **** +19079 NaberiusCommand_RadialMaster **** **** **** **** **** **** **** **** +19080 NaberiusCommand_Approach **** **** **** **** **** **** **** **** +19081 NaberiusCommand_Drop **** **** **** **** **** **** **** **** +19082 NaberiusCommand_Fall **** **** **** **** **** **** **** **** +19083 NaberiusCommand_Flee **** **** **** **** **** **** **** **** +19084 NaberiusCommand_Halt **** **** **** **** **** **** **** **** +19085 RonoveFar_Hand **** **** **** **** **** **** **** **** +19086 RonoveBullrush **** **** **** **** **** **** **** **** +19087 DahlverNarMaddeningMoan **** **** **** **** **** **** **** **** +19088 DahlverNarSharePainForced **** **** **** **** **** **** **** **** +19089 HaagentiConfusingTouch **** **** **** **** **** **** **** **** +19090 MalphasArcaneEye **** **** **** **** **** **** **** **** +19091 MalphasInvisibility **** **** **** **** **** **** **** **** +19092 SavnokCallArmor **** **** **** **** **** **** **** **** +19093 SavnokMoveAlly **** **** **** **** **** **** **** **** +19094 AndromaliusTashas_Hideous_Laughter **** **** **** **** **** **** **** **** +19095 AndromaliusLocateObject **** **** **** **** **** **** **** **** +19096 AndromaliusSee_Invisibility **** **** **** **** **** **** **** **** +19097 FocalorAuraSadness **** **** **** **** **** **** **** **** +19098 FocalorLightningStrike **** **** **** **** **** **** **** **** +19099 FocalorBreath **** **** **** **** **** **** **** **** +19100 KarsusSenses **** **** **** **** **** **** **** **** +19101 KarsusTouch **** **** **** **** **** **** **** **** +19102 PaimonDanceOfDeath **** **** **** **** **** **** **** **** +19103 AgaresEarthshakingStep **** **** **** **** **** **** **** **** +19104 AgaresElementalCompanion **** **** **** **** **** **** **** **** +19105 AndrasSmite **** **** **** **** **** **** **** **** +19106 AndrasSowDiscord **** **** **** **** **** **** **** **** +19107 AndrasMount **** **** **** **** **** **** **** **** +19108 BuerHealingGift **** **** **** **** **** **** **** **** +19109 TenebrousDeeperDarkness **** **** **** **** **** **** **** **** +19110 TenebrousTouchVoid **** **** **** **** **** **** **** **** +19111 TenebrousTurnUndead **** **** **** **** **** **** **** **** +19112 TenebrousFlicker **** **** **** **** **** **** **** **** +19113 AcererakDetectUndead **** **** **** **** **** **** **** **** +19114 AcererakHideUndead **** **** **** **** **** **** **** **** +19115 AcererakParalyze **** **** **** **** **** **** **** **** +19116 BalamCunning **** **** **** **** **** **** **** **** +19117 BalamGlare **** **** **** **** **** **** **** **** +19118 DantalionAwe **** **** **** **** **** **** **** **** +19119 DantalionReadThoughts **** **** **** **** **** **** **** **** +19120 DantalionThoughtTravel **** **** **** **** **** **** **** **** +19121 GeryonAcidicGlare **** **** **** **** **** **** **** **** +19122 GeryonSwiftFlight **** **** **** **** **** **** **** **** +19123 OtiaxAirBlast **** **** **** **** **** **** **** **** +19124 OtiaxOpen **** **** **** **** **** **** **** **** +19125 OtiaxUnlock **** **** **** **** **** **** **** **** +19126 AreteResistance **** **** **** **** **** **** **** **** +19127 AstarothsBreath **** **** **** **** **** **** **** **** +19128 AstarothWord **** **** **** **** **** **** **** **** +19129 ChupoclopsAuraDespair **** **** **** **** **** **** **** **** +19130 ChupoclopsEthereal **** **** **** **** **** **** **** **** +19131 HauresMajorImage **** **** **** **** **** **** **** **** +19132 HauresPhantasmalKiller **** **** **** **** **** **** **** **** +19133 IposFlashInsight **** **** **** **** **** **** **** **** +19134 ShaxFreedomMovement **** **** **** **** **** **** **** **** +19135 ShaxStormStrike **** **** **** **** **** **** **** **** +19136 ZaganAversion **** **** **** **** **** **** **** **** +19137 VanusFreeAlly **** **** **** **** **** **** **** **** +19138 TheTriadSmite **** **** **** **** **** **** **** **** +19139 DesharisTeleport **** **** **** **** **** **** **** **** +19140 DesharisSmite **** **** **** **** **** **** **** **** +19141 DesharisAnimate **** **** **** **** **** **** **** **** +19142 ZceryllBoltsMadness **** **** **** **** **** **** **** **** +19143 ZceryllSummonAlien **** **** **** **** **** **** **** **** +19144 ZceryllTrueStrike **** **** **** **** **** **** **** **** +19145 EligorChromaticStrike_Radial_Master **** **** **** **** **** **** **** **** +19146 EligorChromaticStrike_Acid **** **** **** **** **** **** **** **** +19147 EligorChromaticStrike_Cold **** **** **** **** **** **** **** **** +19148 EligorChromaticStrike_Elec **** **** **** **** **** **** **** **** +19149 EligorChromaticStrike_Fire **** **** **** **** **** **** **** **** +19150 MarchosiasSmoke **** **** **** **** **** **** **** **** +19151 AshardalonFear **** **** **** **** **** **** **** **** +19152 AshardalonLocate **** **** **** **** **** **** **** **** +19153 HalphaxImprison **** **** **** **** **** **** **** **** +19154 HalphaxBarrier **** **** **** **** **** **** **** **** +19155 HalphaxMansion **** **** **** **** **** **** **** **** +19156 OrthosBreath **** **** **** **** **** **** **** **** +19157 **** **** **** **** **** **** **** **** **** +19158 **** **** **** **** **** **** **** **** **** +19159 **** **** **** **** **** **** **** **** **** +19160 **** **** **** **** **** **** **** **** **** +19161 **** **** **** **** **** **** **** **** **** +19162 **** **** **** **** **** **** **** **** **** +19163 **** **** **** **** **** **** **** **** **** +19164 **** **** **** **** **** **** **** **** **** +19165 **** **** **** **** **** **** **** **** **** +19166 **** **** **** **** **** **** **** **** **** +19167 **** **** **** **** **** **** **** **** **** +19168 **** **** **** **** **** **** **** **** **** +19169 **** **** **** **** **** **** **** **** **** +19170 BindVestige **** **** **** **** **** **** **** **** +19171 PactAugment **** **** **** **** **** **** **** **** +19172 ExpelVestige **** **** **** **** **** **** **** **** +19173 AnimaMageExploitVestige **** **** **** **** **** **** **** **** +19174 AnimaMageVestigeMetamagic **** **** **** **** **** **** **** **** +19175 AnimaMageVestigeCasting **** **** **** **** **** **** **** **** +19176 TenebrousRebuke **** **** **** **** **** **** **** **** +19177 TenebrousDestroyEmpowerUndead **** **** **** **** **** **** **** **** +19178 TenebrousUmbralBody **** **** **** **** **** **** **** **** +19179 TenebrousBlastVoid **** **** **** **** **** **** **** **** +19180 KnightOfTheSacredSealVestigesProtection **** **** **** **** **** **** **** **** +19181 KnightOfTheSacredSealVestigesPower **** **** **** **** **** **** **** **** +19182 KnightOfTheSacredSealVestigesSurge **** **** **** **** **** **** **** **** +19183 DantalionScholarship **** **** **** **** **** **** **** **** +19184 DantalionOverwhelmThoughts **** **** **** **** **** **** **** **** +19185 DantalionGlare **** **** **** **** **** **** **** **** +19186 **** **** **** **** **** **** **** **** **** +19187 **** **** **** **** **** **** **** **** **** +19188 **** **** **** **** **** **** **** **** **** +19189 **** **** **** **** **** **** **** **** **** +19190 **** **** **** **** **** **** **** **** **** +19191 **** **** **** **** **** **** **** **** **** +19192 **** **** **** **** **** **** **** **** **** +19193 **** **** **** **** **** **** **** **** **** +19194 **** **** **** **** **** **** **** **** **** +19195 **** **** **** **** **** **** **** **** **** +19196 **** **** **** **** **** **** **** **** **** +19197 **** **** **** **** **** **** **** **** **** +19198 **** **** **** **** **** **** **** **** **** +19199 **** **** **** **** **** **** **** **** **** +19200 **** **** **** **** **** **** **** **** **** +19201 **** **** **** **** **** **** **** **** **** +19202 **** **** **** **** **** **** **** **** **** +19203 **** **** **** **** **** **** **** **** **** +19204 **** **** **** **** **** **** **** **** **** +19205 **** **** **** **** **** **** **** **** **** +19206 **** **** **** **** **** **** **** **** **** +19207 **** **** **** **** **** **** **** **** **** +19208 **** **** **** **** **** **** **** **** **** +19209 **** **** **** **** **** **** **** **** **** +19210 **** **** **** **** **** **** **** **** **** +19211 **** **** **** **** **** **** **** **** **** +19212 **** **** **** **** **** **** **** **** **** +19213 **** **** **** **** **** **** **** **** **** +19214 **** **** **** **** **** **** **** **** **** +19215 **** **** **** **** **** **** **** **** **** +19216 **** **** **** **** **** **** **** **** **** +19217 **** **** **** **** **** **** **** **** **** +19218 **** **** **** **** **** **** **** **** **** +19219 **** **** **** **** **** **** **** **** **** +19220 **** **** **** **** **** **** **** **** **** +19221 **** **** **** **** **** **** **** **** **** +19222 **** **** **** **** **** **** **** **** **** +19223 **** **** **** **** **** **** **** **** **** +19224 **** **** **** **** **** **** **** **** **** +19225 **** **** **** **** **** **** **** **** **** +19226 **** **** **** **** **** **** **** **** **** +19227 **** **** **** **** **** **** **** **** **** +19228 **** **** **** **** **** **** **** **** **** +19229 **** **** **** **** **** **** **** **** **** +19230 **** **** **** **** **** **** **** **** **** +19231 **** **** **** **** **** **** **** **** **** +19232 **** **** **** **** **** **** **** **** **** +19233 **** **** **** **** **** **** **** **** **** +19234 **** **** **** **** **** **** **** **** **** +19235 **** **** **** **** **** **** **** **** **** +19236 **** **** **** **** **** **** **** **** **** +19237 **** **** **** **** **** **** **** **** **** +19238 **** **** **** **** **** **** **** **** **** +19239 **** **** **** **** **** **** **** **** **** +19240 **** **** **** **** **** **** **** **** **** +19241 **** **** **** **** **** **** **** **** **** +19242 **** **** **** **** **** **** **** **** **** +19243 **** **** **** **** **** **** **** **** **** +19244 **** **** **** **** **** **** **** **** **** +19245 **** **** **** **** **** **** **** **** **** +19246 **** **** **** **** **** **** **** **** **** +19247 **** **** **** **** **** **** **** **** **** +19248 **** **** **** **** **** **** **** **** **** +19249 **** **** **** **** **** **** **** **** **** +19250 **** **** **** **** **** **** **** **** **** +19251 **** **** **** **** **** **** **** **** **** +19252 **** **** **** **** **** **** **** **** **** +19253 **** **** **** **** **** **** **** **** **** +19254 **** **** **** **** **** **** **** **** **** +19255 **** **** **** **** **** **** **** **** **** +19256 **** **** **** **** **** **** **** **** **** +19257 **** **** **** **** **** **** **** **** **** +19258 **** **** **** **** **** **** **** **** **** +19259 **** **** **** **** **** **** **** **** **** +19260 **** **** **** **** **** **** **** **** **** +19261 **** **** **** **** **** **** **** **** **** +19262 **** **** **** **** **** **** **** **** **** +19263 **** **** **** **** **** **** **** **** **** +19264 **** **** **** **** **** **** **** **** **** +19265 **** **** **** **** **** **** **** **** **** +19266 **** **** **** **** **** **** **** **** **** +19267 **** **** **** **** **** **** **** **** **** +19268 **** **** **** **** **** **** **** **** **** +19269 **** **** **** **** **** **** **** **** **** +19270 **** **** **** **** **** **** **** **** **** +19271 **** **** **** **** **** **** **** **** **** +19272 **** **** **** **** **** **** **** **** **** +19273 **** **** **** **** **** **** **** **** **** +19274 **** **** **** **** **** **** **** **** **** +19275 **** **** **** **** **** **** **** **** **** +19276 **** **** **** **** **** **** **** **** **** +19277 Arcane_Boost_Attack_Bonus **** **** **** **** **** **** **** **** +19278 Arcane_Boost_Armor_Bones **** **** **** **** **** **** **** **** +19279 Arcane_Boost_Damage_Bonus **** **** **** **** **** **** **** **** +19280 Arcane_Boost_Elemental_Resistance **** **** **** **** **** **** **** **** +19281 Arcane_Boost_Save_Bonus **** **** **** **** **** **** **** **** +19282 DragonShaman_Fire_Cone **** **** **** **** **** **** **** **** +19283 DragonShaman_Frost_Cone **** **** **** **** **** **** **** **** +19284 DragonShaman_Electric_Cone **** **** **** **** **** **** **** **** +19285 DragonShaman_Acid_Cone **** **** **** **** **** **** **** **** +19286 Jade_Phoenix_SpellSelect **** **** **** **** **** **** **** **** +19287 Jade_Phoenix_SpellSelect_Convo **** **** **** **** **** **** **** **** +19288 Jade_Phoenix_SpellSelect_Quick1 **** **** **** **** **** **** **** **** +19289 Jade_Phoenix_SpellSelect_Quick2 **** **** **** **** **** **** **** **** +19290 Jade_Phoenix_SpellSelect_Quick3 **** **** **** **** **** **** **** **** +19291 Jade_Phoenix_SpellSelect_Quick4 **** **** **** **** **** **** **** **** +19292 Jade_Phoenix_ArcaneWrath **** **** **** **** **** **** **** **** +19293 Jade_Phoenix_RiteOfWaking **** **** **** **** **** **** **** **** +19294 **** **** **** **** **** **** **** **** **** +19295 **** **** **** **** **** **** **** **** **** +19296 Jade_Phoenix_MysticPhoenixStance **** **** **** **** **** **** **** **** +19297 Jade_Phoenix_MysticPhoenixStance_Unaugmented **** **** **** **** **** **** **** **** +19298 Jade_Phoenix_MysticPhoenixStance_Augmented **** **** **** **** **** **** **** **** +19299 Jade_Phoenix_EmpoweringStrike **** **** **** **** **** **** **** **** +19300 Jade_Phoenix_FirebirdStance **** **** **** **** **** **** **** **** +19301 Jade_Phoenix_FirebirdStance_Unaugmented **** **** **** **** **** **** **** **** +19302 Jade_Phoenix_FirebirdStance_Augmented **** **** **** **** **** **** **** **** +19303 Eternal_Blade_Blade_Guide_Dummy **** **** **** **** **** **** **** **** +19304 Jade_Phoenix_QuickeningStrike **** **** **** **** **** **** **** **** +19305 Jade_Phoenix_EmeraldImmolation **** **** **** **** **** **** **** **** +19306 MasterOfNineDualStance **** **** **** **** **** **** **** **** +19307 Eternal_Blade_Maneuver_Quickselects **** **** **** **** **** **** **** **** +19308 Eternal_Blade_Maneuver_Quickselects_Convo **** **** **** **** **** **** **** **** +19309 Eternal_Blade_Maneuver_Quickselects_Quick1 **** **** **** **** **** **** **** **** +19310 Eternal_Blade_Maneuver_Quickselects_Quick2 **** **** **** **** **** **** **** **** +19311 Eternal_Blade_Maneuver_Quickselects_Quick3 **** **** **** **** **** **** **** **** +19312 Eternal_Blade_Maneuver_Quickselects_Quick4 **** **** **** **** **** **** **** **** +19313 Eternal_Blade_Eternal_Training **** **** **** **** **** **** **** **** +19314 Eternal_Blade_Eternal_Training_Maneuver **** **** **** **** **** **** **** **** +19315 Eternal_Blade_Eternal_Training_Racial_Type **** **** **** **** **** **** **** **** +19316 Eternal_Blade_Guided_Strike **** **** **** **** **** **** **** **** +19317 Eternal_Blade_Defensive_Insight **** **** **** **** **** **** **** **** +19318 Eternal_Blade_Tactical_Insight **** **** **** **** **** **** **** **** +19319 Eternal_Blade_Island_In_Time **** **** **** **** **** **** **** **** +19320 ShadowSunNinjaTouchOfTheShadowSun **** **** **** **** **** **** **** **** +19321 ShadowSunNinjaFlameOfTheShadowSun **** **** **** **** **** **** **** **** +19322 ShadowSunNinjaFlameOfTheShadowSunAttack **** **** **** **** **** **** **** **** +19323 ShadowSunNinjaLightWithinDarkness **** **** **** **** **** **** **** **** +19324 ShadowSunNinjaDarknessWithinLight **** **** **** **** **** **** **** **** +19325 ShadowSunNinjaVoidOfTheShadowSun **** **** **** **** **** **** **** **** +19326 ShadowSunNinjaVoidOfTheShadowSunAttack **** **** **** **** **** **** **** **** +19327 ShadowSunNinjaChildOfShadowAnddLight **** **** **** **** **** **** **** **** +19328 ShadowSunNinjaBalanceOfLightAndDark **** **** **** **** **** **** **** **** +19329 ShadowSunNinjaBalanceOfLightAndDarkAttack **** **** **** **** **** **** **** **** +19330 RethDekala_VilefireBlast **** **** **** **** **** **** **** **** +19331 RethDekala_MartialSpirit **** **** **** **** **** **** **** **** +19332 RethDekala_ThicketOfBlades **** **** **** **** **** **** **** **** +19333 RethDekala_DauntingStrike **** **** **** **** **** **** **** **** +19334 RethDekala_DeathFromAbove **** **** **** **** **** **** **** **** +19335 RethDekala_DisarmingStrike **** **** **** **** **** **** **** **** +19336 RethDekala_EntanglingBlade **** **** **** **** **** **** **** **** +19337 RethDekala_WallOfBlades **** **** **** **** **** **** **** **** +19338 RethDekala_RecoverManeuver **** **** **** **** **** **** **** **** +19339 **** **** **** **** **** **** **** **** **** +19340 Shadow_Conjuration_Conversation **** **** **** **** **** **** **** **** +19341 PNP_SHADES **** **** **** **** **** **** **** **** +19342 PNP_SHADES_QS1 **** **** **** **** **** **** **** **** +19343 PNP_SHADES_QS2 **** **** **** **** **** **** **** **** +19344 PNP_SHADES_QS3 **** **** **** **** **** **** **** **** +19345 PNP_SHADES_QS4 **** **** **** **** **** **** **** **** +19346 PNP_SHADES_QS5 **** **** **** **** **** **** **** **** +19347 PNP_SHADOW_CONJURATION **** **** **** **** **** **** **** **** +19348 PNP_SHADOW_CONJURATION_QS1 **** **** **** **** **** **** **** **** +19349 PNP_SHADOW_CONJURATION_QS2 **** **** **** **** **** **** **** **** +19350 PNP_SHADOW_CONJURATION_QS3 **** **** **** **** **** **** **** **** +19351 PNP_SHADOW_CONJURATION_QS4 **** **** **** **** **** **** **** **** +19352 PNP_SHADOW_CONJURATION_QS5 **** **** **** **** **** **** **** **** +19353 PNP_GREATER_SHADOW_CONJURATION **** **** **** **** **** **** **** **** +19354 PNP_GREATER_SHADOW_CONJURATION_QS1 **** **** **** **** **** **** **** **** +19355 PNP_GREATER_SHADOW_CONJURATION_QS2 **** **** **** **** **** **** **** **** +19356 PNP_GREATER_SHADOW_CONJURATION_QS3 **** **** **** **** **** **** **** **** +19357 PNP_GREATER_SHADOW_CONJURATION_QS4 **** **** **** **** **** **** **** **** +19358 PNP_GREATER_SHADOW_CONJURATION_QS5 **** **** **** **** **** **** **** **** +19359 SPELL_MYSTIC_BACKLASH **** **** **** **** **** **** **** **** +19360 SPELL_ACIDIC_SPLATTER **** **** **** **** **** **** **** **** +19361 SPELL_FIERY_BURST **** **** **** **** **** **** **** **** +19362 SPELL_STORM_BOLT **** **** **** **** **** **** **** **** +19363 SPELL_WINTERS_BLAST **** **** **** **** **** **** **** **** +19364 SPELL_CLAP_OF_THUNDER **** **** **** **** **** **** **** **** +19365 SPELL_SICKENING_GRASP **** **** **** **** **** **** **** **** +19366 SPELL_TOUCH_OF_HEALING **** **** **** **** **** **** **** **** +19367 SPELL_DIMENSIONAL_JAUNT **** **** **** **** **** **** **** **** +19368 SPELL_CLUTCH_OF_EARTH **** **** **** **** **** **** **** **** +19369 SPELL_BORNE_ALOFT **** **** **** **** **** **** **** **** +19370 SPELL_PROTECTIVE_WARD **** **** **** **** **** **** **** **** +19371 SPELL_SHADOW_VEIL **** **** **** **** **** **** **** **** +19372 SPELL_SUNLIGHT_EYES **** **** **** **** **** **** **** **** +19373 SPELL_TOUCH_OF_DISTRACTION **** **** **** **** **** **** **** **** +19374 SPELL_UMBRAL_SHROUD **** **** **** **** **** **** **** **** +19375 SPELL_CHARNEL_MIASMA **** **** **** **** **** **** **** **** +19376 SPELL_DROWNING_GLANCE **** **** **** **** **** **** **** **** +19377 SPELL_INVISIBLE_NEEDLE **** **** **** **** **** **** **** **** +19378 SUMMON_ELEMENTAL_MASTER **** **** **** **** **** **** **** **** +19379 SPELL_SUMMON_ELEMENTAL_AIR **** **** **** **** **** **** **** **** +19380 SPELL_SUMMON_ELEMENTAL_EARTH **** **** **** **** **** **** **** **** +19381 SPELL_SUMMON_ELEMENTAL_FIRE **** **** **** **** **** **** **** **** +19382 SPELL_SUMMON_ELEMENTAL_WATER **** **** **** **** **** **** **** **** +19383 SPELL_DIMENSIONAL_REACH **** **** **** **** **** **** **** **** +19384 SPELL_HURRICANE_BREATH **** **** **** **** **** **** **** **** +19385 MINOR_SHAPESHIFT_MASTER **** **** **** **** **** **** **** **** +19386 SPELL_MINOR_SHAPESHIFT_MIGHT **** **** **** **** **** **** **** **** +19387 SPELL_MINOR_SHAPESHIFT_MOBILITY **** **** **** **** **** **** **** **** +19388 SPELL_MINOR_SHAPESHIFT_SAVAGERY **** **** **** **** **** **** **** **** +19389 SPELL_MINOR_SHAPESHIFT_SPEED **** **** **** **** **** **** **** **** +19390 SPELL_MINOR_SHAPESHIFT_VIGOR **** **** **** **** **** **** **** **** +19391 FACECHANGER_MASTER **** **** **** **** **** **** **** **** +19392 Disguise_Self_Learn **** **** **** **** **** **** **** **** +19393 SPELL_FACECHANGER_OPTIONS **** **** **** **** **** **** **** **** +19394 SPELL_FACECHANGER_QS1 **** **** **** **** **** **** **** **** +19395 SPELL_FACECHANGER_QS2 **** **** **** **** **** **** **** **** +19396 SPELL_FACECHANGER_QS3 **** **** **** **** **** **** **** **** diff --git a/src/hakpak/peps_prc8/tga/armor_pallet.tga b/src/hakpak/peps_prc8/tga/armor_pallet.tga new file mode 100644 index 0000000000000000000000000000000000000000..7fae6b206785859e0f3e1a7e58225811d38493ac GIT binary patch literal 180268 zcmeI5cUV-{+P8@fv3Id6Ac_UCqbMk1L9v1gb_9FJib1h=jSXW>>^*9tF={j#O*1BH z>Pa;{CnqQUB1>;h2~hRIFGLRjO1$aBwif!om<99*)+nTf1)U+OsD;rwhept?#1riyK(sN zVO+m{-TI#J@xIT`cl|s#e{^iFUAs0?Qc}G3_sEeWxN+l#^*y2Ed`L(L8V5$BW8-8D z=r|Rld#%Lc^iw#v_BA}c<2v>|_6nAz9mkj+3y~B(263VNaPi_rG-%Mk`cBb&dH<@Y zSE)7HH|vF@xRIDTWHq)dI*F&YU&iLe$1!=pa`b4Miq@gs5mq|V!B?%?1uddRA|_!8 zIu6{4zEj@BqRpQmXa6lM+4ceYjCuo|5;r5dV3R55%NaQ?a%C zE?l1W8s1p@7M`De8SA@k#n?uZky36LI^^%_;MYzXf}?9!;oRY4xb*Zn+_-!dpS}H| z>vr?S*YM(rXYlN{&Dgal)4`Vv@JFT6B~U*k2<=)l$Akg>@Z{oboZY`0PcE8^vB^nj z(q#u13@7>A_P;h4WZ2P0=>qC@ZAXcFBP)$4`9ziesvx!Hf4-U&z? zm4>nNvXHrM1vVZ#h|{mUf@fd4gl8^a!umt|Fm>e$44aXGZs|iE`!DEU07Z%wM%9{u zXwtF)2Bh}J(zSE3@2MSFymmJF4NE|SCZQ-7SPK3D1s%M9fkG(mUj(%(RzvH0O))ZI z5H`G$) zz}k7UF|1btnuLWSuuLfg6msrAUqAo~l`M%ep`i$B*B&t$(~y4X2v%LVh~Wnhq1EIJ zRBh81MXOdr{-Q-4`!7(yAO8NuQ8BO?=rp^l`LYv<9`uPDici0Vo=gj7yg; zp?>}P=+UDGnl^1J_W$I`la~L6m-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7 ze+Mu0pLwbO%uD@eUh2Q$bsM}%lO~q`fz5iOMdyAF|Ks+YaQRRW@{tp~D z&}!35vp@&;Z6M4{)dmBX2t(u**mQGZ}(rvf4_v0(7cZS+F#wDC-r~bx^*u9 zH81s_d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ss9dM=s)vP|CyKi&%D%s!)yO_ zf1cfco&Wb5J=c-{x9*W@<^S4$&1?UM4IB1{{MUViy8Ul>ssGGN{bye4Kl4)mnV0&{ zywrc@rT#N7^`CjE|IADMckn|0nV0&{ywrc@rT!a!=+L2-|9+7@t@c01|B0)Qy4wHR zf1Uqp|241upEG9;I&|nDj{o!L&$s+Hywrc@rT#N7^`CjE|IADMXI|<*^HTqrm-^4V z)PLrs{yTV~|IADMXI|<*^HTrqd~9s2EB@>LKa>CK{y*b?kMvo2`u{Yq{a>Ro!9gAO#W~Dx3~Xw|DTTk z#($mvYhL@mYu7Go9*;Es&zd#M^55`M|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)m znV0(S;D!D(FZG{!ssGGN{kQXazMsAS&*cBQ|DW@JGybP}<9|d%ggE|>A3xsZzviX> zGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZJKS3;kza>Ob>R|CyKiZ|8OX?oIx$ z=l>Z0HLv~OzJ0spu{8dV9zELP3@`Pcd8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{! zss9dM=s)vP|CyKi&%D%sJFh)9@!vlG&p!Uo`M>6k|9>R@4;eB9HEY(izCZp*{AXV3 zKl4)mnV0&{ywrc@rT#N7^`CjE|IADMXI|>RgBSYGywrc@rT#N7_216x_;38TkN=tZ zzwYM$3?4if)vH&>o;`bzoSbaU0np=s@$vEK+O;d<;^Lsk6?A=%zUlfQT}Pzn8t8hD zUcGvuS+iz7-uLiun71Z@YJ$v@F z=KX*B?YDSE)p@+|!V5Tm{yZ*RxPY@~&*IpzW7xTKC$?_tkGdxcY6K zQ~5rB-{=3J*5B~e@B8Zaef9efu73YP`)BI^rvztUVWZX9)!-~nHM)swJ-)@qbAQB# zSwG^VM}NfY3E$#W!yDM#Y!4PST;{4jHheXyOK9`%qhq$5^L>VcE1({T0ZD%?E11+N@gjbkf^W5KxYm^iQ%QrlK>@S&k4 z(4kuxhL3N7xl5vP^w}P`@xgR_cq<2Qyqk&L&vwJK>}d2)ZHo4B)f{};vISACW=TXe zt%dj=jgUFNE1o$w9xuO{gCnOWV%nT8=+LDB!WvdYg+OQhd|;ezqbS|v~|E*OymTcg9Y&PaZ8Am&|} zk1aR1WB#QD=)ZLk+E0i>!~V@sroHp{E5#(B`B1g~L$+G~VY^!Y;dQnC!zXI}hg)j> zhY!^H4_DOs4{O!>4;h)LJHUDU1XQn$>g_rrGG!n-Oqqt{ZBJs}SalHQ`MQWi^wf1NdnT(julhAkg zc09WBGIDmliL9kBpwHmVXwzW~YS-_JvgM;)ys6)p`fuuw4KMYdd8z-*OZ{hF>Ob>R z|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl1@X|CyKi&%D%s!<+hjssE<_*zi*SnV0&{ zywrc@rT#N7^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD^Z^LlJR>c6Q! zHtPpS{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2 z-|(h>U+TZ9KQ_G7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN z{bye4Kl4)m4R7lArT*LNkM&#wssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADM zXI|<*^HTqrm-^4V)PLrs{u|!Z?@Rr+*B|S7#8Us6m-^4V)PLrs{xdK2pLwbO%uD@e zUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ_*zso$6SZ?8Yr^N*$eGcWa@d8z-*OZ{hF z>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)mnV0%+cvHVG_1|89tk)lq`p>-7 zf99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN{bye4zn$0hds6@H z^~ai*`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN{bye4 zzu`^&zSMtv{jpvLSn5CXQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s z=B55KFZG{!ssDEVkHmj_{qY}(|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD@e zUg|&dQvaEk`p>-7f99qB8{Sv{?_2-CxBkO_@A?LH#cMX7!u) z8EC8OtD83K;^3=QtA^m5E8`i9f z_D#c))TIN`lasJ`RtENL-iX7ypTy2h>#<t7b}FN7);%A;}pFbwF` z9V_O{!h!9ZvEtDgNJ;2|@X#QXFIgP=wHGg5wAODn=WlHNDp(R3j17Hauy1e|ypTBp z*SD?2^{p%L=9cBSFf$GNk~?5aTmvj>QPaVRnbpjoHgD+AbA4(M}fY1u1(Y|g?OzjedgBj{N+o(RnNkcHLV{=3YRYLXR z0Vq~5zk?r<+6Y-wW3X#Y2R!>^SG;j{G(Nue7(RMK-CkdVYiCB{>FwRHW?>g(PK$Ez z(d{c^@PKekpAdt`7Ien*2U2kJ#YK4kwRL#&g+(~EF9l2HcE+S}tuSCf9S2{zdH~u+ zS3&=zCKx|D29K}ni}NQR#cMC-;M}P!Y-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZJK>rhZ@QzrB7~uL&&m zpLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%sJFn~i zrT&}xVN?Gv^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk z`p>-7f5V&leX0MZe%SC*|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@ zrT#N7^`CjE|IADMH@vC;m-=t&hYc_FpLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@ zd8z-*OZ{hF>Ob>R|CyKi&%D%s!<+hlssE;a*zi*SnV0&{ywrc@rT#N7^`CjE|IADM zXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD?@ys7_}`fuuo4KMYdd8z-*OZ{hF>Ob>R z|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)mnV0&{ywrcgoBDsL|MvP}UH>ojpLwbO z%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%sJFn~ar2d=w zVg3D~d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@ zrT!b<)c;HUx7QEr`hTha%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R z|CyKi&%D%s=B57I`9Bi>P5rR`{`e#DpLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@ zd8z-*OZ{hF>Ob>R|CyKi&%D%s!~5$0ef9so`hQ>jzy96u^XJb)|AzS4vuAPa*s**5 ze)#a=!||Z&mwo&9tzY0wp)*REYLdGcgr zWMn|k&73`ZHWn^ih((JQVa=K~ShZ>ua&mHT>Cz?W?+M@ef4I;8{hmKl{~ZzE88HKs zkvwKJMr6*y!u9L0>*!JJJaPm(jvT_=^=mO~=2Ubam5w$8`Z?;4t2Ste@b>M|At?z- z>1oJVya*fj?8cLa4`KbzotU^_0eYmRp>>}=sNXKu!51lA7FFxkLzCzj#P#fjGJ(c6jl4*qbI_m+MuF(-9@TjFW_Gog#wD8eB~+#i)f7Q0|sE$vK838 z{{UvF`!4-c5Y#Xn#mkn5el7Fm!(!2>YdWIFEJLS9cOWh2IjlMPI@X+e6RV%OhE%nF zLENluh#veX!eR$Ic)$ErP&OnA_2UMjMe;QCoWB?I4qV1#Ctktao#)Vd_71e{Jsv?V zdZI|>W=>wm@ObB|yzrwk>f^OeE^2j4F=Rc} zbDn+%VmOci_v*%*c&VAT$ z{zdG(@+vl-K932TccSl`gncT^&c}`fccuItpRU zTcb>+YVa?T`}vvUZ_}Ob>R|Lwf4|Cjo2>W5AJztn%`rT#N7 z^`CjE|IADMckn|04X^#z{drRV_54rczdrv`|IPl*`Iq|7ywrc@rT#N7^`CjE|IADM zXI|>R;Z6O%)PGYyY-7e+Mu0 z-|*VMs#U9sT`IGu@_HTHp|IADMXI|<*^HTqrm-^4V)PLrs{u|!Z?@RqR z^}~jj`p>-7f99qBGcWa@d8z*nUg*E!$Bi48$9>%n@TUErrp97){5R)M>c82);idjF zFZG{!ssGGN{bye4Kl4)mnV0%+cvHVG_21MF8(!)^^HTqrm-^4V)PLrs{yTV~|AyD+ zv0%Z1dAOb>R{|#^I|E2!h z>xXsyztn%`rT#N7^`CjE|IADMckn|04Zm{bN^2gEwEs`{+v)gk&cD=uvwy=&{bye4 zKl4)mnV0&{ywrc@rT#N7_216x`aP-trheGe|4aR6Ug|&dQvaEk`p>-7e+Mu0-|*W1 zLWK&6<9|Xzg3Et>{-yq#{hRYI^`CjE|IADMXI|<*^HTqrm-^4V)PKX9`hTha_WEI6 z|1b5Qd8z-*OZ{hF>Ob>R{~f&0f5R_cyx8(s8vna=>0)u_{7d~e`!~GQf99qBGcWa@ zd8z-*OZ{hF>Ob>R|Ly!AiT|d4*wp_^{bye4Kl4)mnV0&{ywraOFZAE=+W$Wi|Mi%^ z{?0JxPwKzfzu~3+GcWa@d8z-*OZ{hF>Ob>R|CyKiZ+Kt*|HEDXzk2m*G;iMAnggK6 z0rhVn)~;O}dOegXRjNSO2kBe+^5vmx1$7Oe_Fm^~MT-`N@BBa9=l_1spRa!Y;jW+m z2M%EC)~(QUJoGrP&Jpy#Gcz+WWy%!mHfho%tM<=# z{vYo1f4}GNe(Q&Q{C{`-xbOTw+~@y(>xX^(e|P=3@BBa9=ik&nH>ffek-sU4W6{ICRjn2)MqgkyPs1rEE!51l{+Nq`6A|j+e+BF%ELEScD;k0M5 zWz|cVH~9>b<8sid-gwlhoP>%cA{~5zd__>GKq*ux9g4a&+oMa=R7@Ry5F3|W#H1mI z(Xsh71XYSgiGb=Tn7^2VuM|2Np>38TIyncO(+?nR-iuhV^DT9|fu%ccB6ZG1bR519 zjp8?>R@0>pzF5hws2n;HjoZ&aOyV;1o_G>j8?R#J6K`V9x|h&<%yG1cUyh*0nJ8a< zgo7`TKNuy-#33YnpjrcA61om}92pDFVbzvbF**BrbV%HSuojb1q1qq>6m`~*=X<0q z3KXn}QswHSdPpaCOw5^>#tzoxD#j^or#K7w)NBUJr%eN39FfuG(N zW42_dwG%cdb|+S!*ogGUr=ZjH-e{5@gP=Z59ekn6>fE&qLc{JY5IwXL1}sd+g8eJ8 z<@8Rqj>1axT{sjihQ^{+H&w&lBG|#_E9$T2Jr+T^pg`1)s*g^idt&m|N3s6oc8uSa ziT0xsP_so{6suAe`HMN%e`t}?AKk}|#*pkxj9s$~ix2L`zKiFu_l0xVqize;_NdiM z)Y=9!(0SY#$Nnotw?VT$z0qyNaHPzbhN)XOVe{#yEq2qX6PWz?M)aLJ1?^K)5!R=d zgD+g8Ix4k_MDy+m=savF($xAHD-IvP&U0t6{Lldmn?Fx|E<+HS&=qA`JFoxzrAorT zY#CIn9fEqQZ@0(jQJArP8@8T0iRr2>*m=|_1h;O5;-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s z=B55KFZG{!ssGGN{WrX+-W2+4^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2 zpLwbO%uD@eUg|&dQvaEk`p>-7f5V&lZK?mJe%SC*|CyKi&%D%s=B55KFZG{!ssGGN z{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADMH@vCemilk%hYc_FpLwbO%uD@eUg|&d zQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s!<+hTssE;a*zi*SnV0&{ zywrc@rT#N7^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD?@ys6)o`fslv z*7g5V|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADM zxAVIGPwKy^A2#*hQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55K zFZG{!ssGGN{WrX+--7f99qBGcWa@d8z-*OZ~U=eMzls$rT5CP&wV(9w!RqliU6*Ta?b@}2{+%dYr=xFrzJHSX zo$l`4yZe6sUHxWxojP?eK>c3$m@#88cI;Sdt(;Y>Rv{-R2OBo18dg<5xoz7v?A^N; zyLa!l*4ep!{kruz`|96)pWnlL{h0cFzoG%iU%oVo)vk&1ZJHxEr3WH1$D-e+pm_PRs1zEEx@}q^CM5|&r)OaP`p2;6=nMQ*4>(358u2=zdFJBxJL#tv=`<8fYSTc4zIt|Bj*5QTYNAc$6i@5df zJNWC@U*Vs>{o>#&l_-j!iscYlCm8)=qA+PtGM3DofgKyy;pDNW@XCuX;)8eJ#@3WY0HLWMf@RsD2F#P?0Z_{mw=uyPYl9yozlp1*<*ufK=yKl=uM|M71Q zKA=b`lu^H7Up=@!8bozOy8-DKl$nLBO^@Tr6DM%;rOSBrz4!3ZH{akde{=4?K#?*i zUbYIV1T{dDmT^exGYm7P%);i?>+tNMLwN1N1$=z-CcgjtGyLNx=jZQNq$vE#RzTre zbx^r!ESe^yq35V&m^AMMRzLoM`W^c3aOv{j@c#S%i|@XJ^Y*Y%~ zfY69TXw~^LdZ&Jdtd(D5^Pa!rdoKr>F57+@CE!^qhLU1_?H@u;#D`GcH|+n z>2n!L6Fx!q#&59o@L%xki$CGoyT9YJum9!X^X0FDeEFN9fPYW;mz;(wb+@BMrx%el zM)7OE#rDJBs|f7DgXS^EXH z?*A4iU-((^e^=L_bN`h)Pehd-vk@|G6T+7qMbjNGq4k+ti2dl_$o%o2*r9G0fBh#u zRkvUM{%^k6KB=m`S5T5a=ZV+Wow{l<$5R`8in#L z`k+?NiHI1x0&P}4gN$?UVdJ%L@$9YN@b1t5#?Sxwf3Ej$>i6&E|L!XnaQ5AsF8@va zu;K0ghqZ0(@c-3e$baUY{-4g{|2FcUdCULMXv_a{ zZv4+7{~f&D|CWiU)oapS{WrX+|M$j!d;GW859>CC)PLrs{xi@1yNmxHzW0tR{xi@1 zcS#y<#ecj1AKiH075|y{#{bvef8Q1VnK%Ad4Q>eSe`4>Uca8td8~+1>>Uxa-FJAfG z75|yPm;YP#=JlU>_MhYbZU0sLy%YbLclz&)|EFKfjsFhb;s4#^KlAtUU&sGTw)oAw z)Bn8j-}3*rf4TAp=I`ad75{(uw=4cTc=rDu@!!r{Yr(t8{~OO9=gR+e{I~mW>W5AJ zzukY6{|}on)noq8yxo7D|F0R^A5UaWcjf;a|Cu-bx2hZB%Kw+nn&~nBXWsZ;F8r`9J&5 ze6IgvZ2A8cSN_lOpZQ$>d*$Z;s{P?9|99{%|J!+$|1e)#{W8PyvqL#Z|e7@@!!-B8{VD&cWeJM&;E1!pZ#avwEyk?->v=6ygUDO z``?rQ%uCz<%zNwqU%&X=YX39O{@<(p&wOtC|L*?3ey9D{lDG+XWIXL@AUua_;E&nso!_!zdirw{(n;E_LpLyf|-P-^5 z{(t80mH(Umf8#&%x&GhI|8M)BoBx~sf8#&%x&E8{U-|DQ|2O_Sc$fbs|L6X{y#4>o zyZpaL|G)8{d6)mL{{OuFf877iyfpuJ@Wy|W|GV+u-v4iSQ@?*N|GEF))DIip_-~K@ zck`e5d->1#Kl8?a6aRJppF97}_#gAee{bVI^X~k=+xQ>z#{YZ8f8#&%#(!_)Kl8c% zyC474?SFgxXFk_|`}p4#c#8kb=lXBrzv}-}{(Fl54&LRziT}6z|8nF1w|U|}^HTqr zclv+3|IbtWXWr$1p7?(WCjRUGKYRRl@Wy`=|K0Te+2g%YDKFL(Ukb^O=kf6o4Y`}n_u zclmGPzv=&f%{BgS&;ObC=>LcRay$OdyeI$7_&?|W%)9b`)&6%k{>T11c;mm0|9bq- z_`l+5*Z9BPe><=1|Ge?v-v4jvhfV#z-G9^nZ}0!(_CND>|J~*P>_77+{(I{`^Pc?o z)c$8)8vmKM`+v9m-^~AEUg|&dx$&Ro|Ic1Otn2^pKF;Msq7G-en|G)qEql0Jv?>7GT=Rd>2JN-YHXa1jw|EB%#c>k{XeQj`_dLv;X$-zg3(5 z?vLsJH}ij)znlNlRlhyY|6|_ef1dXL?f9Re=Ku2iKL>C8zf1ey-v4KKU;XyOUBB%+ zf4=jVoSbac^mXXa0rBzi=-Ra_;^N{E8yjoY_vsq7wr$%&*NW=7y1HJeSFc`Z)~p$P z_1h13{kHG?`Oe=fue^d6UU&iL&!5KyRVQ}#>{%Q;b__dr?!=ZYTcC4v{qObb*JI_% zmDX+f^5qylT>W0J`cAl?`e7gM`}};@&mXV9f6)H;>eqes>ko7Ny6^hEzw6i3@8|bZ z^}~f5pkmoLgw`C3=$30Sbiht5n0p+1p1g=Nr*GnoYoFn>Pkz9U-#hE43l%PplBKJo zN{t9KY|d0?XQ2p*S|XVulw%`1y)Asum-3e+X>Bv zjX=NI*~rS-f+vrkP_^eT;q~|4$0uKZi@*N%n{)r=3c)X^2>c_ zv1dLWe{K(sUwsa*eDnrB`0i8u`R_kEc>j_CC>2-+Rl{l`Jhr*|4fmcH_2@(_-Lwk( zj~~Lh%NKB6t)Fn~>o4%rZ_f1(g7OtZ{i5X&7g!q;>O^5(yJYN2osJU=*W%)yqquSA z5y@rop{}_M$d05FA&LZdMy04RXg6>!hRs}$1?%@>&#|+3?!~LP{?5nv^y}~N(=Y#UeEx-smqp16 zRZ%@O0ugNz&}-mGOq@9ntJZJ9;isO#3opKmx8L~_zWnN2{QRqP{f46D{ZKAAAA%zT z&?==g`p;~H>8lg5Zud+aIlTifUOkDoKfH>szWW5f{{FpV|3ym`M7c^O5L~YcTE{g& z|6%c%nl%dRHZ8*uwSLCME6?NYcW>a!uRq7HZr0DJ7~qGRWdhK=R$26GQ4`sHn&R;( zi8!(*6BiC|!}W_N@#))F@z*au!asg??!Qz~e^e@03JpT4qf_e$r1$HJIn%~q^V;Qj z`sjXKx%fQZfBOc${_=A*{*`a_PMw6_;2cm4X^z#QL38d ze|Xa#F8`OVe8Teo{DoKZ_|Lp2{|9e8VfnxR%8fk!JNSF}fBN#vxccsUF8>|8_P>^A z|4+PrCXfHj+x>6Up@qZ$=dZkgH`V$H#((DR{!gsi#^L|XvoGfHpLwbO%-_rZH%`Bi z$A9Lv|CLKt_S%2u{XF=;aKk>!|1+0g&*MMycK;isnUiT|Gbcko{LZ;$^DUg$sb#{X*dYQdBL z_V~}dC;y*bw9bnE>_7AD|LC6m?;8J^_vHWKES0;c_^cJKyFBLqrheGe|J(i7`G3cR2^ckD2|UGr z<{kbITx;e3#(&QL9sC{t%hYRV<^N5GrlbF(^IZAAj{kQ59X$D8GqW|~9~`9J&5ygUCFOq}j9|7V{4pWk#Y9#7c_yZ`q5pLuuw zXOGYJnEx|x{4W~P#g+f3&e{M^@t=9S|DN)Hd;Djf{qHv;+{*v${@e3^2XFJ=w|1S`_H^P|L@lRXP*5x?SD`HGcRrbGw;rS z-TwFFKl66~y~+QXH|_ts#ecj14&IIb_Vz#f&%E7#Z{k1mQvVHa>i6yb+uQ%1@_$o5 zYi0SS z*Zu$Q^8e32{n6_GH}%7Y=luU({r}A8`k%M`@2UUa!Mln7_WYmw{~bK#|GNL*p8uQv z{}2Ci%j*AU-uSQE|L*dC)Bpe3H(y%)|IB;x-&6lT^TvOB|G&HZ|Ic5j`Ulnj&%7u9 zJ@x-HFU|j%H~!o6e|P==x4!v{)&I}D-G6WLf95&=zgPdigLf1E?fF0V|1)p=*X@6u z|9k5H`{ApPt^R-J?f$#V|GEF)@TPv>o&S3L&%}Qo|1Tl_1}H`*X@6M z{CDue`0wEF;Xmj9%p3o`jsMJh^50YZXWm=?&G;Ylp8WTe|1yP9{-uYm;c=UH@vC;_muy88vnP~59|7W zlmB!3-_!U%^SSS7;{@<VkjsG)m{Pz_9dHj!gPyXA-|Lyrd^Cti2 z_P?j`e+O@i|L*$#IsP+m{J&fOzukZ4?f!d{|J!+8|K}Ey|OJ^tq@{(rB2|A*hdANjAx|J?bn+yCGG{)2<}#(y3Eb^HIv zUw?A&>_3nHas21^&;ENF|2OS_=GlKe{-@{v+5I=;fB*Q)KOFC0>Ob$_TmMb_pLuWm zH}U_cU!3bVu>bcO|Kt6e`G0!+-<|*V`2WkV&h;C-@n6S()BflE+x^$^KdohB{u#G_UFRK&KPimow>F|E&0obCS%4i4Ifi|Lto zc6bI>qz*#Hq$ms>(%4b|oWG!|f36sWn$;pvzjhBKwV8`E{hoI5i@GGDcVr7hwycI) zHA_4A%8jR@QEVm#q|L<&RkMCm{nowxKfS$r%{n9xpNp{QYzJSZaRzF)S%A2{i;X<2{Pl=UT!I>{mO6Obc(Cx^+X%nl(|pcyZ|0Uc7h_dfjGo{?pUbv2fu+=(?~oXU^akwMMf2 zKfSFV*U#(MG4JQ+2YvJR_qX1I{=E3})9+0`uV2S}$bt9K@wv}2{PH)LfBk!0`u2DG z?yYV8xPD&0j`;x@Ph#5g6Ij0OJa!$wiW~2Lm50~c`f>fdejW4rJ(Vb40@bV6K(nUJ z&@CYWBSwtCyzFdj-MZB}4{uz11D}8XIev4qe#GwSV{v2i3VgbEBTmelij?RUC{?&1 ziWDn>F%u`@<4-=tfBy5oxT)4~)^l%p|D8K`hPO9;V9cA(-`jh`oBI8_T|1%qupx*` znuf0JmLRR)F)T?xi=+Kd;h0%U7<$jT`R$*WV9eG1+eU z2JN!Yci22ET)Iy6_g>3${;#XQm!oo{3#igZ`QIK{S=o86-#P00 zpk8=um;e0!Ej~B{0fF(TqxhMb^YZZ8hui+gTK+Sy*KX|7rw>w6QZRDlNSFUlJ@u5e zhMRV7^5n@@zpeJ4dF`~ml`mf&jT$v_`M+`FMvNUh)>;R$N|h=u|CyKi&%C+ry!D@X zssGGN{bydkfBoHP`LEW+OmO)>&+`A&sZ(nGi)$|bnV;A_4hLpUz*}2a;*&k9ZgTb{ z^oeYYVg(DJWSO#Rs3$G{O^~VjioErL;Gs~&%}Sr ze-;1j^~-wwfpQV^QLFW0ME6>XDYG{?@(2C*<}O^1jw(OUuVemR{=4FT;O+SDjxSg_ z35Cl=A|$*U`VC)-9S5)C)Wy$m_R_m|;(v1#t`K8=&oJMyV@J#Xp+i;8@tyd8;J^VK zI&=t|Hf^$EhJIW>ul;A<_^+?w`t|Eu{_F1y?f-7 zf99qBGw<@hhKm2n|85E0toWZj@3#LZwf}GA#((Bp)vk$*-d%7cYck&1z6Kxf-hkaR z#-dx(h6u?22+CIs#GC~S@R#qu$G`slFUR>aUfZvEcmFo8?=C}(OIp8=_V-{ju^NASRZ~#pGu&Mvo{+Cs?OChZy z(5P1edd|tlsN>JM_-^X^AhLFMG_TYGwMy1>@KqX5w&MTY{9mQ={}dJf>qO6U@D&@+ zLS6N}5TCpdgU4;eW7}T9!klY(bj@pO?Dz}pJaom1|CawziyeG!{@?p{{CAuGw{pdQ zK7Rk83>2)Ch{7dnqhWXirm3~3UU~g}eD&wQVfp5lFlf{ggz5G}`8KMZG2XF%o&RgE z)6&vh{;yrT)`}B42hj61bsSGkO|@Rf`?veAJ=ghvW@e_9|LgC8cJ11shPt**{?EMB zf9B0~=dJ(DOZ{hF>Ob?wfBhNh{69gpmqw^OEPLMV{QuOclelKf|CujUxDeXb4aUr* zZaA*;|M#AF3?DqX4%;V>KwQH*DD=o9sI1x+%T}(&Pe1?cIRD0Lch1`%Gq2iK6d=9Kyl*mX{|VNN1#&`QKbWuR-r!H(Zw zFR1dI8Y-_3ZC(?#d(=bM`D*>YbGdx?-V4!M|1Od0AE>1KH}%J6|5dgB?H@(r(0N$0 z+-^!i|G}33_V%xC{|_Fu7}djvsQBN`EpOWY+JEi&s#U8j_jR78 zZ+h+KQKLp-@ZiB#p1|+FNRc84QEjW*wQHkk)26QcU$_6KPoIufty-zvwz|uI=B55K zZ>~FU{bye4Kl4)mnb+@MxBo5wn>DrK|47yTcl!T@)&6(Kmn~8lvGqeSC%FesE|{VG zUyJwE_dw3LVb*s;fk*sMD>M`vavpbFKgMgj>+b$-UgvKA<{Wr)Z+KI`-?dI_q_%30 zj4?5oKPMg|52j<(nGB3NcLF2Np2mp7$IwHy3pyoEM{JwnRz9lpf5R8dR{%lfDk8F3 zbtJ^sL$@sTH=fJo<5hb)yhAV5KhO#l%LhAn9shOvz1N`ms{QWXf8GC=qWsr!-qbIf z{Tn`Ui0XGx{&V}`wb!pBQS}S9@3X|p|Czt-ziR(iO;YXm4tMGQyY0V&xBTy|;(v(c z|G<$;@Z{mE)+sdohr!`J5Kto(g+pdJ-oM>{-Tv3{-t;>e|8@J{e&$|L^4g zy8VAmwg11k)BneOsj_9Qe$9%-0?@fp80HV`gXflH;=`Tm@b{)2svpZ@= zMxty@wZ56^SJmGihS%}CUd&u{AFu%P7b}0S->@IH)tR4aV)6zwjbDMFs6~$b`v*-{{c@`Ru4@0={;TgRd;hiW|FiPFcM`=9r( z^M9QKG;G)q&6_vRp$~S|CyKi&%A#Bx^3jj z|5g9r$Ppv+^#AMp|BKIW$A9J{+eD*SsnXVWK;;s}kkCY3+r#?d`Q=&oXqUR4)!2aE zj;K+^dJXf&>pT~&n+@|i=FR8t?Y-em{eJVBaaOy2YU@-i?=%w6jLyK>18HjQ$49YE zeTNM`I2wuB6A_a!5$%Q!QT^jtmcNG2ul(2T`p9Y#=oJ=)g$ao`yFZujn3aHtZtYPc zvNw8Cn*2tY5(uh|Hu2+;|KctqsPDnR{oH={0uf9c-Qp_>c6M+ie~XE zQKjVy$Nv3Q?tk0=es2BO`FvP-TNJJoZ?)ff|F`r1K9>KX;c-Y9xEz1_;1j3+Wt*W; z_2G{Fck0y1YS-&|*{1(*_wL;|sDAtJvBw_60@ZgkY0@OCe?a#W@cy;`ItQqwKHKQ% zXv=@i==@)||F!@2{(t7B{xff`J8%7GUg|&dQvaEE`LE)CGb{hs^derWQ`R&Hzf{o9do}yxJQ`Br8f^s#hIQXiK zCt3bl{x5Rxzt#VDr~PlQU)JNwdi=o3AC&(KmaNB<2QRxm!7sl34X2;KYWd$SWufIi z^SVz?e+S&o|6|?e|F`|`qWquWc>lTW|J(h4rv3lx-~NpgXWl~ExJ4>2Q1QQPa}=tU z>fpO{>EiNV_t)$Auls29?>6aw&zLd8>W|j_e|n6N-@m>8&-DLKojTPTKhSMG-5+T0 z|7Tw6KlA3g^VWanrT#N7^`Cjm{}OlNzt#VLd;DL=Nvj=Z_5bCL|1p19^_P#GFcFPZ z-(le*MXm3ET4hTisdZDV9W@A-*UYoV1z%aW2(wflA@jy-*G22$ALez;o6q0ddpob| z|LSzlzrt^N0q|6Bck zZRa_7SNlQvZ?zw6`NLZu{D2jk&Rc(1f4_vNc|!dDUH(@|^w|El{0~(AtNA|;-qrt? z*Z-Zz{)BmJFQMyz6$lOQsKy6dz`uIBgE#rV_FLC>>V6F!zmFU_;>!OgOqgKx{psI! zU7(BAd1c^&WHeE#0v8{X9a*XbON#=|-zDqZFHYOH=r;yx_sdmLv6sPBN(H8?pq z6HC*3A!B%~n*Yz^w{%vAk)OVBc51t!egkf;6d&wu?d*6p~69>a3b zrT-#?ww>?bbxhY|czXVx&fne5{|gImgTi;(|GfX)_vObpshZcI=KtyTfu5Vf`#1iVRsB$rs*lA!|4;wT zmMvRaV*_UVk9n#8%$w`ZTmPAt`p>-7f9CD}>;6AIU(%ZYcW3G*&g=N!ylZoW4^@6K^s3t)t*eKqae_(?UdMkuuQy)# zIY;@g=j+=4GxL82kCd>i|N8If_Wwlnz0g~YFX(;-=5M$E zry-zPii-bnc+_qGpYeaJTfU&~|GU%wZ~WK$*8P8aK4A6m!Rq@ZQRV+b9X$K5$NO}@ zUrtVrHGZf21a$n@V*@(>=l5^?*M5hpF($kJI{(+#v+mn6{xdK2pLui5dFwy(QvaEk z`p>-azqZ8VA$97i zv6e#c&-Vx#R1HL0$7no}F%s8QKLGREYj1D*nquC3{@&gj-dDfZK4`g^ec`Rdnw_3ICF{kre^y}#?%RsZc5 zggJiok>l4C$Nbvhs$VmFQ@s;@j~t9|s&=-v_2V1V^RxZx!PE~MzGD6&Xj-TO5&~*s zRI&P4R4NjC%5}ua3Z1Nby{#Ybrk;-|RNlcisZkr9)cANx+s+u@wIAjWNXLQs%W?UM zy*My$nYFDS?;q6(9U3%q@Veilbm5{14XlQ!dJ#yBj>E*n!N?k-eg|IN>uvpbNMKcz z^e^Jz(-ZwLXS5%39`#dWoqo7_#t+|oULC*x5{YjPCik=y4TzK@owt*h_FJA{Wob;1D#^Sk&@UJ<41N?bFc^C z!2bET{NfYpex9|hAMf8M3LRn^IC$&$OBF_Fa3G>0>mjjcG$xK!^Mqy%vF`P@emo>7 z5G9NIJNV-1>hqi9hjKZ7sCdi|0ayJ{{hL~d{JjmTepA)j){mFl;D=J`Gq_0W2NbHP z)*onE2xSri5ICwBYAh;+I(y2Y_Q?v?z24T3m+2OOViC^c4{A~a5uL)(KBX;sjPHuU z^9Nx5f%$mi@{^c%V4k(DACKuDrRq!FAAdmU!l)D)hz3#h&^|F5{U;_OHEW1(N>5Z=A(=cHE zY<2v5)bU?b$G^wg){jT^?}Y{(+B$fB{tK5biNMex)Qf6~=)~?woHz^k4T)>-j&1m-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7 zf9Cb^OZ<26LjReU`p>-7f99qB8{X9KOZ~Uk59_(5QvaEk`p>-7f99qBGcWa@d8z-* zOZ{hF>Ob>R|CyKi&%D%s2QT!Wd8z-*OZ{hF>c5@W_5V`;P5rQ`|CjpDywrc@rT#N7 z^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{yTV~|IADMXI|<*^HTo}Z|d)*{+s$?!%O{V zUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R{~f&0f99qBGcWa@d8z+~H}&&U z|4sd{;idjFFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE{|;X0Kl4)mnV0&{ zywrcgoBDgH|E7M}@KXPom-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7e+Mu0 zpLwbO%uD@eUh2Q$P5r*qe^Wnfc&Y!)OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssGGN z{bye4zk?V0&%D%s=B55KFZJK>rhZ@QzrB7~*WXM1XI|<*^HTqrm-^4V)PLrs{xdK2 zpLwbO%uD@eUg|&dQvV&i(0}Ho{xdK2pLwbOc3#*2N&PqV!>0aU>Ob>R|CyKi&%D%s z=B55KFZG{!ssGGN{bye4Kl4)mnV0(S;D!D(FZG{!ssGGN{WrX+|Cjo2uOHU)fTaF2 zFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE{|;X0Kl4)mnV0&{ywra?|3~7# zsUJ4=_fr3vm-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7e+Mu0pLwbO%uD@e zUh2Q$ef8tM`tkdzANO595BK%ss~`8(kKa%IxbOOTxUU~y{q=*bzxI9pzR&+bu0P?c zpT58PY2WAP`}`i}^%G3}e#l()`|BIj@2~GszrX&h`u+8f==ayvwtiecuU~hO>c6WF z-G!j(uc6tpPm#3kOKg4VCw%wY|LCO(@fUTkxAo)tdHp)(%eJ40$|;*sbHaJlU-&U* z9RCj2zx=1gzw^z%tZn_ceqO(h`BKdXLf_2aX}9(>9KG=?{{6rIhvVvAZ);9JuV2T! zbp1%?rdn4#dq=3uYb4RzrNSo`f>fdejW4St$U+g?Dxm+{eO-&_2xuYRz$_2c?^{W|9BG>(J5nZGl6@l$y5^-u8s{^x&j<=Q9E+nUqQ z>(?>w=a;U2mu8N-<*3^+l=i!dHr2mD-^kz5vg$Y1wtn2tZ-ctccJTT0S45#gO%V`~ zfMUf)p;W0wC|7O|s#Z8@-Ro`rctAim^|}ZLU!z77gok%R+qNm_+I2hz515ao^ABLp z6PK}g-T`Y{KOPm;U)7y=aPU_DSK-p?_l-i;?;J&`-#|%Jzo#$}!-iy8_j+4D9vBz` zfB%vWey}?JY3le_sN>(Ij`OPD%WD0L_tg3qU#aykKCrg+5Ik{>4SL z{>5HvTR+}c9e;Zd$6s0wO*9sg`~{Q6#R>&HXX@t3e2zp3As`fuuo z4KMYddE>3O{xdK2pLwbO%uD@e-gxV+|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO z%i?zwGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s z=B55KFZG{!ssGGN{bye4Kl4)mnV0%+cvHVG_21MF8(!)^^HTqrm-^4V)PLrs{xdK2 zpLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z+~H}(5c|4sd{;idjFFZG{!ssGGN z{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADMXI|<*^HTqrm-=sbQ@=0u-_#EqUg|&d zQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55KFZG{!ssDyI_4`u) zP5rRprT#N7^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk z`fqqs|1b65UO%ks|E2yjFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADM zXI|<*^HTqrm-=t#b^V{ze^Wnf>i?zwGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s=B55K zFZG{!ssGGN{bye4Kl4)mnV0%+cvJr`_1|7Utn2@!{xdK2pLwbO%uD@eUg|&dQvaEk z`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKiZ|DC={5SQ(rv6{*Kl4)mnV0&{ywrc@ zrT#N7^`CjE|IADMXI|<*^HTqrm-^4V)PLrs{xdK2pLwbOhWFKPKiu`(zVqihfA_O~ zgRg%3;jZ8Ioj>3CyPx$NeD&wP`tt`_f9|{f9_;n!t6%rkuRqN7>%Qyv{;pqB|DT?o zj)e;sLe~YIIdcZT{PK%cdv5-xxAo)tdHuSJRR7<+d2{G?$n@#cp=%3n-n?m0>t1i` z$My62bXozaCGn99eQly#EBF5zyJF`*Wb|F`f>fdejW3=|3lx*-{k(o1^Tmr7M{sa3^yk>Qb7xGLFacY)Znb#b$EvsW z@3ebXt^e?u zTL0lcYW)XwueUX)pVzNre$dJtn6dLXRvvpEyI*(>H*bCAy7u%x^tOInKd)cMe5bK9 z(Qm;9jM;Pm^A9|WQ`g?XPk+0!{)4*L+xl_+ynY??5nXztecB}Sp1lIY*X_a9voGP} zZ||)C@ZAsAwtiecuV2S}ov2vooB2B#+mGV%dmrCk|KZ(_p|>@spVzN5ys6)p`fuuo z4KMYddE>3O{xdK2pLwbO%uD@e-gxV+|IADMXI|<*^HTqrH{N>dKl4)mnV0&{ywrc@ zjkn(V&%D%s!<+hlssHx+VI9w;{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@ zd8z-*OZ{hF>Ob>R|CyKiZ|8OWztn$IKWys%rT#N7^`CjE|IADMXI|<*^HTqrm-^4V z)PLrs{xdK2pLwbO%uD@eUg|&dQvaEk`fqqszc2OQ)DIh8>Ob>R|CyKi&%D%s=B55K zFZG{!ssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|Asg9`%?c+{jlMs{xdK2pLwbO z%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKiZ+KI`FZJKl4;xOb>R|CyKi&%D%s=B55KFZG{!ssGGN{bye4Kl4)m znV0%+cvJr`_1|7UtjE=*{xdK2pLwbO%uD@eUg|&dQvaEk`p>-7f99qBGcWa@d8z-* zOZ{hF>Ob>R|CyKiZ|AMw{}s;vG4;cy{$J`p^HTqrm-^4V)PLrs{xdK2pLwbO%uD@e zUg|&dQvaEk`p>-7f99qBGcWa@d8z+~H}(J0_;0Tt*7g5V|CyKi&%D%s=B55KFZG{! zssGGN{bye4Kl4)mnV0&{ywrc@rT#N7^`CjE|IADMxAT7_{+s$?Q~xjZpLwbO%uD@e zUg|&dQvaEk`p>-7f99qBGcWa@d8z-*OZ{hF>Ob>R|CyKi&%D%s!~5#Tef8t_Q$Oyz xeje`Y$5%h@s~^9g`f=a&^Kf53DsQ&_OX}0NW54*s_?|r)CU=TY=os$z{{czD{|*2E literal 0 HcmV?d00001 diff --git a/src/hakpak/peps_prc8/tga/gui_pal_tattoo.tga b/src/hakpak/peps_prc8/tga/gui_pal_tattoo.tga new file mode 100644 index 0000000000000000000000000000000000000000..c8e2a27e7ea55171b70c4ad4b2ba4441873b7509 GIT binary patch literal 180268 zcmeFacU0GBwl&VA8cpoIqaYSUDbl2fAkur24$_Ns>Am+RA{`W|DhgPzWAD8s8l%P- z$7C`|rrepibMJo7d1jHH_ruKn&3{?zeVw(wOV{Y;OYnR4v(G;JJRcdE_hf$g-*5KI zEF7b+ua6lsW?;^oIas`SF_tY`1|=mWXlrZ#@>;iU9rX0{uy*ZQ@zT-JfrEnsEG;eZ z4*%}w_wMua>(vj}<+N$jFl*K<$jZuM>C&ZGxpF16w6uPCagFNg>i$yCT*vnI_OP(9 zfPsMl6ciNT>gtN%;9!J=grKOX2qh&YsHv$zb#*oB>+8|b(17;#cI@1_6FogWxN+l# z;E8wmcR#;(pPyf^e)w#bmzT$;O`HDh`t9xQ#m$>H1yArfFDEAlV|ho|t@ekHeiFjX z^AYDziA0wgByHM`c*ja?vB-z-x;Qwk@rT(82b?-}3W|z~f>Rj3@FPViPSSzaTq_tV zxWZz!A8gcuV6PDhD;0m3tnh&DB1@>w(#MkVN~7@0m&QX)y&T4t4RG|@37?Q2_;1;V zfQUYLhwO#DYZr`+Td-EE0LqHdqwuOSny{5|f$x|wginsg);SqST9AX(MfpgapN;65 zDe#{d2AgrtSo?wgD12jV0D4O^ainD%&UCfm>i!;F@85$P1AB30e>cu_H{(cs8M-o} zQ4#Jv3cqOF2UtG-W2~Js5gX-Z!A4OQ_N(OJuv#A0^m`-v|I}ws!LrHYF#nSeN8$Tx z8*sdNCoXjD!OgxycyRC-9vwb`FNRLx!J!klJ#ZM8d;4&5S0@Gn!24szK<2&QjKW(7ZiY*21pKp75M5e` zl3izWK&uta+;mZ+%wTll&2 z7GklS5|%4!L20!vlvUS3X_XdMD6aZn@iJ4EW6VNbOi{AHTrDRktoOnS@JX(P zMot;zL*gK-=ZbNwU2yvJX{=bW0#;U5P*qihgGvxK8>AqX>ORw_6~!UlsEXQ$iimwE z4(&m%|4!n83IuLQ7921zFd*uG1ixZ}4z%anz+#m@Ty$dKLw_&GA`5}$nb^EB4W0(^ zuvYcQ`X%;)1EhF$?Mj&1H^4i%3*qqx5tnfSDS2m*lzRs8nWqqyGz9m6eK56b7aSnP zTgo`W|C4ZRot2JUg;JERu0f?%BdXOKP@%E|1uH6%G(QW$Q(^=MNb&osa&fe62d*91 zhx`(rV7+Eh%MHwQBo%VO@*C77cik6H4IF^ws4ar#`c+tGu8xg%x-hoYfuW@~bdA-Zs=iwEm&^hG48M4;EY`}az;yLG*lU@> zeVq+9>0855#{!lbM$lAN|6lQo=FNrXiX|}CRE5pDwQ$*J2q$9$*c$4=Oji?{sw)2y zKasd=nw&hQYieWOMia=|+C$dG6$;Lqu++{TOU*2>TuU1Y%a`L{egAXjE{5EawOFNM z3QcVX=&o~v-a1!k>pDPP(-O)mTL1F>Kc?EBy2=vr2A)v04ug(MEDXJqvEDNYdam)% zu#dztBVWwda1b0Y^7G>!T!pxa>wl)2Ez~zUjjDg6UHgBj|M6atqW%X52Sxq6xw(m+ z-b*(D(e{o@=sq-O9>cD@)95HXi)O0D9r1%G2<{Xdz&fC*sY%rT2wrWb8BAAh zrhl`o2)4>WoLePQe0LztuO9L4Rfw=Jgs*W5X@UTu1Ely3*0u1WuOF3s7^(TgD5|-N z^7>n-YPyT!nw!WfxrDg%6M_R+2T1W=?*}4wMk;a?%Tc|y39Tkw=(O%bx9tJ6nf7AG zx?RKx+mXB=Tj&5O{%~^*o%4Hf|I{#^UcQR2?>xZkhmY~*^DpuG?tQ$tb_0)xPYMoT z9U#SP&l(Ri^(}cIldIZ~AVvCaz0)>NRXV<%dO1NWXdhJmxg7(90dJ;#Tz z^H4u3yW0f^unv&oXU>_1Whx7?)>s*)4*GENHG@a6ExbbQ;p}S(Yu61}Z>|M34P|i- zO7Zii&w=(LWjZ4a;bCBhPz!JRJkr0ZV=zLkz3B{bCSEmzmWswd$IqMr^`&w!*H*_S zQzHaAS!0Wb6C%A_5a?_NFDo|6E!q3&B6+c+}yD|I0VX(QBaMJ z!D{;bGH+ijv$4er(gLivrQiSb8S^2#SR2Y})>yaR6XsT7uyc%oy;CeKtwXWFWHYpN z?4hEn{ZH`|mYZO)zB@D=B4Fa13WqI4aNk-5kN9dhMijv;FpD@Ljx>Rv&;cXw&wV>< z_>uFU>t87>R-FId=}qGNf4lzq{Fku^5Z^za|6IT9=Y?4mBFm>46*2p;Gw&q!Zo7&@ zE%!(dKfuAd+r$Is1P8DV;9j7zvhtVuXS{)&E1b0H46)2cl6MUXBHOVor4Kc!2T-xK z7a9Hyf&*9wa4#UmyO8Dx+uBdHe;Va=H_*`W2)hqFMQ8s@wDmqib<+dE0jvYK7m(sZ z$HyXFp$L_0$)~XCMW4?Qj)kA0*LfTb7)F;}zu*AY0o)5n@#nfbaQoN^Jh^loFYY|T zn=hW@$7iqchp*qzudndk!zY3RSO;(~AjNN7Hjh4^Yv5&KKy`16cyBkP1^FQ(*bgaw zUWnXeCpdt00QUk?{Ea>Rcyx3aUtPS0m$x6`yGPIQ)6>`Z;lX3U0jvYK z7m(uL`|MLpoI4wH=*(ZPz6NRr>!4$53SBcgi;N7hLQ`FE0P6tm1*G`c(gKw2Y({H; z9|no%PT#nSs}Jtt%A@-@f9EFp&kYL>U>(4{fD|vgd?wTl6k+0^3)es^glzT1)~sN9 zg&;E358h#pf&*9wa4#UmE6-U9GbKHE=-VRN#vhs9u_z7AKxtS83IdW5=Nv3JfOP=( z0#dw^>|7YHQN||X-f&k3BnNLse(V+$kgmy&3_+B)tKb0E0o)5n@#9vm!o-cHm`}B@ zxFr(W=^5BiR08AT60Fb3gL+J?-~iSE+zUwYv*xUZ;wm#b^F3f?7Yz^ZOazCOA|$*F zenACrq}pW;U>(4{fD}Jl-5$zT!7%nofm>`DLUS6CP|<~i%5FpzwZk)Uo8SP}0o)6W z;JNpm4Ea$zQJ2+^-4&1_dE2T{#I}R>j3Tr*bk86W2Pk| zcV#)6Oxw}tdkClEF5qhJUEIulfXgYj1P8DV;9h|J04e_RKGNQ&&*15ed-(R@S5)(F z@R#p?#^1mHGyd}WN5KKC1GpDpKR}A#xN0e!^|k1%x5QQ-cVveLqj+mH$`WEx5VJ*a z0P6tm1=tUe;%`&W|M{u2`0CnSeEZ-jetPy>{Pp!u`1^N%#9zMsz2E@W0o)6)A0Wkl zNN4)gh4bmNsSI^PLm1iF!Pd(M)*c=(adZ?Mz&e0?0rmr=_>}50Z0p#CK052qT)%?b zUwn=)zxf7Vz5W&tUwkDvfOP=(0_+D!@k>_EgU&`3*n4k8NSqgv@*+{NEe%E6Gmu@D zAUJ?^0QUmy2T1Xn3s#Xf+<;J1Ph@$;Vp~Km+S01go?e57gi^r)tOK|gU_U^LS6drV6s4dHyoRotui9FMm@$F01FLI?Da24FvcJwYk{YJWc-oWD%bQgAKY!^Bp&M8Fr0qhA%@tR8)!+!l*1UuUzZA%cU zvQp7nS%NO|FdIwqgbs-E-X#10_5`K)G1T|ZaB{}d@Ga2E%7t}p9Xxk;Az`~da@-^Q8OFH5ExAP!(1z`X$X0PG1mswj-Y-#l;x z56)bq`hP&@KkJXz`0H=!{3j0h%eOy@Uf}h;&xI%WIe7r-lAr&Wsgp5li9D8TkY{db z4F@{MLXyaLB@SR6z`cN?mZtCo`TUpSb9QV))4pCDJbeO}Zr#G?Prt-BZ+T*%lSRix&_X1r1CiZ$z(Oy0ZueV4A zo2dRHtu`ZXa{}t(O3;~Ihn~D9p#!)Vh$An6J;8M=HAmsKm&wD?P#2*tcB1~v$5Lri}k4fY3@b!@8y?=n6355%;`iRLlidKgbp|v zdtUef>s2pzz^0Q&*#3G!TkXM<9_+^X5oHC2Y4r!o8@UFqK` z6d6TZg$_u}jSzkSdxAU{;Mt%QuRd21cB&f@Y~qfzO~joc8Q2k9EObEimK@;+uqViK z0iF#?@oI7lV5O^$&9>%<^Y=n-TqKwSSO*j(#R@-wJwcue@N7_u|3FP0lgQs&6c_~6 z#1t47mkJJG9bi&cDf|HT1bHsNvq33-&O8nB{_J3E8Ukn6R0M{WAv&&3=zy>Y^6|(I zU{8?e0z4a(;uq?;V67v~R>N`-lu?6}sty!39uPW!dja+X*c0Tr0M7>B#&ce8ME{S} z|J(gP`+t1?kJLZwf5vnDx3#s298a)m0g~M7P!YQa4S7T8puU}T0QUmy2e2o|a{-A3QD!NsDq&sk;L$b{&EPSO;(~u+Qfp zcH8bjm3AYt<%>l=K#D)x)rA{F$8i7rRXn+NPjCS10PY1|Q9sU}AkPJOHpuw^Dc)e& zB3P5R?L*#kDEWWP0jvYK7hpetJwcue@NAIt0aEeE)EzW)o10|6Ukm6TPm4nezEqLkLA==tcZ~*H7?gcVDq7h>oKxe-#OjhZOe1H_c zeC`aaTfG9Vq_0BA|6>l|J|Hzb5D7uP*y8307ZXEl&`=Ti04e@AD-`j`dPB@|^T4w3 zNWlTD1GpE^Oi9Peh$zUqx?!&IMv)JY;-^es358`FpsnW#OPgr8xTOglz`cN*X9le8 zV@UhELrIx@e#!?(@iSCyu*%dACO*mVAl?hk+%9xLRADp1vg_d@K- zoDm8O3;U)18NX(x6^xgYKSMJB<^a|K3EtJh4`5G_=K?$%G*|M2<{ZmWcuS`mcm(dE z89<-l0M-HA3$P!+o*>T!cs9uSfDIP)qwrqu1tDTa64I6y2o7K!z`X$b0qhC#T!3eT zaWm84^Ks}X{PDJCT-e`_o5xNI4qzR?y}(yD9|%v7=K?$%yh<}d&In2W``0a+4wKc( zVXw1BZ~*H7?giKnU{8?e0z4b!d;n*Jr14qzR?y#V_G>e98$(@iMZDA)~H|aVDmM16T(vqd5Tk0qhC#T!3eT z(=@a&ebJ&(_|GQDVa|LlEMI9RIDmD4rA?IR2iOzjxd6`w7t3p7&fEo~@ym>S@$NK%>(f^$P8L5B9bNx3qHi|m7TOA5t z!%V>etON3bccCb}Q+R?r7s&8x6!`$o2ysp@C@4taM(_&bbfGcFR&W680PY36Y2MGC zAkPJOHpm_!XM{K>D8*~8FM{=^TEPLV1ENz0ur>3r@C11-5E^$tQjxni8CBZxbBAI^fRmdE7roTAMsU zo(tSMdR*iKI3u*DENc{AWBNGgFPS4afOP=(0&a%-!V~1VfStCQ$OmvnXvKsvqwvR? zcH$ys0GI<<2i&7te|Y+$@C11-@Nnp~$Omvnh_gb{@1OHOG9P~=IDmBk_X0EJ770&~ z=K>Sv%o6#4_dXpfa)MI4>((el&fds{;+ae0vps;i+liQg#H=+y-AZH zBfms&0P6tm1*SPT3Qv&d0uzi){*e!$jL<*Be=>FwCQMo?IDmBk_X2A)orEXIbAc5~ zrXnA}8KHlM|IJ)&Od{@J4qzR?y@39vIN=HMT!3eTT>G36;+){yKR>SHk@NrU{NLO2 zf2saw{7C)t`E9bqo$5MN=m72o*biV&kmmwC8{~WdXM{K>$XQ`ePfsjdxKQv1;}^WY z8q5K#19W9wzLQ$fwa@KY%?!o(u47kn;gP9|nVSf}9nW;ya2`!5qLk zfO`S<1K1Pfxd6`wIUm3oAj3TrHm+O>_5^t@z_UTl2XID+{~l+B zrTBxC|78wf9l*T+`vL3;-WfOoo(*z7fHOi|`d;TetiCq)c@P_zmfd!Kg<7k&|G-_{Q20mYZqKxTto(d=YXcvFPfQ| z!N|x6JXhfT9)9uu5bqIj)`0gtY;0_xrl$4||L*7a?(_32*N?L^?X*x`a=n_En1~wY zTIRat{UCmEMvr#|IV;HdMQdwok^6u3>J=_f#{J~UlQ@3-I8K~6fuSMt%;?N(ZEZze zU7a}N`S(>-RVXel7O%oW%JcgA;vN3o&+pym=hv&B*RNmWB4tue(LNs6F4yr<@~Hbr zzyAN#uaA$9IMd(lZ~uDx+pMYH{runk{C}p2Q}1ow~3;q{3XyvJI@ zbBqO?J~V*YZ&aWnvj8(>J{yIv_R>RV%tq`jam1k=K{(kOhtoUbai%>Hr`n=$w9XfY zvYgNsZh;D~4WsaWS_`q&OaaB-w3`y8iP{uH)TbMxG1CN%^!pv*Ymw)wfjBc|`0Fek zh1b`XfsND0@C~QgSn?{wk*%)ji{96@C}*;d#gz>)c$A`e!)B$$S;+F z`g$1{+snYx?PJRQenQ#5ajWmbKL_cl(#IGh!u&sSeH`{tI}H7RW`uBsu5;obpvK}r;ZE#Q94bO~DI3(}J`shZexz%F1Sq@}rmUT*U|Aox- zb@)Ke8K0?#WA?^a$U7uqnM)cJ-7+C>myWp`QZQXT7!#H{E15BP`hq(*=Ag>q+r8S9A z(MrV{oeZqjNXCj)^xr4%hq<%uF?oW)FZhxD{r&m}an$TAF1tL$UEi1ZBJ_KF74H^Llq|pJcTJ#eT}zmSBRGYG>c5()Z~H9y&(u4h(`30L_`fGApBq~0{3l!d6PTTN{j^uNbxde6Y!Zo z?f-A3{Bah|>xwCBSLp=nN=KNN*+RF#6pNC`1NU7bI6#V@5u6C+UJ7dKJPjEe~q( z8JH0ii_h%*1P4g*@;3Qc8&m=3q!#!U>_J%NAY!%;A&OpGstzHjct5OD+M&6*UT}aE z|DN0?OwguGj6(tpd~;wHQUcqkD%eC;!6LjIdI3d{x5>h6ohZQpQoO2qCJZ*#z=rDH zBlr*kqfa6{=`6zH&mt&xn9hZxaCGaYeBn010aEa6j-hp2q%+Z_@q~Z*qY*1;B69 z{|n#5{{>%!yb&D0I$&h~cm!X+yb-;c`*GOp6wW$c$F{wg&?ygE(q^499Ix;E?GN^cnP_O|21m%MyeRkm9vu z6lwNH`}X4lkvt<7`LbCkmd`_}LIHAR(~vqR77>$u1qZMWkm7raop8J<7FYJ>P~BJH z%QKC5aj^|AFYm&$vyJ%T#5TbR%mJ(er1*UAm8jZkK{-hus{3#ZH7Cm(oQ{D(xgBXu>~gHQa(13l3l%AjPZYZGc0g8v^%k zLF|zvWSz}N{-qKWUMWM?g#sj;Oh*WPKggPFl`LI+6k8h#~k zN@}J$--o!`A!O}7i~OETDBN=e*}E?yvGEkbDh34yunv&o$F2#)D*HGX`Q^esrW#(9 zy$i@|M^FLn5M;E%C4q9pVP#lin=N#J6t8Po32V1b_(mK-MDiJ=7TrKr`Ca5x-bZTT zEyQG8rhmf|f&*9wNbxi1TwJCa58aK0Fn6k@&p{jQTXfMG(1T5WyJ73rg!L8`P}NEi zI^bXSAqjr2XHSS#ivb8!1krv(N5?6faM{a zbR#ViKz&HiEnM=wisN>t1P8DV;9fwAw~?W}?{TzOFk>r<0CNEA0PY2( z_>#zVXv%cQp2{sa+M0ojd&+R@@DAKPQjhBc)fn!`797AjfO`QcJ}gNE>18IUYIeg; zs=))t(s2B25l&nz!jZE%=s6T4IDmBk_X1M9k^RST^jS#f#41E4=piZF3|U2X$S$!* zdcGy)sq_U0unyo}K#I4jafEMIFk%lUA@6)Kw%y*2mPc)9{gQUMA2p-sdWGNs)&blL zNbw6pXQu=Op116T)eFCfKRN7rI=UN>TE4Njx}%R!wD-E;0M-HA z3rO*@rs2@{%79%oku>CK0c*>V&~b%O{g>Jl8lI)HltDc;1s6&@i2v?o1G zb$=5T&5u#v{S_LzU!i8_3*=Tk5FEfdfO`QcUUqo|(4{ z0Q&(W`^O{rjy3ym*mM{dy>H{r)@OK;`+Iy}{h#=;`oHj|>@R`?SO;(~zF%%|JiojLPtNWZ9Kbq&dja+Xr1+=|P2^Qu z)1Ffx_7A4xbCO-8*@N#cCrd%N%*7E-2sb zgUTJ7QL@cLZ~*H7?giKnkmBv?>Hf&Q5lBCogY8$hqvMMX^uO%K;Ojx``+A??0M-HA z3$Py`#VbXr!6?TJo;!RI(-V)}qXnqGREwG`J5YMAQg8t40PY3Y50K)`imKq<)Q|QVgwoD_DrLEgPn!KHT_pm+IvoL0P6tm1=tUe;w?9I(9XnRBo|yl zdCMKN_C2FrtT)(qf_C2zzY!e3I)Hlt_5-ANh1GG;H7TTfmzofkxF2anr%_UO9c6Tf zR$lcL!2zrTxEEkQU<5z1zkk8`5$T2cjWd#_#-UIyAJvrkZ8P49 zF53Co?|49P0P6tm1=tT@Pf&_y?SH+$1Ye$N#p~;X_`~CK`1`BdM0{Te4qzR?y}$$V z1lSXl;;Z6p&{-0U!;NXU*jI&zr*`A(YX|V%-66cVvRCK;?giKnU{6qrk0I?}QtO14 z?lANp$-$WmwYYV+3!i_v4>#|(2_3+_0Q&*#2}<$iF4HL=y#ia}^^lrljp9l#Y-aJ@!7?i({{jVfe>k9Q^G;p#!)VU_XF8 zK`CCDw7+?w4SXB?>C8<*>8WxwTqh2G(1F@(^+E@5FTj2PdxBCtYyW^*!Nb^g_5vE|-nO#g zvqA@OFTj2PdxBEDQ*tvRs}GRYKaIM>*U@|F3k=a-!870E_?17S@8s`=4&YvZ{Q&j^rTArP@i4L}g|J?uY)b7J!+q1YBa2I!zUf@O9&-lLXzwl!-@Lkp4L@#hF|NS?M81(frz*4U0F z<2H0ycMA?+9l*Un+0sJc3Hpq&8-+jKvK7}4l;Vq1ZFqHU5WoNY9RBw5mf(QDJ-Z}& zfv+#_5}x4j?!-~}s;#!@C<(!#rZimGTZsp!+VPxp#LMgbczV8D^a7`LXA4iTG1Foc zJ~msI>faeHR3rNjlGk{a?jpTKcaq(sJTU11?gcvgqpAMgsQwK{;Vn1Kr21b;+JBv> z|01gYs=6S-0jvYK7l=+-Cp!*I<460jiV*9SULI-d!;1kvjGl%U^S)2aL`;YAJpLMv8+acfLaq>@i zQS=}9e#d_c4qzR?y#V_G>Pr9TNB z@I2=S;RjstxhLiVJR6ka^Je6repLfH40|!)G=$TE7X=5f4&YvZ{Q&j^c`m@SK`Gu- z#vWTIMj>}$HcDytXNNB37B{pC9nhfLB>VvO1bHsNvq33-s6L8v{snXgUjv?<--Fk; zhVa9qvqA@OFTj2PdxAU{;Mt%QUlwJ7w!F=h%}>P1jzU};tfw8Gok9oPIoc%rfWwW6 zVlKe5K`A~WO&$4Fwy4_`fUbQ>ICQiar_R(09dP1ox$pzn6Xdx7&jzJUqPH|kP^ z#AqWv%@kP$PADk%5IP{YgtQU)0qhC#T!3eTQatPbkY3XN$1_oRz7lP>+OX&09-#wv zf4*Dz0U5)&VlKe5K`CBwiwcZ$%;8?+g^2cOWDaBt4qzR?y#V_G>T=2e1yvX&VxL0DFQw7vR~T6mRL$4*%#wNGdo_ z|HjwQ)cX(}178Xq(6a9<;RmD?UKeu#o()Rz@~dN@Z%+3N`ZQ3F(1XOhBjg;f+km9Y#{|o)t52>{8lTSLIIe>Kl_X6w(uqViK z0iF$VK0u1^-xh-5_Eg*&tfafX$@3=;U>(4{z{|^h!V~1V0M7<5Xvn&;i^FuphvlAkPJOHpuw^DL!zk67_yYbmy@fTH7Pg-IpwMz=6Zr=o?7G zu6+@xYH>qWrK!jVNb&1!K7*~tJZuhCMnwEN!2#R{@QeKb_5^*xSBlvn=L4j8^J+VI zlCF;%OhUnl0#se75;}l;0rmsf6O1{WC}xA450K&)2P}hDqCRYk9kIDS5RtoMgbqm9 zn~do0t-=$uA#YGG(@5k4r1H7QoKbZ%^os$A#VF1a_Qc^ z%D(eL2XHUIegJ!dvD=S`*&ycwqhX-47z)&blLuphvlAkPJOHpuw^&In2I zQM8kvH!}~F3flw+unyR3)-U`3_5^t@z_Y=E`B?~=<6$X$a4Xn4SK$BB{D+N_wOn7#gT?+oa@Z|2M3T2;9lVA={DgB@?3ytgU6a>*WOxV;U>$I{IbHYx>%-kBBt7*Q(e=Z~*Io*3K=$ z4`5G_=K?$%jLTk2I&StTysib!|D2}5(R-2L0M-HA3$P!+o*>T!cs6M6I$mUir0;K7 zWCjP~p3NP>f&*9wa4*1q0DFQw7vR|-=L1yo4M)BI6wd`vico`os-fTj)&YKvfx-`9 zPmt#VJR4jdr;f4SGe_aIld{M^sD$fw@~?;kSO=sI9uj^4dxAU{;MpMO1C}S`jKYtz za)!KD0MsL51qZMW;9h|J0QLlVF2J)vS-)_R5t9D*8wHlYF`V95J~hIDmD)t>9O<7yd?gf;<eB2XID+bAoU0 zA9D_{bRPLVOIrm8unrh7JAotCXM`unbAkPaM?^k=GeVpbl;S;PtPwvpT5tgCfI6jm zG^@4Z439Kbr@(%yW!>!V0`f;<;E-<2-%0h|%)iXHv_N%jko6`&(HfOSA? zt}k{M1qx4)=K>Asl;xp(0B3|aCn){?Z9G4t{LfOs0jvY^DsAW)2oAy%J6!`$o z2ysqOieDHK2c480!2zrTyqntKzq3Plf;<;++1@Pj0h|%yoS+mhqi=$#cCLa0SO@6F zCBq;wU3h{#7g!UqRpbLWBg8pDDSo+gI*dcg1P8DV2rlWtmP)Ec@&tJ<;G0W%Jjw@f zMu>BQQoIc1`sNvI797AjfO`S6kOJWe@?1dAGhO5ZI3vV4K`CBYBbW4ht>6IG0e(>j z5xn)N@C11-;1+a1jVo(*z7fHOjz6XdM$+xy3iPoJJBIDmBk_X6w( zuqW81bpSjYc?*YyUa#mQ1 z=lmaY0P6tm1>9&J$etk21$Z{d`2fxc@!#XDuoU08MGwpYtOK|gU_XF8!4u7K;MpMO z12`kZIYG_}OYz|bv%nm{I)Hlt_5;`xtfm*w200(V86nOIa#mQ1H!`REFL40tfS~wQ z!~^PJPmt#VJR9VEfM?hoa88i3!csiv|Cj?<2XHT7;y4BD3G!TkXM>y%;EWLeJ@K-GFJ5L3(5&{R#=LkX_y4&0M-HA3$P!+o*>T!cs9uS0L}<; zPLQ+0QoPI@BQOWB4p_1=80-hIC&+UFo(*z7V4QjoI48(iVJTi=c^sGnSO;(~z);d@5D{q|eI6aP2h-|fHuzq|kbYwzFx z+V9Wj{DKAK4TqM%J*5sIg&o*hOFI~?N07bqIL$&&BBSjn5^4vrrKA^bDYTCrUX1(q z?~7*{kKpHNdyw}T1p}XKSVol7uEP#^q&C7ctr@O_;XOzL-)yY1jmAR#&7<&R#>}C+ z71c3&H9dpDi1rw*>CRK~Pt;uE1%^G9d8*EszF-~3k6%0r{}J8a_{k@q&}%N;&$tW| zr)gmFY#mIQtB1+6*5b3zR$@8 zj}?n$F@MI?QTWe3d>`XK`T#S=)BT%MCqZuZ3@FT-jivMFKz{Bl$kH=EW>21oDdRrD zxDVbNh0n9nM}x}-?Det4kq`$AN4eo_j0eugd107-J-WpeJ%J9W@vuUM-G)(kyH)ZC z)n17#<29(X(nXzc@%!i2QrxbA^Dr*KZ4rSPoX<|67=Uz zfx-M~(3v|GDl;cy$)ry)d)&tu|NiLv4>HrWP*q}tmL1mUZrOzXPH!CS*^I+`{L$a# zi{5tH`=;zw1xrYz~w|a=bF~$+ImhGDKymF{;aHr>k@W3Uc%i6R!qO zzZI}>TrdhRt4Q}V=zfHamQ&#DHWxmAa_|pYilERH@C{IallvkVThqO!>n1>M^#`Ny z6Q|2y+FTjP(brk6Ap3v|5&2T1Xsd@`2mo9?-uvIa90Ofg5z5ep2wF>kFq=4sIV zsVl57X}UJ?gS_B?5&X#g1zuFI!BqPRROcD=yv~B;c$8ui3mk> zfUn?yk^Sir{Cdqbu%hSxxmlYdfH)$;*AuZpn-LqhnfSy9Vcs;0ATDq;HxV2l#V?*c z9m)!eVW6%83%Wbp(aad`w)DJE;u;rA+Ns@WDEL5Id8Ob0DSpC7?_=ipPqBE`G^|)i zvk>}PT8c}tW`zRO=pI}pxrJCVcQ)ovqi2K@2T1Wv&PMdyR7;$TaKYVpFFZ*P!1KH< zc%BoAFEfL2Cp7@Wv0n6SHD|#AQhbEABJwt>qt1@*QSmUv0e@Q@4t1iJGd+XF0lj`U zsB@)UqNTpz04ZL3_GH*Dorf@uWk@kpMWH$ENZPGKxvc^6t!SsgL>mFRDzH^vCOANf zpZAdrR*e4`dNaqvVj<-q6lTL?n8QWTj~#F+qi% zC$bcl4)X*DNbxh~%RqtZTTA}~7@5(XFLsmZIYcvI=QJIb_EWLJd?GaTKY@bEZv+R7 z;CX+K&#-{JHmdJ~*mm$D+J|pr|Fx$$eD@n1x%UeFH=d!B_91F1%gh|WI$-bKy`ug{ z@Oo6U4pjTW`Sfg_?S05=JBE_ZVU*MEQ(?zxq%<5tIOQvu16T)0@iUj2VYx*Z)^E;) zV{8?Cvzmn#2`}jue6or7X=6|!R@=r19U#Sj^2tnmHc1t;m2Dxr&I?M!BWiXrSmO{! zzYl|)aRB|9gWv$x0VDX4`wO^chlKh1uK**YCjr@mwCfpvfsKXvRF$WEtc@GPc#ua!uPsH?(+ zbc3mm7K})j=&n|Tih`Wr0M-Fg{2nheoC|Zn!xTR}%in@mRY{Zq&%h7$S+vKQgjdBe zc$5(&IDmD46rW|Nf;t;r?D00o;V@^MOYp_z)IeOz2*J5TKb(kiM_+)w-~iSEQoQ-1 z83E{!~MOj%f8|?l3{Fr5*zHRD}+Z;uXfek99LXg@fD-c(0U2 zxaLws=_n#bPYEF!E8wFnC-{XqfOUWr-?+^J1G_zOb}$mRPAB2>i~0EKdMTdYET?C} z<>KzS3|u%8B{+a}fE1q?r-YI`Jv7zWkbZC{?GTJ(`y+6I?o2qmHw61Se6X|8L2v-; z04d(c^fLtbEkFuoqlx3mqWEFQU7jwDsPD zmF)yunyo}K#E_e?}N4O$*_woLon@6CvD${+}5KgXg`6hrX$2TbdLdX z0P6tm1*G^fW0qj%3UkOB_+X8F6pVb+U>QQsaSbiN2H#AmInez_%mJhWxEC0~kKA7n z;p2f!I`{d^Z!D)>oBA3Y*wupm-E^l>YXjP<>G{~i0jvYK7Z}-}9>Lqw`RqqE%4dEq z{hg}ZOf-}iqp6|B51GpC$!3P8c zi26@!8NiOg3)oBN{HcfE;`-}9;qLGLhI@bdJMR4cZ-N6@2XHUIegN+cvHl;y+eVcm ztZ*0YIvhsJ&=nlG@)*OPzrpb1?{Jhf1akoE0PY3Y50K)QnufrT&VKJ?%JA5*w4Yh&;SO;(~zFhs4 z&-%NU7lm)=ncqL|D#g$3W%$0iP;db20PY3Y50K(Rlx2}aXMdyHM)XCv<5YSWu9YU? zRz)f<7j6|Cz&e0?0rmr=c!OzU;Vd^3ks3>pPJKuzam+S%bJThe*V6kj2e1y{UV!}o zDgMANH=I8hfjj4N=$UUd^!(R0{OQ$RdiHZ4{`j&-Z~*H7?giKnkm8Fdm)*S07X2MT zID0r1cP^CT>Fs(vyGJ?l8+30BaRBQ8?giKnkmCJ)=8Chwve=Y#f;am2Mq+q~_~t|g zjvq=A9Kbq&dja+XqU_O1qZMW;9h|JfDwE_ zL4kPIM@Gv*G!0$FzRO?W%#$~`{rW%f#ozu5kN*DOf&*9wa4*n&@~-d%OG`^d{g2=s zsm7v8I#ASc6uXXH$I;s_aP`GcxJh5<%;Vn)9l*T+`vL3;O7Th-;V=)$hks@r(x`u^ z*>esZ$M0hQ#jntI^p4O0+zYTDz@DHKKVgPCc>|tMcZh^pKswyFmLep*4qFOZ1qZMW z;9h|J0QLk&@FVvh@cCLqTD^{*ebduahasx@b3=!4nSfsa{iw zLn??vTB(mMz!G1(6c@OLduqP;ef7u!I?5kxC7hGzq1s7>2Cr~_5kPl1qZMW;9lTGZkX@{rT7NxwdfD9 z!G#1Ld|n)fSIq_Zxwi&?>u_$bxIC^6SUGwJ?;7;l`u=nN!3fIUGee#4Bh@Ln+oarA8Q95XFcy3oC=o9)pW=qxyZbpZDQ z><6$XD8(P#?Tsr(66o2F`FM7B2Y&ag3x9btNXzd>1qZMW;9lUyN!sh!L;YQ5rg;9{ z$iH7%t}fc^Trk)ZiVH_G@#yL{ynMJ5-+$GG=l2_h4&YvZ{Q&j^rTAb!%8n*!VOyCM zI@~8t4i*`B ziDx8Q1g6t7R7>a?s!r3E( zf&)$-*eiO07J4QY_XjED0i;Xzw>MdG{d!~WiiR+&C= zze~@!bfB-Zna=zzz8-=DSO+janGufrgQYYVkm4_eJK`SKe|0jxqx%2j{s!PUEq^ly z9BLE2z?-^E;R#-f^%#Y3v>B;?Up%7vf7z6eA9}Xq4|}!?9l*W7)%0K-A#b3W<^t09 zk6p7E#Z><-|A)Qrj>`JXxvPs(C2PXwrM&w*`|PvN z^NS0>3E}_EMLD>;x)}G@EmS&yy}+L2Fsu&sM7F!+&9&d3U#F%>Apb|$V!==RuTBhB zHGn#Ry+E$;pPt~zZf(u*r}rcZ|MP_ZOYzy;RrvPfz4+&!PN*92<5!1NFYwu0<;oL0 zdtizgzFd0to$I6J@12EP=jP+R*Vp2Y_jll{KkUTEcQ>eB;L%vfY=JA3#r#a{g~5U8@Qj;< zkaXF_&R(u`KuFdSyo-2t!ScM&B z6XaZgvq2qyD>V@B6ei=Nidp!wdJ+DzceSbk)B)@T=m*dfG9e7I&FzSy)_>3}cR7AZgAW?q7t3vf25<1+{Lz+&$qsEYEDUOxio=BD6ANw(4f z>;>ot&=cfbfU`jzKdN0r#PsWcY$q$s6EAY9ocAju$0!|87UHS=0D6L)3vf25;&?$r{Gl^5qLzn?XL zI)ER0Hmp^iV8#4-YBtDxfa(79fB^#(=Qu;0AsT&w^y+2OCr}5l7oZJ3!F1B zAE4t0N$);dW{4ByoTdig=TZmoV|GR=vcxxx2^t4~nKLjSpyN9=Zw#Amo#cGC5#Qfg zeLvIz>;>ot&=YjAw^6e}<^y#6mBg`lGj}51TQm(H%UR7DKpntd;J-x6(-Y)efU`m7 z19bcf@4?s};fb?pq0$2+;q8T)N(ZnPpdUa_@Qlm@IU8g?K*z@mcjvg;V8!_1N&_5_ zIU{wziJUkb$(o2=Nr6};XMetzgUSc!_~Ff8Ku|a7e+P*FCmMh?fI5J^0Q~@Zf}9I* zHpqN{jz1vY{G~(5c=f_uymLeDfsq^HDs60W=1vncl+IB|i@Z8+o8vYaS5i8FH7Y&eD%=?cHC>_9F zfPMfyLCys@8)QDfBYr+~e5d{au=Y!Z>x4X21E>QgOaD$kfSw@d0-O!nicipGK(HCU zapSIN(S9g84H&0t0CfPLmrg%`o*?G}oDDJ`z>JXb`s6?N7pI6`o*^D!QFex^0n`EP z1**%JDo>EQpR>VP!b@g^^!;yN@z*29Qg_SwEj55W0{uSv0rUhp7vOA=`2c2wbi7UX z&cf^d%BN=ypblUipdUa_kaGdf20i3_A1LR%j&IwzK6;4;csK*FQ96LV0Q~@Zg4F$- z4fc{gff*qke{AAt+?pDKH)qGG8bBSuUf^?nh$qOo0B3_YG9y$*NXIYsu*HUP!?0(< zXjKEK174Yvr2GJSf}9I*HpqMcGeSB(tVb(M8`K?z?slpMPzSIVpdUa_kaGdf2B!|~ z2Y)Mhk7vkT`?7a#{QU+tmgk7k;0nP?FBV!GQ$T2HbSy^fVtCbRSlpHU@t&FfSw?80GtgbPw4@lfYxUCevS0F50T@K%pndxj=&4i^zNcGeXP> z>i8y22cYx7U{wRC14btm!!K3#!Nn8gT);I(_A>)AR7Qw7K^@?mtkuo#=2?1JvwIW&x$5_2~(6F2K6Ld;mEaA0GVJ z{xsi*ZbJrweK~6YbpU<$OqnUt6C{Rpf!;kcLd*%8?q3t%y=_a_$^4ErfI5J^K)B5M z=m~Nz;OFk5@&VNE%n9oFRt@T*eG_@MxYPjZ0QLeyt@|oZkaGdM9$i#EfEl3{^0_*G zdzc5#O!9eH14IYBJ#Px$6|bM3Am;*a&zhw20n7+(iuN(X&vfdG(vkM622ckajPt{> z$>WtL$hp9t3EnCnz>E-cg8J*bi+?|%R~uCWr~}vwEc0_#o*?G}oDDJ`z>E-cf;zr$ z!#Wt+w2rC))B)@TCfRgSo*?G}fjwHQd;l{-UFz2{!>?ZEgBRRgF4Hm?rG4w>E46XaZAU4@^@2QVYVoS=?( z9$|s75Xk^Y4WJIl&mDqd*~g|QNZxZcm@N4KW`vj%)bTy~Sio-J!x}&xz+NCSvaRw2 zIT!E?Xsq%9%m}rU{ci(L{_^||nqCgp0O|nt0`vpu2^I_IIU8g?fEgj?1UZ9CN=gEE zCJel#=VY)3PzSIVpcbGf7%^*=fEgijpIKo8PyX}#=lqT} zfI5J^0Q~@Zg5*4BgUkm|yOZ0@3LE>=27aim^}`w2>Jo^1UVPrY>@eYaeX?0IYDNHbv*Nb ztO3*k>;=5qHUK?A&ILFdWIliyA$}gS!a9DLXmZv7>Hziv^aJP#axTExAoBst2r(zf ztgw!cjTP@r)c`xN7oZeMO3#Kfo! z!06GV;qUK{fPesadwZ+riE}@JA8u}L@bK_ZSwZd#g@%U0!NCE)cl`7F51!wD@IU$f z1IYhAk$cwf-@lJ{-gyW2?%l&%Z@q=<*RSLF@#EOPf4@58`R{z5cvV%E`dGJaozf7$ zcl>X?fBpRRpWnamTi(CGGyS*RKmNVHey?7=U}0gQKI+t|BYj3g*-vbau3hDxv7bJu zmwNW>iEiDxsSn<>FnsuMrJsIl{O|qu|NQ&^b^QIU_m6+?uivLnAJnT?PxVObiNeCd zFn8|5``wu_C@CpXS;LBoiW=R--GkR(e_hpy-x~jW|NTGz{ykNGZ^DEL;w_}f&d*ep zZ7VA)!`iiLv1W}t2eY~w8#iuz>^=`_e9o@EMaM5`{{(5zht)Nj@j7WEsN z;k_pm@jy2tVc{Ni*K>Nsab&JMDfhn~#gs++C7ZMjq4GI?6N_u`Jmc%ut&28Y z?9sz+6b5)r!tjvk@Rs{t{SxF(Yq|5;XHo%11ZQE8dlY)xd7(qMfjD>W9GWy~qBH{W zb?dc4!)CI-+};}Px;vnowL5ys*Xupd2R-|HqLZZ~T6eG(FS9%9)o*ErH#7*pPQAvR z(XhGPbd|0AUi=JrEqzhiG-&S-=U8Plw*EjzD{_;$`h*`3Ku~2f8a_8oBxrckk zhHc2Lmgh;y-Mg79Wfr?=B__xnoa2*oYJPqL-`{O4oB}6cR6@Eu2WJ+-atkHrwEz?5 zmLM{3K7z93`807;;W~aI26&j?pU|YE_!E`X?!$Xf@3fuEDpm0Ct|R7 z2&{+spj-c8Xw|j9+3Q<0ZU>8IUC>CrP7BKcXlE^Z;QgJ^$<75GY@E=h*B~_Q)DQJq zc7sKOmS*_S$V9{@W+F9nHm1unLh}ksF?W6$@)wk2PH`z_&Rv9z>;fcAnU1iiL^J$g z2RFEn^cR1A0z#vbFfl$|_I2gnSJPhIwF#%$a5!S zFe)fW)c_sex_b}dz8&m@=fix)z*9cYCp-eI8>2%);T|Brw~=138S12JfR4A2dp#Pq zZi|*(yQ5>De&}Iqk6u!fdJh~7OZ!3SYTY00r5-fz*jd#89Uqt}+|S>Pl(NH^UM2UP zY`=!Wy)UC+w>-OX$4i)5eG%#9ML>$f6xne0=^ z=Ndo1fp-dymHX|p5R@|yF-1#}v~-pHzSbkPd>xWYS4&N;P<6m>@^n=LbbPyh^0#vF z#t^xqcVuiT#-`*TFe?v1!pDHLTzJQ4V3_l?U`>sPg(A(7q z{e^4R!pXiPe9_a<6CJIc(4woYssTDaHc7ZIHEPzprSh!Q)mXBk8s+P@VfmUZC|$J) zCCgy+J16n&{V*mV5`pr0Q4>=TJ|P()Qkw##c6fLN$lc%Wss`xz1`S%vY^)19ckPGX zeFvex{V)t1;*J4>N5F1?3#_c=?CfD9_x#D3AT_|i8~g7;@o~b{Or#eUV0P&e%wMw- zOC-Zyy0HoiD_0}Gq72y!=BpY&9boJa8+d1#7mNy#d!uD87$@0)^!$8GFD^!oYQ$$0=imnL3P|s0H z2k7`0o3}&@IpaGC&-*$Ig}tjA9Hd@2iryGF!UO%BhN+ss8bBSONz_kUuE=!Z>6S-cN< zRl=Dq7f`(Yvg97mB2(&0Z2neN1E>R5u3V}3Z{W$PZ(Az28J{6kpAGDKv_ zebk9X@QRYVq({fW($-7q03BcF#pY-r{BABaq-{?J^spE0FxVG;9sSYWcBIrkN3`tN zU)2EW00VFQ{bJl{tl%70?HJ5K-!_8Mw{nBfwymAv|XD?y?{-de}PzM-4 zzk&CNOT+l=xrkpNIq-`0$lJIb^S19r(a!zy-0a=RUb7jKm#kDZfI2|OcN5MI8W)XG ziRrTAHCKLDC78TmIg(4tF=^fsnI#v(PjrWiXaVW~9bdnFAGEP{gr$q<%h7=t8Z<$2 zpp)Pl5wEnw03Uhou+$gU0O|l8KSiDin47;?o|nE3E7osE)%JtfvR6Fs{U=eq;}BMF z+>Ip_8&nOT4$$#q{3B&AHyJ6JdB_pnGjCCaJacgk7D@dpUc3@{@-wg|um(^E==eVU z24k4(82C$#i;7J_lIXFi)8;D8ku2X^Tw)f2r6!CNO+X!>;<^7Ckt*N2oclcUOV+K$itSrabzncL5ADa= zy?d~9;|5g&r~}vw82iKg`xEarE&$_1>+{UdES!hA%a>!(+Da^vIYIHNmB?ARP}KnH z0G{bOzSp3^a1^cYEoXjsatbEr&cyVhVyPkXF*UzHbVrt|0n`EP1$2DFw(TYV+fSYO zgQag6KGq*z(vOb{4THz{Kn#&Oz#2duz+OPdPg=MO(>I($@jiL}@~OA6;o1k-@#^Q; zb^9x9yY)w@1s|vyKpntdz`&Eg%Fm0C++t28QkU$-oa!?u-G5VdCGMc=tlXV+RQ8v* zUQsoGI)J?Z^T#~@4SZ|q39Mbi;3k>H(2P>V&y(lT%6%!*%MT+>bVQ`&Ggt$t1K11b z_!mX0hi$#5P!84f;^(A#0GssYpi>;(+G@%Kv>%|CnRK9rs~ zgSA&~VEe0YVE^5Bap;~rhwjcjY`XQDssYpi>;;UU-@yA$or#I^9-k`j_kyi^PI7iFLC^hs3%r~}vw&<`;7hYkEl(d(gd_9y4f!klGG zu}nONwR?7B{ocJ;wPTyA0n`EP1?UUtcq_-Da`sC;E-oIEXXIjr)QkD6R$-y|7xT(w zmse^4bpU$-`T;t=X~!<2ouz+p9f1-4<3vM5Az1p5(8MHpy-BJDPzSIVpdX;)6G{(a z*49f{cJvKYUzYd$>tEo+yMMvS_x_5b?|i3f0CfO+0r~+3-dFq%^4~LVzB>D}S06#? zUU`1~rFU@nwNG&5w%na`^Fvhwr~}vw&<~(TNd6o64s!Mn92F~m!F(jhe)Md47H#Q{ zE3*4^6Z1D;R5gG)fV}|y03BanbbpIZHt0Fn2ZKk8Rt%Ynv9WpZkDHCrQ8}sxPzSIV zpdVo1jlW-77jL|-Y5;Wrdja|ZIzBXdvO4?c z&R>p-%FWm;b#ni)3pjY<0`?p_t!e;u0DA%Y0Xlx@aBuMrq7j#zh1@xE-$Usdtd?4| zX2VXD%k$1z1E>So3(ybH@f|z&ML%07xQ-mFzD}e(?<9UomfRIE4Kd=$um(^Euos{o zVBn4YWorMN5~*FH``7H+iCrg8;MkQbICJYIRRgF4*bB^BvRHY7#{RH@=UE#~|50>* zp?KXZw{OFiBZsASoI=&UeM$$g7oa|%C#d7Cot@zx7=#evYf4@o@|Vf8f2!o1*|uGD zg!oaS1K0~tJJ1u<@znl32Modhcge`hc|SgO5~5O45i1zh0O|nt0`vpu3F`PM6^Bu< z>l&7ycmtcRy^q6pzQ(x^WOw=V|EL;39l&0Io&Y^T15dxz%F0T17Z=O>f4k%)IU`ETI6imrDGNJY@p#YkJY1M}s+w6$_) z(iYJW<$GRII)J?Z{Q!D`I=+E;eQmlALN5nj4E2qNZ_EsYr!7Eq)?!ryr~}vw&<~&| zXyA>%U*`JFSa|pZ)?B!PU2^uHeDDFT{P9cN`tx_H22cmE7g&7kjPeAHpWncb%gM)- z(iOt-9VkC4_d{KK8AslF2dCcs5PM&HOX&di0`vpu3F`R4!c9LpuVV{JWRHA37VkWO z%HwCT>HIZ$9`9+T15)HXq#r;}P{+5C_rA4gW0$a4_$Emm$(e)1c_m1hzf{!#>Hziv z^aJP#>i8L={Y!;sRonIpZ_nf0)mQM+?R$9r?e|p;pblU!P*%BBd4f8g+CP0p0g4u_ zkms&%$L@nCas1p>oR_b2=;TGE1K11D51=QgI=*?g9_T4O#6Wpg!AN;7f#QF1nyLZR0jy6$q;Aj?Y$yEJ@yRQWDE^n7xQ$I$ z-@}17zQCFHzEd^e*u8I6FF-$l{7+wXvIakM=1lQZ8e>fIQh9#tR>@Aw{)Fr-@4Egj zPRV^q=j0B>L$7|UdV#_%7nL^5%^2ryf2AuooGt~=J%Q;R@Fn8mQnxEgm2Z=sS zCjaHRePu^ZVB0l0H{Q5|qtZL%nQJ9Z9dF5klSSMRDCaOtHtR4=e?pZsmb6U-NnL&rx- z&z_N+ulT=G{DYkbj^pT=D>xzbYv0lHsux&PUa7o+c$p#S_~CAT2$CLRvhaWQJgG%1 z)}u=F(#Gxkl@4GpkS@LmJwa-D9p9x#fARa=Fj9U8<3nXvl>AT6RW*P*fV}|g2K$U2 zJ#B07#{PQrRJotBcpm1hD8uqi8?j-Z)ShFF z+?}~-5lV#bE4FS?I$&v4mGT49=FCwwg0n##-$#6O7wOpp#OI3@Ze-0XR5gG)fV}|y z0D6L)3vf25UJzP#wa;U6-)_^lj|C zc3%+|^aAt)=m~Nzz}cXIH~xN8E2~ko z{|Ht{&%Q~xyYKcLRRgF4*bC4PpeM+=0B3{7&u`%UsQ*irVa7V~%J&?UUD1o!diAE# z0qf6SQGURz>TPN+z}cXVw;vlW{%JZQg{!HHW#%TYv2fcSr32Ut&<~&|$hiP@ypC^W zBff{s%p3!w;1!#Uz_jUz$eyiqK#=f&egHi|_6VE}>iFri7h+LG6)J^u+xH#E;Zv7z z`qE2E2e22QA3#r#a{28b{< z)bT@xjaIY6SkW$-Gv=X4K9@CsI)J?Z{Q!D`oC|O^sN*|`{A3#r#a{Dg8Y) z06&*HfFFt3Im#2H_ILL7QTYHJU%$2F2Q2%D&n0(Ui0{uDKpntdfPMfy!9If>)ohUY z03APJ!7gO3JBi}mH&A};byWkX1K0~}xFq+NiYLgq0B3{D2N-x}ESUFm5&v&oMg@`< z?LeON03~u~33UK_0r~;-1UVPrY>@eYDdJ_2{|3HAw?XLb7@+*W;Ebh+pCdbzq61PF zY)8VpO$f_eCca@N`niOve1MLBLHxfa;_Y>?l3CBN@u~(;2e22QA3#r#a{=WLMq0ORL3@T28?4Hxfgs(hU} zo1|ykdr0X3_5$<+=m~Nzz}X=40Xn{qXMo)QkO2P-dA4T3LfI9sP&y!c#X4jzUyXRt z@qywSdWd(%e1MK`Y-um|Kf1$qjQHJhjP44EgSWX%%aFd5!bCz%h>@vYi) zN6$V3;o$74z7A^ubpU$-`U>;}ITzq;kof>pJon!MCdD9HJiz2Ra?hO90O|nt0t+fv zDNm4d0nP>|NuR)skg-3^zd!K~UY^pw2O=OgR@DINfQ*8CngOr|PzSIVpdUa_ zkh-6So z3(yasC&;+~XM@ZKc*RdO!*_L-=Yz|8)-`6bssYpi>;>ot&=cfbfU`jdnGsqJ^)kcP z@7xdc0J;wwrD_0m0DA%Y0rUhp7vOBLO+QDK5z@c^MB!z&_!33ZXR`)S2e22Y-f>WQ zf}9I*Hpm$vGeSDv+dmwk(Q<=6G{=UN2jp$NC|>^+ zuFsenAS2ch-AbQ?L#EKt4PmsJ1&R(PP0n7+7 zCm15X3-aH<*KgJhO*`7E8bBQ|$U7d6W2Y!jkaK~4!$VX)fEgj?1a-Vc-A1U>Q1XpZ z1E>So3$*GwKzV|k3pA10AoBst2r(;U;ElguaGvxXOUhLZpbp?HV7{E&^aT0uc{}#1 zd;l{-k&^#0etrW#Bs3Q8(sQx~PzS^LK^#=c9kGzrL&Fl6(RpR1KgG zm@M8~TJ~J!36l5m$7qDj&cZ zKJ~kfZ`imknzih#Y5;WrdjUJ~`sfLAE?_C=KJx+02-R=U>M=ae?~y^{)Y(iOz+QlU z06jr+p0h#b1DFwFPLNq)V}F=`f8u+~2WtRz0DA#y0eWuy;B1ij0A_@k6J%Cc$JcAs zTHgPiK^@S|)=uic5XE=S1vndIKA^LeHJB4*R#?X~|Hm3Y9l&0oNrz6LCrHk7HpqMc zGeZ14W`%XUchVBD22cmE7oZ;*Uv zq$kL^0RMfs{C~^{F(=5Zu#bHziv^aJP#axTExAoBst2r(zftgw!6)TJL- z1E>S~ibqF3fSw@d0-OypAJARSFy;iA71r_0|FH&82e21tDRXXmg46_@4Kg3Vj1WJM zSz#T|vzs-5I)J?Z{Q!D`xdltW*!(5Oade3hVgh!d=z?>HzYVegHi|&ILFdq;J>PTJE?M?lUW_5%UmB42w zS5{VHx#S>u#`E77${ZtK@)7))BeM|RwZh;3Z;k&g_s^fd|9<`Z@7MhOcy>MC|L>sg zGUJ{;pDAGMMRK=|A0x#_bQe#8&pG1<^UmD!9XD>AI{Tmh{+|E-co*L9@%{6BfBM($ zPe1?tJ^%f&*Zcq7zyGb@KgRyH|A>VM^IVTu-+h=8coG>Amyi{81=A;7lYd@9TG%Nh z1?@rf*i{Jhnpd+wY~byB1;W`T1zv*-F?LuPLOj+YV$=pij;==dsPzbRUyd;@d2&al z%%l5{H^aAR)EgaJImxprWIoUey@Qx!_!_|K) zyuuGkUiK7%QZ67Q?GnP$uSkyWG6ECNiT8N~qXM_f^HWxv;k$I7ieCNa!gknlIC!pu zi{BQE2-pty@jKxr{~YFB1&86wDF|K^2fw^X zc%%iI;k%8pL%(3Tw;@q>&oX58lsg`yXNSONZWu<-3W3`+@qZJ1U>_>8SZ@b2yhV?e zXlyV3@9@6pKE@tafzIe3>I(Y^nTduBL*KEo*Xv=2)(*YUQ10=*diAQh|J!)~Su|?^ zi&l+b(Y-ld=qr2B13IAbV97){bU_pQuBd0z9(62R!J>ULSTw0`hIbdAJ5c7;u`=gQ zSydsvXC$me8gWlnCCuULt+~oO?VR=IMcs{$pVo7J|M};(Jb%nMXu8 zx&;TKwa;iYa&>`)ovk^(z1)A$r86w7`oLm<9V~_pL0#vec+tffb)6hxF?b*>Z2HOX zNBqy$ZEEnw{&uKGm2h94vk`IyIni%oZu|ojr+$dS$seE~={@Adzkz8JE+HjU=HF5S zjQwE)?`)HSQ4Vr9#PGF<8odJv0dik(@Co@ij-;bpSlzX|TadoX6=5dJV|cf?`1 zkJ}1I_Z6xJ==g?>$o(nk-fu3fhc3Zj_mvnbHN$!II>|e)!6271+272U>}I;E0Xn{} zh5X$uJW;P+ILMy+fHd{)iwc5n?|6)i(^#{(D91<3npN~swqg^ zn2wB{vyii|0Mqx%4(jfiNZmR^>Ols=OOsR$(D7EGa&JYF^hwj@4vhS81eL@hVp)>< z2wxnJ!1*!onH36`WM5SSbbKS*PH5-W7rg@=Fd)tqPANWc&+^BJ%mBDd^}*1D(dZvC z9G0U7s~Vu=Em{lrd&my7eFrpi?yA04r_ue<$y44FBgOxA>5V1>x}aVk;fd4$9UnYT zvMs{>taY;MzHK8G?%#>h!~3x0@LnuBuv_N9+oT>;VY2MUu?Fb)KEhGQDU&fKSN1L> zBOA9&o@KeB98*@7Bfe}oq9s!^W_BK&(^6Fp(DCGc3$Kyr85{(AnZY^Byv<#*bZ%K0 z^7E%kT}ecr$Z)jx_fs{%4Bxd2Ec#i&Vu;*zJz_XojPgVWUzs(H@kT4}QE2Mnrs{!( zU4K;r47{HXV-cRC7$e;2Ga^tQdBk~*)#vf2MfI2|O_iX2fL6)iT z8YFkcxL06;??xm9?m$xTE=&s8BpRX;e#7Tu#Na7P2k7{Qb^4-hBR5#K4Hn+Vz_E{H zzHGAKYCB!-!B4>e%So!fum(^E=y;E?eej!dR_^Jzg@pNckzV$` zu=rvb=ABuLyu*_1+c8Vk0O|l8KVXvhBALGMFOp}JEtf3pTDb$FIu}`+^N_S*I$~C) zA+#h;)d1=M9pA!P_BX~4#NY&XsUh-=)BFeoEr>;kU;+wdr*CEmTvB{tE1G~hK*w8j zZi*M}Hr--anV9#R<4ly3S_tO z$Udw&BRh1Czf) zcEYw)BVF`E%(7Bd1E>RZd?Vp(x4?05kgwx4eVS;IxrkUeA5rr40;M+j$lW_mQWLDA zBb5%&@fN-19?HRk(A>iv9sPXKJ0uwWq$b%!MWR<|2)YFLOMUTtSOY`{nBwVY#rvH` zcJv#<{r9k9&ga-v@(p&E{~dcOe#F+&zhP~`H>w6u2e20~_J@uAZ|}i!-@oS$BnO=k zt?&{`GTugcp6tEO{ure>4^WW&s;U9h0qg~IymjYTjOd?_@vh~F8@m;m6C^)3`7Gun zpTo@f(?|~8t!e;u0DA!)-~2^KbZa>dwp}M-n6+d^9Hbr%FF}CoV)!@}!qqNI)d1=M z_5wP7RNPU?=3bZQl)Q!ME8drVvoBDx^BXMQ{XL4e{ugrBe6DH$bpU$-9dGAWDf!%; z@J~FBi8HStwfHu2%HGC|^;Wi!^lz7?x(Z9vJT<*Eiy2e22=@lL6u zMC*sjd7psP>Kx?mEk@DtB`7+v9CHtqAY)sessYpi>;-guCvR)m#kk0MC(k)5l>N2k zX-HcucVMiaiOFl^&aFj>ss>O8uouwr7JXWvsdG1U_O_Aty%UDSdBQc-7b8-~V(4Vi z4&g4U22cmE7trxj%1e>IRq{Ru_h8-G6WD&^5)Qm}3kTnL8GBy2flXJ=s~SKZz+OPd zdt{^|yl5U$D#|f?%LXjkzek>xcMK~}9mld`@;r^5J5&vz4qz{!koPP=y@Xqn|3Xqv%B?ss>O8uouwr7X7W!*mXEMN%qD@vY|sItK*)U0(a3H z&XXrg9f(pjfI5J^fPpvmx0A+RLEa?UQM5$O8uos{opyRz0&&d6Ex8&Jo_fW9mGc4WnEhRp z0DA%Y0Xlww^!%O?dl8m(R(4KbLEh?jv2e@h^32mOP+0YessYpi>;>ot==k=%XG-2_ z8Qg<53-=F82J*ID&2O>`^s8f&g^MA@ZERRgF4*bC4P(D7Zz*@$=GE`4(- zCY8$b4y$J)fA3-x9#|^b!}+QPPzSIVpdX;)>)5tLOLxgw1P{iLc-aBX5DhU)vN+;b zc<0EyQBnh_1K11D576-$t7NBd=Vq)ten@tfF5=MbmvQdF+qm%leVn|1N7Vr80QLg( z19ZH1wrHG1a^Khb)w27rOVyB_H)NOk)-`OtDtwU|KpntdfPR3E?>f#Oj)@5vKYO<9 zNS9&u=1o{~@Bo&|?%jO3M}swhI)J?Z{QwsX z6EyaR4ZOe8IwbfXMsCb?ES`2xIR8iNUG+VVRQ(Ivmwm5v0DA%Y0rUiQ{JeWR&w9VP}zI+u0UL% z^lM?8RSlpHU@t&FfS#a^_Z6KHGw*e|qvu_@d*XAfIP|^jp8p3D0ai7DI)J@ELebmG z6V&m841QkL&^`JC#d7=G>DMAZ@T22=g8i}VvHOw{nCVu z2#npSY5;Wrdja|Z^aOQ$)QUu8?aW2t@x@qqbv?GdwHJrqKZz5comVx0I)J@E_P%`O z3F`RaSz{2kFcy>7PsiMS3$XmcT2#HV4O`!m`=f4dRyu&a06hVEf;zr?-~iFLqYyAh zYDjrHa<>&>;n8v|Kf4Y^2TPR>2wfDf`~Z4_I=-HLJ9O}pJ21qDa84Qp@9Yo+7sw7t zvFsE{4WJHSFF-$lo}iAOwsr*;?%9UbCl6!ijmtQB=Qgf>_yD&)|5()k>HzivOQkoU zC#d87abgD@4kWEFJD(WfV}|y0D6KtzPo6DSJC%jaz{>v z+?Tar*LJKtaST-#&Z6|lVWk727ndkMfS#a^XW!r6TQc%tp%@|k#rPRHh?05{D|hy> z22cmE7oZ{``amjH&B>-2P^VE68?XUL+k&FvpfH{ssSf9|8La`R2F=tJi%#^ zH){5W4ZOe8dL#<}XT)B|lIi!bVc}=kv-%tCTm6I50qh0xC%-J-z)6`4$gZijzdg9e zbm1-ezft%vy;jy$R1~~{)kSxe4qz{k7_1%Z9I05yIrm zj~~BY)d1=M_5vepvy~^O!he}B3>vve z^4BZHKiH^h0CfO+fj%;up(oh5S+p5GT6+I!;`tSeW?v=z-+FsD4n8=cYQXM$vI8T% zz@qbI$`g!VGt~_5I?WehC6h2^eI{n_n=kxdgQ}Nhm+rM4Sb1%O>IE`||B=fltGR&w z^IHZFz|fRY7^nE3ff-xp$^L=l@Q+m}9l%~7cwrnoq<82a>0~oA2N5MssYpi>;?Kq$$h}$2{swr#SEXlb|n_>-iFGPN3lcB|Ko4Iic9a^S2f`5 zyLVMDu;HTI>n5IHj@*S;r2YNI%AHt=OBZ35@PGLM;r|7>JL}~eIP%&nQctd^ULap~ z=#y7gV0^(GGrXl_>fJ=Ihl{tEAs%C~+?loF=pn2+Dfh674qz`3U9u1!(jQm}kM-BD zJH!DUWjYUQs%Ly#W0HdV-t_a5kvpTh|+jK5e5h zq*o?J${83iVi7_|l_?z%=(be(0rUhp7vOAA$B#}tg~-{rWKZv|Jil1(`rH16ssYpi z>;>ot&=cfbfU`jzZ|_-&k&$~4ntn#^oVbRZinlOt{R5=~X05uf{D6qeOKL8_*`SVZ zYdHfpE~RoeZZ*co?Zu?*Q%K9ds&oK*0r~;-1UVPrY*5Er)DMw+&r{H~|4dlB6v?i| za=49Op>%-Lm~!O@&=cfbfU`jzAGUlFrf!w9`|tuRJ-b5A>`kf$PzSIVpdUa_kaGdf z26eo1`e^CfqcCaJRAg_RgW{vhP;p4#?b)r~CkVf}9I*HmKuYux*339=&9KFc^bl-Qbos7T(i?l@9Po z_g8)ZJwbYaoDJ&u^i|7Iv}2R(YwyR#3#YN~CAs@gY5;Wrdja|Z^aME<;A~LG`($Uy z?!*F2mwnm!J2qp@u|wE${;bjgYtI~4egHYlxd3N_I=-{``c5)C9M66CC35ff`breZ zJ$%#wd7CyWKY*Sf=K`D!>Uiq^)}AB9_msO&Wq#m2HBELevXu@Potduu0D6L)3vf1Q z;Enz5m{Dhu6)w;BPJ3Ip`@X6H)B)@Ts!P67p5Xk{57cas`2f@XVdmvV+ATxyh)tL> zp5Fg86s5kQbO3t+`T_I=sr@+{WIjO0_iiKFz3)r}IF~66kQ};4>3}SmqfL!GfO!9H za`uzd&LNo%G9RGh$1RS)r1dGt-YsX-@kOcz zPzSIVSbkaF)8YwoF2LC!^8q^EA;}FMGXoH@G#<(8vXHZFuF?VQ1?UIR6XaZgvq9zq zbbRYkJHzivTdrPE{d}p+ z0y!IGK0wF2iM|e=EB95DEkT}WfCVx~pblU!KtF(&n7Ygp6PN2 zik#a?(o0YWq{~OL%o`%)E^SY_ch@dPUpWrU3VVPpT> zwci5x4iT@-LwX#k0n`DxlWr(KfSw@d0-OypAHa-|j_=w$7HG zF8EA7CHwnVRSlpHU@wqW{y=$xoC|O^I5zo=$_VLrONUa}%lGUOv{lsr>Hziv^aJP# zaxTExAoBtJotK&Y{0&+rp-t~uuymNOY5;Y>=7cA;J z$a77?(WrHzssYpi>;>ot&=cfbfV06D8-%HhkpBITDGWhGSv(S}(^L(h4qz`(bYh9} z1UVPrY%qG|WR(%p@wTzUFf79x-gAOf4WJH4uF6t=06js@1vndIK475C_;h^JVO`KQ zK)5@>S=9jQ0QLg(1Lz5IF2LDfuknLbMo7n7bZLUR_HEGIMP>j}1E>So3(yasC&;+~ zXM^?a+N+F^j-R-&2$|vm&fO$;4@wQ74qz{^=F}18334vL*6_>HvN%`T_I=ITzq; zu!o%Q%n0dtHUAql5KUzk&l*4-z+QlU06js@1vneDa2TXALI&R0-wqtU2~i`DsTx2X zFk9w)`AK(_C&;1j!S``5jcAAm;+%Be$!3 z05d|&3F`RP4P1r05vm4I2aFsrAKo$#qbJC@0B3{D2QVYVoS=@cZz0dSv9MP)fI5J^ zfK~g6$`j;Vplgc&l@DM>h*=>W@94J~u95py4WJH)$a@JB@?TY+Am;)h)5W`&d;l{- zBLcRW;XB(%M$d7nssYpi9ud1Sdg1})334tlTylfV2QVYVoS^>tbzTfb!#2sP22clB z50kGYdWW7M=K{SP7O8vyGeXP>>UawaTiO40RyBY+fW1JA&XW5PzmIc)MlIyrm-@hr z5VJx$-hGBYe2c?W4WJH4+cFKAJLDc3@dP;+NUV}O^~56>CmEqpdBJA*ULgbJYUMCAjR5n@hIfBm}sTci1iZmI@Q2e21#OqS>iFKmGpET(ss>O8OcdWOPG)`d1UVN7E0h_&aGx0= z<^*-T#Xxzki~9&w1E>RrCdOlU$`s`ZaxP#eb%FT+W`vj(GQ;=m0gFDpVIehuI)J@E z+fiQ16XaZg^@aHWl@aRN7qF;5 z9`pn`7vOA=`2c2w_<76<>-b?AlDCr@KpntdfPMfyLCys@8)QC!86oBbnHARYoyXXK zHGn#Ry#W0HdV>7mY>+%=Mu<5I1pYtgsngIBmfiz#NeD0@V2Q1UVO=H^6*=`fvO^$qF0z z-~0aZ^Y8zE_Wt_wzyGiM`#;~m{%!ZKpa1@!|Nei?{{F9h|2*ISe}4bL^ZN__=iXoN zTkjt~fBonC^S|f)`QQ8dw`PC3Nh7?_t`(a0?TL0HhN5@0+!sDa?)_X>ijt#yRsP|^ zyKm#pSD)jvzkgq|KWyM%Y}#1vr)(pBRc~02aDhj37~;hHn7?`jb{;y2bJwoojeGCl z(=WcjcYpiA3_rT*ix}6g8M3UpVxFfnR>VhPbAB$4%Dm-@ENqrJ%t^^lzI^>U{&4>td@Zm4iPmj8 zp?hyznYVjmq}m*Aj&rvz~(ha=w?z{NltFQ21|1f|37aO-mvo>AOrI(%D z-#i*&A@P_c&#$N|Uxm~A_v2N07So4!@8X-!KE=PjH~;-xG#1~hO?x!7?1#=nyf7pn z34tj~F|GI*%Gdt^dk+5@*KYg+4<7s<{Q1u?`~Dj=43k_?0-CojLZ{xcV=!nxT*ll$ zaKfi3SpFrdc7BVK7k|KOcYnmkpZ(hm|6+sT@@(-j;$NnsS=Tk_J8VBjgxrwl7JP)F z%CAs;;JaDf-PEL?2U)*`nAXSuj5VmU+6W=jQ?-ly!IIXbv*fR*}hE;|EI@BKb8MFzBc|>maSL(f929k zkMUo}lmD$+cYJ34>v&WC4;kkDME-wp=S~g(b^I^ozm9*%|M*(@U%mTr{_A+1|5h%K z^MB*P$N8`0ALsu};s55R^4|<^#(&A#JjVY&J;r|>|8xA`qVZqHoAdw7WBlK!@n6R) z{#&^#{01f8Q|4*vR>B%Ks1UJg7PUb^NpN|J4T%YR-QhZ}7isZ+p4>*&Ct3 zaZf$}b-cm|J3LQ9shIuSLgqC|6Ozbo8fi- z|IGPsis%0SllVV)uH?3U(*HdFP5E!^4;%acru;YbfBdW&wd#KzZ_0n_|BARsY$=#o zqyP2uU&kB#cd_nMqyLx8mU~8O(f>N$;C}~eJEi~0|IF-pkMZAB|Lb_2{~mImeC*tL zwd#KzZ_0n_|DWT(j@S9`;Gg(Z{jcL6@xS*v2I|8@K? z?f-TBv-1Dj&p%WBzmC`W|8xDnj(^nuKb`-t|J48M_-Ez+8}B~s|8@Mc^8XFd5A6TV z@V}7%I{sPt|H)7NzmET<{MYd{{r@xa-wgi?`ETHj{rzX*ziIz(><=4wgZ~}-_IjfK zr}zIl-jx5((*Nstga3yA_jCQfjyL$P`+uhT-<1D4{+IG!#~b{An*V3o|Lb^z|Ih0G z>G((dFMQ(p&;I|!g&$z>U&lY<|3m-J=>Nli^8a}LpSt!v4F2o*NBlSZzlZ&QxaR*E z{5Qkb@Za$N9`^rHsfPdeC!8?x|8#r}|EI2fqW@>~{|5hcd=3Bovwrgb9`^sPKly*u z|Cde9e;r@Lf6f2%_{slc|9{TJ|1-lI{5Sl+C-ncPO#D9sZ|v_siT|ehpZkxd`oBoq ze>V7U>i<7Y|Lb^D{y&TVuj6(7PyRni|NrUBFO~nV;|=~B`v2$re;u#ufBOGV)Bif& z;6MBSr}_WJ`LE**{y(k%H}(H@{Lkrs!~Zw-ZY}*ZBXB`+vIsuj7BI{x`!L{5SOf z6ZmiH{~LH?fB)zBulxVT{;+{J_-}gtKaKx7{^$6w>wg_@@ZUK9>Hj^6|Hk}J#~b{A z*7IM-KZ*ZOoB!!}ga1Ew{u}()@dp2&_59cIkNE%O`5*g#)AL`)KjOdX{O=}eJO6e3 zBmNubzxaQ`|Ju%fGkgvIjr0GZ|M%$p|N61>U&sGa{_A*i{y+5pYCHdRd=38}JO8i2 zIREMYnV$bwg_zqyMGFi>->M1|Iz(_9sex+H_iX(_{aJG^Z6e$e69R9 z`v1rEzmBh!|Fz_Qbo{gM-!%WD<7>|U$NazA^FL;IQ~p0g{>Q)@`~T0vf7A0{-#`92 z{_E$zjyL5$&wtMUO!I%H{QsBa2X*|j@}K?xKmPhxGrZ3KC(Zv2|L@1|{%(fX`Oo=Z zZTkPul3&!nf1UqNn*Z_qr~d!vU;bi-*ZKdn`QM-Z1T(xj|7F+NB>!ie|3?3B_Wjr7 z|BUm0-(&edbpChw$U&I$pZQ-M zZ}8u=|2O7;C*%%gJ^!oY4gTx>zmfmd^}mkS`EQ#4-E#D(S^ihY>-;y>|EKotGt2+# zc%A>I^S`on@0sO)b^Ig#Ke_+c^M5-2(fM!M|3B3Kg_8f(=l?qX5&up4|EJ`C&G0q+ zf4u*Hl>dD^|EJ^4`Tr>YJ6p0phW~Hme|7xR_&-y8dp-ZB<7@c;SpWa<{Lhj6ub%%i z!yEj6O8;-_{~7q_`_sQ}fBO0F@A>a9N}jF34Be0fA~56`TqKExxfDW{rBtMf6w>-pYQ)a-~WHU z|Nnb^e);cx|N8m&|NQ=g-}3$gV}JhzxjVB-LpyY6Ga6Psr^4NNCE_M*!-B%2*tzv8 z&Yii7H*SB5Pe1w&fBD9If4Y9dc4*P6JG%531bc^Z@EMndmKymtMx3 zcm9A+KmQtk`QgW!{bS?xEn0MhMF)8Xy0r%^Mkd1|W)I2KUuJEmxgq)r8vHt8%9DVI9UjE<>{Nc|Z<4^zmiy6K_ zi$-YKu{FBd^uz$Kp%@b%h?M*+ELm5EJ#v@y1-VE5ExAA8lP^EV_kTCP|Dadhrm$_& z4x>BvMP@%&tQr}G?Fln+Y~e~=-FXOi&RxT&Z{EjupZpR3`Of_QgI0~2pmXcC@{H5I z@EbY;X+iRgugqL*EL(*W`w!vP6?$L2tOW9*(%~u~^_( zgmqDCus?qvE^N7g+ox~i!`DB=w;z3re}7}Xf8V-6YjkPZ1@_(T;WyY8md;7;`pIGxOw#=9=vl0U;gnknSVWc{~7!HSfBx*-kMZBwA2#shfAf~z6#oYd8DGQyCCj%c{$INM%47W3@wM?kw(^+b z|DKz79^=0m{%81q=Eg0&cK_WP{+r>+f6LnWf9&;hkMUo}oAQ6)C?_-iU%Yt*Z_51% z2LE-uDgU#qN0{;d?)mGF@n6UPQvU1spX2`>|2m%h@7$vEGxJ}^Thzk;g==;z z{-3+?`eXdp@uvJA>^AO+{D1qM2Q~cH@#KG-UUi40u@Za?OH^cuz{_A*y|K0jqqBj1Up8q<&HvS(k zS*6Z@o&P#s=YMKoVNNmOr&HkMs4T6 zjyL1~#Fa|_8~oSxzZw1~{!T}S%70V+ zuj8M@|DuedTJ^t3`GnU&rhGkC-(;>3>uHo9cfv zyb1pe{hvE8wMPHz=f93O<-ei-t8&6>)&Dx)l>blC|N8lF;EnzLU)uj0`@;s_=>MN~ z{+ssyI^K-`KlT5$@!t%u@n7%%b^e>-f2RM}`LE+m`Ts2EzmC`WulN5t|8@M6`2V#2 zU&rhGH~RnD_^;!CY5%X|pTvLm|F!X7$D8v1S@ge-H~Rmlo&To%H^V=H|EB%F&VL(n` z@?Xc-#{cT&8=mO@>3Dc)R|% zE9>G~th3H}&%G@H|NruDf2a9>ix1>~Q~ZC6xBmaP<^MhSAof4d|F`*ni+B8I{7?VCvHagZ z{q|>?|F`%+{s;5_ZT{ck-TnPw{Ac~o*?(LAbN7cG-toVw_TS>~@jtlzXZ#;%|2=r0 z_TPj57XDlR-{Kwrn`-|pzA^qcX8$d|sr+~KKZ|dS|BdIon|1I9}zp3`$gZF9wE#C3p+5ceqzd-wM@!!UO8~;1JyZ_&q|KC{sKk)uA z@Bcgh-^Txq)&DL29{(G+|AGAX;Dgxz!1}+f|9S8}{eO#h{QqP5|3LrW;>rIWVNYoN zKUn>b_5VQs-{Q&tXCC`Olk5K$-x&X${kQc$i*L;TZ>;`r@s9tE*?(LAv-rmNA6Wkn z^#3j1`TsWlZ>;|B!3Ws?VEKP*|1I9}|BvPW1Nm?9f&6cZ{~w6w{lCWSzvI8H|GE3a z?*6~C|CaxO`TxNBpT#%E|G@Y^u>Z${Zvy`V^Zy=v5c?n4|6}dH#W#ijf%$)nZ_NHX z|KH~SEIye1|6}<-i*Jnof%ZSJ{%7%x+5g7)Z}E-szp?n=;+w+%!2TbLclO`%zp?n= zgAd?;VEpg;e;EG<*8eQNDf|!Y|FQT${s;5_t^Id+cmF?-|IGif{uj*uck#cy|7`is z`XBrM9RCCR|NiOs|J`$c+Qa`K^*?9-fBUch%ZoSsXZ^1+`~Q!4|BwCoLk#~}{|m-{ z#{Yl!KmN&sZwmiu{~7=P^S}MxgSY&*^*?L>?ay!d-&p`Oo?v`~L#@@9Ka5 z^LPK#^Yi=Vzm?xq{=4|!;+w*MXa9fyuinpZu>AkF`k$5W`u|w}561sM`~R>1=KcJJ zrtqKk-^Kq{ejxv8|CdHgzOVl;kpKVwFZcibS^FQD|8LCxyZgiL{=emaVE(V}z>W`_nYtU|KGg7|EK=_x%>AWMu$l6 z$Pk&fGDPAFLnObZgH&7^D#zZLE>+it>YVFSQbMF3_Pzb~+tQ;)4{`XA=^+xb3}5Sh zAR%P~<GRe~opU{8-P5|ygC8_qLMASgkR|IRB)d!=-E~5GAA3_K zT>C`&oPJB^Tn~xG^C`=`@v^d@k^%z^?_KbFOy*zI70M zY)D6071CR_giMp_kR@{I;e7e<#R~ay#8LV1h21*mdQr#}$q4D^kv}~I|8Mxp4hfa* z-+Nh(y*No;du5Tl6~0Wayb>)(yG)eQ@4qZ-L&9{Q)jvKyUJ45fh4;d4+_)kCiqA+6 z{Kq-h`JDSKJ_NG)_0U5P>A9GfmnXmchaZ%dVXbBP$~5`e&wn9*_{0Ave}T_%X78<)KXKwjY3dghvv~LWZ|dmq z?*6`C{=56b4)2%$9=uQfd+`KGE}p_S5l)+;7T1x6jIVzyGF=4)5;& z`{jS&{bAn!_sf3|-Y5S(c%S_D;{EYI7~T*6E#5ExE#5ExE#5ExE#CdzHI@Gs@0b4; z@0b4;-@yOpVE@7Y@TuWy|MLs#`G1xC|LmUqxA>u5J4)uPNpdzfUA{U{CO@mKl-jIh z3Gd%iTKxF~@`ESa$%ajv9beE0ir>KKUU{eQpw zclU?g{eQpw_uzf<--Gwbe=pu2|AXQE@ZaM7^55e9^55e9^55d!-(6GrZ}EQlZ}EQl zZ}E=*&yoM||EGq7|A~o`Ur_J=U%PfyJ`M2yE&h>*zb_+S>MYrF!{s9U|DPP%Dc>C4 zB?r-BkWty!-t(b#!=lf8Q_v-Th&Q_sf3| z-Y5S(c%S_D;{EYI7~T*6E#5ExE#5ExE#5ExE#CdzHI@Gs@0b4;@0b4;&!3<1zw&=T zf3^RKi2uF(|Fy>d!SIi@d|1YIe?d0PpDtH7Wr6?Y@-@zZs+2fA8@~5Ih;(}41*xps zt2t)cf5#uc{0}DI{U0=Cba;1v-!K2&{b7gq%YP5vC;vTopZxdY{qa8--VgsR-Y@?x z-Y@?x-Y@?x-u=xrmH!s+m;V;;m;V;;`2Xy)&r1Km`2Vi|&-njS#Q(p(oBy-;M;?1j z^O{eFwUCLuUzUvvXUp|1Yvrd$cFC7DJESaOp$x`nb3TA`=H;HfGzUojJO23Pzm@NP z|4kho-re8#%YS!&*x~*1--Gwbe-GX#|GjvB{11lr!+(qS%YTda%YTda%YTb^e|Jsg zzs39Izs39Izs2+CXa29j|405WF(L83{6GEwU;nD!{#*Qz5u+sRk+ymUJl#4>ruOS0 zTjJ))o7-~bua8#97pM(z-sibzbdSaR<-f(d-+xm_hj;h){qo=4A9i@Z{P*B}^528^ z$$u~2AOC~l{qW!7{qo=9{qo=9{qo=9-QQhP`ET)l`ET)l`ET(J{D=J?p#DGWf8c+E z{b&5o{C_?FEj}%Cwe%l6R6<*~mOsN;(xGiDnK`(RlrD{uw@dTn=e4`#ld59LUoca; zJ^h4OykGuXy!-t(b#!=l|KBhF1Md&BuIrco9=uQfd+%YS!& z*xmp4%YP5vC;vTopZxdY{qa8--VgsR-Y@?x-Y@?x-Y@?x-u>M*mH!s+m;V;;m;V;8 z{CEC;gZ;mk|6~2{)6eel-{ODqi(g9JiIWnav|PIP?u*aEX@Sqw2$3#NJSGd!3sjXH zCm)m-YJbq3vV5_4zx=m&_xo?^=woP3yIcRede{DI{Qqy>&ktbT z?x%nK*K+7+t;8;kmlwPDln2r4_#krrFFo}GSu}Q->|eQ5KHgm; z%|Czh=La-@e!zTT58t?P<7D#W$ueci6d6B$yo? zQt4W_OL~{q$k2*f8DD)$CLKI0QxBZeaa_$QUGKXcci6X7c z_gw(_vxCTQ0r`(Y{!@_O1@e1A{s71y1o<3$K|a<)pN4$wd)s_|L8nJ6r2Dh`Wynj% zWNg3F5x%p7|~A|_nXaq{pBx<0tuQF*ETeh`y9{DKd(h!Ne&$&IboBfpw%2HYP~?VwT{DAtd3h+FVyv{ut|~>I@*IT z?LAp4hR&7)6BbDAw0JokxkAn^%#d@jnL3_|SfT6HW+Kj~+b92shx6k57qgEJ+ua)gWq;N=x)XeQ5 zmokRRJB8Eb8b;2!p7IR#{kiw^6GlIZ_5Q$51b#8_xxnuQ{v_~Kz+=w!lquNP?;hUW zKki&uA>{Vxy>-g@xph}1>g;t{aOS#>oQEGeC!?$Cbf3FF?C>q8gL~k1SR(%ZS8kF= zRu{{Y8+J&${GB>--YR{QKIcA*?>qzY!R^sWkPpt!&4K(p$j^s-jGTvKeRKlkW1q#h zYz6t?c33ya9{~9yAb$enPlSAoobxOQdnrdk+k54|{LFqKwUnp{P>o`h1}lMDiVB;k@7anq^iwI z+52dQj+~dYUX17Suy2az=dTz%Q^@VQ*~^vlR}qxPK~pMUCgiNAD9R$O~eQg3`9E3Uq$bFR}L7`nUGbALH>Zc@G7 z2ge^@TPj^PS4z*VH8?8{VB9aA3oCVrI23+`55E3 z+|qTP4cr%af0^fN=#!97yAO^(J{Iz4LjF9+UjX?LkUs;&a)vki2N5JpZ1*`p9A>| zAwLoFlOR74@)tlp*LgM!3?lzfm-TAj$?;pWYUEDLarrpmqt96}cLqV {e7>@0@m@9DhA| zgWOuZRo=_pF7I#HDeq#u1^dBu`UADo5~&Uq%#4`3`{@u3|cA3lHEk&q9r4~&8QWXR8ee2koT zo(cK%0}u;X{9y2eK0oa|xt^W;xolkXl@#axrH-8QOyG0I0u~<@mJJ`j2zI{$wcctO z+3S={9(Gw~jk~HN=Py5fQ2heN0v4YL`Skg>;QN#72O#e_9`RgH{Bj*btpMC&i0gJDDxj=n>+Ie#Q^W+Qi)tc+_m$`51$T`mh zK4&ao@!4VF>ho8$fqibjT2A#Ul*_})f{;SK@Dc3(L zsFW{C4#K8B; zuz0`xw|Kw&w|Kw&_uzf<-{IZ;B8M=(=8Vie{kp`Qy(#m6;Th0#+kSn{eHK4( z5#%GzkIIGo?T}vs`KKZOJmjB*e4GJX=X36}_|T4!k2wG7@sN)k!uS-(Uk~}4Ab&mN z;|%CI5AyMx`z(G$uj3l$FPZzMWWw$i=6ofUB|njx%CBYjwx8%3kO4c)=gbROe5+Qu z;Qu!1{OE2O0J}SF)Mbg8{+7hg$C)wXrk(-x1NfZ#EPgrUGtMu;_umWoCn5hb0R$lnh6n<1ZPKmz3RIrmxl$H7m= z`)|%Y0K0!$zRG!Beo}HrzOH;vezNTyJp(?%I-hf&#pkw~sd4`9M_0h^Z;;EQ%H*x- z2j$NETDdu+TF-!^FXRfJGcREAhbF~ood4R2eAxXR@TLS+#b(6;X zeRmvCyB~ArCeD)gWzmH`bAs@ay!TT zAMy`C4(&db>&aVW%J>&hl?)hr>@610eKTJF= zcOsAIoa=iYO9TI7J@OAvUZTD~nMD72n8*2aE{b7f9_W#M89S!zB68VBf=iZb^*#GedPO1HWa$TAF2^QaA z|2IH>5c{871NmzIAs_bN;+_3}at!3(wf~XGBP_~?eAxf-D@y`B7K)$p8TOfZYrHa9VE9ski?Y@9ck7o8=Am|JF?85pZ7IoVg#d#ZKe_a%E4O6t({r@9h6|yfgeh z`w#BZ{(rvxpwRx`Sdpjp-{PJ9-_dKrJ^POu6uEzGIdU8GQZ)}y*85ep{}%7p{#(3X z{#(3X{(JB~`S0-V{(j#QZ~RZr)9&ZJ^O@X>|F3DDz}+8q_|V9E@jv5y#{1+vW`*pYc99PrIK5`7ZvS4*ARz zSbS~w4FU20agG1UdD{Ii*WS>%i~m_0wD|0>R~zDg#`%o*$$7^A7e<%qoa+@hA6Of- z_?lM(6aSff5!QY_sMzM{Zo-Ebr4)5;&2j>4HPuAxE=?7^3A8|i(e_UsMfc*i1_lJ4^|6cyT zKptOLB3(A^RzE=V|A_lJ=Q?8q_6JyeL;fFpjm)jj0n*-U{vRWAf?Q{e!2G|(H{|~Z zL;hIEpAPx(12q2+yU#h-86&VxVDT>hKO6b?m^n8!2S`7F`G4Ad<^;LU`T+X_EZ*h+ z8QXVgQz^aLA5cHQ<^MV7I%5Rp|1CZ+|Gx!tm;4JZTk$! zSp<3X1DOA(-RGR^j1gETu=soV{|dP|2XQ-cfXoBb=l|iuW6pKf2iPBA@h<jW0>^8W>0 zhDvFV39@_GO!Wg?{-1NMGe%&4fW`aezs39Izs39IzX$J=|ABbk|LeS|zWzUI5AxvP zxYqyS>oeYu!dFDyWnJg<-lf%^`^)#$|KW3K{U5$Q<9)^ik7Nhb|4}P&_mAD@2XvlZ zU;iJq4D!Kot^emjKH~i-!~_xRARp^|-a9IY{II+A{})mJM|`jKfB5>0_ZbsBGCHvS z@0H)()&B>dQI0duzXZNE<9)^iF*EDy|Ksp{@JqFxpTA{8{l8G_{H*tPhOfv@-ZB?i>K<4@B z>oeYGOfU^|)&_^*d5<9S_dl~r>-uK~Z&Qvl&re^U@jhdMH)f*e0^C0{xI}7S^4?#M zZ#hKk|AnaUvj)g|KYe}1`-}<7@x}GRR*{m8`oI1EuNX3;zWzTeNjc6uKYe}1`-};$ zAcv>*|CvcrGj5>=AKSK**8kT&i~2umfUNh^*Jr%Xm|$zSvAWLZtp8j2e)(_le)(_l ze);dg`{cjFyZisz|F@-5dwaD1Z{G=-bm**dp85X3{=cr+7kGb|pJS-~f9UJe9w6=i zTd#3Gdw#SJ5H&yAeb@hI@%8nh;Joes>pCll{1$in|JVb>K7ihk zKd|xsKP#X8e?2;&W{=()?f)BfUZx|?roCsrKd}Fg`z*e`|1afk4-n*nXY>Wgd5-t@ z|D|~F+W&{|%ibQ^_cf5e7IMjX+yA#Pi2Ns@f9KE??E#{F9|ieiA(xz|PY~Gu$9?wa zXa8Syhb%ns(x{=oh}?z4FI|D~X>k3B%N?}e?{|F>8<&wPJi{~z~R zJp2DD(f`LDAlmm6@bS+sK>r`?J@fs6{eRqN@%8<{Qxycc~u z6}r#eA9nZu9~wNV{tTGDR6^&apbt1zm=g?(%hXZl^HYR=LW{8xp8Ly>y#o2@0q!yt z@@GRn`T>{|91;up7&-420r@i^ANxG=AA)?I0j(ha2au0`0Okb4o`-ylI)4iCTS0yc zul)9Hb_&mco*nkd0QBOpAAmW*(S1(n$T?#K_6c%dqw-rO;tW`=Hl8^_)&)4y=5w8X zLNNK$AfIPI4CKc{4*LO^6HJACj+`&SI{O5<&&qED{dopF5Bc37hy4J|2@ZgKj-0=M zb@mCi3!?u{)a`i&?CX#zhq~mTZ>K<*6FkwUP)E)Wby+9u6XZTCf6_x;g=at_`T$pl zjfag77v=;v;EN;YtHUM=`vfCe^zz_~5ts7}*fn&9>>V>t*bl&*;NkGaI&!{uOeA`L z;m2d2NB+Z42+x4Hw$DrQ6EET%=q}6&u6m}Ij+`ey{<5%7a8B4W9=u=vTls$ZZ}EQl z@4@@zzr#1*pKrcD-+X`mzkYxIyUw5H`_q5g{psf4U-R$pyZreH&G-MC@BcU7|8Ktk z-+ceS`Tl?N{r~@W@Ba^~#Cz-aAYXiNmrOf~d!r|+CGyk(iNY7h*_d;E!ohMGxu@83 zfBLD7neu#bj&$2uDE%snWa!>)GP1f1eg9=Ta?bT`JMyGcah3-kk{To5UlT8F@-n1d zVJ7zENY~O_d2xHbj?ZDv^)|Vw@*wuv`_mya#>t<}pDqta&yiM(Bjxd>3*?Dqi=b~(UE;lT<3G{v-nY?M(Jn9 z@*GXXdm}S5GquLNe*JnK)6>&+ozHnE+~V7|Z7Ur+b`<7f-S?U`YnIHLH%~Yc!*xFA zJE|<+<)1=BL*?qMmFa@m*U=O3zTq7!)d5!@?wIOdB0D z2ZrhT(k?A^pGW?3$j^ZMJjgGC{Oypx6Y?t{A7kxy$j5rcddN=?BELW6kAVD1kUs{z;kM*T^9yPp$=jUHp*jchldP?5z!Lp@htn8=_mtA!;rTq9@9m{H` z=z3no5Xmm_${#ZOVHp$ELMFwxlvydEGCw0!7G;G=Y)%^;qcX#EebUmFy3gwWOli1u z-8Dyg*Tl)t+9Vl&DqSX>T_sb`t<`bdsWe^hTfIoSRLt`H{4M6SmX`5PN@!YF3Crps zt#SuTtAb(DYSXCtal=4e4_(n2`<`gPyZiei_HI>f&pcM8oR2+!OqN`#lckrDcgDzh z)Tu)<^VnY9=k5({ki|?%cWhock=EoF=#1wQHxGXHB+W zzkbrce}5f0=UKq#+-LD6bGr+d5)=tXXn!OU@$~0)qisgRG6^PCvSp9}dDz4Eh4x(m5odT^q0 ze&4xhIeaNjj$U4>Bj>x0&ysC;&V5$?NOB+Cp1U$sIlnCbDM>5pC>h1i>&SUrPHTNW z8T%~0bH!{Sw@23{E9d84&6B9>8)d=uO*(QOel8o&SLi;ASMGz`VL83Q`7!cH@dSBt z$7E@@bE=MDWemtQ@t>+}b> zFYx{_@87?)ZN1uea(uG-5Bp^P*~1cj_9*&?4ypgZb)F6VDmQ!Zp*hRdzLVp9afXb< z`_jf8s*nkX%4OVvav8p_RM&Yn&=0WkAB>uz_MIGm4!nOMJxRK)S|L4Gr|Q@>BT3hJ zHqbw?c=kimzLVqp449iYZ_4}czb_ws^pU*#?z=kYI-hf&#m|{DN9{W~URqkJ{zGkT zt(-V(vzAPK^Vc*H|i#3p63;E|D z|2*WMh5TcXk9D36HJgLTf2H2;ljECHAb%C)=RtlRED#*t=&j$JdR{wQn{nfsc z<24r{=k;Vc{Z@vYzr9LM-ol+G%(+f~pcwvv#gAW9Z}-XZl+Djdc4-gEtsE!?RYN4V zVvwvU?XK(e2WG=Ru=s9!qSU^Vz5B)phy{PEJs(xq~)^u)Q@_duNV+#e&IG3PqZhOn&e_u+Z}pME`ke%g6*eKmN${_WQ# z|LxawGQWwSpx1am)=>aGGJ|n3|_xl zN6x!uEK|RLv4F*sXY~1L=gIv~KEb`WufLX`|NQ4Va?W)=CzmZgIyzc?e%g8WeQw;i zA-8Ye7LE?b=Zpm`p0=9roS>a2*Lgpa-{>* zIoJ7|v4F+zjvJyr|M`v4%Jn;Yv*qI>8|9O_VjVf>89+aPv4F+X_S5IzIO%CAjqD-& z6G!Sko+sST`F5NE^aB_RSp4n{kiR`#&R0V|xPIpXLQ9g8Us*^gQ9n`F5NE^aB_RSbV|mA?ow*JCDyG0@p9z$(HLMZWF5>pi4!|47|ef%Am>InUnSUFZie7O?ofINRv+&%L%0+%J`k zkN3*DFAmGbzo^rZbDjzG0~iZfd}wNC_4(Uwn*{Dh$iTz#^2(WXnR0Hmj+}SiGgtkB zR)_^0-rXOca%8v0`SBM{z}{bw4dDHj58sl~kKd6kAKcb6ApQDz;dAB#-2GvP?_Iu8 z06yp0ZSnj)u&0_nKkYrw3cfG$$3OnDo+Ug3 zxX$O?XYoUZ3{k$)*Qed*JLfK3xFD~+_L`hKcTUd$`T=}SUR(Slk36DrKF<-_d-@}> zv9bCN8;-o&od&_?&qGi{FzE`H1r`9)Nt<`ybwb z{C6S$L&(1a`8We^orZio=RS*H77qD{^Ea=6{9MT20r@yft{#DW*gu{D73(1%&$-Xy z3-^rFIRC)K#c~FA|HcnD%lltJ?$`J{lrPKm3^)TnfX|s1u=wfAT56oXV)OHo2fJTZ zJ53H=#94JUUTQAj-Z9Pq`T=~-ynw|IJiJun{HWJ9slCtp;;5AT zN6xuEy>_4G1TFsYjp-WqGv0p{en0I#xu13e_g3MLaL#q+7Z@X0d?dfd#+AV zyFadAy-eP`QO0h})j8LnUxEHN?6Y|OKIq%?^Bw8))9&*#AOG_||5HcKxz6{%aG%A~ zF4MPXyicE>cAwn;72X&B)mLBXoa=nfeHKsKOy8gJeo;}8+I@2WgAYEC>({UAoa=nf z7{KD0KcsKZc;Dp^`2MQ2v@|^fh~YY)bDzcUTRKYPd&c{>_pVX9Pwszn`?!34wMyq) zzYIPz2C(>~7ZG=lYOV2p)zV@5y{>MHm$#}i&4`5!|*=3KuFJH{Bm;*+K@?uUHD`&D_6kMDK07V^(S{!w5s=Xy~Z^vpWHwG&22pc=m&5;`g)P(2P{4;6Z}W6 zkMVwAoRPHqF*mo$iubEz(VN9O=X(2{h?B9;;obdxXaAR6y5Ihj`?UYLx39o2I4?`U zf7*ZABKndJ@9h87+Tiv->BtNpilXa5IO;qz((>_53r`#~*?;uE-nIXu^K-!cJQMId;u#Rk{#(4W|Cct$-EaTFecJzzjur~-|K*}Mwf`3H z?0?bpj`!^UrWkpx1ojtWZF;!o0g7gHRQqr7&i-FI2>F5bAKa(?|LAqdhyA~N81iBN zE#BGxqBO{Fu>X*cGvGos*~BVvm*1P$+CL;@9^&a{zTOM?#2Hn)n_N?8UJs%>%+VFpZnbXVTbQo zwy7chXPnP?pPZ-N=hzVcBhFy_Z}E?ANNWApL;){C~2}xy~4Y`G1S&@5AN) zX>Wt&|GDn+{}vyZ|7R@0Ga@km&pFp!{@>yQ^Z%?5WMyTkkLL3KoO7Kq0`vbCADI8| z-MhEu`WWvA=Ks0w^8XeenE$`9@oxSfc>vA-!|pTp$94Mg><_Sbm;cWm-bOY}?tsr7 zME)Il0GI#goa>Ac*dJi=f%*Rn`yn4WK>7ii|A*b@oa^K>>jW0R=x+W$I~wwnARjew z`T?5%hu!C#>x>bY|F?LT|0iD$UWnBkApHR5|7rJ`6XZJU1MCm5c$fcQoZUuNZ0aCu zw)ap!pdtT{IoBB@us^`!@8$oqB=TCG<^b>I|0{IPb;bzn53u-#{6Av*$4ig{+#RWY zKz;r{TIXD+@6Y~#Ks@V0BlebR4PXZ9`{cOR|KaO1-e*j(81|g&Gmh=SzFnUC)6B`U z{yz}!Hf0Tv^?v&LjQ1H6Og>ER@4)jd*yp`J{^x5F@7DjbG`_E||8LWHpFThH3-$H? z)w<8!Uv{4#;OhTvmM&0^*Vq3OHQuMs|LooRKcBNtz~Wu~pLtPooc5c!KF0fj^?yER z{omq))&F^(1grl?MMZh=uKv$=Hj?AaC(zfYoWS}&pOeQ{zN`PUmzNx8Y(}5L*8lmO zwE~MTfz7V3|G%mnXP%$FKI47H1ZVSObp2rRt5O*|*n^L1cenoE8-LrV0c!mpzCPo9 z#svAVK3!k`$8*;IJ@R3*wfbV9co*MXDq&D zJo-8s>i@&*>;Lfe8SgVDc%*ndxX=1OKC1^g5{Gy9|F!=QemU!awC{6|??;?pt(>?0 zf1|K3@cuCW)*AZ%a0Y1qA9@5wR+lR0nePwm|6`w^#cTgx)-vVxxAp&hANxG`8RO)E zsF|k!FGkM-=KBNt|G3ZM$u-(oa+|!R56?V5&jOB|bDht*&*Ev5>6g3yKi2qo#?sz% z4DA2oK8v^ge>_hZ=kqM!$T?;3tY)8}#gqRJJn(>W``h~exXPpF(FcS$pJxH%ecS(M@!J1~x*dCfwEyo!8shv+Jqwuc5A6Tz zihUMe-~V^_3}FA?`hm#v4^_@wW^KYsz>h3%PM(!yQ#sWMCm=g@gS-_EV zuCq^&``rCucmMzKyfi%nI&E1iFP7v9`vI5}e><3^@@CoeY$a(0x<-$He?(^U$zas1bejswXJh*VSupfXq!LYbU9XWq+;VkX_ z4VgK?gI~IIsoGom0gMIccQYr*o*j;ybDht5R#^E12M$zzlBbLXm=9q7jo+6e=UjI@ zw)lr1epq-0&<}X|<(JiVGbhNp07u$#uJbwfSv>jgz8DM8#xp0#y&O5`y4z#%`IFiU z&wy?7dPsS6e_=lWbAtPpjnCbzwxMsQd>!PYAAmW*eT9&Zk@NB#$VZ zf=SaLA0y|nV<8{hpEbZMKPkVx@C;bBt%s~D$7hG2AAmW*!hNH4Z zuCq^&`>gzjCbbYf1C~A|q3CyHKLB%rVVT`@)H(W}*eBQ`0zJu#7O5TiuHRp7{`s3f zzo7Z^3;ye$U(kGiz4`w7clrK$^WX2E_V?R-|G)YEfAjtS=KKH5TQSef*p_vw?c29Y zRaKSVcVjPVO-+r|)zxWD>&%%m^2HZl2`^Dc)LtUu9O*>2PJAf z?hF^6k!8gfBzfCK9T#KH^_i;<;Qbwy9(=p8tMJ*M>!f!?kqnF5A>)&F%j8tl4%5&# zfN?D5T<!!-+q?t%?}Yvs^S45Otf#Mo{@7>n!zV(2d@k{fDCoZw`mccg z>Ck@_^vAdubFR-^2>r3o;@fqF{(YhUFzEj(^q&F!=R*H^&>!PiyuX0!eTGB-K0)+< z3i@}1{x3lPUeJF4^dAiUhe3agJuv5b#}}dhb3ydq3;pqV&uPb@|2gP?1^VN?55=!T ze~kH6dMDt$uQTw@j;P(xzXtjrg8oOKKgPwFbA2Y>2R(js5dGtz z|8nS`3H|Z8|Kkgxe=+pm2K_OP#hmMXGN6A_5dB|;{^8Jn7WAJF{iC6OEc9Ot{W124 zf&N(UI2-z7pZ)olq-4wTj17{JQzY4WC98cAGi_R*ybE|JD=gUriA{7_DklmMlq$B5Ba2Dk5zoq-!{b7e6msF|T zj>$hE$y+Z0ayu9A86oG(_CWs{=zkFUW8{2G8T2oL{@7=K{&6#)Ke!!}1pPCi|2pW8 z^I~lw^vB5ga-0P*%b-8@S$wBn&>!3$H3j-dK>t|ip9uYvpg%^=!*LdjnhgC%1kwLl z=nrmp>kIvdLjTdwe?0V`0R1s?-Vf`1-tna%`X7Y;;CAjs=nu}9y#@X8{^#BAL4S;# zZ^3%*1?Z1`_U9i5?vvXwd!hef=zjwG4j=!nJ z&>!#pS%|$c`=CEY&cksQjLL)lnL+d?_rdLM3!pzZKQs~gr$GM|&>th`{jkpG9p`xU zUj|N-+v_&%P|j~H+b^XR2W7|ZLppNKvtZrE9lFo{{L>>7l-oQB@Yj(dO1&7{|;$t65$%&6KejxN8xX!a7 zD!0yq?=~x6?K?Rhwf?vyY&j>X+pkJ``D+-jNPN*bUFX>_Z1D~czWvZeYTwE65fM2u zK6-;pj@u~VOAB=zw{U~5^K76WVDDe2tbzXEDLKAtKlDEa{ZB&wGtmDe^sj~fSm)W0 zgLevBeE2-*5BpAzugQb{CD4B-^v8S4ig!YP_zzs?*$@>UME^n1ANHLbk6H@-@!o^f zEa<-u`e#A^mCzsSJR62h45EJ*=nwl&j*l1%{ii_x>Ck@`^v5`EGW5qf&j#+ZKYz+m z=ntNfI)PE=}sgk1YdxazY2d?vMh)r7K!4DfhN9{W~9+!mvlJpIdmQ^Sj zYm0Q`oa=l(X?C0k->vURweRHkxXE*6@{A~%HakY9&t0VBr0G$*&a;93L7@J;|DRrd zO@02d)1NBWPrUsLx%koF$hA-ZPDjppCeRNcm)-qgcmIFZ>VxX@XO>^r@3RBnXYZA- z`MtU3mj?@VIzOe-rv+ z=;%7xefB5*B>!3fr&yFhSe;E27hyEBj&&N9b0LB6q-*+VRhtD4o3;n_M z)f=GyR_KrOh$H9mY0w{j0Am4*?*yAppMU6R=nt+>p9}pLLjOh3A0y}Ea3;_XU@Tzq z=_jB+I9m1=^as~Zd({unvunLs~)T(8lUx{odjq^v%%aO^8H%cV9AD2}r32Un)ZcT-r0bJ*E<^?Q%bsqFboL^ZD z{ZB#v8_@qf=>IYFe;4}W3^;lk`r|qGS$sqs^hcbZQvm(Tq5lz{A<+LS^vBu3GoZK} z`r|qGS^U6Ppg-dL=tStB4gE`?|32t{2>S1X{x}0tv!OqpbDza`=??u7=Z_i>{bxXb za6T>(`X@vG1n7@B*ZG|LEPnNA=#MzR5;p$mXVCwr(Eqp4|L>vyZ=gTUfTN#7e>~?t zi;pOW{)qE)VB?G5fd1h8i7%o5PoO`}4xRzUH=sYBbDzZz%!dAm^P{Vve;xD(=XXNZ zp7)_Y-apGTAhizq<2mE;FNXfxpnnnc#~HwNKIcA*U%kFq zRjUcW8pF5lEMfa`qDynw|=CuC}z&)fm+{jR;W!ZYK@iHkb& z4B$GSGcREAG1TB8hq7n&*Z_ju?13o|P z{+>%emfD+tjWgg&opXIr{z=UVT6~vR5~Uw}d&c`y;q%k(C*)K~YJLsQfIT|r`e@_? zm=m=4H3iTgwwCdJ9ejS;eRBWPA4C6-pg-nZuQ~wz5d&EKyd}^dzCGjp(n{zLyHD<4 ze+&9wh5ndxecdMLj~Kz?2aSXN@a-AzXTayD-QRN%`k#XShoC>^Twjy~{ShNre3u^3 ze+cwPygzj|^oQL~SPuQuq5pE|k2%*zPk{c&30nM`v(O*DJ>&g4`24i{6>hyH&L z{W0fy)w|Fi`z(H5CG>}H&v?HSK0oa~xqtl^(En@bk2%-ZorC^}5iEYtTIjzO`Xk=Y zI05}(_xHR9{Xc{LA3%T1xxQ#G^hbH`DGXY=!=1(0?2B$DHe< zlc7Ii0E=Ix-CMxPg(m8oszODeBK1+Twj`!qx&qL{HJfv zcz;GjtlE8Ye|c(_o&od&xIO{T86!BnyT9-3f5rJPjQ#(2wf~ns{w>zOk&5#_s;>u_ z`~S}VXII@c_Ww6(|My+RyR>2dv#Z`z`|s`_JNeH3FU-ZA;k)*~oc90Hmr@S<&wK*y z|H9mpYX2?X+5eFdYa8tUV%qZ^_(EcxshyJkt7Vqr;$g$A>uKiz3`=12;VgKhXg#K9PbJ~B4clN*H4)njz{zHG* z|4ToG{;>ZQcc4G(0apLJ_CNb9^bfTE;6CmDzK@_k?0@!I=nwmE@y`A)tb+b`?SJ_l z+JET(HuOjAK>NS23i`wTTfDRXBbP(}yY_!E-cy;d75c;e&)Wd~vCikT{}%7;KXZQf z*?(|f?fgklKHXclMt-zx(a~CAI(Md!79+Rr_!8&i*f6Ztee(di#&qq2B)I zsQtHiXaC1dzGwgAg4lmPr~P+$cYi-)XF&XqIG;W{IZr>}GRAxH|EC(?yZgfqKYP`^ z_@8k;<9%|Te!zZ=4e|f3>zXI9_5AJ@NQ7V{}%r|a{n&= zXPnP?pPZ*35Q(uN{-2Yj`z$^qF#boJPtKC_wELGa-i!aCKjL_cpS|#2{LeU_@jf|E zyT2b}L;SxU`Xm0g_wjMi+?^K{%4%ec%Pi7-H(ih z{x1F>1N{;ITYLuUehu+I;(T(JoTuHt{0;PPi2tEK;(Lpqz5QPN&p4m)J~>ajzyCw% z@8bVc&>!)?#rH$q&&B_Y^BM1x^R)XLF*d~ic=tT_S^V>;`?>g^aX#aHa-McS5@SRB zkNg1lS$xp=ADpKja13KZ{C_u&xA>^V-uR!KXZ*hlql^DnA5$UK1N z|6%tv|BrRn2Xau?3%ozfKA?vDe+lxxh$YxRz&wEF|6%tz=Q?8q)(I@WA^)GgU+V)2 zMd#HI(ELB_KIg0(Fh*b>fW^1JFaMvdIY8Qb&HrO$PH;p-w#Ep||66=R{vW>mu4?Fy z93cGw&HuyhYyKbWj1gETu=s}j|7z%uSb}E+{Q%AX!|rp=b;by+6IgsVm;aB1{-_Tm ztc3pX12q2+yU#h-86&VxVDatm%l|`v^sLl2O< zKkV+`k6Tt>|Bptko;5(N|HId3yw8|mRYiUMKN|f3GtdKM@tr2u*Z)VNzRwz<*8kz_ zGu~%RFmLTqT_1`5fZpfpMTh#`uabgvroX{<5TPF z|LZqHe{fvu|M2x0?=vRYxwpRlzaI7fw6#I>pI%@8k4CMYH9)QZ!`ElL&zNAI&)Fy7(Z8m?{=XjaJ2|fPfB5>0_ZbuHyj%ZYkN$wP<3aS_RA2v( zMy;MTK&}77*Jr%Xm|)eZ`uczLKIo77zm?x=g4@UF~KUt?ppsxf53dy|1G|u{y+C#{eMYvj>h|p z37B8d`ahntPr%~utN$au*ZMzvea8Fr`CozE53K(?yu1Hj-~V?`dwXc#3l6?5n`__G zvw(eof&G7p#pmw3Kg>EnegEHX?d_@W|2r+qwqDS)fcgHw{=W&yyFK{&{=fCw161Gt zS1FTM?o-a&{=Y6$*L(2w{eRKQ?S}rpscCu^Fy0UB|7$le+Jmp}|AYSM?WynogZ^dE zA7_E>|4YmWqQCb4L4Wl2X#Za-^v{I;I16n5--KB~^zVxPw?5Dx+^+BcgZ>fFADp-S zf81y9e?P+hzvrMoxJ~=6{eMHCKh6T%|Hpk6AEW($&>!5c@Bf4T*P%bo0^9$Wh}yix zYyaP7=nrnwPA{o}{zsrc&H~2!tod=B&nIA?#kXVsUlR0350Li%;XIkV75anow*Qa& zEdCMg|AYSEHtoCi|HVOnoCUW3uU)uTf7k!V9w6=i+q_c>wg&J2W1pav&;GxeQOlIu z_5FYAG|ngInePwm|KmQ3zt{g4*`)qIi)a7ei@k;3$I&~CGZ zXTX#F@eY6?vBG`;<^;Qw~j+}?jgZ}6fH#31*#v{unt=sfGUN6XZUNACLw8(E~hwBlJgpj{N|v3G(}L zv^O^9j&D75bwefH}dzs0(o9yjvRdPlEn&LG*tG`r{0EatidH z0sV0fFelh`9`wh^IoF>EhyK`S<jE4(=Q{la?z8yz zUHYQ0b0Ge|hoZ-Gq%a@AoM7J}<8|bm>+};kVV}b{-=A;3Ki_ ] will try to center the button. -json // Element -NuiSpacer(); +json NuiSpacer(); // Create a label field. Labels are single-line stylable non-editable text fields. -json // Element -NuiLabel( - json jValue, // Bind:String - json jHAlign, // Bind:Int:NUI_HALIGN_* - json jVAlign // Bind:Int:NUI_VALIGN_* -); +// - jValue: Bind:String +// - jHAlign: Bind:Int:NUI_HALIGN_* +// - jVAlign: Bind:Int:NUI_VALIGN_* +json NuiLabel(json jValue, json jHAlign, json jVAlign); // Create a non-editable text field. Note: This text field internally implies a NuiGroup wrapped // around it, which is providing the optional border and scrollbars. -json // Element -NuiText( - json jValue, // Bind:String - int bBorder = TRUE, // Bool - int nScroll = NUI_SCROLLBARS_AUTO // Int:NUI_SCROLLBARS_* -); +// - jValue: Bind:String +// - bBorder: Bool +// - nScroll: Int:NUI_SCROLLBARS_* +json NuiText(json jValue, int bBorder = TRUE, int nScroll = NUI_SCROLLBARS_AUTO); // A clickable button with text as the label. // Sends "click" events on click. -json // Element -NuiButton( - json jLabel // Bind:String -); +// - jLabel: Bind:String +json NuiButton(json jLabel); // A clickable button with an image as the label. // Sends "click" events on click. -json // Element -NuiButtonImage( - json jResRef // Bind:ResRef -); +// - jResRef: Bind:String +json NuiButtonImage(json jResRef); // A clickable button with text as the label. // Same as the normal button, but this one is a toggle. // Sends "click" events on click. -json // Element -NuiButtonSelect( - json jLabel, // Bind:String - json jValue // Bind:Bool -); +// - jLabel: Bind:String +// - jValue: Bind:Bool +json NuiButtonSelect(json jLabel, json jValue); // A checkbox with a label to the right of it. -json // Element -NuiCheck( - json jLabel, // Bind:String - json jBool // Bind:Bool -); +// - jLabel: Bind:String +// - jBool: Bind:Bool +json NuiCheck(json jLabel, json jBool); // A image, with no border or padding. -json // Element -NuiImage( - json jResRef, // Bind:ResRef - json jAspect, // Bind:Int:NUI_ASPECT_* - json jHAlign, // Bind:Int:NUI_HALIGN_* - json jVAlign // Bind:Int:NUI_VALIGN_* -); +// - jResRef: Bind:String +// - jAspect: Bind:Int:NUI_ASPECT_* +// - jHAlign: Bind:Int:NUI_HALIGN_* +// - jVAlign: Bind:Int:NUI_VALIGN_* +json NuiImage(json jResRef, json jAspect, json jHAlign, json jVAlign); -// Optionally render only subregion of jImage. +// Optionally render only subregion of jImage. This property can be set on +// NuiImage and NuiButtonImage widgets. // jRegion is a NuiRect (x, y, w, h) to indicate the render region inside the image. -json // NuiImage -NuiImageRegion( - json jImage, // NuiImage - json jRegion // Bind:NuiRect -); +json NuiImageRegion(json jImage, json jRegion); // A combobox/dropdown. -json // Element -NuiCombo( - json jElements, // Bind:ComboEntry[] - json jSelected // Bind:Int (index into jElements) -); +// - jElements: Bind:ComboEntry[] +// - jSelected: Bind:Int (index into jElements) +json NuiCombo(json jElements, json jSelected); -json // ComboEntry -NuiComboEntry( - string sLabel, - int nValue -); +json NuiComboEntry(string sLabel, int nValue); // A floating-point slider. A good step size for normal-sized sliders is 0.01. -json // Element -NuiSliderFloat( - json jValue, // Bind:Float - json jMin, // Bind:Float - json jMax, // Bind:Float - json jStepSize // Bind:Float -); +// - jValue: Bind:Float +// - jMin: Bind:Float +// - jMax: Bind:Float +// - jStepSize: Bind:Float +json NuiSliderFloat(json jValue, json jMin, json jMax, json jStepSize); // A integer/discrete slider. -json // Element -NuiSlider( - json jValue, // Bind:Int - json jMin, // Bind:Int - json jMax, // Bind:Int - json jStepSize // Bind:Int -); +// - jValue: Bind:Int +// - jMin: Bind:Int +// - jMax: Bind:Int +// - jStepSize: Bind:Int +json NuiSlider(json jValue, json jMin, json jMax, json jStepSize); // A progress bar. Progress is always from 0.0 to 1.0. -json // Element -NuiProgress( - json jValue // Bind:Float (0.0->1.0) -); +// - jValue: Bind:Float (0.0->1.0 +json NuiProgress(json jValue); // A editable text field. -json // Element -NuiTextEdit( - json jPlaceholder, // Bind:String - json jValue, // Bind:String - int nMaxLength, // UInt >= 1, <= 65535 - int bMultiline, // Bool - int bWordWrap = TRUE // Bool -); +// - jPlaceholder: Bind:String +// - jValue: Bind:String +// - nMaxLength: UInt >= 1, <= 65535 +// - bMultiLine: Bool +// - bWordWrap: Bool +json NuiTextEdit(json jPlaceholder, json jValue, int nMaxLength, int bMultiline, int bWordWrap = TRUE); // Creates a list view of elements. // jTemplate needs to be an array of NuiListTemplateCell instances. @@ -339,67 +309,52 @@ NuiTextEdit( // e.g. when rendering a NuiLabel(), the bound label String should be an array of strings. // You can pass in one of the template jRowCount into jSize as a convenience. The array // size will be uses as the Int bind. -// jRowHeight defines the height of the rendered rows. -json // Element -NuiList( - json jTemplate, // NuiListTemplateCell[] (max: 16) - json jRowCount, // Bind:Int - float fRowHeight = NUI_STYLE_ROW_HEIGHT, - int bBorder = TRUE, - int nScroll = NUI_SCROLLBARS_Y // Note: Cannot be AUTO. -); +// fRowHeight defines the height of the rendered rows. +// - jTemplate: NuiListTemplateCell[] (max: 16) +// - jRowCount: Bind:Int +// - bBorder: Bool +// - nScroll: Int:NUI_SCROLLBARS_*, Note: Cannot be AUTO +json NuiList(json jTemplate, json jRowCount, float fRowHeight = NUI_STYLE_ROW_HEIGHT, int bBorder = TRUE, int nScroll = NUI_SCROLLBARS_Y); -json // NuiListTemplateCell -NuiListTemplateCell( - json jElem, // Element - float fWidth, // Float:0 = auto, >1 = pixel width - int bVariable // Bool:Cell can grow if space is available; otherwise static -); +// - jElem: Element +// - fWidth: Float:0 = auto, >1 = pixel width +// - bVariable: Bool:Cell can grow if space is available; otherwise static +json NuiListTemplateCell(json jElem, float fWidth, int bVariable); // A simple color picker, with no border or spacing. -json // Element -NuiColorPicker( - json jColor // Bind:Color -); +// - jColor: Bind:Color +json NuiColorPicker(json jColor); // A list of options (radio buttons). Only one can be selected // at a time. jValue is updated every time a different element is // selected. The special value -1 means "nothing". -json // Element -NuiOptions( - int nDirection, // NUI_DIRECTION_* - json jElements, // JsonArray of string labels - json jValue // Bind:Int -); +// - nDirection: NUI_DIRECTION_* +// - jElements: JsonArray of string labels +// - jValue: Bind:UInt +json NuiOptions(int nDirection, json jElements, json jValue); -// A group of buttons. Only one can be selected at a time. jValue -// is updated every time a different button is selected. The special +// A group of buttons. Only one can be selected at a time. jValue +// is updated every time a different button is selected. The special // value -1 means "nothing". -json // Element -NuiToggles( - int nDirection, // NUI_DIRECTION_* - json jElements, // JsonArray of string labels - json jValue // Bind:Int -); +// - nDirection: NUI_DIRECTION_* +// - jElements: JsonArray of string labels +// - jValue: Bind:Int +json NuiToggles(int nDirection, json jElements, json jValue); const int NUI_CHART_TYPE_LINES = 0; const int NUI_CHART_TYPE_COLUMN = 1; -json // NuiChartSlot -NuiChartSlot( - int nType, // Int:NUI_CHART_TYPE_* - json jLegend, // Bind:String - json jColor, // Bind:NuiColor - json jData // Bind:Float[] -); +// - nType: Int:NUI_CHART_TYPE_* +// - jLegend: Bind:String +// - jColor: Bind:NuiColor +// - jData: Bind:Float[] +json NuiChartSlot(int nType, json jLegend, json jColor, json jData); // Renders a chart. // Currently, min and max values are determined automatically and // cannot be influenced. -json // Element -NuiChart( - json jSlots // NuiChartSlot[] -); +// - jSlots: NuiChartSlot[] +json NuiChart( json jSlots); // ----------------------- // Draw Lists @@ -417,6 +372,7 @@ const int NUI_DRAW_LIST_ITEM_TYPE_ARC = 3; const int NUI_DRAW_LIST_ITEM_TYPE_TEXT = 4; const int NUI_DRAW_LIST_ITEM_TYPE_IMAGE = 5; const int NUI_DRAW_LIST_ITEM_TYPE_LINE = 6; +const int NUI_DRAW_LIST_ITEM_TYPE_RECT = 7; // You can order draw list items to be painted either before, or after the // builtin render of the widget in question. This enables you to paint "behind" @@ -438,100 +394,100 @@ const int NUI_DRAW_LIST_ITEM_RENDER_MOUSE_RIGHT = 4; // Only render while MMB is held down. const int NUI_DRAW_LIST_ITEM_RENDER_MOUSE_MIDDLE = 5; -json // DrawListItem -NuiDrawListPolyLine( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jFill, // Bind:Bool - json jLineThickness, // Bind:Float - json jPoints, // Bind:Float[] Always provide points in pairs - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jFill: Bind:Bool +// - jLineThickness: Bind:Float +// - jPoints: Bind:Float[] Always provide points in pairs +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListPolyLine(json jEnabled, json jColor, json jFill, json jLineThickness, json jPoints, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // DrawListItem -NuiDrawListCurve( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jLineThickness, // Bind:Float - json jA, // Bind:Vec2 - json jB, // Bind:Vec2 - json jCtrl0, // Bind:Vec2 - json jCtrl1, // Bind:Vec2 - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jLineThickness: Bind:Float +// - jA: Bind:Vec2 +// - jB: Bind:Vec2 +// - jCtrl0: Bind:Vec2 +// - jCtrl1: Bind:Vec2 +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListCurve(json jEnabled, json jColor, json jLineThickness, json jA, json jB, json jCtrl0, json jCtrl1, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // DrawListItem -NuiDrawListCircle( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jFill, // Bind:Bool - json jLineThickness, // Bind:Float - json jRect, // Bind:Rect - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jFill: Bind:Bool +// - jLineThickness: Bind:Float +// - jRect: Bind:Rect +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListCircle(json jEnabled, json jColor, json jFill, json jLineThickness, json jRect, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // DrawListItem -NuiDrawListArc( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jFill, // Bind:Bool - json jLineThickness, // Bind:Float - json jCenter, // Bind:Vec2 - json jRadius, // Bind:Float - json jAMin, // Bind:Float - json jAMax, // Bind:Float - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jFill: Bind:Bool +// - jLineThickness: Bind:Float +// - jCenter: Bind:Rect +// - jRadius: Bind:Float +// - jAMin: Bind:Float +// - jAMax: Bind:Float +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListArc(json jEnabled, json jColor, json jFill, json jLineThickness, json jCenter, json jRadius, json jAMin, json jAMax, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // DrawListItem -NuiDrawListText( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jRect, // Bind:Rect - json jText, // Bind:String - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jRect: Bind:Rect +// - jText: Bind:String +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +// - jFont: Bind:String +json NuiDrawListText(json jEnabled, json jColor, json jRect, json jText, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE, json jFont = JSON_STRING); -json // DrawListItem -NuiDrawListImage( - json jEnabled, // Bind:Bool - json jResRef, // Bind:ResRef - json jPos, // Bind:Rect - json jAspect, // Bind:Int:NUI_ASPECT_* - json jHAlign, // Bind:Int:NUI_HALIGN_* - json jVAlign, // Bind:Int:NUI_VALIGN_* - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jResRef: Bind:String +// - jPos: Bind:Rect +// - jAspect: Bind:Int:NUI_ASPECT_* +// - jHAlign: Bind:Int:NUI_HALIGN_* +// - jVAlign: Bind:Int:NUI_VALIGN_* +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListImage(json jEnabled, json jResRef, json jPos, json jAspect, json jHAlign, json jVAlign, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // DrawListItemImage -NuiDrawListImageRegion( - json jDrawListImage, // DrawListItemImage - json jRegion // Bind:NuiRect -); +// - jDrawListImage: DrawListItemImage +// - jRegion: Bind:NuiRect +json NuiDrawListImageRegion(json jDrawListImage, json jRegion); -json // DrawListItem -NuiDrawListLine( - json jEnabled, // Bind:Bool - json jColor, // Bind:Color - json jLineThickness, // Bind:Float - json jA, // Bind:Vec2 - json jB, // Bind:Vec2 - int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, // Int:NUI_DRAW_LIST_ITEM_ORDER_* - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS // Int:NUI_DRAW_LIST_ITEM_RENDER_* -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jLineThickness: Bind:Float +// - jA: Bind:Vec2 +// - jB: Bind:Vec2 +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListLine(json jEnabled, json jColor, json jLineThickness, json jA, json jB, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); -json // Element -NuiDrawList( - json jElem, // Element - json jScissor, // Bind:Bool Constrain painted elements to widget bounds. - json jList // DrawListItem[] -); +// - jEnabled: Bind:Bool +// - jColor: Bind:Color +// - jFill: Bind:Bool +// - jLineThickness: Bind:Float +// - jRext: Bind:Rect +// - nOrder: Int:NUI_DRAW_LIST_ITEM_ORDER_* +// - nRender: Int:NUI_DRAW_LIST_ITEM_RENDER_* +// - nBindArrays: Values in binds are considered arrays-of-values +json NuiDrawListRect(json jEnabled, json jColor, json jFill, json jLineThickness, json jRect, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, int nBindArrays = FALSE); + +// - jElem: Element +// - jScissor: Bind:Bool, Constrain painted elements to widget bounds. +// - jList: DrawListItem[] +json NuiDrawList(json jElem, json jScissor, json jList); // ----------------------- // Implementation @@ -546,21 +502,27 @@ NuiWindow( json jClosable, json jTransparent, json jBorder, - json jAcceptsInput + json jAcceptsInput = JSON_TRUE, + json jWindowConstraint = JSON_NULL, + json jEdgeConstraint = JSON_NULL, + json jFont = JSON_STRING ) { json ret = JsonObject(); // Currently hardcoded and here to catch backwards-incompatible data in the future. - ret = JsonObjectSet(ret, "version", JsonInt(1)); - ret = JsonObjectSet(ret, "title", jTitle); - ret = JsonObjectSet(ret, "root", jRoot); - ret = JsonObjectSet(ret, "geometry", jGeometry); - ret = JsonObjectSet(ret, "resizable", jResizable); - ret = JsonObjectSet(ret, "collapsed", jCollapsed); - ret = JsonObjectSet(ret, "closable", jClosable); - ret = JsonObjectSet(ret, "transparent", jTransparent); - ret = JsonObjectSet(ret, "border", jBorder); - ret = JsonObjectSet(ret, "accepts_input", jAcceptsInput); + JsonObjectSetInplace(ret, "version", JsonInt(1)); + JsonObjectSetInplace(ret, "title", jTitle); + JsonObjectSetInplace(ret, "root", jRoot); + JsonObjectSetInplace(ret, "geometry", jGeometry); + JsonObjectSetInplace(ret, "resizable", jResizable); + JsonObjectSetInplace(ret, "collapsed", jCollapsed); + JsonObjectSetInplace(ret, "closable", jClosable); + JsonObjectSetInplace(ret, "transparent", jTransparent); + JsonObjectSetInplace(ret, "border", jBorder); + JsonObjectSetInplace(ret, "accepts_input", jAcceptsInput); + JsonObjectSetInplace(ret, "size_constraint", jWindowConstraint); + JsonObjectSetInplace(ret, "edge_constraint", jEdgeConstraint); + JsonObjectSetInplace(ret, "font", jFont); return ret; } @@ -572,18 +534,26 @@ NuiElement( ) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "type", JsonString(sType)); - ret = JsonObjectSet(ret, "label", jLabel); - ret = JsonObjectSet(ret, "value", jValue); + JsonObjectSetInplace(ret, "type", JsonString(sType)); + JsonObjectSetInplace(ret, "label", jLabel); + JsonObjectSetInplace(ret, "value", jValue); return ret; } json NuiBind( - string sId + string sId, + int nNumberFlags = 0, + int nNumberPrecision = 0, + int nTextFlags = 0 ) { - return JsonObjectSet(JsonObject(), "bind", JsonString(sId)); + json ret = JsonObject(); + JsonObjectSetInplace(ret, "bind", JsonString(sId)); + JsonObjectSetInplace(ret, "number_flags", JsonInt(nNumberFlags)); + JsonObjectSetInplace(ret, "number_precision", JsonInt(nNumberPrecision)); + JsonObjectSetInplace(ret, "text_flags", JsonInt(nTextFlags)); + return ret; } json @@ -601,7 +571,7 @@ NuiStrRef( ) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "strref", JsonInt(nStrRef)); + JsonObjectSetInplace(ret, "strref", JsonInt(nStrRef)); return ret; } @@ -629,9 +599,9 @@ NuiGroup( ) { json ret = NuiElement("group", JsonNull(), JsonNull()); - ret = JsonObjectSet(ret, "children", JsonArrayInsert(JsonArray(), jChild)); - ret = JsonObjectSet(ret, "border", JsonBool(bBorder)); - ret = JsonObjectSet(ret, "scrollbars", JsonInt(nScroll)); + JsonObjectSetInplace(ret, "children", JsonArrayInsert(JsonArray(), jChild)); + JsonObjectSetInplace(ret, "border", JsonBool(bBorder)); + JsonObjectSetInplace(ret, "scrollbars", JsonInt(nScroll)); return ret; } @@ -720,8 +690,8 @@ json NuiVec(float x, float y) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "x", JsonFloat(x)); - ret = JsonObjectSet(ret, "y", JsonFloat(y)); + JsonObjectSetInplace(ret, "x", JsonFloat(x)); + JsonObjectSetInplace(ret, "y", JsonFloat(y)); return ret; } @@ -729,10 +699,10 @@ json NuiRect(float x, float y, float w, float h) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "x", JsonFloat(x)); - ret = JsonObjectSet(ret, "y", JsonFloat(y)); - ret = JsonObjectSet(ret, "w", JsonFloat(w)); - ret = JsonObjectSet(ret, "h", JsonFloat(h)); + JsonObjectSetInplace(ret, "x", JsonFloat(x)); + JsonObjectSetInplace(ret, "y", JsonFloat(y)); + JsonObjectSetInplace(ret, "w", JsonFloat(w)); + JsonObjectSetInplace(ret, "h", JsonFloat(h)); return ret; } @@ -740,10 +710,10 @@ json NuiColor(int r, int g, int b, int a = 255) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "r", JsonInt(r)); - ret = JsonObjectSet(ret, "g", JsonInt(g)); - ret = JsonObjectSet(ret, "b", JsonInt(b)); - ret = JsonObjectSet(ret, "a", JsonInt(a)); + JsonObjectSetInplace(ret, "r", JsonInt(r)); + JsonObjectSetInplace(ret, "g", JsonInt(g)); + JsonObjectSetInplace(ret, "b", JsonInt(b)); + JsonObjectSetInplace(ret, "a", JsonInt(a)); return ret; } @@ -756,6 +726,15 @@ NuiStyleForegroundColor( return JsonObjectSet(jElem, "foreground_color", jColor); } +json +NuiStyleFont( + json jElem, + json jFont +) +{ + return JsonObjectSet(jElem, "font", jFont); +} + json NuiSpacer() { @@ -770,8 +749,8 @@ NuiLabel( ) { json ret = NuiElement("label", JsonNull(), jValue); - ret = JsonObjectSet(ret, "text_halign", jHAlign); - ret = JsonObjectSet(ret, "text_valign", jVAlign); + JsonObjectSetInplace(ret, "text_halign", jHAlign); + JsonObjectSetInplace(ret, "text_valign", jVAlign); return ret; } @@ -783,8 +762,8 @@ NuiText( ) { json ret = NuiElement("text", JsonNull(), jValue); - ret = JsonObjectSet(ret, "border", JsonBool(bBorder)); - ret = JsonObjectSet(ret, "scrollbars", JsonInt(nScroll)); + JsonObjectSetInplace(ret, "border", JsonBool(bBorder)); + JsonObjectSetInplace(ret, "scrollbars", JsonInt(nScroll)); return ret; } @@ -831,9 +810,9 @@ NuiImage( ) { json img = NuiElement("image", JsonNull(), jResRef); - img = JsonObjectSet(img, "image_aspect", jAspect); - img = JsonObjectSet(img, "image_halign", jHAlign); - img = JsonObjectSet(img, "image_valign", jVAlign); + JsonObjectSetInplace(img, "image_aspect", jAspect); + JsonObjectSetInplace(img, "image_halign", jHAlign); + JsonObjectSetInplace(img, "image_valign", jVAlign); return img; } @@ -873,9 +852,9 @@ NuiSliderFloat( ) { json ret = NuiElement("sliderf", JsonNull(), jValue); - ret = JsonObjectSet(ret, "min", jMin); - ret = JsonObjectSet(ret, "max", jMax); - ret = JsonObjectSet(ret, "step", jStepSize); + JsonObjectSetInplace(ret, "min", jMin); + JsonObjectSetInplace(ret, "max", jMax); + JsonObjectSetInplace(ret, "step", jStepSize); return ret; } @@ -888,9 +867,9 @@ NuiSlider( ) { json ret = NuiElement("slider", JsonNull(), jValue); - ret = JsonObjectSet(ret, "min", jMin); - ret = JsonObjectSet(ret, "max", jMax); - ret = JsonObjectSet(ret, "step", jStepSize); + JsonObjectSetInplace(ret, "min", jMin); + JsonObjectSetInplace(ret, "max", jMax); + JsonObjectSetInplace(ret, "step", jStepSize); return ret; } @@ -912,9 +891,9 @@ NuiTextEdit( ) { json ret = NuiElement("textedit", jPlaceholder, jValue); - ret = JsonObjectSet(ret, "max", JsonInt(nMaxLength)); - ret = JsonObjectSet(ret, "multiline", JsonBool(bMultiline)); - ret = JsonObjectSet(ret, "wordwrap", JsonBool(bWordWrap)); + JsonObjectSetInplace(ret, "max", JsonInt(nMaxLength)); + JsonObjectSetInplace(ret, "multiline", JsonBool(bMultiline)); + JsonObjectSetInplace(ret, "wordwrap", JsonBool(bWordWrap)); return ret; } @@ -928,11 +907,11 @@ NuiList( ) { json ret = NuiElement("list", JsonNull(), JsonNull()); - ret = JsonObjectSet(ret, "row_template", jTemplate); - ret = JsonObjectSet(ret, "row_count", jRowCount); - ret = JsonObjectSet(ret, "row_height", JsonFloat(fRowHeight)); - ret = JsonObjectSet(ret, "border", JsonBool(bBorder)); - ret = JsonObjectSet(ret, "scrollbars", JsonInt(nScroll)); + JsonObjectSetInplace(ret, "row_template", jTemplate); + JsonObjectSetInplace(ret, "row_count", jRowCount); + JsonObjectSetInplace(ret, "row_height", JsonFloat(fRowHeight)); + JsonObjectSetInplace(ret, "border", JsonBool(bBorder)); + JsonObjectSetInplace(ret, "scrollbars", JsonInt(nScroll)); return ret; } @@ -944,9 +923,9 @@ NuiListTemplateCell( ) { json ret = JsonArray(); - ret = JsonArrayInsert(ret, jElem); - ret = JsonArrayInsert(ret, JsonFloat(fWidth)); - ret = JsonArrayInsert(ret, JsonBool(bVariable)); + JsonArrayInsertInplace(ret, jElem); + JsonArrayInsertInplace(ret, JsonFloat(fWidth)); + JsonArrayInsertInplace(ret, JsonBool(bVariable)); return ret; } @@ -967,8 +946,8 @@ NuiOptions( ) { json ret = NuiElement("options", JsonNull(), jValue); - ret = JsonObjectSet(ret, "direction", JsonInt(nDirection)); - ret = JsonObjectSet(ret, "elements", jElements); + JsonObjectSetInplace(ret, "direction", JsonInt(nDirection)); + JsonObjectSetInplace(ret, "elements", jElements); return ret; } @@ -980,8 +959,8 @@ NuiToggles( ) { json ret = NuiElement("tabbar", JsonNull(), jValue); - ret = JsonObjectSet(ret, "direction", JsonInt(nDirection)); - ret = JsonObjectSet(ret, "elements", jElements); + JsonObjectSetInplace(ret, "direction", JsonInt(nDirection)); + JsonObjectSetInplace(ret, "elements", jElements); return ret; } @@ -994,10 +973,10 @@ NuiChartSlot( ) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "type", JsonInt(nType)); - ret = JsonObjectSet(ret, "legend", jLegend); - ret = JsonObjectSet(ret, "color", jColor); - ret = JsonObjectSet(ret, "data", jData); + JsonObjectSetInplace(ret, "type", JsonInt(nType)); + JsonObjectSetInplace(ret, "legend", jLegend); + JsonObjectSetInplace(ret, "color", jColor); + JsonObjectSetInplace(ret, "data", jData); return ret; } @@ -1018,17 +997,19 @@ NuiDrawListItem( json jFill, json jLineThickness, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { json ret = JsonObject(); - ret = JsonObjectSet(ret, "type", JsonInt(nType)); - ret = JsonObjectSet(ret, "enabled", jEnabled); - ret = JsonObjectSet(ret, "color", jColor); - ret = JsonObjectSet(ret, "fill", jFill); - ret = JsonObjectSet(ret, "line_thickness", jLineThickness); - ret = JsonObjectSet(ret, "order", JsonInt(nOrder)); - ret = JsonObjectSet(ret, "render", JsonInt(nRender)); + JsonObjectSetInplace(ret, "type", JsonInt(nType)); + JsonObjectSetInplace(ret, "enabled", jEnabled); + JsonObjectSetInplace(ret, "color", jColor); + JsonObjectSetInplace(ret, "fill", jFill); + JsonObjectSetInplace(ret, "line_thickness", jLineThickness); + JsonObjectSetInplace(ret, "order", JsonInt(nOrder)); + JsonObjectSetInplace(ret, "render", JsonInt(nRender)); + JsonObjectSetInplace(ret, "arrayBinds", JsonBool(nBindArrays)); return ret; } @@ -1040,11 +1021,12 @@ NuiDrawListPolyLine( json jLineThickness, json jPoints, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_POLYLINE, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender); - ret = JsonObjectSet(ret, "points", jPoints); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_POLYLINE, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "points", jPoints); return ret; } @@ -1058,14 +1040,15 @@ NuiDrawListCurve( json jCtrl0, json jCtrl1, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_CURVE, jEnabled, jColor, JsonBool(0), jLineThickness, nOrder, nRender); - ret = JsonObjectSet(ret, "a", jA); - ret = JsonObjectSet(ret, "b", jB); - ret = JsonObjectSet(ret, "ctrl0", jCtrl0); - ret = JsonObjectSet(ret, "ctrl1", jCtrl1); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_CURVE, jEnabled, jColor, JsonBool(0), jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "a", jA); + JsonObjectSetInplace(ret, "b", jB); + JsonObjectSetInplace(ret, "ctrl0", jCtrl0); + JsonObjectSetInplace(ret, "ctrl1", jCtrl1); return ret; } @@ -1077,11 +1060,12 @@ NuiDrawListCircle( json jLineThickness, json jRect, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_CIRCLE, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender); - ret = JsonObjectSet(ret, "rect", jRect); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_CIRCLE, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "rect", jRect); return ret; } @@ -1096,14 +1080,15 @@ NuiDrawListArc( json jAMin, json jAMax, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_ARC, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender); - ret = JsonObjectSet(ret, "c", jCenter); - ret = JsonObjectSet(ret, "radius", jRadius); - ret = JsonObjectSet(ret, "amin", jAMin); - ret = JsonObjectSet(ret, "amax", jAMax); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_ARC, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "c", jCenter); + JsonObjectSetInplace(ret, "radius", jRadius); + JsonObjectSetInplace(ret, "amin", jAMin); + JsonObjectSetInplace(ret, "amax", jAMax); return ret; } @@ -1114,12 +1099,15 @@ NuiDrawListText( json jRect, json jText, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE, + json jFont = JSON_STRING ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_TEXT, jEnabled, jColor, JsonNull(), JsonNull(), nOrder, nRender); - ret = JsonObjectSet(ret, "rect", jRect); - ret = JsonObjectSet(ret, "text", jText); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_TEXT, jEnabled, jColor, JsonNull(), JsonNull(), nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "rect", jRect); + JsonObjectSetInplace(ret, "text", jText); + ret = NuiStyleFont(ret, jFont); return ret; } @@ -1132,15 +1120,16 @@ NuiDrawListImage( json jHAlign, json jVAlign, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_IMAGE, jEnabled, JsonNull(), JsonNull(), JsonNull(), nOrder, nRender); - ret = JsonObjectSet(ret, "image", jResRef); - ret = JsonObjectSet(ret, "rect", jRect); - ret = JsonObjectSet(ret, "image_aspect", jAspect); - ret = JsonObjectSet(ret, "image_halign", jHAlign); - ret = JsonObjectSet(ret, "image_valign", jVAlign); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_IMAGE, jEnabled, JsonNull(), JsonNull(), JsonNull(), nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "image", jResRef); + JsonObjectSetInplace(ret, "rect", jRect); + JsonObjectSetInplace(ret, "image_aspect", jAspect); + JsonObjectSetInplace(ret, "image_halign", jHAlign); + JsonObjectSetInplace(ret, "image_valign", jVAlign); return ret; } @@ -1161,12 +1150,30 @@ NuiDrawListLine( json jA, json jB, int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, - int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE ) { - json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_LINE, jEnabled, jColor, JsonNull(), jLineThickness, nOrder, nRender); - ret = JsonObjectSet(ret, "a", jA); - ret = JsonObjectSet(ret, "b", jB); + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_LINE, jEnabled, jColor, JsonNull(), jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "a", jA); + JsonObjectSetInplace(ret, "b", jB); + return ret; +} + +json +NuiDrawListRect( + json jEnabled, + json jColor, + json jFill, + json jLineThickness, + json jRect, + int nOrder = NUI_DRAW_LIST_ITEM_ORDER_AFTER, + int nRender = NUI_DRAW_LIST_ITEM_RENDER_ALWAYS, + int nBindArrays = FALSE +) +{ + json ret = NuiDrawListItem(NUI_DRAW_LIST_ITEM_TYPE_RECT, jEnabled, jColor, jFill, jLineThickness, nOrder, nRender, nBindArrays); + JsonObjectSetInplace(ret, "rect", jRect); return ret; } @@ -1178,7 +1185,7 @@ NuiDrawList( ) { json ret = JsonObjectSet(jElem, "draw_list", jList); - ret = JsonObjectSet(ret, "draw_list_scissor", jScissor); + JsonObjectSetInplace(ret, "draw_list_scissor", jScissor); return ret; } @@ -1190,4 +1197,3 @@ NuiDrawList( // json ret = NuiElement("canvas", JsonNull(), jList); // return ret; // } - diff --git a/src/include/prc_inc_combat.nss b/src/include/prc_inc_combat.nss index 3cdbab5..df4a5b7 100644 --- a/src/include/prc_inc_combat.nss +++ b/src/include/prc_inc_combat.nss @@ -1206,6 +1206,7 @@ int GetIsDoubleSidedWeaponType(int iWeaponType) return ( iWeaponType == BASE_ITEM_DIREMACE || iWeaponType == BASE_ITEM_DOUBLEAXE || iWeaponType == BASE_ITEM_TWOBLADEDSWORD + || iWeaponType == BASE_ITEM_DOUBLE_SCIMITAR ); } diff --git a/src/module/dlg/nw_g_animal.dlg.json b/src/module/dlg/nw_g_animal.dlg.json new file mode 100644 index 0000000..a65a225 --- /dev/null +++ b/src/module/dlg/nw_g_animal.dlg.json @@ -0,0 +1,49670 @@ +{ + "__data_type": "DLG ", + "DelayEntry": { + "type": "dword", + "value": 0 + }, + "DelayReply": { + "type": "dword", + "value": 0 + }, + "EndConverAbort": { + "type": "resref", + "value": "" + }, + "EndConversation": { + "type": "resref", + "value": "" + }, + "EntryList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_scout" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 439 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_identify" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 438 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " You feel warm thoughts from your animal companion, as it wonders what you would like.", + "id": 53321 + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58454 + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58455 + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58456 + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58457 + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58458 + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58459 + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58460 + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58461 + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58462 + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58463 + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "The animal seems confused about your actions, but slinks away to appease you.", + "id": 58464 + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st-11" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58464 + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58465 + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58466 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58467 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_12" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "The animal is quite famished and devours the food you offer. The companion seems content.", + "id": 58468 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58469 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 141 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + }, + { + "__struct_id": 7, + "Key": { + "type": "cexostring", + "value": "nClass8" + }, + "Value": { + "type": "cexostring", + "value": "46" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " looks up at you, obviously willing to do as you ask.", + "id": 58470 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x2_hen_tomishad3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " waits for you to tell it what to summon." + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 58 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 48 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 38 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Ready to cast it waits for your command.", + "id": 88866 + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 37 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 47 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 46 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 45 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 44 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 43 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 42 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 41 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 40 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 39 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 57 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 54 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 53 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 52 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 51 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 50 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 49 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 140 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 139 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 130 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 129 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 128 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 127 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 126 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 125 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 124 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 123 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 122 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 121 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 120 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 119 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 116 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 115 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 16, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 114 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 17, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 113 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 18, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 112 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 19, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 111 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 20, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 110 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 21, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 109 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 22, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 108 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 23, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 107 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 24, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 106 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 25, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 105 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 26, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 104 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 27, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 103 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 28, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 102 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 29, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 101 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 30, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 100 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 31, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 99 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 32, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 98 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 33, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 97 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 34, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 96 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 35, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 95 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 36, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 94 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 37, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 93 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 38, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 92 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 39, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 91 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 40, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 90 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 41, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 89 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 42, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 88 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 43, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 87 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 44, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 86 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 45, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 85 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 46, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 84 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 47, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 83 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 48, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 82 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 49, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 81 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 50, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 80 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 51, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 79 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 52, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 78 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 53, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 77 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 54, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 76 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 55, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 75 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 56, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 74 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 57, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 73 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 58, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 72 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 59, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 71 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 60, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 70 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 61, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 69 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 62, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 68 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 63, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 67 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 64, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 66 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 65, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 65 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 66, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 64 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 67, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 63 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 68, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 62 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 69, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 70, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 71, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 72, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "At the ready your companion listens.", + "id": 87720 + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 118 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 117 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 138 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 137 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 136 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 135 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 134 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 133 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 132 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 131 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Okay. Who shoulds I cast it on?", + "id": 87722 + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 150 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 149 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 148 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 147 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 146 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 145 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 144 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 143 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 142 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Looking at you it waits.", + "id": 87722 + } + } + }, + { + "__struct_id": 29, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 180 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 179 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 178 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_pickuploot" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 177 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 170 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 159 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 158 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 157 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_skillrank" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSkill" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nRank" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 153 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " looks at you awaiting your instructions on tactics." + } + } + }, + { + "__struct_id": 30, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 156 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 155 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 154 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Looking around, it listens for you to tell them how to deal with objects." + } + } + }, + { + "__struct_id": 31, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 169 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 168 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 167 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 166 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 165 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 164 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 163 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_cntrspell" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 162 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 161 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 160 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Your companion looks up to the sky while you tell it how to use magic." + } + } + }, + { + "__struct_id": 32, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 176 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 175 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 174 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 173 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 172 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 171 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Looking at you, waits for instructon on how it should heal.", + "id": 55427 + } + } + }, + { + "__struct_id": 33, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 437 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_defensive" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 436 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ambusher" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 435 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ranged" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 187 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_peaceful" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 186 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_taunt" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 185 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_taunt" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 184 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 183 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_assoc_mode" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nMode" + }, + "Value": { + "type": "cexostring", + "value": "16384" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 182 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 181 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Your companion listens intently for your combat tactics." + } + } + }, + { + "__struct_id": 34, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 434 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_defensive" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 433 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ambusher" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 432 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ranged" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 187 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 431 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_taunt" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 430 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 429 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 428 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 427 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 426 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What do you think is the best tactic?" + } + } + }, + { + "__struct_id": 35, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 425 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 424 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 423 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_pickuploot" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 422 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 415 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 403 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 402 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 401 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 397 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What do you have in mind?" + } + } + }, + { + "__struct_id": 36, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 38 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_scout" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 396 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_identify" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 395 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_open_inven" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 391 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 380 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 298 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 266 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + }, + { + "__struct_id": 7, + "Key": { + "type": "cexostring", + "value": "nClass8" + }, + "Value": { + "type": "cexostring", + "value": "46" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 251 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 195 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_hen_leave" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 192 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_convo" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 191 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What would you like to discuss?" + } + } + }, + { + "__struct_id": 37, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 194 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 193 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Are you sure you want to do that?" + } + } + }, + { + "__struct_id": 38, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_polymorph" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 250 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "305" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 244 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "304" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 239 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "898" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 233 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "900" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 229 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "901" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 225 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "903" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 221 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "902" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 217 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "1060" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 213 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "1061" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 209 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "257" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 208 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "x2_d2_haslayon" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 198 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "x2_d1_dmight" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 197 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "x2_d1_dshield" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 196 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's see what I can do...", + "id": 95904 + } + } + }, + { + "__struct_id": 39, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 207 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 206 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 205 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 204 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 201 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 200 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And who should be the target of my healing?", + "id": 87722 + } + } + }, + { + "__struct_id": 40, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 212 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 211 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 210 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 41, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 216 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 215 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 214 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 42, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 220 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 219 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 218 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 43, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 224 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 223 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 222 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 44, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 228 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 227 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 226 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 45, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 232 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 231 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 230 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 46, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 238 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 237 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 236 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 235 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 234 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 47, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 243 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 242 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 241 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 240 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 48, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 249 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 248 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 247 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 246 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 245 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 49, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 265 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 264 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x2_hen_tomishad3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 263 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 262 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 261 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 260 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 259 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 258 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 257 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 256 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 255 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 254 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 253 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 252 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What would you have me summon?" + } + } + }, + { + "__struct_id": 50, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 297 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 287 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 277 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 267 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What would you like to discuss about my defensive spells?", + "id": 88866 + } + } + }, + { + "__struct_id": 51, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 276 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 275 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 274 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 273 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 272 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 271 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 270 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 269 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 268 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 52, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 286 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 285 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 284 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 283 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 282 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 281 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 280 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 279 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 278 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 53, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 296 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 295 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 294 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 293 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 292 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 291 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 290 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 289 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 288 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 54, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 379 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 378 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 369 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 368 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 367 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 366 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 365 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 364 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 363 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 362 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 361 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 360 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 359 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 358 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 355 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 354 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 16, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 353 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 17, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 352 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 18, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 351 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 19, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 350 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 20, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 349 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 21, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 348 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 22, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 347 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 23, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 346 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 24, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 345 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 25, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 344 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 26, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 343 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 27, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 342 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 28, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 341 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 29, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 340 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 30, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 339 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 31, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 338 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 32, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 337 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 33, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 336 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 34, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 335 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 35, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 334 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 36, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 333 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 37, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 332 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 38, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 331 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 39, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 330 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 40, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 329 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 41, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 328 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 42, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 327 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 43, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 326 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 44, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 325 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 45, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 324 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 46, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 323 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 47, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 322 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 48, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 321 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 49, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 320 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 50, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 319 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 51, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 318 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 52, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 317 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 53, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 316 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 54, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 315 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 55, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 314 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 56, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 313 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 57, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 312 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 58, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 311 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 59, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 310 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 60, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 309 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 61, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 308 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 62, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 307 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 63, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 306 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 64, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 305 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 65, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 304 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 66, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 303 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 67, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 302 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 68, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 301 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 69, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 300 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 70, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 299 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 71, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 381 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What you want me to cast?", + "id": 87720 + } + } + }, + { + "__struct_id": 55, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 357 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 356 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 56, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 377 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 376 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 375 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 374 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 373 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 372 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 371 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 370 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 381 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Okay. Who shoulds I cast it on?", + "id": 87722 + } + } + }, + { + "__struct_id": 57, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 390 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 389 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 388 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 387 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 386 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 385 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 384 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 383 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 382 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 381 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And who should be the target of my healing?", + "id": 87722 + } + } + }, + { + "__struct_id": 58, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 394 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 393 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 392 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sure, what would you like me to do?" + } + } + }, + { + "__struct_id": 59, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_skillrank" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSkill" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nRank" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 400 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_skillrank" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSkill" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nRank" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 399 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 398 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Should I do something else?" + } + } + }, + { + "__struct_id": 60, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 414 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 413 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_a_magic_m" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nMode" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 412 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 411 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 410 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 409 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 408 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 407 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_cntrspell" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 406 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 405 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 404 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " How would you like me to use magic in combat?" + } + } + }, + { + "__struct_id": 61, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 421 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 420 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 419 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 418 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 417 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 416 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " When do you think I should heal our allies?", + "id": 55427 + } + } + }, + { + "__struct_id": 62, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "The creature looks at you strangely and resumes what it was doing before.", + "id": 53320 + } + } + } + ] + }, + "NumWords": { + "type": "dword", + "value": 2384 + }, + "PreventZoomIn": { + "type": "byte", + "value": 1 + }, + "ReplyList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_03" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_04" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 53319 + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_03" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_04" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 53318 + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58436 + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58437 + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_03" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_04" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58438 + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_11" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58439 + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Me needs you to do something for me.", + "id": 58440 + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I would like you to do something different for me.", + "id": 58441 + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Nevermind." + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets do something else." + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to summon something if you can." + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IX.", + "id": 88353 + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VIII.", + "id": 88354 + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VII.", + "id": 88355 + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VI.", + "id": 88356 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature V.", + "id": 88358 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IV.", + "id": 88358 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature III.", + "id": 88359 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature II.", + "id": 88360 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature I.", + "id": 88361 + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Create Undead.", + "id": 88425 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Animate Dead.", + "id": 88446 + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "Henchmen" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_hen_tomishad4" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Shadow." + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Familiar." + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Companion." + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about your defensive spells.", + "id": 89061 + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your defensive spells.", + "id": 89063 + } + } + }, + { + "__struct_id": 29, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 30, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 31, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 32, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 33, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 34, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 35, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 36, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 37, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 38, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your long duration defensive spells.", + "id": 89064 + } + } + }, + { + "__struct_id": 39, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 40, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 41, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 42, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 43, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 44, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 45, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 46, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 47, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 48, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your short duration defensive spells.", + "id": 89065 + } + } + }, + { + "__struct_id": 49, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 50, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 51, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 52, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 53, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 54, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 55, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 56, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 57, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 58, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast long duration spells after resting." + } + } + }, + { + "__struct_id": 59, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a spell.", + "id": 88348 + } + } + }, + { + "__struct_id": 60, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wounding Whispers.", + "id": 88350 + } + } + }, + { + "__struct_id": 61, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ultravision.", + "id": 88351 + } + } + }, + { + "__struct_id": 62, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "True Seeing.", + "id": 88352 + } + } + }, + { + "__struct_id": 63, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stoneskin.", + "id": 88362 + } + } + }, + { + "__struct_id": 64, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Resistance.", + "id": 88363 + } + } + }, + { + "__struct_id": 65, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Mantle.", + "id": 88364 + } + } + }, + { + "__struct_id": 66, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield of Faith.", + "id": 88365 + } + } + }, + { + "__struct_id": 67, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield.", + "id": 88366 + } + } + }, + { + "__struct_id": 68, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shadow Shield.", + "id": 88367 + } + } + }, + { + "__struct_id": 69, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "See Invisibility.", + "id": 88368 + } + } + }, + { + "__struct_id": 70, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sanctuary.", + "id": 88369 + } + } + }, + { + "__struct_id": 71, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Restoration.", + "id": 88370 + } + } + }, + { + "__struct_id": 72, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resistance.", + "id": 88371 + } + } + }, + { + "__struct_id": 73, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resist Elements.", + "id": 88372 + } + } + }, + { + "__struct_id": 74, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Paralysis.", + "id": 88373 + } + } + }, + { + "__struct_id": 75, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Fear.", + "id": 88374 + } + } + }, + { + "__struct_id": 76, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Disease.", + "id": 88375 + } + } + }, + { + "__struct_id": 77, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Curse.", + "id": 88376 + } + } + }, + { + "__struct_id": 78, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Blindness/Deafness.", + "id": 88377 + } + } + }, + { + "__struct_id": 79, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Regenerate.", + "id": 88378 + } + } + }, + { + "__struct_id": 80, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Spells.", + "id": 88379 + } + } + }, + { + "__struct_id": 81, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Evil." + } + } + }, + { + "__struct_id": 82, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Elements.", + "id": 88380 + } + } + }, + { + "__struct_id": 83, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Premonition.", + "id": 88381 + } + } + }, + { + "__struct_id": 84, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Prayer.", + "id": 88382 + } + } + }, + { + "__struct_id": 85, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Owl's Wisdom.", + "id": 88383 + } + } + }, + { + "__struct_id": 86, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Neutralize poison.", + "id": 88384 + } + } + }, + { + "__struct_id": 87, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Monstrous Regeneration.", + "id": 88385 + } + } + }, + { + "__struct_id": 88, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minor Globe of Invulnerability.", + "id": 88386 + } + } + }, + { + "__struct_id": 89, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mind Blank.", + "id": 88387 + } + } + }, + { + "__struct_id": 90, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mass Haste.", + "id": 88388 + } + } + }, + { + "__struct_id": 91, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Magical Vestment.", + "id": 88389 + } + } + }, + { + "__struct_id": 92, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mage Armor.", + "id": 88390 + } + } + }, + { + "__struct_id": 93, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Light.", + "id": 88391 + } + } + }, + { + "__struct_id": 94, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Spell Mantle.", + "id": 88392 + } + } + }, + { + "__struct_id": 95, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Restoration.", + "id": 88393 + } + } + }, + { + "__struct_id": 96, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Mind Blank", + "id": 88394 + } + } + }, + { + "__struct_id": 97, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Dispel.", + "id": 88395 + } + } + }, + { + "__struct_id": 98, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Knock.", + "id": 88396 + } + } + }, + { + "__struct_id": 99, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility Sphere.", + "id": 88397 + } + } + }, + { + "__struct_id": 100, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility", + "id": 88398 + } + } + }, + { + "__struct_id": 101, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Improved Invisibility.", + "id": 88399 + } + } + }, + { + "__struct_id": 102, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Haste.", + "id": 88400 + } + } + }, + { + "__struct_id": 103, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Stoneskin.", + "id": 88401 + } + } + }, + { + "__struct_id": 104, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Spell Mantle.", + "id": 88402 + } + } + }, + { + "__struct_id": 105, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Sanctuary.", + "id": 88403 + } + } + }, + { + "__struct_id": 106, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Restoration.", + "id": 88404 + } + } + }, + { + "__struct_id": 107, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Magic Weapon.", + "id": 88405 + } + } + }, + { + "__struct_id": 108, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Dispelling.", + "id": 88406 + } + } + }, + { + "__struct_id": 109, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Globe of Invulnerability.", + "id": 88407 + } + } + }, + { + "__struct_id": 110, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ghostly Visage.", + "id": 88408 + } + } + }, + { + "__struct_id": 111, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Freedom of Movement.", + "id": 88409 + } + } + }, + { + "__struct_id": 112, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fox's Cunning", + "id": 88410 + } + } + }, + { + "__struct_id": 113, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Find Traps.", + "id": 88411 + } + } + }, + { + "__struct_id": 114, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ethereal Visage.", + "id": 88412 + } + } + }, + { + "__struct_id": 115, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Entropic Shield.", + "id": 88413 + } + } + }, + { + "__struct_id": 116, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Energy Buffer.", + "id": 88414 + } + } + }, + { + "__struct_id": 117, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 118, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 119, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endure Elements.", + "id": 88417 + } + } + }, + { + "__struct_id": 120, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endurance.", + "id": 88418 + } + } + }, + { + "__struct_id": 121, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Elemental Shield.", + "id": 88419 + } + } + }, + { + "__struct_id": 122, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Eagle's Splendour.", + "id": 88420 + } + } + }, + { + "__struct_id": 123, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Power.", + "id": 88421 + } + } + }, + { + "__struct_id": 124, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dispel Magic.", + "id": 88422 + } + } + }, + { + "__struct_id": 125, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Ward.", + "id": 88423 + } + } + }, + { + "__struct_id": 126, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Armor.", + "id": 88424 + } + } + }, + { + "__struct_id": 127, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Continual Flame.", + "id": 88426 + } + } + }, + { + "__struct_id": 128, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Clarity.", + "id": 88427 + } + } + }, + { + "__struct_id": 129, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cat's Grace.", + "id": 88428 + } + } + }, + { + "__struct_id": 130, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bull's Strength.", + "id": 88429 + } + } + }, + { + "__struct_id": 131, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 132, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 133, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 134, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 135, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 136, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 137, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 138, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 139, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bless.", + "id": 88445 + } + } + }, + { + "__struct_id": 140, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Aid.", + "id": 88447 + } + } + }, + { + "__struct_id": 141, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a healing spell." + } + } + }, + { + "__struct_id": 142, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Heal up the whole party.", + "id": 88431 + } + } + }, + { + "__struct_id": 143, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 144, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 145, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 146, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "Target" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 147, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 148, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 149, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 150, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 151, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to discuss your tactics." + } + } + }, + { + "__struct_id": 152, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about something else." + } + } + }, + { + "__struct_id": 153, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets discuss how you deal with objects." + } + } + }, + { + "__struct_id": 154, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Bash" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your bashing tactics.", + "id": 96501 + } + } + }, + { + "__struct_id": 155, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Locks" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your lock picking tactics.", + "id": 96501 + } + } + }, + { + "__struct_id": 156, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Traps" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your trap tactics.", + "id": 96502 + } + } + }, + { + "__struct_id": 157, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Search" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your search tactics." + } + } + }, + { + "__struct_id": 158, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Stealth" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your stealth tactics." + } + } + }, + { + "__struct_id": 159, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's change how you use magic in combat." + } + } + }, + { + "__struct_id": 160, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you use magic items or not.", + "id": 96498 + } + } + }, + { + "__struct_id": 161, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Dispel" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your dispel tactics.", + "id": 96500 + } + } + }, + { + "__struct_id": 162, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stop countering the enemies spells.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 163, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 164, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BuffFirst" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change who you cast defensive spells on first.", + "id": 96500 + } + } + }, + { + "__struct_id": 165, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "OffensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast offensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 166, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast defensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 167, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "NoMagic" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change how you use magic spells in combat." + } + } + }, + { + "__struct_id": 168, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic more in combat." + } + } + }, + { + "__struct_id": 169, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic less in combat." + } + } + }, + { + "__struct_id": 170, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change when you decide to heal me.", + "id": 54985 + } + } + }, + { + "__struct_id": 171, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal out of combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 172, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health an one needs for you to heal out of combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 173, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal during combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 174, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health any one needs for you to heal during combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 175, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealSelf" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal yourself.", + "id": 54990 + } + } + }, + { + "__struct_id": 176, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealAllies" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal any allies.", + "id": 54989 + } + } + }, + { + "__struct_id": 177, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Pickup" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change if you retrieve items and gold." + } + } + }, + { + "__struct_id": 178, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowFarther" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow farther away from me.", + "id": 96508 + } + } + }, + { + "__struct_id": 179, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowCloser" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow closer to me.", + "id": 96508 + } + } + }, + { + "__struct_id": 180, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about your tactics in combat." + } + } + }, + { + "__struct_id": 181, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AttackTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you fight every opponent during combat." + } + } + }, + { + "__struct_id": 182, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AtkAssociates" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your tactics against familiars, companions, and summons." + } + } + }, + { + "__struct_id": 183, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Ranged" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your ranged combat tactics." + } + } + }, + { + "__struct_id": 184, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!" + } + } + }, + { + "__struct_id": 185, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Taunt" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to taunt the enemy!" + } + } + }, + { + "__struct_id": 186, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "PeaceTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Don't engage in combat." + } + } + }, + { + "__struct_id": 187, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RangedTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use agressive ranged tactics, stay out of melee.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 188, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "That will be all for now." + } + } + }, + { + "__struct_id": 189, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to discuss how we can work together." + } + } + }, + { + "__struct_id": 190, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about something else." + } + } + }, + { + "__struct_id": 191, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_get_convo" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about something completely different." + } + } + }, + { + "__struct_id": 192, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 37 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "We should part ways." + } + } + }, + { + "__struct_id": 193, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I like having you around." + } + } + }, + { + "__struct_id": 194, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_fire_henchmen" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes I'm sure, Perhapse we'll meet again." + } + } + }, + { + "__struct_id": 195, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 38 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you use a special ability?", + "id": 96382 + } + } + }, + { + "__struct_id": 196, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_d2_dshield" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Shield.", + "id": 96383 + } + } + }, + { + "__struct_id": 197, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_d2_dmight" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Might.", + "id": 96384 + } + } + }, + { + "__struct_id": 198, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 39 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lay on Hands.", + "id": 96385 + } + } + }, + { + "__struct_id": 199, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I've changed my mind.", + "id": 88430 + } + } + }, + { + "__struct_id": 200, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 201, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 202, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 203, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 204, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 205, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 206, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 207, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 208, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "257" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_use_feat" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your bard song.", + "id": 88342 + } + } + }, + { + "__struct_id": 209, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 40 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your construction shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 210, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "740" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Iron Golem" + } + } + }, + { + "__struct_id": 211, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "739" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Demon Flesh Golem" + } + } + }, + { + "__struct_id": 212, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "738" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stone Golem" + } + } + }, + { + "__struct_id": 213, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 41 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your outsider shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 214, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "735" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Slaad" + } + } + }, + { + "__struct_id": 215, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "734" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Rakshasa" + } + } + }, + { + "__struct_id": 216, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "733" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Azer" + } + } + }, + { + "__struct_id": 217, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 42 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your humanoid shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 218, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "684" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Kobold Assasin" + } + } + }, + { + "__struct_id": 219, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "683" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lizard folk" + } + } + }, + { + "__struct_id": 220, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "682" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Drow" + } + } + }, + { + "__struct_id": 221, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 43 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape V.", + "id": 88342 + } + } + }, + { + "__struct_id": 222, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "691" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mindflayer" + } + } + }, + { + "__struct_id": 223, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "679" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Medusa" + } + } + }, + { + "__struct_id": 224, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "694" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dire Tiger" + } + } + }, + { + "__struct_id": 225, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 44 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape III.", + "id": 88342 + } + } + }, + { + "__struct_id": 226, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "674" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Manticore" + } + } + }, + { + "__struct_id": 227, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "673" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Drider" + } + } + }, + { + "__struct_id": 228, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "670" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Basilisk" + } + } + }, + { + "__struct_id": 229, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 45 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape II.", + "id": 88342 + } + } + }, + { + "__struct_id": 230, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "680" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minotaur" + } + } + }, + { + "__struct_id": 231, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "678" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Gargoyle" + } + } + }, + { + "__struct_id": 232, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "672" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Harpy" + } + } + }, + { + "__struct_id": 233, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 46 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape I.", + "id": 88342 + } + } + }, + { + "__struct_id": 234, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "662" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Green Wyrmling" + } + } + }, + { + "__struct_id": 235, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "661" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "White Wyrmling" + } + } + }, + { + "__struct_id": 236, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "660" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Black Wyrmling" + } + } + }, + { + "__struct_id": 237, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "659" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Blue Wyrmling" + } + } + }, + { + "__struct_id": 238, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "658" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Red Wyrmling" + } + } + }, + { + "__struct_id": 239, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 47 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your elemental shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 240, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "398" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Water" + } + } + }, + { + "__struct_id": 241, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "397" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fire" + } + } + }, + { + "__struct_id": 242, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "399" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Earth" + } + } + }, + { + "__struct_id": 243, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "400" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Air" + } + } + }, + { + "__struct_id": 244, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 48 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your wild shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 245, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "405" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Badger" + } + } + }, + { + "__struct_id": 246, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "404" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Boar" + } + } + }, + { + "__struct_id": 247, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "403" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wolf" + } + } + }, + { + "__struct_id": 248, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "402" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Panther" + } + } + }, + { + "__struct_id": 249, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "401" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bear" + } + } + }, + { + "__struct_id": 250, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nEffectType" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_remove_effect" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Transform back into your natural form.", + "id": 96384 + } + } + }, + { + "__struct_id": 251, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 49 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to summon something if you can." + } + } + }, + { + "__struct_id": 252, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IX.", + "id": 88353 + } + } + }, + { + "__struct_id": 253, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VIII.", + "id": 88354 + } + } + }, + { + "__struct_id": 254, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VII.", + "id": 88355 + } + } + }, + { + "__struct_id": 255, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VI.", + "id": 88356 + } + } + }, + { + "__struct_id": 256, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature V.", + "id": 88358 + } + } + }, + { + "__struct_id": 257, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IV.", + "id": 88358 + } + } + }, + { + "__struct_id": 258, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature III.", + "id": 88359 + } + } + }, + { + "__struct_id": 259, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature II.", + "id": 88360 + } + } + }, + { + "__struct_id": 260, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature I.", + "id": 88361 + } + } + }, + { + "__struct_id": 261, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Create Undead.", + "id": 88425 + } + } + }, + { + "__struct_id": 262, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Animate Dead.", + "id": 88446 + } + } + }, + { + "__struct_id": 263, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_hen_tomishad4" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Shadow." + } + } + }, + { + "__struct_id": 264, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Familiar." + } + } + }, + { + "__struct_id": 265, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Companion." + } + } + }, + { + "__struct_id": 266, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 50 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about your defensive spells.", + "id": 89061 + } + } + }, + { + "__struct_id": 267, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 51 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your defensive spells.", + "id": 89063 + } + } + }, + { + "__struct_id": 268, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 269, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 270, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 271, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 272, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 273, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 274, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 275, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 276, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 277, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 52 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your long duration defensive spells.", + "id": 89064 + } + } + }, + { + "__struct_id": 278, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 279, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 280, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 281, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 282, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 283, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 284, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 285, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 286, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 287, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 53 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your short duration defensive spells.", + "id": 89065 + } + } + }, + { + "__struct_id": 288, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 289, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 290, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 291, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 292, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 293, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 294, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 295, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 296, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 297, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 50 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast long duration spells after resting." + } + } + }, + { + "__struct_id": 298, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 54 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a spell.", + "id": 88348 + } + } + }, + { + "__struct_id": 299, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wounding Whispers.", + "id": 88350 + } + } + }, + { + "__struct_id": 300, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ultravision.", + "id": 88351 + } + } + }, + { + "__struct_id": 301, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "True Seeing.", + "id": 88352 + } + } + }, + { + "__struct_id": 302, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stoneskin.", + "id": 88362 + } + } + }, + { + "__struct_id": 303, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Resistance.", + "id": 88363 + } + } + }, + { + "__struct_id": 304, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Mantle.", + "id": 88364 + } + } + }, + { + "__struct_id": 305, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield of Faith.", + "id": 88365 + } + } + }, + { + "__struct_id": 306, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield.", + "id": 88366 + } + } + }, + { + "__struct_id": 307, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shadow Shield.", + "id": 88367 + } + } + }, + { + "__struct_id": 308, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "See Invisibility.", + "id": 88368 + } + } + }, + { + "__struct_id": 309, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sanctuary.", + "id": 88369 + } + } + }, + { + "__struct_id": 310, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Restoration.", + "id": 88370 + } + } + }, + { + "__struct_id": 311, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resistance.", + "id": 88371 + } + } + }, + { + "__struct_id": 312, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resist Elements.", + "id": 88372 + } + } + }, + { + "__struct_id": 313, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Paralysis.", + "id": 88373 + } + } + }, + { + "__struct_id": 314, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Fear.", + "id": 88374 + } + } + }, + { + "__struct_id": 315, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Disease.", + "id": 88375 + } + } + }, + { + "__struct_id": 316, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Curse.", + "id": 88376 + } + } + }, + { + "__struct_id": 317, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Blindness/Deafness.", + "id": 88377 + } + } + }, + { + "__struct_id": 318, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Regenerate.", + "id": 88378 + } + } + }, + { + "__struct_id": 319, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Spells.", + "id": 88379 + } + } + }, + { + "__struct_id": 320, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Evil." + } + } + }, + { + "__struct_id": 321, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Elements.", + "id": 88380 + } + } + }, + { + "__struct_id": 322, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Premonition.", + "id": 88381 + } + } + }, + { + "__struct_id": 323, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Prayer.", + "id": 88382 + } + } + }, + { + "__struct_id": 324, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Owl's Wisdom.", + "id": 88383 + } + } + }, + { + "__struct_id": 325, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Neutralize poison.", + "id": 88384 + } + } + }, + { + "__struct_id": 326, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Monstrous Regeneration.", + "id": 88385 + } + } + }, + { + "__struct_id": 327, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minor Globe of Invulnerability.", + "id": 88386 + } + } + }, + { + "__struct_id": 328, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mind Blank.", + "id": 88387 + } + } + }, + { + "__struct_id": 329, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mass Haste.", + "id": 88388 + } + } + }, + { + "__struct_id": 330, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Magical Vestment.", + "id": 88389 + } + } + }, + { + "__struct_id": 331, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mage Armor.", + "id": 88390 + } + } + }, + { + "__struct_id": 332, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Light.", + "id": 88391 + } + } + }, + { + "__struct_id": 333, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Spell Mantle.", + "id": 88392 + } + } + }, + { + "__struct_id": 334, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Restoration.", + "id": 88393 + } + } + }, + { + "__struct_id": 335, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Mind Blank", + "id": 88394 + } + } + }, + { + "__struct_id": 336, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Dispel.", + "id": 88395 + } + } + }, + { + "__struct_id": 337, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Knock.", + "id": 88396 + } + } + }, + { + "__struct_id": 338, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility Sphere.", + "id": 88397 + } + } + }, + { + "__struct_id": 339, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility", + "id": 88398 + } + } + }, + { + "__struct_id": 340, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Improved Invisibility.", + "id": 88399 + } + } + }, + { + "__struct_id": 341, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Haste.", + "id": 88400 + } + } + }, + { + "__struct_id": 342, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Stoneskin.", + "id": 88401 + } + } + }, + { + "__struct_id": 343, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Spell Mantle.", + "id": 88402 + } + } + }, + { + "__struct_id": 344, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Sanctuary.", + "id": 88403 + } + } + }, + { + "__struct_id": 345, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Restoration.", + "id": 88404 + } + } + }, + { + "__struct_id": 346, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Magic Weapon.", + "id": 88405 + } + } + }, + { + "__struct_id": 347, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Dispelling.", + "id": 88406 + } + } + }, + { + "__struct_id": 348, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Globe of Invulnerability.", + "id": 88407 + } + } + }, + { + "__struct_id": 349, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ghostly Visage.", + "id": 88408 + } + } + }, + { + "__struct_id": 350, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Freedom of Movement.", + "id": 88409 + } + } + }, + { + "__struct_id": 351, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fox's Cunning", + "id": 88410 + } + } + }, + { + "__struct_id": 352, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Find Traps.", + "id": 88411 + } + } + }, + { + "__struct_id": 353, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ethereal Visage.", + "id": 88412 + } + } + }, + { + "__struct_id": 354, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Entropic Shield.", + "id": 88413 + } + } + }, + { + "__struct_id": 355, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Energy Buffer.", + "id": 88414 + } + } + }, + { + "__struct_id": 356, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 357, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 358, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endure Elements.", + "id": 88417 + } + } + }, + { + "__struct_id": 359, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endurance.", + "id": 88418 + } + } + }, + { + "__struct_id": 360, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Elemental Shield.", + "id": 88419 + } + } + }, + { + "__struct_id": 361, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Eagle's Splendour.", + "id": 88420 + } + } + }, + { + "__struct_id": 362, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Power.", + "id": 88421 + } + } + }, + { + "__struct_id": 363, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dispel Magic.", + "id": 88422 + } + } + }, + { + "__struct_id": 364, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Ward.", + "id": 88423 + } + } + }, + { + "__struct_id": 365, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Armor.", + "id": 88424 + } + } + }, + { + "__struct_id": 366, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Continual Flame.", + "id": 88426 + } + } + }, + { + "__struct_id": 367, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Clarity.", + "id": 88427 + } + } + }, + { + "__struct_id": 368, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cat's Grace.", + "id": 88428 + } + } + }, + { + "__struct_id": 369, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bull's Strength.", + "id": 88429 + } + } + }, + { + "__struct_id": 370, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 371, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 372, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 373, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 374, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 375, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 376, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 377, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 378, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bless.", + "id": 88445 + } + } + }, + { + "__struct_id": 379, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Aid.", + "id": 88447 + } + } + }, + { + "__struct_id": 380, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 57 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a healing spell." + } + } + }, + { + "__struct_id": 381, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I've changed my mind.", + "id": 88430 + } + } + }, + { + "__struct_id": 382, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Heal up the whole party.", + "id": 88431 + } + } + }, + { + "__struct_id": 383, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 384, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 385, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 386, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 387, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 388, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 389, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 390, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 391, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 58 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can we talk about your items?" + } + } + }, + { + "__struct_id": 392, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "GiveMagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Give me all the magical items in your inventory.", + "id": 96514 + } + } + }, + { + "__struct_id": 393, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "GiveUnIdentifiedItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Give me all your unidentified items.", + "id": 96514 + } + } + }, + { + "__struct_id": 394, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x0_d1_hen_inven" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to adjust your equipment.", + "id": 96514 + } + } + }, + { + "__struct_id": 395, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x1_hen_identify" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you identify our equipment?", + "id": 88341 + } + } + }, + { + "__struct_id": 396, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Scout" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I would like you to scout the area." + } + } + }, + { + "__struct_id": 397, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets discuss how you deal with objects." + } + } + }, + { + "__struct_id": 398, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Bash" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your bashing tactics.", + "id": 96507 + } + } + }, + { + "__struct_id": 399, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Locks" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your lock picking tactics.", + "id": 96507 + } + } + }, + { + "__struct_id": 400, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Traps" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your trap tactics.", + "id": 96502 + } + } + }, + { + "__struct_id": 401, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Search" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your search tactics.", + "id": 96505 + } + } + }, + { + "__struct_id": 402, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Stealth" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your stealth tactics.", + "id": 96505 + } + } + }, + { + "__struct_id": 403, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's change how you use magic in combat." + } + } + }, + { + "__struct_id": 404, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you use magic items or not.", + "id": 96498 + } + } + }, + { + "__struct_id": 405, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Dispel" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your dispel tactics.", + "id": 96500 + } + } + }, + { + "__struct_id": 406, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stop countering the enemies spells.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 407, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Counter the enemy spells!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 408, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BuffFirst" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change who you cast defensive spells on first.", + "id": 96500 + } + } + }, + { + "__struct_id": 409, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "OffensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Only cast offensive spells for now.", + "id": 96498 + } + } + }, + { + "__struct_id": 410, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Only cast defensive spells for now.", + "id": 96498 + } + } + }, + { + "__struct_id": 411, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "NoMagic" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Don't use any magic until I say otherwise.", + "id": 96497 + } + } + }, + { + "__struct_id": 412, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "UseMagic" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use any magic spells you have.", + "id": 96498 + } + } + }, + { + "__struct_id": 413, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic more in combat." + } + } + }, + { + "__struct_id": 414, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic less in combat." + } + } + }, + { + "__struct_id": 415, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change when you should heal.", + "id": 54985 + } + } + }, + { + "__struct_id": 416, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal out of combat.", + "id": 54990 + } + } + }, + { + "__struct_id": 417, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health an one needs for you to heal out of combat.", + "id": 54989 + } + } + }, + { + "__struct_id": 418, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal during combat.", + "id": 54990 + } + } + }, + { + "__struct_id": 419, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health any one needs for you to heal during combat.", + "id": 54989 + } + } + }, + { + "__struct_id": 420, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealSelf" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal yourself.", + "id": 54989 + } + } + }, + { + "__struct_id": 421, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealAllies" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal any allies.", + "id": 54989 + } + } + }, + { + "__struct_id": 422, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Pickup" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change if you pickup items and gold." + } + } + }, + { + "__struct_id": 423, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowFarther" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow farther away from me.", + "id": 96510 + } + } + }, + { + "__struct_id": 424, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowCloser" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow closer to me.", + "id": 96511 + } + } + }, + { + "__struct_id": 425, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about your tactics in combat." + } + } + }, + { + "__struct_id": 426, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AttackTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you fight every opponent during combat.", + "2": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"", + "3": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"" + } + } + }, + { + "__struct_id": 427, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AtkAssociates" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your tactics against familiars, companions, and summons.", + "id": 62531 + } + } + }, + { + "__struct_id": 428, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Ranged" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your ranged combat tactics.", + "id": 62531 + } + } + }, + { + "__struct_id": 429, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 430, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Taunt" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to taunt the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 431, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "PeaceTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Don't engage in combat.", + "2": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"", + "3": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"" + } + } + }, + { + "__struct_id": 432, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AmbushTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use ambush tactics, hide and then strike.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 433, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use defensive tactics to protect yourself.", + "id": 62532 + } + } + }, + { + "__struct_id": 434, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your best judgement in combat.", + "id": 62531 + } + } + }, + { + "__struct_id": 435, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AmbushTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use ambush tactics, hide and then strike.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 436, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use defensive tactics protect yourself.", + "id": 62532 + } + } + }, + { + "__struct_id": 437, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use basic combat tactics.", + "id": 62531 + } + } + }, + { + "__struct_id": 438, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x1_hen_identify" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you identify my equipment?", + "id": 88341 + } + } + }, + { + "__struct_id": 439, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Scout" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I would like you to scout the area." + } + } + } + ] + }, + "StartingList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_ac_st_01" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 62 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + } + } + ] + } +} diff --git a/src/module/dlg/nw_g_fam.dlg.json b/src/module/dlg/nw_g_fam.dlg.json new file mode 100644 index 0000000..5be0aae --- /dev/null +++ b/src/module/dlg/nw_g_fam.dlg.json @@ -0,0 +1,23412 @@ +{ + "__data_type": "DLG ", + "DelayEntry": { + "type": "dword", + "value": 0 + }, + "DelayReply": { + "type": "dword", + "value": 0 + }, + "EndConverAbort": { + "type": "resref", + "value": "" + }, + "EndConversation": { + "type": "resref", + "value": "" + }, + "EntryList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 193 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_scout" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 192 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_identify" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 191 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What do you require of me ?", + "id": 58490 + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58491 + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58492 + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58493 + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58494 + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58495 + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58496 + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58497 + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58498 + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58499 + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58500 + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58501 + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st-11" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58502 + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st-11" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58503 + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58506 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58507 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58508 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_10" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58509 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "nw_ch_fm_st_12" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58504 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58505 + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 141 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + }, + { + "__struct_id": 7, + "Key": { + "type": "cexostring", + "value": "nClass8" + }, + "Value": { + "type": "cexostring", + "value": "46" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What would you like me to do, my ?", + "id": 58510 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x2_hen_tomishad3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What would you have me summon?" + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 58 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 48 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 38 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What would you like to discuss about my defensive spells?", + "id": 88866 + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 37 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 47 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 46 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 45 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 44 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 43 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 42 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 41 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 40 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 39 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 57 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 54 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 53 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 52 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 51 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 50 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "x2_d1_targetall" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 49 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 140 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 139 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 130 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 129 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 128 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 127 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 126 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 125 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 124 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 123 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 122 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 121 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 120 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 119 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 116 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 115 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 16, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 114 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 17, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 113 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 18, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 112 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 19, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 111 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 20, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 110 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 21, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 109 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 22, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 108 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 23, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 107 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 24, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 106 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 25, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 105 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 26, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 104 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 27, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 103 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 28, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 102 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 29, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 101 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 30, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 100 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 31, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 99 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 32, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 98 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 33, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 97 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 34, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 96 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 35, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 95 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 36, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 94 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 37, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 93 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 38, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 92 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 39, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 91 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 40, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 90 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 41, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 89 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 42, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 88 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 43, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 87 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 44, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 86 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 45, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 85 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 46, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 84 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 47, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 83 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 48, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 82 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 49, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 81 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 50, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 80 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 51, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 79 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 52, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 78 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 53, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 77 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 54, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 76 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 55, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 75 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 56, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 74 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 57, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 73 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 58, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 72 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 59, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 71 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 60, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 70 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 61, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 69 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 62, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 68 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 63, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 67 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 64, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 66 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 65, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 65 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 66, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 64 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 67, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 63 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 68, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 62 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 69, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 70, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 71, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What you want me to cast?", + "id": 87720 + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 118 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 117 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 29, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 138 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 137 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 136 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 135 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 134 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 133 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 132 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 131 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Okay. Who shoulds I cast it on?", + "id": 87722 + } + } + }, + { + "__struct_id": 30, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 150 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 149 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 148 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 147 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 146 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 145 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 144 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 143 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 142 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And who should be the target of my healing?", + "id": 87722 + } + } + }, + { + "__struct_id": 31, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 180 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 179 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 178 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_pickuploot" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 177 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 170 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 159 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 158 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 157 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 153 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What tactic would you like me to change, ?" + } + } + }, + { + "__struct_id": 32, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 156 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 155 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 154 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " My benignant , how can I change my actions?\"" + } + } + }, + { + "__struct_id": 33, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 169 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 168 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 167 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 166 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 165 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 164 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 163 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_cntrspell" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 162 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 161 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 160 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Almighty , how shall I use magic in combat?" + } + } + }, + { + "__struct_id": 34, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 176 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 175 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 174 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 173 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 172 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 171 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Let me know when to heal, all knowning .", + "id": 55427 + } + } + }, + { + "__struct_id": 35, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_defensive" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ambusher" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ranged" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 187 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_peaceful" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 186 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_taunt" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 185 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 184 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 183 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 182 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 181 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "nw_d2_intn" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "nw_d2_intl" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Oh powerful ! How would you like to change my tactics?" + } + } + }, + { + "__struct_id": 36, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 194 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 63861 + } + } + }, + { + "__struct_id": 37, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 195 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 63862 + } + } + }, + { + "__struct_id": 38, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 63863 + } + } + }, + { + "__struct_id": 39, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58520 + } + } + } + ] + }, + "NumWords": { + "type": "dword", + "value": 1302 + }, + "PreventZoomIn": { + "type": "byte", + "value": 1 + }, + "ReplyList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58472 + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58473 + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58474 + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "nw_s0_heal" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58475 + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_04" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_09" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58477 + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_11" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58476 + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58478 + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change how you are doing things.", + "id": 58479 + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58480 + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 58481 + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to summon something if you can." + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IX.", + "id": 88353 + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VIII.", + "id": 88354 + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VII.", + "id": 88355 + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VI.", + "id": 88356 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature V.", + "id": 88358 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IV.", + "id": 88358 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature III.", + "id": 88359 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature II.", + "id": 88360 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature I.", + "id": 88361 + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Create Undead.", + "id": 88425 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Animate Dead.", + "id": 88446 + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_hen_tomishad4" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Shadow." + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Familiar." + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Companion." + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about your defensive spells.", + "id": 89061 + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your defensive spells.", + "id": 89063 + } + } + }, + { + "__struct_id": 29, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 30, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 31, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 32, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 33, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 34, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 35, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 36, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 37, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 38, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your long duration defensive spells.", + "id": 89064 + } + } + }, + { + "__struct_id": 39, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 40, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 41, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 42, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 43, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 44, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 45, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 46, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 47, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 48, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your short duration defensive spells.", + "id": 89065 + } + } + }, + { + "__struct_id": 49, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 50, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 51, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 52, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 53, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 54, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 55, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 56, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 57, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 58, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast long duration spells after resting." + } + } + }, + { + "__struct_id": 59, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a spell.", + "id": 88348 + } + } + }, + { + "__struct_id": 60, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wounding Whispers.", + "id": 88350 + } + } + }, + { + "__struct_id": 61, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ultravision.", + "id": 88351 + } + } + }, + { + "__struct_id": 62, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "True Seeing.", + "id": 88352 + } + } + }, + { + "__struct_id": 63, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stoneskin.", + "id": 88362 + } + } + }, + { + "__struct_id": 64, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Resistance.", + "id": 88363 + } + } + }, + { + "__struct_id": 65, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Mantle.", + "id": 88364 + } + } + }, + { + "__struct_id": 66, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield of Faith.", + "id": 88365 + } + } + }, + { + "__struct_id": 67, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield.", + "id": 88366 + } + } + }, + { + "__struct_id": 68, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shadow Shield.", + "id": 88367 + } + } + }, + { + "__struct_id": 69, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "See Invisibility.", + "id": 88368 + } + } + }, + { + "__struct_id": 70, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sanctuary.", + "id": 88369 + } + } + }, + { + "__struct_id": 71, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Restoration.", + "id": 88370 + } + } + }, + { + "__struct_id": 72, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resistance.", + "id": 88371 + } + } + }, + { + "__struct_id": 73, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resist Elements.", + "id": 88372 + } + } + }, + { + "__struct_id": 74, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Paralysis.", + "id": 88373 + } + } + }, + { + "__struct_id": 75, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Fear.", + "id": 88374 + } + } + }, + { + "__struct_id": 76, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Disease.", + "id": 88375 + } + } + }, + { + "__struct_id": 77, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Curse.", + "id": 88376 + } + } + }, + { + "__struct_id": 78, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Blindness/Deafness.", + "id": 88377 + } + } + }, + { + "__struct_id": 79, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Regenerate.", + "id": 88378 + } + } + }, + { + "__struct_id": 80, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Spells.", + "id": 88379 + } + } + }, + { + "__struct_id": 81, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Evil." + } + } + }, + { + "__struct_id": 82, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Elements.", + "id": 88380 + } + } + }, + { + "__struct_id": 83, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Premonition.", + "id": 88381 + } + } + }, + { + "__struct_id": 84, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Prayer.", + "id": 88382 + } + } + }, + { + "__struct_id": 85, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Owl's Wisdom.", + "id": 88383 + } + } + }, + { + "__struct_id": 86, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Neutralize poison.", + "id": 88384 + } + } + }, + { + "__struct_id": 87, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Monstrous Regeneration.", + "id": 88385 + } + } + }, + { + "__struct_id": 88, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minor Globe of Invulnerability.", + "id": 88386 + } + } + }, + { + "__struct_id": 89, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mind Blank.", + "id": 88387 + } + } + }, + { + "__struct_id": 90, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mass Haste.", + "id": 88388 + } + } + }, + { + "__struct_id": 91, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Magical Vestment.", + "id": 88389 + } + } + }, + { + "__struct_id": 92, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mage Armor.", + "id": 88390 + } + } + }, + { + "__struct_id": 93, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Light.", + "id": 88391 + } + } + }, + { + "__struct_id": 94, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Spell Mantle.", + "id": 88392 + } + } + }, + { + "__struct_id": 95, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Restoration.", + "id": 88393 + } + } + }, + { + "__struct_id": 96, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Mind Blank", + "id": 88394 + } + } + }, + { + "__struct_id": 97, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Dispel.", + "id": 88395 + } + } + }, + { + "__struct_id": 98, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Knock.", + "id": 88396 + } + } + }, + { + "__struct_id": 99, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility Sphere.", + "id": 88397 + } + } + }, + { + "__struct_id": 100, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility", + "id": 88398 + } + } + }, + { + "__struct_id": 101, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Improved Invisibility.", + "id": 88399 + } + } + }, + { + "__struct_id": 102, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Haste.", + "id": 88400 + } + } + }, + { + "__struct_id": 103, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Stoneskin.", + "id": 88401 + } + } + }, + { + "__struct_id": 104, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Spell Mantle.", + "id": 88402 + } + } + }, + { + "__struct_id": 105, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Sanctuary.", + "id": 88403 + } + } + }, + { + "__struct_id": 106, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Restoration.", + "id": 88404 + } + } + }, + { + "__struct_id": 107, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Magic Weapon.", + "id": 88405 + } + } + }, + { + "__struct_id": 108, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Dispelling.", + "id": 88406 + } + } + }, + { + "__struct_id": 109, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Globe of Invulnerability.", + "id": 88407 + } + } + }, + { + "__struct_id": 110, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ghostly Visage.", + "id": 88408 + } + } + }, + { + "__struct_id": 111, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Freedom of Movement.", + "id": 88409 + } + } + }, + { + "__struct_id": 112, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fox's Cunning", + "id": 88410 + } + } + }, + { + "__struct_id": 113, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Find Traps.", + "id": 88411 + } + } + }, + { + "__struct_id": 114, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ethereal Visage.", + "id": 88412 + } + } + }, + { + "__struct_id": 115, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Entropic Shield.", + "id": 88413 + } + } + }, + { + "__struct_id": 116, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Energy Buffer.", + "id": 88414 + } + } + }, + { + "__struct_id": 117, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 118, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 119, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endure Elements.", + "id": 88417 + } + } + }, + { + "__struct_id": 120, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endurance.", + "id": 88418 + } + } + }, + { + "__struct_id": 121, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Elemental Shield.", + "id": 88419 + } + } + }, + { + "__struct_id": 122, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Eagle's Splendour.", + "id": 88420 + } + } + }, + { + "__struct_id": 123, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Power.", + "id": 88421 + } + } + }, + { + "__struct_id": 124, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dispel Magic.", + "id": 88422 + } + } + }, + { + "__struct_id": 125, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Ward.", + "id": 88423 + } + } + }, + { + "__struct_id": 126, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Armor.", + "id": 88424 + } + } + }, + { + "__struct_id": 127, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Continual Flame.", + "id": 88426 + } + } + }, + { + "__struct_id": 128, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Clarity.", + "id": 88427 + } + } + }, + { + "__struct_id": 129, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cat's Grace.", + "id": 88428 + } + } + }, + { + "__struct_id": 130, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bull's Strength.", + "id": 88429 + } + } + }, + { + "__struct_id": 131, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 132, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 133, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 134, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 135, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 136, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 137, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 138, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 139, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bless.", + "id": 88445 + } + } + }, + { + "__struct_id": 140, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Aid.", + "id": 88447 + } + } + }, + { + "__struct_id": 141, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a healing spell." + } + } + }, + { + "__struct_id": 142, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Heal up the whole party.", + "id": 88431 + } + } + }, + { + "__struct_id": 143, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 144, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 145, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 146, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 147, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 148, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 149, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 150, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 151, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to discuss your tactics." + } + } + }, + { + "__struct_id": 152, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about something else." + } + } + }, + { + "__struct_id": 153, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Object" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets discuss how you deal with objects." + } + } + }, + { + "__struct_id": 154, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Bash" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Object" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your bashing tactics.", + "id": 96501 + } + } + }, + { + "__struct_id": 155, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Locks" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Object" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your lock picking tactics.", + "id": 96501 + } + } + }, + { + "__struct_id": 156, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Traps" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Object" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your trap tactics.", + "id": 96502 + } + } + }, + { + "__struct_id": 157, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Search" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your search tactics." + } + } + }, + { + "__struct_id": 158, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Stealth" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your stealth tactics." + } + } + }, + { + "__struct_id": 159, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's change how you use magic in combat." + } + } + }, + { + "__struct_id": 160, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you use magic items or not.", + "id": 96498 + } + } + }, + { + "__struct_id": 161, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Dispel" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your dispel tactics.", + "id": 96500 + } + } + }, + { + "__struct_id": 162, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stop countering the enemies spells.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 163, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 164, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BuffFirst" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change who you cast defensive spells on first.", + "id": 96500 + } + } + }, + { + "__struct_id": 165, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "OffensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast offensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 166, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast defensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 167, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "NoMagic" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change how you use magic spells in combat.", + "id": 96498 + } + } + }, + { + "__struct_id": 168, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic more in combat." + } + } + }, + { + "__struct_id": 169, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic less in combat." + } + } + }, + { + "__struct_id": 170, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change when you decide to heal me.", + "id": 54985 + } + } + }, + { + "__struct_id": 171, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal out of combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 172, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health an one needs for you to heal out of combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 173, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal during combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 174, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health any one needs for you to heal during combat.", + "id": 54991 + } + } + }, + { + "__struct_id": 175, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealSelf" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal yourself.", + "id": 54991 + } + } + }, + { + "__struct_id": 176, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealAllies" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal any allies.", + "id": 54991 + } + } + }, + { + "__struct_id": 177, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Pickup" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change if you retrieve items and gold." + } + } + }, + { + "__struct_id": 178, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowFarther" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow farther away from me.", + "id": 96508 + } + } + }, + { + "__struct_id": 179, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowCloser" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow closer to me.", + "id": 96508 + } + } + }, + { + "__struct_id": 180, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about your tactics in combat." + } + } + }, + { + "__struct_id": 181, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AttackTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you fight every opponent during combat." + } + } + }, + { + "__struct_id": 182, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AtkAssociates" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your tactics against familiars, companions, and summons.", + "id": 62531 + } + } + }, + { + "__struct_id": 183, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Ranged" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your ranged combat tactics.", + "id": 62531 + } + } + }, + { + "__struct_id": 184, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 185, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Taunt" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to taunt the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 186, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "PeaceTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Don't engage in combat.", + "2": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"", + "3": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"" + } + } + }, + { + "__struct_id": 187, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RangedTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use agressive ranged tactics, stay out of melee.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 188, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AmbushTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use ambush tactics, hide and then strike.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 189, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use defensive tactics protect yourself.", + "id": 62532 + } + } + }, + { + "__struct_id": 190, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use basic combat tactics.", + "id": 62531 + } + } + }, + { + "__struct_id": 191, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x1_hen_identify" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you identify my equipment?", + "id": 88341 + } + } + }, + { + "__struct_id": 192, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Scout" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I would like you to scout the area." + } + } + }, + { + "__struct_id": 193, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "id": 63860 + } + } + }, + { + "__struct_id": 194, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 37 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": {} + } + }, + { + "__struct_id": 195, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 38 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": {} + } + } + ] + }, + "StartingList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "nw_ch_fm_st_01" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 39 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + } + } + ] + } +} diff --git a/src/module/dlg/oc_ai_henchmen.dlg.json b/src/module/dlg/oc_ai_henchmen.dlg.json new file mode 100644 index 0000000..d9ca1b6 --- /dev/null +++ b/src/module/dlg/oc_ai_henchmen.dlg.json @@ -0,0 +1,27180 @@ +{ + "__data_type": "DLG ", + "DelayEntry": { + "type": "dword", + "value": 0 + }, + "DelayReply": { + "type": "dword", + "value": 0 + }, + "EndConverAbort": { + "type": "resref", + "value": "" + }, + "EndConversation": { + "type": "resref", + "value": "" + }, + "EntryList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 38 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_scout" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 247 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_identify" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 246 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_open_inven" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 242 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 191 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 109 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 77 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_class" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nClass1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nClass2" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 2, + "Key": { + "type": "cexostring", + "value": "nClass3" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 3, + "Key": { + "type": "cexostring", + "value": "nClass4" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 4, + "Key": { + "type": "cexostring", + "value": "nClass5" + }, + "Value": { + "type": "cexostring", + "value": "10" + } + }, + { + "__struct_id": 5, + "Key": { + "type": "cexostring", + "value": "nClass6" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + }, + { + "__struct_id": 6, + "Key": { + "type": "cexostring", + "value": "nClass7" + }, + "Value": { + "type": "cexostring", + "value": "48" + } + }, + { + "__struct_id": 7, + "Key": { + "type": "cexostring", + "value": "nClass8" + }, + "Value": { + "type": "cexostring", + "value": "46" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 62 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_hen_leave" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_convo" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What would you like to discuss?" + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Are you sure you want to do that?" + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_polymorph" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 61 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "305" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 55 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "304" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 50 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "898" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 44 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "900" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 40 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "901" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 36 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "903" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 32 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "902" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 28 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "1060" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "1061" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "257" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "sTarget" + }, + "Value": { + "type": "cexostring", + "value": "OBJECT_SELF" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "x2_d2_haslayon" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "x2_d1_dmight" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "x2_d1_dshield" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's see what I can do...", + "id": 95904 + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And who should be the target of my healing?", + "id": 87722 + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 31 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 30 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 29 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 35 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 34 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 33 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 39 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 38 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 37 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 43 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 42 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 41 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 49 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_feat" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 48 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 47 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 46 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 45 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 54 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 53 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 52 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 51 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 60 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 59 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 58 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 57 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 56 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Which form should I take?" + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 76 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_assoc" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 75 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x2_hen_tomishad3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 74 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 73 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 72 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 71 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 70 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 69 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 68 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 67 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 66 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 65 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 64 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 63 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What would you have me summon?" + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 108 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 98 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 88 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 78 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What would you like to discuss about my defensive spells?", + "id": 88866 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 87 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 86 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 85 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 84 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 83 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 82 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 81 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 80 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 79 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 97 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 96 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 95 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 94 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 93 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 92 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 91 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 90 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 89 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 107 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 106 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 105 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 104 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 103 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 102 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 101 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 100 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 99 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "0c_listhenchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And what is my target?", + "id": 87722 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 190 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 189 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 180 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 179 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 178 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 177 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 176 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 175 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 174 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 173 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 172 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 171 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 12, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 170 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 13, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 169 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 14, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 166 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 15, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 165 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 16, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 164 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 17, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 163 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 18, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 162 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 19, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 161 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 20, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 160 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 21, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 159 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 22, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 158 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 23, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 157 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 24, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 156 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 25, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 155 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 26, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 154 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 27, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 153 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 28, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 152 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 29, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 151 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 30, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 150 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 31, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 149 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 32, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 148 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 33, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 147 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 34, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 146 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 35, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 145 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 36, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 144 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 37, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 143 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 38, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 142 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 39, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 141 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 40, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 140 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 41, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 139 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 42, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 138 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 43, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 137 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 44, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 136 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 45, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 135 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 46, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 134 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 47, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 133 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 48, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 132 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 49, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 131 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 50, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 130 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 51, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 129 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 52, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 128 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 53, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 127 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 54, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 126 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 55, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 125 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 56, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 124 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 57, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 123 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 58, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 122 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 59, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 121 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 60, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 120 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 61, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 119 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 62, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 118 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 63, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 117 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 64, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 116 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 65, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 115 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 66, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 114 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 67, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 113 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 68, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 112 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 69, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 111 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 70, + "Active": { + "type": "resref", + "value": "0c_if_has_spell" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell1" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 110 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 71, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 192 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "What you want me to cast?", + "id": 87720 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 168 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 167 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "You sure?", + "id": 87721 + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 188 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 187 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 186 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 185 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 184 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 183 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 182 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 181 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 192 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Okay. Who shoulds I cast it on?", + "id": 87722 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 201 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 200 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "x0_d2_hasfamil" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 199 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "x0_d2_hascompan" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 198 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "x2_d1_hashench1" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 197 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "x2_d1_hashench2" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 196 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "x2_d1_hashench3" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 195 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "x2_d1_hashench4" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 194 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 193 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 192 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "x2_d1_gentags" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "And who should be the target of my healing?", + "id": 87722 + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 231 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 230 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 229 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_if_pickuploot" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 228 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 221 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 210 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 209 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 208 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 204 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What do you have in mind?" + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_skillrank" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSkill" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nRank" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 207 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_skillrank" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSkill" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nRank" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 206 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 205 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " Should I do something else?" + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 220 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 219 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_if_a_magic_m" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nMode" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 218 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 217 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 216 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 215 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 214 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "0c_if_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_cntrspell" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 213 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 212 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 211 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " How would you like me to use magic in combat?" + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 227 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 226 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 225 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 224 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 223 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 222 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " When do you think I should heal our allies?", + "id": 55427 + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 241 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_defensive" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 240 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ambusher" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 239 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_ranged" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 238 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "0c_no_com_script" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAIScript" + }, + "Value": { + "type": "cexostring", + "value": "ai_a_peaceful" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 237 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 5, + "Active": { + "type": "resref", + "value": "0c_if_taunt" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 236 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 6, + "Active": { + "type": "resref", + "value": "0c_if_cntrspell" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 235 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 7, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 234 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 8, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 233 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 9, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 232 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 10, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 202 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 11, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": " What do you think is the best tactic?" + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 245 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 244 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 2, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 243 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 3, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 203 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + }, + { + "__struct_id": 4, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sure, what would you like me to do?" + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 29 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "RepliesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 249 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 248 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Speaker": { + "type": "cexostring", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wel-met. I think we should work together, what do you say?" + } + } + } + ] + }, + "NumWords": { + "type": "dword", + "value": 1148 + }, + "PreventZoomIn": { + "type": "byte", + "value": 1 + }, + "ReplyList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "That will be all for now." + } + } + }, + { + "__struct_id": 1, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_get_convo" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about something completely different." + } + } + }, + { + "__struct_id": 2, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 1 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "We should part ways." + } + } + }, + { + "__struct_id": 3, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I like having you around." + } + } + }, + { + "__struct_id": 4, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_fire_henchmen" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes I'm sure, Perhapse we'll meet again." + } + } + }, + { + "__struct_id": 5, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Speaking" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change how much you speak.", + "id": 96511 + } + } + }, + { + "__struct_id": 6, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 2 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you use a special ability?", + "id": 96382 + } + } + }, + { + "__struct_id": 7, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_d2_dshield" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Shield.", + "id": 96383 + } + } + }, + { + "__struct_id": 8, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_d2_dmight" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Might.", + "id": 96384 + } + } + }, + { + "__struct_id": 9, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 3 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lay on Hands.", + "id": 96385 + } + } + }, + { + "__struct_id": 10, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I've changed my mind.", + "id": 88430 + } + } + }, + { + "__struct_id": 11, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 12, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 13, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 14, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 15, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 16, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 17, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 18, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 19, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nFeat" + }, + "Value": { + "type": "cexostring", + "value": "257" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_use_feat" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your bard song.", + "id": 88342 + } + } + }, + { + "__struct_id": 20, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 4 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your construction shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 21, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "740" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Iron Golem" + } + } + }, + { + "__struct_id": 22, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "739" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Demon Flesh Golem" + } + } + }, + { + "__struct_id": 23, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "738" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stone Golem" + } + } + }, + { + "__struct_id": 24, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 5 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your outsider shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 25, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "735" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Slaad" + } + } + }, + { + "__struct_id": 26, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "734" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Rakshasa" + } + } + }, + { + "__struct_id": 27, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "733" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Azer" + } + } + }, + { + "__struct_id": 28, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 6 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your humanoid shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 29, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "684" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Kobold Assasin" + } + } + }, + { + "__struct_id": 30, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "683" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lizard folk" + } + } + }, + { + "__struct_id": 31, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "682" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Drow" + } + } + }, + { + "__struct_id": 32, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 7 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape V.", + "id": 88342 + } + } + }, + { + "__struct_id": 33, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "691" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mindflayer" + } + } + }, + { + "__struct_id": 34, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "679" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Medusa" + } + } + }, + { + "__struct_id": 35, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "694" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dire Tiger" + } + } + }, + { + "__struct_id": 36, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 8 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape III.", + "id": 88342 + } + } + }, + { + "__struct_id": 37, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "674" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Manticore" + } + } + }, + { + "__struct_id": 38, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "673" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Drider" + } + } + }, + { + "__struct_id": 39, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "670" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Basilisk" + } + } + }, + { + "__struct_id": 40, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 9 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape II.", + "id": 88342 + } + } + }, + { + "__struct_id": 41, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "680" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minotaur" + } + } + }, + { + "__struct_id": 42, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "678" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Gargoyle" + } + } + }, + { + "__struct_id": 43, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "672" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Harpy" + } + } + }, + { + "__struct_id": 44, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 10 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your greater wild shape I.", + "id": 88342 + } + } + }, + { + "__struct_id": 45, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "662" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Green Wyrmling" + } + } + }, + { + "__struct_id": 46, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "661" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "White Wyrmling" + } + } + }, + { + "__struct_id": 47, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "660" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Black Wyrmling" + } + } + }, + { + "__struct_id": 48, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "659" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Blue Wyrmling" + } + } + }, + { + "__struct_id": 49, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "658" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Red Wyrmling" + } + } + }, + { + "__struct_id": 50, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 11 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your elemental shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 51, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "398" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Water" + } + } + }, + { + "__struct_id": 52, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "397" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fire" + } + } + }, + { + "__struct_id": 53, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "399" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Earth" + } + } + }, + { + "__struct_id": 54, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "400" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Air" + } + } + }, + { + "__struct_id": 55, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 12 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your wild shape.", + "id": 88342 + } + } + }, + { + "__struct_id": 56, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "405" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Badger" + } + } + }, + { + "__struct_id": 57, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "404" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Boar" + } + } + }, + { + "__struct_id": 58, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "403" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wolf" + } + } + }, + { + "__struct_id": 59, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "402" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Panther" + } + } + }, + { + "__struct_id": 60, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "401" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_cast_polymorp" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bear" + } + } + }, + { + "__struct_id": 61, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nEffectType" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_remove_effect" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Transform back into your natural form.", + "id": 96384 + } + } + }, + { + "__struct_id": 62, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 13 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to summon something if you can." + } + } + }, + { + "__struct_id": 63, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "178" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IX.", + "id": 88353 + } + } + }, + { + "__struct_id": 64, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "182" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VIII.", + "id": 88354 + } + } + }, + { + "__struct_id": 65, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "181" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VII.", + "id": 88355 + } + } + }, + { + "__struct_id": 66, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "180" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature VI.", + "id": 88356 + } + } + }, + { + "__struct_id": 67, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "179" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature V.", + "id": 88358 + } + } + }, + { + "__struct_id": 68, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "177" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature IV.", + "id": 88358 + } + } + }, + { + "__struct_id": 69, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "176" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature III.", + "id": 88359 + } + } + }, + { + "__struct_id": 70, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "175" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature II.", + "id": 88360 + } + } + }, + { + "__struct_id": 71, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "174" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Creature I.", + "id": 88361 + } + } + }, + { + "__struct_id": 72, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "30" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Create Undead.", + "id": 88425 + } + } + }, + { + "__struct_id": 73, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Animate Dead.", + "id": 88446 + } + } + }, + { + "__struct_id": 74, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x2_hen_tomishad4" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Summon Shadow." + } + } + }, + { + "__struct_id": 75, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Familiar" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Familiar." + } + } + }, + { + "__struct_id": 76, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAssociate" + }, + "Value": { + "type": "cexostring", + "value": "Companion" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_summon_assoc" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Your Companion." + } + } + }, + { + "__struct_id": 77, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let us talk about your defensive spells.", + "id": 89061 + } + } + }, + { + "__struct_id": 78, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 15 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your defensive spells.", + "id": 89063 + } + } + }, + { + "__struct_id": 79, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 80, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 81, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 82, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 83, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 84, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 85, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 86, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 87, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 88, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 16 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your long duration defensive spells.", + "id": 89064 + } + } + }, + { + "__struct_id": 89, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 90, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 91, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 92, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 93, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 94, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 95, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 96, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 97, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 98, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 17 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast all your short duration defensive spells.", + "id": 89065 + } + } + }, + { + "__struct_id": 99, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast on all the party members.", + "id": 88431 + } + } + }, + { + "__struct_id": 100, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 101, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 102, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 103, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 104, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 105, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 106, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 107, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 108, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "RestBuffing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 14 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast long duration spells after resting." + } + } + }, + { + "__struct_id": 109, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 18 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a spell.", + "id": 88348 + } + } + }, + { + "__struct_id": 110, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "441" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Wounding Whispers.", + "id": 88350 + } + } + }, + { + "__struct_id": 111, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "365" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ultravision.", + "id": 88351 + } + } + }, + { + "__struct_id": 112, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "186" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "True Seeing.", + "id": 88352 + } + } + }, + { + "__struct_id": 113, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "172" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stoneskin.", + "id": 88362 + } + } + }, + { + "__struct_id": 114, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "168" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Resistance.", + "id": 88363 + } + } + }, + { + "__struct_id": 115, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "169" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Spell Mantle.", + "id": 88364 + } + } + }, + { + "__struct_id": 116, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "450" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield of Faith.", + "id": 88365 + } + } + }, + { + "__struct_id": 117, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "417" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shield.", + "id": 88366 + } + } + }, + { + "__struct_id": 118, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "159" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Shadow Shield.", + "id": 88367 + } + } + }, + { + "__struct_id": 119, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "157" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "See Invisibility.", + "id": 88368 + } + } + }, + { + "__struct_id": 120, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "154" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Sanctuary.", + "id": 88369 + } + } + }, + { + "__struct_id": 121, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "152" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Restoration.", + "id": 88370 + } + } + }, + { + "__struct_id": 122, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "151" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resistance.", + "id": 88371 + } + } + }, + { + "__struct_id": 123, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "150" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Resist Elements.", + "id": 88372 + } + } + }, + { + "__struct_id": 124, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "149" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Paralysis.", + "id": 88373 + } + } + }, + { + "__struct_id": 125, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "148" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Fear.", + "id": 88374 + } + } + }, + { + "__struct_id": 126, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "147" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Disease.", + "id": 88375 + } + } + }, + { + "__struct_id": 127, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "146" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Curse.", + "id": 88376 + } + } + }, + { + "__struct_id": 128, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "145" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Remove Blindness/Deafness.", + "id": 88377 + } + } + }, + { + "__struct_id": 129, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "374" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Regenerate.", + "id": 88378 + } + } + }, + { + "__struct_id": 130, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "141" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Spells.", + "id": 88379 + } + } + }, + { + "__struct_id": 131, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "321" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Evil." + } + } + }, + { + "__struct_id": 132, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "137" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Protection From Elements.", + "id": 88380 + } + } + }, + { + "__struct_id": 133, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "134" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Premonition.", + "id": 88381 + } + } + }, + { + "__struct_id": 134, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "133" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Prayer.", + "id": 88382 + } + } + }, + { + "__struct_id": 135, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "355" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Owl's Wisdom.", + "id": 88383 + } + } + }, + { + "__struct_id": 136, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "126" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Neutralize poison.", + "id": 88384 + } + } + }, + { + "__struct_id": 137, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "525" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Monstrous Regeneration.", + "id": 88385 + } + } + }, + { + "__struct_id": 138, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "119" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Minor Globe of Invulnerability.", + "id": 88386 + } + } + }, + { + "__struct_id": 139, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "117" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mind Blank.", + "id": 88387 + } + } + }, + { + "__struct_id": 140, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "113" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mass Haste.", + "id": 88388 + } + } + }, + { + "__struct_id": 141, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "108" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Magical Vestment.", + "id": 88389 + } + } + }, + { + "__struct_id": 142, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "102" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Mage Armor.", + "id": 88390 + } + } + }, + { + "__struct_id": 143, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "100" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Light.", + "id": 88391 + } + } + }, + { + "__struct_id": 144, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "99" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Spell Mantle.", + "id": 88392 + } + } + }, + { + "__struct_id": 145, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "97" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Restoration.", + "id": 88393 + } + } + }, + { + "__struct_id": 146, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "95" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Mind Blank", + "id": 88394 + } + } + }, + { + "__struct_id": 147, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "94" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lesser Dispel.", + "id": 88395 + } + } + }, + { + "__struct_id": 148, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "93" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Knock.", + "id": 88396 + } + } + }, + { + "__struct_id": 149, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "92" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility Sphere.", + "id": 88397 + } + } + }, + { + "__struct_id": 150, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "90" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Invisibility", + "id": 88398 + } + } + }, + { + "__struct_id": 151, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "88" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Improved Invisibility.", + "id": 88399 + } + } + }, + { + "__struct_id": 152, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "78" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Haste.", + "id": 88400 + } + } + }, + { + "__struct_id": 153, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "74" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Stoneskin.", + "id": 88401 + } + } + }, + { + "__struct_id": 154, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "73" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Spell Mantle.", + "id": 88402 + } + } + }, + { + "__struct_id": 155, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "443" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Sanctuary.", + "id": 88403 + } + } + }, + { + "__struct_id": 156, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "70" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Restoration.", + "id": 88404 + } + } + }, + { + "__struct_id": 157, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "109" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Magic Weapon.", + "id": 88405 + } + } + }, + { + "__struct_id": 158, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "67" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Greater Dispelling.", + "id": 88406 + } + } + }, + { + "__struct_id": 159, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "65" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Globe of Invulnerability.", + "id": 88407 + } + } + }, + { + "__struct_id": 160, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "120" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ghostly Visage.", + "id": 88408 + } + } + }, + { + "__struct_id": 161, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "62" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Freedom of Movement.", + "id": 88409 + } + } + }, + { + "__struct_id": 162, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "356" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Fox's Cunning", + "id": 88410 + } + } + }, + { + "__struct_id": 163, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "377" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Find Traps.", + "id": 88411 + } + } + }, + { + "__struct_id": 164, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "121" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Ethereal Visage.", + "id": 88412 + } + } + }, + { + "__struct_id": 165, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "418" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Entropic Shield.", + "id": 88413 + } + } + }, + { + "__struct_id": 166, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "369" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Energy Buffer.", + "id": 88414 + } + } + }, + { + "__struct_id": 167, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "No, I've changed my mind.", + "id": 88415 + } + } + }, + { + "__struct_id": 168, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yes, go ahead.", + "id": 88416 + } + } + }, + { + "__struct_id": 169, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "50" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endure Elements.", + "id": 88417 + } + } + }, + { + "__struct_id": 170, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "49" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Endurance.", + "id": 88418 + } + } + }, + { + "__struct_id": 171, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "47" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Elemental Shield.", + "id": 88419 + } + } + }, + { + "__struct_id": 172, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "354" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Eagle's Splendour.", + "id": 88420 + } + } + }, + { + "__struct_id": 173, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "42" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Divine Power.", + "id": 88421 + } + } + }, + { + "__struct_id": 174, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "41" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Dispel Magic.", + "id": 88422 + } + } + }, + { + "__struct_id": 175, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "38" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Ward.", + "id": 88423 + } + } + }, + { + "__struct_id": 176, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "519" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 19 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Death Armor.", + "id": 88424 + } + } + }, + { + "__struct_id": 177, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "419" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Continual Flame.", + "id": 88426 + } + } + }, + { + "__struct_id": 178, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "21" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Clarity.", + "id": 88427 + } + } + }, + { + "__struct_id": 179, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "13" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cat's Grace.", + "id": 88428 + } + } + }, + { + "__struct_id": 180, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "9" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bull's Strength.", + "id": 88429 + } + } + }, + { + "__struct_id": 181, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 182, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 183, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 184, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 185, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 186, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 187, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 188, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 189, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Bless.", + "id": 88445 + } + } + }, + { + "__struct_id": 190, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nSpell" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 20 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_h_cast_spell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Aid.", + "id": 88447 + } + } + }, + { + "__struct_id": 191, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 21 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to cast a healing spell." + } + } + }, + { + "__struct_id": 192, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I've changed my mind.", + "id": 88430 + } + } + }, + { + "__struct_id": 193, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "0" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Heal up the whole party.", + "id": 88431 + } + } + }, + { + "__struct_id": 194, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "6" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88437 + } + } + }, + { + "__struct_id": 195, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "5" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88438 + } + } + }, + { + "__struct_id": 196, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88439 + } + } + }, + { + "__struct_id": 197, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "3" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on .", + "id": 88440 + } + } + }, + { + "__struct_id": 198, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "8" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my animal companion.", + "id": 88441 + } + } + }, + { + "__struct_id": 199, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "7" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on my familiar.", + "id": 88442 + } + } + }, + { + "__struct_id": 200, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "1" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on me.", + "id": 88443 + } + } + }, + { + "__struct_id": 201, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "nTarget" + }, + "Value": { + "type": "cexostring", + "value": "2" + } + }, + { + "__struct_id": 1, + "Key": { + "type": "cexostring", + "value": "nBuffType" + }, + "Value": { + "type": "cexostring", + "value": "4" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_henchmenspell" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Cast it on yourself.", + "id": 88444 + } + } + }, + { + "__struct_id": 202, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to discuss how we can work together." + } + } + }, + { + "__struct_id": 203, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about something else." + } + } + }, + { + "__struct_id": 204, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets discuss how you deal with objects." + } + } + }, + { + "__struct_id": 205, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Bash" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your bashing tactics.", + "id": 96507 + } + } + }, + { + "__struct_id": 206, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Locks" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your lock picking tactics.", + "id": 96507 + } + } + }, + { + "__struct_id": 207, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Traps" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Objects" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 23 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your trap tactics.", + "id": 96502 + } + } + }, + { + "__struct_id": 208, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Search" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your search tactics.", + "id": 96505 + } + } + }, + { + "__struct_id": 209, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Stealth" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I need you to change your stealth tactics.", + "id": 96505 + } + } + }, + { + "__struct_id": 210, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Let's change how you use magic in combat." + } + } + }, + { + "__struct_id": 211, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you use magic items or not.", + "id": 96498 + } + } + }, + { + "__struct_id": 212, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Dispel" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your dispel tactics.", + "id": 96500 + } + } + }, + { + "__struct_id": 213, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Stop countering the enemies spells.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 214, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Counter the enemy spells!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 215, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BuffFirst" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change who you cast defensive spells on first.", + "id": 96500 + } + } + }, + { + "__struct_id": 216, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "OffensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast offensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 217, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveCasting" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you cast defensive spells.", + "id": 96498 + } + } + }, + { + "__struct_id": 218, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "NMagic" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change how you use magic spells in combat.", + "id": 96498 + } + } + }, + { + "__struct_id": 219, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic more in combat." + } + } + }, + { + "__struct_id": 220, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "MagicMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Spells" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 24 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your magic less in combat." + } + } + }, + { + "__struct_id": 221, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change when you should heal.", + "id": 54985 + } + } + }, + { + "__struct_id": 222, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal out of combat.", + "id": 54990 + } + } + }, + { + "__struct_id": 223, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealOutMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health an one needs for you to heal out of combat.", + "id": 54989 + } + } + }, + { + "__struct_id": 224, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInPlus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Increase the health an one needs for you to heal during combat.", + "id": 54990 + } + } + }, + { + "__struct_id": 225, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealInMinus" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Reduce the health any one needs for you to heal during combat.", + "id": 54989 + } + } + }, + { + "__struct_id": 226, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealSelf" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal yourself.", + "id": 54989 + } + } + }, + { + "__struct_id": 227, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "HealAllies" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Healing" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 25 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you heal any allies.", + "id": 54989 + } + } + }, + { + "__struct_id": 228, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Pickup" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets change if you pickup items and gold." + } + } + }, + { + "__struct_id": 229, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowFarther" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow farther away from me.", + "id": 96510 + } + } + }, + { + "__struct_id": 230, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "FollowCloser" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "Plans" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 22 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Follow closer to me.", + "id": 96511 + } + } + }, + { + "__struct_id": 231, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Lets talk about your tactics in combat." + } + } + }, + { + "__struct_id": 232, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AttackTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change if you fight every opponent during combat.", + "2": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"", + "3": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"" + } + } + }, + { + "__struct_id": 233, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AtkAssociates" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your tactics against familiars, companions, and summons.", + "id": 62531 + } + } + }, + { + "__struct_id": 234, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Ranged" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Change your ranged combat tactics.", + "id": 62531 + } + } + }, + { + "__struct_id": 235, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "CounterSpell" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to counter spell the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 236, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Taunt" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want you to taunt the enemy!", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 237, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "PeaceTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Don't engage in combat.", + "2": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"", + "3": "\"Je ne veux pas du tout que vous vous engagiez dans un combat à distance rapproché,eloignez vous de l'enemi s'il devient trop proche!\"" + } + } + }, + { + "__struct_id": 238, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "RangedTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use agressive ranged tactics, stay out of melee.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 239, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "AmbushTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use ambush tactics, hide and then strike.", + "2": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"", + "3": "\"Je veux que vous fassiez confiance à votre instinct du moment où il faut changer entre armes de mélée ou à projectiles.\"" + } + } + }, + { + "__struct_id": 240, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "DefensiveTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use defensive tactics to protect yourself.", + "id": 62532 + } + } + }, + { + "__struct_id": 241, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "BasicTactics" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 1 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "CombatTactics" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 26 + }, + "IsChild": { + "type": "byte", + "value": 1 + }, + "LinkComment": { + "type": "cexostring", + "value": "" + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Use your best judgement in combat.", + "id": 62531 + } + } + }, + { + "__struct_id": 242, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 27 + }, + "IsChild": { + "type": "byte", + "value": 0 + } + } + ] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can we talk about your items?" + } + } + }, + { + "__struct_id": 243, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "GiveMagicItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Give me all the magical items in your inventory.", + "id": 96514 + } + } + }, + { + "__struct_id": 244, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "GiveUnIdentifiedItems" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Give me all your unidentified items.", + "id": 96514 + } + } + }, + { + "__struct_id": 245, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "x0_d1_hen_inven" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I want to adjust your equipment.", + "id": 96514 + } + } + }, + { + "__struct_id": 246, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Identify" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Can you identify our equipment?", + "id": 88341 + } + } + }, + { + "__struct_id": 247, + "ActionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sAction" + }, + "Value": { + "type": "cexostring", + "value": "Scout" + } + } + ] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_assoc_actions" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "I would like you to scout the area." + } + } + }, + { + "__struct_id": 248, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 0 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Not right now." + } + } + }, + { + "__struct_id": 249, + "ActionParams": { + "type": "list", + "value": [] + }, + "Animation": { + "type": "dword", + "value": 45 + }, + "AnimLoop": { + "type": "byte", + "value": 1 + }, + "Comment": { + "type": "cexostring", + "value": "" + }, + "Delay": { + "type": "dword", + "value": 4294967295 + }, + "EntriesList": { + "type": "list", + "value": [] + }, + "Quest": { + "type": "cexostring", + "value": "" + }, + "Script": { + "type": "resref", + "value": "0c_get_henchman" + }, + "Sound": { + "type": "resref", + "value": "" + }, + "Text": { + "type": "cexolocstring", + "value": { + "0": "Yea, thats a good idea." + } + } + } + ] + }, + "StartingList": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Active": { + "type": "resref", + "value": "0c_if_not_master" + }, + "ConditionParams": { + "type": "list", + "value": [] + }, + "Index": { + "type": "dword", + "value": 28 + } + }, + { + "__struct_id": 1, + "Active": { + "type": "resref", + "value": "0c_if_ass_convo" + }, + "ConditionParams": { + "type": "list", + "value": [ + { + "__struct_id": 0, + "Key": { + "type": "cexostring", + "value": "sOption" + }, + "Value": { + "type": "cexostring", + "value": "BaseMode" + } + } + ] + }, + "Index": { + "type": "dword", + "value": 0 + } + } + ] + } +} diff --git a/src/module/ifo/module.ifo.json b/src/module/ifo/module.ifo.json index 526b64d..f996b85 100644 --- a/src/module/ifo/module.ifo.json +++ b/src/module/ifo/module.ifo.json @@ -669,7 +669,7 @@ "Mod_Description": { "type": "cexolocstring", "value": { - "0": "A Time for Heroes\nv 1.03\nby Shawn Overcash\nbugfixes for version 1.03 by Stacey Keast\n\nA freeform hack&slash module that allows you to explore the world and make a name for yourself at your own leisure.\n\nSingle player only.\nFor characters level 1 to 40.\n\nNote: If you encounter any bugs or problems with the module, contact me through my profile (fsovercash) on NWVault.\n\nNote 2: Or contact me, Stacey Keast and I'll see if I can fix the bugs. (slikster on nwvault). Shawn seems to be on hiatus." + "0": "A Time for Heroes\nv 1.06prc8\nby Shawn Overcash\nbugfixes for version 1.03 by Stacey Keast\n\nA freeform hack&slash module that allows you to explore the world and make a name for yourself at your own leisure.\n\nSingle player only.\nFor characters level 1 to 40.\n\nNote: If you encounter any bugs or problems with the module, contact me through my profile (fsovercash) on NWVault.\n\nNote 2: Or contact me, Stacey Keast and I'll see if I can fix the bugs. (slikster on nwvault). Shawn seems to be on hiatus." } }, "Mod_DuskHour": { @@ -711,6 +711,13 @@ "Mod_HakList": { "type": "list", "value": [ + { + "__struct_id": 8, + "Mod_Hak": { + "type": "cexostring", + "value": "peps_prc8" + } + }, { "__struct_id": 8, "Mod_Hak": { diff --git a/src/module/nss/0c_assoc_actions.nss b/src/module/nss/0c_assoc_actions.nss new file mode 100644 index 0000000..74975d4 --- /dev/null +++ b/src/module/nss/0c_assoc_actions.nss @@ -0,0 +1,172 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_assoc_actions + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Conversation script that sets modes or allows oAssociate to do actions from a + conversation. + Param "sAction" +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oPC = GetPCSpeaker(); + object oAssociate = OBJECT_SELF; + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + object oArea = GetArea(oAssociate); + string sAction = GetScriptParam("sAction"); + // Scout ahead is done int 0e_ch_1_hb (heartbeat script). + if(sAction == "Scout") + { + ai_ClearCreatureActions(); + ai_HaveCreatureSpeak(oAssociate, 4, ":29:35:46:"); + ai_SetAIMode(oAssociate, AI_MODE_SCOUT_AHEAD, TRUE); + ai_ScoutAhead(oAssociate); + } + else if(sAction == "BasicTactics") + { + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, ""); + ai_SetAssociateAIScript(oAssociate, FALSE); + } + else if(sAction == "AmbushTactics") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_ambusher"); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, "ai_a_ambusher"); + } + else if(sAction == "DefensiveTactics") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_defensive"); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, "ai_a_defensive"); + } + else if(sAction == "RangedTactics") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_ranged"); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, "ai_a_ranged"); + } + else if(sAction == "Taunt") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_taunter"); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, "ai_a_taunter"); + } + else if(sAction == "CounterSpell") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_cntrspell"); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, "ai_a_cntrspell"); + } + else if(sAction == "PeaceTactics") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, "ai_a_peaceful"); + } + else if(sAction == "AttackTactics") + { + if(ai_GetAIMode(oAssociate, AI_MODE_CHECK_ATTACK)) + { + ai_SetAIMode(oAssociate, AI_MODE_CHECK_ATTACK, FALSE); + } + else ai_SetAIMode(oAssociate, AI_MODE_CHECK_ATTACK, TRUE); + } + else if(sAction == "FollowCloser") ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sAction == "FollowFarther") ai_FollowIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sAction == "Pickup") ai_Loot(oPC, oAssociate, sAssociateType); + else if(sAction == "HealSelf") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 1); + else if(sAction == "HealAllies") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 2); + else if(sAction == "HealOutMinus") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sAction == "HealOutPlus") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sAction == "HealInMinus") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sAction == "HealInPlus") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sAction == "Traps") ai_Traps(oPC, oAssociate, sAssociateType); + else if(sAction == "Locks") ai_Locks(oPC, oAssociate, sAssociateType, 1); + else if(sAction == "Bash") ai_Locks(oPC, oAssociate, sAssociateType, 2); + else if(sAction == "Search") ai_Search(oPC, oAssociate, sAssociateType); + else if(sAction == "Stealth") ai_Stealth(oPC, oAssociate, sAssociateType); + else if(sAction == "NoMagic") ai_UseMagic(oPC, oAssociate, sAssociateType); + else if(sAction == "DefensiveCasting") ai_UseOffensiveMagic(oPC, oAssociate, TRUE, FALSE, sAssociateType); + else if(sAction == "OffensiveCasting") ai_UseOffensiveMagic(oPC, oAssociate, FALSE, TRUE, sAssociateType); + else if(sAction == "MagicMinus") ai_MagicIncrement(oPC, oAssociate, -1, sAssociateType); + else if(sAction == "MagicPlus") ai_MagicIncrement(oPC, oAssociate, 1, sAssociateType); + else if(sAction == "Speaking") + { + if(ai_GetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK)) + { + ai_SetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK, FALSE); + } + else ai_SetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK, TRUE); + } + else if(sAction == "Ranged") + { + if(ai_GetAIMode(oAssociate, AI_MODE_STOP_RANGED)) + { + ai_SetAIMode(oAssociate, AI_MODE_STOP_RANGED, FALSE); + } + else ai_SetAIMode(oAssociate, AI_MODE_STOP_RANGED, TRUE); + } + else if(sAction == "AtkAssociates") + { + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES)) + { + ai_SetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES, FALSE); + } + else ai_SetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES, TRUE); + } + else if(sAction == "BuffFirst") + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_MASTER)) + { + ai_SetMagicMode(oAssociate, AI_MAGIC_BUFF_MASTER, FALSE); + } + else ai_SetMagicMode(oAssociate, AI_MAGIC_BUFF_MASTER, TRUE); + } + else if(sAction == "RestBuffing") + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST)) + { + ai_SetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST, FALSE); + } + else ai_SetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST, TRUE); + } + else if(sAction == "Dispel") + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_STOP_DISPEL)) + { + ai_SetMagicMode(oAssociate, AI_MAGIC_STOP_DISPEL, FALSE); + } + else ai_SetMagicMode(oAssociate, AI_MAGIC_STOP_DISPEL, TRUE); + } + else if(sAction == "MagicItems") + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS)) + { + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS, FALSE); + } + else ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS, TRUE); + } + else if(sAction == "Identify") + { + ai_IdentifyAllVsKnowledge(oAssociate, oPC, oPC); + return; + } + else if(sAction == "GiveUnIdentifiedItems") + { + ai_ClearCreatureActions(); + object oItem = GetFirstItemInInventory(oAssociate); + while(oItem != OBJECT_INVALID) + { + if(!GetIdentified(oItem)) ActionGiveItem(oItem, oPC); + oItem = GetNextItemInInventory(oAssociate); + } + return; + } + else if(sAction == "GiveMagicItems") + { + ai_ClearCreatureActions(); + itemproperty ipItemProp; + object oItem = GetFirstItemInInventory(oAssociate); + while(oItem != OBJECT_INVALID) + { + ipItemProp = GetFirstItemProperty(oItem); + if(GetIsItemPropertyValid(ipItemProp)) ActionGiveItem(oItem, oPC); + oItem = GetNextItemInInventory(oAssociate); + } + return; + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} diff --git a/src/module/nss/0c_cast_polymorp.nss b/src/module/nss/0c_cast_polymorp.nss new file mode 100644 index 0000000..b06f183 --- /dev/null +++ b/src/module/nss/0c_cast_polymorp.nss @@ -0,0 +1,18 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// + Script Name: 0c_cast_polymorp + Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Conversation script to have a henchman cast a polymorph spell. + int nSpell is the spell to cast. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_items" +void main() +{ + object oHenchman = OBJECT_SELF; + int nSpell = StringToInt (GetScriptParam ("nSpell")); + // Save the original form so we can check when we turn back (Add 1 so we don't save a 0!). + SetLocalInt (oHenchman, AI_NORMAL_FORM, GetAppearanceType (oHenchman) + 1); + SetLocalString (oHenchman, AI_COMBAT_SCRIPT, "ai_a_polymorphed"); + ActionCastSpellAtObject (nSpell, oHenchman, 255, TRUE); +} + diff --git a/src/module/nss/0c_fire_henchmen.nss b/src/module/nss/0c_fire_henchmen.nss new file mode 100644 index 0000000..5505be9 --- /dev/null +++ b/src/module/nss/0c_fire_henchmen.nss @@ -0,0 +1,15 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_fire_henchmen + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Action taken script to fire/remove henchman for higher. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oHenchman = OBJECT_SELF; + ai_ClearCreatureActions(); + ai_FireHenchman (GetPCSpeaker(), oHenchman); + PlayVoiceChat (VOICE_CHAT_GOODBYE, oHenchman); +} + diff --git a/src/module/nss/0c_get_convo.nss b/src/module/nss/0c_get_convo.nss new file mode 100644 index 0000000..7cdfd40 --- /dev/null +++ b/src/module/nss/0c_get_convo.nss @@ -0,0 +1,22 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_get_convo + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Action taken script that leaves the current conversation and starts a new + conversation with oCreature using the linked conversation instead of the + ai_Henchman conversation. + + Allows use of ai_conversation for henchman in other modules. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void BeginOriginalHenchmanConversation(string sDialog, object oPC) +{ + BeginConversation(sDialog, oPC); +} +void main() +{ + ai_ClearCreatureActions(); + // Need to check special dialogs for HOTU henchman. + string sDialog = GetDialogFileToUse(GetLastSpeaker()); + DelayCommand(0.0, BeginOriginalHenchmanConversation(sDialog, GetPCSpeaker())); +} diff --git a/src/module/nss/0c_get_henchman.nss b/src/module/nss/0c_get_henchman.nss new file mode 100644 index 0000000..e0952d5 --- /dev/null +++ b/src/module/nss/0c_get_henchman.nss @@ -0,0 +1,25 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_get_henchman + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Action taken script that adds oCreature to oPC's party as a henchman + while giving a random message. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oPC = GetPCSpeaker(); + AddHenchman(oPC, oCreature); + int nVoice; + switch(d4()) + { + case 1: nVoice = VOICE_CHAT_CANDO; break; + case 2: nVoice = VOICE_CHAT_CHEER; break; + case 3: nVoice = VOICE_CHAT_GOODIDEA; break; + case 4: nVoice = VOICE_CHAT_LAUGH; break; + } + PlayVoiceChat(nVoice, oCreature); +} + + diff --git a/src/module/nss/0c_h_cast_spell.nss b/src/module/nss/0c_h_cast_spell.nss new file mode 100644 index 0000000..40868d8 --- /dev/null +++ b/src/module/nss/0c_h_cast_spell.nss @@ -0,0 +1,12 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_cast_spell + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Action taken script that sets the specified spell to be cast. + Param + nSpell - the spell to cast. +*/////////////////////////////////////////////////////////////////////////////// +void main() +{ + SetLocalInt (OBJECT_SELF, "0_SPELL_TO_CAST", StringToInt (GetScriptParam ("nSpell"))); +} diff --git a/src/module/nss/0c_henchmenspell.nss b/src/module/nss/0c_henchmenspell.nss new file mode 100644 index 0000000..5e64cba --- /dev/null +++ b/src/module/nss/0c_henchmenspell.nss @@ -0,0 +1,81 @@ +/*/////////////////////////////////////////////////////////////////////////////// + Script: 0c_henchmenspell + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Action script to cast a specific spell for a henchman. + + Script Param + nTarget (INT) : 0 = ALL, 1 PC, 2 Caster, 3-6 = oPC's Henchman, 7 = PC's Familiar + 8 = PC's Animal Companion, 9 = PC's Summon. + nBuffType = 1 all 2 short 3 long, 4 healing, 5 lay on hands. + If nBuffType is 0 then it will cast a specific spell from + Variable "0_SPELL_TO_CAST". Use script: 0c_h_spell_cast spell to set the spell. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +float ai_UseLayOnHands(object oTarget, object oPC, float fDelay, object oCaster); +void main() +{ + object oTarget, oPC = GetPCSpeaker(); + object oCreature = OBJECT_SELF; + float fDelay; + int nTarget = StringToInt(GetScriptParam("nTarget")); + int nBuffType = StringToInt(GetScriptParam("nBuffType")); + // Cast a group of buff spells based on nBuffType and nTarget or a single spell. + if(nBuffType < 4) + { + // Cast a specific spell. + if(nBuffType == 0) + { + int nSpell = GetLocalInt(oCreature, "0_SPELL_TO_CAST"); + // These are buff spells so Acid fog (index 0) is not a valid spell. + if(nSpell > 0) + { + ai_ClearCreatureActions(); + object oTarget = GetLocalObject(oCreature, "AI_ALLY_TARGET_" + IntToString(nTarget)); + if(oTarget != OBJECT_INVALID && ai_CheckAndCastSpell(oCreature, nSpell, 0, 0.0f, oTarget, oPC)) + { + DeleteLocalInt(oCreature, "0_SPELL_TO_CAST"); + } + else + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) PlayVoiceChat(VOICE_CHAT_CANTDO, oCreature); + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_SendMessages("I cannot cast " + sSpellName + ".", AI_COLOR_RED, oPC); + } + } + } + // Cast a creatures buff spells on nTarget. + else ai_CastBuffs(oCreature, nBuffType, nTarget, oPC); + } + // Cast Healing spells. + else if(nBuffType == 4) + { + ai_SetupAllyTargets(oCreature, oPC); + oTarget = GetLocalObject(oCreature, "AI_ALLY_TARGET_" + IntToString(nTarget)); + ai_TryHealing(oCreature, oTarget); + } + // Use lay on hands. + else if(nBuffType == 5) + { + ai_SetupAllyTargets(oCreature, oPC); + oTarget = GetLocalObject(oCreature, "AI_ALLY_TARGET_" + IntToString(nTarget)); + ai_UseLayOnHands(oTarget, oPC, 0.0f, oCreature); + } + else if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) PlayVoiceChat(VOICE_CHAT_CUSS, oCreature); +} +float ai_UseLayOnHands(object oTarget, object oPC, float fDelay, object oCreature) +{ + int nHpLost = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + if(!nHpLost) + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) PlayVoiceChat(VOICE_CHAT_CANTDO, oCreature); + ai_SendMessages(GetName(oTarget) + " does not need healed.", AI_COLOR_RED, oPC); + } + else + { + ai_SendMessages(GetName(oCreature) + " is laying hands on " + GetName(oTarget), AI_COLOR_GREEN, oPC); + ActionUseFeat(FEAT_LAY_ON_HANDS, oTarget); + fDelay += 6.0f; + } + return fDelay; +} diff --git a/src/module/nss/0c_if_a_magic_m.nss b/src/module/nss/0c_if_a_magic_m.nss new file mode 100644 index 0000000..7ef4832 --- /dev/null +++ b/src/module/nss/0c_if_a_magic_m.nss @@ -0,0 +1,16 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_a_magic_m + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if the henchmen has a specific + associate magic mode. + Param: + nMode - The mode to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + int nMode = StringToInt(GetScriptParam("nMode")); + return ai_GetMagicMode (oHenchman, nMode); +} diff --git a/src/module/nss/0c_if_ass_convo.nss b/src/module/nss/0c_if_ass_convo.nss new file mode 100644 index 0000000..190a0f7 --- /dev/null +++ b/src/module/nss/0c_if_ass_convo.nss @@ -0,0 +1,132 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_ass_convo + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that has the henchman tell the player what options + have been selected. + + sOption will decide what the henchman says. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oPC = GetPCSpeaker(); + object oAssociate = OBJECT_SELF; + string sParam = GetScriptParam("sOption"); + if(sParam == "BaseMode") + { + string sBaseMode = "I'm ready to attack."; + string sVolume = " While shouting when I see things."; + // Lets get which base mode the henchman is in. + if(ai_GetAIMode(oAssociate, AI_MODE_STAND_GROUND)) sBaseMode = "I'm holding here."; + else if(ai_GetAIMode(oAssociate, AI_MODE_DEFEND_MASTER)) sBaseMode = "I'm defending you."; + else if(ai_GetAIMode(oAssociate, AI_MODE_FOLLOW)) sBaseMode = "I'm following you."; + if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_peaceful") sBaseMode = "I will not fight the enemy!"; + if(ai_GetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK)) sVolume = " While not speaking unless spoken to."; + SetCustomToken(AI_BASE_CUSTOM_TOKEN, sBaseMode + sVolume); + } + else if(sParam == "CombatTactics") + { + string sRangedUse = "", sCombatTactic = "I'm using my best judgement in combat "; + string sAtkAssociates = ""; + string sTargets = "against all enemies and "; + // Lets get which base mode the henchman is in. + if(ai_GetAIMode(oAssociate, AI_MODE_CHECK_ATTACK)) sTargets = "against enemies I can handle and "; + if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_ambusher") sCombatTactic = "I'm using ambush tactics "; + else if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_defensive") sCombatTactic = "I'm using defensive tactics "; + else if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_taunter") sCombatTactic = "I'm ready to taunt "; + else if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_cntrspell") sCombatTactic = "I'm ready to counter spell "; + if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_peaceful") + { + sCombatTactic = "I will not fight the enemy!"; + sTargets = ""; + } + else + { + if(ai_GetAIMode(oAssociate, AI_MODE_STOP_RANGED)) sRangedUse = "will not use a ranged weapon."; + else sRangedUse = "will use a ranged weapon."; + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES)) sAtkAssociates = " I will also ignore familiars, companions, and summons."; + else sAtkAssociates = " I will also attack familiars, companions, and summons."; + } + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 1, sCombatTactic + sTargets + sRangedUse + sAtkAssociates); + } + else if(sParam == "Plans") + { + float fFollowRange = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE); + string sFollowRange = FloatToString(fFollowRange, 0, 0); + string sDistance = "I'm following from " + sFollowRange + " meters away while"; + string sStealth, sSearch, sPickup; + if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sPickup = " picking up items"; + else sPickup = " not picking up any items"; + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH)) sStealth = " in stealth"; + else sStealth = ""; + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH)) sSearch = " and searching"; + else sSearch = ""; + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 2, sDistance + sPickup + sStealth + sSearch + "."); + } + else if(sParam == "Healing") + { + string sHealingIn = IntToString(GetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT)) + "%"; + string sHealingOut = IntToString(GetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT)) + "%"; + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 5, "I'm healing our allies if they go below " + + sHealingIn + " health in combat and " + sHealingOut + " out of combat."); + } + else if(sParam == "Spells") + { + string sCastingLevel = "[" + IntToString(GetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT)) + "] "; + string sCasting = "I'm casting"; + string sType = " spells I choose."; + string sBuff = " I'll also targeting anyone that needs it "; + string sDispel = "while using Dispel spells."; + string sMagicItems = " Lastly I'll use any magic items I have."; + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_MASTER)) sBuff = " Ofcourse I'll target you first "; + if(ai_GetMagicMode(oAssociate, AI_MAGIC_STOP_DISPEL)) sDispel = "while not using Dispel spells."; + if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_a_cntrspell") + { + sCasting = "I'm ready to counter spell our enemies."; + sType = ""; + sBuff = ""; + sDispel = ""; + } + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC)) + { + sCasting = "I'm not use any magic."; + sType = ""; + sBuff = ""; + sDispel = ""; + } + else if(ai_GetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING)) sType = " defensive spells only."; + else if(ai_GetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING)) + { + sType = " offensive spells only."; + sBuff = ""; + } + else if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS)) sMagicItems = " Finally I'll not use magic items."; + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 5, sCastingLevel + sCasting + sType + sBuff + sDispel+ sMagicItems); + } + else if(sParam == "Objects") + { + int bTraps = ai_GetAIMode(oAssociate, AI_MODE_DISARM_TRAPS); + int bLocks = ai_GetAIMode(oAssociate, AI_MODE_PICK_LOCKS); + int bBash = ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS); + string sText = "I'm going to ignore all traps and locks."; + if(bTraps && bLocks && bBash) + { + sText = "I'm disarming all the traps and am either picking or bashing any of the locks we find."; + } + else if(bTraps && bLocks) sText = "I'm going to disarm all the traps and I'll pick all the locks we encounter."; + else if(bTraps && bBash) sText = "I shall disarm all the traps and will bash any locks we come across."; + else if(bTraps) sText = "I will disarm all the traps I can but will leave any locks for you to deal with."; + else if(bLocks && bBash) sText = "I will leave the traps for you but will either pick or bash any locks we see."; + else if(bLocks) sText = "I'll keep my distance from any traps we see, but will pick the locks found."; + else if(bBash) sText = "I'll let you mess with the traps, but I'll bash any locks that are out there."; + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 3, sText); + } + else if(sParam == "RestBuffing") + { + string sRestBuffing = ""; + if(!ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST)) sRestBuffing = "not "; + SetCustomToken(AI_BASE_CUSTOM_TOKEN + 10, "After we rest I am " + sRestBuffing + "casting my long buff spells on us."); + } + return TRUE; +} diff --git a/src/module/nss/0c_if_assoc_mode.nss b/src/module/nss/0c_if_assoc_mode.nss new file mode 100644 index 0000000..342bfff --- /dev/null +++ b/src/module/nss/0c_if_assoc_mode.nss @@ -0,0 +1,22 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_assoc_mode + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if the henchmen has a specific + associate mode. + Param: + nMode - The mode to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + int nMode = StringToInt(GetScriptParam("nMode")); + // This conversation line turns off picking up any items. + if (nMode == -1) + { + if(ai_SetAIMode (oHenchman, AI_MODE_PICKUP_ITEMS)) return TRUE; + return FALSE; + } + return ai_GetAIMode (oHenchman, nMode); +} diff --git a/src/module/nss/0c_if_cntrspell.nss b/src/module/nss/0c_if_cntrspell.nss new file mode 100644 index 0000000..a0a5c87 --- /dev/null +++ b/src/module/nss/0c_if_cntrspell.nss @@ -0,0 +1,17 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_cntrspell + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that returns TRUE the server allows a henchman to + use counterspell and if they don't have the counterspell ai script set. + Param: + sAIScript - The special combat script to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + return (AI_COUNTERSPELLING_ON && + ai_CheckClassType(oHenchman, AI_CLASS_TYPE_CASTER) && + GetLocalString(oHenchman, AI_COMBAT_SCRIPT) != "ai_a_cntrspell"); +} diff --git a/src/module/nss/0c_if_com_script.nss b/src/module/nss/0c_if_com_script.nss new file mode 100644 index 0000000..34d8370 --- /dev/null +++ b/src/module/nss/0c_if_com_script.nss @@ -0,0 +1,16 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_com_script + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that returns TRUE the caller does have an ai combat + script set to sAIScript. + Param: + sAIScript - The special combat script to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + string sAIScript = GetScriptParam("sAIScript"); + string sAICombatScript = GetLocalString (OBJECT_SELF, AI_COMBAT_SCRIPT); + return (sAIScript == sAICombatScript); +} diff --git a/src/module/nss/0c_if_convo.nss b/src/module/nss/0c_if_convo.nss new file mode 100644 index 0000000..83e1db4 --- /dev/null +++ b/src/module/nss/0c_if_convo.nss @@ -0,0 +1,21 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_if_convo + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that check if oCreature has a linked conversation. + Only checks for Henchman. + Allows use of ai_conversation for henchman in other modules. +*/////////////////////////////////////////////////////////////////////////////// +#include "nw_inc_gff" +#include "0i_messages" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + if(GetAssociateType(oHenchman) == ASSOCIATE_TYPE_HENCHMAN) + { + json jHenchman = ObjectToJson(oHenchman); + string sConversation = JsonGetString(GffGetResRef(jHenchman, "Conversation")); + if(sConversation != "") return TRUE; + } + return FALSE; +} diff --git a/src/module/nss/0c_if_has_assoc.nss b/src/module/nss/0c_if_has_assoc.nss new file mode 100644 index 0000000..cd16680 --- /dev/null +++ b/src/module/nss/0c_if_has_assoc.nss @@ -0,0 +1,18 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_has_assoc + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if caller has the specified feat + to summon either a companion or a familiar and they are not summoned. + Param + sAssociate - "Familiar" or "Companion" +*/////////////////////////////////////////////////////////////////////////////// +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + string sAssociate = GetScriptParam("sAssociate"); + if(sAssociate == "Familiar" && GetHasFeat(FEAT_SUMMON_FAMILIAR, oHenchman) && + GetAssociate(ASSOCIATE_TYPE_FAMILIAR) == OBJECT_INVALID) return TRUE; + return (sAssociate == "Companion" && GetHasFeat(FEAT_ANIMAL_COMPANION, oHenchman) && + GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION) == OBJECT_INVALID); +} diff --git a/src/module/nss/0c_if_has_class.nss b/src/module/nss/0c_if_has_class.nss new file mode 100644 index 0000000..1251c0a --- /dev/null +++ b/src/module/nss/0c_if_has_class.nss @@ -0,0 +1,28 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_has_class + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if conversation owner has a + specified class. Multiple classes maybe selected. + Param + nClass# - the class to look for use nClass1, nClass2, nClass3 for each one to check. +*/////////////////////////////////////////////////////////////////////////////// +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + int nCntr = 1; + int nClass; + string sClass; + while(nCntr < 10) + { + sClass = GetScriptParam("nClass" + IntToString(nCntr)); + if(sClass != "") + { + nClass = StringToInt(sClass); + if(GetLevelByClass(nClass, oHenchman)) return TRUE; + nCntr++; + } + else break; + } + return FALSE; +} diff --git a/src/module/nss/0c_if_has_feat.nss b/src/module/nss/0c_if_has_feat.nss new file mode 100644 index 0000000..fc111d8 --- /dev/null +++ b/src/module/nss/0c_if_has_feat.nss @@ -0,0 +1,22 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_has_feat + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if they have a specific feat. + Param: + sTarget - either "OBJECT_SELF", or "PCSpeaker", blanks defaults to "PCSpeaker" + nFeat - the feat number from Feats.2da + bNot - if 1 TRUE then this returns true for the target not having the feat. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +int StartingConditional() +{ + string sTarget = GetScriptParam("sTarget"); + int nFeat = StringToInt(GetScriptParam("nFeat")); + int bNot = StringToInt(GetScriptParam("bNot")); + object oCreature; + if(sTarget == "OBJECT_SELF") oCreature = OBJECT_SELF; + else if(sTarget == "" || sTarget == "PCSpeaker") oCreature = GetPCSpeaker(); + if(bNot) return !GetHasFeat(nFeat, oCreature); + return (GetHasFeat(nFeat ,oCreature) || ai_GetIsDungeonMaster(oCreature)); +} diff --git a/src/module/nss/0c_if_has_spell.nss b/src/module/nss/0c_if_has_spell.nss new file mode 100644 index 0000000..02004ff --- /dev/null +++ b/src/module/nss/0c_if_has_spell.nss @@ -0,0 +1,26 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_has_spell + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if caster can cast the specified spell. + Param + nSpell# - the spell to look for nSpell1, sSpell2, nSpell3 for each spell to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_spells" +int StartingConditional() +{ + object oCaster = OBJECT_SELF; + int nCnt = 1; + int nSpell; + string sSpell; + while(nCnt < 20) + { + sSpell = GetScriptParam("nSpell" + IntToString(nCnt)); + if(sSpell == "") return FALSE; + nSpell = StringToInt(sSpell); + if(GetHasSpell(nSpell, oCaster)) return TRUE; + //else if(ai_GetKnownSpell(oCaster, nSpell)) return TRUE; + nCnt++; + } + return FALSE; +} diff --git a/src/module/nss/0c_if_hen_leave.nss b/src/module/nss/0c_if_hen_leave.nss new file mode 100644 index 0000000..e2b2bbd --- /dev/null +++ b/src/module/nss/0c_if_hen_leave.nss @@ -0,0 +1,12 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_hen_leave + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that check if allowing the player to remove a henchman + is activated on this server. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + return AI_REMOVE_HENCHMAN_ON; +} diff --git a/src/module/nss/0c_if_identify.nss b/src/module/nss/0c_if_identify.nss new file mode 100644 index 0000000..b593baf --- /dev/null +++ b/src/module/nss/0c_if_identify.nss @@ -0,0 +1,17 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_identify + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if the henchmen has a better lore + skill than the speaker. + Also checks AI_IDENTIFY_ON to see if the server wants them to help. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + if (!AI_IDENTIFY_ON && !ai_CanISpeak (oHenchman)) return FALSE; + int nHenchmanLore = GetSkillRank(SKILL_LORE, oHenchman); + int nMasterLore = GetSkillRank(SKILL_LORE, GetMaster(oHenchman)); + return (nHenchmanLore > nMasterLore); +} diff --git a/src/module/nss/0c_if_not_master.nss b/src/module/nss/0c_if_not_master.nss new file mode 100644 index 0000000..73cb84e --- /dev/null +++ b/src/module/nss/0c_if_not_master.nss @@ -0,0 +1,11 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_not_master + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks if the speaker is the master of this + henchman. +*/////////////////////////////////////////////////////////////////////////////// +int StartingConditional() +{ + return !GetIsObjectValid(GetMaster()); +} diff --git a/src/module/nss/0c_if_open_inven.nss b/src/module/nss/0c_if_open_inven.nss new file mode 100644 index 0000000..2755c99 --- /dev/null +++ b/src/module/nss/0c_if_open_inven.nss @@ -0,0 +1,13 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_open_equip + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks if opening a henchmans inventory + is activated on this server. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + if(GetAssociateType(OBJECT_SELF) != ASSOCIATE_TYPE_HENCHMAN) return FALSE; + return AI_OPEN_INVENTORY; +} diff --git a/src/module/nss/0c_if_pickuploot.nss b/src/module/nss/0c_if_pickuploot.nss new file mode 100644 index 0000000..f4edfdb --- /dev/null +++ b/src/module/nss/0c_if_pickuploot.nss @@ -0,0 +1,12 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_pickuploot + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that check if having associates picking up loot is + activated on this server. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + return AI_PICKUP_LOOT; +} diff --git a/src/module/nss/0c_if_polymorph.nss b/src/module/nss/0c_if_polymorph.nss new file mode 100644 index 0000000..e2317f6 --- /dev/null +++ b/src/module/nss/0c_if_polymorph.nss @@ -0,0 +1,11 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_polymorph +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if the caller is polymorphed. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + if (GetLocalInt(OBJECT_SELF, AI_NORMAL_FORM) != 0) return TRUE; + return FALSE; +} diff --git a/src/module/nss/0c_if_scout.nss b/src/module/nss/0c_if_scout.nss new file mode 100644 index 0000000..9f7b0a3 --- /dev/null +++ b/src/module/nss/0c_if_scout.nss @@ -0,0 +1,11 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_scout + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that check if scouting is activated on this server. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + return AI_SCOUT_AHEAD_ON; +} diff --git a/src/module/nss/0c_if_skillrank.nss b/src/module/nss/0c_if_skillrank.nss new file mode 100644 index 0000000..e0d7729 --- /dev/null +++ b/src/module/nss/0c_if_skillrank.nss @@ -0,0 +1,18 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_SkillRank + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that checks to see if the caller's skill ranks + are above or equal to the param value. + Param: + nSkill - the skill number for the skill. See skills.2da. + nRank - the rank required. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +int StartingConditional() +{ + string sSkill = GetScriptParam("nSkill"); + if(sSkill == "") return FALSE; + int nRank = StringToInt(GetScriptParam("nRank")); + return (GetSkillRank(StringToInt(sSkill)) >= nRank); +} diff --git a/src/module/nss/0c_if_taunt.nss b/src/module/nss/0c_if_taunt.nss new file mode 100644 index 0000000..3e0fde6 --- /dev/null +++ b/src/module/nss/0c_if_taunt.nss @@ -0,0 +1,15 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_if_taunt + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that returns TRUE the server allows a henchman to + taunt and if they have the don't have the taunt ai script set. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + object oHenchman = OBJECT_SELF; + return (AI_TAUNTING_ON && + GetSkillRank(SKILL_TAUNT, oHenchman) > ai_GetCharacterLevels(oHenchman) && + GetLocalString(oHenchman, AI_COMBAT_SCRIPT) != "ai_a_taunter"); +} diff --git a/src/module/nss/0c_listhenchman.nss b/src/module/nss/0c_listhenchman.nss new file mode 100644 index 0000000..802f100 --- /dev/null +++ b/src/module/nss/0c_listhenchman.nss @@ -0,0 +1,19 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// + Script Name: 0c_cast_polymorp + Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Conversation script to setup the tokens for the henchman in the speakers party + except for who they are talking to. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +void main() +{ + object oSpeaker = OBJECT_SELF; + object oPC = GetPCSpeaker(); + int nCntr = 1; + object oHenchman = GetHenchman(oPC, nCntr); + while(oHenchman != OBJECT_INVALID) + { + if(oHenchman != oSpeaker) SetCustomToken(77100 + nCntr, GetName(oHenchman)); + oHenchman = GetHenchman(oPC, ++nCntr); + } +} diff --git a/src/module/nss/0c_no_com_script.nss b/src/module/nss/0c_no_com_script.nss new file mode 100644 index 0000000..ca5c386 --- /dev/null +++ b/src/module/nss/0c_no_com_script.nss @@ -0,0 +1,27 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0c_no_com_script + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Text Appears When script that returns TRUE the caller does not have an ai combat + script set to sAIScript. + if sAIScript is blank then if its equal to all of them. + Param: sAIScripts:"ai_a_ambusher", "ai_a_defensive", "ai_a_taunter", "ai_coward". + sAIScript - The special combat script to check. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +int StartingConditional() +{ + string sAIScript = GetScriptParam("sAIScript"); + string sAICombatScript = GetLocalString (OBJECT_SELF, AI_COMBAT_SCRIPT); + // This is the value for do your own thing in combat! + if (sAIScript == "") + { + return (sAICombatScript == "ai_a_ambusher" || + sAICombatScript == "ai_a_defensive" || + sAICombatScript == "ai_a_ranged" || + sAICombatScript == "ai_a_taunter" || + sAICombatScript == "ai_a_cntrspell" || + sAICombatScript == "ai_a_peaceful"); + } + return (sAIScript != sAICombatScript); +} diff --git a/src/module/nss/0c_remove_effect.nss b/src/module/nss/0c_remove_effect.nss new file mode 100644 index 0000000..aa95a0c --- /dev/null +++ b/src/module/nss/0c_remove_effect.nss @@ -0,0 +1,14 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script:0c_remove_effect + Programmer:Philos +//////////////////////////////////////////////////////////////////////////////// + Actions Taken script that removes an effect from OBJECT_SELF. + Param: nEffect - the EFFECT_TYPE_* number to remove. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_spells" +void main () +{ + int nEffect = StringToInt (GetScriptParam ("nEffectType")); + ai_RemoveASpecificEffect (OBJECT_SELF, nEffect); +} + diff --git a/src/module/nss/0c_summon_assoc.nss b/src/module/nss/0c_summon_assoc.nss new file mode 100644 index 0000000..19544de --- /dev/null +++ b/src/module/nss/0c_summon_assoc.nss @@ -0,0 +1,17 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// + Script Name: 0c_summon_assoc + Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Conversation script to have the caller summon either an animal companion or + familiar associate. + + Param + sAssociate - which associate to summon. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + string sAssociate = GetScriptParam ("sAssociate"); + if (sAssociate == "Familiar") SummonFamiliar (); + else if (sAssociate == "Companion") SummonAnimalCompanion (); +} diff --git a/src/module/nss/0c_use_feat.nss b/src/module/nss/0c_use_feat.nss new file mode 100644 index 0000000..ec3ddcc --- /dev/null +++ b/src/module/nss/0c_use_feat.nss @@ -0,0 +1,15 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// + Script Name: 0c_summon_assoc + Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Conversation script to have the caller use nFeat from the feat.2da. + + Param + nFeat - Feat number from the feat.2da. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + int nFeat = StringToInt (GetScriptParam ("nFeat")); + ActionUseFeat(nFeat, OBJECT_SELF); +} diff --git a/src/module/nss/0e_c2_1_hb.nss b/src/module/nss/0e_c2_1_hb.nss new file mode 100644 index 0000000..05fbfc2 --- /dev/null +++ b/src/module/nss/0e_c2_1_hb.nss @@ -0,0 +1,16 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_c2_1_hb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnHeartbeat script; + This will usually fire every 6 seconds (1 game round). + + I am reverting the AI script back to the games default scripts for efficiency. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_module" +void main() +{ + SetLocalInt(OBJECT_SELF, AI_ONSPAWN_EVENT, TRUE); + ai_ChangeEventScriptsForMonster(OBJECT_SELF); + ExecuteScript("nw_c2_default1"); +} diff --git a/src/module/nss/0e_c2_7_ondeath.nss b/src/module/nss/0e_c2_7_ondeath.nss new file mode 100644 index 0000000..129e81e --- /dev/null +++ b/src/module/nss/0e_c2_7_ondeath.nss @@ -0,0 +1,32 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_c2_7_ondeath + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnDeath script; + This fires when the creature dies. +*//////////////////////////////////////////////////////////////////////////////// +#include "0i_module" +void main() +{ + object oCreature = OBJECT_SELF; + // Added code to allow for permanent associates in the battle! + object oModule = GetModule(); + if(GetLocalInt(oModule, AI_RULE_PERM_ASSOC)) + { + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex < 5; nIndex++) + { + oAssociate = GetAssociate(nIndex, oCreature); + if(oAssociate != OBJECT_INVALID) + { + SetIsDestroyable(FALSE, FALSE, FALSE); + DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE)); + } + } + } + if(GetLocalInt(oModule, AI_RULE_CORPSES_STAY)) SetIsDestroyable(FALSE, FALSE, TRUE); + ai_ClearCombatState(oCreature); + ExecuteScript(GetLocalString(oCreature, "AI_ON_DEATH")); +} + diff --git a/src/module/nss/0e_ch_1_hb.nss b/src/module/nss/0e_ch_1_hb.nss new file mode 100644 index 0000000..d04eeb8 --- /dev/null +++ b/src/module/nss/0e_ch_1_hb.nss @@ -0,0 +1,14 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_ch_1_hb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate(Summons, Familiar, Companion) OnHeart beat script when out of combat; + This will usually fire every 6 seconds (1 game round). +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_module" +void main() +{ + SetLocalInt(OBJECT_SELF, AI_ONSPAWN_EVENT, TRUE); + ai_ChangeEventScriptsForAssociate(OBJECT_SELF); + ExecuteScript("nw_ch_ac1"); +} diff --git a/src/module/nss/0e_ch_7_ondeath.nss b/src/module/nss/0e_ch_7_ondeath.nss new file mode 100644 index 0000000..76d955d --- /dev/null +++ b/src/module/nss/0e_ch_7_ondeath.nss @@ -0,0 +1,41 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_ch_7_ondeath + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate OnSpawn script; + This fires when an associate dies. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_module" +void main() +{ + object oCreature = OBJECT_SELF; + // Added code to allow for permanent associates in the battle! + if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "13", GetName(oCreature) + " has died!" + + " AI_RULE_PERM_ASSOC: " + IntToString(GetLocalInt(GetModule(), AI_RULE_PERM_ASSOC))); + object oModule = GetModule(); + if(GetLocalInt(oModule, AI_RULE_PERM_ASSOC)) + { + object oAssociate; + int nIndex; + for(nIndex = 2; nIndex < 5; nIndex++) + { + oAssociate = GetAssociate(nIndex, oCreature); + if(oAssociate != OBJECT_INVALID) + { + SetIsDestroyable(FALSE, FALSE, FALSE); + ChangeFaction(oAssociate, oCreature); + } + } + } + // Remove the widget! + object oPC = GetMaster(oCreature); + if(oPC != OBJECT_INVALID) + { + NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oCreature) + AI_WIDGET_NUI)); + DelayCommand(0.5, ai_CheckXPPartyScale(oCreature)); + DelayCommand(2.0, ai_ClearCreatureActions(TRUE)); + } + DelayCommand(2.0, ai_ClearCombatState(oCreature)); + ExecuteScript(GetLocalString(oCreature, "AI_ON_DEATH")); +} + diff --git a/src/module/nss/0e_do_combat_rnd.nss b/src/module/nss/0e_do_combat_rnd.nss new file mode 100644 index 0000000..f1cb9c0 --- /dev/null +++ b/src/module/nss/0e_do_combat_rnd.nss @@ -0,0 +1,22 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_do_combat_rnd + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Used to execute a combat round just after the current action is over. + Note: Do not use with an attack action since it will continue until + the attacked enemy is dead. We end attack actions with a ClearAllActions + command and would also end this one so it will not work with attack actions. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("0e_do_combat_rnd", "14", GetName(oCreature) + " is calculating a new round." + + "nAction: " + IntToString(GetCurrentAction(oCreature))); + if(ai_GetIsInCombat(oCreature)) + { + if(GetAssociateType(oCreature) == ASSOCIATE_TYPE_NONE && + !ai_GetIsCharacter(oCreature)) ai_DoMonsterCombatRound(oCreature); + else if(ai_CanIAttack(oCreature)) ai_DoAssociateCombatRound(oCreature); + } +} diff --git a/src/module/nss/0e_gui_events.nss b/src/module/nss/0e_gui_events.nss new file mode 100644 index 0000000..401c825 --- /dev/null +++ b/src/module/nss/0e_gui_events.nss @@ -0,0 +1,60 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: 0e_gui_events + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + OnPlayerGUIEvent event script + Used to allow PEPS to gain control of specific GUI events. + +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_gui_events" +#include "0i_menus" +void main() +{ + object oPC = GetLastGuiEventPlayer(); + int nEventType = GetLastGuiEventType(); + int nEventInt = GetLastGuiEventInteger(); + //object oEventObject = GetLastGuiEventObject(); + switch(nEventType) + { + case GUIEVENT_EFFECTICON_CLICK: + { + if(ai_GetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT)) + { + ai_CreateEffectChatReport(oPC, nEventInt); + return; + } + int nToken = NuiFindWindow(oPC, AI_EFFECT_ICON_NUI); + json jData; + if(nToken) + { + jData = NuiGetUserData(oPC, nToken); + int nOldEffectIcon = JsonGetInt(JsonArrayGet(jData, 1)); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + if(nOldEffectIcon == nEventInt) return; + } + ai_CreateEffectIconMenu(oPC, nEventInt); + } + case GUIEVENT_PARTYBAR_PORTRAIT_CLICK: + { + object oAssociate = GetLastGuiEventObject(); + if(GetMaster(oAssociate) == oPC) + { + // If all the Command buttons are blocked then don't load the menu. + if(GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028) + { + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + if(IsWindowClosed(oPC, sAssociateType + AI_COMMAND_NUI)) + { + ai_CreateAssociateCommandNUI(oPC, oAssociate); + } + IsWindowClosed(oPC, sAssociateType + AI_NUI); + IsWindowClosed(oPC, sAssociateType + AI_LOOTFILTER_NUI); + IsWindowClosed(oPC, sAssociateType + AI_COPY_NUI); + IsWindowClosed(oPC, sAssociateType + AI_QUICK_WIDGET_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_MEMORIZE_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_KNOWN_NUI); + } + } + } + } +} diff --git a/src/module/nss/0e_m1_3_endround.nss b/src/module/nss/0e_m1_3_endround.nss new file mode 100644 index 0000000..e8a0125 --- /dev/null +++ b/src/module/nss/0e_m1_3_endround.nss @@ -0,0 +1,46 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_m1_3_endround + Original Script: m1_combanter_3 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnCombatRoundEnd event script used in the original campaign + for monsters that may do a one liner during combat; + + Fires at the end of each combat round (6 seconds). + This will fire as long as oCreature is in combat (GetIsInCombat()). + This event starts counting once a combat action is started. + Every time a spell is cast it will queue another end combat round so haste with + two spells cast will fire this twice in one round. + It will also fire at the end of a hostile effect that stops actions i.e Stunned, Knockdown etc. + Action modes are also cleared prior to this event executing! + GetAttemptedAttackTarget() & GetAttemptedSpellTarget() also get cleared prior to this event. + This event can be canceled with ClearAllActions(TRUE) and SurrenderToEnemies. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("0e_m1_3_endround", "23", GetName(oCreature) + " ends combat round."); + // Action modes get cleared prior to each OnCombatRoundEnd! + // We do this to keep the action mode going. + int nActionMode = GetLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + if(nActionMode > 0) + { + SetActionMode(oCreature, nActionMode, TRUE); + // We don't want to use up all of the Dwarven Defenders uses! + if(nActionMode == 12) IncrementRemainingFeatUses(oCreature, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE); + } + if (ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(Random(4) == 0) SpeakOneLinerConversation(); + if(ai_GetIsInCombat(oCreature)) ai_DoMonsterCombatRound(oCreature); + ai_SpellConcentrationCheck(oCreature); + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) ai_DetermineSpecialBehavior(oCreature); + if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1003)); + } +} + + + + diff --git a/src/module/nss/0e_nui.nss b/src/module/nss/0e_nui.nss new file mode 100644 index 0000000..7d18c65 --- /dev/null +++ b/src/module/nss/0e_nui.nss @@ -0,0 +1,1975 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: 0e_nui + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Menu event script + sEvent: close, click, mousedown, mouseup, watch (if bindwatch is set). +/*////////////////////////////////////////////////////////////////////////////// +#include "nw_inc_gff" +#include "x0_i0_assoc" +#include "0i_menus" +#include "0i_player_target" +// Save a window ID to the database. +void ai_SaveWindowLocation(object oPC, int nToken, string sAssociateType, string sWindowID); +// Sets the Widget Buttons state to sElem Checkbox state. +void ai_SetWidgetButtonToCheckbox(object oPC, int nButton, object oAssociate, string sAssociateType, int nToken, string sElem); +// Flips an AI Buttons state to sElem Checkbox state. +void ai_SetAIButtonToCheckbox(object oPC, int nButton, object oAssociate, string sAssociateType, int nToken, string sElem); +// Flips the flag for the loot filter to sElem Checkbox state. +void ai_SetLootFilterToCheckbox(object oPC, object oAssociate, int nFilterBit, int nToken, string sElem); +// Sets an associates companion type. Cannot set companion for a player! +void ai_SetCompanionType(object oPC, object oAssociate, int nToken, int nCompanionType); +// Sets an associates companion name. Cannot set companion for a player! +void ai_SetCompanionName(object oPC, object oAssociate, int nToken, int nCompanionType); +// Sets an associates AI script via a combo box. +void ai_SetAIScript(object oPC, object oAssociate, int nToken); +// Increments/Decrements the Perception Range use variable for the AI. +void ai_PercRangeIncrement(object oPC, object oAssociate, int nIncrement, string sAssociateType, int nToken); +// Saves an associates perception range changed on the button. +void ai_Perc_Range(object oPC, object oAssociate, int nToken, string sAssociateType); +// Changes Perception Distance Rule for monsters. +void ai_RulePercDistInc(object oPC, object oModule, int nIncrement, int nToken); +// Adds a spell to a json AI restricted spell list then returns jRules. +// bRestrict = TRUE will add to the list FALSE will remove it from the list. +json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE); +// Turns on oAssociate AI, Setting all event scripts. +void ai_TurnOn(object oPC, object oAssociate, string sAssociateType); +// Turns off oAssociate AI, Setting all event scripts. +void ai_TurnOff(object oPC, object oAssociate, string sAssociateType); +// Adds a henchman back into the players party. +object ai_AddHenchman(object oPC, json jHenchman, location lLocation, int nFamiliar, int nCompanion); + +void ai_SaveWindowLocation(object oPC, int nToken, string sAssociateType, string sWindowID) +{ + json jGeometry = NuiGetBind(oPC, nToken, "window_geometry"); + float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x")); + float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y")); + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) jLocations = JsonObject(); + json jWindow = JsonObjectGet(jLocations, sWindowID); + if(JsonGetType(jWindow) == JSON_TYPE_NULL) jWindow = JsonObject(); + jWindow = JsonObjectSet(jWindow, "x", JsonFloat(fX)); + jWindow = JsonObjectSet(jWindow, "y", JsonFloat(fY)); + jLocations = JsonObjectSet(jLocations, sWindowID, jWindow); + //SendMessageToPC(oPC, "0e_nui, 52, sAssociateType: " + sAssociateType + + // " sWindowID: " + sWindowID + + // " jLocations: " + JsonDump(jLocations, 1)); + ai_SetAssociateDbJson(oPC, sAssociateType, "locations", jLocations); +} +void ai_ToggleAssociateWidgetOnOff(object oPC, int nToken, object oAssociate, string sAssociateType) +{ + string sText, sText2, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int bWidget = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType, bWidget); + NuiSetBind(oPC, nToken, "btn_widget_onoff", JsonBool (!bWidget)); + if(bWidget) + { + sText = "on"; + sText2 = "Off"; + IsWindowClosed(oPC, sAssociateType + AI_WIDGET_NUI); + } + else + { + sText = "off"; + sText2 = "On"; + ai_CreateWidgetNUI(oPC, oAssociate); + } + NuiSetBind(oPC, nToken, "btn_widget_onoff_label", JsonString("Widget " + sText2)); + NuiSetBind(oPC, nToken, "btn_widget_onoff_tooltip", JsonString(" Turn " + sName + " widget " + sText)); +} +void main() +{ + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + string sWndId = NuiGetWindowId(oPC, nToken); + //SendMessageToPC(oPC, "0e_nui , 64 sWndId: " + sWndId + " sEvent: " + sEvent + " sElem: " + sElem + + // " nToken: " + IntToString(nToken) + " nIndex: " + IntToString(nIndex) + + // " oPC: " + GetName(oPC)); + // Get if the menu has an associate attached. + json jData = NuiGetUserData(oPC, nToken); + object oAssociate = StringToObject(JsonGetString(JsonArrayGet(jData, 0))); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + if(!ai_GetIsCharacter(oAssociate) && !GetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE") && + (oAssociate == OBJECT_INVALID || GetMaster(oAssociate) != oPC)) + { + ai_SendMessages("This creature is no longer in your party!", AI_COLOR_RED, oPC); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + return; + } + if(sAssociateType == "") return; + //************************************************************************** + // Watch to see if the window moves and save. + if(sElem == "window_geometry" && sEvent == "watch") + { + if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + // If the widget is locked then don't save. + if(sWndId == sAssociateType + AI_WIDGET_NUI && + ai_GetWidgetButton(oPC, BTN_WIDGET_LOCK, oAssociate, sAssociateType)) return; + ai_SaveWindowLocation(oPC, nToken, sAssociateType, sWndId); + return; + } + //************************************************************************** + // Main AI events. + if(sWndId == AI_MAIN_NUI) + { + //if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + if(sEvent == "click") + { + if(sElem == "btn_plugin_manager") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreatePluginNUI(oPC); + } + else if(sElem == "btn_action_ghost") + { + // We set ghost mode differently for each AI. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + if(GetLocalInt(oPC, sGhostModeVarname)) + { + DeleteLocalInt(oPC, sGhostModeVarname); + ai_SendMessages("Action Ghost mode is turned off when using commands.", AI_COLOR_YELLOW, oPC); + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + } + else + { + SetLocalInt(oPC, sGhostModeVarname, TRUE); + ai_SendMessages("Action Ghost mode is turned on when using commands.", AI_COLOR_YELLOW, oPC); + } + } + else + { + if(ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST)) + { + ai_SetAIMode(oPC, AI_MODE_ACTION_GHOST, FALSE); + ai_SendMessages("Action Ghost mode is turned off when using commands.", AI_COLOR_YELLOW, oPC); + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID && !ai_GetAIMode(oAssociate, AI_MODE_GHOST)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID && !ai_GetAIMode(oAssociate, AI_MODE_GHOST)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + } + else + { + ai_SetAIMode(oPC, AI_MODE_ACTION_GHOST); + ai_SendMessages("Action Ghost mode is turned on when using commands.", AI_COLOR_YELLOW, oPC); + } + aiSaveAssociateModesToDb(oPC, oPC); + } + } + else if(sElem == "btn_toggle_assoc_widget") + { + int bWidgetOff = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc"); + string sAssocType; + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc", bWidgetOff); + object oAssoc = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff); + if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI); + else ai_CreateWidgetNUI(oPC, oAssoc); + } + oAssoc = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff); + if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI); + else ai_CreateWidgetNUI(oPC, oAssoc); + } + oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff); + if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI); + else ai_CreateWidgetNUI(oPC, oAssoc); + } + oAssoc = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff); + if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI); + else ai_CreateWidgetNUI(oPC, oAssoc); + } + int nIndex; + object oHenchman; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oHenchman != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oHenchman); + ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oHenchman, sAssocType, bWidgetOff); + if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI); + else ai_CreateWidgetNUI(oPC, oHenchman); + } + } + } + else if(sElem == "btn_effect_icon") + { + if(ai_GetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT)) + { + ai_SetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT, FALSE); + ai_SendMessages("All effect icons will be reported in a menu at the top of the screen.", AI_COLOR_YELLOW, oPC); + } + else + { + ai_SetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT); + ai_SendMessages("All effect icons will be reported in the chat screen.", AI_COLOR_YELLOW, oPC); + } + aiSaveAssociateModesToDb(oPC, oPC); + } + if(sElem == "btn_default_xp") + { + int nDefaultXP = GetLocalInt(GetModule(), AI_RULE_DEFAULT_XP_SCALE); + SetModuleXPScale(nDefaultXP); + NuiSetBind(oPC, nToken, "txt_xp_scale", JsonString(IntToString(nDefaultXP))); + } + } + if(sEvent == "watch") + { + string sPreElem = GetStringLeft(sElem, 4); + if(sPreElem == "txt_") + { + object oModule = GetModule(); + json jRules = ai_GetCampaignDbJson("rules"); + string sText = JsonGetString(NuiGetBind(oPC, nToken, sElem)); + if(sElem == "txt_max_henchman") + { + int nMaxHenchmen = StringToInt(sText); + if(nMaxHenchmen < 1) nMaxHenchmen = 1; + if(nMaxHenchmen > 12) + { + nMaxHenchmen = 12; + ai_SendMessages("The maximum henchmen for this mod is 12!", AI_COLOR_RED, oPC); + } + SetMaxHenchmen(nMaxHenchmen); + SetLocalInt(oModule, AI_RULE_MAX_HENCHMAN, nMaxHenchmen); + jRules = JsonObjectSet(jRules, AI_RULE_MAX_HENCHMAN, JsonInt(nMaxHenchmen)); + ai_SendMessages("Maximum henchmen has been changed to " + IntToString(nMaxHenchmen), AI_COLOR_YELLOW, oPC); + } + else if(sElem == "txt_ai_difficulty") + { + int nChance = StringToInt(sText); + if(nChance < 0) nChance = 0; + else if(nChance > 100) nChance = 100; + SetLocalInt(oModule, AI_RULE_AI_DIFFICULTY, nChance); + jRules = JsonObjectSet(jRules, AI_RULE_AI_DIFFICULTY, JsonInt(nChance)); + } + else if(sElem == "txt_perception_distance") + { + float fDistance = StringToFloat(sText); + if(fDistance < 10.0) fDistance = 10.0; + else if(fDistance > 60.0) fDistance = 60.0; + SetLocalFloat(oModule, AI_RULE_PERCEPTION_DISTANCE, fDistance); + jRules = JsonObjectSet(jRules, AI_RULE_PERCEPTION_DISTANCE, JsonFloat(fDistance)); + } + else if(sElem == "txt_inc_enc") + { + float fNumber = StringToFloat(sText); + if(fNumber < 0.0) fNumber = 0.0; + else if(fNumber > 9.0) fNumber = 9.0; + SetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS, fNumber); + jRules = JsonObjectSet(jRules, AI_INCREASE_ENC_MONSTERS, JsonFloat(fNumber)); + } + else if(sElem == "txt_inc_hp") + { + int nNumber = StringToInt(sText); + if(nNumber < 0) nNumber = 0; + else if(nNumber > 100) nNumber = 100; + SetLocalInt(oModule, AI_INCREASE_MONSTERS_HP, nNumber); + jRules = JsonObjectSet(jRules, AI_INCREASE_MONSTERS_HP, JsonInt(nNumber)); + } + else if(sElem == "txt_wander_distance") + { + float fDistance = StringToFloat(sText); + if(fDistance < 0.0) fDistance = 0.0; + else if(fDistance > 99.0) fDistance = 99.0; + SetLocalFloat(oModule, AI_RULE_WANDER_DISTANCE, fDistance); + jRules = JsonObjectSet(jRules, AI_RULE_WANDER_DISTANCE, JsonFloat(fDistance)); + } + else if(sElem == "txt_xp_scale") + { + int nNumber = StringToInt(sText); + if(nNumber < 0) nNumber = 0; + else if(nNumber > 200) nNumber = 200; + SetModuleXPScale(nNumber); + return; + } + ai_SetCampaignDbJson("rules", jRules); + } + else if(sPreElem == "chbx") + { + object oModule = GetModule(); + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + json jRules = ai_GetCampaignDbJson("rules"); + if(sElem == "chbx_moral_check") + { + SetLocalInt(oModule, AI_RULE_MORAL_CHECKS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_MORAL_CHECKS, JsonInt(bCheck)); + } + else if(sElem == "chbx_buff_monsters_check") + { + SetLocalInt(oModule, AI_RULE_BUFF_MONSTERS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_BUFF_MONSTERS, JsonInt(bCheck)); + } + else if(sElem == "chbx_buff_summons_check") + { + SetLocalInt(oModule, AI_RULE_PRESUMMON, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PRESUMMON, JsonInt(bCheck)); + } + else if(sElem == "chbx_ambush_monsters_check") + { + SetLocalInt(oModule, AI_RULE_AMBUSH, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_AMBUSH, JsonInt(bCheck)); + } + else if(sElem == "chbx_companions_check") + { + SetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_SUMMON_COMPANIONS, JsonInt(bCheck)); + } + else if(sElem == "chbx_advanced_movement_check") + { + SetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ADVANCED_MOVEMENT, JsonInt(bCheck)); + } + else if(sElem == "chbx_ilr_check") + { + SetLocalInt(oModule, AI_RULE_ILR, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ILR, JsonInt(bCheck)); + } + else if(sElem == "chbx_umd_check") + { + SetLocalInt(oModule, AI_RULE_ALLOW_UMD, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ALLOW_UMD, JsonInt(bCheck)); + } + else if(sElem == "chbx_use_healingkits_check") + { + SetLocalInt(oModule, AI_RULE_HEALERSKITS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_HEALERSKITS, JsonInt(bCheck)); + } + else if(sElem == "chbx_perm_assoc_check") + { + SetLocalInt(oModule, AI_RULE_PERM_ASSOC, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PERM_ASSOC, JsonInt(bCheck)); + } + else if(sElem == "chbx_corpses_stay_check") + { + SetLocalInt(oModule, AI_RULE_CORPSES_STAY, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_CORPSES_STAY, JsonInt(bCheck)); + } + else if(sElem == "chbx_wander_check") + { + SetLocalInt(oModule, AI_RULE_WANDER, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_WANDER, JsonInt(bCheck)); + NuiSetBind(oPC, nToken, "txt_wander_distance_event", JsonBool(bCheck)); + } + else if(sElem == "chbx_open_doors_check") + { + SetLocalInt(oModule, AI_RULE_OPEN_DOORS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_OPEN_DOORS, JsonInt(bCheck)); + } + else if(sElem == "chbx_party_scale_check") + { + if(bCheck) + { + SetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP, GetModuleXPScale()); + ai_CheckXPPartyScale(oPC); + } + else + { + SetModuleXPScale(GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE)); + } + SetLocalInt(oModule, AI_RULE_PARTY_SCALE, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PARTY_SCALE, JsonInt(bCheck)); + string sText = IntToString(GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP)); + NuiSetBind(oPC, nToken, "chbx_party_scale_tooltip", JsonString(" PEPS adjusts your XP based on party size from (" + sText + ").")); + sText = IntToString(GetModuleXPScale()); + NuiSetBind(oPC, nToken, "txt_xp_scale", JsonString(sText)); + } + else if(sElem == "chbx_darkness_check") + { + if(bCheck) + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_DARKNESS); + jRules = ai_AddRestrictedSpell(jRules, 159); + jRules = ai_AddRestrictedSpell(jRules, SPELLABILITY_AS_DARKNESS); + jRules = ai_AddRestrictedSpell(jRules, 688); // WildShape_Darkness + } + else + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_DARKNESS, FALSE); + jRules = ai_AddRestrictedSpell(jRules, 159, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELLABILITY_AS_DARKNESS, FALSE); + jRules = ai_AddRestrictedSpell(jRules, 688, FALSE); // WildShape_Darkness + } + } + else if(sElem == "chbx_dispels_check") + { + if(bCheck) + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_LESSER_DISPEL); + jRules = ai_AddRestrictedSpell(jRules, SPELL_DISPEL_MAGIC); + jRules = ai_AddRestrictedSpell(jRules, SPELL_GREATER_DISPELLING); + jRules = ai_AddRestrictedSpell(jRules, SPELL_MORDENKAINENS_DISJUNCTION); + } + else + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_LESSER_DISPEL, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_DISPEL_MAGIC, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_GREATER_DISPELLING, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_MORDENKAINENS_DISJUNCTION, FALSE); + } + } + else if(sElem == "chbx_timestop_check") + { + if(bCheck) jRules = ai_AddRestrictedSpell(jRules, SPELL_TIME_STOP); + else jRules = ai_AddRestrictedSpell(jRules, SPELL_TIME_STOP, FALSE); + } + ai_SetCampaignDbJson("rules", jRules); + } + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + // Follow range is only changed on non-pc's + if(sElem == "lbl_perc_dist") ai_RulePercDistInc(oPC, GetModule(), 1, nToken); + } + else if(nMouseScroll == -1.0) // Scroll down + { + // Follow range is only changed on non-pc's + if(sElem == "lbl_perc_dist") ai_RulePercDistInc(oPC, GetModule(), -1, nToken); + } + } + return; + } + //************************************************************************** + // Associate Command events. + if(sWndId == sAssociateType + AI_COMMAND_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_ai_menu") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreateAssociateAINUI(oPC, oAssociate); + } + if(sElem == "btn_vertical_widget") + { + int bVertical = !ai_GetWidgetButton(oPC, BTN_WIDGET_VERTICAL, oAssociate, sAssociateType); + ai_SetWidgetButton(oPC, BTN_WIDGET_VERTICAL, oAssociate, sAssociateType, bVertical); + if(oPC == oAssociate || + (oPC != oAssociate && !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType))) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + } + else if(sElem == "btn_main_menu") + { + if(ai_GetIsCharacter(oAssociate)) ai_CreateAIMainNUI(oPC); + } + else if(sElem == "btn_widget_onoff") + { + ai_ToggleAssociateWidgetOnOff(oPC, nToken, oAssociate, sAssociateType); + } + else if(sElem == "btn_widget_lock") + { + int bLocked = !ai_GetWidgetButton(oPC, BTN_WIDGET_LOCK, oAssociate, sAssociateType); + ai_SetWidgetButton(oPC, BTN_WIDGET_LOCK, oAssociate, sAssociateType, bLocked); + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + } + else if(sElem == "btn_copy_settings") + { + ai_CreateCopySettingsNUI(oPC, oAssociate); + } + else if(sElem == "btn_cmd_action") ai_Action(oPC, oAssociate); + else if(sElem == "btn_cmd_guard") ai_DoCommand(oPC, oAssociate, 1); + else if(sElem == "btn_cmd_hold") ai_DoCommand(oPC, oAssociate, 3); + else if(sElem == "btn_cmd_search") ai_DoCommand(oPC, oAssociate, 5); + else if(sElem == "btn_cmd_stealth") ai_DoCommand(oPC, oAssociate, 6); + else if(sElem == "btn_cmd_attack") ai_DoCommand(oPC, oAssociate, 4); + else if(sElem == "btn_cmd_follow") ai_DoCommand(oPC, oAssociate, 2); + else if(sElem == "btn_follow_target") ai_FollowTarget(oPC, oAssociate); + else if(sElem == "btn_cmd_ai_script") ai_AIScript(oPC, oAssociate, sAssociateType, nToken); + else if(sElem == "btn_cmd_place_trap") ai_HavePCPlaceTrap(oPC, oAssociate); + else if(sElem == "btn_quick_widget") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate); + } + else if(sElem == "btn_spell_memorize") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreateSpellMemorizationNUI(oPC, oAssociate); + } + else if(sElem == "btn_spell_known") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreateSpellKnownNUI(oPC, oAssociate); + } + else if(sElem == "btn_buff_short") + { + ai_Buff_Button(oPC, oAssociate, 2, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_long") + { + ai_Buff_Button(oPC, oAssociate, 3, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_all") + { + ai_Buff_Button(oPC, oAssociate, 1, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_rest") ai_Buff_Button(oPC, oAssociate, 0, sAssociateType); + else if(sElem == "btn_jump_to") ai_JumpToPC(oPC, oAssociate); + else if(sElem == "btn_ghost_mode") ai_GhostMode(oPC, oAssociate, nToken, sAssociateType); + else if(sElem == "btn_camera") ai_ChangeCameraView(oPC, oAssociate); + else if(sElem == "btn_inventory") ai_OpenInventory(oAssociate, oPC); + else if(sElem == "btn_familiar_name") ai_SetCompanionName(oPC, oAssociate, nToken, ASSOCIATE_TYPE_FAMILIAR); + else if(sElem == "btn_companion_name") ai_SetCompanionName(oPC, oAssociate, nToken, ASSOCIATE_TYPE_ANIMALCOMPANION); + else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oPC, sElem); + } + else if(sEvent == "watch") + { + if(sElem == "txt_familiar_name") + { + string sName = JsonGetString(NuiGetBind(oPC, nToken, sElem)); + if(sName != "") NuiSetBind(oPC, nToken, "btn_familiar_name_event", JsonBool(TRUE)); + else NuiSetBind(oPC, nToken, "btn_familiar_name_event", JsonBool(FALSE)); + } + if(GetStringLeft(sElem, 12) == "chbx_plugin_" && GetStringRight(sElem, 6) == "_check") + { + int nIndex = StringToInt(GetSubString(sElem, 12, 1)); + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + json jPlugin = JsonArrayGet(jPlugins, nIndex); + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + else if(sElem == "chbx_buff_rest_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_BUFF_REST, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_action_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_guard_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_GUARD, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_hold_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_HOLD, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_search_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_SEARCH, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_stealth_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_STEALTH, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_attack_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_ATTACK, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_follow_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_FOLLOW, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_ai_script_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_AI_SCRIPT, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cmd_place_trap_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_PLACE_TRAP, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_quick_widget_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_SPELL_WIDGET, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_follow_target_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_FOLLOW_TARGET, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_buff_short_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_BUFF_SHORT, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_buff_long_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_BUFF_LONG, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_buff_all_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_BUFF_ALL, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_jump_to_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_JUMP_TO, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_ghost_mode_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_GHOST_MODE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_camera_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_inventory_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_familiar_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_FAMILIAR, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_companion_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "cmb_familiar_selected") ai_SetCompanionType(oPC, oAssociate, nToken, ASSOCIATE_TYPE_FAMILIAR); + else if(sElem == "cmb_companion_selected") ai_SetCompanionType(oPC, oAssociate, nToken, ASSOCIATE_TYPE_ANIMALCOMPANION); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + // Follow range is only changed on non-pc's + if(sElem == "btn_cmd_follow" && + oPC != oAssociate) ai_FollowIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_follow_target") ai_FollowIncrement(oPC, oAssociate, 1.0, sAssociateType); + } + else if(nMouseScroll == -1.0) // Scroll down + { + // Follow range is only changed on non-pc's + if(sElem == "btn_cmd_follow" && + oPC != oAssociate) ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_follow_target") ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + } + } + return; + } + //************************************************************************** + // Associate AI events. + if(sWndId == sAssociateType + AI_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_command_menu") + { + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_CreateAssociateCommandNUI(oPC, oAssociate); + } + if(sElem == "btn_main_menu") + { + if(ai_GetIsCharacter(oAssociate)) ai_CreateAIMainNUI(oPC); + } + else if(sElem == "btn_loot_filter") + { + ai_CreateLootFilterNUI(oPC, oAssociate); + } + else if(sElem == "btn_ai") + { + if(GetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT) == "xx_pc_1_hb") ai_TurnOff(oPC, oAssociate, sAssociateType); + else ai_TurnOn(oPC, oAssociate, sAssociateType); + } + else if(sElem == "btn_quiet") ai_ReduceSpeech(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ranged") AssignCommand(oAssociate, ai_Ranged(oPC, oAssociate, sAssociateType)); + else if(sElem == "btn_equip_weapon") ai_EquipWeapons(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_search") ai_Search(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_stealth") ai_Stealth(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoor(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_traps") ai_Traps(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_pick_locks") ai_Locks(oPC, oAssociate, sAssociateType, 1); + else if(sElem == "btn_bash_locks") ai_Locks(oPC, oAssociate, sAssociateType, 2); + else if(sElem == "btn_magic") ai_UseMagic(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_magic_items") ai_UseMagicItems(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_def_magic") ai_UseOffensiveMagic(oPC, oAssociate, TRUE, FALSE, sAssociateType); + else if(sElem == "btn_off_magic") ai_UseOffensiveMagic(oPC, oAssociate, FALSE, TRUE, sAssociateType); + else if(sElem == "btn_spontaneous") ai_Spontaneous(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_heals_onoff") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 1); + else if(sElem == "btn_healp_onoff") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 2); + else if(sElem == "btn_cure_onoff") ai_Cure_OnOff(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_loot") ai_Loot(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ignore_assoc") ai_Ignore_Associates(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ignore_traps") ai_Ignore_Traps(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_perc_range") ai_Perc_Range(oPC, oAssociate, nToken, sAssociateType); + else if(sElem == "btn_ai_script") ai_SaveAIScript(oPC, oAssociate, nToken); + } + else if(sEvent == "watch") + { + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + if(sElem == "chbx_ai_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_FOR_PC, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_quiet_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_REDUCE_SPEECH, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_ranged_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_USE_RANGED, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_equip_weapon_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_STOP_WEAPON_EQUIP, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_search_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_USE_SEARCH, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_stealth_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_USE_STEALTH, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_open_door_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_OPEN_DOORS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_traps_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_REMOVE_TRAPS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_pick_locks_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_PICK_LOCKS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_bash_locks_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_BASH_LOCKS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_magic_level_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_MAGIC_LEVEL, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_spontaneous_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_NO_SPONTANEOUS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_magic_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_NO_MAGIC_USE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_magic_items_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_NO_MAGIC_ITEM_USE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_def_magic_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_DEF_MAGIC_USE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_off_magic_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_OFF_MAGIC_USE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_heal_out_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_HEAL_OUT, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_heal_in_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_HEAL_IN, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_heals_onoff_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_STOP_SELF_HEALING, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_healp_onoff_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_STOP_PARTY_HEALING, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_cure_onoff_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_STOP_CURE_SPELLS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_loot_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_LOOT, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_ignore_assoc_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_IGNORE_ASSOCIATES, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_ignore_traps_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_IGNORE_TRAPS, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "chbx_perc_range_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_PERC_RANGE, oAssociate, sAssociateType, nToken, sElem); + else if(sElem == "cmb_ai_script_selected") ai_SetAIScript(oPC, oAssociate, nToken); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + if(sElem == "btn_magic_level") ai_MagicIncrement(oPC, oAssociate, 1, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoorIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_traps") ai_TrapRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_pick_locks") ai_LockRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_bash_locks") ai_LockRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_heal_out") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_heal_in") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_loot") ai_LootRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_perc_range") ai_PercRangeIncrement(oPC, oAssociate, 1, sAssociateType, nToken); + } + else if(nMouseScroll == -1.0) // Scroll down + { + if(sElem == "btn_magic_level") ai_MagicIncrement(oPC, oAssociate, -1, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoorIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_traps") ai_TrapRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_pick_locks") ai_LockRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_bash_locks") ai_LockRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_heal_out") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_heal_in") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_loot") ai_LootRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_perc_range") ai_PercRangeIncrement(oPC, oAssociate, -1, sAssociateType, nToken); + } + } + return; + } + //************************************************************************** + // Associate Widget events. + if(sWndId == sAssociateType + AI_WIDGET_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_open_main") + { + // If all the Command buttons are blocked then don't load the menu. + if(GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028) + { + if(IsWindowClosed(oPC, sAssociateType + AI_COMMAND_NUI)) + { + ai_CreateAssociateCommandNUI(oPC, oAssociate); + } + IsWindowClosed(oPC, sAssociateType + AI_NUI); + IsWindowClosed(oPC, sAssociateType + AI_LOOTFILTER_NUI); + IsWindowClosed(oPC, sAssociateType + AI_COPY_NUI); + IsWindowClosed(oPC, sAssociateType + AI_QUICK_WIDGET_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_MEMORIZE_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_KNOWN_NUI); + if(ai_GetIsCharacter(oAssociate)) + { + IsWindowClosed(oPC, AI_MAIN_NUI); + IsWindowClosed(oPC, AI_PLUGIN_NUI); + } + } + } + else if(sElem == "btn_ai") + { + if(GetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT) == "xx_pc_1_hb") + { + ai_TurnOff(oPC, oAssociate, sAssociateType); + } + else ai_TurnOn(oPC, oAssociate, sAssociateType); + } + else if(sElem == "btn_quiet") ai_ReduceSpeech(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ranged") AssignCommand(oAssociate, ai_Ranged(oPC, oAssociate, sAssociateType)); + else if(sElem == "btn_equip_weapon") ai_EquipWeapons(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_search") ai_Search(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_stealth") ai_Stealth(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoor(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_traps") ai_Traps(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_pick_locks") ai_Locks(oPC, oAssociate, sAssociateType, 1); + else if(sElem == "btn_bash_locks") ai_Locks(oPC, oAssociate, sAssociateType, 2); + else if(sElem == "btn_magic_minus") ai_MagicIncrement(oPC, oAssociate, -1, sAssociateType); + else if(sElem == "btn_magic_plus") ai_MagicIncrement(oPC, oAssociate, 1, sAssociateType); + else if(sElem == "btn_magic") ai_UseMagic(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_magic_items") ai_UseMagicItems(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_def_magic") ai_UseOffensiveMagic(oPC, oAssociate, TRUE, FALSE, sAssociateType); + else if(sElem == "btn_off_magic") ai_UseOffensiveMagic(oPC, oAssociate, FALSE, TRUE, sAssociateType); + else if(sElem == "btn_cure_onoff") ai_Cure_OnOff(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_loot") ai_Loot(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ignore_assoc") ai_Ignore_Associates(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_ignore_traps") ai_Ignore_Traps(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_perc_range") ai_Perc_Range(oPC, oAssociate, nToken, sAssociateType); + else if(sElem == "btn_spontaneous") ai_Spontaneous(oPC, oAssociate, sAssociateType); + else if(sElem == "btn_buff_short") + { + ai_Buff_Button(oPC, oAssociate, 2, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_long") + { + ai_Buff_Button(oPC, oAssociate, 3, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_all") + { + ai_Buff_Button(oPC, oAssociate, 1, sAssociateType); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sElem == "btn_buff_rest") ai_Buff_Button(oPC, oAssociate, 0, sAssociateType); + else if(sElem == "btn_jump_to") ai_JumpToPC(oPC, oAssociate); + else if(sElem == "btn_ghost_mode") ai_GhostMode(oPC, oAssociate, nToken, sAssociateType); + else if(sElem == "btn_camera") ai_ChangeCameraView(oPC, oAssociate); + else if(sElem == "btn_inventory") ai_OpenInventory(oAssociate, oPC); + else if(sElem == "btn_familiar") + { + if(GetHasFeat(FEAT_SUMMON_FAMILIAR, oAssociate)) + { + DecrementRemainingFeatUses(oAssociate, FEAT_SUMMON_FAMILIAR); + SummonFamiliar(oAssociate); + } + } + else if(sElem == "btn_companion") + { + if(GetHasFeat(FEAT_ANIMAL_COMPANION, oAssociate)) + { + DecrementRemainingFeatUses(oAssociate, FEAT_ANIMAL_COMPANION); + SummonAnimalCompanion(oAssociate); + } + } + else if(sElem == "btn_heals_onoff") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 1); + else if(sElem == "btn_healp_onoff") ai_Heal_OnOff(oPC, oAssociate, sAssociateType, 2); + else if(sElem == "btn_cmd_action") ai_Action(oPC, oAssociate); + else if(sElem == "btn_cmd_guard") ai_DoCommand(oPC, oAssociate, 1); + else if(sElem == "btn_cmd_hold") ai_DoCommand(oPC, oAssociate, 3); + else if(sElem == "btn_cmd_search") ai_DoCommand(oPC, oAssociate, 5); + else if(sElem == "btn_cmd_stealth") ai_DoCommand(oPC, oAssociate, 6); + else if(sElem == "btn_cmd_attack") ai_DoCommand(oPC, oAssociate, 4); + else if(sElem == "btn_cmd_follow") ai_DoCommand(oPC, oAssociate, 2); + else if(sElem == "btn_cmd_ai_script") ai_AIScript(oPC, oAssociate, sAssociateType, nToken); + else if(sElem == "btn_cmd_place_trap") ai_HavePCPlaceTrap(oPC, oAssociate); + else if(sElem == "btn_follow_target") ai_FollowTarget(oPC, oAssociate); + else if(sElem == "btn_update_widget") ai_UpdateAssociateWidget(oPC, oAssociate); + else if(GetStringLeft(sElem, 15) == "btn_exe_plugin_") ai_Plugin_Execute(oPC, sElem); + else if(GetStringLeft(sElem, 11) == "btn_widget_") ai_SelectWidgetSpellTarget(oPC, oAssociate, sElem); + } + if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + if(sElem == "btn_cmd_follow" && + oPC != oAssociate) ai_FollowIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_follow_target") ai_FollowIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_magic_level") ai_MagicIncrement(oPC, oAssociate, 1, sAssociateType); + else if(sElem == "btn_pick_locks") ai_LockRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_bash_locks") ai_LockRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_traps") ai_TrapRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoorIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_heal_out") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_heal_in") ai_Heal_Button(oPC, oAssociate, 5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_loot") ai_LootRangeIncrement(oPC, oAssociate, 1.0, sAssociateType); + else if(sElem == "btn_perc_range") ai_PercRangeIncrement(oPC, oAssociate, 1, sAssociateType, -1); + } + if(nMouseScroll == -1.0) // Scroll down + { + if(sElem == "btn_cmd_follow" && + oPC != oAssociate) ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_follow_target") ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_magic_plus") ai_MagicIncrement(oPC, oAssociate, -1, sAssociateType); + if(sElem == "btn_magic_level") ai_MagicIncrement(oPC, oAssociate, -1, sAssociateType); + else if(sElem == "btn_pick_locks") ai_LockRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_bash_locks") ai_LockRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_traps") ai_TrapRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_open_door") ai_OpenDoorIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_heal_out") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_OUT_OF_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_heal_in") ai_Heal_Button(oPC, oAssociate, -5, AI_HEAL_IN_COMBAT_LIMIT, sAssociateType); + else if(sElem == "btn_loot") ai_LootRangeIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(sElem == "btn_perc_range") ai_PercRangeIncrement(oPC, oAssociate, -1, sAssociateType, -1); + } + } + if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + AssignCommand(oPC, PlaySound("gui_button")); + if(sElem == "btn_open_main") + { + // If all the AI buttons are blocked then don't load the menu. + if(GetLocalInt(GetModule(), sDMAIAccessVarname) != 203423743) + { + if(IsWindowClosed(oPC, sAssociateType + AI_NUI)) + { + ai_CreateAssociateAINUI(oPC, oAssociate); + } + } + IsWindowClosed(oPC, sAssociateType + AI_COMMAND_NUI); + IsWindowClosed(oPC, sAssociateType + AI_LOOTFILTER_NUI); + IsWindowClosed(oPC, sAssociateType + AI_COPY_NUI); + IsWindowClosed(oPC, sAssociateType + AI_QUICK_WIDGET_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_MEMORIZE_NUI); + IsWindowClosed(oPC, sAssociateType + AI_SPELL_KNOWN_NUI); + if(ai_GetIsCharacter(oAssociate)) + { + IsWindowClosed(oPC, AI_MAIN_NUI); + IsWindowClosed(oPC, AI_PLUGIN_NUI); + } + } + else if(sElem == "btn_follow_range") ai_FollowIncrement(oPC, oAssociate, -1.0, sAssociateType); + else if(GetStringLeft(sElem, 11) == "btn_widget_") + { + if(GetStringLength(sElem) == 13) nIndex = StringToInt(GetStringRight(sElem, 2)); + else nIndex = StringToInt(GetStringRight(sElem, 1)); + json jAIData = ai_GetAssociateDbJson(oPC, ai_GetAssociateType(oPC, oAssociate), "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jSpell = JsonArrayGet(jWidget, nIndex); + ai_CreateDescriptionNUI(oPC, jSpell); + } + } + } + return; + } + //************************************************************************** + // Associate Loot events. + if(sWndId == sAssociateType + AI_LOOTFILTER_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_set_all") + { + SetLocalInt(oPC, "AI_BLOCK_CHECKS", TRUE); + SetLocalInt(oAssociate, sLootFilterVarname, 65535); + int nIndex; + for(nIndex = 2; nIndex < 20; nIndex++) + { + NuiSetBind(oPC, nToken, "chbx_" + IntToString(nIndex) + "_check", JsonBool (TRUE)); + } + json jLootFilter = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + jLootFilter = JsonArraySet(jLootFilter, 1, JsonInt(65535)); + ai_SetAssociateDbJson(oPC, sAssociateType, "lootfilters", jLootFilter); + DelayCommand(1.0, DeleteLocalInt(oPC, "AI_BLOCK_CHECKS")); + } + else if(sElem == "btn_clear_all") + { + SetLocalInt(oPC, "AI_BLOCK_CHECKS", TRUE); + SetLocalInt(oAssociate, sLootFilterVarname, 0); + int nIndex; + for(nIndex = 2; nIndex < 20; nIndex++) + { + NuiSetBind(oPC, nToken, "chbx_" + IntToString(nIndex) + "_check", JsonBool (FALSE)); + } + json jLootFilter = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + jLootFilter = JsonArraySet(jLootFilter, 1, JsonInt(0)); + ai_SetAssociateDbJson(oPC, sAssociateType, "lootfilters", jLootFilter); + DelayCommand(1.0, DeleteLocalInt(oPC, "AI_BLOCK_CHECKS")); + } + } + else if(sEvent == "watch") + { + if(GetStringLeft(sElem, 5) == "chbx_") + { + if(GetLocalInt(oPC, "AI_BLOCK_CHECKS")) return; + if(sElem == "chbx_give_loot_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_GIVE_TO_PC, nToken, sElem); + else if(sElem == "chbx_2_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_PLOT, nToken, sElem); + else if(sElem == "chbx_3_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_ARMOR, nToken, sElem); + else if(sElem == "chbx_4_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_BELTS, nToken, sElem); + else if(sElem == "chbx_5_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_BOOTS, nToken, sElem); + else if(sElem == "chbx_6_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_CLOAKS, nToken, sElem); + else if(sElem == "chbx_7_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_GEMS, nToken, sElem); + else if(sElem == "chbx_8_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_GLOVES, nToken, sElem); + else if(sElem == "chbx_9_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_HEADGEAR, nToken, sElem); + else if(sElem == "chbx_10_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_JEWELRY, nToken, sElem); + else if(sElem == "chbx_11_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_MISC, nToken, sElem); + else if(sElem == "chbx_12_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_POTIONS, nToken, sElem); + else if(sElem == "chbx_13_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_SCROLLS, nToken, sElem); + else if(sElem == "chbx_14_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_SHIELDS, nToken, sElem); + else if(sElem == "chbx_15_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_WANDS_RODS_STAVES, nToken, sElem); + else if(sElem == "chbx_16_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_WEAPONS, nToken, sElem); + else if(sElem == "chbx_17_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_ARROWS, nToken, sElem); + else if(sElem == "chbx_18_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_BOLTS, nToken, sElem); + else if(sElem == "chbx_19_check") ai_SetLootFilterToCheckbox(oPC, oAssociate, AI_LOOT_BULLETS, nToken, sElem); + json jLootFilter = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + int nLootFilter = GetLocalInt(oAssociate, sLootFilterVarname); + jLootFilter = JsonArraySet(jLootFilter, 1, JsonInt(nLootFilter)); + ai_SetAssociateDbJson(oPC, sAssociateType, "lootfilters", jLootFilter); + } + else if(GetStringLeft(sElem, 4) == "txt_") + { + if(sElem == "txt_max_weight") + { + int nMaxWeight = StringToInt(JsonGetString(NuiGetBind(oPC, nToken, sElem))); + if(nMaxWeight > 1000) nMaxWeight = 1000; + if(nMaxWeight < 1) nMaxWeight = 1; + SetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT, nMaxWeight); + json jLootFilter = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + jLootFilter = JsonArraySet(jLootFilter, 0, JsonInt(nMaxWeight)); + ai_SetAssociateDbJson(oPC, sAssociateType, "lootfilters", jLootFilter); + return; + } + if(GetStringLeft(sElem, 9) == "txt_gold_") + { + int nAmount = StringToInt(JsonGetString(NuiGetBind(oPC, nToken, sElem))); + int nIndex; + if(GetStringLength(sElem) == 11) nIndex = StringToInt(GetStringRight(sElem, 2)); + else nIndex = StringToInt(GetStringRight(sElem, 1)); + SetLocalInt(oAssociate, AI_MIN_GOLD_ + IntToString(nIndex), nAmount); + json jLootFilter = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + jLootFilter = JsonArraySet(jLootFilter, nIndex, JsonInt(nAmount)); + ai_SetAssociateDbJson(oPC, sAssociateType, "lootfilters", jLootFilter); + } + } + } + return; + } + //************************************************************************** + // Associate Paste events. + if(sWndId == sAssociateType + AI_COPY_NUI) + { + if(sEvent == "click") + { + int nIndex, nAssociateType = GetAssociateType(oAssociate); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + object oAssoc; + string sAssocType; + json jModes = ai_GetAssociateDbJson(oPC, sAssociateType, "modes"); + json jButtons = ai_GetAssociateDbJson(oPC, sAssociateType, "buttons"); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jLootFilters = ai_GetAssociateDbJson(oPC, sAssociateType, "lootfilters"); + string sCombatScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + string sDefaultScript = GetLocalString(oAssociate, AI_DEFAULT_SCRIPT); + if(sElem == "btn_paste_all") + { + // Check all non-henchman associates. + for(nIndex = 2; nIndex < 6; nIndex++) + { + if(nAssociateType != nIndex) + { + oAssoc = GetAssociate(nIndex, oPC); + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetAssociateDbJson(oPC, sAssocType, "modes", jModes); + ai_SetAssociateDbJson(oPC, sAssocType, "buttons", jButtons); + ai_SetAssociateDbJson(oPC, sAssocType, "aidata", jAIData); + ai_SetAssociateDbJson(oPC, sAssocType, "lootfilters", jLootFilters); + SetLocalString(oAssoc, AI_COMBAT_SCRIPT, sCombatScript); + SetLocalString(oAssoc, AI_DEFAULT_SCRIPT, sDefaultScript); + if(oAssoc != OBJECT_INVALID) + { + // Clear the creatures Perception distance so we can + // repopulate the local variables. + SetLocalFloat(oAssoc, AI_ASSOC_PERCEPTION_DISTANCE, 0.0); + ai_CheckAssociateData(oPC, oAssoc, sAssocType); + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType)) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssocType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssoc)); + } + } + } + } + // Check all of our henchman. + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetAssociateDbJson(oPC, sAssocType, "modes", jModes); + ai_SetAssociateDbJson(oPC, sAssocType, "buttons", jButtons); + ai_SetAssociateDbJson(oPC, sAssocType, "aidata", jAIData); + ai_SetAssociateDbJson(oPC, sAssocType, "lootfilters", jLootFilters); + SetLocalString(oAssoc, AI_COMBAT_SCRIPT, sCombatScript); + SetLocalString(oAssoc, AI_DEFAULT_SCRIPT, sDefaultScript); + // Clear the creatures Perception distance so we can + // repopulate the local variables. + SetLocalFloat(oAssoc, AI_ASSOC_PERCEPTION_DISTANCE, 0.0); + ai_CheckAssociateData(oPC, oAssoc, sAssocType); + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType)) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssocType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssoc)); + } + } + else break; + } + ai_SendMessages(GetName(oAssociate) + "'s settings have been copied to all associates.", AI_COLOR_GREEN, oPC); + return; + } + else if(GetStringLeft(sElem, 18) == "btn_paste_henchman") + { + int nIndex = StringToInt(GetStringRight(sElem, 1)); + oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssoc != OBJECT_INVALID) + { + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetAssociateDbJson(oPC, sAssocType, "modes", jModes); + ai_SetAssociateDbJson(oPC, sAssocType, "buttons", jButtons); + ai_SetAssociateDbJson(oPC, sAssocType, "aidata", jAIData); + ai_SetAssociateDbJson(oPC, sAssocType, "lootfilters", jLootFilters); + SetLocalString(oAssoc, AI_COMBAT_SCRIPT, sCombatScript); + SetLocalString(oAssoc, AI_DEFAULT_SCRIPT, sDefaultScript); + // Clear the creatures Perception distance so we can + // repopulate the local variables. + SetLocalFloat(oAssoc, AI_ASSOC_PERCEPTION_DISTANCE, 0.0); + ai_CheckAssociateData(oPC, oAssoc, sAssocType); + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType)) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssocType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssoc)); + } + ai_SendMessages(GetName(oAssociate) + "'s settings have been copied to " + GetName(oAssoc) + ".", AI_COLOR_GREEN, oPC); + } + return; + } + else if(sElem == "btn_paste_familiar") nIndex = ASSOCIATE_TYPE_FAMILIAR; + else if(sElem == "btn_paste_companion") nIndex = ASSOCIATE_TYPE_ANIMALCOMPANION; + else if(sElem == "btn_paste_summons") nIndex = ASSOCIATE_TYPE_SUMMONED; + else if(sElem == "btn_paste_dominated") nIndex = ASSOCIATE_TYPE_DOMINATED; + if(nIndex > 1 && nIndex < 6) + { + oAssoc = GetAssociate(nIndex, oPC); + sAssocType = ai_GetAssociateType(oPC, oAssoc); + ai_SetAssociateDbJson(oPC, sAssocType, "modes", jModes); + ai_SetAssociateDbJson(oPC, sAssocType, "buttons", jButtons); + ai_SetAssociateDbJson(oPC, sAssocType, "aidata", jAIData); + ai_SetAssociateDbJson(oPC, sAssocType, "lootfilters", jLootFilters); + SetLocalString(oAssoc, AI_COMBAT_SCRIPT, sCombatScript); + SetLocalString(oAssoc, AI_DEFAULT_SCRIPT, sDefaultScript); + if(oAssoc != OBJECT_INVALID) + { + // Clear the creatures Perception distance so we can + // repopulate the local variables. + SetLocalFloat(oAssoc, AI_ASSOC_PERCEPTION_DISTANCE, 0.0); + ai_CheckAssociateData(oPC, oAssoc, sAssocType); + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType)) + { + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssocType + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssoc)); + } + ai_SendMessages(GetName(oAssociate) + "'s settings have been copied to " + GetName(oAssoc) + ".", AI_COLOR_GREEN, oPC); + } + } + } + return; + } + //************************************************************************** + // Plugins events. + if(sWndId == AI_PLUGIN_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_load_plugins") + { + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_buffing"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_forcerest"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_henchmen"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_crafting"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_mod_set"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_debug"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "pi_test"); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + } + if(sElem == "btn_load_m_mods") + { + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, "mm_prc_spells"); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + } + if(sElem == "btn_check_plugins") + { + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + if(JsonGetInt(JsonArrayGet(jPlugin, 1)) < 3) + { + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(TRUE)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + if(sElem == "btn_clear_plugins") + { + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + if(JsonGetInt(JsonArrayGet(jPlugin, 1)) < 3) + { + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(FALSE)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + else if(sElem == "btn_add_plugin") + { + string sScript = JsonGetString(NuiGetBind (oPC, nToken, "txt_plugin")); + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + jPlugins = ai_Plugin_Add(oPC, jPlugins, sScript); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + } + else if(GetStringLeft(sElem, 18) == "btn_remove_plugin_") + { + int nIndex = StringToInt(GetStringRight(sElem, 1)); + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + jPlugins = JsonArrayDel(jPlugins, nIndex); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreatePluginNUI(oPC)); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oPC, sElem); + } + else if(sEvent == "watch") + { + if(GetStringLeft(sElem, 12) == "chbx_plugin_" && GetStringRight(sElem, 6) == "_check") + { + int nIndex = StringToInt(GetSubString(sElem, 12, 1)); + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + json jPlugin = JsonArrayGet(jPlugins, nIndex); + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + } + return; + } + //************************************************************************** + // Quick Use Widget events. + if(sWndId == sAssociateType + AI_QUICK_WIDGET_NUI) + { + if(sEvent == "click") + { + if(GetStringLeft(sElem, 10) == "btn_class_") // Changes the class. + { + string sClassPosition = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 0, JsonInt(StringToInt(sClassPosition))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate)); + } + else if(GetStringLeft(sElem, 10) == "btn_level_") // Changes the level. + { + string sLevel; + if(GetStringLength(sElem) == 12) sLevel = GetStringRight(sElem, 2); + else sLevel = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 1, JsonInt(StringToInt(sLevel))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate)); + } + else if(sElem == "btn_text_spell") // Adds abilities to quick use widget. + { + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + if(JsonGetType(jWidget) == JSON_TYPE_NULL) + { + jWidget = JsonArray(); + if(JsonGetLength(jSpells) == 2) jSpells = JsonArrayInsert(jSpells, JsonArray()); + } + if(JsonGetLength(jWidget) < 20) + { + json jData = NuiGetUserData(oPC, nToken); + json jQuickListArray = JsonArrayGet(jData, 1); + json jSpell = JsonArrayGet(jQuickListArray, nIndex); + jWidget = JsonArrayInsert(jWidget, jSpell); + jSpells = JsonArraySet(jSpells, 2, jWidget); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate)); + } + else ai_SendMessages("The quick widget can only have 20 abilities or spells!", AI_COLOR_RED, oPC); + } + else if(sElem == "btn_info_spell") + { + json jQuickListArray = JsonArrayGet(jData, 1); + json jSpell = JsonArrayGet(jQuickListArray, nIndex); + ai_CreateDescriptionNUI(oPC, jSpell); + } + else if(GetStringLeft(sElem, 11) == "btn_widget_") + { + string sIndex; + if(GetStringLength(sElem) == 13) sIndex = GetStringRight(sElem, 2); + else sIndex = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + jWidget = JsonArrayDel(jWidget, StringToInt(sIndex)); + jSpells = JsonArraySet(jSpells, 2, jWidget); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate)); + } + } + else if(sEvent == "close") + { + int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI); + if(nUIToken) + { + DelayCommand(0.0, NuiDestroy(oPC, nUIToken)); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + } + return; + } + //************************************************************************** + // Spell Memorization events. + if(sWndId == sAssociateType + AI_SPELL_MEMORIZE_NUI) + { + if(sEvent == "click") + { + if(GetStringLeft(sElem, 10) == "btn_class_") // Changes the class. + { + string sClassPosition = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 0, JsonInt(StringToInt(sClassPosition))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateSpellMemorizationNUI(oPC, oAssociate)); + } + else if(GetStringLeft(sElem, 10) == "btn_level_") // Changes the level. + { + string sLevel = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 1, JsonInt(StringToInt(sLevel))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateSpellMemorizationNUI(oPC, oAssociate)); + } + else if(sElem == "btn_text_spell") // Adds spell to memorization. + { + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate); + int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1)); + json jSpellArray = JsonArrayGet(jData, 1); + int nMaxMemorizationSlot = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevel); + int nSlot, nSpell; + while(nSlot < nMaxMemorizationSlot) + { + if(GetMemorizedSpellId(oAssociate, nClass, nLevel, nSlot) == -1) + { + nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex)); + SetMemorizedSpell(oAssociate, nClass, nLevel, nSlot, nSpell, FALSE); + //NuiDestroy(oPC, nToken); + //ai_CreateSpellMemorizationNUI(oPC, oAssociate); + string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + string sIndex = IntToString(nSlot); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + return; + } + nSlot++; + } + if(nSlot >= nMaxMemorizationSlot) ai_SendMessages("All spell memorization slots are full!", AI_COLOR_RED, oPC); + } + else if(sElem == "btn_info_spell") + { + json jSpellArray = JsonArrayGet(jData, 1); + int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex)); + ai_CreateDescriptionNUI(oPC, JsonArray(), nSpell); + } + else if(GetStringLeft(sElem, 14) == "btn_memorized_") + { + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate); + int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1)); + string sIndex = GetStringRight(sElem, 1); + ClearMemorizedSpell(oAssociate, nClass, nLevel, StringToInt(sIndex)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_tooltip", JsonString("")); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(FALSE)); + //NuiDestroy(oPC, nToken); + //ai_CreateSpellMemorizationNUI(oPC, oAssociate); + } + } + else if(sEvent == "close") + { + int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI); + if(nUIToken) + { + DelayCommand(0.0, NuiDestroy(oPC, nUIToken)); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + } + return; + } + //************************************************************************** + // Spell Known events. + if(sWndId == sAssociateType + AI_SPELL_KNOWN_NUI) + { + if(sEvent == "click") + { + if(GetStringLeft(sElem, 10) == "btn_class_") // Changes the class. + { + string sClassPosition = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 0, JsonInt(StringToInt(sClassPosition))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateSpellKnownNUI(oPC, oAssociate)); + } + else if(GetStringLeft(sElem, 10) == "btn_level_") // Changes the level. + { + string sLevel = GetStringRight(sElem, 1); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + jSpells = JsonArraySet(jSpells, 1, JsonInt(StringToInt(sLevel))); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateSpellKnownNUI(oPC, oAssociate)); + } + else if(sElem == "btn_text_spell") // Adds spell to known list. + { + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate); + int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1)); + json jSpellArray = JsonArrayGet(jData, 1); + int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex)); + json jClassList = GetLocalJson(oAssociate, AI_CLASS_LIST_JSON); + // Get the correct class array. + int bAddList, nClassIndex = 0; + json jClass = JsonArrayGet(jClassList, nClassIndex); + while(JsonGetInt(GffGetInt(jClass, "Class")) != nClass) + { + jClass = JsonArrayGet(jClassList, ++nClassIndex); + } + string sLevel = IntToString(nLevel); + json jSpell, jKnownList = GffGetList(jClass, "KnownList" + sLevel); + if(JsonGetType(jKnownList) == JSON_TYPE_NULL) + { + bAddList = TRUE; + jKnownList = JsonArray(); + } + int nMaxKnownSlots, nSlot; + string sSpellKnownTable = Get2DAString("classes", "SpellKnownTable", nClass); + if(sSpellKnownTable != "") nMaxKnownSlots = StringToInt(Get2DAString(sSpellKnownTable, "SpellLevel" + sLevel, GetLevelByClass(nClass, oAssociate) - 1)); + else nMaxKnownSlots = 20; + while(nSlot < nMaxKnownSlots) + { + jSpell = JsonArrayGet(jKnownList, nSlot); + if(JsonGetType(jSpell) == JSON_TYPE_NULL) + { + jSpell = GffAddWord(JsonObject(), "Spell", nSpell); + jSpell = JsonObjectSet(jSpell, "__struct_id", JsonInt(3)); + jKnownList = JsonArrayInsert(jKnownList, jSpell); + string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + string sIndex = IntToString(nSlot); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + sLevel + ")")); + SetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE", TRUE); + break; + } + else if(JsonGetInt(GffGetWord(jSpell, "Spell")) == nSpell) + { + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_SendMessages(sName + " is already in the known spell list!", AI_COLOR_RED, oPC); + return; + } + nSlot++; + } + if(nSlot >= nMaxKnownSlots) + { + ai_SendMessages("All known spell slots are full!", AI_COLOR_RED, oPC); + return; + } + if(bAddList) jClass = GffAddList(jClass, "KnownList" + sLevel, jKnownList); + else jClass = GffReplaceList(jClass, "KnownList" + sLevel, jKnownList); + jClassList = JsonArraySet(jClassList, nClassIndex, jClass); + SetLocalJson(oAssociate, AI_CLASS_LIST_JSON, jClassList); + } + else if(sElem == "btn_info_spell") + { + json jSpellArray = JsonArrayGet(jData, 1); + int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex)); + ai_CreateDescriptionNUI(oPC, JsonArray(), nSpell); + } + else if(GetStringLeft(sElem, 10) == "btn_known_") // Remove a known spell. + { + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate); + int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1)); + string sIndex = GetStringRight(sElem, 1); + // Check to see if there is a spell in this slot. + string sImageName = JsonGetString(NuiGetBind(oPC, nToken, "btn_known_" + sIndex + "_image")); + if(sImageName == "ctl_cg_btn_splvl") return; + json jClassList = GetLocalJson(oAssociate, AI_CLASS_LIST_JSON); + // Get the correct class array. + int nClassIndex = 0; + json jClass = JsonArrayGet(jClassList, nClassIndex); + while(JsonGetInt(GffGetInt(jClass, "Class")) != nClass) + { + jClass = JsonArrayGet(jClassList, ++nClassIndex); + } + string sLevel = IntToString(nLevel); + json jKnownList = GffGetList(jClass, "KnownList" + sLevel); + jKnownList = JsonArrayDel(jKnownList, StringToInt(sIndex)); + jClass = GffReplaceList(jClass, "KnownList" + sLevel, jKnownList); + jClassList = JsonArraySet(jClassList, nClassIndex, jClass); + SetLocalJson(oAssociate, AI_CLASS_LIST_JSON, jClassList); + SetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE", TRUE); + // Relist all known spells so they match the index. + int nMaxKnownSlots, nSpell; + string sName, sSpellIcon, sClass = IntToString(nClass); + string sSpellKnownTable = Get2DAString("classes", "SpellKnownTable", nClass); + json jSpell; + if(sSpellKnownTable != "") nMaxKnownSlots = StringToInt(Get2DAString(sSpellKnownTable, "SpellLevel" + IntToString(nLevel), GetLevelByClass(nClass, oAssociate) - 1)); + else nMaxKnownSlots = 20; + nIndex = 0; + while(nIndex < 20) + { + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(TRUE)); + if(nIndex < nMaxKnownSlots) + { + jSpell = JsonArrayGet(jKnownList, nIndex); + if(JsonGetType(jSpell) == JSON_TYPE_NULL) + { + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" Empty known spell slot")); + } + else + { + nSpell = JsonGetInt(GffGetWord(jSpell, "Spell")); + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + //nMetaMagic = 255; + //nDomain = 0; + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + //sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, -1, -1, -1, nMetaMagic, nDomain); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + } + } + else + { + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString("")); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(FALSE)); + } + ++nIndex; + } + } + } + else if(sEvent == "close") + { + if(GetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE")) + { + RemoveHenchman(oPC, oAssociate); + json jHenchman = ObjectToJson(oAssociate, TRUE); + json jClassList = GetLocalJson(oAssociate, AI_CLASS_LIST_JSON); + jHenchman = GffReplaceList(jHenchman, "ClassList", jClassList); + location lLocation = GetLocation(oAssociate); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oAssociate); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oAssociate); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + AssignCommand(oAssociate, SetIsDestroyable(TRUE, FALSE, FALSE)); + DestroyObject(oAssociate); + oAssociate = ai_AddHenchman(oPC, jHenchman, lLocation, nFamiliar, nCompanion); + DeleteLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE"); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + } + } + return; + } + //************************************************************************** + // Spell Description events. + if(sWndId == AI_SPELL_DESCRIPTION_NUI) + { + if(sEvent == "click" && sElem == "btn_ok") DelayCommand(0.0, NuiDestroy(oPC, nToken)); + } + //************************************************************************** + // Effect Icon NUI events. + if(sWndId == AI_EFFECT_ICON_NUI) + { + if(sEvent == "click") + { + if(GetStringLeft(sElem, 18) == "btn_remove_effect_") + { + int nEffectIndex = StringToInt(GetStringRight(sElem, GetStringLength(sElem) - 18)); + json jEffectID = JsonArrayGet(jData, 2); + string sEffectLinkID = JsonGetString(JsonArrayGet(jEffectID, nEffectIndex)); + int nIndex; + effect eEffect = GetFirstEffect(oPC); + while(GetIsEffectValid(eEffect)) + { + if(GetEffectLinkId(eEffect) == sEffectLinkID) + { + RemoveEffect(oPC, eEffect); + int nEffectIconToken = NuiFindWindow(oPC, AI_EFFECT_ICON_NUI); + if(nEffectIconToken) DelayCommand(0.0, NuiDestroy(oPC, nEffectIconToken)); + } + nIndex++; + eEffect = GetNextEffect(oPC); + } + } + } + else if(sEvent == "mousedown") + { + AssignCommand(oPC, PlaySound("gui_button")); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + } + } +} +void ai_SetWidgetButtonToCheckbox(object oPC, int nButton, object oAssociate, string sAssociateType, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + ai_SetWidgetButton(oPC, nButton, oAssociate, sAssociateType, bCheck); +} +void ai_SetAIButtonToCheckbox(object oPC, int nButton, object oAssociate, string sAssociateType, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + ai_SetAIButton(oPC, nButton, oAssociate, sAssociateType, bCheck); +} +void ai_SetLootFilterToCheckbox(object oPC, object oAssociate, int nFilterBit, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + ai_SetLootFilter(oAssociate, nFilterBit, bCheck); +} +void ai_AddAssociate(object oPC, int nToken, json jAssociate, location lLocation, int nFamiliar, int nCompanion, int nRange = 0) +{ + object oAssociate = JsonToObject(jAssociate, lLocation, OBJECT_INVALID, TRUE); + //ChangeToStandardFaction(oAssociate, STANDARD_FACTION_COMMONER); + //SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 50, oAssociate); + //SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 50, oAssociate); + //SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 50, oAssociate); + //SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 0, oAssociate); + AddHenchman(oPC, oAssociate); + DeleteLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE"); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + if(nRange) SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, nRange); + if(nFamiliar) SummonFamiliar(oAssociate); + if(nCompanion) SummonAnimalCompanion(oAssociate); +} +void ai_SetCompanionType(object oPC, object oAssociate, int nToken, int nAssociateType) +{ + if(ai_GetIsCharacter(oAssociate)) return; + SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE); + int nSelection; + // Need to remove the henchman before we copy them to keep factions correct. + ai_FireHenchman(oPC, oAssociate); + json jAssociate = ObjectToJson(oAssociate, TRUE); + if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) + { + nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_familiar_selected")); + jAssociate = GffReplaceInt(jAssociate, "FamiliarType", nSelection); + } + else if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) + { + nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_companion_selected")); + jAssociate = GffReplaceInt(jAssociate, "CompanionType", nSelection); + } + //ai_Debug("0e_nui", "916", JsonDump(jAssociate, 1)); + location lLocation = GetLocation(oAssociate); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oAssociate); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oAssociate); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate); + DestroyObject(oAssociate); + DelayCommand(0.1, ai_AddAssociate(oPC, nToken, jAssociate, lLocation, nFamiliar, nCompanion)); +} +void ai_SetCompanionName(object oPC, object oAssociate, int nToken, int nAssociateType) +{ + if(ai_GetIsCharacter(oAssociate)) return; + SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE); + string sAssociateType; + string sName; + // Need to remove the henchman before we copy them to keep factions correct. + ai_FireHenchman(oPC, oAssociate); + json jAssociate = ObjectToJson(oAssociate, TRUE); + if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) + { + sName = JsonGetString(NuiGetBind(oPC, nToken, "txt_familiar_name")); + jAssociate = GffReplaceString(jAssociate, "FamiliarName", sName); + } + else if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) + { + sAssociateType = "txt_companion_name"; + sName = JsonGetString(NuiGetBind(oPC, nToken, "txt_companion_name")); + jAssociate = GffReplaceString(jAssociate, "FamiliarName", sName); + } + location lLocation = GetLocation(oAssociate); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oAssociate); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oAssociate); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate); + DestroyObject(oAssociate); + DelayCommand(0.1, ai_AddAssociate(oPC, nToken, jAssociate, lLocation, nFamiliar, nCompanion)); +} +void ai_SetAIScript(object oPC, object oAssociate, int nToken) +{ + int nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_ai_script_selected")); + if(nSelection == 0) return; + string sScript = sScript = ResManFindPrefix("ai_a_", RESTYPE_NCS, nSelection); + NuiSetBind(oPC, nToken, "txt_ai_script", JsonString(sScript)); + string sOldScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + if(sScript != sOldScript) + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + if(JsonGetType(JsonArrayGet(jAIData, 8)) == JSON_TYPE_NULL) jAIData = JsonArrayInsert(jAIData, JsonString(sScript)); + else jAIData = JsonArraySet(jAIData, 8, JsonString(sScript)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + ai_SendMessages(GetName(oAssociate) + " is now using " + sScript + " AI script!", AI_COLOR_GREEN, oPC); + } + else ai_SendMessages(GetName(oAssociate) + " is already using this script! Did not change AI script.", AI_COLOR_RED, oPC); +} +void ai_PercRangeIncrement(object oPC, object oAssociate, int nIncrement, string sAssociateType, int nToken) +{ + int nAdjustment = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU"); + nAdjustment += nIncrement; + if(nAdjustment < 8 || nAdjustment > 11) return; + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU", nAdjustment); + json jAssociate = ObjectToJson(oAssociate, TRUE); + int nHenchPercRange = JsonGetInt(GffGetByte(jAssociate, "PerceptionRange")); + string sText, sInfo; + if(nAdjustment == nHenchPercRange) + { + if(nAdjustment == 8) sText = " Perception Range Short [10 meters Sight / 10 meters Listen]"; + else if(nAdjustment == 9) sText = " Perception Range Medium [20 meters Sight / 20 meters Listen]"; + else if(nAdjustment == 10) sText = " Perception Range Long [35 meters Sight / 20 meters Listen]"; + else sText = " Perception Range Default [20 meters Sight / 20 meters Listen]"; + sInfo = " "; + } + else + { + if(nAdjustment == 8) sText = " !!! Click the Perception Range button to set to short range !!!"; + else if(nAdjustment == 9) sText = " !!! Click the Perception Range button to set to medium range !!!"; + else if(nAdjustment == 10) sText = " !!! Click the Perception Range button to set to long range !!!"; + else sText = " !!! Click the Perception Range button to set to the default range !!!"; + sInfo = sText; + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_perc_range_tooltip", sText); + if(nToken > -1) NuiSetBind (oPC, nToken, "lbl_info_label", JsonString(sInfo)); +} +void ai_Perc_Range(object oPC, object oAssociate, int nToken, string sAssociateType) +{ + if(ai_GetIsCharacter(oAssociate)) return; + SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE); + int nBtnPercRange = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU"); + string sText, sText2; + float fRange = 20.0; + if(nBtnPercRange == 8) + { + sText = "short"; + sText2 = " Perception Range Short [10 meters Sight / 10 meters Listen]"; + fRange = 10.0; + } + else if(nBtnPercRange == 9) + { + sText = "medium"; + sText2 = " Perception Range Medium [20 meters Sight / 20 meters Listen]"; + } + else if(nBtnPercRange == 10) + { + sText = "long"; + sText2 = " Perception Range Long [35 meters Sight / 20 meters Listen]"; + fRange = 35.0; + } + else if(nBtnPercRange == 11) + { + sText = "default"; + sText2 = " Perception Range Default [20 meters Sight / 20 meters Listen]"; + } + SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, fRange); + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, nBtnPercRange); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 7, JsonInt(nBtnPercRange)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + // Need to remove the henchman before we copy them to keep factions correct. + ai_FireHenchman(oPC, oAssociate); + json jAssociate = ObjectToJson(oAssociate, TRUE); + int nHenchPercRange = JsonGetInt(GffGetByte(jAssociate, "PerceptionRange")); + if(nBtnPercRange == nHenchPercRange) + { + ai_SendMessages(GetName(oAssociate) + " already has this perception set.", AI_COLOR_YELLOW, oPC); + AddHenchman(oPC, oAssociate); + DeleteLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE"); + return; + } + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_NUI))); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_perc_range_tooltip", sText2); + ai_SendMessages(GetName(oAssociate) + " has updated their perception range to " + sText + ".", AI_COLOR_YELLOW, oPC); + location lLocation = GetLocation(oAssociate); + jAssociate = GffReplaceByte(jAssociate, "PerceptionRange", nBtnPercRange); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oAssociate); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oAssociate); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate); + DestroyObject(oAssociate); + DelayCommand(0.1, ai_AddAssociate(oPC, nToken, jAssociate, lLocation, nFamiliar, nCompanion, nBtnPercRange)); +} +void ai_RulePercDistInc(object oPC, object oModule, int nIncrement, int nToken) +{ + int nAdjustment = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE) + nIncrement; + if(nAdjustment < 8 || nAdjustment > 11) return; + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, nAdjustment); + string sText; + if(nAdjustment == 8) sText = " Monster perception: Short [10 Sight / 10 Listen]"; + else if(nAdjustment == 9) sText = " Monster perception: Medium [20 Sight / 20 Listen]"; + else if(nAdjustment == 10) sText = " Monster perception: Long [35 Sight / 20 Listen]"; + else sText = " Monster perception: Default [Monster's default values]"; + NuiSetBind(oPC, nToken, "lbl_perc_dist_label", JsonString(sText)); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_MON_PERC_DISTANCE, JsonInt(nAdjustment)); + ai_SetCampaignDbJson("rules", jRules); +} +json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE) +{ + object oModule = GetModule(); + json jRSpells = GetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS); + if(JsonGetType(jRSpells) == JSON_TYPE_NULL) jRSpells = JsonArray(); + int nIndex, nMaxIndex = JsonGetLength(jRSpells); + if(bRestrict) + { + while(nIndex < nMaxIndex) + { + if(JsonGetInt(JsonArrayGet(jRSpells, nIndex)) == nSpell) return jRules; + nIndex++; + } + jRSpells = JsonArrayInsert(jRSpells, JsonInt(nSpell)); + } + else + { + while(nIndex < nMaxIndex) + { + if(JsonGetInt(JsonArrayGet(jRSpells, nIndex)) == nSpell) + { + jRSpells = JsonArrayDel(jRSpells, nIndex); + break; + } + nIndex++; + } + } + SetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS, jRSpells); + return JsonObjectSet(jRules, AI_RULE_RESTRICTED_SPELLS, jRSpells); +} +void ai_TurnOn(object oPC, object oTarget, string sAssociateType) +{ + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI On"); + ai_SendMessages("AI turned on for " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "xx_pc_1_hb"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_NOTICE, "xx_pc_2_percept"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "xx_pc_3_endround"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "xx_pc_4_convers"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "xx_pc_5_phyatked"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "xx_pc_6_damaged"); + //SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DEATH, ""); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "xx_pc_8_disturb"); + //SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_RESTED, ""); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "xx_pc_b_castat"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "xx_pc_e_blocked"); + //SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); + // This sets the script for the PC to run AI based on class. + ai_SetAssociateAIScript(oTarget, FALSE); + // Set so PC can hear associates talking in combat. + ai_SetListeningPatterns(oTarget); +} +void ai_TurnOff(object oPC, object oAssociate, string sAssociateType) +{ + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI Off"); + ai_SendMessages("AI Turned off for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_NOTICE, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DAMAGED, ""); + //SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DEATH, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DISTURBED, ""); + //SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_RESTED, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, ""); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, ""); + //SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); + DeleteLocalInt(oAssociate, "AI_I_AM_BEING_HEALED"); + DeleteLocalString(oAssociate, "AIScript"); + ai_ClearCreatureActions(); +} +object ai_AddHenchman(object oPC, json jHenchman, location lLocation, int nFamiliar, int nCompanion) +{ + jHenchman = GffReplaceResRef(jHenchman, "ScriptSpawn", ""); + object oHenchman = JsonToObject(jHenchman, lLocation, OBJECT_INVALID, TRUE); + AddHenchman(oPC, oHenchman); + DeleteLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE"); + string sAssociateType = ai_GetAssociateType(oPC, oHenchman); + NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)); + if(nFamiliar) SummonFamiliar(oHenchman); + if(nCompanion) SummonAnimalCompanion(oHenchman); + return oHenchman; +} + diff --git a/src/module/nss/0e_nui_dm.nss b/src/module/nss/0e_nui_dm.nss new file mode 100644 index 0000000..4ffd851 --- /dev/null +++ b/src/module/nss/0e_nui_dm.nss @@ -0,0 +1,700 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: 0e_nui_dm + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Menu event script + sEvent: close, click, mousedown, mouseup, watch (if bindwatch is set). +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_menus_dm" +void ai_SetDMWidgetButtonToCheckbox(object oDM, int nButton, int nToken, string sElem); +void ai_SetDMWAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem); +void ai_SetDMAIAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem); +void ai_SetDMAIAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem); +void ai_RulePercDistInc(object oDM, object oModule, int nIncrement, int nToken); +// Adds a spell to a json AI restricted spell list then returns jRules. +// bRestrict = TRUE will add to the list FALSE will remove it from the list. +json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE); +// Adds a selected creature to the group. +void ai_SelectToGroup(object oDM, string sElem); +// Does a selected action for nGroup. +void ai_DMSelectAction(object oDM, string sElem); +// Changes if the group will run (nSpeed: 1) or walk (nSpeed: 0). +void ai_DMChangeMoveSpeed(object oDM, string sElem, int nSpeed); +void main() +{ + object oDM = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + string sWndId = NuiGetWindowId(oDM, nToken); + //if(AI_DEBUG) ai_Debug ("0e_nui", "58", "sWndId: " + sWndId + " sEvent: " + sEvent + " sElem: " + sElem + + // " nToken: " + IntToString(nToken) + " oPC: " + GetName(oPC)); + //WriteTimestampedLogEntry("0e_nui, 58, sWndId: " + sWndId + " sEvent: " + sEvent + " sElem: " + sElem + + // " nToken: " + IntToString(nToken) + " oDM: " + GetName(oDM)); + //************************************************************************** + string sName = ai_RemoveIllegalCharacters(GetName(oDM)); + // Watch to see if the window moves and save. + if(sElem == "window_geometry" && sEvent == "watch") + { + if(GetLocalInt(oDM, AI_NO_NUI_SAVE)) return; + SaveMenuToCampaignDb(oDM, nToken, sWndId); + } + //************************************************************************** + // Widget events. + if(sWndId == "dm" + AI_WIDGET_NUI) + { + //if(GetLocalInt(oDM, AI_NO_NUI_SAVE)) return; + if(sEvent == "click") + { + if(sElem == "btn_open_main") + { + if(IsWindowClosed(oDM, "dm" + AI_COMMAND_NUI)) ai_CreateDMCommandNUI(oDM); + IsWindowClosed(oDM, "dm" + AI_MAIN_NUI); + } + else if(sElem == "btn_camera") ai_SelectCameraView(oDM); + else if(sElem == "btn_inventory") ai_SelectOpenInventory(oDM); + else if(GetStringLeft(sElem, 13) == "btn_cmd_group") + { + ai_DMSelectAction(oDM, sElem); + } + else if(GetStringLeft(sElem, 15) == "btn_exe_plugin_") ai_Plugin_Execute(oDM, sElem, TRUE); + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + if(GetStringLeft(sElem, 13) == "btn_cmd_group") ai_DMChangeMoveSpeed(oDM, sElem, 1); + } + if(nMouseScroll == -1.0) // Scroll down + { + if(GetStringLeft(sElem, 13) == "btn_cmd_group") ai_DMChangeMoveSpeed(oDM, sElem, 0); + } + } + else if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + if(sElem == "btn_open_main") + { + if(IsWindowClosed(oDM, "dm" + AI_MAIN_NUI)) ai_CreateDMOptionsNUI(oDM); + } + else if(GetStringLeft(sElem, 13) == "btn_cmd_group") + { + ai_SelectToGroup(oDM, sElem); + } + } + } + } + else if(sWndId == "dm" + AI_COMMAND_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_widget_lock") + { + if(ai_GetDMWidgetButton(oDM, BTN_DM_WIDGET_LOCK)) + { + ai_SendMessages(GetName(oDM) + " AI widget unlocked.", AI_COLOR_YELLOW, oDM); + ai_SetDMWidgetButton(oDM, BTN_DM_WIDGET_LOCK, FALSE); + } + else + { + ai_SendMessages(GetName(oDM) + " AI widget locked.", AI_COLOR_YELLOW, oDM); + ai_SetDMWidgetButton(oDM, BTN_DM_WIDGET_LOCK, TRUE); + } + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + else if(sElem == "btn_main_menu") + { + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMOptionsNUI(oDM)); + } + else if(sElem == "btn_camera") ai_SelectCameraView(oDM); + else if(sElem == "btn_inventory") ai_SelectOpenInventory(oDM); + else if(GetStringLeft(sElem, 13) == "btn_cmd_group") ai_DMSelectAction(oDM, sElem); + else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oDM, sElem, 1); + } + else if(sEvent == "watch") + { + if(sElem == "chbx_cmd_group1_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP1, nToken, sElem); + else if(sElem == "chbx_cmd_group2_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP2, nToken, sElem); + else if(sElem == "chbx_cmd_group3_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP3, nToken, sElem); + else if(sElem == "chbx_cmd_group4_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP4, nToken, sElem); + else if(sElem == "chbx_cmd_group5_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP5, nToken, sElem); + else if(sElem == "chbx_cmd_group6_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_GROUP6, nToken, sElem); + else if(sElem == "chbx_camera_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_CAMERA, nToken, sElem); + else if(sElem == "chbx_inventory_check") ai_SetDMWidgetButtonToCheckbox(oDM, BTN_DM_CMD_INVENTORY, nToken, sElem); + if(GetStringLeft(sElem, 12) == "chbx_plugin_" && GetStringRight(sElem, 6) == "_check") + { + int nIndex = StringToInt(GetSubString(sElem, 12, 1)); + json jPlugins = ai_GetCampaignDbJson("plugins", sName, AI_DM_TABLE); + json jPlugin = JsonArrayGet(jPlugins, nIndex); + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + ai_SetCampaignDbJson("plugins", jPlugins, sName, AI_DM_TABLE); + } + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + if(GetStringLeft(sElem, 13) == "btn_cmd_group") ai_DMChangeMoveSpeed(oDM, sElem, 1); + } + if(nMouseScroll == -1.0) // Scroll down + { + if(GetStringLeft(sElem, 13) == "btn_cmd_group") ai_DMChangeMoveSpeed(oDM, sElem, 0); + } + } + else if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + if(GetStringLeft(sElem, 13) == "btn_cmd_group") + { + ai_SelectToGroup(oDM, sElem); + } + } + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + } + else if(nMouseScroll == -1.0) // Scroll down + { + } + } + } + //************************************************************************** + // Main AI events. + if(sWndId == "dm" + AI_MAIN_NUI) + { + if(sEvent == "click") + { + if(sElem == "btn_plugin_manager") + { + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + } + if(sElem == "btn_widget_manager") + { + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMWidgetManagerNUI(oDM)); + } + } + if(sEvent == "watch") + { + if(sElem == "txt_max_henchman") + { + int nMaxHenchmen = StringToInt(JsonGetString(NuiGetBind(oDM, nToken, sElem))); + if(nMaxHenchmen < 1) nMaxHenchmen = 1; + if(nMaxHenchmen > 12) + { + nMaxHenchmen = 12; + ai_SendMessages("The maximum henchmen for this mod is 12!", AI_COLOR_RED, oDM); + } + SetMaxHenchmen(nMaxHenchmen); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_MAX_HENCHMAN, JsonInt(nMaxHenchmen)); + ai_SetCampaignDbJson("rules", jRules); + ai_SendMessages("Maximum henchmen has been changed to " + IntToString(nMaxHenchmen), AI_COLOR_YELLOW, oDM); + } + else if(sElem == "txt_ai_difficulty") + { + int nChance = StringToInt(JsonGetString(NuiGetBind(oDM, nToken, sElem))); + if(nChance < 0) nChance = 0; + else if(nChance > 100) nChance = 100; + SetLocalInt(GetModule(), AI_RULE_AI_DIFFICULTY, nChance); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_AI_DIFFICULTY, JsonInt(nChance)); + ai_SetCampaignDbJson("rules", jRules); + } + else if(sElem == "txt_perception_distance") + { + float fDistance = StringToFloat(JsonGetString(NuiGetBind(oDM, nToken, sElem))); + if(fDistance < 10.0) fDistance = 10.0; + else if(fDistance > 60.0) fDistance = 60.0; + SetLocalFloat(GetModule(), AI_RULE_PERCEPTION_DISTANCE, fDistance); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_PERCEPTION_DISTANCE, JsonFloat(fDistance)); + ai_SetCampaignDbJson("rules", jRules); + } + else if(sElem == "txt_inc_hp") + { + int nNumber = StringToInt(JsonGetString(NuiGetBind(oDM, nToken, sElem))); + if(nNumber < 0) nNumber = 0; + else if(nNumber > 100) nNumber = 100; + SetLocalInt(GetModule(), AI_INCREASE_MONSTERS_HP, nNumber); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_INCREASE_MONSTERS_HP, JsonInt(nNumber)); + ai_SetCampaignDbJson("rules", jRules); + } + else if(GetStringLeft(sElem, 4) == "chbx") + { + object oModule = GetModule(); + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + json jRules = ai_GetCampaignDbJson("rules"); + if(sElem == "chbx_moral_check") + { + SetLocalInt(oModule, AI_RULE_MORAL_CHECKS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_MORAL_CHECKS, JsonInt(bCheck)); + } + else if(sElem == "chbx_buff_monsters_check") + { + SetLocalInt(oModule, AI_RULE_BUFF_MONSTERS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_BUFF_MONSTERS, JsonInt(bCheck)); + } + else if(sElem == "chbx_buff_summons_check") + { + SetLocalInt(oModule, AI_RULE_PRESUMMON, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PRESUMMON, JsonInt(bCheck)); + } + else if(sElem == "chbx_ambush_monsters_check") + { + SetLocalInt(oModule, AI_RULE_AMBUSH, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_AMBUSH, JsonInt(bCheck)); + } + else if(sElem == "chbx_companions_check") + { + SetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_SUMMON_COMPANIONS, JsonInt(bCheck)); + } + else if(sElem == "chbx_advanced_movement_check") + { + SetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ADVANCED_MOVEMENT, JsonInt(bCheck)); + } + else if(sElem == "chbx_ilr_check") + { + SetLocalInt(oModule, AI_RULE_ILR, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ILR, JsonInt(bCheck)); + } + else if(sElem == "chbx_umd_check") + { + SetLocalInt(oModule, AI_RULE_ALLOW_UMD, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_ALLOW_UMD, JsonInt(bCheck)); + } + else if(sElem == "chbx_use_healingkits_check") + { + SetLocalInt(oModule, AI_RULE_HEALERSKITS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_HEALERSKITS, JsonInt(bCheck)); + } + else if(sElem == "chbx_perm_assoc_check") + { + SetLocalInt(oModule, AI_RULE_PERM_ASSOC, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PERM_ASSOC, JsonInt(bCheck)); + } + else if(sElem == "chbx_corpses_stay_check") + { + SetLocalInt(oModule, AI_RULE_CORPSES_STAY, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_CORPSES_STAY, JsonInt(bCheck)); + } + else if(sElem == "chbx_wander_check") + { + SetLocalInt(oModule, AI_RULE_WANDER, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_CORPSES_STAY, JsonInt(bCheck)); + } + else if(sElem == "chbx_open_doors_check") + { + SetLocalInt(oModule, AI_RULE_OPEN_DOORS, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_OPEN_DOORS, JsonInt(bCheck)); + } + else if(sElem == "chbx_party_scale_check") + { + if(bCheck) + { + SetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP, GetModuleXPScale()); + ai_CheckXPPartyScale(oDM); + } + else + { + SetModuleXPScale(GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE)); + } + SetLocalInt(oModule, AI_RULE_PARTY_SCALE, bCheck); + jRules = JsonObjectSet(jRules, AI_RULE_PARTY_SCALE, JsonInt(bCheck)); + string sText = IntToString(GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP)); + NuiSetBind(oDM, nToken, "chbx_party_scale_tooltip", JsonString(" PEPS adjusts your XP based on party size from (" + sText + ").")); + sText = IntToString(GetModuleXPScale()); + NuiSetBind(oDM, nToken, "txt_xp_scale", JsonString(sText)); + } + else if(sElem == "chbx_darkness_check") + { + if(bCheck) + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_DARKNESS); + jRules = ai_AddRestrictedSpell(jRules, 159); + jRules = ai_AddRestrictedSpell(jRules, SPELLABILITY_AS_DARKNESS); + jRules = ai_AddRestrictedSpell(jRules, 688); // WildShape_Darkness + } + else + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_DARKNESS, FALSE); + jRules = ai_AddRestrictedSpell(jRules, 159, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELLABILITY_AS_DARKNESS, FALSE); + jRules = ai_AddRestrictedSpell(jRules, 688, FALSE); // WildShape_Darkness + } + } + else if(sElem == "chbx_dispels_check") + { + if(bCheck) + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_LESSER_DISPEL); + jRules = ai_AddRestrictedSpell(jRules, SPELL_DISPEL_MAGIC); + jRules = ai_AddRestrictedSpell(jRules, SPELL_GREATER_DISPELLING); + jRules = ai_AddRestrictedSpell(jRules, SPELL_MORDENKAINENS_DISJUNCTION); + } + else + { + jRules = ai_AddRestrictedSpell(jRules, SPELL_LESSER_DISPEL, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_DISPEL_MAGIC, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_GREATER_DISPELLING, FALSE); + jRules = ai_AddRestrictedSpell(jRules, SPELL_MORDENKAINENS_DISJUNCTION, FALSE); + } + } + else if(sElem == "chbx_timestop_check") + { + if(bCheck) jRules = ai_AddRestrictedSpell(jRules, SPELL_TIME_STOP); + else jRules = ai_AddRestrictedSpell(jRules, SPELL_TIME_STOP, FALSE); + } + ai_SetCampaignDbJson("rules", jRules); + } + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + if(nMouseScroll == 1.0) // Scroll up + { + // Follow range is only changed on non-pc's + if(sElem == "lbl_perc_dist") ai_RulePercDistInc(oDM, GetModule(), 1, nToken); + } + else if(nMouseScroll == -1.0) // Scroll down + { + // Follow range is only changed on non-pc's + if(sElem == "lbl_perc_dist") ai_RulePercDistInc(oDM, GetModule(), -1, nToken); + } + } + } + //************************************************************************** + // Plugins events. + if(sWndId == "dmai_plugin_nui") + { + string sName = ai_RemoveIllegalCharacters(GetName(oDM)); + json jPlugins = ai_GetCampaignDbJson("plugins"); + if(sEvent == "click") + { + if(sElem == "btn_load_plugins") + { + string sScript = JsonGetString(NuiGetBind (oDM, nToken, "txt_plugin")); + if(JsonGetType(JsonArrayGet(jPlugins, 0)) == JSON_TYPE_NULL) jPlugins = JsonArray(); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_buffing"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_forcerest"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_henchmen"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_crafting"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_mod_set"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_debug"); + jPlugins = ai_Plugin_Add(oDM, jPlugins, "pi_test"); + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + if(sElem == "btn_check_plugins") + { + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(TRUE)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + if(sElem == "btn_clear_plugins") + { + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(FALSE)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + else if(sElem == "btn_add_plugin") + { + string sScript = JsonGetString(NuiGetBind (oDM, nToken, "txt_plugin")); + if(JsonGetType(JsonArrayGet(jPlugins, 0)) == JSON_TYPE_NULL) jPlugins = JsonArray(); + jPlugins = ai_Plugin_Add(oDM, jPlugins, sScript); + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + } + else if(GetStringLeft(sElem, 18) == "btn_remove_plugin_") + { + int nIndex = StringToInt(GetStringRight(sElem, 1)); + jPlugins = JsonArrayDel(jPlugins, nIndex); + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMPluginManagerNUI(oDM)); + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oDM, sElem, 2); + } + else if(sEvent == "watch") + { + if(GetStringLeft(sElem, 12) == "chbx_plugin_" && GetStringRight(sElem, 6) == "_check") + { + int nIndex = StringToInt(GetSubString(sElem, 12, 1)); + json jPlugin = JsonArrayGet(jPlugins, nIndex); + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck)); + jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin); + ai_SetCampaignDbJson("plugins", jPlugins); + DelayCommand(0.0, NuiDestroy(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))); + DelayCommand(0.1, ai_CreateDMWidgetNUI(oDM)); + } + } + } + if(sWndId == "dm_widget_manager_nui") + { + //SendMessageToDM(oDM, "sEvent: " + sEvent + " sElem: " + sElem); + if(sEvent == "click") + { + if(sElem == "btn_clear_buttons") + { + object oModule = GetModule(); + SetLocalInt(oModule, sDMWidgetAccessVarname, 0); + SetLocalInt(oModule, sDMAIAccessVarname, 0); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, sDMWidgetAccessVarname, JsonInt(0)); + jRules = JsonObjectSet(jRules, sDMAIAccessVarname, JsonInt(0)); + ai_SetCampaignDbJson("rules", jRules); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMWidgetManagerNUI(oDM)); + return; + } + else if(sElem == "btn_check_buttons") + { + object oModule = GetModule(); + SetLocalInt(oModule, sDMWidgetAccessVarname, 7340028); + SetLocalInt(oModule, sDMAIAccessVarname, 203423743); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, sDMWidgetAccessVarname, JsonInt(7340028)); + jRules = JsonObjectSet(jRules, sDMAIAccessVarname, JsonInt(203423743)); + ai_SetCampaignDbJson("rules", jRules); + DelayCommand(0.0, NuiDestroy(oDM, nToken)); + DelayCommand(0.1, ai_CreateDMWidgetManagerNUI(oDM)); + return; + } + SetLocalInt(oDM, "CHBX_SKIP", TRUE); + DelayCommand(2.0, DeleteLocalInt(oDM, "CHBX_SKIP")); + if(sElem == "btn_cmd_action") NuiSetBind(oDM, nToken, "chbx_cmd_action_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_ACTION))); + else if(sElem == "btn_cmd_guard") NuiSetBind(oDM, nToken, "chbx_cmd_guard_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_GUARD))); + else if(sElem == "btn_cmd_hold") NuiSetBind(oDM, nToken, "chbx_cmd_hold_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_HOLD))); + else if(sElem == "btn_cmd_attack") NuiSetBind(oDM, nToken, "chbx_cmd_attack_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_ATTACK))); + else if(sElem == "btn_cmd_follow") NuiSetBind(oDM, nToken, "chbx_cmd_follow_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_FOLLOW))); + else if(sElem == "btn_follow_target") NuiSetBind(oDM, nToken, "chbx_follow_target_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_FOLLOW_TARGET))); + else if(sElem == "btn_cmd_search") NuiSetBind(oDM, nToken, "chbx_cmd_search_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_SEARCH))); + else if(sElem == "btn_cmd_stealth") NuiSetBind(oDM, nToken, "chbx_cmd_stealth_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_STEALTH))); + else if(sElem == "btn_cmd_ai_script") NuiSetBind(oDM, nToken, "chbx_cmd_ai_script_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_AI_SCRIPT))); + else if(sElem == "btn_cmd_place_trap") NuiSetBind(oDM, nToken, "chbx_cmd_place_trap_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_PLACE_TRAP))); + else if(sElem == "btn_quick_widget") NuiSetBind(oDM, nToken, "chbx_quick_widget_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_SPELL_WIDGET))); + else if(sElem == "btn_spell_memorize") NuiSetBind(oDM, nToken, "chbx_spell_memorize_check", JsonBool(!ai_GetDMWAccessButton(BTN_DM_CMD_MEMORIZE))); + else if(sElem == "btn_buff_short") NuiSetBind(oDM, nToken, "chbx_buff_short_check", JsonBool(!ai_GetDMWAccessButton(BTN_BUFF_SHORT))); + else if(sElem == "btn_buff_long") NuiSetBind(oDM, nToken, "chbx_buff_long_check", JsonBool(!ai_GetDMWAccessButton(BTN_BUFF_LONG))); + else if(sElem == "btn_buff_all") NuiSetBind(oDM, nToken, "chbx_buff_all_check", JsonBool(!ai_GetDMWAccessButton(BTN_BUFF_ALL))); + else if(sElem == "btn_buff_rest") NuiSetBind(oDM, nToken, "chbx_buff_rest_check", JsonBool(!ai_GetDMWAccessButton(BTN_BUFF_REST))); + else if(sElem == "btn_jump_to") NuiSetBind(oDM, nToken, "chbx_jump_to_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_JUMP_TO))); + else if(sElem == "btn_ghost_mode") NuiSetBind(oDM, nToken, "chbx_ghost_mode_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_GHOST_MODE))); + else if(sElem == "btn_camera") NuiSetBind(oDM, nToken, "chbx_camera_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_CAMERA))); + else if(sElem == "btn_inventory") NuiSetBind(oDM, nToken, "chbx_inventory_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_INVENTORY))); + else if(sElem == "btn_familiar") NuiSetBind(oDM, nToken, "chbx_familiar_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_FAMILIAR))); + else if(sElem == "btn_companion") NuiSetBind(oDM, nToken, "chbx_companion_check", JsonBool(!ai_GetDMWAccessButton(BTN_CMD_COMPANION))); + else if(sElem == "btn_ai") NuiSetBind(oDM, nToken, "chbx_ai_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_FOR_PC))); + else if(sElem == "btn_quiet") NuiSetBind(oDM, nToken, "chbx_quiet_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_REDUCE_SPEECH))); + else if(sElem == "btn_ranged") NuiSetBind(oDM, nToken, "chbx_ranged_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_USE_RANGED))); + else if(sElem == "btn_search") NuiSetBind(oDM, nToken, "chbx_search_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_USE_SEARCH))); + else if(sElem == "btn_stealth") NuiSetBind(oDM, nToken, "chbx_stealth_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_USE_STEALTH))); + else if(sElem == "btn_open_door") NuiSetBind(oDM, nToken, "chbx_open_door_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_OPEN_DOORS))); + else if(sElem == "btn_traps") NuiSetBind(oDM, nToken, "chbx_traps_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_REMOVE_TRAPS))); + else if(sElem == "btn_pick_locks") NuiSetBind(oDM, nToken, "chbx_pick_locks_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_PICK_LOCKS))); + else if(sElem == "btn_bash_locks") NuiSetBind(oDM, nToken, "chbx_bash_locks_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_BASH_LOCKS))); + else if(sElem == "btn_magic_level") NuiSetBind(oDM, nToken, "chbx_magic_level_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_MAGIC_LEVEL))); + else if(sElem == "btn_spontaneous") NuiSetBind(oDM, nToken, "chbx_spontaneous_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_NO_SPONTANEOUS))); + else if(sElem == "btn_magic") NuiSetBind(oDM, nToken, "chbx_magic_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_USE))); + else if(sElem == "btn_magic_items") NuiSetBind(oDM, nToken, "chbx_magic_items_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_ITEM_USE))); + else if(sElem == "btn_def_magic") NuiSetBind(oDM, nToken, "chbx_def_magic_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_DEF_MAGIC_USE))); + else if(sElem == "btn_off_magic") NuiSetBind(oDM, nToken, "chbx_off_magic_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_OFF_MAGIC_USE))); + else if(sElem == "btn_heal_out") NuiSetBind(oDM, nToken, "chbx_heal_out_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_HEAL_OUT))); + else if(sElem == "btn_heal_in") NuiSetBind(oDM, nToken, "chbx_heal_in_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_HEAL_IN))); + else if(sElem == "btn_heals_onoff") NuiSetBind(oDM, nToken, "chbx_heals_onoff_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_STOP_SELF_HEALING))); + else if(sElem == "btn_healp_onoff") NuiSetBind(oDM, nToken, "chbx_healp_onoff_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_STOP_PARTY_HEALING))); + else if(sElem == "btn_loot") NuiSetBind(oDM, nToken, "chbx_loot_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_LOOT))); + else if(sElem == "btn_ignore_assoc") NuiSetBind(oDM, nToken, "chbx_ignore_assoc_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_IGNORE_ASSOCIATES))); + else if(sElem == "btn_ignore_traps") NuiSetBind(oDM, nToken, "chbx_ignore_traps_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_IGNORE_TRAPS))); + else if(sElem == "btn_perc_range") NuiSetBind(oDM, nToken, "chbx_perc_range_check", JsonBool(!ai_GetDMAIAccessButton(BTN_AI_PERC_RANGE))); + } + if(sEvent == "watch") + { + if(GetLocalInt(oDM, "CHBX_SKIP")) return; + if(sElem == "chbx_cmd_action_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_ACTION, nToken, sElem); + else if(sElem == "chbx_cmd_guard_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_GUARD, nToken, sElem); + else if(sElem == "chbx_cmd_hold_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_HOLD, nToken, sElem); + else if(sElem == "chbx_cmd_attack_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_ATTACK, nToken, sElem); + else if(sElem == "chbx_cmd_follow_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_FOLLOW, nToken, sElem); + else if(sElem == "chbx_follow_target_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_FOLLOW_TARGET, nToken, sElem); + else if(sElem == "chbx_cmd_search_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_SEARCH, nToken, sElem); + else if(sElem == "chbx_cmd_stealth_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_STEALTH, nToken, sElem); + else if(sElem == "chbx_cmd_ai_script_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_AI_SCRIPT, nToken, sElem); + else if(sElem == "chbx_cmd_place_trap_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_PLACE_TRAP, nToken, sElem); + else if(sElem == "chbx_quick_widget_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_SPELL_WIDGET, nToken, sElem); + else if(sElem == "chbx_spell_memorize_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_DM_CMD_MEMORIZE, nToken, sElem); + else if(sElem == "chbx_buff_short_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_BUFF_SHORT, nToken, sElem); + else if(sElem == "chbx_buff_long_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_BUFF_LONG, nToken, sElem); + else if(sElem == "chbx_buff_all_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_BUFF_ALL, nToken, sElem); + else if(sElem == "chbx_buff_rest_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_BUFF_REST, nToken, sElem); + else if(sElem == "chbx_jump_to_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_JUMP_TO, nToken, sElem); + else if(sElem == "chbx_ghost_mode_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_GHOST_MODE, nToken, sElem); + else if(sElem == "chbx_camera_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_CAMERA, nToken, sElem); + else if(sElem == "chbx_inventory_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_INVENTORY, nToken, sElem); + else if(sElem == "chbx_familiar_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_FAMILIAR, nToken, sElem); + else if(sElem == "chbx_companion_check") ai_SetDMWAccessButtonToCheckbox(oDM, BTN_CMD_COMPANION, nToken, sElem); + else if(sElem == "chbx_ai_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_FOR_PC, nToken, sElem); + else if(sElem == "chbx_quiet_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_REDUCE_SPEECH, nToken, sElem); + else if(sElem == "chbx_ranged_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_USE_RANGED, nToken, sElem); + else if(sElem == "chbx_search_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_USE_SEARCH, nToken, sElem); + else if(sElem == "chbx_stealth_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_USE_STEALTH, nToken, sElem); + else if(sElem == "chbx_open_door_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_OPEN_DOORS, nToken, sElem); + else if(sElem == "chbx_traps_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_REMOVE_TRAPS, nToken, sElem); + else if(sElem == "chbx_pick_locks_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_PICK_LOCKS, nToken, sElem); + else if(sElem == "chbx_bash_locks_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_BASH_LOCKS, nToken, sElem); + else if(sElem == "chbx_magic_level_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_MAGIC_LEVEL, nToken, sElem); + else if(sElem == "chbx_spontaneous_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_NO_SPONTANEOUS, nToken, sElem); + else if(sElem == "chbx_magic_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_NO_MAGIC_USE, nToken, sElem); + else if(sElem == "chbx_magic_items_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_NO_MAGIC_ITEM_USE, nToken, sElem); + else if(sElem == "chbx_def_magic_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_DEF_MAGIC_USE, nToken, sElem); + else if(sElem == "chbx_off_magic_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_OFF_MAGIC_USE, nToken, sElem); + else if(sElem == "chbx_heal_out_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_HEAL_OUT, nToken, sElem); + else if(sElem == "chbx_heal_in_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_HEAL_IN, nToken, sElem); + else if(sElem == "chbx_heals_onoff_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_STOP_SELF_HEALING, nToken, sElem); + else if(sElem == "chbx_healp_onoff_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_STOP_PARTY_HEALING, nToken, sElem); + else if(sElem == "chbx_loot_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_LOOT, nToken, sElem); + else if(sElem == "chbx_ignore_assoc_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_IGNORE_ASSOCIATES, nToken, sElem); + else if(sElem == "chbx_ignore_traps_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_IGNORE_TRAPS, nToken, sElem); + else if(sElem == "chbx_perc_range_check") ai_SetDMAIAccessButtonToCheckbox(oDM, BTN_AI_PERC_RANGE, nToken, sElem); + } + } +} +void ai_SetDMWidgetButtonToCheckbox(object oDM, int nButton, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + ai_SetDMWidgetButton(oDM, nButton, bCheck); +} +void ai_SetDMWAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + ai_SetDMWAccessButton(nButton, bCheck); +} +void ai_SetDMAIAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem) +{ + int bCheck = JsonGetInt(NuiGetBind(oDM, nToken, sElem)); + ai_SetDMAIAccessButton(nButton, bCheck); +} +void ai_RulePercDistInc(object oDM, object oModule, int nIncrement, int nToken) +{ + int nAdjustment = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE) + nIncrement; + if(nAdjustment < 8 || nAdjustment > 11) return; + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, nAdjustment); + string sText; + if(nAdjustment == 8) sText = " Monster perception: Short [10 Sight / 10 Listen]"; + else if(nAdjustment == 9) sText = " Monster perception: Medium [20 Sight / 20 Listen]"; + else if(nAdjustment == 10) sText = " Monster perception: Long [35 Sight / 20 Listen]"; + else sText = " Monster perception: Default [Monster's default values]"; + NuiSetBind(oDM, nToken, "lbl_perc_dist_label", JsonString(sText)); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_MON_PERC_DISTANCE, JsonInt(nAdjustment)); + ai_SetCampaignDbJson("rules", jRules); +} +json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE) +{ + object oModule = GetModule(); + json jRSpells = GetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS); + int nIndex, nMaxIndex = JsonGetLength(jRSpells); + if(bRestrict) + { + while(nIndex < nMaxIndex) + { + if(JsonGetInt(JsonArrayGet(jRSpells, nIndex)) == nSpell) return jRules; + nIndex++; + } + jRSpells = JsonArrayInsert(jRSpells, JsonInt(nSpell)); + } + else + { + while(nIndex < nMaxIndex) + { + if(JsonGetInt(JsonArrayGet(jRSpells, nIndex)) == nSpell) + { + jRSpells = JsonArrayDel(jRSpells, nIndex); + break; + } + nIndex++; + } + } + SetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS, jRSpells); + return JsonObjectSet(jRules, AI_RULE_RESTRICTED_SPELLS, jRSpells); +} +void ai_SelectToGroup(object oDM, string sElem) +{ + string sGroup = GetStringRight(sElem, 1); + SetLocalString(oDM, AI_TARGET_MODE, "DM_SELECT_GROUP" + sGroup); + ai_SendMessages("Select a creature to add to group " + sGroup + ". Selecting yourself will clear group1.", AI_COLOR_YELLOW, oDM); + EnterTargetingMode(oDM, OBJECT_TYPE_CREATURE, MOUSECURSOR_PICKUP, MOUSECURSOR_PICKUP_DOWN); +} +void ai_DMSelectAction(object oDM, string sElem) +{ + string sGroup = GetStringRight(sElem, 1); + SetLocalString(oDM, AI_TARGET_MODE, "DM_ACTION_GROUP" + sGroup); + ai_SendMessages(GetName(oDM) + " select an action for group" + sGroup + ".", AI_COLOR_YELLOW, oDM); + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_DMChangeMoveSpeed(object oDM, string sElem, int nSpeed) +{ + string sGroup = GetStringRight(sElem, 1); + json jGroup = GetLocalJson(oDM, "DM_GROUP" + sGroup); + if(JsonGetType(jGroup) == JSON_TYPE_NULL) + { + ai_SendMessages("This group does not contain any creatures!", AI_COLOR_RED, oDM); + return; + } + jGroup = JsonArraySet(jGroup, 0, JsonInt(nSpeed)); + SetLocalJson(oDM, "DM_GROUP" + sGroup, jGroup); + object oLeader = GetObjectByUUID(JsonGetString(JsonArrayGet(jGroup, 1))); + string sName = GetName(oLeader); + string sText = " " + sName + "'s group"; + if(nSpeed == 0) sText += " [Walk]"; + else sText += " [Run]"; + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText)); + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_COMMAND_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText)); +} diff --git a/src/module/nss/0e_onclientload.nss b/src/module/nss/0e_onclientload.nss new file mode 100644 index 0000000..041d49f --- /dev/null +++ b/src/module/nss/0e_onclientload.nss @@ -0,0 +1,23 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_onclientload + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnClientLoad script; + This will fire when the client is loading. + + If you have your own OnClientLoad event script just take the below + script lines and add them into your OnClientLoad script. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_menus_dm" +#include "0i_module" +void main() +{ + object oCreature = OBJECT_SELF; + // This can be moved to the OnClientLoad script event of your module. + if(ai_GetIsCharacter(oCreature)) ai_CheckPCStart(oCreature); + // If this is a server you can add this as well. + else if(AI_SERVER && (GetIsDM(oCreature) || GetIsPlayerDM(oCreature))) + { + ai_CheckPCStart(oCreature); + } +} diff --git a/src/module/nss/0e_player_target.nss b/src/module/nss/0e_player_target.nss new file mode 100644 index 0000000..16b83fb --- /dev/null +++ b/src/module/nss/0e_player_target.nss @@ -0,0 +1,154 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: 0e_player_target + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + OnPlayerTarget event script + Used to allow player targeting while passing any module player targeting + script through to work as intended. + + We Use a string variable upon the player using the targeting mode to define the + action of the target. + AI_TARGET_MODE is the constant used. + AI_TARGET_ASSOCIATE is the associate that triggered the target mode. +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_player_target" +void main() +{ + object oPC = GetLastPlayerToSelectTarget(); + // Get any plugin target scripts and run it instead of this one. + string sPluginTargetScript = GetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT); + if(sPluginTargetScript != "") + { + DeleteLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT); + ExecuteScript(sPluginTargetScript, oPC); + // Remove the plugin script as it must be set each time the plugin uses the target event. + } + else + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + vector vTarget = GetTargetingModeSelectedPosition(); + location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + object oAssociate = GetLocalObject(oPC, AI_TARGET_ASSOCIATE); + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + // ********************* Exiting Target Actions ************************ + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget) && vTarget == Vector()) + { + if(sTargetMode == "ASSOCIATE_ACTION_ALL") + { + ai_SendMessages("You have exited selecting an action for the party.", AI_COLOR_YELLOW, oPC); + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + if(GetLocalInt(oPC, sGhostModeVarname)) ai_OriginalRemoveAllActionMode(oPC); + } + else ai_RemoveAllActionMode(oPC); + } + else if(sTargetMode == "ASSOCIATE_ACTION") + { + ai_SendMessages("You have exited selecting an action for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC); + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + if(GetLocalInt(oPC, sGhostModeVarname)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + else + { + ai_SetAIMode(oAssociate, AI_MODE_COMMANDED, FALSE); + if(ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST) && !ai_GetAIMode(oPC, AI_MODE_GHOST) && + GetLocalInt(oAssociate, sGhostModeVarname)) + { + + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + ExecuteScript("nw_ch_ac1", oAssociate); + } + } + else if(sTargetMode == "ASSOCIATE_GET_TRAP") + { + ai_SendMessages(GetName(oAssociate) + " has exited selecing a trap!", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "ASSOCIATE_PLACE_TRAP") + { + ai_SendMessages(GetName(oAssociate) + " has exited placing the trap!", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DM_SELECT_CAMERA_VIEW") + { + AttachCamera(oPC, oPC); + ai_SendMessages(GetName(oPC) + " has defaulted camera view back to the player!", AI_COLOR_YELLOW, oPC); + } + return; + } + // ************************* Targeted Actions ************************** + else + { + // This action makes an associates move to vTarget. + if(sTargetMode == "ASSOCIATE_ACTION_ALL") + { + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + ai_OriginalActionAllAssociates(oPC, oTarget, lLocation); + } + else ai_ActionAllAssociates(oPC, oTarget, lLocation); + } + else if(sTargetMode == "ASSOCIATE_ACTION") + { + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + AssignCommand(oAssociate, ai_OriginalActionAssociate(oPC, oTarget, lLocation)); + } + else AssignCommand(oAssociate, ai_ActionAssociate(oPC, oTarget, lLocation)); + } + else if(sTargetMode == "ASSOCIATE_FOLLOW_TARGET") ai_SelectFollowTarget(oPC, oAssociate, oTarget); + else if(sTargetMode == "ASSOCIATE_GET_TRAP") ai_SelectTrap(oPC, oAssociate, oTarget); + else if(sTargetMode == "ASSOCIATE_PLACE_TRAP") AssignCommand(oAssociate, ai_PlaceTrap(oPC, lLocation)); + else if(sTargetMode == "ASSOCIATE_USE_ITEM") + { + if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID; + ai_UseWidgetItem(oPC, oAssociate, oTarget, lLocation); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sTargetMode == "ASSOCIATE_USE_FEAT") + { + if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID; + ai_UseWidgetFeat(oPC, oAssociate, oTarget, lLocation); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sTargetMode == "ASSOCIATE_CAST_SPELL") + { + if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID; + ai_CastWidgetSpell(oPC, oAssociate, oTarget, lLocation); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + } + else if(sTargetMode == "DM_SELECT_CAMERA_VIEW") + { + AttachCamera(oPC, oTarget); + ai_SendMessages(GetName(oPC) + " has changed the camera view to " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DM_SELECT_OPEN_INVENTORY") + { + if(LineOfSightObject(oPC, oTarget)) + { + OpenInventory(oTarget, oPC); + ai_SendMessages("You have opened the inventory of "+ GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + } + else ai_SendMessages(GetName(oTarget) + " is not in your line of sight!", AI_COLOR_YELLOW, oPC); + } + else if(GetStringLeft(sTargetMode, 15) == "DM_SELECT_GROUP") + { + ai_AddToGroup(oPC, oTarget, sTargetMode); + } + else if(GetStringLeft(sTargetMode, 15) == "DM_ACTION_GROUP") + { + ai_DMAction(oPC, oTarget, lLocation, sTargetMode); + } + // Get saved module player target script and execute it for pass through compatibility. + string sModuleTargetScript = GetLocalString(GetModule(), AI_MODULE_TARGET_EVENT); + ExecuteScript(sModuleTargetScript); + } + } +} diff --git a/src/module/nss/0e_prc_ch_events.nss b/src/module/nss/0e_prc_ch_events.nss new file mode 100644 index 0000000..3028e9c --- /dev/null +++ b/src/module/nss/0e_prc_ch_events.nss @@ -0,0 +1,78 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0e_prc_ch_events +//////////////////////////////////////////////////////////////////////////////// + associate event handler while using the PRC. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +#include "x0_i0_assoc" +void main() +{ + object oCreature = OBJECT_SELF; + int nEvent = GetCurrentlyRunningEvent(); + //WriteTimestampedLogEntry("0e_prc_ch_events [13] " + GetName(oCreature) + " nEvent: " + IntToString(nEvent)); + switch (nEvent) + { + case EVENT_SCRIPT_CREATURE_ON_HEARTBEAT: + { + if(GetLocalInt(oCreature, "CohortID")) ExecuteScript("prc_ai_coh_hb"); + ExecuteScript("nw_ch_ac1", oCreature); + ExecuteScript("prc_npc_hb", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_NOTICE: + { + ExecuteScript("nw_ch_ac2", oCreature); + ExecuteScript("prc_npc_percep", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DIALOGUE: + { + //if(GetLocalInt(oCreature, "CohortID")) ExecuteScript("prc_ai_coh_conv"); + ExecuteScript("nw_ch_ac4", oCreature); + //ExecuteScript("prc_npc_conv", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED: + { + ExecuteScript("nw_ch_ac5", oCreature); + ExecuteScript("prc_npc_physatt", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DAMAGED: + { + ExecuteScript("nw_ch_ac6", oCreature); + ExecuteScript("prc_npc_damaged", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT: + { + ExecuteScript("nw_ch_acb", oCreature); + ExecuteScript("prc_npc_spellat", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND: + { + ExecuteScript("nw_ch_ac3", oCreature); + ExecuteScript("prc_npc_combat", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR: + { + ExecuteScript("nw_ch_ace", oCreature); + ExecuteScript("prc_npc_blocked", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_RESTED: + { + ExecuteScript("nw_ch_aca", oCreature); + //ExecuteScript("prc_npc_rested", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DISTURBED: + { + ExecuteScript("nw_ch_ac8", oCreature); + ExecuteScript("prc_npc_disturb", oCreature); + break; + } + } +} diff --git a/src/module/nss/0i_actions.nss b/src/module/nss/0i_actions.nss new file mode 100644 index 0000000..7d7d2d7 --- /dev/null +++ b/src/module/nss/0i_actions.nss @@ -0,0 +1,2325 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_actions +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts for action in and out of combat. + + Detect Mode: + Passive(default) mode + * Trap detection radius: 5ft + * Trap detection rate: every 6 seconds + * Trap detection roll: d20 + 1/2 skill + * Spot/Listen roll: d10 + 1/2 skill + + Active(Detect) mode + * Trap detection radius: 10ft + * Trap detection rate: every 3 seconds + * Trap detection roll: d20 + skill + * Spot/Listen roll: d20 + skill + + Stealth checks + * Player detects stealth: 5 times per second. + * Player rolls for hide/move silently & spot/listen: every 6 seconds. + * NPC detects stealth: 4 seconds + * NPC rolls for hide/move silently & spot/listen: every 6 seconds. + + Listen/Move Silently: + * Cannot detect silenced creatures. + * Cannot detect sanctuaried creatures. + * Can only detect invisible (or when your blind) creatures within max attack range. + * Listen checks are made each round for success and failur. + * Outdoors: Objects between you and the target gives a +5 DC for every 40cm of thickness. + * Indoors: No Line of sight and the target is within 40 meters gives a +2 DC. + * +10 DC in combat for the target. + * +5 DC if the target is standing still. + * -5 DC if the listener is standing still. + * +1 DC for every 3 meters of distance to the target. + * Relative size modifiers for both: Tiny +8, Small +4, Medium 0, Larget -4, Huge -8. + * Favored enemy bonuses. + + Spot/Hide: + * Cannot spot invisible creatures. + * Cannot spot any creatures while blinded. + * Night time: Spotter has not light or darkvision +5 DC. + * Night time: Target has a light no them -10 DC. + * +5 DC if target is behind the spotter. + * +10 DC if the spotter are in combat. + * +5 DC if the target is standing still. + * -5 DC if the spotter is standing still. + * Relative size modifiers for both: Tiny +8, Small +4, Medium 0, Larget -4, Huge -8. + * Favored enemy bonuses. + +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_talents" +#include "x0_inc_henai" +#include "X0_I0_ANIMS" +// Chooses an action in combat and executes it for oCreature that is an associate. +void ai_DoAssociateCombatRound(object oCreature, object oTarget = OBJECT_INVALID); +// Sets variables and states for oAssociate to start combat. +void ai_StartAssociateCombat(object oAssociate, object oTarget = OBJECT_INVALID); +// Chooses an action in combat and executes it for oCreature that is a monster. +void ai_DoMonsterCombatRound(object oCreature); +// Sets variables and states for oMonster to start combat. +void ai_StartMonsterCombat(object oMonster); +// Return the distance that is set for how close we should follow our master. +float ai_GetFollowDistance(object oCreature); +// Returns TRUE if the caller's distance is greater than fDistance from who they +// are following. Unless they are cowardly or in stand ground mode. +// This will also force the caller to move towards them. +int ai_StayClose(object oCreature); +// Returns TRUE if oCreature becomes invisible or hides. +int ai_TryToBecomeInvisible(object oCreature); +// Returns TRUE if oCreature continues to bash a door. +int ai_BashDoorCheck(object oCreature); +// Returns TRUE if we find an hidden creature within battle and do an action. +// If oCreature is too far away they will run upto 14 meters of the invisible creature. +// If oCreature is close they will attempt to cast a spell or search for them. +// bMonster needs to be set for monsters otherwise we do associate perception checks. +// fRange is how close we want to get to hidden targets. +int ai_SearchForHiddenCreature(object oCreature, int bMonster, object oHidden = OBJECT_INVALID, float fRange = 1.0); +// Returns TRUE if oCreature fails a moral check. +// We only make moral checks once we are below AI_HEALTH_WOUNDED health percent. +// If we are at AI_HEALTH_BLOODY hp percent then add + AI_MORAL_INC_DC to the Check. +int ai_MoralCheck(object oCreature); +// Returns TRUE if oCreature is in and nSpell is a dangerous Area Of Effect. +// Used in the on spell cast at scripts. [nw_c2_defaultb and nw_ch_acb]. +int ai_GetInAOEReaction(object oCreature, object oCaster, int nSpell); +// Have the associate speak a random voice from VOICE_CHAT_*. +// nRoll is the number to roll. If nRoll is 0 then it will SpeakString(sVoiceChatArray); +// sVoiceChatArray is an array of VOICE_CHAT_* numbers over nRoll. +// example(4, ":3:4:8:7:") will roll a d4() picking from 3,4,8,7 of VOICE_CHAT_*. +// if nRoll is higher than the number of VOICE_CHAT_* then it will not speak. +void ai_HaveCreatureSpeak(object oCreature, int nRoll, string sVoiceChatArray, int bImportant = FALSE); +// Returns if a spell talent was used. +// This is a common set of AI scripts ran on associate spell casters. +int ai_CheckForAssociateSpellTalent(object oAssociate, int nInMelee, int nMaxLevel, int nRound = 0); +// Targets the best creature oCreature it can see. +// This checks all physcal attack talents starting with ranged attacks then melee. +// Using TALENT_CATEGORY_HARMFUL_MELEE [22] talents. +// If no talents are used it will do either a ranged attack or a melee attack. +void ai_DoPhysicalAttackOnBest(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Targets the nearest creature oCreature it can see. +// This checks all physcal attack talents starting with ranged attacks then melee. +// Using TALENT_CATEGORY_HARMFUL_MELEE [22] talents. +// If no talents are used it will do either a ranged attack or a melee attack. +void ai_DoPhysicalAttackOnNearest(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Targets the weakest creature oCreature can see. +// This checks all physcal attack talents starting with ranged attacks then melee. +// Using TALENT_CATEGORY_HARMFUL_MELEE [22] talents. +// If no talents are used it will do either a ranged attack or a melee attack. +void ai_DoPhysicalAttackOnLowestCR(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Returns TRUE if they equip a melee weapon, FALSE if they don't. +// This also calls for the next combat round. +int ai_InCombatEquipBestMeleeWeapon(object oCreature); +// Returns TRUE if they equip a ranged weapon, FALSE if they don't. +// This also calls for the next combat round. +int ai_InCombatEquipBestRangedWeapon(object oCreature); +// Action wrapper for ai_TryHealing. +void ai_ActionTryHealing(object oCreature, object oTarget); +// Returns TRUE if oCreature heals oTarget. +// This uses an action and must use AssignCommand or OBJECT_SELF is the caster! +int ai_TryHealing(object oCreature, object oTarget, int bForce = FALSE); +// oCreature will move into the area looking for creatures. +void ai_ScoutAhead(object oCreature); +// Have oCreature search one object, may continue from that object. +void ai_SearchObject(object oCreature, object oObject, object oMaster, int bOnce = FALSE); +// Returns TRUE if oCreature disarms oTrap. +// bForce if TRUE, oCreature will try to disarm the trap even if they have tried before. +int ai_ReactToTrap(object oCreature, object oTrap, int bForce = FALSE); +// Returns TRUE if oCreature opens oLocked object. +// This will make oCreature open oLocked either by picking or casting a spell. +// bForce if TRUE, oCreature will try to pick the lock even if they have tried before. +int ai_AttemptToByPassLock(object oCreature, object oLocked, int bForce = FALSE); +// Returns TRUE if oCreature opens oDoor. +// bForce if TRUE, oCreature will try to open the door even if they have tried before. +int ai_AttemptToOpenDoor(object oCreature, object oDoor, int bForce = FALSE); +// Action for Checking nearby objects for traps, locks and loot. +void ai_ActionCheckNearbyObjects(object oCreature); +// oCreature will check nearby objects and see what they should do based upon +// selected actions by the player. +int ai_CheckNearbyObjects(object oCreature); +// Used to determine special behaviors for oCeature. +void ai_DetermineSpecialBehavior(object oCreature); +// The target object flees to the specified way point and then destroys itself, +// to be respawned at a later point. For unkillable sign post characters +// who are not meant to fight back. +void ai_ActivateFleeToExit(object oCreature); +// Returns TRUE if oCreature should flee to an exit. +int ai_GetFleeToExit(object oCreature); +// Does random animation in a close distance for creatures. +void ai_AmbientAnimations(); + +void ai_DoAssociateCombatRound(object oCreature, object oTarget = OBJECT_INVALID) +{ + if(ai_StayClose(oCreature)) return; + // Is the target our Player has locked in dead? If so then clear it. + if(GetIsDead(GetLocalObject(oCreature, AI_PC_LOCKED_TARGET))) DeleteLocalObject(oCreature, AI_PC_LOCKED_TARGET); + // Setup the combat state for this round of combat. + object oNearestEnemy = ai_SetCombatState(oCreature); + // If we are in standground mode we only fight if the enemy is near us. + if(ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND) && + ai_GetEnemyAttackingMe(oCreature) == OBJECT_INVALID) oNearestEnemy = OBJECT_INVALID; + // If we found an Enemy or we have a Target then continue into the combat round. + if(oNearestEnemy != OBJECT_INVALID || oTarget != OBJECT_INVALID) + { + // In combat we should stop searching. + if(GetActionMode(oCreature, ACTION_MODE_DETECT) && !GetHasFeat(FEAT_KEEN_SENSE)) + { + SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + } + ai_SetCombatRound(oCreature); + string sAI = GetLocalString(oCreature, AI_COMBAT_SCRIPT); + if(AI_DEBUG) ai_Debug("0i_actions", "167", " AI not Coward/Peaceful: " + + IntToString(sAI != "ai_coward" && sAI != "ai_a_peaceful")); + // If we are using a normal AI script and are polymorphed we should use + // the polymorph AI script. + if(sAI != "ai_coward" && sAI != "ai_a_peaceful") + { + if(AI_DEBUG) ai_Debug("0i_actions", "173", "Should we use polymorph? " + + IntToString(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature))); + if(AI_DEBUG) + { + if(ai_GetIsHidden(oCreature)) + { + ai_Debug("0i_actions", "179", "We are hidden!" + + " Can they see us? " + IntToString(ai_GetNearestIndexThatSeesUs(oCreature))); + } + } + if(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature)) + { + sAI = "ai_a_polymorphed"; + } + else if(ai_GetIsHidden(oCreature) && !ai_GetNearestIndexThatSeesUs(oCreature)) sAI = "ai_a_invisible"; + } + if(sAI == "") sAI = "ai_a_default"; + if(AI_DEBUG) ai_Debug("0i_actions", "190", "********** " + GetName (oCreature) + " **********"); + if(AI_DEBUG) ai_Debug("0i_actions", "191", "********** " + sAI + " **********"); + ai_ClearCreatureActions(); + if(AI_DEBUG) ai_Counter_Start(); + // Execute this creatures AI routine. + ExecuteScript(sAI, oCreature); + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + " has finalized round action."); + return; + } + // We have exhausted our check for an enemy. Combat is over. + if(AI_DEBUG) ai_Debug("0i_actions", "200", "---------- " + GetName (OBJECT_SELF) + "'s combat has ended! ----------"); + ai_ClearCombatState(oCreature); + // Run the heartbeat script so we start doing our actions out of combat. + ExecuteScript("nw_ch_ac1", oCreature); +} +void ai_StartAssociateCombat(object oAssociate, object oTarget = OBJECT_INVALID) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "217", "---------- " + GetName(oAssociate) + " is starting combat! ----------"); + ai_SetCreatureTalents(oAssociate, FALSE); + ai_CheckXPPartyScale(oAssociate); + ai_DoAssociateCombatRound(oAssociate, oTarget); +} +void ai_DoMonsterCombatRound(object oMonster) +{ + object oNearestEnemy = ai_SetCombatState(oMonster); + if(oNearestEnemy != OBJECT_INVALID) + { + if(GetActionMode(oMonster, ACTION_MODE_DETECT) && !GetHasFeat(FEAT_KEEN_SENSE, oMonster)) + SetActionMode(oMonster, ACTION_MODE_DETECT, FALSE); + ai_SetCombatRound(oMonster); + string sAI = GetLocalString(oMonster, AI_COMBAT_SCRIPT); + if(sAI != "ai_coward") + { + if(GetAppearanceType(oMonster) != ai_GetNormalAppearance(oMonster)) + { + sAI = "ai_polymorphed"; + } + else if(ai_GetIsHidden(oMonster) && !ai_GetNearestIndexThatSeesUs(oMonster)) sAI = "ai_invisible"; + } + if(sAI == "") sAI = "ai_default"; + if(AI_DEBUG) ai_Debug("0i_actions", "230", "********** " + GetName (oMonster) + " **********"); + if(AI_DEBUG) ai_Debug("0i_actions", "231", "********** " + sAI + " **********"); + // We clear actions here and setup multiple actions to the queue for oCreature. + ai_ClearCreatureActions(); + ai_Counter_Start(); + ExecuteScript(sAI, oMonster); + ai_Counter_End(GetName(oMonster) + " is ending round calculations."); + return; + } + // Check to see if we just didn't see the enemies. + if(GetLocalInt(oMonster, AI_ENEMY_NUMBERS) && + ai_SearchForHiddenCreature(oMonster, TRUE)) return; + // We have exhausted our check for an enemy. Combat is over. + ai_EndCombatRound(oMonster); + ai_ClearCombatState(oMonster); + // Run the heartbeat script so we start doing our actions out of combat. + ExecuteScript("nw_c2_default1", oMonster); + if(AI_DEBUG) ai_Debug("0i_actions", "247", GetName(oMonster) + "'s combat has ended!"); + return; +} +void ai_StartMonsterCombat(object oMonster) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "264", "---------- " + GetName(oMonster) + " is starting combat! ----------"); + ai_SetCreatureTalents(oMonster, TRUE); + ai_DoMonsterCombatRound(oMonster); +} +float ai_GetFollowDistance(object oCreature) +{ + // Also check for size of creature and adjust based on that. + float fDistance = StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oCreature))); + return GetLocalFloat(oCreature, AI_FOLLOW_RANGE) + fDistance; +} +int ai_StayClose(object oCreature) +{ + if(ai_GetIsCharacter(oCreature) || + ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND) || + GetLocalString(oCreature, AI_COMBAT_SCRIPT) == "ai_a_peaceful" || + GetLocalString(oCreature, AI_COMBAT_SCRIPT) == "ai_coward") return FALSE; + object oMaster = GetMaster(oCreature); + // We stay within our perception range of who we are following. + float fPerceptionDistance = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fPerceptionDistance == 0.0) + { + fPerceptionDistance = GetLocalFloat(oMaster, AI_ASSOC_PERCEPTION_DISTANCE); + if(fPerceptionDistance == 0.0) fPerceptionDistance = 20.0; + } + object oTarget = GetLocalObject(oCreature, AI_FOLLOW_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oMaster; + if(AI_DEBUG) ai_Debug("0i_associates", "214", "Distance from who we are following in combat." + + " oFollowing: " + FloatToString(GetDistanceBetween(oTarget, oCreature), 0, 2) + " fPerceptionDistance: " + FloatToString(fPerceptionDistance, 0, 2)); + if(GetDistanceBetween(oTarget, oCreature) < fPerceptionDistance) return FALSE; + ai_ClearCreatureActions(); + if(AI_DEBUG) ai_Debug("0i_associates", "218", "We are too far away! Move back to our master."); + ActionMoveToObject(oTarget, TRUE, ai_GetFollowDistance(oCreature)); + return TRUE; +} +int ai_TryToBecomeInvisible(object oCreature) +{ + // If we are invisible then we don't need to check this. + if(!ai_GetIsHidden(oCreature)) return FALSE; + // If we are not invisible lets try. + int nDarkness; + if(GetHasSpell(SPELL_DARKNESS, oCreature) && ai_GetHasEffectType(oCreature, EFFECT_TYPE_ULTRAVISION)) nDarkness = TRUE; + if(GetHasSpell(SPELL_IMPROVED_INVISIBILITY, oCreature) || GetHasSpell(SPELL_INVISIBILITY, oCreature) || + GetHasSpell(SPELL_INVISIBILITY_SPHERE, oCreature) ||(nDarkness) || + GetHasSpell(SPELL_SANCTUARY, oCreature) || GetHasSpell(SPELL_ETHEREALNESS, oCreature) || + GetHasSpell(799/*SPELLABILITY_VAMPIRE_INVISIBILITY*/) || + GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature) == TRUE) + { + // This bit ported directly from Jasperre + // Can anyone see me?(has spell effects of X) + // The point of this is to see if its even worthwhile to go invisbile + // or will it be immediately dispeled. + object oSeeMe = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oCreature, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_HAS_SPELL_EFFECT, SPELL_TRUE_SEEING); + if(oSeeMe == OBJECT_INVALID) + { + oSeeMe = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oCreature, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_HAS_SPELL_EFFECT, SPELL_SEE_INVISIBILITY); + } + if(oSeeMe == OBJECT_INVALID) + { + // Check non-invisibility options first. Since they can be used + // while near enemies. + if(GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature)) + { + // Go into stealth mode + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + if(AI_DEBUG) ai_Debug("0i_actions", "207", "Using HIDE_IN_PLAIN_SIGHT!"); + return TRUE; + } + if(nDarkness) + { + ai_SetLastAction(oCreature, SPELL_DARKVISION); + ActionCastSpellAtObject(SPELL_DARKVISION, oCreature); + return TRUE; + } + if(GetHasSpell(SPELL_ETHEREALNESS, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_ETHEREALNESS); + ActionCastSpellAtObject(SPELL_ETHEREALNESS, oCreature); + return TRUE; + } + if(GetHasSpell(SPELL_SANCTUARY, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_SANCTUARY); + ActionCastSpellAtObject(SPELL_SANCTUARY, oCreature); + return TRUE; + } + // Get the nearest Enemy and how close they are. + // Use this to keep invisibility from being spammed in melee. + object oEnemy = ai_GetNearestEnemy(oCreature); + if(GetDistanceBetween(oCreature, oEnemy) > AI_RANGE_MELEE) + { + if(GetHasSpell(SPELL_IMPROVED_INVISIBILITY, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_IMPROVED_INVISIBILITY); + ActionCastSpellAtObject(SPELL_IMPROVED_INVISIBILITY, oCreature); + return TRUE; + } + if(GetHasSpell(SPELL_INVISIBILITY, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_INVISIBILITY); + ActionCastSpellAtObject(SPELL_INVISIBILITY, oCreature); + return TRUE; + } + if(GetHasSpell(SPELL_INVISIBILITY_SPHERE, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_INVISIBILITY_SPHERE); + ActionCastSpellAtObject(SPELL_INVISIBILITY_SPHERE, oCreature); + return TRUE; + } + if(GetHasSpell(799/*SPELLABILITY_VAMPIRE_INVISIBILITY*/, oCreature)) + { + ai_SetLastAction(oCreature, 799/*SPELLABILITY_VAMPIRE_INVISIBILITY*/); + ActionCastSpellAtObject(799/*SPELLABILITY_VAMPIRE_INVISIBILITY*/, oCreature); + return TRUE; + } + } + } + } + return FALSE; +} +int ai_SearchForHiddenCreature(object oCreature, int bMonster, object oInvisible = OBJECT_INVALID, float fRange = 1.0) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "358", GetName(oCreature) + " is searching for an invisible creature (" + + GetName(oInvisible) + ")."); + if(oInvisible == OBJECT_INVALID) + { + // Have we seen anyone go invisible? + oInvisible = GetLocalObject(oCreature, AI_IS_INVISIBLE); + if(oInvisible == OBJECT_INVALID || GetIsDead(oInvisible)) + { + oInvisible = ai_GetNearestEnemy(oCreature, 1, 7, PERCEPTION_HEARD_AND_NOT_SEEN); + if(oInvisible == OBJECT_INVALID) oInvisible = ai_GetNearestEnemy(oCreature); + } + } + float fPerceptionDistance, fDistance; + if(bMonster) + { + GetDistanceBetween(oCreature, oInvisible); + fPerceptionDistance = GetLocalFloat(GetModule(), AI_RULE_PERCEPTION_DISTANCE); + } + else + { + // We want to use the distance between the PC and target not us. + object oMaster = GetMaster(); + if(oMaster != OBJECT_INVALID) fDistance = GetDistanceBetween(oMaster, oInvisible); + else GetDistanceBetween(oCreature, oInvisible); + fPerceptionDistance = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fPerceptionDistance == 0.0) fPerceptionDistance = 20.0; + } + if(AI_DEBUG) ai_Debug("0i_actions", "383", "Is invisible: " + GetName(oInvisible) + + " fDistance: " + FloatToString(fDistance, 0, 2) + + " fPerceptionDistance: " + FloatToString(fPerceptionDistance, 0, 2)); + // Might need to end combat at this point? + if(fDistance > fPerceptionDistance) return FALSE; + // If we are close enough then lets look for them. + if(fDistance < AI_RANGE_LONG) + { + // nHidden 1 = Invisible effects, 2 = Darkness effects, 3 = Sanctuary effects, 4 Stealth. + int nHidden = ai_GetIsHidden(oInvisible); + if(nHidden) + { + // They have a magical effect! Is there a spell we can use to see? + if(nHidden < 4) + { + if(AI_DEBUG) ai_Debug("0i_actions", "399", " They are using magic to hide: " + + IntToString(nHidden)); + // True Seeing pierces all types of magical hiding. + if(GetHasSpell(SPELL_TRUE_SEEING, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_TRUE_SEEING); + ActionCastSpellAtObject(SPELL_TRUE_SEEING, oCreature); + return TRUE; + } + if(nHidden == 1 || nHidden == 3) // Invisibility or Ethereal effect. + { + if(GetHasSpell(SPELL_SEE_INVISIBILITY, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_SEE_INVISIBILITY); + ActionCastSpellAtObject(SPELL_SEE_INVISIBILITY, oCreature); + return TRUE; + } + if(GetHasSpell(SPELL_INVISIBILITY_PURGE, oCreature)) + { + ai_SetLastAction(oCreature, SPELL_INVISIBILITY_PURGE); + ActionCastSpellAtObject(SPELL_INVISIBILITY_PURGE, oCreature); + return TRUE; + } + } + if(nHidden == 2) // Darkness spell effect. + { + if(GetHasSpell(SPELL_DARKVISION)) + { + ai_SetLastAction(oCreature, SPELL_DARKVISION); + ActionCastSpellAtObject(SPELL_DARKVISION, oCreature); + return TRUE; + } + } + // To be able to attack a magically hidden foe we have to be + // with in melee attack range. Cannot hear Ethereal foes! + // We will automatically hear them once we are within range. + // We also walk so we don't give attacks of opportunity. + if(nHidden < 3) + { + if(AI_DEBUG) ai_Debug("0i_actions", "437", " We have no spells to counter with. Moving up to attack!"); + SetLocalInt(oCreature, AI_AM_I_SEARCHING, TRUE); + ActionMoveToObject(oInvisible); + ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING)); + if(ai_GetIsInCombat(oCreature)) ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + } + else // They are using stealth! + { + if(AI_DEBUG) ai_Debug("0i_actions", "447", " Using Detect mode and moving up."); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + SetLocalInt(oCreature, AI_AM_I_SEARCHING, TRUE); + // We use to move to the object but that is creepy! + //ActionMoveToObject(oInvisible, FALSE, fRange); + ActionMoveToLocation(GetLocation(oInvisible), FALSE); + ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING)); + if(ai_GetIsInCombat(oCreature)) ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + } + else // They are not hidden, then that means we can hear them but not see them. + // Probably behind a wall or door. + { + SetLocalInt(oCreature, AI_AM_I_SEARCHING, TRUE); + // We use to move to the object but that is creepy! + //ActionMoveToObject(oInvisible, FALSE, fRange); + ActionMoveToLocation(GetLocation(oInvisible), FALSE); + ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING)); + if(ai_GetIsInCombat(oCreature)) ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + } + else // We need to get closer to start looking for them. + { + if(AI_DEBUG) ai_Debug("0i_actions", "469", "Moving towards invisible creature from a distance: " + GetName(oInvisible)); + SetLocalInt(oCreature, AI_AM_I_SEARCHING, TRUE); + // We use to move to the object but that is creepy! + //ActionMoveToObject(oInvisible, TRUE, 14.0); + ActionMoveToLocation(GetLocation(oInvisible), FALSE); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING))); + if(ai_GetIsInCombat(oCreature)) ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + return FALSE; +} +int ai_MoralCheck(object oCreature) +{ + // If we are immune to fear then we are immune to MoralChecks! + // Constructs and Undead are also immune to fear. + int nRaceType = GetRacialType(oCreature); + if(!GetLocalInt(GetModule(), AI_RULE_MORAL_CHECKS) || GetIsImmune(oCreature, IMMUNITY_TYPE_FEAR) || + nRaceType == RACIAL_TYPE_UNDEAD || + nRaceType == RACIAL_TYPE_CONSTRUCT || + ai_GetIsCharacter(oCreature)) return FALSE; + // Moral DC is AI_WOUNDED_MORAL_DC - The number of allies. + // or AI_BLOODY_MORAL_DC - number of allies. + int nDC; + int nHpPercent = ai_GetPercHPLoss(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + // We only make moral checks if we are below half hitpoints and the Difficulty should be adjusted to -10 at 0. + if(nHpPercent <= AI_HEALTH_WOUNDED) + { + // Debug code to look for multiple moral checks at once by one creature? + if(GetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE) == "") + { + SetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE, GetName(oCreature)); + ai_Debug("0i_actions", "424", GetName(oCreature) + " starting debug mode to test Moral checks!"); + } + if(nHpPercent <= AI_HEALTH_BLOODY) nDC = AI_BLOODY_MORAL_DC; + else nDC = AI_WOUNDED_MORAL_DC; + nDC = nDC - GetLocalInt(oCreature, AI_ALLY_NUMBERS); + if(nDC < 1) nDC = 1; + if(AI_DEBUG) ai_Debug("0i_talents", "367", "Moral check DC: " + IntToString(nDC) + "."); + //SendMessageToPC(GetFirstPC(), "0i_talents, 431, " + GetName(oCreature) + " Moral check DC: " + IntToString(nDC) + "."); + if(!WillSave(oCreature, nDC, SAVING_THROW_TYPE_FEAR, oNearestEnemy)) + { + if(AI_DEBUG) ai_Debug("0i_talents", "370", "Moral check failed, we are fleeing!"); + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_coward"); + effect eVFX = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR); + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVFX, oCreature, 6.0f); + ActionMoveAwayFromObject(oNearestEnemy, TRUE, AI_RANGE_LONG); + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + int nRoll = d4(); + if(nRoll == 1) PlayVoiceChat(VOICE_CHAT_FLEE, oCreature); + else if(nRoll == 2) PlayVoiceChat(VOICE_CHAT_GUARDME, oCreature); + else if(nRoll == 3) PlayVoiceChat(VOICE_CHAT_HELP, oCreature); + else if(nRoll == 4 && nHpPercent < 100) PlayVoiceChat(VOICE_CHAT_HEALME, oCreature); + } + return TRUE; + } + if(nDC >= 11 && !ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + int nRoll = d6(); + // Cry out when you are overwhelmed! + if(nRoll == 1) PlayVoiceChat(VOICE_CHAT_CUSS, oCreature); + else if(nRoll == 2) PlayVoiceChat(VOICE_CHAT_BADIDEA, oCreature); + else if(nRoll == 3) PlayVoiceChat(VOICE_CHAT_ENEMIES, oCreature); + } + } + return FALSE; +} +int ai_GetInAOEReaction(object oCreature, object oCaster, int nSpell) +{ + switch(nSpell) + { + case SPELL_ACID_FOG: + case SPELL_CLOUDKILL: + case SPELL_CREEPING_DOOM: + { + // Nothing but bad times with these spells. + return TRUE; + } + case SPELL_STORM_OF_VENGEANCE: + { + // This only harms our enemies! + return (oCaster != oCreature && GetIsEnemy(oCaster, oCreature)); + } + // They should only flee Silence if they want to cast a spell! + //case SPELL_SILENCE: + case SPELL_BLADE_BARRIER: + case SPELL_WALL_OF_FIRE: + case SPELL_INCENDIARY_CLOUD: + { + // Check reflex feats and saves. + return (!GetHasFeat(FEAT_EVASION, oCreature) && + !GetHasFeat(FEAT_IMPROVED_EVASION, oCreature) && + GetReflexSavingThrow(oCreature) < 21 + d6()); + } + case SPELL_STINKING_CLOUD: + { + // Do we have a high fortitude save? 20 + 5 + return (GetFortitudeSavingThrow(oCreature) < 20 + d6()); + } + case SPELL_GREASE: + case SPELL_ENTANGLE: + case SPELL_VINE_MINE_ENTANGLE: + case SPELL_WEB: + { + // Do we have a high reflex save? d20 + 1 + return (!GetHasFeat(FEAT_WOODLAND_STRIDE, oCreature) && + !GetLocalInt(oCreature, "X2_L_IS_INCORPOREAL") && + GetReflexSavingThrow(oCreature) < 15 + d6()); + } + case SPELL_EVARDS_BLACK_TENTACLES: + { + // Small creatures are immune and can they hit me? d20 + 8 + caster lvl(7) + return (GetCreatureSize(oCreature) > 2 && + GetAC(oCreature) < 30 + d6()); + } + case SPELL_CLOUD_OF_BEWILDERMENT: + { + // Do we have a high fortitude save? 20 + 2 + return (GetFortitudeSavingThrow(oCreature) < 17 + d6()); + } + case SPELL_MIND_FOG: + case SPELL_STONEHOLD: + { + // Do we have a high enough will save? 20 + 6 + return (GetWillSavingThrow(oCreature) < 21 + d6()); + } + case SPELL_SPIKE_GROWTH: + case SPELL_VINE_MINE_HAMPER_MOVEMENT: + { + // Do we have a high reflex save? d20 + 3 + return (GetReflexSavingThrow(oCreature) < 18 + d6()); + } + } + return FALSE; +} +void ai_HaveCreatureSpeak(object oCreature, int nRoll, string sVoiceChatArray, int bImportant = FALSE) +{ + if(ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK) && !bImportant) return; + if(nRoll == 0) + { + // Some races shouldn't talk. + int nRacialType = GetRacialType(oCreature); + if(nRacialType == RACIAL_TYPE_ANIMAL || nRacialType == RACIAL_TYPE_BEAST || + nRacialType == RACIAL_TYPE_MAGICAL_BEAST || nRacialType == RACIAL_TYPE_OOZE || + nRacialType == RACIAL_TYPE_UNDEAD || nRacialType == RACIAL_TYPE_VERMIN) return; + SpeakString(sVoiceChatArray); + return; + } + nRoll = Random(nRoll); + string sVoice = ai_GetStringArray(sVoiceChatArray, nRoll); + if(sVoice != "") PlayVoiceChat(StringToInt(sVoice), oCreature); +} +int ai_CheckForAssociateSpellTalent(object oAssociate, int nInMelee, int nMaxLevel, int nRound = 0) +{ + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oAssociate, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return TRUE; + if(ai_UseCreatureTalent(oAssociate, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return TRUE; + } + if(ai_GetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING)) return FALSE; + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oAssociate); + return ai_TryDefensiveTalents(oAssociate, nInMelee, nMaxLevel, nRound, oTarget); +} +void ai_DoPhysicalAttackOnBest(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + talent tUse; + object oTarget; + if(AI_DEBUG) ai_Debug("0i_actions", "496", "Check for ranged attack on nearest enemy!"); + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the nearest targets first. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("0i_actions", "525", "Check for melee attack on nearest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, bAlwaysAtk); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "536", "Do melee attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} +void ai_DoPhysicalAttackOnNearest(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + talent tUse; + object oTarget; + if(AI_DEBUG) ai_Debug("0i_actions", "496", "Check for ranged attack on nearest enemy!"); + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the nearest targets first. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("0i_actions", "525", "Check for melee attack on nearest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee, bAlwaysAtk); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "536", "Do melee attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} +void ai_DoPhysicalAttackOnLowestCR(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "533", "Check for ranged attack on weakest enemy!"); + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the weaker targets. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "559", GetName(OBJECT_SELF) + " does ranged attack on weakest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("0i_actions", "571", "Check for melee attack on weakest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee, bAlwaysAtk); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "577", GetName(OBJECT_SELF) + " does melee attack against weakest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} +int ai_InCombatEquipBestMeleeWeapon(object oCreature) +{ + if(ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature))) return FALSE; + if(ai_EquipBestMeleeWeapon(oCreature)) + { + // We delay 1 second since ActionEquip is not an action we can check for. + // This keeps event scripts from clearing before we actually equip. + SetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS, 2); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + return FALSE; +} +int ai_InCombatEquipBestRangedWeapon(object oCreature) +{ + if(ai_EquipBestRangedWeapon(oCreature)) + { + // We delay 1 second since ActionEquip is not an action we can check for. + // This keeps event scripts from clearing before we actually equip. + SetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS, 1); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + return FALSE; +} +int ai_CheckItemForHealing(object oCreature, object oTarget, object oItem, int nHpLost, int bEquiped = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "629", "Checking Item properties on " + GetName(oItem)); + int nIprpSubType, nSpell, nLevel, nIPType; + itemproperty ipProp = GetFirstItemProperty(oItem); + // Lets skip this if there are no properties. + if(!GetIsItemPropertyValid(ipProp)) return FALSE; + // Check for cast spell property and add them to the talent list. + int nIndex; + ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + if(AI_DEBUG) ai_Debug("0i_actions", "639", "ItempropertyType(15): " + IntToString(GetItemPropertyType(ipProp))); + nIPType = GetItemPropertyType(ipProp); + if(nIPType == ITEM_PROPERTY_CAST_SPELL) + { + nIprpSubType = GetItemPropertySubType(ipProp); + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + if(ai_ShouldWeCastThisCureSpell(nSpell, nHpLost)) + { + // We have established that we can use the item if it is equiped. + if(!bEquiped) ai_CheckIfCanUseItem(oCreature, oItem); + // Get how they use the item (charges or uses per day). + int nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses > 1 && nUses < 7) + { + int nCharges = GetItemCharges(oItem); + if(AI_DEBUG) ai_Debug("0i_actions", "654", "Item charges: " + IntToString(nCharges)); + if(nUses == 6 && nCharges < 1 || nUses == 5 && nCharges < 3 || + nUses == 4 && nCharges < 5 || nUses == 3 && nCharges < 7 || + nUses == 2 && nCharges < 9) return FALSE; + } + else if(nUses > 7 && nUses < 13) + { + int nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(AI_DEBUG) ai_Debug("0i_actions", "662", "Item uses: " + IntToString(nPerDay)); + if(nPerDay == 0) return FALSE; + } + // SubType is the ip spell index for iprp_spells.2da + nIprpSubType = GetItemPropertySubType(ipProp); + if(AI_DEBUG) ai_Debug("0i_actions", "667", GetName(oCreature) + " is using " + GetName(oItem) + " on " + GetName(oTarget) + "."); + ActionUseItemOnObject(oItem, ipProp, oTarget, nIprpSubType); + return TRUE; + } + } + nIndex++; + ipProp = GetNextItemProperty(oItem); + } + return FALSE; +} +int ai_HealSickness(object oCreature, object oTarget, object oPC, int nSickness, int bForce = FALSE) +{ + // If the player is not forcing a check. + if(!bForce) + { + // Is Casting Cure spells off? + if(ai_GetMagicMode(oCreature, AI_MAGIC_CURE_SPELLS_OFF)) return FALSE; + // Do we have no magic on? + if(ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) return FALSE; + // Should we ignore associates? + if(ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + } + // Check for spells. + if(nSickness == AI_ALLY_IS_DISEASED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "717", "Attempting to remove disease."); + if(ai_CheckAndCastSpell(oCreature, SPELL_REMOVE_DISEASE, 0, 0.0, oTarget)) return TRUE; + } + else if(nSickness == AI_ALLY_IS_POISONED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "726", "Attempting to remove poison."); + if(ai_CheckAndCastSpell(oCreature, SPELL_NEUTRALIZE_POISON, 0, 0.0, oTarget)) return TRUE; + } + else if(nSickness == AI_ALLY_IS_WEAK) + { + if(AI_DEBUG) ai_Debug("0i_actions", "735", "Attempting to remove ability score drain."); + if(ai_CheckAndCastSpell(oCreature, SPELL_LESSER_RESTORATION, 0, 0.0, oTarget)) return TRUE; + if(ai_CheckAndCastSpell(oCreature, SPELL_RESTORATION, 0, 0.0, oTarget)) return TRUE; + if(ai_CheckAndCastSpell(oCreature, SPELL_GREATER_RESTORATION, 0, 0.0, oTarget)) return TRUE; + } + else return FALSE; + // Check for healing kits. + if(!GetLocalInt(GetModule(), AI_RULE_HEALERSKITS)) return FALSE; + int nIprpSubType, nSpell; + itemproperty ipProp; + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetIdentified(oItem)) + { + int nBaseItemType = GetBaseItemType(oItem); + if(nBaseItemType == BASE_ITEM_HEALERSKIT && + (nSickness == AI_ALLY_IS_DISEASED || + nSickness == AI_ALLY_IS_POISONED)) + { + ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + if(GetItemPropertyType(ipProp) == ITEM_PROPERTY_HEALERS_KIT) + { + if(AI_DEBUG) ai_Debug("0i_actions", "772", "Attempting to remove (" + IntToString(nSickness) + ") with a healing kit."); + if(ai_GetIsCharacter(oPC)) ai_SendMessages(GetName(oCreature) + " uses " + GetName(oItem) + " on " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + ipProp = GetNextItemProperty(oItem); + } + } + else if(nBaseItemType == BASE_ITEM_POTIONS || + nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == FEAT_BREW_POTION) + { + ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + nIprpSubType = GetItemPropertySubType(ipProp); + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + if(AI_DEBUG) ai_Debug("0i_actions", "789", "Checking potion, " + IntToString(nSpell)); + if(nSpell == SPELL_REMOVE_DISEASE && nSickness == AI_ALLY_IS_DISEASED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "786", "Using a potion of Remove Disease."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_NEUTRALIZE_POISON && nSickness == AI_ALLY_IS_POISONED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "786", "Using a potion of Neturalize Poison."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_LESSER_RESTORATION && nSickness == AI_ALLY_IS_WEAK) + { + if(AI_DEBUG) ai_Debug("0i_actions", "781", "Using a potion of Lesser Restoration."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_RESTORATION && nSickness == AI_ALLY_IS_WEAK) + { + if(AI_DEBUG) ai_Debug("0i_actions", "791", "Using a potion of Restoration."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + ipProp = GetNextItemProperty(oItem); + } + } + else if(nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL || + nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == BASE_ITEM_MAGICSTAFF) + { + if(ai_CheckIfCanUseItem(oCreature, oItem)) + { + ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + if(nSpell == SPELL_REMOVE_DISEASE && nSickness == AI_ALLY_IS_DISEASED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "786", "Using a potion of Remove Disease."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_NEUTRALIZE_POISON && nSickness == AI_ALLY_IS_POISONED) + { + if(AI_DEBUG) ai_Debug("0i_actions", "786", "Using a potion of Neturalize Poison."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_LESSER_RESTORATION && nSickness == AI_ALLY_IS_WEAK) + { + if(AI_DEBUG) ai_Debug("0i_actions", "781", "Using a potion of Lesser Restoration."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + if(nSpell == SPELL_RESTORATION && nSickness == AI_ALLY_IS_WEAK) + { + if(AI_DEBUG) ai_Debug("0i_actions", "791", "Using a potion of Restoration."); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + ipProp = GetNextItemProperty(oItem); + } + } + } + } + oItem = GetNextItemInInventory(oCreature); + } + return FALSE; +} +int ai_UseHealingItem(object oCreature, object oTarget, object oPC) +{ + if(ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC_ITEMS)) return FALSE; + string sSlots; + int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + itemproperty ipProp; + // Cycle through all the creatures equiped items. + int nSlot; + object oItem = GetItemInSlot(nSlot, oCreature); + while(nSlot < 11) + { + if(oItem != OBJECT_INVALID && + ai_CheckItemForHealing(oCreature, oTarget, oItem, nDamage, TRUE)) return TRUE; + oItem = GetItemInSlot(++nSlot, oCreature); + } + oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetIdentified(oItem)) + { + // Does the item need to be equiped to use its powers? + sSlots = Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)); + if(AI_DEBUG) ai_Debug("0i_actions", "696", GetName(oItem) + " requires " + Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)) + " slots."); + if(sSlots == "0x00000") + { + int nBaseItemType = GetBaseItemType(oItem); + // Lets not use up our healing kits on minor damage. + if(nBaseItemType == BASE_ITEM_HEALERSKIT) + { + if(!GetLocalInt(GetModule(), AI_RULE_HEALERSKITS)) return FALSE; + ipProp = GetFirstItemProperty(oItem); + if(GetItemPropertyType(ipProp) == ITEM_PROPERTY_HEALERS_KIT) + { + if(ai_GetIsCharacter(oPC)) ai_SendMessages(GetName(oCreature) + " uses " + GetName(oItem) + " on " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + ActionUseItemOnObject(oItem, ipProp, oTarget); + return TRUE; + } + } + // Do we want Player AI and Associates to use potions on others? + //else if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + // nBaseItemType == BASE_ITEM_POTIONS) + //{ + // if(oCaster == oTarget) + // { + // if(ai_CheckItemForHealing(oCreature, oTarget, oItem, nDamage)) return TRUE; + // } + //} + else if(ai_CheckItemForHealing(oCreature, oTarget, oItem, nDamage)) return TRUE; + } + } + oItem = GetNextItemInInventory(oCreature); + } + return FALSE; +} +void ai_ActionTryHealing(object oCreature, object oTarget) +{ + ai_TryHealing(oCreature, oTarget, TRUE); +} +int ai_TryHealing(object oCreature, object oTarget, int bForce = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "733", "Try healing: oCreature: " + GetName(oCreature) + + " oTarget: " + GetName(oTarget) + " No Party Healing: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) + + " No Self Healing: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF)) + + " AI_I_AM_BEING_HEALED: " + IntToString(GetLocalInt(oTarget, "AI_I_AM_BEING_HEALED")) + + " Undead: " + IntToString(GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)); + // If the player is not forcing a check. + if(!bForce) + { + // Should we ignore associates? + if(ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + } + // Limits the number of times a wounded creature will ask for help. + if(GetLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT") > 3) return FALSE; + // This keeps everyone from healing the same character in one round and over healing! + if(oCreature == oTarget) DeleteLocalInt(oTarget, "AI_I_AM_BEING_HEALED"); + else if(GetLocalInt(oTarget, "AI_I_AM_BEING_HEALED")) return FALSE; + if(ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF) && + oCreature != oTarget) return FALSE; + if(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF) && + oCreature == oTarget) return FALSE; + // Undead don't heal so lets skip this for them, maybe later we can fix this. + if(GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) return FALSE; + int nHpLost = ai_GetPercHPLoss(oTarget); + if(bForce && nHpLost < 100) nHpLost = 0; + if(AI_DEBUG) ai_Debug("0i_actions", "743", "nHpLost: " + IntToString(nHpLost) + + " limit: " + IntToString(ai_GetHealersHpLimit(oTarget, FALSE))); + if(nHpLost >= ai_GetHealersHpLimit(oTarget, FALSE)) + { + // Check to see if we need poison, disease, or ability drain removed. + int nEffectType; + effect eEffect = GetFirstEffect(oTarget); + while(GetIsEffectValid(eEffect)) + { + nEffectType = GetEffectType(eEffect); + if(AI_DEBUG) ai_Debug("0i_actions", "1094", "Checking to cure(31/32/39) nEffectType: " + IntToString(nEffectType)); + if(nEffectType == EFFECT_TYPE_DISEASE) + { + if(AI_DEBUG) ai_Debug("0i_actions", "1097", "I am diseased!"); + if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_DISEASED, bForce)) return TRUE; + if(oCreature == oTarget) + { + if(!d20()) ai_HaveCreatureSpeak(oCreature, 5, ":43:4:14:15:16:"); + SpeakString(AI_I_AM_DISEASED, TALKVOLUME_SILENT_TALK); + } + } + else if(nEffectType == EFFECT_TYPE_POISON) + { + if(AI_DEBUG) ai_Debug("0i_actions", "1107", "I am poisoned!"); + if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_POISONED, bForce)) return TRUE; + if(oCreature == oTarget) + { + if(!d20()) ai_HaveCreatureSpeak(oCreature, 6, ":43:4:14:15:16:19:"); + SpeakString(AI_I_AM_POISONED, TALKVOLUME_SILENT_TALK); + } + } + else if(nEffectType == EFFECT_TYPE_ABILITY_DECREASE) + { + if(AI_DEBUG) ai_Debug("0i_actions", "1117", "I am weak!"); + if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_WEAK, bForce)) return TRUE; + if(oCreature == oTarget) + { + if(!d20()) ai_HaveCreatureSpeak(oCreature, 3, ":43:4:5:"); + SpeakString(AI_I_AM_WEAK, TALKVOLUME_SILENT_TALK); + } + } + eEffect = GetNextEffect(oTarget); + } + return FALSE; + } + // Do they have Lay on Hands? + if(GetHasFeat(FEAT_LAY_ON_HANDS, oCreature)) + { + int nCanHeal = GetAbilityModifier(ABILITY_CHARISMA, oCreature) * ai_GetCharacterLevels(oCreature); + if(nCanHeal <= nHpLost) + { + ai_UseFeat(oCreature, FEAT_LAY_ON_HANDS, oTarget); + return TRUE; + } + } + object oMaster = ai_GetPlayerMaster(oCreature); + // Do we have no magic on? + if(!ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) + { + int nClass, nPosition = 1; + string sMemorized; + while(nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + nClass = GetClassByPosition(nPosition, oCreature); + if(AI_DEBUG) ai_Debug("0i_actions", "753", "nClass: " + IntToString(nClass)); + if(nClass == CLASS_TYPE_INVALID) break; + sMemorized = Get2DAString("classes", "MemorizesSpells", nClass); + // If Memorized column is "" then they are not a caster. + if(sMemorized != "") + { + if(sMemorized == "1") + { + if(ai_CastMemorizedHealing(oCreature, oTarget, oMaster, nClass)) + { + SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE); + return TRUE; + } + } + else if(ai_CastKnownHealing(oCreature, oTarget, oMaster, nClass)) + { + SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE); + return TRUE; + } + } + nPosition++; + } + } + // We have exhausted all attempts to use normal healing spells. + if(ai_UseHealingItem(oCreature, oTarget, oMaster)) + { + SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE); + return TRUE; + } + // Final attempt to heal oTarget, check for Spontaneous cure spells. + if(ai_CastSpontaneousCure(oCreature, oTarget, oMaster)) + { + SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE); + return TRUE; + } + // We can't heal ourselves! Can any of our allies? Lets ask. + if(oCreature == oTarget) + { + SetLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT", GetLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT") + 1); + SpeakString(AI_I_AM_WOUNDED, TALKVOLUME_SILENT_TALK); + } + return FALSE; +} +int ai_PerceiveEnemy(object oCreature, object oEnemy) +{ + float fDistance = GetDistanceBetween(oCreature, oEnemy); + if(fDistance < 50.0) + { + // Game is in meters, so 1 foot = 3.333 meter + // penalty is -1 per 10' so divide it by 10 to use 0.3333f + int nDC = 10 + FloatToInt(fDistance * 0.3333f); + // Check to see if the creature is hiding and add the creatures checks. + int nEnemyMoveSilent, nEnemyHide; + if(GetStealthMode(oEnemy)) + { + nEnemyMoveSilent =(d20() + GetSkillRank(SKILL_MOVE_SILENTLY, oEnemy)); + nEnemyHide =(d20() + GetSkillRank(SKILL_HIDE, oEnemy)); + } + if(GetIsSkillSuccessful (oCreature, SKILL_SPOT, nDC + nEnemyHide)) return TRUE; + if(GetIsSkillSuccessful (oCreature, SKILL_LISTEN, nDC + nEnemyMoveSilent)) return TRUE; + } + return FALSE; +} +void ai_ScoutAhead(object oCreature) +{ + object oPerceived; + object oEnemy = ai_GetNearestEnemy(oCreature, 1, -1, -1, -1, -1, TRUE); + // We see them so fight! + if(oEnemy != OBJECT_INVALID) + { + if(ai_PerceiveEnemy(oCreature, oEnemy)) + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + int nRoll = d10(); + if(nRoll == 1) PlayVoiceChat(VOICE_CHAT_ENEMIES, oCreature); + else if(nRoll == 2) PlayVoiceChat(VOICE_CHAT_FOLLOWME, oCreature); + else if(nRoll == 3) PlayVoiceChat(VOICE_CHAT_LOOKHERE, oCreature); + } + ActionMoveToObject(oEnemy, TRUE, AI_RANGE_LONG); + return; + } + // There are enemies here so lets go to them. + else + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + int nRoll = d3(); + if(nRoll == 1) PlayVoiceChat(VOICE_CHAT_BADIDEA, oCreature); + else if(nRoll == 2) PlayVoiceChat(VOICE_CHAT_SEARCH, oCreature); + else if(nRoll == 3) PlayVoiceChat(VOICE_CHAT_FOLLOWME, oCreature); + } + ActionMoveToObject(oEnemy, TRUE, AI_RANGE_CLOSE); + } + } + // There are no more enemies, but we must look like we are patroling so + // go to encounter points. + else + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + int nRoll = d10(); + if(nRoll == 1) PlayVoiceChat(VOICE_CHAT_BADIDEA, oCreature); + else if(nRoll == 2) PlayVoiceChat(VOICE_CHAT_SEARCH, oCreature); + else if(nRoll == 3) PlayVoiceChat(VOICE_CHAT_FOLLOWME, oCreature); + } + // No enemy so lets get a spawn point! + object oSpawnPoint = GetNearestObjectByTag("ip_encounter", oCreature, d6()); + ActionMoveToObject(oSpawnPoint, TRUE, AI_RANGE_CLOSE); + } +} +int ai_ShouldIPickItUp(object oCreature, object oItem) +{ + int nMinGold; + if(GetResRef(oItem) == "nw_it_gold001") return TRUE; + int nBaseItem = GetBaseItemType(oItem); + if(GetPlotFlag(oItem)) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_PLOT)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_2"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_ARMOR) + { + if (ai_GetLootFilter(oCreature, AI_LOOT_ARMOR)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_3"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BELT) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_BELTS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_4"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BOOTS) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_BOOTS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_5"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_CLOAK) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_CLOAKS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_6"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_GEM) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_GEMS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_7"); + else return FALSE; + } + else if((nBaseItem == BASE_ITEM_BRACER|| nBaseItem == BASE_ITEM_GLOVES)) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_GLOVES)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_8"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_HELMET) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_HEADGEAR)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_9"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_AMULET || nBaseItem == BASE_ITEM_RING) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_JEWELRY)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_10"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BLANK_POTION || nBaseItem == BASE_ITEM_POTIONS || + nBaseItem == BASE_ITEM_ENCHANTED_POTION) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_POTIONS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_12"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BLANK_SCROLL || nBaseItem == BASE_ITEM_SCROLL || + nBaseItem == BASE_ITEM_ENCHANTED_SCROLL || nBaseItem == BASE_ITEM_SPELLSCROLL) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_SCROLLS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_13"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BLANK_WAND || nBaseItem == BASE_ITEM_ENCHANTED_WAND || + nBaseItem == BASE_ITEM_MAGICWAND || nBaseItem == BASE_ITEM_MAGICROD || + nBaseItem == BASE_ITEM_MAGICSTAFF) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_WANDS_RODS_STAVES)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_15"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_ARROW) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_ARROWS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_17"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BOLT) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_BOLTS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_18"); + else return FALSE; + } + else if(nBaseItem == BASE_ITEM_BULLET) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_BULLETS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_19"); + else return FALSE; + } + else if(ai_GetIsWeapon(oItem)) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_WEAPONS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_16"); + else return FALSE; + } + else if(ai_GetIsShield(oItem)) + { + if(ai_GetLootFilter(oCreature, AI_LOOT_SHIELDS)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_14"); + else return FALSE; + } + else if(ai_GetLootFilter(oCreature, AI_LOOT_MISC)) nMinGold = GetLocalInt(oCreature, "AI_MIN_GOLD_11"); + else return FALSE; + // Check if it is too heavy. + int nItemWeight = GetWeight(oItem); + if(AI_DEBUG) ai_Debug("0i_actions", "1146", GetName(oItem) + " nItemWeight: " + + IntToString(nItemWeight) + " Max Weight: " + IntToString(GetLocalInt(oCreature, AI_MAX_LOOT_WEIGHT) * 10)); + if(nItemWeight > GetLocalInt(oCreature, AI_MAX_LOOT_WEIGHT) * 10) return FALSE; + // Check if it is not valuable enough. + int bID = GetIdentified(oItem); + if(!bID) SetIdentified(oItem, TRUE); + int nItemValue = GetGoldPieceValue(oItem); + if(!bID) SetIdentified(oItem, FALSE); + if(AI_DEBUG) ai_Debug("0i_actions", "998", GetName(oItem) + " nMinGold: " + IntToString(nMinGold) + " nItemValue: " + + IntToString(nItemValue) + " bID: " + IntToString(bID)); + if(nMinGold > nItemValue) return FALSE; + return TRUE; +} +void ai_TakeItemMessage(object oCreature, object oObject, object oItem, object oMaster) +{ + int bId = GetIdentified(oItem); + int nCreatureSkill = GetSkillRank(SKILL_LORE, oCreature); + int nMasterSkill = GetSkillRank(SKILL_LORE, oMaster); + if(nCreatureSkill + nMasterSkill > 0) + { + if(nCreatureSkill > nMasterSkill) ai_IdentifyItemVsKnowledge(oCreature, oItem); + else ai_IdentifyItemVsKnowledge(oMaster, oItem); + } + if(!ai_GetIsCharacter(oCreature)) + { + if(GetIdentified(oItem)) + { + if(bId) ai_SendMessages(GetName(oCreature) + " has found a " + GetName(oItem) + " from the " + GetName(oObject) + ".", AI_COLOR_GRAY, oMaster); + else ai_SendMessages(GetName(oCreature) + " has found and identified " + GetName(oItem) + " from the " + GetName(oObject) + ".", AI_COLOR_GREEN, oMaster); + } + else if(!ai_GetIsCharacter(oCreature)) + { + string sBaseName = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "name", GetBaseItemType(oItem)))); + ai_SendMessages(GetName(oCreature) + " has found a " + sBaseName + " from the " + GetName(oObject) + ".", AI_COLOR_GRAY, oMaster); + } + } + else if(GetIdentified(oItem) && !bId) + { + ai_SendMessages(GetName(oCreature) + " has identified " + GetName(oItem) + " from the " + GetName(oObject) + ".", AI_COLOR_GREEN, oMaster); + } + if(GetPlotFlag(oItem)) + { + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) PlayVoiceChat(VOICE_CHAT_LOOKHERE, oCreature); + } +} +void ai_SearchObject(object oCreature, object oObject, object oMaster, int bOnce = FALSE) +{ + ai_Debug("0i_actions", "966", GetName(OBJECT_SELF) + " is opening " + GetName(oObject)); + string sTag = GetTag(oCreature); + AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_OPEN)); + if(GetIsTrapped(oObject)) DoPlaceableObjectAction(oObject, PLACEABLE_ACTION_USE); + SetLocalInt(oObject, "AI_LOOTED_" + sTag, TRUE); + // Big Hack to allow NPC's to loot! + string sLootScript = GetEventScript(oObject, EVENT_SCRIPT_PLACEABLE_ON_OPEN); + //ai_Debug("0i_actions", "972", "Loot script: " + sLootScript); + if(sLootScript != "") + { + // Used in Original Campaign, and SOU for loot scripts to get treasure to work. + SetLocalObject(oObject, "AI_GET_LAST_OPENED_BY", oMaster); + ExecuteScript(sLootScript, oObject); + } + AssignCommand(oObject, ActionWait(2.0f)); + AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_CLOSE)); + int nItemType, nGold; + object oItem = GetFirstItemInInventory(oObject); + //ai_Debug("0i_actions", "983", "Found: " + GetName(oItem) + " ResRef: " + GetResRef(oItem) + + // " in " + GetName(oObject)); + while(oItem != OBJECT_INVALID) + { + ai_Debug("0i_actions", "987", "Found: " + GetName(oItem) + " ResRef: " + GetResRef(oItem)); + if(ai_ShouldIPickItUp(oCreature, oItem)) + { + ai_Debug("0i_actions", "1002", "Taking: " + GetName(oItem)); + if(GetResRef(oItem) == "nw_it_gold001") + { + if(!ai_GetIsCharacter(oCreature)) + { + int nGold = GetItemStackSize(oItem); + DestroyObject(oItem); + ActionDoCommand(GiveGoldToCreature(oMaster, nGold)); + ActionDoCommand(ai_SendMessages(GetName(oCreature) + " has retrieved " + IntToString(nGold) + + " gold from the " + GetName(oObject) + ".", AI_COLOR_GRAY, oMaster)); + } + else AssignCommand(oCreature, ActionTakeItem(oItem, oObject)); + } + // Check if they are a henchman, companions and familiars give all items to the pc. + else if(!ai_GetLootFilter(oCreature, AI_LOOT_GIVE_TO_PC) && + GetAssociateType(oCreature) == ASSOCIATE_TYPE_HENCHMAN && + !GetPlotFlag(oItem)) + { + if(GetBaseItemFitsInInventory(GetBaseItemType(oItem), oCreature)) + { + ActionDoCommand(ai_TakeItemMessage(oCreature, oObject, oItem, oMaster)); + ActionTakeItem(oItem, oObject); + } + else + { + if(GetIdentified(oItem)) SpeakString("My inventory is full! I cannot pick up the " + GetName(oItem) + "."); + else + { + string sBaseName = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "name", GetBaseItemType(oItem)))); + SpeakString("My inventory is full! I cannot pick up the " + sBaseName + "."); + } + } + } + else + { + if(GetBaseItemFitsInInventory(GetBaseItemType(oItem), oMaster)) + { + //ai_Debug("0i_actions", "1010", "Giving to master: " + GetName(oItem)); + ActionDoCommand(ai_TakeItemMessage(oCreature, oObject, oItem, oMaster)); + AssignCommand(oObject, ActionGiveItem(oItem, oMaster)); + } + else + { + if(GetIdentified(oItem)) SpeakString("Your inventory is full! You cannot take the " + GetName(oItem) + "."); + else + { + string sBaseName = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "name", GetBaseItemType(oItem)))); + SpeakString("Your inventory is full! You cannot take the " + sBaseName + "."); + } + } + } + } + oItem = GetNextItemInInventory(oObject); + //ai_Debug("0i_actions", "1016", GetName(oItem) + " is the next item."); + } + //ai_Debug("0i_actions", "1018", "Setting object as looted. Check for a new Placeable."); + if(!bOnce) ActionDoCommand(ai_ActionCheckNearbyObjects(oCreature)); +} +int ai_IsContainerLootable(object oCreature, object oObject) +{ + string sTag = GetTag(oCreature); + //ai_Debug("0i_actions", "1303", GetName(oObject) + " (sTag " + GetTag(oObject) + ") " + + // "has inventory: " + IntToString(GetHasInventory(oObject)) + " Has been looted: " + + // IntToString(GetLocalInt(oObject, "AI_LOOTED_" + sTag)) + " Is Useable? " + + // IntToString(GetUseableFlag(oObject))); + if(!GetHasInventory(oObject) || !GetUseableFlag(oObject)) return FALSE; + // This associate has already looted this object, skip. + if(GetLocalInt(oObject, "AI_LOOTED_" + sTag) || ai_GetIsCharacter(oObject)) return FALSE; + return TRUE; +} +int ai_AttempToCastKnockSpell(object oCreature, object oLocked) +{ + if(GetHasSpell(SPELL_KNOCK, oCreature) && + (GetIsDoorActionPossible(oLocked, DOOR_ACTION_KNOCK) || + GetIsPlaceableObjectActionPossible(oLocked, PLACEABLE_ACTION_KNOCK)) && + ai_GetIsInLineOfSight(oCreature, oLocked)) + { + SetLocalInt(oLocked, AI_OBJECT_IN_USE, TRUE); + DelayCommand(6.0, DeleteLocalInt(oLocked, AI_OBJECT_IN_USE)); + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionWait(1.0)); + AssignCommand(oCreature, ActionCastSpellAtObject(SPELL_KNOCK, oLocked)); + AssignCommand(oCreature, ActionWait(1.0)); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oLocked, AI_OBJECT_IN_USE))); + return TRUE; + } + return FALSE; +} +int ai_ReactToTrap(object oCreature, object oTrap, int bForce = FALSE) +{ + int nTrapDC = GetTrapDisarmDC(oTrap); + if(AI_DEBUG) ai_Debug("0i_actions", "1520", "Reacting to trap on " + GetName(oTrap) + + " bForce: " + IntToString(bForce) + " nTrapDC: " + IntToString(nTrapDC) + + " [AI_OBJECT_IN_USE: " + IntToString(GetLocalInt(oTrap, AI_OBJECT_IN_USE)) + "]."); + if(nTrapDC == 0) return FALSE; + string sTag = GetTag(oCreature); + if(bForce || ai_GetAIMode(oCreature, AI_MODE_DISARM_TRAPS)) + { + if(GetTrapDisarmable(oTrap)) + { + if(GetLocalInt(oTrap, AI_OBJECT_IN_USE)) return FALSE; + // We must have ranks in disable traps to actually disable the trap! + if(GetSkillRank(SKILL_DISABLE_TRAP, oCreature, TRUE)) + { + int nSkill = GetSkillRank(SKILL_DISABLE_TRAP, oCreature); + if(AI_DEBUG) ai_Debug("0i_actions", "1534", "nSkill: " + IntToString(nSkill) + + " + 20 = " + IntToString(nSkill + 20) + " nTrapDC: " + IntToString(nTrapDC)); + if(nSkill + 20 >= nTrapDC) + { + SetLocalInt(oTrap, AI_OBJECT_IN_USE, TRUE); + DelayCommand(18.0, DeleteLocalInt(oTrap, AI_OBJECT_IN_USE)); + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionUseSkill(SKILL_DISABLE_TRAP, oTrap, 0)); + // Let them know we did it! + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 6, ":44:42:31:35:"))); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oTrap, AI_OBJECT_IN_USE))); + // Continue checking for traps, locks, and loot. + AssignCommand(oCreature, ActionDoCommand(ai_ActionCheckNearbyObjects(oCreature))); + return TRUE; + } + if(GetHasSpell(SPELL_FIND_TRAPS, oCreature)) + { + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionCastSpellAtObject(SPELL_FIND_TRAPS, oTrap)); + // Continue checking for traps, locks, and loot. + AssignCommand(oCreature, ActionDoCommand(ai_ActionCheckNearbyObjects(oCreature))); + return TRUE; + } + } + if(GetLocalInt(oTrap, "AI_CANNOT_TRAP_" + sTag) && !bForce) return FALSE; + // Let them know we can't get this done!. + //StrRef(40551) "I cannot disarm this trap!" + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, GetStringByStrRef(40551))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oTrap, "AI_CANNOT_TRAP_" + sTag, TRUE); + return FALSE; + } + if(GetLocalInt(oTrap, "AI_SAW_TRAP_" + sTag) && !bForce) return FALSE; + // Let them know we can't get this done!. + ai_HaveCreatureSpeak(oCreature, 0, "I'm not skilled enough to disable the trap!", TRUE); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oTrap, "AI_SAW_TRAP_" + sTag, TRUE); + return FALSE; + } + if(GetObjectType(oTrap) == OBJECT_TYPE_TRIGGER) + { + object oMaster = ai_GetPlayerMaster(oCreature); + if(oMaster != OBJECT_INVALID && !ai_GetIsCharacter(oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_IGNORE_TRAPS)) + { + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, TRUE); + ai_SetAIMode(oCreature, AI_MODE_FOLLOW, FALSE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + int nToken = NuiFindWindow(oMaster, ai_GetAssociateType(oMaster, oCreature) + AI_WIDGET_NUI); + ai_HighlightWidgetMode(oMaster, oCreature, nToken); + aiSaveAssociateModesToDb(oMaster, oCreature); + if(ai_IsInCombatRound(oCreature)) ai_ClearCombatState(oCreature); + ai_ClearCreatureActions(TRUE); + ai_SendMessages(GetName(oCreature) + " has went into hold mode after seeing a trap!", AI_COLOR_YELLOW, oMaster); + return TRUE; + } + } + if(ai_GetAIMode(oCreature, AI_MODE_PICKUP_ITEMS)) + { + if(GetLocalInt(oTrap, "AI_SAW_TRAP_" + sTag) && !bForce) return FALSE; + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oTrap) + " is trapped!", TRUE)); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oTrap, "AI_SAW_TRAP_" + sTag, TRUE); + } + return FALSE; +} +int ai_AttemptToByPassLock(object oCreature, object oLocked, int bForce = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "1446", "Attempting to bypass lock on " + + GetName(oLocked) + " [AI_OBJECT_IN_USE: " + + IntToString(GetLocalInt(oLocked, AI_OBJECT_IN_USE)) + "]" + + " bForce: " + IntToString(bForce)); + if(GetLocalInt(oLocked, AI_OBJECT_IN_USE)) return FALSE; + string sTag = GetTag(oCreature); + // Attempt to cast knock because its always safe to cast it, even on a trapped object. + if(ai_AttempToCastKnockSpell(oLocked, oCreature)) return TRUE; + // First, let's see if we notice that it's trapped + if(GetTrapDetectedBy(oCreature, oLocked)) + { + // Ick! Try and disarm the trap first + if(ai_ReactToTrap(oCreature, oLocked, bForce)) return TRUE; + } + if(GetLockKeyRequired(oLocked)) + { + // We might be able to open this. + string sKeyTag = GetLockKeyTag(oLocked); + // Do we have the key? + object oKey = ai_GetCreatureHasItem(oCreature, sKeyTag, FALSE); + if(AI_DEBUG) ai_Debug("0i_actions", "1469", "Requires a Key! sKeyTag: " + + sKeyTag + " Has key oKey: " + GetName(oKey)); + if(oKey != OBJECT_INVALID) + { + int nObjectType = GetObjectType(oLocked); + if(nObjectType == OBJECT_TYPE_DOOR) return ai_AttemptToOpenDoor(oCreature, oLocked, bForce); + else if (nObjectType == OBJECT_TYPE_PLACEABLE) + { + SetLocalInt(oLocked, AI_OBJECT_IN_USE, TRUE); + DelayCommand(18.0, DeleteLocalInt(oLocked, AI_OBJECT_IN_USE)); + AssignCommand(oCreature, ActionUnlockObject(oLocked)); + // Let them know we did it! + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 6, ":44:42:31:35:")); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oLocked, AI_OBJECT_IN_USE))); + // Continue checking for traps, locks, and loot. + AssignCommand(oCreature, ActionDoCommand(ai_ActionCheckNearbyObjects(oCreature))); + return TRUE; + } + } + else + { + if(GetLocalInt(oLocked, "AI_LOCKED_" + sTag) && !bForce) return FALSE; + // Let them know we can't get this done!. + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oLocked) + " is special! It requires a special key to open."))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oLocked, "AI_LOCKED_" + sTag, TRUE); + return FALSE; + } + } + if(bForce || ai_GetAIMode(oCreature, AI_MODE_PICK_LOCKS)) + { + // We must have ranks in open locks to actually open the lock! + if(GetSkillRank(SKILL_OPEN_LOCK, oCreature, TRUE)) + { + int nSkill = GetSkillRank(SKILL_OPEN_LOCK, oCreature); + int nLockDC = GetLockUnlockDC(oLocked); + object oPicks = ai_GetBestPicks(oCreature, nLockDC); + int nPickBonus = GetLocalInt(oPicks, "AI_BONUS"); + if(AI_DEBUG) ai_Debug("0i_actions", "1497", "I have picks: " + GetName(oPicks) + + " nSkill :" + IntToString(nSkill) + " nPickBonus: " + + IntToString(nPickBonus) + " + 20 = " + + IntToString(nSkill + nPickBonus + 20) + + " nLockDC: " + IntToString(nLockDC)); + if(nSkill + 20 + nPickBonus >= nLockDC) + { + SetLocalInt(oLocked, AI_OBJECT_IN_USE, TRUE); + DelayCommand(18.0, DeleteLocalInt(oLocked, AI_OBJECT_IN_USE)); + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionWait(1.0)); + AssignCommand(oCreature, ActionUseSkill(SKILL_OPEN_LOCK, oLocked, 0, oPicks)); + AssignCommand(oCreature, ActionWait(1.0)); + // Let them know we did it! + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":44:42:26:31:35:")); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oLocked, AI_OBJECT_IN_USE))); + // Continue checking for traps, locks, and loot. + AssignCommand(oCreature, ActionDoCommand(ai_ActionCheckNearbyObjects(oCreature))); + return TRUE; + } + else if(!GetLocalInt(oLocked, "AI_LOCKED_" + sTag)) + { + // Let them know we can't get this done! + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "I'm not skilled enough to pick the lock on this " + GetName(oLocked) + "!", TRUE))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oLocked, "AI_LOCKED_" + sTag, TRUE); + return FALSE; + } + } + } + if(bForce || ai_GetAIMode(oCreature, AI_MODE_BASH_LOCKS)) + { + //AssignCommand(oCreature, ai_ClearCreatureActions()); + // Check to make sure we are not using a ranged weapon. + if(!ai_GetIsRangeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature))) + { + if(ai_CheckClassType(oCreature, CLASS_TYPE_MONK)) ai_EquipBestMonkMeleeWeapon(oCreature); + else ai_EquipBestMeleeWeapon(oCreature); + AssignCommand(oCreature, ActionWait(1.0)); + if(ai_TryImprovedPowerAttackFeat(oCreature, oLocked)) return TRUE; + if(ai_TryPowerAttackFeat(oCreature, oLocked)) return TRUE; + if(ai_TryFlurryOfBlowsFeat(oCreature, oLocked)) return TRUE; + AssignCommand(oCreature, ActionAttack(oLocked)); + return TRUE; + } + if(GetLocalInt(oLocked, "AI_LOCKED_" + sTag) && !bForce) return FALSE; + // Let them know we can't get this done!. + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "I cannot bash this " + GetName(oLocked) + " open!", TRUE))); + SetLocalInt(oLocked, "AI_LOCKED_" + sTag, TRUE); + return FALSE; + } + if(bForce || ai_GetAIMode(oCreature, AI_MODE_PICKUP_ITEMS)) + { + if(GetLocalInt(oLocked, "AI_LOCKED_" + sTag) && !bForce) return FALSE; + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oLocked) + " is locked!", TRUE))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oLocked, "AI_LOCKED_" + sTag, TRUE); + } + return FALSE; +} +int ai_AttemptToOpenDoor(object oCreature, object oDoor, int bForce = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_actions", "1542", "Attempting to open " + + GetName(oDoor) + " [AI_OBJECT_IN_USE: " + + IntToString(GetLocalInt(oDoor, AI_OBJECT_IN_USE)) + "] " + + " IsOpen: " + IntToString(GetIsOpen(oDoor)) + + " Plot: " + IntToString(GetPlotFlag(oDoor)) + "."); + if(!ai_GetAIMode(oCreature, AI_MODE_OPEN_DOORS) && !bForce) return FALSE; + if(GetLocalInt(oDoor, AI_OBJECT_IN_USE)) return FALSE; + if(GetIsOpen(oDoor)) return FALSE; + string sTag = GetTag(oCreature); + if(GetIsTrapped(oDoor)) + { + if(GetTrapDetectedBy(oDoor, GetMaster(oCreature))) SetTrapDetectedBy(oDoor, oCreature); + if(GetTrapDetectedBy(oDoor, oCreature)) + { + if(GetLocalInt(oDoor, "AI_SAW_TRAP_" + sTag)) return FALSE; + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oDoor) + " is trapped!", TRUE)); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oDoor, "AI_SAW_TRAP_" + sTag, TRUE); + return FALSE; + } + } + if(GetLocked(oDoor)) + { + if(GetLocalInt(oDoor, "AI_LOCKED_" + sTag)) return FALSE; + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oDoor) + " is locked!", TRUE))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oDoor, "AI_LOCKED_" + sTag, TRUE); + return FALSE; + } + SetLocalInt(oDoor, AI_OBJECT_IN_USE, TRUE); + DelayCommand(18.0, DeleteLocalInt(oDoor, AI_OBJECT_IN_USE)); + AssignCommand(oCreature, ActionOpenDoor(oDoor, TRUE)); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oDoor, AI_OBJECT_IN_USE))); + return TRUE; +} +void ai_ActionCheckNearbyObjects(object oCreature) +{ + if(ai_GetIsBusy(oCreature)) return; + ai_CheckNearbyObjects(oCreature); +} +int ai_CheckNearbyObjects(object oCreature) +{ + object oMaster = ai_GetPlayerMaster(oCreature); + location lMaster = GetLocation(oMaster); + int nObjectType, bIgnore; + int nFilter = OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_TRIGGER | OBJECT_TYPE_ITEM; + float fLockRange, fDoorRange, fLootRange, fObjectDistance; + float fTrapRange = GetLocalFloat(oCreature, AI_TRAP_CHECK_RANGE); + if(ai_GetAIMode(oCreature, AI_MODE_PICK_LOCKS) || + ai_GetAIMode(oCreature, AI_MODE_BASH_LOCKS)) fLockRange = GetLocalFloat(oCreature, AI_LOCK_CHECK_RANGE); + if(ai_GetAIMode(oCreature, AI_MODE_PICKUP_ITEMS)) fLootRange = GetLocalFloat(oCreature, AI_LOOT_CHECK_RANGE); + if(ai_GetAIMode(oCreature, AI_MODE_OPEN_DOORS)) fDoorRange = GetLocalFloat(oCreature, AI_OPEN_DOORS_RANGE); + if(AI_DEBUG && fTrapRange != 0.0) ai_Debug("0i_actions", "1579", " Checking " + FloatToString(fTrapRange, 0, 0) + " foot area for traps."); + if(AI_DEBUG && fLootRange != 0.0) ai_Debug("0i_actions", "1580", " Checking " + FloatToString(fLootRange, 0, 0) + " foot area for traps."); + if(AI_DEBUG && fLockRange != 0.0) ai_Debug("0i_actions", "1581", " Checking " + FloatToString(fLockRange, 0, 0) + " foot area for locks."); + if(AI_DEBUG && fDoorRange != 0.0) ai_Debug("0i_actions", "1582", " Checking " + FloatToString(fDoorRange, 0, 0) + " foot area for doors."); + float fLongestRange = fTrapRange; + vector vCreature = GetPositionFromLocation(GetLocation(oCreature)); + if(fLongestRange < fLootRange) fLongestRange = fLootRange; + if(fLongestRange < fLockRange) fLongestRange = fLockRange; + if(fLongestRange < fDoorRange) fLongestRange = fDoorRange; + object oObject = GetFirstObjectInShape(SHAPE_SPHERE, fLongestRange, lMaster, TRUE, nFilter); + while(oObject != OBJECT_INVALID) + { + fObjectDistance = GetDistanceBetween(oMaster, oObject); + if(AI_DEBUG) ai_Debug("0i_actions", "1651", "Checking Nearby Objects: " + + GetName(oObject) + " fDistance: " + FloatToString(fObjectDistance, 0, 2)); + if(GetTrapDetectedBy(oObject, oCreature)) + { + if(fTrapRange >= fObjectDistance) + { + if(ai_ReactToTrap(oCreature, oObject)) return TRUE; + } + } + if(GetLocked(oObject)) + { + if(fLockRange >= fObjectDistance) + { + if(ai_AttemptToByPassLock(oCreature, oObject)) return TRUE; + } + } + nObjectType = GetObjectType(oObject); + if(fDoorRange >= fObjectDistance && nObjectType == OBJECT_TYPE_DOOR) + { + if(ai_AttemptToOpenDoor(oCreature, oObject)) return TRUE; + } + if(fLootRange >= fObjectDistance) + { + if(nObjectType == OBJECT_TYPE_PLACEABLE) + { + if(!GetLocalInt(oObject, AI_OBJECT_IN_USE) && + ai_IsContainerLootable(oCreature, oObject)) + { + if(GetLocked(oObject)) + { + string sTag = GetTag(oCreature); + if(GetLocalInt(oObject, "AI_LOCKED_" + sTag)) return FALSE; + AssignCommand(oCreature, ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oObject) + " is locked!", TRUE))); + ActionDoCommand(ai_HaveCreatureSpeak(oCreature, 8, ":47:30:43:5:36:")); + SetLocalInt(oObject, "AI_LOCKED_" + sTag, TRUE); + return FALSE; + } + ai_ClearCreatureActions(); + ActionMoveToObject(oObject, TRUE); + AssignCommand(oCreature, ActionDoCommand(ai_SearchObject(oCreature, oObject, oMaster))); + return TRUE; + } + } + else if(nObjectType == OBJECT_TYPE_ITEM) + { + if(ai_ShouldIPickItUp(oCreature, oObject)) + { + ActionPickUpItem(oObject); + return TRUE; + } + } + } + oObject = GetNextObjectInShape(SHAPE_SPHERE, fLongestRange, lMaster, TRUE, nFilter); + } + return FALSE; +} +void ai_DetermineSpecialBehavior(object oCreature) +{ + object oTarget = ai_GetNearestEnemy(oCreature, 1, 7, 7, -1, -1, TRUE); + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE)) + { + if(ai_GetIsInCombat(oCreature)) ai_DoMonsterCombatRound(oTarget); + // * if not attacking, then wander. + else + { + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionRandomWalk()); + return; + } + } + else if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE)) + { + if(GetIsObjectValid(ai_GetAttackedTarget(oCreature, TRUE, TRUE))) + { + if(oTarget != OBJECT_INVALID && GetDistanceBetween(oCreature, oTarget) <= 6.0) + { + if(!GetIsFriend(oTarget)) + { + if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_coward"); + ActionMoveAwayFromObject(oTarget, TRUE, AI_RANGE_LONG); + } + } + } + } + else if(!IsInConversation(OBJECT_SELF)) + { + AssignCommand(oCreature, ai_ClearCreatureActions()); + AssignCommand(oCreature, ActionRandomWalk()); + return; + } + } +} +//This function is used only because ActionDoCommand can only accept void functions +void ai_CreateSignPostNPC(string sTag, location lLocal) +{ + CreateObject(OBJECT_TYPE_CREATURE, sTag, lLocal); +} +void ai_ActivateFleeToExit(object oCreature) +{ + //minor optimizations - only grab these variables when actually needed + //can make for larger code, but it's faster + //object oExitWay = GetWaypointByTag("EXIT_" + GetTag(OBJECT_SELF)); + //location lLocal = GetLocalLocation(OBJECT_SELF, "NW_GENERIC_START_POINT"); + //string sTag = GetTag(OBJECT_SELF); + int nPlot = GetLocalInt(oCreature, "NW_GENERIC_MASTER"); + if(nPlot & NW_FLAG_TELEPORT_RETURN || nPlot & NW_FLAG_TELEPORT_LEAVE) + { + effect eVis = EffectVisualEffect(VFX_IMP_UNSUMMON); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCreature); + if(nPlot & NW_FLAG_TELEPORT_RETURN) + { + location lLocal = GetLocalLocation(oCreature, "NW_GENERIC_START_POINT"); + string sTag = GetTag(oCreature); + DelayCommand(6.0, AssignCommand(oCreature, ActionDoCommand(ai_CreateSignPostNPC(sTag, lLocal)))); + } + AssignCommand(oCreature, ActionDoCommand(DestroyObject(oCreature, 0.75))); + } + else + { + if(nPlot & NW_FLAG_ESCAPE_LEAVE) + { + object oExitWay = GetWaypointByTag("EXIT_" + GetTag(oCreature)); + ActionMoveToObject(oExitWay, TRUE); + AssignCommand(oCreature, ActionDoCommand(DestroyObject(oCreature, 1.0))); + } + else if(nPlot & NW_FLAG_ESCAPE_RETURN) + { + string sTag = GetTag(oCreature); + object oExitWay = GetWaypointByTag("EXIT_" + sTag); + ActionMoveToObject(oExitWay, TRUE); + location lLocal = GetLocalLocation(oCreature, "NW_GENERIC_START_POINT"); + DelayCommand(6.0, AssignCommand(oCreature, ActionDoCommand(ai_CreateSignPostNPC(sTag, lLocal)))); + AssignCommand(oCreature, ActionDoCommand(DestroyObject(oCreature, 1.0))); + } + } +} +int ai_GetFleeToExit(object oCreature) +{ + int nPlot = GetLocalInt(oCreature, "NW_GENERIC_MASTER"); + if(nPlot & NW_FLAG_ESCAPE_RETURN) return TRUE; + else if(nPlot & NW_FLAG_ESCAPE_LEAVE) return TRUE; + else if(nPlot & NW_FLAG_TELEPORT_RETURN) return TRUE; + else if(nPlot & NW_FLAG_TELEPORT_LEAVE) return TRUE; + return FALSE; +} +void ai_ActionInitialization() +{ + SetAnimationCondition(NW_ANIM_FLAG_IS_ACTIVE); + SetAnimationCondition(NW_ANIM_FLAG_INITIALIZED); + SetLocalLocation(OBJECT_SELF, "ANIM_START_LOCATION", GetLocation(OBJECT_SELF)); +} +// Start interacting with a placeable object +void ai_ActionStartInteracting(object oPlaceable) +{ + SetAnimationCondition(NW_ANIM_FLAG_IS_INTERACTING); + ActionMoveToObject(oPlaceable, FALSE, DISTANCE_TINY); + ActionDoCommand(SetFacingPoint(GetPosition(oPlaceable))); + SetCurrentInteractionTarget(oPlaceable); + AnimActionPlayRandomInteractAnimation(oPlaceable); +} + +void ai_ActionStopInteracting() +{ + AnimActionRandomMoveAway(GetCurrentInteractionTarget(), DISTANCE_LARGE); + SetCurrentInteractionTarget(OBJECT_INVALID); + SetAnimationCondition(NW_ANIM_FLAG_IS_INTERACTING, FALSE); + AnimActionTurnAround(); + AnimActionPlayRandomAnimation(); +} + +// Start talking with a friend +void ai_ActionStartTalking(object oFriend, int nHDiff=0) +{ + object oMe = OBJECT_SELF; + ActionMoveToObject(oFriend, FALSE, DISTANCE_TINY); + AnimActionPlayRandomGreeting(nHDiff); + AssignCommand(oFriend, ActionMoveToObject(oMe, FALSE, DISTANCE_TINY)); + AssignCommand(oFriend, AnimActionPlayRandomGreeting(0 - nHDiff)); + SetCurrentFriend(oFriend); + AssignCommand(oFriend, SetCurrentFriend(oMe)); + ActionDoCommand(SetFacingPoint(GetPosition(oFriend))); + AssignCommand(oFriend, ActionDoCommand(SetFacingPoint(GetPosition(oMe)))); + SetAnimationCondition(NW_ANIM_FLAG_IS_TALKING); + SetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, TRUE, oFriend); +} +void ai_ActionStopTalking(object oFriend, int nHDiff=0) +{ + object oMe = OBJECT_SELF; + AnimActionPlayRandomGoodbye(nHDiff); + AnimActionRandomMoveAway(oFriend, DISTANCE_LARGE); + AssignCommand(oFriend, AnimActionPlayRandomGoodbye(0 - nHDiff)); + AssignCommand(oFriend, AnimActionRandomMoveAway(oMe, DISTANCE_HUGE)); + SetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, FALSE); + SetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, FALSE, oFriend); +} +object ai_GetRandomFriend(float fMaxDistance) +{ + object oCreature = OBJECT_SELF; + location lStartLocation = GetLocalLocation(oCreature, "ANIM_START_LOCATION"); + object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, + REPUTATION_TYPE_FRIEND, + oCreature, d2(), + CREATURE_TYPE_PERCEPTION, + PERCEPTION_SEEN); + //SendMessageToPC(GetFirstPC(), " 0i_actions, 1748 oFriend: " + GetName(oFriend) + + // " AnimationCondition: " + IntToString(GetAnimationCondition(NW_ANIM_FLAG_IS_ACTIVE, oFriend)) + + // " Conversation: " + IntToString(IsInConversation(oFriend)) + + // " Combat: " + IntToString(GetIsInCombat(oFriend)) + + // " Distance: " + FloatToString(GetDistanceBetweenLocations(GetLocation(oFriend), lStartLocation), 0,0 )); + if(fMaxDistance > 20.0) fMaxDistance = 20.0; + if(GetIsObjectValid(oFriend) + && !GetIsPC(oFriend) + && !GetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, oFriend) + && !IsInConversation(oFriend) + && !GetIsInCombat(oFriend) + && GetDistanceBetweenLocations(GetLocation(oFriend), lStartLocation) <= fMaxDistance) + { + return oFriend; + } + + return OBJECT_INVALID; +} +int ai_ActionFindFriend(float fMaxDistance) +{ + // Try and find a friend to talk to. + object oFriend = ai_GetRandomFriend(fMaxDistance); + //SendMessageToPC(GetFirstPC(), GetName(oFriend) + " TALKING: " + IntToString(GetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, oFriend))); + if(GetIsObjectValid(oFriend) && !GetAnimationCondition(NW_ANIM_FLAG_IS_TALKING, oFriend)) + { + int nHDiff = GetHitDice(OBJECT_SELF) - GetHitDice(oFriend); + ai_ActionStartTalking(oFriend, nHDiff); + return TRUE; + } + return FALSE; +} +object ai_GetRandomObjectbyTag(string sTag, float fMaxDistance) +{ + int nIndex; + if(fMaxDistance < DISTANCE_MEDIUM) nIndex = d4(); + else if (fMaxDistance < DISTANCE_HUGE) nIndex = d8(); + else nIndex = d10(); + location lStartLocation = GetLocalLocation(OBJECT_SELF, "ANIM_START_LOCATION"); + if(fMaxDistance > 20.0) fMaxDistance = 20.0; + object oObject = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lStartLocation, nIndex); + while(nIndex > 0) + { + if(GetTag(oObject) == sTag && + GetDistanceBetweenLocations(GetLocation(oObject), lStartLocation) <= fMaxDistance) break; + oObject = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lStartLocation, --nIndex); + } + if(GetIsObjectValid(oObject)) + return oObject; + return OBJECT_INVALID; +} +int ai_ActionSitInChair(float fMaxDistance) +{ + object oChair = GetRandomObjectByTag("Chair", fMaxDistance); + if (GetIsObjectValid(oChair) && + !GetIsObjectValid(GetSittingCreature(oChair))) + { + ActionSit(oChair); + SetAnimationCondition(NW_ANIM_FLAG_IS_INTERACTING); + return TRUE; + } + return FALSE; +} +object ai_GetRandomUseableObject(float fMaxDistance) +{ + int nIndex; + if(fMaxDistance < DISTANCE_MEDIUM) nIndex = d2(); + else if (fMaxDistance < DISTANCE_HUGE) nIndex = d4(); + else nIndex = d6(); + location lStartLocation = GetLocalLocation(OBJECT_SELF, "ANIM_START_LOCATION"); + if(fMaxDistance > 20.0) fMaxDistance = 20.0; + object oObject = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lStartLocation, nIndex); + while(nIndex > 0) + { + if(GetUseableFlag(oObject) && !GetLocked(oObject) && + GetDistanceBetweenLocations(GetLocation(oObject), lStartLocation) <= fMaxDistance) break; + oObject = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lStartLocation, --nIndex); + } + if(GetIsObjectValid(oObject)) + return oObject; + return OBJECT_INVALID; +} +int ai_ActionFindPlaceable(float fMaxDistance) +{ + object oPlaceable = ai_GetRandomUseableObject(fMaxDistance); + if(GetIsObjectValid(oPlaceable)) + { + ai_ActionStartInteracting(oPlaceable); + return 1; + } + return 0; +} +int ai_ActionCheckDoor(float fMaxDistance) +{ + int nIndex = 1; + object oCreature = OBJECT_SELF; + location lStartLocation = GetLocalLocation(oCreature, "ANIM_START_LOCATION"); + if(fMaxDistance > 20.0) fMaxDistance = 20.0; + object oDoor = GetNearestObject(OBJECT_TYPE_DOOR, oCreature); + while(oDoor != OBJECT_INVALID) + { + if(GetDistanceBetweenLocations(GetLocation(oDoor), lStartLocation) <= fMaxDistance) + { + // Make sure everyone doesn't run to close or open the same door. + if(!GetLocalInt(oDoor, "DOOR_INTERACTION")) + { + if(GetIsOpen(oDoor)) + { + //SendMessageToPC(GetFirstPC(), GetName(oCreature) + + // " Closing " + GetName(oDoor) + "."); + SetLocalInt(oDoor, "DOOR_INTERACTION", TRUE); + ActionCloseDoor(oDoor); + AssignCommand(oDoor, ActionDoCommand(SetLocalInt(oDoor, "DOOR_INTERACTION", FALSE))); + return TRUE; + } + else if(GetLocalInt(GetModule(), AI_RULE_OPEN_DOORS)) + { + //SendMessageToPC(GetFirstPC(), GetName(oDoor) + " Locked: " + + // IntToString(GetLocked(oDoor)) + " Trapped: " + + // IntToString(GetIsTrapped(oDoor)) + + // " Plot: " + IntToString(GetPlotFlag(oDoor))); + if(!GetLocked(oDoor) && + !GetIsTrapped(oDoor) && + !GetPlotFlag(oDoor)) + { + //SendMessageToPC(GetFirstPC(), GetName(oCreature) + + // " Opening " + GetName(oDoor) + "."); + SetLocalInt(oDoor, "DOOR_INTERACTION", TRUE); + ActionOpenDoor(oDoor); + // If a door has been opened lets not go right behind and close for a minute. + DelayCommand(60.0, SetLocalInt(oDoor, "DOOR_INTERACTION", FALSE)); + return TRUE; + } + } + } + } + oDoor = GetNearestObject(OBJECT_TYPE_DOOR, oCreature, ++nIndex); + } + return FALSE; +} +int ai_ActionInteraction() +{ + // If we're talking, either keep going or stop. + // Low prob of stopping, since both parties have + // a chance and conversations are cool. + if(GetAnimationCondition(NW_ANIM_FLAG_IS_TALKING)) + { + object oFriend = GetCurrentFriend(); + //SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF) + " Is talking to " + GetName(oFriend)); + int nHDiff = GetHitDice(OBJECT_SELF) - GetHitDice(oFriend); + if(Random(100) < 20) + { + //SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF) + " I'm done talking!"); + ai_ActionStopTalking(oFriend, nHDiff); + return TRUE; + } + AnimActionPlayRandomTalkAnimation(nHDiff); + return TRUE; + } + // If we're interacting with a placeable, either keep going or stop. + // High probability of stopping, since looks silly to + // constantly turn something on-and-off. + if(GetAnimationCondition(NW_ANIM_FLAG_IS_INTERACTING)) + { + //SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF) + " Is interacting."); + if(Random(100) < 40) + { + //SendMessageToPC(GetFirstPC(), GetName(OBJECT_SELF) + " I'm done interacting!"); + ai_ActionStopInteracting(); + return TRUE; + } + AnimActionPlayRandomInteractAnimation(GetCurrentInteractionTarget()); + return TRUE; + } + return FALSE; +} +location ai_GetWalkingLocation(object oSource, float fDistance) +{ + location lStart = GetLocation(oSource); + // Try to move in a north/south/east/west direction that will allow better + // movement around the map! + float fFacing = GetFacing(oSource); + if(Random(100) < 25) fFacing = IntToFloat(Random(360)); + float fAngle; + if(fFacing > 315.0 || fFacing < 45.0) fAngle = DIRECTION_EAST; + else if(fFacing < 135.0) fAngle = DIRECTION_NORTH; + else if(fFacing < 225.0) fAngle = DIRECTION_WEST; + else fAngle = DIRECTION_SOUTH; + fAngle += IntToFloat(Random(20) - 10); + float fOrientation = fAngle; + return GenerateNewLocationFromLocation(lStart, fDistance, fAngle, fOrientation); +} +void ai_ActionRandomWalk(float fMaxDistance) +{ + // If we stay within our alloted distance then we can walk to the new location. + location lStartLocation = GetLocalLocation(OBJECT_SELF, "ANIM_START_LOCATION"); + int nRandom = FloatToInt(fMaxDistance); + if(nRandom > 20) nRandom = 20; + float fRandom = IntToFloat(Random(nRandom) + 1); + location lNewLocation = ai_GetWalkingLocation(OBJECT_SELF, fRandom); + if(AI_DEBUG) ai_Debug("0i_actions", "2092", GetName(OBJECT_SELF) + " is walking " + + FloatToString(GetDistanceBetweenLocations(lNewLocation, lStartLocation), 0, 0) + + " distance of fMaxDistance: " + FloatToString(fMaxDistance, 0, 0)); + ActionMoveToLocation(lNewLocation); +} +void ai_Actions() +{ + float fMaxDistance = GetLocalFloat(GetModule(), AI_RULE_WANDER_DISTANCE); + // Are we interacting? If so continue else see what else there is to do. + if(ai_ActionInteraction()) return; + // If we got here, we're not busy + ClearAllActions(); + // Check for chance to do an action to keep things interesting. + int nRoll = Random(100); + if(fMaxDistance < 2.0) + { + if(nRoll < 51) AnimActionPlayRandomAnimation(); + return; + } + int nRace = GetRacialType(OBJECT_SELF); + if(nRace != RACIAL_TYPE_ABERRATION && nRace != RACIAL_TYPE_ANIMAL && + nRace != RACIAL_TYPE_BEAST && nRace != RACIAL_TYPE_MAGICAL_BEAST && + nRace != RACIAL_TYPE_OOZE && nRace != RACIAL_TYPE_VERMIN) + { + if(nRoll < 5) if(ai_ActionSitInChair(fMaxDistance)) return; + // Open or close a door + if(nRoll < 20) if(ai_ActionCheckDoor(fMaxDistance)) return; + // Fiddle with a placeable + if(nRoll < 40) if(ai_ActionFindPlaceable(fMaxDistance)) return; + // Start talking to a friend + if(nRoll < 50) if(ai_ActionFindFriend(fMaxDistance)) return; + } + // Lets walk around. + if(nRoll < 80) + { + ai_ActionRandomWalk(fMaxDistance); + return; + } + // If we find nothing interesting to do then just stay put and look interesting. + AnimActionPlayRandomAnimation(); +} +int ai_CheckCurrentAction() +{ + int nAction = GetCurrentAction(); + if(nAction == ACTION_SIT) + { + // low prob of getting up, so we don't bop up and down constantly + if (Random(10) == 0) + { + AnimActionGetUpFromChair(); + return TRUE; + } + } + else if(nAction != ACTION_INVALID) + { + // Sometimes we cannot do an action so lets break out sometimes. + if((nAction == ACTION_CLOSEDOOR || + nAction == ACTION_OPENDOOR || + nAction == ACTION_MOVETOPOINT) && Random(100) < 20) return FALSE; + // we're doing *something*, don't switch + //AnimDebug("performing action"); + return TRUE; + } + return FALSE; +} +void ai_AmbientAnimations() +{ + if(!GetAnimationCondition(NW_ANIM_FLAG_INITIALIZED)) ai_ActionInitialization(); + // Check if we should turn off + if(!CheckIsAnimActive(OBJECT_SELF)) return; + // Check current actions so we don't interrupt something in progress + if(ai_CheckCurrentAction()) return; + // First check: go back to starting position and rest if we are hurt + //if(AnimActionRest()) return; + // If we get here then lets go see what we can do! + ai_Actions(); +} diff --git a/src/module/nss/0i_associates.nss b/src/module/nss/0i_associates.nss new file mode 100644 index 0000000..2309160 --- /dev/null +++ b/src/module/nss/0i_associates.nss @@ -0,0 +1,2192 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0i_associates + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Scripts used for Associates. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +#include "nw_inc_gff" +// Return TRUE if oCreature can attack based on current modes and actions. +int ai_CanIAttack(object oCreature); +// Returns the nearest locked object from oMaster. +object ai_GetNearestLockedObject(object oCreature); +// Will look for the oTarget or go to the oSpeaker depending on the situation. +void ai_FindTheEnemy(object oCreature, object oSpeaker, object oTarget, int bMonster); +// Selects the correct response base on nCommand from oCommander. +// These are given from either a radial menu option or voice command. +void ai_SelectAssociateCommand(object oCreature, object oCommander, int nCommand); +// Set nAction for the caller to pass to their associates. i.e. For henchmans summons. +void ai_PassActionToAssociates(object oCreature, int nAction, int bStatus = TRUE); +// Set Set the AI Mode to oAssociate and their associates. +void ai_PassAIModeToAssociates(object oAssociate, int nAIMode, int bStatus = TRUE); +// Set oCreature's ai scripts based on its first class or the variable "AI_DEFAULT_SCRIPT". +// bSetBasicAIScript set to TRUE will skip defensive and ambush tactic type scripts. +void ai_SetAssociateAIScript(object oCreature, int bCheckTacticScripts = TRUE); +// Returns TRUE if oCreature can speak. +int ai_CanISpeak(object oCreature); +// Cleansup any henchman actions and then removes them from the PC's faction. +void ai_FireHenchman(object oPC, object oHenchman); +// Will cast defensive spells (Buffs) on oPC's party from oCreature. +void ai_HenchmanCastDefensiveSpells(object oCreature, object oPC); +// Returns TRUE if we are starting combat due to an enemy being near. +// This should be checked after any "is in combat" checks. +int ai_CheckForCombat(object oCreature, int bMonster); +// Checks all perceived creatures to see if we should calculate a combat round +// or start combat for Associates. +void ai_AssociateEvaluateNewThreat(object oCreature, object oLastPerceived, string sPerception); +// Checks all perceived creatures to see if we should calculate a combat round +// or start combat for Monsters. +void ai_MonsterEvaluateNewThreat(object oCreature, object oLastPerceived, string sPerception); +// Copies all int, float, and string variables from oOldObject to oNewObject. +void ai_CopyObjectVariables(object oOldObject, object oNewObject); +//****************************************************************************** +//********************* Creature event scripts ********************************* +//****************************************************************************** + +// Add to nw_ch_aca OnRested event script of henchman. +void ai_OnRested(object oCreature); + +//****************************************************************************** +//******************* Associate AI option scripts ****************************** +//****************************************************************************** + +// Increments/Decrements the following distance of associates. +void ai_FollowIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType); +// Turns on/off Ranged combat for oAssociate. +void ai_Ranged(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Ignore enemy associates for oAssociate. +void ai_Ignore_Associates(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Ignore floor traps for oAssociate. +void ai_Ignore_Traps(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Search for oAssociate. +void ai_Search(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Stealth for oAssociate. +void ai_Stealth(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Open Doors for oAssociate. +void ai_OpenDoor(object oPC, object oAssociate, string sAssociateType); +// Turns on/off Picking/Bashing locks for oAssociate. +void ai_Locks(object oPC, object oAssociate, string sAssociateType, int nMode); +// Turns on/off Disarming of Traps for oAssociate. +void ai_Traps(object oPC, object oAssociate, string sAssociateType); +// Turns on/off the amount of speaking for oAssociate. +void ai_ReduceSpeech(object oPC, object oAssociate, string sAssociateType); +// Turns on/off use of offensive/defensive spells. +void ai_UseOffensiveMagic(object oPC, object oAssociate, int bDefensive, int bOffensive, string sAssociateType); +// Turns on/off magic use. +void ai_UseMagic(object oPC, object oAssociate, string sAssociateType); +// Turn Magic Item use on/off for oAssociates. +void ai_UseMagicItems(object oPC, object oAssociate, string sAssociateType); +// Adjusts loot options for oAssociate +void ai_Loot(object oPC, object oAssociate, string sAssociateType); +// Adjust loot options for oAssociate +void ai_Spontaneous(object oPC, object oAssociate, string sAssociateType); +// Increments/Decrements the magic use variable for the AI. +void ai_MagicIncrement(object oPC, object oAssociate, int nIncrement, string sAssociateType); +// Increments/Decrements the Loot Range use variable for the AI. +void ai_LootRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType); +// Increments/Decrements the Lock Range use variable for the AI. +void ai_LockRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType); +// Increments/Decrements the Trap Range use variable for the AI. +void ai_TrapRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType); +// Increments/Decrements the Open Door Range use variable for the AI. +void ai_OpenDoorIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType); +// Saves a new AI script for oAssociate. +void ai_SaveAIScript(object oPC, object oAssociate, int nToken); +// Button action for buffing a PC. +void ai_Buff_Button(object oPC, object oAssociate, int nOption, string sAssociateType); +// Button action for setting healing ranges. +void ai_Heal_Button(object oPC, object oAssociate, int nIncrement, string sVar, string sAssociateType); +// Button action for turning healing on/off. +void ai_Heal_OnOff(object oPC, object oAssociate, string sAssociateType, int nMode); +// Button action for selecting a target to follow. +void ai_FollowTarget(object oPC, object oAssociate); +// Code to make oCreature guard oMaster. +void ai_Philos_Guard(object oMaster, object oCreature); +// Code to make OBJECT_SELF follow oMaster. +void ai_Philos_Follow(object oMaster); +// Code to make OBJECT_SELF hold at their location. +void ai_Philos_StandGround(object oMaster); +// Code to make oCreature attack the nearest enemy. +void ai_Philos_AttackNearest(object oMaster, object oCreature); +// Code to make oCreature turn search mode on. +void ai_Philos_SetSearch(object oMaster, object oCreature, string sAssociateType, int bTurnOn); +// Code to make oCreature turn stealth mode on. +void ai_Philos_SetStealth(object oMaster, object oCreature, string sAssociateType, int bTurnOn); +// Button action for giving commands to associates. +void ai_DoCommand(object oPC, object oAssociate, int nCommand); +// Button action to have associate do an action based on the target via OnPlayer Target event. +void ai_Action(object oPC, object oAssociate); +// Toggles between normal ai script and special tactic ai scripts. +void ai_AIScript(object oPC, object oAssociate, string sAssociate, int nToken); +// Has the PC select a Trap and then place it on the ground from an associate. +void ai_HavePCPlaceTrap(object oPC, object oAssociate); +// Jumps oAssociate to oPC, if oPC == oAssociate it jumps all oAssocites to oPC. +void ai_JumpToPC(object oPC, object oAssociate); +// Allow oAssociate to use no clipping. +void ai_GhostMode(object oPC, object oAssociate, int nToken, string sAssociateType); +// Changes the camera view from either the player to the associate or back. +void ai_ChangeCameraView(object oPC, object oAssociate); +// Checks that the oAssociate is within sight and then opens the inventory. +void ai_OpenInventory(object oAssociate, object oPC); +// Executes an installed plugin. +void ai_Plugin_Execute(object oPC, string sElem, int bUser = 0); + +int ai_CanIAttack(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_associate", "122", "Can I attack? Hold mode: " + + IntToString(ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND)) + + " Follow mode: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_FOLLOW)) + + " Action (19/4): " + IntToString(GetCurrentAction(oCreature))); + if(ai_GetIsCharacter(oCreature)) return TRUE; + int nAction = GetCurrentAction(oCreature); + return (!ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND) && + !ai_GetAIMode(oCreature, AI_MODE_FOLLOW) && + nAction != ACTION_ITEMCASTSPELL && + nAction != ACTION_CASTSPELL); +} +object ai_GetNearestLockedObject(object oCreature) +{ + int nCnt = 1; + object oMaster = GetMaster(oCreature); + float fRange = GetLocalFloat(oCreature, AI_TRAP_CHECK_RANGE); + location lCreature = GetLocation(oCreature); + object oObject = GetNearestObjectToLocation(OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE, lCreature, nCnt); + while (oObject != OBJECT_INVALID || GetDistanceBetween(oMaster, oObject) > fRange) + { + if(GetLocked(oObject) && ai_GetIsInLineOfSight(oMaster, oObject)) return oObject; + oObject = GetNearestObjectToLocation(OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE, lCreature, ++nCnt); + } + return OBJECT_INVALID; +} +void ai_FindTheEnemy(object oCreature, object oSpeaker, object oTarget, int bMonster) +{ + if(GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return; + if(oSpeaker == oTarget && d100() < 34) + { + // Let them know we heard something in the distance!. + if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) + { + string sSpeak = "I heard something!"; + int nRoll = d8(); + if(nRoll == 1) sSpeak = "Did you hear that?"; + if(nRoll == 2) sSpeak = "What was that noise?"; + if(nRoll == 3) sSpeak = "Something is moving."; + if(nRoll == 4) sSpeak = "Lookout! I heard a noise."; + if(nRoll == 5) sSpeak = "Listen! We have company."; + AssignCommand(oCreature, ai_HaveCreatureSpeak(oCreature, 0, sSpeak)); + } + ai_HaveCreatureSpeak(oCreature, 8, ":43:6:9:10:23:42:"); + } + if(GetLocalString(oCreature, AI_COMBAT_SCRIPT) == "ai_a_peaceful" || + GetLocalString(oCreature, AI_COMBAT_SCRIPT) == "ai_coward") return; + float fDistance, fPerceptionDistance; + if(bMonster) + { + // Check distance from the creature hearing this and the target. + fDistance = GetDistanceBetween(oCreature, oTarget); + fPerceptionDistance = GetLocalFloat(GetModule(), AI_RULE_PERCEPTION_DISTANCE); + } + else + { + // We want to use the distance between the PC and target not us. + fDistance = GetDistanceBetween(GetMaster(), oTarget); + fPerceptionDistance = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + } + if(AI_DEBUG) ai_Debug("0i_associates", "175", " fDistance: " + FloatToString(fDistance, 0, 2) + + " fPerceptionDistance: " + FloatToString(fPerceptionDistance, 0, 2) + + " Hiding? " + IntToString(GetStealthMode(oTarget))); + if(fDistance <= fPerceptionDistance) + { + SetLocalInt(oCreature, AI_AM_I_SEARCHING, TRUE); + if(LineOfSightObject(oCreature, oTarget)) + { + if(fDistance > AI_RANGE_CLOSE) + { + int bMoveForward = TRUE; + // We check this because if the enemy is moving or has not + // started acting then we don't want to move up on them as they + // might move towards us! Just attack! Only sneak attack if they are busy. + int nAction = GetCurrentAction(oTarget); + if(AI_DEBUG) ai_Debug("0i_associates", "189", GetName(oTarget) + " current action: " + IntToString(nAction)); + if(nAction == ACTION_MOVETOPOINT || + nAction == ACTION_INVALID || + nAction == ACTION_RANDOMWALK) bMoveForward = FALSE; + // If they are attacking make sure it is in melee? + // If not then don't move since they might be moving toward us. + if(nAction == ACTION_ATTACKOBJECT) + { + if(!ai_GetNumOfEnemiesInRange(oTarget)) bMoveForward = FALSE; + } + if(bMoveForward) + { + if(AI_DEBUG) ai_Debug("0i_associates", "201", "Running towards combat to engage " + GetName(oTarget)); + ActionMoveToObject(oTarget, TRUE, AI_RANGE_CLOSE); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING))); + return; + } + if(AI_DEBUG) ai_Debug("0i_associates", "207", "Searching for " + GetName(oTarget) + " while moving towards " + GetName(oSpeaker)); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + ActionMoveToObject(oSpeaker); + return; + } + if(AI_DEBUG) ai_Debug("0i_associates", "176", "Moving and searching for " + GetName(oTarget)); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + ActionMoveToLocation(GetLocation(oTarget), FALSE); + //ActionMoveToObject(oTarget, FALSE, AI_RANGE_MELEE); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING))); + return; + } + if(AI_DEBUG) ai_Debug("0i_associates", "218", "No line of sight for " + GetName(oTarget) + ". Moving towards " + GetName(oSpeaker)); + ActionMoveToObject(oSpeaker, TRUE); + AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING))); + } + +} +void ai_ReactToAssociate(object oCreature, object oCommander, int bMonster) +{ + object oTarget = GetLocalObject(oCommander, AI_MY_TARGET); + if (oTarget == OBJECT_INVALID) return; + if(ai_GetIsInCombat(oCreature)) + { + if(oCommander == GetMaster(oCreature) && ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) + { + ai_DoAssociateCombatRound(oCreature, oTarget); + } + else ai_DoAssociateCombatRound(oCreature); + return; + } + ai_FindTheEnemy(oCreature, oCommander, oTarget, bMonster); +} +void ai_SelectAssociateCommand(object oCreature, object oCommander, int nCommand) +{ + object oMaster = GetMaster(oCreature); + // These nCommands can be issued even when the caller is busy. + switch(nCommand) + { + // Master is being attacked by the enemy. + case ASSOCIATE_COMMAND_MASTERGOINGTOBEATTACKED: + { + object oAttacker = GetGoingToBeAttackedBy(oMaster); + if(AI_DEBUG) ai_Debug("0i_associate", "120", GetName(oMaster) + " has been attack by " + + GetName(GetGoingToBeAttackedBy(oMaster)) + "!"); + // Used to set who monsters are attacking. + int nAction = GetCurrentAction(oAttacker); + if(nAction == ACTION_ATTACKOBJECT) SetLocalObject(oAttacker, AI_ATTACKED_PHYSICAL, oMaster); + else if(nAction == ACTION_CASTSPELL || nAction == ACTION_ITEMCASTSPELL) + { + SetLocalObject(oAttacker, AI_ATTACKED_SPELL, oMaster); + } + if(!ai_GetIsBusy(oCreature) && ai_CanIAttack(oCreature)) + { + if(ai_GetIsInCombat(oCreature)) ai_DoAssociateCombatRound(oCreature); + else ai_FindTheEnemy(oCreature, oCommander, oAttacker, FALSE); + } + return; + } + // Menu used by a player to have the henchman follow them. + case ASSOCIATE_COMMAND_FOLLOWMASTER: + { + if(AI_DEBUG) ai_Debug("0i_associate", "135", GetName(oMaster) + " has commanded " + + GetName(oCreature) + " to FOLLOW."); + AssignCommand(oCreature, ai_Philos_Follow(oMaster)); + return; + } + // Menu used by a player to have the henchman go into NORMAL MODE. + // We also attack the nearest, this keeps henchman going into combat quickly. + case ASSOCIATE_COMMAND_ATTACKNEAREST: + { + if(AI_DEBUG) ai_Debug("0i_associates", "158", GetName(oMaster) + " has commanded " + + GetName(oCreature) + " to attack nearest(NORMAL MODE)."); + ai_Philos_AttackNearest(oMaster, oCreature); + return; + } + // Menu used by a player to have the henchman stay where they are standing. + case ASSOCIATE_COMMAND_STANDGROUND: + { + if(AI_DEBUG) ai_Debug("0i_associate", "189", GetName(oMaster) + " has commanded " + + GetName(OBJECT_SELF) + " to STANDGROUND."); + AssignCommand(oCreature, ai_Philos_StandGround(oMaster)); + return; + } + // Menu used by a player to have the henchman attack anyone who attacks them. + case ASSOCIATE_COMMAND_GUARDMASTER: + { + if(AI_DEBUG) ai_Debug("0i_associate", "211", GetName(oMaster) + " has commanded " + + GetName(oCreature) + " to GAURDMASTER."); + ai_Philos_Guard(oMaster, oCreature); + return; + } + // Menu used by a player to have the henchman heal them as soon as possible. + case ASSOCIATE_COMMAND_HEALMASTER: + { + // Player will be stuck with this variable if they are not using the AI. + DeleteLocalInt(oCommander, "AI_I_AM_BEING_HEALED"); + if(ai_GetIsInCombat(oCreature)) ai_TryHealingTalent(oCreature, ai_GetNumOfEnemiesInRange(oCreature), oCommander); + else AssignCommand(oCreature, ai_ActionTryHealing(oCreature, oCommander)); + return; + } + // Menu used by a player to toggle a henchmans casting options. + case ASSOCIATE_COMMAND_TOGGLECASTING: + { + if(ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) + { + ai_SetMagicMode(oCreature, AI_MAGIC_NO_MAGIC, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING, TRUE); + ai_SetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING, FALSE); + ai_SendMessages(GetName(oCreature) + " will now cast defensive spells only.", AI_COLOR_GRAY, oCommander); + } + else if(ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + ai_SetMagicMode(oCreature, AI_MAGIC_NO_MAGIC, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING, TRUE); + ai_SendMessages(GetName(oCreature) + " will now cast offensive spells only.", AI_COLOR_GRAY, oCommander); + } + else if(ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + ai_SetMagicMode(oCreature, AI_MAGIC_NO_MAGIC, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING, FALSE); + ai_SendMessages(GetName(oCreature) + " will now cast any spell.", AI_COLOR_GRAY, oCommander); + } + else + { + ai_SetMagicMode(oCreature, AI_MAGIC_NO_MAGIC, TRUE); + ai_SetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING, FALSE); + ai_SetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING, FALSE); + ai_SendMessages(GetName(oCreature) + " will not use any magic.", AI_COLOR_GRAY, oCommander); + } + aiSaveAssociateModesToDb(oMaster, oCreature); + return; + } + } + // If we are busy then these nCommands are ignored. + if(!ai_GetIsBusy(oCreature)) + { + // Respond to shouts from friendly non-PCs only. + if (ai_CanIAttack(oCreature)) + { + if(nCommand == AI_ALLY_IS_WOUNDED) + { + if(ai_TryHealing(oCreature, oCommander)) return; + } + else if(nCommand == AI_ALLY_IS_DISEASED || + nCommand == AI_ALLY_IS_POISONED || + nCommand == AI_ALLY_IS_WEAK) + { + if(ai_HealSickness(oCreature, oCommander, oMaster, nCommand)) return; + } + // A friend sees an enemy. If we are not in combat lets seek them out too! + else if(nCommand == AI_ALLY_SEES_AN_ENEMY || + nCommand == AI_ALLY_HEARD_AN_ENEMY) + { + if(AI_DEBUG) ai_Debug("0i_associates", "282", GetName(oCreature) + " receives notice that " + + GetName(oCommander) + " has seen1/heard2(" + IntToString(nCommand) + " an enemy: " + + GetName(GetLocalObject(oCommander, AI_MY_TARGET)) + "!"); + ai_ReactToAssociate(oCreature, oCommander, FALSE); + return; + } + // A friend is in combat. Make some checks to see if we should help. + else if(nCommand == AI_ALLY_ATKED_BY_WEAPON || + nCommand == AI_ALLY_ATKED_BY_SPELL) + { + if(AI_DEBUG) ai_Debug("0i_associates", "291", GetName(oCreature) + " receives notice that " + + GetName(oCommander) + " was attacked by an enemy!" + + GetName(GetLocalObject(oCommander, AI_MY_TARGET)) + "!"); + ai_ReactToAssociate(oCreature, oCommander, FALSE); + return; + } + else if(nCommand == AI_ALLY_IS_DEAD) + { // Nothing at the moment. + if(AI_DEBUG) ai_Debug("0i_associates", "298", GetName(oCreature) + " receives notice that " + + GetName(oCommander) + " has died!"); + return; + } + } + switch(nCommand) + { + case ASSOCIATE_COMMAND_MASTERATTACKEDOTHER: + { + if(AI_DEBUG) ai_Debug("0i_associate", "307", GetName(oMaster) + " has attacked!"); + if(ai_CanIAttack(oCreature)) + { + if(ai_GetIsInCombat(oCreature)) ai_DoAssociateCombatRound(oCreature); + else ai_FindTheEnemy(oCreature, oCommander, ai_GetAttackedTarget(oCommander, TRUE, TRUE), FALSE); + } + return; + } + // Master tried to open a door or chest that is locked. + case ASSOCIATE_COMMAND_MASTERFAILEDLOCKPICK: + { + // In command mode we let the player tell us what to do. + if(ai_CanIAttack(oCreature)) + { + object oLock = ai_GetNearestLockedObject(oMaster); + //Check and see if our master want's us to open locks. + if(ai_GetAIMode(oCreature, AI_MODE_PICK_LOCKS) || + ai_GetAIMode(oCreature, AI_MODE_BASH_LOCKS)) + { + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_AttemptToByPassLock(oCreature, oLock); + } + } + return; + } + // Master saw a trap. + case ASSOCIATE_COMMAND_MASTERSAWTRAP: + { + // In command mode we let the player tell us what to do. + if(ai_CanIAttack(oCreature)) + { + object oTrap = GetLastTrapDetected(oMaster); + // Sometimes GetLastTrapDetected seems to fail. + if(oTrap == OBJECT_INVALID) oTrap = GetNearestTrapToObject(oMaster, TRUE); + //Check and see if our master want's us to disarm the trap. + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); + SetTrapDetectedBy(oTrap, oCreature); + ai_ReactToTrap(oCreature, oTrap); + } + return; + } + // Menu used by a player to toggle henchmans search on and off. + case ASSOCIATE_COMMAND_TOGGLESEARCH: + { + int bTurnOn = !ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH); + string sAssociateType = ai_GetAssociateType(oMaster, oCreature); + ai_Philos_SetSearch(oMaster, oCreature, sAssociateType, bTurnOn); + return; + } + // Menu used by a player to toggle henchmans stealth on and off. + case ASSOCIATE_COMMAND_TOGGLESTEALTH: + { + int bTurnOn = !ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH); + string sAssociateType = ai_GetAssociateType(oMaster, oCreature); + ai_Philos_SetStealth(oMaster, oCreature, sAssociateType, bTurnOn); + return; + } + // Menu used by a player to have the henchman try to bypass the nearest lock. + case ASSOCIATE_COMMAND_PICKLOCK: + { + ai_SetAIMode(oCreature, AI_MODE_DEFEND_MASTER, FALSE); + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_SetAIMode(oCreature, AI_MODE_FOLLOW, FALSE); + object oLock = ai_GetNearestLockedObject(oMaster); + // Clear locked variable incase we tried already. + string sID = ObjectToString(oCreature); + SetLocalInt(oLock, "AI_LOCKED_" + sID, FALSE); + ai_AttemptToByPassLock(oCreature, oLock); + aiSaveAssociateModesToDb(oMaster, oCreature); + return; + } + // Menu used by a player to have the henchman try to disarm the nearest trap. + case ASSOCIATE_COMMAND_DISARMTRAP: + { + ai_SetAIMode(oCreature, AI_MODE_DEFEND_MASTER, FALSE); + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_SetAIMode(oCreature, AI_MODE_FOLLOW, FALSE); + object oTrap = GetNearestTrapToObject(oMaster); + // Clear trapped variable incase we tried already. + string sID = ObjectToString(oCreature); + ai_ReactToTrap(oCreature, oTrap, TRUE); + aiSaveAssociateModesToDb(oMaster, oCreature); + return; + } + // Menu used by a player to open a henchmans inventory to give, move, or take. + case ASSOCIATE_COMMAND_INVENTORY: + { + if(AI_OPEN_INVENTORY) + { + ai_HaveCreatureSpeak(oCreature, 4, ":29:46:35:"); + OpenInventory(oCreature, oCommander); + } + // Can't look at an associate's inventory. + else + { + ai_HaveCreatureSpeak(oCreature, 6, ":47:30:36:8:48:"); + ai_SendMessages("You cannot open " + GetName(oCreature) + "'s inventory.", AI_COLOR_GRAY, oMaster); + } + return; + } + case ASSOCIATE_COMMAND_LEAVEPARTY: + { + if(AI_REMOVE_HENCHMAN_ON) + { + ai_ClearCreatureActions(); + ai_FireHenchman (GetPCSpeaker(), oCreature); + PlayVoiceChat (VOICE_CHAT_GOODBYE, oCreature); + } + } + } + } +} +void ai_PassActionToAssociates(object oCreature, int nAction, int bStatus = TRUE) +{ + int nAssociateType; + object oAssociate; + for(nAssociateType = 2; nAssociateType < 6; nAssociateType ++) + { + oAssociate = GetAssociate(nAssociateType); + if(oAssociate != OBJECT_INVALID) SetActionMode(oAssociate, nAction, bStatus); + } +} +void ai_PassToAssociate(object oAssociate, int nAIMode, int bStatus) +{ + ai_ClearCreatureActions(TRUE); + ai_SetAIMode(oAssociate, nAIMode, bStatus); +} +void ai_PassAIModeToAssociates(object oAssociate, int nAIMode, int bStatus = TRUE) +{ + ai_SetAIMode(oAssociate, nAIMode, bStatus); + int nAssociateType; + object oAssoc; + for(nAssociateType = 2; nAssociateType < 6; nAssociateType ++) + { + oAssoc = GetAssociate(nAssociateType, oAssociate); + if(oAssoc != OBJECT_INVALID) AssignCommand(oAssoc, ai_PassToAssociate(oAssoc, nAIMode, bStatus)); + } +} +void ai_SetAssociateAIScript(object oCreature, int bCheckTacticScripts = TRUE) +{ + string sCombatAI; + object oMaster = GetMaster(); + if(ai_GetIsCharacter(oMaster)) + { + string sAssociateType = ai_GetAssociateType(oMaster, oCreature); + json jAIData = ai_GetAssociateDbJson(oMaster, sAssociateType, "aidata"); + sCombatAI = JsonGetString(JsonArrayGet(jAIData, 8)); + } + else sCombatAI = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + int nAssociateType = GetAssociateType(oCreature); + if (nAssociateType == ASSOCIATE_TYPE_FAMILIAR && sCombatAI == "") + { + sCombatAI = "ai_a_default"; + } + else if(sCombatAI == "ai_coward") + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, sCombatAI); + return; + } + else if(bCheckTacticScripts && GetLocalInt(GetModule(), AI_RULE_AMBUSH)) + { + // They should have a skill ranks equal to their level + 1 to use a special AI. + int nSkillNeeded = GetHitDice(oCreature) + 1; + if(sCombatAI == "" || sCombatAI == "ai_a_ambusher") + { + // Ambusher: requires either Improved Invisibility or Invisibility. + if(GetHasSpell(SPELL_IMPROVED_INVISIBILITY, oCreature) || + GetHasSpell(SPELL_INVISIBILITY, oCreature)) + { + int bCast = ai_TryToCastSpell(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature); + if(!bCast) bCast = ai_TryToCastSpell(oCreature, SPELL_INVISIBILITY, oCreature); + if(bCast) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_a_ambusher"); + return; + } + } + // Ambusher: Requires a Hide and Move silently skill equal to your level + 1. + else if(GetSkillRank(SKILL_HIDE, oCreature) >= nSkillNeeded && + GetSkillRank(SKILL_MOVE_SILENTLY, oCreature) >= nSkillNeeded) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_a_ambusher"); + return; + } + } + // Defensive : requires Parry skill equal to your level or Expertise. + else if(sCombatAI == "ai_a_defensive" || + (sCombatAI == "" && + (GetSkillRank(SKILL_PARRY, oCreature) >= nSkillNeeded || + GetHasFeat(FEAT_EXPERTISE, oCreature) || + GetHasFeat(FEAT_IMPROVED_EXPERTISE, oCreature)))) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_a_defensive"); + return; + } + else if(sCombatAI == "ai_cntrspell" || GetHasSpell(SPELL_LESSER_DISPEL, oCreature) || + GetHasSpell(SPELL_DISPEL_MAGIC, oCreature) || GetHasSpell(SPELL_GREATER_DISPELLING, oCreature)) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_cntrspell"); + return; + } + } + if(sCombatAI == "") + { + // Select the best ai for this henchmen based on class. + int nClass = GetClassByPosition(1, oCreature); + // If they have more than one class use the default ai. + if(GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID) sCombatAI = "ai_a_default"; + else if(nClass == CLASS_TYPE_BARBARIAN) sCombatAI = "ai_a_barbarian"; + else if(nClass == CLASS_TYPE_BARD) sCombatAI = "ai_a_bard"; + else if(nClass == CLASS_TYPE_CLERIC) sCombatAI = "ai_a_cleric"; + else if(nClass == CLASS_TYPE_DRUID) sCombatAI = "ai_a_druid"; + else if(nClass == CLASS_TYPE_FIGHTER) sCombatAI = "ai_a_fighter"; + else if(nClass == CLASS_TYPE_MONK) sCombatAI = "ai_a_monk"; + else if(nClass == CLASS_TYPE_PALADIN) sCombatAI = "ai_a_paladin"; + else if(nClass == CLASS_TYPE_RANGER) sCombatAI = "ai_a_ranger"; + else if(nClass == CLASS_TYPE_ROGUE) sCombatAI = "ai_a_rogue"; + else if(nClass == CLASS_TYPE_SORCERER) sCombatAI = "ai_a_sorcerer"; + else if(nClass == CLASS_TYPE_WIZARD) sCombatAI = "ai_a_wizard"; + //else if(nClass == CLASS_TYPE_ABERRATION) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_ANIMAL) sCombatAI = "ai_a_animal"; + //else if(nClass == CLASS_TYPE_CONSTRUCT) sCombatAI = "ai_a_animal"; + //else if(nClass == CLASS_TYPE_DRAGON) sCombatAI = "ai_a_dragon"; + //else if(nClass == CLASS_TYPE_ELEMENTAL) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_FEY) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_GIANT) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_HUMANOID) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_MAGICAL_BEAST) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_MONSTROUS) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_OOZE) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_OUTSIDER) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_UNDEAD) sCombatAI = "ai_a_default"; + //else if(nClass == CLASS_TYPE_VERMIN) sCombatAI = "ai_a_animal"; + else sCombatAI = "ai_a_default"; + } + if(AI_DEBUG) ai_Debug("0i_associates", "530", GetName(oCreature) + " is setting AI to " + sCombatAI); + SetLocalString(oCreature, AI_COMBAT_SCRIPT, sCombatAI); + SetLocalString(oCreature, AI_DEFAULT_SCRIPT, sCombatAI); +} +int ai_CanISpeak (object oCreature) +{ + int nRace = GetRacialType (oCreature); + if (nRace == RACIAL_TYPE_ANIMAL || nRace == RACIAL_TYPE_BEAST || + nRace == RACIAL_TYPE_CONSTRUCT || nRace == RACIAL_TYPE_OOZE) return FALSE; + return (GetAbilityScore (oCreature, ABILITY_INTELLIGENCE) > 7); +} +void ai_FireHenchman(object oPC, object oHenchman) +{ + if(oPC == OBJECT_INVALID || oHenchman == OBJECT_INVALID) return; + // Now double-check that this is actually our master + if(GetMaster(oHenchman) != oPC) return; + // Turn off stealth mode + SetActionMode(oHenchman, ACTION_MODE_STEALTH, FALSE); + // Remove the henchman + RemoveHenchman (oPC, oHenchman); + ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER); +} +void ai_HenchmanCastDefensiveSpells (object oCreature, object oPC) +{ + ai_CastBuffs(oCreature, 3, 0, oPC); +} +int ai_CheckForCombat(object oCreature, int bMonster) +{ + object oEnemy = ai_GetNearestEnemy(oCreature, 1, 7, 7, 7, 5, TRUE); + //object oEnemy = ai_GetNearestEnemy(oCreature, 1, -1, -1, -1, -1, TRUE); + if(AI_DEBUG) ai_Debug("0i_associate", "586", "Checking for Combat: oEnemy is " + GetName(oEnemy) + + " Distance: " + FloatToString(GetDistanceBetween(oEnemy, oCreature), 0, 2)); + if(oEnemy != OBJECT_INVALID) + { + float fPerceptionDistance, fDistance; + if(bMonster) + { + fDistance = GetDistanceBetween(oCreature, oEnemy); + fPerceptionDistance = GetLocalFloat(GetModule(), AI_RULE_PERCEPTION_DISTANCE); + } + else + { + // We want to use the distance between the PC and target not us. + object oMaster = GetMaster(); + if(oMaster != OBJECT_INVALID) fDistance = GetDistanceBetween(oMaster, oEnemy); + else fDistance = GetDistanceBetween(oCreature, oEnemy); + fPerceptionDistance = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fPerceptionDistance == 0.0) fPerceptionDistance = 20.0; + } + if(fDistance < fPerceptionDistance) + { + ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:"); + SetLocalObject (oCreature, AI_MY_TARGET, oEnemy); + SpeakString(AI_I_SEE_AN_ENEMY, TALKVOLUME_SILENT_TALK); + if(bMonster) ai_StartMonsterCombat(oCreature); + else if(ai_CanIAttack(oCreature)) ai_StartAssociateCombat(oCreature); + return TRUE; + } + } + return FALSE; +} +void ai_AssociateEvaluateNewThreat(object oCreature, object oLastPerceived, string sPerception) +{ + if(!ai_CanIAttack(oCreature)) return; + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("0i_associates", "775", "Our current action: " + IntToString(nAction)); + switch(nAction) + { + // These actions are uninteruptable. + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_COUNTERSPELL : return; + // Might be doing a special action that is not a defined action. + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("0i_associate", "761", "Doing a special action (nCombatWait): " + IntToString(nCombatWait)); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + } + // We need to reevaluate combat during these actions when we see a new enemy. + //case ACTION_ATTACKOBJECT : + //case ACTION_MOVETOPOINT : + } + if(ai_GetIsInCombat(oCreature)) + { + object oTarget = ai_GetAttackedTarget(oCreature); + if(AI_DEBUG) ai_Debug("0i_associates", "775", "Should we recalculate our combat round? oTarget: " + GetName(oTarget) + + " oTarget Distance: " + FloatToString(GetDistanceBetween(oCreature, oTarget), 0, 2) + + " oLastPerceived Distance: " + FloatToString(GetDistanceBetween(oCreature, oLastPerceived), 0, 2)); + // If the LastPerceived is our target then don't recalculate. + if(oTarget == oLastPerceived) return; + // If we don't have a target or the lastperceived is closer than our + // target then recalculate. + if(oTarget == OBJECT_INVALID || + GetDistanceBetween(oCreature, oTarget) > GetDistanceBetween(oCreature, oLastPerceived)) + { + // We should clear any skill cooldowns that are at at max since that means they were skipped. + if(GetLocalInt(oCreature, "AI_EMPATHY_COOLDOWN") == AI_EMPATHY_COOLDOWN) + { DeleteLocalInt(oCreature, "AI_EMPATHY_COOLDOWN"); } + else if (GetLocalInt(oCreature, "AI_TAUNT_COOLDOWN") == AI_TAUNT_COOLDOWN) + { DeleteLocalInt(oCreature, "AI_EMPATHY_COOLDOWN"); } + ai_DoAssociateCombatRound(oCreature); + return; + } + // Lets only reevaluate combat if the new enemy is more powerful + // than the average enemies we already know about. + int nPower = ai_GetCharacterLevels(oLastPerceived) / 2; + int nEnemyPower = GetLocalInt(oCreature, AI_ENEMY_POWER) / (GetLocalInt(oCreature, AI_ENEMY_NUMBERS) + 1); + if(AI_DEBUG) ai_Debug("0i_associates", "797", " Is the new opponent more powerful? " + + GetName(oLastPerceived) + " nPower: " + IntToString(nPower) + + " nEnemyPower: " + IntToString(nEnemyPower)); + if(nEnemyPower < nPower) ai_DoAssociateCombatRound(oCreature); + return; + } + // Heard fires first, but Heard and Seen are both set at the same time. + // So lets skip the hearing code if they are also seen. + if(sPerception == AI_I_SEE_AN_ENEMY || GetObjectSeen(oLastPerceived, oCreature)) + { + // We are not in combat and we see the enemy so alert our allies! + ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:"); + SetLocalObject (oCreature, AI_MY_TARGET, oLastPerceived); + SpeakString(sPerception, TALKVOLUME_SILENT_TALK); + ai_StartAssociateCombat(oCreature); + } + else ai_FindTheEnemy(oCreature, oLastPerceived, oLastPerceived, FALSE); +} +void ai_MonsterEvaluateNewThreat(object oCreature, object oLastPerceived, string sPerception) +{ + if(!ai_CanIAttack(oCreature)) return; + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("0i_associates", "672", "nAction: " + IntToString(nAction)); + switch(nAction) + { + // These actions are uninteruptable. + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_COUNTERSPELL : return; + // Might be doing a special action that is not a defined action. + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("0i_associates", "683", "nCombatWait: " + IntToString(nCombatWait)); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + } + // We need to reevaluate combat during these actions when we see a new enemy. + //case ACTION_ATTACKOBJECT : + //case ACTION_MOVETOPOINT : + } + if(ai_GetIsInCombat(oCreature)) + { + object oTarget = ai_GetAttackedTarget(oCreature); + if(AI_DEBUG) ai_Debug("0i_associates", "697", "oTarget: " + GetName(oTarget) + + " oTarget Distance: " + FloatToString(GetDistanceBetween(oCreature, oTarget), 0, 2) + + " oLastPerceived Distance: " + FloatToString(GetDistanceBetween(oCreature, oLastPerceived), 0, 2)); + // If the LastPerceived is our target then don't recalculate. + if(oTarget == oLastPerceived) return; + // If we don't have a target or the lastperceived is closer than our + // target then recalculate. + if(oTarget == OBJECT_INVALID || + GetDistanceBetween(oCreature, oTarget) > GetDistanceBetween(oCreature, oLastPerceived)) + { + ai_DoMonsterCombatRound(oCreature); + return; + } + // Now only reevaluate combat if the new enemy is more powerful + // than the average enemies we already know about. + int nPower = ai_GetCharacterLevels(oLastPerceived) / 2; + int nEnemyPower = GetLocalInt(oCreature, AI_ENEMY_POWER) / (GetLocalInt(oCreature, AI_ENEMY_NUMBERS) + 1); + if(AI_DEBUG) ai_Debug("0i_associates", "714", GetName(oLastPerceived) + " nPower: " + IntToString(nPower) + + " nEnemyPower: " + IntToString(nEnemyPower)); + if(nEnemyPower < nPower) ai_DoMonsterCombatRound(oCreature); + return; + } + if(sPerception == AI_I_SEE_AN_ENEMY) + { + if(d100() < 34) + { + // We are not in combat so alert our allies! + ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:"); + } + SetLocalObject(oCreature, AI_MY_TARGET, oLastPerceived); + SpeakString(sPerception, TALKVOLUME_SILENT_TALK); + ai_StartMonsterCombat(oCreature); + } + else ai_FindTheEnemy(oCreature, oLastPerceived, oLastPerceived, TRUE); +} +void ai_CopyObjectVariables(object oOldObject, object oNewObject) +{ + json jObject = ObjectToJson(oOldObject, TRUE); + json jVarTable = GffGetList(jObject, "VarTable"); + string sVariable, sName; + int nIndex, nVarType; + json jVar = JsonArrayGet(jVarTable, nIndex); + while(JsonGetType(jVar) != JSON_TYPE_NULL) + { + sName = JsonGetString(GffGetString(jVar, "Name")); + nVarType = JsonGetInt(GffGetDword(jVar, "Type")); + if(nVarType == 1) SetLocalInt(oNewObject, sName, JsonGetInt(GffGetInt(jVar, "Value"))); + else if(nVarType == 2) SetLocalFloat(oNewObject, sName, JsonGetFloat(GffGetFloat(jVar, "Value"))); + else if(nVarType == 3) SetLocalString(oNewObject, sName, JsonGetString(GffGetString(jVar, "Value"))); + jVar = JsonArrayGet(jVarTable, ++nIndex); + } +} +//****************************************************************************** +//********************* Creature event scripts ********************************* +//****************************************************************************** + +void ai_OnRested(object oCreature) +{ + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_AFTER_REST)) + { + int nLevel = ai_GetCharacterLevels(oCreature); + float fDelay = StringToFloat(Get2DAString("restduration", "DURATION", nLevel)); + fDelay = (fDelay / 1000.0f) + 2.0f; + DelayCommand(fDelay, ai_HenchmanCastDefensiveSpells(oCreature, GetMaster())); + } +} + +//****************************************************************************** +//******************* Associate AI option scripts ****************************** +//****************************************************************************** +void ai_UpdateToolTipUI(object oPC, string sWindowID1, string sWindowID2, string sToolTipBind, string sText) +{ + int nMenuToken = NuiFindWindow(oPC, sWindowID1); + if(nMenuToken) NuiSetBind (oPC, nMenuToken, sToolTipBind, JsonString (sText)); + if(sWindowID2 != "") + { + int nWidgetToken = NuiFindWindow(oPC, sWindowID2); + if(nWidgetToken) NuiSetBind (oPC, nWidgetToken, sToolTipBind, JsonString (sText)); + } +} +void ai_FollowIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType) +{ + float fAdjustment = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE) + fIncrement; + if(fAdjustment > 10.0) fAdjustment = 10.0; + else if(fAdjustment < 1.0) fAdjustment = 1.0; + SetLocalFloat(oAssociate, AI_FOLLOW_RANGE, fAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 6, JsonFloat(fAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sName; + object oTarget = GetLocalObject(oAssociate, AI_FOLLOW_TARGET); + string sTarget; + if(oTarget != OBJECT_INVALID) sTarget = GetName(oTarget); + else + { + if(ai_GetIsCharacter(oAssociate)) sTarget = "nobody"; + else sTarget = GetName(oPC); + } + float fRange = fAdjustment + + StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oAssociate))); + string sRange = FloatToString(fRange, 0, 0); + if(oPC == oAssociate) + { + sName = " All associates"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_follow_tooltip", sName + " enter follow mode "); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_follow_target_tooltip", " " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]"); + } + else + { + sName = " " + GetName(oAssociate); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_follow_tooltip", sName + " enter follow mode [" + sRange + " meters]"); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_follow_target_tooltip", " " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]"); + } +} +void ai_Ranged(object oPC, object oAssociate, string sAssociateType) +{ + //ai_ClearCreatureActions(); + if(ai_GetAIMode(oAssociate, AI_MODE_STOP_RANGED)) + { + ai_SendMessages(GetName(oAssociate) + " is using ranged combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ranged_tooltip", " Ranged On"); + ai_SetAIMode(oAssociate, AI_MODE_STOP_RANGED, FALSE); + ai_EquipBestRangedWeapon(oAssociate); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is using melee combat only.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ranged_tooltip", " Ranged Off"); + ai_SetAIMode(oAssociate, AI_MODE_STOP_RANGED, TRUE); + ai_EquipBestMeleeWeapon(oAssociate); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_EquipWeapons(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_EQUIP_WEAPON_OFF)) + { + ai_SendMessages(GetName(oAssociate) + " will be equiping their best weapons.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_equip_weapon_tooltip", " Equiping Best Weapons On"); + ai_SetAIMode(oAssociate, AI_MODE_EQUIP_WEAPON_OFF, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will not equip their best weapons.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_equip_weapon_tooltip", " Equiping Best Weapons Off"); + ai_SetAIMode(oAssociate, AI_MODE_EQUIP_WEAPON_OFF, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Search(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH)) + { + ai_SendMessages(GetName(oAssociate) + " is turning search off.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_search_tooltip", " Search mode Off"); + SetActionMode(oAssociate, ACTION_MODE_DETECT, FALSE); + ai_SetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is turning search on.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_search_tooltip", " Search mode On"); + SetActionMode(oAssociate, ACTION_MODE_DETECT, TRUE); + ai_SetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Stealth(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH)) + { + ai_SendMessages(GetName(oAssociate) + " is turning stealth off.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_stealth_tooltip", " Stealth mode Off"); + SetActionMode(oAssociate, ACTION_MODE_STEALTH, FALSE); + ai_SetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is turning stealth on.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_stealth_tooltip", " Stealth mode On"); + SetActionMode(oAssociate, ACTION_MODE_STEALTH, TRUE); + ai_SetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_OpenDoor(object oPC, object oAssociate, string sAssociateType) +{ + string sRange = FloatToString(GetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE), 0, 0); + if(ai_GetAIMode(oAssociate, AI_MODE_OPEN_DOORS)) + { + ai_SendMessages(GetName(oAssociate) + " is turning open doors off.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_open_door_tooltip", " Open Doors Off [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_OPEN_DOORS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is turning open doors on.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_open_door_tooltip", " Open Doors On [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_OPEN_DOORS, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Locks(object oPC, object oAssociate, string sAssociateType, int nMode) +{ + string sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE), 0, 0); + if(nMode == 1) + { + if(ai_GetAIMode(oAssociate, AI_MODE_PICK_LOCKS)) + { + ai_SendMessages(GetName(oAssociate) + " will stop picking locks.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_pick_locks_tooltip", " Pick Locks Off [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_PICK_LOCKS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will now pick locks.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_pick_locks_tooltip", " Pick Locks On [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_PICK_LOCKS, TRUE); + } + } + else if(nMode == 2) + { + if(ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS)) + { + ai_SendMessages(GetName(oAssociate) + " will stop bashing.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_bash_locks_tooltip", " Bash Locks Off [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_BASH_LOCKS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will now bash things.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_bash_locks_tooltip", " Bash Locks On [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_BASH_LOCKS, TRUE); + } + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Traps(object oPC, object oAssociate, string sAssociateType) +{ + string sRange = FloatToString(GetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE), 0, 0); + if(ai_GetAIMode(oAssociate, AI_MODE_DISARM_TRAPS)) + { + ai_SendMessages(GetName(oAssociate) + " will stop disarming traps.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_traps_tooltip", " Disable Traps Off [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_DISARM_TRAPS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will now disarm traps.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_traps_tooltip", " Disable Traps On [" + sRange + " meters]"); + ai_SetAIMode(oAssociate, AI_MODE_DISARM_TRAPS, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_ReduceSpeech(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK)) + { + ai_SendMessages(GetName(oAssociate) + " will increase speech.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_quiet_tooltip", " Reduced Speech Off"); + ai_SetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will reduce speech.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_quiet_tooltip", " Reduced Speech On"); + ai_SetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_UseOffensiveMagic(object oPC, object oAssociate, int bDefensive, int bOffensive, string sAssociateType) +{ + if(bOffensive) + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING)) + { + ai_SendMessages(GetName(oAssociate) + " has stopped using offensive magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_off_magic_tooltip", " Offensive Magic Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is now using offensive magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_off_magic_tooltip", " Offensive Magic On"); + ai_SetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING, TRUE); + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_def_magic_tooltip", " Defensive Magic Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING, FALSE); + } + else if(bDefensive) + { + if(ai_GetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING)) + { + ai_SendMessages(GetName(oAssociate) + " has stopped using defensive magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_def_magic_tooltip", " Defensive Magic Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " is now using defensive magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_def_magic_tooltip", " Defensive Magic On"); + ai_SetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING, TRUE); + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_off_magic_tooltip", " Offensive Magic Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING, FALSE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_UseMagic(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC)) + { + ai_SendMessages(GetName(oAssociate) + " is now using magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_magic_tooltip", " Magic On"); + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " has stopped using magic in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_magic_tooltip", " Magic Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_UseMagicItems(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS)) + { + ai_SendMessages(GetName(oAssociate) + " is now using magic items in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_magic_items_tooltip", " Magic Items On"); + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " has stopped using magic items in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_magic_items_tooltip", " Magic Items Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Loot(object oPC, object oAssociate, string sAssociateType) +{ + int bLooting = !ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS); + string sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE), 0, 0); + string sMessage, sText; + if(bLooting) + { + sMessage = " is picking up items."; + sText = " Looting On [" + sRange + " meters]"; + } + else + { + sMessage = " is not picking up items."; + sText = " Looting Off [" + sRange + " meters]"; + } + ai_SendMessages(GetName(oAssociate) + sMessage, AI_COLOR_YELLOW, oPC); + ai_SetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS, bLooting); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_loot_tooltip", sText); + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Spontaneous(object oPC, object oAssociate, string sAssociateType) +{ + int bSpontaneous = !ai_GetMagicMode(oAssociate, AI_MAGIC_NO_SPONTANEOUS_CURE); + string sMessage, sText; + + if(bSpontaneous) + { + sMessage = " has stop casting spontaneous healing spells."; + sText = " Spontaneous casting Off"; + } + else + { + sMessage = " will now cast spontaneous healing spells."; + sText = " Spontaneous casting On"; + } + ai_SendMessages(GetName(oAssociate) + sMessage, AI_COLOR_YELLOW, oPC); + ai_SetMagicMode(oAssociate, AI_MAGIC_NO_SPONTANEOUS_CURE, bSpontaneous); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_spontaneous_tooltip", sText); + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_MagicIncrement(object oPC, object oAssociate, int nIncrement, string sAssociateType) +{ + int nAdjustment = GetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT) + nIncrement; + if(nAdjustment > 100) nAdjustment = 100; + else if(nAdjustment < -100) nAdjustment = -100; + SetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT, nAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 0, JsonInt(nAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sMagic = IntToString(nAdjustment); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_magic_level_tooltip", " Magic Level [" + sMagic + "]"); +} +void ai_LootRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType) +{ + float fAdjustment = GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE) + fIncrement; + if(fAdjustment > 40.0) fAdjustment = 40.0; + else if(fAdjustment < 0.0) fAdjustment = 0.0; + SetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE, fAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 3, JsonFloat(fAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sRange = FloatToString(fAdjustment, 0, 0); + string sLoot = " Looting Off [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sLoot = " Looting On [" + sRange + " meters]"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_loot_tooltip", sLoot); +} +void ai_LockRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType) +{ + float fAdjustment = GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE) + fIncrement; + if(fAdjustment > 40.0) fAdjustment = 40.0; + else if(fAdjustment < 0.0) fAdjustment = 0.0; + SetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE, fAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 4, JsonFloat(fAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sRange = FloatToString(fAdjustment, 0, 0); + string sPick = " Pick Locks Off [" + sRange + " meters]"; + string sBash = " Bash Off [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_PICK_LOCKS)) sPick = " Pick Locks On [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS)) sBash = " Bash On [" + sRange + " meters]"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_pick_locks_tooltip", sPick); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_bash_locks_tooltip", sBash); +} +void ai_TrapRangeIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType) +{ + float fAdjustment = GetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE) + fIncrement; + if(fAdjustment > 40.0) fAdjustment = 40.0; + else if(fAdjustment < 0.0) fAdjustment = 0.0; + SetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE, fAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 5, JsonFloat(fAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sRange = FloatToString(fAdjustment, 0, 0); + string sText = " Disable Traps Off [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_DISARM_TRAPS)) sText = " Disable Traps On [" + sRange + " meters]"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_traps_tooltip", sText); +} +void ai_OpenDoorIncrement(object oPC, object oAssociate, float fIncrement, string sAssociateType) +{ + float fAdjustment = GetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE) + fIncrement; + if(fAdjustment > 40.0) fAdjustment = 40.0; + else if(fAdjustment < 0.0) fAdjustment = 0.0; + SetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE, fAdjustment); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jAIData = JsonArraySet(jAIData, 9, JsonFloat(fAdjustment)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + string sRange = FloatToString(fAdjustment, 0, 0); + string sText = " Open Doors Off [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_OPEN_DOORS)) sText = " Open Doors On [" + sRange + " meters]"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_open_door_tooltip", sText); +} +void ai_SaveAIScript(object oPC, object oAssociate, int nToken) +{ + string sScript = JsonGetString(NuiGetBind(oPC, nToken, "txt_ai_script")); + string sOldScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + if(GetStringLeft(sScript, 5) != "ai_a_") ai_SendMessages(sScript + " does not have correct prefix it must have ai_a_ for associates! Did not change AI script.", AI_COLOR_RED, oPC); + else if(ResManGetAliasFor(sScript, RESTYPE_NCS) == "") + { + ai_SendMessages(sScript + " not found by ResMan! This is not a valid AI script.", AI_COLOR_RED, oPC); + } + else if(sScript != sOldScript) + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + if(JsonGetType(JsonArrayGet(jAIData, 8)) == JSON_TYPE_NULL) jAIData = JsonArrayInsert(jAIData, JsonString(sScript)); + else jAIData = JsonArraySet(jAIData, 8, JsonString(sScript)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + ai_SendMessages(GetName(oAssociate) + " is now using " + sScript + " AI script!", AI_COLOR_GREEN, oPC); + } + else ai_SendMessages(GetName(oAssociate) + " is already using this script! Did not change AI script.", AI_COLOR_RED, oPC); +} +void ai_Buff_Button(object oPC, object oAssociate, int nOption, string sAssociateType) +{ + if(nOption == 0) + { + int bRestBuff = !ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST); + ai_SetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST, bRestBuff); + if(bRestBuff) + { + ai_SendMessages(GetName(oAssociate) + " will cast long buffs after resting.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_buff_rest_tooltip", " [On] Turn buffing after resting off."); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will not cast long buffs after resting.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_buff_rest_tooltip", " [Off] Turn buffing after resting on."); + } + aiSaveAssociateModesToDb(oPC, oAssociate); + } + else + { + if(!GetIsPossessedFamiliar(oAssociate)) + { + object oEnemy = GetNearestEnemy(oAssociate); + //ai_Debug("0e_nui", "865", "oEnemy: " + GetName(oEnemy) + " fDistance: " + + // FloatToString(GetDistanceBetween(oAssociate, oEnemy), 0, 2)); + if(GetDistanceBetween(oAssociate, oEnemy) > 30.0 || + oEnemy == OBJECT_INVALID) + { + ai_CastBuffs(oAssociate, nOption, 0, oPC); + } + else ai_SendMessages("You cannot buff while there are enemies nearby.", AI_COLOR_RED, oPC); + } + else ai_SendMessages("You cannot buff while possessing your familiar.", AI_COLOR_RED, oPC); + } +} +void ai_Heal_Button(object oPC, object oAssociate, int nIncrement, string sVar, string sAssociateType) +{ + int nHeal = GetLocalInt(oAssociate, sVar); + if(nIncrement > 0 && nHeal > 100 - nIncrement) nHeal = 100 - nIncrement; + if(nIncrement < 0 && nHeal < abs(nIncrement)) nHeal = abs(nIncrement); + nHeal += nIncrement; + SetLocalInt(oAssociate, sVar, nHeal); + string sHeal = IntToString(nHeal); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + if(sVar == AI_HEAL_OUT_OF_COMBAT_LIMIT) + { + string sText = " Will heal at or below [" + sHeal + "%] health out of combat"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_heal_out_tooltip", sText); + jAIData = JsonArraySet(jAIData, 1, JsonInt(nHeal)); + } + else if(sVar == AI_HEAL_IN_COMBAT_LIMIT) + { + string sText = " Will heal at or below [" + sHeal + "%] health in combat"; + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_heal_in_tooltip", sText); + jAIData = JsonArraySet(jAIData, 2, JsonInt(nHeal)); + } + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); +} +void ai_Heal_OnOff(object oPC, object oAssociate, string sAssociateType, int nMode) +{ + string sText, sText2; + if(nMode == 1) + { + if(ai_GetAIMode(oAssociate, AI_MODE_SELF_HEALING_OFF)) + { + ai_SetAIMode(oAssociate, AI_MODE_SELF_HEALING_OFF, FALSE); + sText = " Self healing On"; + sText2 = " will now use healing on themselves."; + } + else + { + ai_SetAIMode(oAssociate, AI_MODE_SELF_HEALING_OFF, TRUE); + sText = " Self healing Off"; + sText2 = " will stop using healing on themselves."; + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_heals_onoff_tooltip", sText); + } + else + { + if(ai_GetAIMode(oAssociate, AI_MODE_PARTY_HEALING_OFF)) + { + ai_SetAIMode(oAssociate, AI_MODE_PARTY_HEALING_OFF, FALSE); + sText = " Party healing On"; + sText2 = " will now use healing on party members."; + } + else + { + ai_SetAIMode(oAssociate, AI_MODE_PARTY_HEALING_OFF, TRUE); + sText = " Party healing Off"; + sText2 = " will stop using healing on party members."; + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_healp_onoff_tooltip", sText); + } + ai_SendMessages(GetName(oAssociate) + sText2, AI_COLOR_YELLOW, oPC); + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Cure_OnOff(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF)) + { + ai_SendMessages(GetName(oAssociate) + " will now cast cure spells.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cure_onoff_tooltip", " Cast Cure Spells On"); + ai_SetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will stop casting cure spells.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cure_onoff_tooltip", " Cast Cure Spells Off"); + ai_SetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Ignore_Associates(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES)) + { + ai_SendMessages(GetName(oAssociate) + " will stop ignoring henchman's associates and enemy associates.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ignore_assoc_tooltip", " Ignore Enemy Associates Off"); + ai_SetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will now ignore henchman's associates and enemy associates.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ignore_assoc_tooltip", " Ignore Enemy Associates On"); + ai_SetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_Ignore_Traps(object oPC, object oAssociate, string sAssociateType) +{ + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_TRAPS)) + { + ai_SendMessages(GetName(oAssociate) + " will stop ignoring traps on the floor and will stop moving when one is seen.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ignore_traps_tooltip", " Ignore Floor Traps Off"); + ai_SetAIMode(oAssociate, AI_MODE_IGNORE_TRAPS, FALSE); + } + else + { + ai_SendMessages(GetName(oAssociate) + " will now ignore traps on the floor and will continue with their actions.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ignore_traps_tooltip", " Ignore Floor Traps On"); + ai_SetAIMode(oAssociate, AI_MODE_IGNORE_TRAPS, TRUE); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_FollowTarget(object oPC, object oAssociate) +{ + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate); + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_FOLLOW_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_Original_Guard() +{ + ResetHenchmenState(); + //Companions will only attack the Masters Last Attacker + SetAssociateState(NW_ASC_MODE_DEFEND_MASTER); + SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE); + object oMaster = GetMaster(); + object oLastAttacker = GetLastHostileActor(oMaster); + // * for some reason this is too often invalid. still the routine + // * works corrrectly + SetLocalInt(OBJECT_SELF, "X0_BATTLEJOINEDMASTER", TRUE); + HenchmenCombatRound(oLastAttacker); + ai_SendMessages(GetName(OBJECT_SELF) + " is now guarding you!", AI_COLOR_YELLOW, oMaster); +} +void ai_Original_Follow() +{ + ResetHenchmenState(); + SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE); + DelayCommand(2.5, VoiceCanDo()); + object oMaster = GetMaster(); + ActionForceFollowObject(oMaster, GetFollowDistance()); + SetAssociateState(NW_ASC_IS_BUSY); + DelayCommand(5.0, SetAssociateState(NW_ASC_IS_BUSY, FALSE)); + ai_SendMessages(GetName(OBJECT_SELF) + " is now following You!", AI_COLOR_YELLOW, oMaster); +} +void ai_Original_StandGround() +{ + SetAssociateState(NW_ASC_MODE_STAND_GROUND); + SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE); + DelayCommand(2.0, VoiceCanDo()); + ActionAttack(OBJECT_INVALID); + ClearActions(CLEAR_X0_INC_HENAI_RespondToShout1); + ai_SendMessages(GetName(OBJECT_SELF) + " is now standing their ground!", AI_COLOR_YELLOW, GetMaster()); +} +void ai_Original_AttackNearest() +{ + ResetHenchmenState(); + SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE); + SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE); + DetermineCombatRound(); + // * bonus feature. If master is attacking a door or container, issues VWE Attack Nearest + // * will make henchman join in on the fun + object oMaster = GetMaster(); + object oTarget = GetAttackTarget(oMaster); + if (GetIsObjectValid(oTarget) == TRUE) + { + if (GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE || GetObjectType(oTarget) == OBJECT_TYPE_DOOR) + { + ActionAttack(oTarget); + } + } + ai_SendMessages(GetName(OBJECT_SELF) + " is now in normal mode!", AI_COLOR_YELLOW, oMaster); +} +void ai_Original_SetSearch(object oAssociate, int bTurnOn) +{ + if(GetRacialType(oAssociate) != RACIAL_TYPE_ELF) SetActionMode(oAssociate, ACTION_MODE_DETECT, bTurnOn); +} +void ai_Original_SetStealth(object oAssociate, int bTurnOn) +{ + SetActionMode(oAssociate, ACTION_MODE_STEALTH, bTurnOn); +} +void ai_Philos_Guard(object oMaster, object oCreature) +{ + ai_PassAIModeToAssociates(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_DEFEND_MASTER, TRUE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_FOLLOW, FALSE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + int nToken = NuiFindWindow(oMaster, ai_GetAssociateType(oMaster, oCreature) + AI_WIDGET_NUI); + ai_HighlightWidgetMode(oMaster, oCreature, nToken); + if(!ai_GetIsBusy(oCreature) && ai_GetIsInCombat(oCreature)) + { + object oLastAttacker = GetLastHostileActor(oMaster); + if(oLastAttacker != OBJECT_INVALID) ai_DoAssociateCombatRound(oCreature, oLastAttacker); + else AssignCommand(oCreature, ActionMoveToObject(oMaster, TRUE)); + } + ai_SendMessages(GetName(oCreature) + " is now guarding you!", AI_COLOR_YELLOW, oMaster); + aiSaveAssociateModesToDb(oMaster, oCreature); +} +void ai_Philos_Follow(object oMaster) +{ + object oCreature = OBJECT_SELF; + ai_PassAIModeToAssociates(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_FOLLOW, TRUE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + int nToken = NuiFindWindow(oMaster, ai_GetAssociateType(oMaster, oCreature) + AI_WIDGET_NUI); + ai_HighlightWidgetMode(oMaster, oCreature, nToken); + aiSaveAssociateModesToDb(oMaster, oCreature); + // To follow we probably should be running and not searching or hiding. + if(GetDetectMode(oCreature) && !GetHasFeat(FEAT_KEEN_SENSE, oCreature)) SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + if(GetStealthMode(oCreature)) SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + ai_PassActionToAssociates(oCreature, ACTION_FOLLOW); + if(ai_IsInCombatRound(oCreature)) ai_ClearCombatState(oCreature); + ai_ClearCreatureActions(TRUE); + object oTarget = GetLocalObject(oCreature, AI_FOLLOW_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oMaster; + ActionMoveToObject(oTarget, TRUE, ai_GetFollowDistance(oCreature)); + ai_SendMessages(GetName(oCreature) + " is now following " + GetName(oTarget) + "!", AI_COLOR_YELLOW, oMaster); +} +void ai_Philos_StandGround(object oMaster) +{ + object oCreature = OBJECT_SELF; + ai_PassAIModeToAssociates(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_STAND_GROUND, TRUE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_DEFEND_MASTER, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_FOLLOW, FALSE); + ai_PassActionToAssociates(oCreature, ACTION_FOLLOW, FALSE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + int nToken = NuiFindWindow(oMaster, ai_GetAssociateType(oMaster, oCreature) + AI_WIDGET_NUI); + ai_HighlightWidgetMode(oMaster, oCreature, nToken); + if(ai_IsInCombatRound(oCreature)) + { + ai_ClearCombatState(oCreature); + DeleteLocalObject(oCreature, AI_ATTACKED_PHYSICAL); + DeleteLocalObject(oCreature, AI_ATTACKED_SPELL); + } + ai_ClearCreatureActions(TRUE); + ai_SendMessages(GetName(oCreature) + " is now standing their ground!", AI_COLOR_YELLOW, oMaster); + aiSaveAssociateModesToDb(oMaster, oCreature); +} +void ai_Philos_AttackNearest(object oMaster, object oCreature) +{ + ai_PassAIModeToAssociates(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_DEFEND_MASTER, FALSE); + ai_PassAIModeToAssociates(oCreature, AI_MODE_FOLLOW, FALSE); + ai_PassActionToAssociates(oCreature, ACTION_FOLLOW, FALSE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + int nToken = NuiFindWindow(oMaster, ai_GetAssociateType(oMaster, oCreature) + AI_WIDGET_NUI); + ai_HighlightWidgetMode(oMaster, oCreature, nToken); + // Removes any targets the PC may have given the associate. + DeleteLocalObject(oCreature, AI_PC_LOCKED_TARGET); + // This resets a henchmens failed Moral save in combat. + string sScript = GetLocalString(oCreature, AI_COMBAT_SCRIPT); + if(sScript == "ai_coward") + { + sScript = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + SetLocalString(oCreature, AI_COMBAT_SCRIPT, sScript); + } + if(!ai_GetIsBusy(oCreature)) + { + object oEnemy = ai_GetNearestEnemy(oCreature, 1, 7, 7); + if(oEnemy != OBJECT_INVALID && GetDistanceBetween(oCreature, oEnemy) < AI_RANGE_BATTLEFIELD) + { + ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:"); + // If master is attacking a target we will attack them too! + if(!ai_GetIsInCombat(oCreature)) ai_StartAssociateCombat(oCreature); + object oTarget = ai_GetAttackedTarget(oMaster); + if(oTarget == OBJECT_INVALID) ai_DoAssociateCombatRound(oCreature); + else ai_DoAssociateCombatRound(oCreature, oTarget); + } + else + { + object oTarget = GetLocalObject(oCreature, AI_FOLLOW_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oMaster; + AssignCommand(oCreature, ActionMoveToObject(oMaster, TRUE, ai_GetFollowDistance(oCreature))); + } + } + ai_SendMessages(GetName(oCreature) + " is now in normal mode!", AI_COLOR_YELLOW, oMaster); + aiSaveAssociateModesToDb(oMaster, oCreature); +} +void ai_Philos_SetSearch(object oMaster, object oCreature, string sAssociateType, int bTurnOn) +{ + if(bTurnOn) + { + ai_SetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH, TRUE); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + ai_PassActionToAssociates(oCreature, ACTION_MODE_DETECT, TRUE); + //ai_PassActionToAssociates(oCreature, ACTION_MODE_DETECT, TRUE); + ai_UpdateToolTipUI(oMaster, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_search_tooltip", " Search mode On"); + } + else + { + ai_SetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH, FALSE); + SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + ai_PassActionToAssociates(oCreature, ACTION_MODE_DETECT, FALSE); + //ai_PassActionToAssociates(oCreature, ACTION_MODE_DETECT, FALSE); + ai_UpdateToolTipUI(oMaster, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_search_tooltip", " Search mode Off"); + } + aiSaveAssociateModesToDb(oMaster, oCreature); +} +void ai_Philos_SetStealth(object oMaster, object oCreature, string sAssociateType, int bTurnOn) +{ + if(bTurnOn) + { + ai_SetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + ai_PassActionToAssociates(oCreature, ACTION_MODE_STEALTH, TRUE); + ai_UpdateToolTipUI(oMaster, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_stealth_tooltip", " Stealth mode On"); + } + else + { + ai_SetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH, FALSE); + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + ai_PassActionToAssociates(oCreature, ACTION_MODE_STEALTH, FALSE); + //ai_PassActionToAssociates(oCreature, ACTION_MODE_STEALTH, FALSE); + ai_UpdateToolTipUI(oMaster, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_stealth_tooltip", " Stealth mode Off"); + } + aiSaveAssociateModesToDb(oMaster, oCreature); +} +void ai_DoCommand(object oPC, object oAssociate, int nCommand) +{ + int nIndex = 1; + if(oPC == oAssociate) + { + if(nCommand == 1) // Guard PC. + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_Guard()); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_Guard()); + } + } + // Use Philos AI commands. + else + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) ai_Philos_Guard(oPC, oAssociate); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) ai_Philos_Guard(oPC, oAssociate); + } + } + } + else if(nCommand == 2) // Follow PC. + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_Follow()); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_Follow()); + } + } + // Use Philos AI commands. + else + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Philos_Follow(oPC)); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Philos_Follow(oPC)); + } + } + } + else if(nCommand == 3) // Standground. + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_StandGround()); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_StandGround()); + } + } + // Use Philos AI commands. + else + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Philos_StandGround(oPC)); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Philos_StandGround(oPC)); + } + } + } + else if(nCommand == 4) // Normal mode - i.e. Attack nearest. + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_AttackNearest()); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_Original_AttackNearest()); + } + } + // Use Philos AI commands. + else + { + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) ai_Philos_AttackNearest(oPC, oAssociate); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) ai_Philos_AttackNearest(oPC, oAssociate); + } + } + } + if(nCommand == 5) // All associates toggle search mode + { + int bTurnOn = !ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_SEARCH); + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + ai_Original_SetSearch(oPC, bTurnOn); + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) ai_Original_SetSearch(oAssociate, bTurnOn); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) ai_Original_SetSearch(oAssociate, bTurnOn); + } + } + else + { + ai_Philos_SetSearch(oPC, oPC, "pc", bTurnOn); + string sAssociateType; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) + { + sAssociateType = ai_GetAssociateType(oPC, oAssociate); + ai_Philos_SetSearch(oPC, oAssociate, sAssociateType, bTurnOn); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) + { + sAssociateType = ai_GetAssociateType(oPC, oAssociate); + ai_Philos_SetSearch(oPC, oAssociate, sAssociateType, bTurnOn); + } + } + } + if(bTurnOn) + { + ai_SendMessages("Everyone is now in search mode!", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, "pc" + AI_COMMAND_NUI, "pc" + AI_WIDGET_NUI, "btn_cmd_search_tooltip", " Everyone leave search mode"); + } + else + { + ai_SendMessages("Everyone has left search mode!", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, "pc" + AI_COMMAND_NUI, "pc" + AI_WIDGET_NUI, "btn_cmd_search_tooltip", " Everyone enter search mode"); + } + } + if(nCommand == 6) // All associate use stealth mode + { + int bTurnOn = !ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_STEALTH); + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + ai_Original_SetStealth(oPC, bTurnOn); + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) ai_Original_SetStealth(oAssociate, bTurnOn); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) ai_Original_SetStealth(oAssociate, bTurnOn); + } + } + else + { + ai_Philos_SetStealth(oPC, oPC, "pc", bTurnOn); + string sAssociateType; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) + { + sAssociateType = ai_GetAssociateType(oPC, oAssociate); + ai_Philos_SetStealth(oPC, oAssociate, sAssociateType, bTurnOn); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) + { + sAssociateType = ai_GetAssociateType(oPC, oAssociate); + ai_Philos_SetStealth(oPC, oAssociate, sAssociateType, bTurnOn); + } + } + } + if(bTurnOn) + { + ai_SendMessages("Everyone is now in stealth mode.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, "pc" + AI_COMMAND_NUI, "pc" + AI_WIDGET_NUI, "btn_cmd_stealth_tooltip", " Everyone leave stealth mode"); + } + else + { + ai_SendMessages("Everyone has left stealth mode.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, "pc" + AI_COMMAND_NUI, "pc" + AI_WIDGET_NUI, "btn_cmd_stealth_tooltip", " Everyone enter stealth mode"); + } + } + } + else + { + if(nCommand == 1) + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + AssignCommand(oAssociate, ai_Original_Guard()); + } + else ai_Philos_Guard(oPC, oAssociate); + } + else if(nCommand == 2) + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + AssignCommand(oAssociate, ai_Original_Follow()); + } + else AssignCommand(oAssociate, ai_Philos_Follow(oPC)); + } + else if(nCommand == 3) + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + AssignCommand(oAssociate, ai_Original_StandGround()); + } + else AssignCommand(oAssociate, ai_Philos_StandGround(oPC)); + } + else if(nCommand == 4) + { + // Not using Philos Henchman AI. Use vanilla commands. + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "") + { + AssignCommand(oAssociate, ai_Original_AttackNearest()); + } + else ai_Philos_AttackNearest(oPC, oAssociate); + } + } +} +void ai_Action(object oPC, object oAssociate) +{ + if(oPC == oAssociate) + { + DeleteLocalObject(oPC, "NW_ASSOCIATE_COMMAND"); + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION_ALL"); + ai_SendMessages("Select an action for the party.", AI_COLOR_YELLOW, oPC); + } + else + { + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate); + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION"); + ai_SendMessages("Select an action for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC); + } + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_AIScript(object oPC, object oAssociate, string sAssociateType, int nToken) +{ + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != "") + { + string sScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + string sIcon = "ir_scommand"; + if(sScript == "ai_a_ambusher") + { + sScript = "ai_a_flanker"; + sIcon = "ir_invite"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using flanking tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Flanker: Attacks enemies engaged with allies"); + } + else if(sScript == "ai_a_flanker") + { + sScript = "ai_a_peaceful"; + sIcon = "ir_ignore"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using peaceful tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Peaceful: Avoids attacking any enemies if possible"); + } + else if(sScript == "ai_a_peaceful") + { + sScript = "ai_a_defensive"; + sIcon = "ir_knockdwn"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using defensive tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Defensive: Attacks then uses Expertise/Parry"); + } + else if(sScript == "ai_a_defensive") + { + sScript = "ai_a_ranged"; + sIcon = "ir_ranger"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using ranged tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Ranged: Attacks from range as much as possible"); + } + else if(sScript == "ai_a_ranged") + { + sScript = "ai_a_cntrspell"; + sIcon = "ir_dcaster"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using counter spell tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Counter Spell: Tries to counter enemy spells"); + } + else if(sScript == "ai_a_cntrspell") + { + DeleteLocalString(oAssociate, AI_DEFAULT_SCRIPT); + ai_SetAssociateAIScript(oAssociate, FALSE); + sScript = GetLocalString(oAssociate, AI_DEFAULT_SCRIPT); + ai_SendMessages(GetName(oAssociate) + " is now using default tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Default tactics: Using the creatures base AI script"); + } + else + { + sScript = "ai_a_ambusher"; + sIcon = "ir_rogue"; + SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, sScript); + ai_SendMessages(GetName(oAssociate) + " is now using ambush tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Ambusher: Attacks from a hidden position"); + } + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_image", JsonString(sIcon)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_label", JsonString("Tactics: " + sScript)); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + if(JsonGetType(JsonArrayGet(jAIData, 8)) == JSON_TYPE_NULL) jAIData = JsonArrayInsert(jAIData, JsonString(sScript)); + else jAIData = JsonArraySet(jAIData, 8, JsonString(sScript)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + else + { + if(GetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, oAssociate)) + { + SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_COWARDLY, TRUE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_RANGED, FALSE, oAssociate); + ai_SendMessages(GetName(oAssociate) + " is now using coward tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Using coward tactics"); + } + else if(GetCombatCondition(X0_COMBAT_FLAG_COWARDLY, oAssociate)) + { + SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_COWARDLY, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, TRUE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_RANGED, FALSE, oAssociate); + ai_SendMessages(GetName(oAssociate) + " is now using defensive tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Using defensive tactics"); + } + else if(GetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, oAssociate)) + { + SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_COWARDLY, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_RANGED, TRUE, oAssociate); + ai_SendMessages(GetName(oAssociate) + " is now using ranged tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Using ranged tactics"); + } + else if(GetCombatCondition(X0_COMBAT_FLAG_RANGED, oAssociate)) + { + SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_COWARDLY, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_RANGED, FALSE, oAssociate); + ai_SendMessages(GetName(oAssociate) + " is now using normal tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Using ambush tactics"); + } + else + { + SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, TRUE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_COWARDLY, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, FALSE, oAssociate); + SetCombatCondition(X0_COMBAT_FLAG_RANGED, FALSE, oAssociate); + ai_SendMessages(GetName(oAssociate) + " is now using ambush tactics in combat.", AI_COLOR_YELLOW, oPC); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_cmd_ai_script_tooltip", " Using ambush tactics"); + } + } +} +void ai_HavePCPlaceTrap(object oPC, object oAssociate) +{ + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate); + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_GET_TRAP"); + ai_SendMessages(GetName(oAssociate) + " select a trap to place.", AI_COLOR_YELLOW, oPC); + OpenInventory(oAssociate, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ITEM, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_JumpAssociateToPC(object oPC) +{ + ai_ClearCreatureActions(TRUE); + JumpToObject(oPC); +} +void ai_JumpToPC(object oPC, object oAssociate) +{ + int nAssociateType, nHenchman, nHenchAssociate; + object oHenchman, oHenchmanAssociate; + if(oPC != oAssociate) + { + if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) + { + for(nHenchAssociate = 2; nHenchAssociate <= 5; nHenchAssociate++) + { + oHenchmanAssociate = GetAssociate(nHenchAssociate, oHenchman, 1); + if(oHenchmanAssociate != OBJECT_INVALID) + { + AssignCommand(oHenchmanAssociate, ai_JumpAssociateToPC(oPC)); + } + } + AssignCommand(oHenchman, ai_JumpAssociateToPC(oPC)); + } + else AssignCommand(oAssociate, ai_JumpAssociateToPC(oPC)); + return; + } + for(nAssociateType = 1; nAssociateType <= 5; nAssociateType++) + { + if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) + { + for(nHenchman = 1; nHenchman <= AI_MAX_HENCHMAN; nHenchman++) + { + oHenchman = GetAssociate(nAssociateType, oPC, nHenchman); + if(oHenchman != OBJECT_INVALID) + { + for(nHenchAssociate = 2; nHenchAssociate <= 5; nHenchAssociate++) + { + oHenchmanAssociate = GetAssociate(nHenchAssociate, oHenchman, 1); + if(oHenchmanAssociate != OBJECT_INVALID) + { + AssignCommand(oHenchmanAssociate, ai_JumpAssociateToPC(oPC)); + } + } + AssignCommand(oHenchman, ai_JumpAssociateToPC(oPC)); + } + } + } + else + { + oHenchman = GetAssociate(nAssociateType, oPC, 1); + if(oHenchman != OBJECT_INVALID) AssignCommand(oHenchman, ai_JumpAssociateToPC(oPC)); + } + } +} +void ai_GhostMode(object oPC, object oAssociate, int nToken, string sAssociateType) +{ + string sText; + if(ai_GetAIMode(oAssociate, AI_MODE_GHOST)) + { + ai_SetAIMode(oAssociate, AI_MODE_GHOST, FALSE); + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + sText = " Turn On clipping through creatures for " + GetName(oAssociate); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ghost_mode_tooltip", sText); + ai_SendMessages(GetName(oAssociate) + " is not in Ghost Mode and will run into creatures.", AI_COLOR_YELLOW, oPC); + } + else + { + ai_SetAIMode(oAssociate, AI_MODE_GHOST, TRUE); + effect eGhost = EffectCutsceneGhost(); + eGhost = UnyieldingEffect(eGhost); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, oAssociate); + sText = " Turn Off clipping through creatures for " + GetName(oAssociate); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ghost_mode_tooltip", sText); + ai_SendMessages(GetName(oAssociate) + " is now in Ghost Mode and will clip through creatures.", AI_COLOR_YELLOW, oPC); + } +} +void ai_ChangeCameraView(object oPC, object oAssociate) +{ + object oCamAssociate = GetLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE"); + if(oCamAssociate == oAssociate) + { + DeleteLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE"); + AttachCamera(oPC, oPC); + } + else + { + SetLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE", oAssociate); + AttachCamera(oPC, oAssociate); + } +} +void ai_SelectCameraView(object oPC) +{ + SetLocalString(oPC, AI_TARGET_MODE, "DM_SELECT_CAMERA_VIEW"); + ai_SendMessages(GetName(oPC) + " select an object to change the camera view to.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_CREATE, MOUSECURSOR_NOCREATE); +} +void ai_OpenInventory(object oAssociate, object oPC) +{ + // Funny things happen when you open associate inventories when they are not + // within sight. + if(LineOfSightObject(oPC, oAssociate)) + { + OpenInventory(oAssociate, oPC); + } + else ai_SendMessages(GetName(oAssociate) + " is not within sight!", AI_COLOR_RED, oPC); +} +void ai_SelectOpenInventory(object oPC) +{ + SetLocalString(oPC, AI_TARGET_MODE, "DM_SELECT_OPEN_INVENTORY"); + ai_SendMessages(GetName(oPC) + " select an object to open its inventory.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); +} +void ai_Plugin_Execute(object oPC, string sElem, int bUser = 0) +{ + int nIndex = StringToInt(GetStringRight(sElem, 1)); + json jPlugins, jPlugin; + if(bUser == 1) // From DM command menu. + { + string sName = ai_RemoveIllegalCharacters(GetName(oPC)); + jPlugins = ai_GetCampaignDbJson("plugins", sName, AI_DM_TABLE); + } + else if(bUser == 2) // From DM plugin menu, master plugin list. + { + jPlugins = ai_GetCampaignDbJson("plugins"); + } + else jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + jPlugin = JsonArrayGet(jPlugins, nIndex); + string sScript = JsonGetString(JsonArrayGet(jPlugin, 0)); + if(ResManGetAliasFor(sScript, RESTYPE_NCS) == "") + { + ai_SendMessages(sScript + " not found by ResMan!", AI_COLOR_RED, oPC); + } + else + { + string sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + ai_SendMessages("Executing plugin " + sName + ".", AI_COLOR_GREEN, oPC); + ExecuteScript(sScript, oPC); + } +} diff --git a/src/module/nss/0i_color.nss b/src/module/nss/0i_color.nss new file mode 100644 index 0000000..b18fe7a --- /dev/null +++ b/src/module/nss/0i_color.nss @@ -0,0 +1,70 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_color +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts that are used to change the color of names and text. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Basic color codes. Message Notes +const string AI_COLOR_BLACK = "000"; // Nothing. +const string AI_COLOR_WHITE = "999"; // _Debug messages. +const string AI_COLOR_GRAY = "666"; // Server messages +const string AI_COLOR_YELLOW = "990"; // Generic messages to players. +const string AI_COLOR_DARK_YELLOW = "660"; // +const string AI_COLOR_RED = "900"; // Negative message to players. +const string AI_COLOR_DARK_RED = "600"; // +const string AI_COLOR_GREEN = "080"; // Positive message to players. +const string AI_COLOR_DARK_GREEN = "060"; // +const string AI_COLOR_BLUE = "009"; // +const string AI_COLOR_DARK_BLUE = "006"; // In game descriptive text. +const string AI_COLOR_CYAN = "099"; // +const string AI_COLOR_DARK_CYAN = "066"; // +const string AI_COLOR_MAGENTA = "909"; // +const string AI_COLOR_DARK_MAGENTA = "606";// +const string AI_COLOR_LIGHT_MAGENTA = "868"; // <âcâ> Combat text: Enemy name color. +const string AI_COLOR_ORANGE = "950"; // +const string AI_COLOR_DARK_ORANGE = "940"; // Combat text: base text color. +const string AI_COLOR_GOLD = "860"; // +// Strips the color codes from sText +string ai_StripColorCodes(string sText); +// This function will make sString be the specified color +// as specified in sRGB. RGB is the Red, Green, and Blue +// Each color can have a value from 0 to 9. +// 1 - 0(20)[ ] 142 - 5(8E)[?] +// 32 - 1(20)[ ] 170 - 6(AA)[ª] +// 57 - 2(39)[9] 198 - 7(C6)[Æ] +// 85 - 3(55)[U] 226 - 8(E2)[â] +// 113 - 4(71)[q] 255 - 9(FE)[ÿ] +string ai_AddColorToText(string sText, string sRGB = AI_COLOR_WHITE); + +string ai_StripColorCodes(string sText) +{ + string sColorCode, sChar; + int nStringLength = GetStringLength(sText); + int i = FindSubString(sText, "" + // End the color token + sText + ""; +} diff --git a/src/module/nss/0i_combat.nss b/src/module/nss/0i_combat.nss new file mode 100644 index 0000000..6c40eb1 --- /dev/null +++ b/src/module/nss/0i_combat.nss @@ -0,0 +1,3498 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_combat +//////////////////////////////////////////////////////////////////////////////// + Include scripts for combat scripts. +*/////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// +#include "0i_messages" +#include "0i_items" +#include "0i_spells" +// This structure is used to represent the number and type of +// enemies that a creature is facing, divided into four main +// categories: FIGHTERS, CLERICS, MAGES, MONSTERS. +struct stClasses +{ + int FIGHTERS; + int FIGHTER_LEVELS; + int CLERICS; + int CLERIC_LEVELS; + int MAGES; + int MAGE_LEVELS; + int MONSTERS; + int MONSTER_LEVELS; + int TOTAL; + int TOTAL_LEVELS; +}; +struct stTarget +{ + object oTarget; + int nValue; + int nBestValue; + int nBestSecondaryValue; + float fNearestRange; + float fNearestSecondaryRange; + int nIndex; + int nSecondaryIndex; + string sTargetType; +}; +//****************************************************************************** +//************ GET TARGETS USING THE OBJECT SEARCH FUNCTIONS ******************* +//****************************************************************************** +// Returns the nearest enemy that is not disabled from oCreature. +// You may pass in any of the CREATURE_TYPE_* constants +// used in GetNearestCreature as nCType1 & nCType2, with +// corresponding values for nCValue1 & nCValue2. +// NOTE: CREATURE_TYPE_PERCEPTION = 7, PERCEPTION_SEEN = 7. +// bDisabled = TRUE will also return any disabled targets that are not dead. +object ai_GetNearestEnemy(object oCreature, int nNth = 1, int nCType1 = -1, int nCValue1 = -1, int nCType2 = -1, int nCValue2 = -1, int bDisabled = FALSE); +// Returns the nearest ally from oCreature. +// You may pass in any of the CREATURE_TYPE_* constants +// used in GetNearestCreature as nCType1 & nCType2, with +// corresponding values for nCValue1 & nCValue2. +// NOTE: CREATURE_TYPE_PERCEPTION = 7, PERCEPTION_SEEN = 7. +object ai_GetNearestAlly(object oCreature, int nNth = 1, int nCType1 = -1, int nCValue1 = -1, int nCType2 = -1, int nCValue2 = -1); +// Returns the number of alive enemies grouped near oCreature within fDistance. +int ai_GetNumOfEnemiesInGroup(object oCreature, float fDistance = AI_RANGE_MELEE); +// Returns the number of alive allies grouped near oCreature within fDistance. +int ai_GetNumOfAlliesInGroup(object oCreature, float fDistance = AI_RANGE_MELEE); +// Returns the number of creatures of nRacial_Type within fDistance that can be seen by oCreature. +int ai_GetRacialTypeCount(object oCreature, int nRacial_Type, float fDistance = AI_RANGE_PERCEPTION); +// Returns the weakest attacker that is in melee or is attacking oCreature's master. +object ai_GetLowestCRAttackerOnMaster(object oCreature); + +//****************************************************************************** +//******************** SET/CLEAR COMBAT STATE FUNCTIONS ************************ +//****************************************************************************** +// Sets oCreatures's combat state by setting variables for AI_ALLIES and AI_ENEMIES. +// Returns the nearest visible enemy. +object ai_SetCombatState(object oCreature); +// Clears all variables that were define for the current round for oCreature. +void ai_ClearCombatState(object oCreature); + +//****************************************************************************** +//*************** GET TARGETS USING COMBAT STATE FUNCTIONS ********************* +//****************************************************************************** +// These functions will find a target or an index to a target based on the +// combat state variables created by the function ai_SetCombatState. + +// Returns the Index of the nearest creature seen within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetNearestIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest creature seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetNearestTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest creature seen with the lowest combat rating +// within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetLowestCRIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest creature seen with the lowest combat rating within fMaxRange +// in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetLowestCRTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest creature seen with the highest combat rating +// within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetHighestCRIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest creature seen with the highest combat rating within fMaxRange +// in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetHighestCRTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the creature seen with the lowest enemies to oCreature that +// they are in melee with minus the number of allies to the caller they are in +// melee with within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetLowestMeleeIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY); +// Returns the index of the creature seen with the most enemies to the caller that +// they are in melee with minus the number of allies to oCreature they are in +// melee with within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetHighestMeleeIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY); +// Returns a creature of sTargetType where they have the least number of +// allies and the most number of enemies within fMaxRange in the combat state. +// Returns OBJECT_INVALID if there is not a good creature to select. +// sTargetType is either AI_ENEMY, or AI_ALLY. +object ai_GetGroupedTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY); +// Returns the index of the nearest creature with the least % of hitpoints within +// fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetMostWoundedIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the creature with the lowest health seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetMostWoundedTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest ally with the least % of hitpoints within +// fMaxRange in the combat state. +// This also filters for AI_MODE_PARTY_HEALING_OFF and AI_MODE_SELF_HEALING_OFF. +// If no ally is found then it will return an index of 0. +int ai_GetAllyToHealIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the ally with the lowest health seen within fMaxRange in the combat state. +// This also filters for AI_MODE_PARTY_HEALING_OFF and AI_MODE_SELF_HEALING_OFF. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetAllyToHealTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the creature with the lowest fortitude save seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetLowestFortitudeSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the creature with the lowest reflex save seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetLowestReflexSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the creature with the lowest will save seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetLowestWillSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the creature with the lowest save based on nSpell save type seen +// within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +object ai_GetSpellTargetBasedOnSaves(object oCreature, int nSpell, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the index of the nearest creature seen that is busy attacking an ally +// within fMaxRange in the combat state. +// If none is found then it will return 0. +int ai_GetSneakAttackIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE); +// Returns the index of the nearest creature seen that is busy attacking an ally +// within fMaxRange in the combat state. +// If none is found then it will return 0. +int ai_GetNearestIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest combat creature seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetNearestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest creature seen with the lowest combat rating +// that is not in a dangerous area of effect within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetLowestCRIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the lowest combat creature seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetLowestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest creature seen with the highest combat rating +// that is not in a dangerous area of effect within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetHighestCRIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the highest combat creature seen within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +object ai_GetHighestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the creature seen with the most enemies to oCreature that +// they are in melee with minus the number of allies to oCreature they are in +// melee with that is not in a dangerous area of effect within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_GetHighestMeleeIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY); +// Returns a creature of sTargetType where they have the least number of +// allies and the most number of enemies within fMaxRange that are not in a +// dangerous area of effect in the combat state. +// Returns OBJECT_INVALID if there is not a good creature to select. +// sTargetType is either AI_ENEMY, or AI_ALLY. +object ai_GetGroupedTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY); +// Returns the nearest creature seen of nClassType within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetNearestClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the creature with the lowest combat rating seen of nClassType within +// fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetLowestCRClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the creature with the highest combat rating seen of nClassType within +// fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetHighestCRClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest creature seen of nRacialType within fMaxRange in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetNearestRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the creature with the lowest combat rating seen of nRacialType within +// fMaxRange in the combat state. Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetLowestCRRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the creature with the highest combat rating seen of nRacialType within +// fMaxRange in the combat state. Returns OBJECT_INVALID if no creature is found. +// sTargetType is either AI_ENEMY or AI_ALLY. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetHighestCRRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the nearest enemy seen that is attacking an ally with the least +// number of enemies on them within fMaxRange in the combat state. +// If none is found then it will return 0. +object ai_GetFlankTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE); +// Returns the nearest enemy creature seen wihtin fMaxRange that is a favored enemy +// of the caller in the combat state. +// Returns OBJECT_INVALID if no creature is found. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetNearestFavoredEnemyTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE); +// Returns the best target for melee combat based if we are in melee or not. +// If not in melee it will get the nearest target that is not in a dangerous +// area of effect for us to attack in the combat state. +// If in melee it will get the weakest target. +// If it returns OBJECT_INVALID then we should stop the attack. The only way +// to not get a target is if we have been told not to attack strong opponents. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetBestCRTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Returns the nearest target for melee combat based if we are in melee or not. +// If not in melee it will get the nearest target that is not in a dangerous +// area of effect for us to attack in the combat state. +// If it returns OBJECT_INVALID then we should stop the attack. The only way +// to not get a target is if we have been told not to attack strong opponents. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetNearestTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Returns the target with the lowest combat rating for melee combat based if +// we are in melee or not. If not in melee it will get the nearest target that +// is not in a dangerous area of effect for us to attack in the combat state. +// If it returns OBJECT_INVALID then we should stop the attack. The only way +// to not get a target is if we have been told not to attack strong opponents. +// bAlwaysAtk TRUE we attack everything! FALSE we don't attack strong enemies. +object ai_GetLowestCRTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Returns the target with the highest combat rating for melee combat based if +// we are in melee or not. If not in melee it will get the nearest target that +// is not in a dangerous area of effect for us to attack in the combat state. +// If it returns OBJECT_INVALID then we should stop the attack. +object ai_GetHighestCRTargetForMeleeCombat(object oCreature, int nInMelee); +// Returns the Index of the nearest creature seen within fMaxRange in the combat state. +// If no creature is found then it will return an index of 0. +// sTargetType is either AI_ENEMY or AI_ALLY. +int ai_MonsterGetNearestIndex(object oMonster, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE); +// Returns the index of the nearest enemy creature that can see oCreature. +int ai_GetNearestIndexThatSeesUs(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION); +// Returns the nearest creature attacking the caller within fMaxRange in the combat state. +// Returns OBJECT_INVALID if oCreature is not being attacked. +object ai_GetEnemyAttackingMe(object oCreature, float fMaxRange = AI_RANGE_MELEE); +// Returns the nearest creature attacking oAlly from oCreature within fMaxRange +// in the combat state. +// Returns OBJECT_INVALID if oAlly is not being attacked. +object ai_GetEnemyAttackingMyAlly(object oCreature, object oAlly, float fMaxRange = AI_RANGE_MELEE); +// Returns the number of enemies within fMaxRange of the caller in the combat state. +int ai_GetNumOfEnemiesInRange(object oCreature, float fMaxRange = AI_RANGE_MELEE); +// Returns the best ally target withing fMaxRange for nSpell to be cast on. +// Uses the ai_spells.2da file to pick a target. +object ai_GetAllyBuffTarget(object oCreature, int nSpell, float fMaxRange = AI_RANGE_BATTLEFIELD); + +//****************************************************************************** +//******************** OTHER COMBAT FUNCTIONS ******************************** +//****************************************************************************** + +// Returns the current round that oCreature is in for this combat. +int ai_GetCurrentRound(object oCreature); +// Returns the difficulty of the battle based on the combat state. +// nDifficulty is Enemy level - Ally level + 20 + Player adjustment. +// 20+ : Impossible - Cannot win. +// 17 to 19 : Overpowering - Use all of our powers. +// 15 to 16 : Very Difficult - Use all of our power (Highest level spells). +// 11 to 14 : Challenging - Use most of our power (Higher level powers). +// 8 to 10 : Moderate - Use half of our power (Mid level powers and less). +// 5 to 7 : Easy - Use our weaker powers (Lowest level powers). +// 2 to 4 : Effortless - Don't waste spells and powers on this. +// 1 or less: Pointless - We probably should ignore these dangers. +int ai_GetDifficulty(object oCreature); +// Returns oCreatures Combat rating. +//(BAB + AC - 10) / 2 +int ai_GetMyCombatRating(object oCreature); +// Returns the last creature oCreature attacked. +// bPhysical checks for creatures attacked in melee or range with a weapon. +// bSpell will look for creatures attacked by a spell. +object ai_GetAttackedTarget(object oCreature, int bPhysical = TRUE, int bSpell = FALSE); +// Returns TRUE if oCreature is of nClassType; +// May also check for general Class types with +// AI_CLASS_TYPE_ARCANE, AI_CLASS_TYPE_DIVINE, AI_CLASS_TYPE_CASTER, AI_CLASS_TYPE_WARRIOR. +int ai_CheckClassType(object oCreature, int nClassType); +// Returns TRUE if oCreature is of nRacialType; +// May also check for general racial types with +// AI_RACIAL_TYPE_ANIMAL_BEAST +int ai_CheckRacialType(object oCreature, int nRacialType); +// Saves oCreatures Normal appearance if they are not polymorphed and it has +// not already been saved. +void ai_SetNormalAppearance(object oCreature); +// Returns the normal appearance of oCreature. +int ai_GetNormalAppearance(object oCreature); +// Return the number and levels of all creatures within fMaxRange. +// They are grouped into Fighters, Clerics, Mages, and Monsters. +struct stClasses ai_GetFactionsClasses(object oCreature, int bEnemy = TRUE, float fMaxRange = AI_RANGE_BATTLEFIELD); +// This will return the class with the most levels. +// Returns a string of "FIGHTER", "CLERIC", "MAGE", or "MONSTER". +// Execute with GetFactionsClasses. +string ai_GetMostDangerousClass(struct stClasses stCount); +// Equips the best weapon, ranged or melee. +// Returns TRUE if equiped, FALSE if not. +// oTarget is the creature the caller is targeting. +void ai_EquipBestWeapons(object oCreature, object oTarget = OBJECT_INVALID); +// Equips a melee weapon AND checks for shield, two weapons, two handed, etc. +// Returns TRUE if equiped, FALSE if not. +// oTarget is the creature the caller is targeting. +int ai_EquipBestMeleeWeapon(object oCreature, object oTarget = OBJECT_INVALID); +// Equips a ranged weapon AND checks for ammo. +// Returns TRUE if equiped, FALSE if not. +// oTarget is the creature the caller is targeting. +int ai_EquipBestRangedWeapon(object oCreature, object oTarget = OBJECT_INVALID); +// Equips the best weapon for a monk character. +// Returns TRUE if equiped, FALSE if not. +// oTarget is the creature the caller is targeting. +int ai_EquipBestMonkMeleeWeapon(object oCreature, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature is in a Dangerous Area of Effect in fMaxRange. +// bMove will attempt to move oCreature out of the Dangerous AOE if needed. +int ai_IsInADangerousAOE(object oCreature, float fMaxRange = AI_RANGE_BATTLEFIELD, int bMove = FALSE); +// Returns 1 if oHidden has an Invisiblity effect, Can't be spotted but can be heard. +// Returns 2 if oHidden has a Darkness effect. Can't be spotted but can be heard. +// Returns 3 if oHidden has a Sanctuary effect, Can't be spotted or heard. +// Returns 4 if oHidden is in stealth mode, Can be spotted and heard. +int ai_GetIsHidden(object oHidden); +// Returns TRUE if if oCaster has a good chance of effecting oCreature with nSpell. +int ai_CastOffensiveSpellVsTarget(object oCaster, object oCreature, int nSpell); +// Gets the base DC for a dragon. +int ai_GetDragonDC(object oCreature); +// Set oCreature's ai scripts based on its first class or the variable "AI_DEFAULT_SCRIPT". +void ai_SetCreatureAIScript(object oCreature); +// Returns TRUE if oTarget is immune to sneak attacks. +int ai_IsImmuneToSneakAttacks(object oCreature, object oTarget); +// Returns TRUE if iIndex target has a higher combat rating than oCreature. +int ai_IsStrongerThanMe(object oCreature, int nIndex); +// Returns TRUE if oTarget's CR is within nAdj of oCreature's level, otherwise FALSE. +int ai_StrongOpponent(object oCreature, object oTarget, int nAdj = 2); +// Returns TRUE if attacking oTarget with Power attack is a good option. +int ai_PowerAttackGood(object oCreature, object oTarget, float fAdj); +// Returns TRUE if oTarget's AC - oCreature Atk - nAtkAdj can hit within 25% to 75%. +int ai_AttackPenaltyOk(object oCreature, object oTarget, float fAtkAdj); +// Returns TRUE if oCreature AC - oTarget's Atk is less than 20. +int ai_ACAdjustmentGood(object oCreature, object oTarget, float fACAdj); +// Checks oCreatures melee weapon to see if they can kill oTarget in one hit. +int ai_WillKillInOneHit(object oCreature, object oTarget); +// Returns TRUE if oCreature has Mobility, SpringAttack, or a high Tumble. +int ai_CanIMoveInCombat(object oCreature); +// Returns TRUE if oCreature can safely fire a ranged weapon. +int ai_CanIUseRangedWeapon(object oCreature, int nInMelee); +// Returns TRUE if oCreature moves before the action. FALSE if they do not move. +// and -1 if the action is canceled. +// Checks current combat state to see if oCreature needs to move before using an action. +int ai_CheckCombatPosition(object oCreature, object oTarget, int nInMelee, int nAction, int nBaseItemType = 0); + +//****************************************************************************** +//************ GET TARGETS USING THE OBJECT SEARCH FUNCTIONS ******************* +//****************************************************************************** +object ai_GetNearestEnemy(object oCreature, int nNth = 1, int nCType1 = -1, int nCValue1 = -1, int nCType2 = -1, int nCValue2 = -1, int bDisabled = FALSE) +{ + object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, + oCreature, nNth, nCType1, nCValue1, nCType2, nCValue2); + if(bDisabled) + { + while(oTarget != OBJECT_INVALID && GetIsDead(oTarget)) + { + oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, + oCreature, ++nNth, nCType1, nCValue1, nCType2, nCValue2); + } + } + else + { + while(oTarget != OBJECT_INVALID && ai_Disabled(oTarget)) + { + oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, + oCreature, ++nNth, nCType1, nCValue1, nCType2, nCValue2); + } + } + return oTarget; +} +object ai_GetNearestAlly(object oCreature, int nNth = 1, int nCType1 = -1, int nCValue1 = -1, int nCType2 = -1, int nCValue2 = -1) +{ + return GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, + oCreature, ++nNth, nCType1, nCValue1, nCType2, nCValue2); +} +int ai_GetNumOfEnemiesInGroup(object oCreature, float fDistance = AI_RANGE_MELEE) +{ + int nCnt; + location lLocation = GetLocation(oCreature); + object oEnemy = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, lLocation); + while(oEnemy != OBJECT_INVALID) + { + if(GetIsEnemy(oEnemy, oCreature) && !GetIsDead(oEnemy)) nCnt++; + oEnemy = GetNextObjectInShape(SHAPE_SPHERE, fDistance, lLocation); + } + return nCnt; +} +int ai_GetNumOfAlliesInGroup(object oCreature, float fDistance = AI_RANGE_MELEE) +{ + int nCnt; + location lLocation = GetLocation(oCreature); + object oAlly = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, lLocation); + while(oAlly != OBJECT_INVALID) + { + if(GetReputation(oCreature, oAlly) > 89 && oAlly != oCreature && !GetIsDead(oAlly)) + { + nCnt++; + } + oAlly = GetNextObjectInShape(SHAPE_SPHERE, fDistance, lLocation); + } + return nCnt; +} +int ai_GetRacialTypeCount(object oCreature, int nRacial_Type, float fDistance = AI_RANGE_PERCEPTION) +{ + int nCnt = 1; + int nCount = 0; + object oEnemy = ai_GetNearestEnemy(oCreature, nCnt, + CREATURE_TYPE_PERCEPTION, + PERCEPTION_SEEN, + CREATURE_TYPE_RACIAL_TYPE, + nRacial_Type); + while(oEnemy != OBJECT_INVALID && GetDistanceBetween(oEnemy, oCreature) <= fDistance) + { + if(!ai_GetHasEffectType(oEnemy, EFFECT_TYPE_TURNED)) nCount++; + nCnt++; + oEnemy = ai_GetNearestEnemy(oCreature, nCnt, + CREATURE_TYPE_PERCEPTION, + PERCEPTION_SEEN, + CREATURE_TYPE_RACIAL_TYPE, + nRacial_Type); + } + return nCount; +} +object ai_GetLowestCRAttackerOnMaster(object oCreature) +{ + object oTarget = OBJECT_INVALID, oMaster = GetMaster(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "419", "Checking for weakest attacker on " + GetName(oMaster)); + int nEnemyCombatRating, nWeakestCombatRating, nCntr = 1; + float fNearest = AI_RANGE_MELEE + 1.0f; + // Get the weakest opponent in melee with our master. + object oEnemy = ai_GetNearestEnemy(oMaster, nCntr, 7, 7); + float fDistance = GetDistanceBetween(oMaster, oEnemy); + while (oEnemy != OBJECT_INVALID && fDistance <= AI_RANGE_MELEE) + { + nEnemyCombatRating = ai_GetMyCombatRating(oEnemy); + if(AI_DEBUG) ai_Debug("0i_combat", "428", GetName(oEnemy) + " nECR: " + IntToString(nEnemyCombatRating)); + if (nEnemyCombatRating < nWeakestCombatRating || + nEnemyCombatRating == nWeakestCombatRating && fDistance < fNearest) + { + fNearest = fDistance; + nWeakestCombatRating = nEnemyCombatRating; + oTarget = oEnemy; + } + oEnemy = ai_GetNearestEnemy(oMaster, ++nCntr, 7, 7); + } + // No targets in melee with our master, lets see if there is a ranged attacker. + if (oTarget == OBJECT_INVALID) oTarget = GetLastHostileActor(oMaster); + return oTarget; +} + +//****************************************************************************** +//******************** SET/CLEAR COMBAT STATE FUNCTIONS ************************ +//****************************************************************************** + +object ai_SetCombatState(object oCreature) +{ + if(AI_DEBUG) ai_Counter_Start(); + object oMaster = GetMaster(); + if(oMaster == OBJECT_INVALID) oMaster = oCreature; + int nEnemyNum, nEnemyPower, nAllyNum, nAllyPower, nInMelee, nMagic; + int nHealth, nNth, nAllies, nPower, nDisabled, bThreat,nObjects; + int nEnemyHighestPower, nAllyHighestPower; + float fNearest = AI_RANGE_BATTLEFIELD; + float fDistance; + float fMaxRange = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fMaxRange == 0.0) fMaxRange = AI_RANGE_PERCEPTION; + string sCnt, sDebugText; + location lLocation = GetLocation(oMaster); + object oMelee, oNearestEnemy = OBJECT_INVALID; + if(AI_DEBUG) ai_Debug("0i_combat", "491", "************************************************************"); + if(AI_DEBUG) ai_Debug("0i_combat", "492", "******************* CREATING COMBAT DATA *******************"); + if(AI_DEBUG) ai_Debug("0i_combat", "493", GetName(oCreature)); + // We want to include ourselves in the combat state. + object oObject = GetFirstObjectInShape(SHAPE_SPHERE, AI_RANGE_BATTLEFIELD, lLocation); + // Get all creatures within 40 meters(5 meters beyond our perception of 35). + // Centered on either the creature or their master. + while(oObject != OBJECT_INVALID) + { + // Process all enemies. + if(GetIsEnemy(oObject, oCreature)) + { + if(GetObjectSeen(oObject, oCreature) || GetObjectHeard(oObject, oCreature)) + { + fDistance = GetDistanceBetween(oObject, oCreature); + if(fDistance <= fMaxRange) + { + // ********** Get the Total levels of the Enemy ********** + nPower = ai_GetCharacterLevels(oObject); + if(nPower < 1) nPower = 1; + if(nEnemyHighestPower < nPower) nEnemyHighestPower = nPower; + nEnemyPower += nPower; + // ********** Check if the Enemy is disabled ********** + bThreat = TRUE; + nDisabled = ai_Disabled(oObject); + if(nDisabled) + { + if(AI_DEBUG) sDebugText += "**** DISABLED(" + IntToString(nDisabled) + ") ****"; + // Decide if they are still a threat: 1 - dead, 2 - Bleeding. + if(nDisabled == 1 || nDisabled == 2 || + //nDisabled == EFFECT_TYPE_CONFUSED || + //nDisabled == EFFECT_TYPE_FRIGHTENED || + //nDisabled == EFFECT_TYPE_PARALYZE || + nDisabled == EFFECT_TYPE_CHARMED || + nDisabled == EFFECT_TYPE_PETRIFY) + { + bThreat = FALSE; + if(AI_DEBUG) ai_Debug("0i_combat", "527", "Enemy: " + GetName(oObject) + sDebugText); + } + } + // If they are using the coward ai then treat them as frightened. + // we place it here as an else so we don't overwrite another disabled effect. + else if(GetLocalString(oObject, AI_COMBAT_SCRIPT) == "ai_coward") + { + nDisabled = EFFECT_TYPE_FRIGHTENED; + // !!!! For /DEBUG CODE !!!! + if(AI_DEBUG) sDebugText += "**** DISABLED(" + IntToString(nDisabled) + ") ****"; + } + if(bThreat) + { + sCnt = IntToString(++nEnemyNum); + // ********** Set if the Enemy is disabled ********** + SetLocalInt(oCreature, AI_ENEMY_DISABLED + sCnt, nDisabled); + // ********** Set the Enemy Object ********** + SetLocalObject(oCreature, AI_ENEMY + sCnt, oObject); + // ********** Set the Enemy Combat Rating ********** + SetLocalInt(oCreature, AI_ENEMY_COMBAT + sCnt, ai_GetMyCombatRating(oObject)); + // ********** Set the Enemy Health Percentage ********** + nHealth = ai_GetPercHPLoss(oObject); + SetLocalInt(oCreature, AI_ENEMY_HEALTH + sCnt, nHealth); + // ********** Set the number of enemies near the enemy ********** + nInMelee = 0; + nNth = 1; + oMelee = GetNearestObject(OBJECT_TYPE_CREATURE, oObject, nNth); + while(oMelee != OBJECT_INVALID && !GetIsDead(oMelee) && + GetDistanceBetween(oMelee, oObject) < AI_RANGE_MELEE) + { + // We add an enemy to the group. + if(GetIsEnemy(oMelee, oCreature)) nInMelee++; + oMelee = GetNearestObject(OBJECT_TYPE_CREATURE, oObject, ++nNth); + } + SetLocalInt(oCreature, AI_ENEMY_MELEE + sCnt, nInMelee); + // ********** Set the Enemies distance ********** + fDistance = GetDistanceBetween(oObject, oCreature); + SetLocalFloat(oCreature, AI_ENEMY_RANGE + sCnt, fDistance); + // ********** Set if the Enemy is perceived ********** + if(GetObjectSeen(oObject, oCreature) || + (GetObjectHeard(oObject, oCreature) && fDistance <= AI_RANGE_MELEE && + ai_GetIsHidden(oObject))) + { + SetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCnt, TRUE); + if(AI_DEBUG) sDebugText += "**** PERCEIVED Seen: " + + IntToString(GetObjectSeen(oObject, oCreature)) + + " Heard: " + IntToString(GetObjectHeard(oObject, oCreature)) + " ****"; + } + else SetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCnt, FALSE); + // ********** Set the Nearest Enemy seen ********** + if(fDistance < fNearest) + { + fNearest = fDistance; + oNearestEnemy = oObject; + } + } + } + // !!! Debug code !!! + if(AI_DEBUG && fDistance < AI_RANGE_MELEE) sDebugText += "**** MELEE ****"; + if(AI_DEBUG) ai_Debug("0i_combat", "587", "Enemy(" + IntToString(nEnemyNum) + "): " + + GetName(oObject) + sDebugText); + if(AI_DEBUG) ai_Debug("0i_combat", "589", "nHealth: " + IntToString(nHealth) + + " nInMelee: " + IntToString(nInMelee) + + " fDistance: " + FloatToString(fDistance, 0, 2) + + " nNum: " + IntToString(nEnemyNum) + + " nPower: " + IntToString(nEnemyPower / 2)); + } + else + { + // ********** Also add the levels of Unknown Enemies *********** + nPower = FloatToInt(ai_GetCharacterLevels(oObject) / 1.5); + if(nPower < 1) nPower = 1; + nEnemyPower += nPower; + if(AI_DEBUG) ai_Debug("0i_combat", "601", "Enemy(NOT PERCEIVED): " + + GetName(oObject) + " fDistance: " + + FloatToString(GetDistanceBetween(oObject, oCreature), 0, 2) + + " nPower: " + IntToString(nEnemyPower)); + } + } + // Process all Allies. + else if(GetFactionEqual(oObject, oCreature)) + { + // ********** Set if the Ally is disabled ********** + nDisabled = ai_Disabled(oObject); + if(nDisabled) + { + sDebugText += "**** DISABLED(" + IntToString(nDisabled) + ") ****"; + SetLocalInt(oCreature, AI_ALLY_DISABLED + sCnt, nDisabled); + } + if(nDisabled != 1) + { + sCnt = IntToString(++nAllyNum); + // ********** Set the Ally Object ********** + SetLocalObject(oCreature, AI_ALLY + sCnt, oObject); + // ********** Set the Ally Combat Rating ********** + SetLocalInt(oCreature, AI_ALLY_COMBAT + sCnt, ai_GetMyCombatRating(oObject)); + // ********** Set the Ally Health Percentage ********** + nHealth = ai_GetPercHPLoss(oObject); + SetLocalInt(oCreature, AI_ALLY_HEALTH + sCnt, nHealth); + // ********** Set the number of enemies near the ally ********** + nInMelee = 0; + nNth = 1; + oMelee = GetNearestObject(OBJECT_TYPE_CREATURE, oObject, nNth); + while(oMelee != OBJECT_INVALID && !GetIsDead(oMelee) && + GetDistanceBetween(oMelee, oObject) < AI_RANGE_MELEE) + { + if(GetIsEnemy(oMelee, oCreature)) nInMelee++; + //else nInMelee--; + oMelee = GetNearestObject(OBJECT_TYPE_CREATURE, oObject, ++nNth); + } + SetLocalInt(oCreature, AI_ALLY_MELEE + sCnt, nInMelee); + // ********** Set the Allies distance ********** + SetLocalFloat(oCreature, AI_ALLY_RANGE + sCnt, GetDistanceBetween(oObject, oCreature)); + // ********** All allies are considered to be seen ********** + SetLocalInt(oCreature, AI_ALLY_PERCEIVED + sCnt, TRUE); + // ********** Get the Total levels of the Allies ********** + nPower = ai_GetCharacterLevels(oObject); + if(nAllyHighestPower < nPower) nAllyHighestPower = nPower; + nAllyPower +=(nPower * nHealth) / 100; + if(AI_DEBUG) ai_Debug("0i_combat", "647", "Ally(" + IntToString(nAllyNum) + "): " + + GetName(oObject) + sDebugText); + if(AI_DEBUG) ai_Debug("0i_combat", "649", "nHealth: " + IntToString(nHealth) + + " nInMelee: " + IntToString(nInMelee) + + " fDistance: " + FloatToString(GetDistanceToObject(oObject), 0, 2) + + " nNum: " + IntToString(nAllyNum) + + " nPower: " + IntToString(nAllyPower / 2)); + } + } + if(AI_DEBUG) sDebugText = ""; + oObject = GetNextObjectInShape(SHAPE_SPHERE, AI_RANGE_BATTLEFIELD, lLocation); + } + if(AI_DEBUG) ai_Debug("0i_combat", "659", "Nearest Enemy: " + GetName(oNearestEnemy)); + if(AI_DEBUG) ai_Debug("0i_combat", "660", "****************** FINISHED COMBAT DATA *******************"); + if(AI_DEBUG) ai_Debug("0i_combat", "661", "************************************************************"); + // Lets save processing by only clearing previous enemy data we don't overwrite. + int nPreviousEnd = GetLocalInt(oCreature, AI_ENEMY_NUMBERS); + int nCnt = nEnemyNum + 1; + if(AI_DEBUG) ai_Debug("0i_combat", "665", "Clearing Enemy Combat Data: nPreviousEnd: " + + IntToString(nPreviousEnd) + " nCurrentEnd: " + IntToString(nCnt - 1)); + while(nPreviousEnd >= nCnt) + { + sCnt = IntToString(nCnt); + if(AI_DEBUG) ai_Debug("0i_combat", "670", "Clearing Enemy Combat Data: " + sCnt + " " + + GetName(GetLocalObject(oCreature, AI_ENEMY + sCnt))); + DeleteLocalObject(oCreature, AI_ENEMY + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCnt); + DeleteLocalFloat(oCreature, AI_ENEMY_RANGE + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_COMBAT + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_MELEE + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_HEALTH + sCnt); + nCnt ++; + } + // Lets save processing by only clearing previous ally data we don't overwrite. + nPreviousEnd = GetLocalInt(oCreature, AI_ALLY_NUMBERS); + nCnt = nAllyNum + 1; + if(AI_DEBUG) ai_Debug("0i_combat", "683", "Clearing Ally Combat Data: nPreviousEnd: " + + IntToString(nPreviousEnd) + " nCurrentEnd: " + IntToString(nCnt - 1)); + while(nPreviousEnd >= nCnt) + { + sCnt = IntToString(nCnt); + if(AI_DEBUG) ai_Debug("0i_combat", "688", "Clearing Ally Combat Data: " + sCnt + " " + + GetName(GetLocalObject(oCreature, AI_ENEMY + sCnt))); + DeleteLocalObject(oCreature, AI_ALLY + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_PERCEIVED + sCnt); + DeleteLocalFloat(oCreature, AI_ALLY_RANGE + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_COMBAT + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_MELEE + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_HEALTH + sCnt); + nCnt ++; + } + // Finally set all group states. + SetLocalInt(oCreature, AI_ENEMY_NUMBERS, nEnemyNum); + // Total enemy power is half the levels of all enemies + the total levels + // of the highest level enemy. + nEnemyPower = (nEnemyPower / 2) + nEnemyHighestPower; + SetLocalInt(oCreature, AI_ENEMY_POWER, nEnemyPower); + SetLocalObject(oCreature, AI_ENEMY_NEAREST, oNearestEnemy); + SetLocalInt(oCreature, AI_ALLY_NUMBERS, nAllyNum); + // Total ally power is half the levels of all allies + the total levels + // of the highest level ally, only used by associates. + nAllyPower = (nAllyPower / 2) + nAllyHighestPower; + SetLocalInt(oCreature, AI_ALLY_POWER, nAllyPower); + if(AI_DEBUG) ai_Debug("0i_combat", "710", "nEnemyPower: " + IntToString(nEnemyPower) + + " nEnemyHighestPower: " + IntToString(nEnemyHighestPower) + + " nAllyPower: " + IntToString(nAllyPower) + + " nAllyHighestPower: " + IntToString(nAllyHighestPower)); + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + " has finished the Combat State"); + return oNearestEnemy; +} +void ai_ClearCombatState(object oCreature) +{ + int bEnemyDone, bAllyDone, nCnt = 1; + int nEnemyNum = GetLocalInt(oCreature, AI_ENEMY_NUMBERS); + int nAllyNum = GetLocalInt(oCreature, AI_ALLY_NUMBERS); + if(AI_DEBUG) ai_Debug("0i_combat", "722", "Clearing " + GetName(oCreature) + "'s combat state." + + " nEnemyNum: " + IntToString(nEnemyNum) + " nAllyNum: " + IntToString(nAllyNum)); + string sCnt; + while(!bEnemyDone || !bAllyDone) + { + sCnt = IntToString(nCnt); + if(nCnt <= nEnemyNum) + { + if(AI_DEBUG) ai_Debug("0i_combat", "730", "Clearing " + GetName(GetLocalObject(oCreature, AI_ENEMY + sCnt)) + "."); + DeleteLocalObject(oCreature, AI_ENEMY + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_DISABLED + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCnt); + DeleteLocalFloat(oCreature, AI_ENEMY_RANGE + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_COMBAT + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_MELEE + sCnt); + DeleteLocalInt(oCreature, AI_ENEMY_HEALTH + sCnt); + } + else bEnemyDone = TRUE; + if(nCnt <= nAllyNum) + { + if(AI_DEBUG) ai_Debug("0i_combat", "742", "Clearing " + GetName(GetLocalObject(oCreature, AI_ALLY + sCnt)) + "."); + DeleteLocalObject(oCreature, AI_ALLY + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_DISABLED + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_PERCEIVED + sCnt); + DeleteLocalFloat(oCreature, AI_ALLY_RANGE + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_COMBAT + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_MELEE + sCnt); + DeleteLocalInt(oCreature, AI_ALLY_HEALTH + sCnt); + } + else bAllyDone = TRUE; + nCnt++; + } + DeleteLocalObject(oCreature, AI_ENEMY_NEAREST); + DeleteLocalInt(oCreature, AI_ENEMY_NUMBERS); + DeleteLocalInt(oCreature, AI_ENEMY_POWER); + DeleteLocalInt(oCreature, AI_ALLY_NUMBERS); + DeleteLocalObject(oCreature, AI_ALLY_POWER); + // Also clear these combat variables at the end of combat. + DeleteLocalObject(oCreature, AI_ATTACKED_PHYSICAL); + DeleteLocalObject(oCreature, AI_ATTACKED_SPELL); + // Remove Talent variables. + DeleteLocalJson(oCreature, AI_TALENT_CURE); + DeleteLocalJson(oCreature, AI_TALENT_HEALING); + DeleteLocalJson(oCreature, AI_TALENT_ENHANCEMENT); + DeleteLocalJson(oCreature, AI_TALENT_PROTECTION); + DeleteLocalJson(oCreature, AI_TALENT_SUMMON); + DeleteLocalJson(oCreature, AI_TALENT_DISCRIMINANT_AOE); + DeleteLocalJson(oCreature, AI_TALENT_INDISCRIMINANT_AOE); + DeleteLocalJson(oCreature, AI_TALENT_RANGED); + DeleteLocalJson(oCreature, AI_TALENT_TOUCH); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_HEALING); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_ENHANCEMENT); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_PROTECTION); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_SUMMON); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_DISCRIMINANT_AOE); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_INDISCRIMINANT_AOE); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_RANGED); + DeleteLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_TOUCH); + DeleteLocalInt(oCreature, AI_AM_I_SEARCHING); + DeleteLocalInt(oCreature, AI_TRIED_TO_HIDE); + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); + DeleteLocalInt(oCreature, sLastActionVarname); + DeleteLocalInt(oCreature, AI_TALENTS_SET); + DeleteLocalInt(oCreature, AI_ROUND); + DeleteLocalInt(oCreature, sIPHasHasteVarname); + DeleteLocalInt(oCreature, sIPImmuneVarname); + DeleteLocalInt(oCreature, sIPResistVarname); + DeleteLocalInt(oCreature, sIPReducedVarname); + ai_EndCombatRound(oCreature); +} +//****************************************************************************** +//*********************** GET TARGETS INTERNAL FUNCTIONS *********************** +//****************************************************************************** +// These functions are used by the Get Index/ Get Target functions below. + +int ai_TargetIsInRangeofCreature(object oCreature, string sTargetType, string sCounter, float fMaxRange) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "796", "fMaxRange: " + FloatToString(fMaxRange, 0, 2) + + " fTargetRange: " + FloatToString(GetLocalFloat(oCreature, sTargetType + "_RANGE" + sCounter), 0, 2)); + return fMaxRange >= GetLocalFloat(oCreature, sTargetType + "_RANGE" + sCounter); +} +int ai_TargetIsInRangeofMaster(object oCreature, object oTarget) +{ + object oMaster = GetMaster(); + if(oMaster == OBJECT_INVALID) return TRUE; + float fMaxRange = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fMaxRange == 0.0) fMaxRange = 20.0; + float fTargetRangefromMaster = GetDistanceBetween(oTarget, oMaster); + if(AI_DEBUG) ai_Debug("0i_combat", "807", "fMaxRangefromMaster: " + FloatToString(fMaxRange, 0, 2) + + " fTargetRangefromMaster: " + FloatToString(fTargetRangefromMaster, 0, 2)); + return fMaxRange >= fTargetRangefromMaster; +} +struct stTarget ai_CheckForNearestTarget(object oCreature, struct stTarget sTarget, int nIndex, string sIndex) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "817", "Getting nearest index: " + sIndex + + " fRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestRange: " + FloatToString(sTarget.fNearestRange, 0, 2) + + " fNearestSecondaryRange: " + FloatToString(sTarget.fNearestSecondaryRange, 0, 2)); + // Lets put any disabled targets and associates if set in a secondary group. + if(GetLocalInt(oCreature, sTarget.sTargetType + "_DISABLED" + sIndex) || + (ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && GetAssociateType(sTarget.oTarget))) + { + if(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestSecondaryRange) + { + sTarget.fNearestSecondaryRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nSecondaryIndex = nIndex; + } + } + else if(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestRange) + { + sTarget.fNearestRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nIndex = nIndex; + } + return sTarget; +} +struct stTarget ai_CheckForLowestValueTarget(object oCreature, struct stTarget sTarget, int nIndex, string sIndex) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "835", "Getting lowest value index: " + sIndex + + " fRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestSecondaryRange: " + FloatToString(sTarget.fNearestSecondaryRange, 0, 2) + + " sTarget.nValue: " + IntToString(sTarget.nValue) + + " sTarget.nBestValue: " + IntToString(sTarget.nBestValue) + + " sTarget.nBestSecondaryValue: " + IntToString(sTarget.nBestSecondaryValue)); + // Lets put any disabled targets and associates if set in a secondary group. + if(GetLocalInt(oCreature, sTarget.sTargetType + "_DISABLED" + sIndex) || + (ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && GetAssociateType(sTarget.oTarget))) + { + if(sTarget.nValue < sTarget.nBestSecondaryValue || + (sTarget.nValue == sTarget.nBestSecondaryValue && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestSecondaryRange)) + { + sTarget.fNearestSecondaryRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nBestSecondaryValue = sTarget.nValue; + sTarget.nSecondaryIndex = nIndex; + } + } + // Has less value or equal value and is closer. + else if(sTarget.nValue < sTarget.nBestValue || + (sTarget.nBestValue == sTarget.nValue && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestRange)) + { + sTarget.fNearestRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nBestValue = sTarget.nValue; + sTarget.nIndex = nIndex; + } + return sTarget; +} +struct stTarget ai_CheckForHighestValueTarget(object oCreature, struct stTarget sTarget, int nIndex, string sIndex) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "865", "Getting highest value index: " + sIndex + + " fRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestRange: " + FloatToString(sTarget.fNearestRange, 0, 2) + + " fNearestSecondaryRange: " + FloatToString(sTarget.fNearestSecondaryRange, 0, 2) + + " sTarget.nValue: " + IntToString(sTarget.nValue) + + " sTarget.nBestValue: " + IntToString(sTarget.nBestValue) + + " sTarget.nBestSecondaryValue: " + IntToString(sTarget.nBestSecondaryValue)); + // Lets put any disabled targets and associates if set in a secondary group. + if(GetLocalInt(oCreature, sTarget.sTargetType + "_DISABLED" + sIndex) || + (ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && GetAssociateType(sTarget.oTarget))) + { + if(sTarget.nValue > sTarget.nBestSecondaryValue || + (sTarget.nValue == sTarget.nBestSecondaryValue && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestSecondaryRange)) + { + sTarget.fNearestSecondaryRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nBestSecondaryValue = sTarget.nValue; + sTarget.nSecondaryIndex = nIndex; + } + } + // Has less value or equal value and is closer. + else if(sTarget.nValue > sTarget.nBestValue || + (sTarget.nBestValue == sTarget.nValue && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestRange)) + { + sTarget.fNearestRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nBestValue = sTarget.nValue; + sTarget.nIndex = nIndex; + } + return sTarget; +} +struct stTarget ai_CheckForNearestAllTarget(object oCreature, struct stTarget sTarget, int nIndex, string sIndex) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "895", "Getting nearest (not disabled) index: " + sIndex + + " fRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestRange: " + FloatToString(sTarget.fNearestRange, 0, 2)); + // If we are ignoring associates set then ignore them. + // Has lower value or equal value and is closer. Familiars/Companions/Summons/Dominated. + if(AI_DEBUG) ai_Debug("0i_combat", "911", "Don't Ignore Associate: " + IntToString(!ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES)) + + " Not an Associate? " + IntToString(GetAssociateType(sTarget.oTarget) < 2)); + if((!ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) || GetAssociateType(sTarget.oTarget) < 2) && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestRange) + { + sTarget.fNearestRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nIndex = nIndex; + } + return sTarget; +} +struct stTarget ai_CheckForLowestValueAllTarget(object oCreature, struct stTarget sTarget, int nIndex, string sIndex) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "923", "Getting lowest value index: " + sIndex + + " fRange: " + FloatToString(GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex), 0, 2) + + " fNearestRange: " + FloatToString(sTarget.fNearestRange, 0, 2) + + " sTarget.nValue: " + IntToString(sTarget.nValue) + + " sTarget.nBestValue: " + IntToString(sTarget.nBestValue)); + // Has less value or equal value and is closer. Ignoring only Familiars/Companions/Summons/Dominated. + if(AI_DEBUG) ai_Debug("0i_combat", "922", "Don't Ignore Associate: " + IntToString(!ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES)) + + " Not an Associate? " + IntToString(GetAssociateType(sTarget.oTarget) < 2)); + if((!ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) || GetAssociateType(sTarget.oTarget) < 2) && + sTarget.nValue < sTarget.nBestValue || + (sTarget.nBestValue == sTarget.nValue && + GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex) < sTarget.fNearestRange)) + { + sTarget.fNearestRange = GetLocalFloat(oCreature, sTarget.sTargetType + "_RANGE" + sIndex); + sTarget.nBestValue = sTarget.nValue; + sTarget.nIndex = nIndex; + } + return sTarget; +} + +//****************************************************************************** +//************ GET INDEX/TARGETs USING COMBAT STATE FUNCTIONS ****************** +//****************************************************************************** +// These functions will find a target based on the combat state variables created +// by the function ai_SetCombatState for associates. + +int ai_GetNearestIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(GetLocalInt(oCreature, AI_RULE_AI_DIFFICULTY)) + { + return ai_GetLowestCRIndex(oCreature, fMaxRange, sTargetType, bAlwaysAtk); + } + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "911", "Getting the nearest index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "918", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "931", "Found nearest [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetNearestTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "936", "Getting the nearest target."); + string sIndex = IntToString(ai_GetNearestIndex(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetLowestCRIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 100; + sTarget.nBestSecondaryValue = 100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "953", "Getting the lowest CR index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "960", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "974", "Found lowest CR [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetLowestCRTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "979", "Getting the lowest CR target."); + string sIndex = IntToString(ai_GetLowestCRIndex(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetHighestCRIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "995", "Getting the highest CR index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1002", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1016", "Found highest CR [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetHighestCRTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1021", "Getting the highest CR target."); + string sIndex = IntToString(ai_GetHighestCRIndex(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetLowestMeleeIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 100; + sTarget.nBestSecondaryValue = 100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1037", "Getting the lowest InMelee index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_MELEE" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1058", "Found lowest InMelee [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +int ai_GetHighestMeleeIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1073", "Getting the highest InMelee index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_MELEE" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1094", "Found highest InMelee [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_CheckForGroupedTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1124", "Getting the highest InMelee target."); + string sIndex = IntToString(ai_GetHighestMeleeIndex(oCreature, fMaxRange, sTargetType)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetMostWoundedIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 200; + sTarget.nBestSecondaryValue = 200; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1113", "Getting the most wounded index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1120", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_HEALTH" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1130", "Found most wounded [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetMostWoundedTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1139", "Getting the most wounded target."); + string sIndex = IntToString(ai_GetMostWoundedIndex(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetAllyToHealIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.nBestValue = 200; + sTarget.sTargetType = AI_ALLY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTarget.sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1154", "Getting the most wounded ally to heal index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ALLY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ALLY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ALLY, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, AI_ALLY_HEALTH + sCounter); + sTarget = ai_CheckForLowestValueAllTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ALLY + sCounter); + } + // If we do not have a normal target then we are done.. + if(AI_DEBUG) ai_Debug("0i_combat", "1187", "Found most wounded ally to heal Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetAllyToHealTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1192", "Getting the most wounded ally to heal target."); + string sIndex = IntToString(ai_GetAllyToHealIndex(oCreature, fMaxRange)); + return GetLocalObject(oCreature, AI_ALLY + sIndex); +} +object ai_GetLowestFortitudeSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 200; + sTarget.nBestSecondaryValue = 200; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1113", "Getting the lowest fortitude save index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetFortitudeSavingThrow(sTarget.oTarget); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1232", "Found lowest fortitude save Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, AI_ENEMY + IntToString(sTarget.nIndex)); +} +object ai_GetLowestReflexSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 200; + sTarget.nBestSecondaryValue = 200; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1248", "Getting the lowest reflex save index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetReflexSavingThrow(sTarget.oTarget); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1269", "Found lowest reflex save Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, AI_ENEMY + IntToString(sTarget.nIndex)); +} +object ai_GetLowestWillSaveTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 200; + sTarget.nBestSecondaryValue = 200; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1285", "Getting the lowest will save index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetWillSavingThrow(sTarget.oTarget); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1306", "Found lowest will save Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, AI_ENEMY + IntToString(sTarget.nIndex)); +} +object ai_GetSpellTargetBasedOnSaves(object oCreature, int nSpell, float fMaxRange = AI_RANGE_PERCEPTION) +{ + // Check the spells save type in "ai_spells.2da" and find the weakest + // creature based on that save. + string sSaveType = Get2DAString("ai_spells", "SaveType", nSpell); + if(sSaveType == "Reflex") return ai_GetLowestReflexSaveTarget(oCreature, fMaxRange); + if(sSaveType == "Fortitude") return ai_GetLowestFortitudeSaveTarget(oCreature, fMaxRange); + if(sSaveType == "Will") return ai_GetLowestWillSaveTarget(oCreature, fMaxRange); + // If there is no save then lets see if we can find an enemy with the lowest health. + return ai_GetMostWoundedTarget(oCreature, fMaxRange); +} +int ai_GetNearestIndexThatSeesUs(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1334", "Getting the nearest creature that sees us index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1373", GetName(sTarget.oTarget) + " can see us? " + + IntToString(GetObjectSeen(oCreature, sTarget.oTarget))); + if(GetObjectSeen(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestAllTarget(oCreature, sTarget, nCounter, sCounter); + } + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(AI_DEBUG) ai_Debug("0i_combat", "1354", "Found nearest creature that sees us Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +int ai_GetBestSneakAttackIndex(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + object oAttacking; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1372", "Getting the best sneak attack index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget) && + !ai_IsImmuneToSneakAttacks(oCreature, sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + oAttacking = ai_GetAttackedTarget(sTarget.oTarget); + if(AI_DEBUG) ai_Debug("0i_combat", "1383", "oTarget: " + GetName(sTarget.oTarget) + + " is attacking " + GetName(oAttacking)); + // They are attacking someone besides us or we are hidden? + if((oAttacking != OBJECT_INVALID && oAttacking != oCreature) || + GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1398", "Found best sneak attack Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +int ai_GetNearestIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(GetLocalInt(oCreature, AI_RULE_AI_DIFFICULTY)) + { + ai_GetLowestCRIndexNotInAOE(oCreature, fMaxRange, sTargetType, bAlwaysAtk); + } + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1416", "Getting the nearest not in AOE index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget) && !ai_IsInADangerousAOE(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1434", "Found nearest not in AOE Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetNearestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1439", "Getting the nearest not in AOE target."); + string sIndex = IntToString(ai_GetNearestIndexNotInAOE(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetLowestCRIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 100; + sTarget.nBestSecondaryValue = 100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1456", "Getting the lowest CR not in AOE index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && !ai_IsInADangerousAOE(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1463", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1477", "Found lowest CR not in AOE [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetLowestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1482", "Getting the lowest cr not in AOE target."); + string sIndex = IntToString(ai_GetLowestCRIndexNotInAOE(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetHighestCRIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1499", "Getting the highest CR not in AOE index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && !ai_IsInADangerousAOE(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1506", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1520", "Found highest CR not in AOE [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_GetHighestTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1525", "Getting the highest cr not in AOE target."); + string sIndex = IntToString(ai_GetHighestCRIndexNotInAOE(oCreature, fMaxRange, sTargetType, bAlwaysAtk)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +int ai_GetHighestMeleeIndexNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1542", "Getting the highest InMelee not in AOE index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && !ai_IsInADangerousAOE(sTarget.oTarget)) + { + if(ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_MELEE" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1563", "Found highest InMelee not in AOE [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return sTarget.nIndex; +} +object ai_CheckForGroupedTargetNotInAOE(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "1574", "Getting the highest InMelee not in AOE target."); + string sIndex = IntToString(ai_GetHighestMeleeIndexNotInAOE(oCreature, fMaxRange, sTargetType)); + return GetLocalObject(oCreature, sTargetType + sIndex); +} +object ai_GetNearestClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(GetLocalInt(oCreature, AI_RULE_AI_DIFFICULTY)) + { + ai_GetLowestCRClassTarget(oCreature, nClassType, fMaxRange, sTargetType, bAlwaysAtk); + } + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1591", "Getting the nearest class index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckClassType(sTarget.oTarget, nClassType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1598", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1611", "Found nearest class Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetLowestCRClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 100; + sTarget.nBestSecondaryValue = 100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1626", "Getting the lowest CR class index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckClassType(sTarget.oTarget, nClassType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1634", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1648", "Found lowest CR class [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetHighestCRClassTarget(object oCreature, int nClassType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1664", "Getting the highest CR class index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckClassType(sTarget.oTarget, nClassType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1671", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1685", "Found highest CR class [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetNearestRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + if(GetLocalInt(oCreature, AI_RULE_AI_DIFFICULTY)) + { + ai_GetLowestCRRacialTarget(oCreature, nRacialType, fMaxRange, sTargetType, bAlwaysAtk); + } + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1703", "Getting the nearest race index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckRacialType(sTarget.oTarget, nRacialType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1710", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1723", "Found nearest race Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetLowestCRRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = 100; + sTarget.nBestSecondaryValue = 100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1739", "Getting the lowest CR race index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckRacialType(sTarget.oTarget, nRacialType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1746", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForLowestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1760", "Found lowest CR race [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetHighestCRRacialTarget(object oCreature, int nRacialType, float fMaxRange = AI_RANGE_PERCEPTION, string sTargetType = AI_ENEMY, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = sTargetType; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1776", "Getting the highest CR race index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, sTargetType + "_PERCEIVED" + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckRacialType(sTarget.oTarget, nRacialType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1783", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, sTargetType, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget.nValue = GetLocalInt(oCreature, sTargetType + "_COMBAT" + sCounter); + sTarget = ai_CheckForHighestValueTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, sTargetType + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1797", "Found highest CR race [" + sTargetType + "] Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, sTargetType + IntToString(sTarget.nIndex)); +} +object ai_GetNearestFavoredEnemyTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.nBestValue = -100; + sTarget.nBestSecondaryValue = -100; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + int nRace, nRacialType; + while(nRace < 24) + { + // Find which favored enemies we have. + if(nRace < 1 && GetHasFeat(FEAT_FAVORED_ENEMY_ABERRATION, oCreature)) + { + nRace = 1; + nRacialType = RACIAL_TYPE_ABERRATION; + } + else if(nRace < 2 && GetHasFeat(FEAT_FAVORED_ENEMY_ANIMAL, oCreature)) + { + nRace = 2; + nRacialType = RACIAL_TYPE_ANIMAL; + } + else if(nRace < 3 && GetHasFeat(FEAT_FAVORED_ENEMY_BEAST, oCreature)) + { + nRace = 3; + nRacialType = RACIAL_TYPE_BEAST; + } + else if(nRace < 4 && GetHasFeat(FEAT_FAVORED_ENEMY_CONSTRUCT, oCreature)) + { + nRace = 4; + nRacialType = RACIAL_TYPE_CONSTRUCT; + } + else if(nRace < 5 && GetHasFeat(FEAT_FAVORED_ENEMY_DRAGON, oCreature)) + { + nRace = 5; + nRacialType = RACIAL_TYPE_DRAGON; + } + else if(nRace < 6 && GetHasFeat(FEAT_FAVORED_ENEMY_DWARF, oCreature)) + { + nRace = 6; + nRacialType = RACIAL_TYPE_DWARF; + } + else if(nRace < 7 && GetHasFeat(FEAT_FAVORED_ENEMY_ELEMENTAL, oCreature)) + { + nRace = 7; + nRacialType = RACIAL_TYPE_ELEMENTAL; + } + else if(nRace < 8 && GetHasFeat(FEAT_FAVORED_ENEMY_ELF, oCreature)) + { + nRace = 8; + nRacialType = RACIAL_TYPE_ELF; + } + else if(nRace < 9 && GetHasFeat(FEAT_FAVORED_ENEMY_FEY, oCreature)) + { + nRace = 9; + nRacialType = RACIAL_TYPE_FEY; + } + else if(nRace < 10 && GetHasFeat(FEAT_FAVORED_ENEMY_GIANT, oCreature)) + { + nRace = 10; + nRacialType = RACIAL_TYPE_GIANT; + } + else if(nRace < 11 && GetHasFeat(FEAT_FAVORED_ENEMY_GNOME, oCreature)) + { + nRace = 11; + nRacialType = RACIAL_TYPE_GNOME; + } + else if(nRace < 12 && GetHasFeat(FEAT_FAVORED_ENEMY_GOBLINOID, oCreature)) + { + nRace = 12; + nRacialType = RACIAL_TYPE_HUMANOID_GOBLINOID; + } + else if(nRace < 13 && GetHasFeat(FEAT_FAVORED_ENEMY_HALFELF, oCreature)) + { + nRace = 13; + nRacialType = RACIAL_TYPE_HALFELF; + } + else if(nRace < 14 && GetHasFeat(FEAT_FAVORED_ENEMY_HALFLING, oCreature)) + { + nRace = 14; + nRacialType = RACIAL_TYPE_HALFLING; + } + else if(nRace < 15 && GetHasFeat(FEAT_FAVORED_ENEMY_HALFORC, oCreature)) + { + nRace = 15; + nRacialType = RACIAL_TYPE_HALFORC; + } + else if(nRace < 16 && GetHasFeat(FEAT_FAVORED_ENEMY_HUMAN, oCreature)) + { + nRace = 16; + nRacialType = RACIAL_TYPE_HUMAN; + } + else if(nRace < 17 && GetHasFeat(FEAT_FAVORED_ENEMY_MAGICAL_BEAST, oCreature)) + { + nRace = 17; + nRacialType = RACIAL_TYPE_MAGICAL_BEAST; + } + else if(nRace < 18 && GetHasFeat(FEAT_FAVORED_ENEMY_MONSTROUS, oCreature)) + { + nRace = 18; + nRacialType = RACIAL_TYPE_HUMANOID_MONSTROUS; + } + else if(nRace < 19 && GetHasFeat(FEAT_FAVORED_ENEMY_ORC, oCreature)) + { + nRace = 19; + nRacialType = RACIAL_TYPE_HUMANOID_ORC; + } + else if(nRace < 20 && GetHasFeat(FEAT_FAVORED_ENEMY_OUTSIDER, oCreature)) + { + nRace = 20; + nRacialType = RACIAL_TYPE_OUTSIDER; + } + else if(nRace < 21 && GetHasFeat(FEAT_FAVORED_ENEMY_REPTILIAN, oCreature)) + { + nRace = 21; + nRacialType = RACIAL_TYPE_HUMANOID_REPTILIAN; + } + else if(nRace < 22 && GetHasFeat(FEAT_FAVORED_ENEMY_SHAPECHANGER, oCreature)) + { + nRace = 22; + nRacialType = RACIAL_TYPE_SHAPECHANGER; + } + else if(nRace < 23 && GetHasFeat(FEAT_FAVORED_ENEMY_UNDEAD, oCreature)) + { + nRace = 23; + nRacialType = RACIAL_TYPE_UNDEAD; + } + else if(nRace < 24 && GetHasFeat(FEAT_FAVORED_ENEMY_VERMIN, oCreature)) + { + nRace = 24; + nRacialType = RACIAL_TYPE_VERMIN; + } + else nRace = 25; + if(nRace < 25) + { + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1940", "Getting the nearest favored race index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget) && ai_CheckRacialType(sTarget.oTarget, nRacialType)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "1947", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) + + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + } + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "1962", "Found nearest favored race Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, AI_ENEMY + IntToString(sTarget.nIndex)); +} +object ai_GetFlankTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE) +{ + int nCnt = 1, nInMelee, nHighestMelee; + string sCnt = "1"; + float fAllyRange; + object oTarget, oAlly = GetLocalObject(oCreature, AI_ALLY + sCnt); + while(oAlly != OBJECT_INVALID) + { + fAllyRange = GetLocalFloat(oCreature, AI_ALLY_RANGE + sCnt); + if(AI_DEBUG) ai_Debug("0i_combat", "1974", "Getting Ally being Flanked Index: " + sCnt + " " + + GetName(oAlly) + " fAllyRange: " + FloatToString(fAllyRange, 0, 2) + + " fMaxRange: " + FloatToString(fMaxRange, 0, 2)); + if(fAllyRange <= fMaxRange) + { + nInMelee = GetLocalInt(oCreature, AI_ALLY_MELEE + sCnt); + if(AI_DEBUG) ai_Debug("0i_combat", "1980", "nInMelee: " + IntToString(nInMelee)); + if(!GetIsDead(oAlly) && nInMelee > nHighestMelee) + { + oTarget = ai_GetEnemyAttackingMyAlly(oCreature, oAlly, fMaxRange); + if(oTarget != OBJECT_INVALID) nHighestMelee = nInMelee; + } + } + sCnt = IntToString(++nCnt); + oAlly = GetLocalObject(oCreature, AI_ALLY + sCnt); + } + // If we do not have a good target then lets see if there are more targets. + if(oTarget == OBJECT_INVALID) + { + // If we just checked within melee then lets check what we can see if + // we can move around in combat. + if (fMaxRange == AI_RANGE_MELEE && ai_CanIMoveInCombat(oCreature)) + { + oTarget = ai_GetFlankTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + } + } + if(AI_DEBUG) ai_Debug("0i_combat", "2000", "oTarget " + GetName(oTarget) + + " is attacking " + GetName(oAlly)); + return oTarget; +} +object ai_GetRangedTarget(object oCreature, float fMaxRange = AI_RANGE_PERCEPTION, int bAlwaysAtk = TRUE) +{ + struct stTarget sTarget; + sTarget.fNearestRange = fMaxRange + 1.0; + sTarget.fNearestSecondaryRange = sTarget.fNearestRange; + sTarget.sTargetType = AI_ENEMY; + int nCounter = 1; + string sCounter = "1"; + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + while(sTarget.oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "2037", "Getting the nearest ranged index: " + + sCounter + " " + GetName(sTarget.oTarget) + + " Seen: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter)) + + " GetIsDead: " + IntToString(GetIsDead(sTarget.oTarget))); + if(GetLocalInt(oCreature, AI_ENEMY_PERCEIVED + sCounter) && + !GetIsDead(sTarget.oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "2044", "bAlwaysAtk: " + IntToString(bAlwaysAtk)); + if((bAlwaysAtk || !ai_IsStrongerThanMe(oCreature, nCounter)) && + ai_TargetIsInRangeofCreature(oCreature, AI_ENEMY, sCounter, fMaxRange) && + ai_TargetIsInRangeofMaster(oCreature, sTarget.oTarget)) + { + if(ai_GetIsRangeWeapon(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, sTarget.oTarget))) + { + sTarget = ai_CheckForNearestTarget(oCreature, sTarget, nCounter, sCounter); + } + } + } + sCounter = IntToString(++nCounter); + sTarget.oTarget = GetLocalObject(oCreature, AI_ENEMY + sCounter); + } + // If we do not have a normal target then use our best secondary target. + if(sTarget.nIndex == 0 && sTarget.nSecondaryIndex != 0) sTarget.nIndex = sTarget.nSecondaryIndex; + if(AI_DEBUG) ai_Debug("0i_combat", "2060", "Found nearest ranged Index: " + IntToString(sTarget.nIndex)); + return GetLocalObject(oCreature, AI_ENEMY + IntToString(sTarget.nIndex)); +} +object ai_GetBestTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget != OBJECT_INVALID) return oPCTarget; + string sIndex; + // Are we in melee? If so try to get the weakest enemy in melee. + if(nInMelee > 0) + { + if(ai_CanIMoveInCombat(oCreature)) + { + sIndex = IntToString(ai_GetLowestCRIndex(oCreature, AI_RANGE_MELEE)); + } + else sIndex = IntToString(ai_GetNearestIndex(oCreature, AI_RANGE_MELEE)); + } + // If not then lets go find someone to attack! + else + { + // If we are not in melee then we should get the nearest enemy. + sIndex = IntToString(ai_GetNearestIndexNotInAOE(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + /* Lets stay out of bad AOE's. + // If we didn't get a target then get any target within range. + if(sIndex == "0") + { + sIndex = IntToString(ai_GetLowestCRIndex(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + } */ + } + object oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("0i_combat", "2048", GetName(oTarget) + " is the best target for melee combat!"); + return oTarget; +} +object ai_GetNearestTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget != OBJECT_INVALID) return oPCTarget; + string sIndex; + // Are we in melee? If so try to get the nearest enemy in melee. + if(nInMelee > 0) sIndex = IntToString(ai_GetNearestIndex(oCreature, AI_RANGE_MELEE)); + // If not then lets go find someone to attack! + else + { + // Get the nearest enemy. + sIndex = IntToString(ai_GetNearestIndexNotInAOE(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + // If we didn't get a target then get any target within range. + if(sIndex == "0") + { + sIndex = IntToString(ai_GetNearestIndex(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + } + } + object oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("0i_combat", "2024", GetName(oTarget) + " is the nearest target for melee combat!"); + return oTarget; +} +object ai_GetLowestCRTargetForMeleeCombat(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget != OBJECT_INVALID) return oPCTarget; + string sIndex; + // Are we in melee? If so try to get the weakest enemy in melee. + if(nInMelee > 0) sIndex = IntToString(ai_GetLowestCRIndex(oCreature, AI_RANGE_MELEE)); + // If not then lets go find someone to attack! + else + { + // Get the weakest combat rated enemy. + sIndex = IntToString(ai_GetLowestCRIndexNotInAOE(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + /* Lets stay out of bad AOE's. + // If we didn't get a target then get any target within range. + if(sIndex == "0") + { + sIndex = IntToString(ai_GetLowestCRIndex(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk)); + } */ + } + object oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("0i_combat", "2048", GetName(oTarget) + " is the weakest target for melee combat!"); + return oTarget; +} +object ai_GetHighestCRTargetForMeleeCombat(object oCreature, int nInMelee) +{ + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget != OBJECT_INVALID) return oPCTarget; + string sIndex; + // Are we in melee? If so try to get the weakest enemy in melee. + if(nInMelee > 0) sIndex = IntToString(ai_GetHighestCRIndex(oCreature, AI_RANGE_MELEE)); + // If not then lets go find someone to attack! + else + { + // Get the weakest combat rated enemy. + sIndex = IntToString(ai_GetHighestCRIndexNotInAOE(oCreature, AI_RANGE_PERCEPTION)); + /* Lets stay out of bad AOE's. + // If we didn't get a target then get any target within range. + if(sIndex == "0") sIndex = IntToString(ai_GetHighestCRIndex(oCreature)); + */ + } + object oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("0i_combat", "2070", GetName(oTarget) + " is the strongest target for melee combat!"); + return oTarget; +} +object ai_GetEnemyAttackingMe(object oCreature, float fMaxRange = AI_RANGE_MELEE) +{ + int nCtr = 1; + float fDistance; + string sCtr = "1"; + object oAttacked; + object oEnemy = GetLocalObject(oCreature, AI_ENEMY + "1"); + while(oEnemy != OBJECT_INVALID) + { + if(!ai_Disabled(oEnemy)) + { + fDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sCtr); + if(AI_DEBUG) ai_Debug("0i_combat", "2084", "Getting Enemy Attacking Me: " + sCtr + " " + + GetName(oEnemy) + " fTargetRange: " + FloatToString(fDistance, 0, 2) + + " fMaxRange: " + FloatToString(fMaxRange, 0, 2) + " Attacking: " + + GetName(ai_GetAttackedTarget(oEnemy))); + if(fDistance <= fMaxRange) + { + oAttacked = ai_GetAttackedTarget(oEnemy); + // If an enemy isn't attacking someone we must assume we are next! + if(oAttacked == oCreature || oAttacked == OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "2095", "Enemy attacking me: " + GetName(oEnemy) + " has attacked: " + GetName(ai_GetAttackedTarget(oEnemy))); + return oEnemy; + } + } + } + sCtr = IntToString(++nCtr); + oEnemy = GetLocalObject(oCreature, AI_ENEMY + sCtr); + } + return OBJECT_INVALID; +} +object ai_GetEnemyAttackingMyAlly(object oCreature, object oAlly, float fMaxRange = AI_RANGE_MELEE) +{ + int nCtr = 1, nIndex, nDIndex; + int bIngnoreAssociates = ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES); + float fEnemyRange, fNearestEnemyRange = fMaxRange + 1.0; + float fNearestDEnemyRange = fMaxRange + 1.0; + string sCtr = "1"; + object oAttacked; + object oEnemy = GetLocalObject(oCreature, AI_ENEMY + "1"); + while(oEnemy != OBJECT_INVALID) + { + fEnemyRange = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sCtr); + if(AI_DEBUG) ai_Debug("0i_combat", "2117", "Getting Enemy Attacking Ally:" + + GetName(oAlly) + ": " + sCtr + " InMelee:" + + GetName(oEnemy) + " fEnemyRange: " + FloatToString(fEnemyRange, 0, 2) + + " fMaxRange: " + FloatToString(fMaxRange, 0, 2) + " Attacking: " + + GetName(ai_GetAttackedTarget(oEnemy))); + if(fEnemyRange <= fMaxRange) + { + oAttacked = ai_GetAttackedTarget(oEnemy); + if(AI_DEBUG) ai_Debug("0i_combat", "2125", "Enemy attacking " + + GetName(oAlly) + ": " + GetName(oEnemy) + + " has attacked: " + GetName(ai_GetAttackedTarget(oEnemy))); + // If an enemy isn't attacking someone we must assume we are next! + if(oAttacked == oAlly) + { + // Lets put any disabled targets in its own group, if we + // ignore associates lets put them here as well. + if(GetLocalInt(oCreature, AI_ENEMY_DISABLED + sCtr) || + (bIngnoreAssociates && GetAssociateType(oEnemy))) + { + if(fEnemyRange < fNearestDEnemyRange) + { + fNearestDEnemyRange = fEnemyRange; + nDIndex = nCtr; + } + } + else if(fEnemyRange < fNearestEnemyRange) + { + fNearestEnemyRange = fEnemyRange; + nIndex = nCtr; + } + } + } + sCtr = IntToString(++nCtr); + oEnemy = GetLocalObject(oCreature, AI_ENEMY + sCtr); + } + // If we do not have a good target then lets see if there are more targets. + if(nIndex == 0 && nDIndex != 0) + { + // If we just checked within melee then lets check what we can see. + if (fMaxRange == AI_RANGE_MELEE) return ai_GetEnemyAttackingMyAlly(oCreature, oAlly, AI_RANGE_PERCEPTION); + else nIndex = nDIndex; + } + return GetLocalObject(oCreature, AI_ENEMY + IntToString(nIndex)); +} +int ai_GetNumOfEnemiesInRange(object oCreature, float fMaxRange = AI_RANGE_MELEE) +{ + int nNumOfEnemies, nCnt = 1; + float fDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + "1"); + while(fDistance != 0.0) + { + if(fDistance < fMaxRange) nNumOfEnemies ++; + fDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + IntToString(++nCnt)); + } + if(AI_DEBUG) ai_Debug("0i_combat", "2459", IntToString (nNumOfEnemies) + " enemies within " + FloatToString(fMaxRange, 0, 2) + " meters."); + return nNumOfEnemies; +} +object ai_GetAllyBuffTarget(object oCreature, int nSpell, float fMaxRange = AI_RANGE_BATTLEFIELD) +{ + // Make sure we don't over extend our movement running across the + // battlefield to cast a spell on someone does not look good. + float fNearestEnemy = GetDistanceBetween(oCreature, GetLocalObject(oCreature, AI_ENEMY_NEAREST)) - 3.0f; + // If we are in melee then extend to melee incase an ally is just past the enemy. + if(fNearestEnemy <= AI_RANGE_MELEE) fNearestEnemy = AI_RANGE_MELEE; + if(fMaxRange > fNearestEnemy) fMaxRange = fNearestEnemy; + // Now lets get the best target based on the spell data in ai_spells.2da + string sBuffTarget = Get2DAString("ai_spells", "Buff_Target", nSpell); + if(AI_DEBUG) ai_Debug("0i_combat", "2596", "sBuffTarget: " + sBuffTarget + " fMaxRange: " + FloatToString(fMaxRange, 0, 2)); + if(sBuffTarget == "0") return oCreature; + if(sBuffTarget == "1") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_STRENGTH, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "2") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_DEXTERITY, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "3") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_CONSTITUTION, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "4") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_INTELLIGENCE, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "5") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_WISDOM, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "6") + return ai_BuffHighestAbilityScoreTarget(oCreature, nSpell, ABILITY_CHARISMA, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "7") + return ai_BuffLowestACTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "8") + return ai_BuffLowestACWithOutACBonus(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "9") + return ai_BuffHighestAttackTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "10") + return ai_BuffMostWoundedTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "11") + return ai_BuffLowestFortitudeSaveTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "12") + return ai_BuffLowestReflexSaveTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "13") + return ai_BuffLowestWillSaveTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + else if(sBuffTarget == "14") + return ai_BuffLowestSaveTarget(oCreature, nSpell, "", fMaxRange, AI_ALLY); + return OBJECT_INVALID; +} + +//****************************************************************************** +//******************** OTHER COMBAT FUNCTIONS ******************************** +//****************************************************************************** + +int ai_GetCurrentRound(object oCreature) +{ + int nRound = GetLocalInt(oCreature, AI_ROUND) + 1; + SetLocalInt(oCreature, AI_ROUND, nRound); + if(AI_DEBUG) ai_Debug("0i_combat", "2471", "nRound: " + IntToString(nRound)); + return nRound; +} +int ai_GetDifficulty(object oCreature) +{ + int nAdjustment = GetLocalInt(oCreature, AI_DIFFICULTY_ADJUSTMENT); + int nDifficulty = GetLocalInt(oCreature, AI_ENEMY_POWER) - GetLocalInt(oCreature, AI_ALLY_POWER) + 13 + nAdjustment; + if(nDifficulty < 1) nDifficulty = 1; + if(AI_DEBUG) ai_Debug("0i_combat", "2474", "(Difficulty: Enemy Power: " + IntToString(GetLocalInt(oCreature, AI_ENEMY_POWER)) + + " - Ally Power: " + IntToString(GetLocalInt(oCreature, AI_ALLY_POWER)) + + ") + 13 + nAdj: " + IntToString(nAdjustment) + + " = " + IntToString(nDifficulty) + "(Min of 1)"); + return nDifficulty; +} +int ai_GetMyCombatRating(object oCreature) +{ + object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + int nAtkBonus = GetBaseAttackBonus(oCreature); + if(GetHasFeat(FEAT_WEAPON_FINESSE, oCreature) && ai_GetIsFinesseWeapon(oCreature, oWeapon)) + { + nAtkBonus += GetAbilityModifier(ABILITY_DEXTERITY, oCreature); + } + else nAtkBonus += GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(ai_GetIsMeleeWeapon(oWeapon)) nAtkBonus += ai_GetWeaponAtkBonus(oWeapon); + if(AI_DEBUG) ai_Debug("0i_combat", "2496", "GetMyCombatRating (nAtkBonus: " + IntToString(nAtkBonus) + + " nAC: " + IntToString(GetAC(oCreature)) + " - 10) / 2 = " + + IntToString((nAtkBonus + GetAC(oCreature) - 10) / 2)); + return(nAtkBonus + GetAC(oCreature) - 10) / 2; +} +object ai_GetAttackedTarget(object oCreature, int bPhysical = TRUE, int bSpell = FALSE) +{ + object oTarget = GetAttackTarget(oCreature); + if(!GetIsObjectValid(oTarget) && bPhysical) oTarget = GetLocalObject(oCreature, AI_ATTACKED_PHYSICAL); + if(!GetIsObjectValid(oTarget) && bSpell) oTarget = GetLocalObject(oCreature, AI_ATTACKED_SPELL); + if(!GetIsObjectValid(oTarget) || GetIsDead(oTarget)) return OBJECT_INVALID; + return oTarget; +} +int ai_CheckClassType(object oTarget, int nClassType) +{ + int nCnt = 1, nClass = GetClassByPosition(1, oTarget); + // We check for the group class types. + if(nClassType < 0) + { + while(nCnt <= AI_MAX_CLASSES_PER_CHARACTER) + { + int nCaster = StringToInt(Get2DAString("classes", "SpellCaster", nClass)); + if(nClassType == AI_CLASS_TYPE_WARRIOR && !nCaster) return TRUE; + else if(nClassType == AI_CLASS_TYPE_CASTER && nCaster) return TRUE; + int nSpellType = StringToInt(Get2DAString("classes", "Arcane", nClass)); + if(nClassType == AI_CLASS_TYPE_ARCANE && nSpellType) return TRUE; + else if(nClassType == AI_CLASS_TYPE_DIVINE && !nSpellType) return TRUE; + nClass = GetClassByPosition(++nCnt, oTarget); + } + } + // Checks for normal classes. + else + { + while(nCnt <= AI_MAX_CLASSES_PER_CHARACTER) + { + if(nClass == nClassType) return TRUE; + nClass = GetClassByPosition(++nCnt, oTarget); + } + } + return FALSE; +} +int ai_CheckRacialType(object oTarget, int nRacialType) +{ + int nRace = GetRacialType(oTarget); + if(nRacialType == nRace) return TRUE; + else if(nRacialType == AI_RACIAL_TYPE_ANIMAL_BEAST) + { + if(nRace == RACIAL_TYPE_ANIMAL || + nRace == RACIAL_TYPE_BEAST || + nRace == RACIAL_TYPE_MAGICAL_BEAST) return TRUE; + } + else if(nRacialType == AI_RACIAL_TYPE_HUMANOID) + { + switch (nRace) + { + case RACIAL_TYPE_DWARF : + case RACIAL_TYPE_ELF : + case RACIAL_TYPE_GNOME : + case RACIAL_TYPE_HALFELF : + case RACIAL_TYPE_HALFLING : + case RACIAL_TYPE_HALFORC : + case RACIAL_TYPE_HUMAN : + case RACIAL_TYPE_HUMANOID_GOBLINOID : + case RACIAL_TYPE_HUMANOID_MONSTROUS : + case RACIAL_TYPE_HUMANOID_ORC : + case RACIAL_TYPE_HUMANOID_REPTILIAN : + return TRUE; + } + } + return FALSE; +} +void ai_SetNormalAppearance(object oCreature) +{ + if(!ai_GetHasEffectType(oCreature, EFFECT_TYPE_POLYMORPH)) + { + int nForm = GetAppearanceType(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "2729", GetName(oCreature) + " form: " + IntToString(nForm)); + SetLocalInt(oCreature, AI_NORMAL_FORM, nForm + 1); + } +} +int ai_GetNormalAppearance(object oCreature) +{ + int nForm = GetLocalInt(oCreature, AI_NORMAL_FORM) - 1; + if(nForm == -1) + { + ai_SetNormalAppearance(oCreature); + nForm = GetLocalInt(oCreature, AI_NORMAL_FORM) - 1; + } + return nForm; +} +struct stClasses ai_GetFactionsClasses(object oCreature, int bEnemy = TRUE, float fMaxRange = AI_RANGE_BATTLEFIELD) +{ + struct stClasses sCount; + int nCnt = 1, nPosition, nClass, nLevels; + object oTarget; + if(bEnemy) oTarget = ai_GetNearestEnemy(oCreature, 1, 7, 7); + else oTarget = ai_GetNearestAlly(oCreature, 1, 7, 7); + while(oTarget != OBJECT_INVALID && GetDistanceBetween(oTarget, oCreature) <= fMaxRange) + { + for(nPosition = 1; nPosition <= AI_MAX_CLASSES_PER_CHARACTER; nPosition++) + { + nClass = GetClassByPosition(nPosition, oTarget); + nLevels = GetLevelByPosition(nPosition, oTarget); + if(nClass == CLASS_TYPE_ANIMAL || + nClass == CLASS_TYPE_BARBARIAN || + nClass == CLASS_TYPE_COMMONER || + nClass == CLASS_TYPE_CONSTRUCT || + nClass == CLASS_TYPE_ELEMENTAL || + nClass == CLASS_TYPE_FIGHTER || + nClass == CLASS_TYPE_GIANT || + nClass == CLASS_TYPE_HUMANOID || + nClass == CLASS_TYPE_MONSTROUS || + nClass == CLASS_TYPE_PALADIN || + nClass == CLASS_TYPE_RANGER || + nClass == CLASS_TYPE_ROGUE || + nClass == CLASS_TYPE_VERMIN || + nClass == CLASS_TYPE_MONK || + nClass == CLASS_TYPE_SHAPECHANGER) + { + sCount.FIGHTERS += 1; + sCount.FIGHTER_LEVELS += nLevels; + } + else if(nClass == CLASS_TYPE_CLERIC || + nClass == CLASS_TYPE_DRUID) + { + sCount.CLERICS += 1; + sCount.CLERIC_LEVELS += nLevels; + } + else if(nClass == CLASS_TYPE_BARD || + nClass == CLASS_TYPE_FEY || + nClass == CLASS_TYPE_SORCERER || + nClass == CLASS_TYPE_WIZARD) + { + sCount.MAGES += 1; + sCount.MAGE_LEVELS += nLevels; + } + else if(nClass == CLASS_TYPE_ABERRATION || + nClass == CLASS_TYPE_DRAGON || + nClass == 29 || //oozes + nClass == CLASS_TYPE_MAGICAL_BEAST || + nClass == CLASS_TYPE_OUTSIDER) + { + sCount.MONSTERS += 1; + sCount.MONSTER_LEVELS += nLevels; + } + sCount.TOTAL_LEVELS += nLevels; + } + sCount.TOTAL += 1; + if(bEnemy) oTarget = ai_GetNearestEnemy(oCreature, ++nCnt, 7, 7); + else oTarget = ai_GetNearestAlly(oCreature, ++nCnt, 7, 7); + } + if(AI_DEBUG) ai_Debug("0i_combat", "2627", "Enemy: " + IntToString(bEnemy) + " fMaxRange: " + FloatToString(fMaxRange, 0, 2) + + " CLERICS: " + IntToString(sCount.CLERICS) + "(" + IntToString(sCount.CLERIC_LEVELS) + + ") FIGHTERS: " +IntToString(sCount.FIGHTERS) + "(" + IntToString(sCount.FIGHTER_LEVELS) + + ") MAGES: " +IntToString(sCount.MAGES) + "(" + IntToString(sCount.MAGE_LEVELS) + + ") MONSTERS: " +IntToString(sCount.MONSTERS) + "(" + IntToString(sCount.MONSTER_LEVELS) + + ") TOTALS: " +IntToString(sCount.TOTAL) + "(" + IntToString(sCount.TOTAL_LEVELS)); + return sCount; +} +string ai_GetMostDangerousClass(struct stClasses stCount) +{ + string sClass; + // Lets weight the fighter levels 30% higher. + int nFighter =((stCount.FIGHTER_LEVELS) * 13)/10; + if(nFighter >= stCount.CLERIC_LEVELS) + { + if(nFighter >= stCount.MAGE_LEVELS) + { + if(nFighter >= stCount.MONSTER_LEVELS) return "FIGHTER"; + else return "MONSTER"; + } + else if(stCount.MAGE_LEVELS >= stCount.MONSTER_LEVELS) return "MAGE"; + else return "MONSTER"; + } + else if(stCount.CLERIC_LEVELS >= stCount.MAGE_LEVELS) + { + if(stCount.CLERIC_LEVELS >= stCount.MONSTER_LEVELS) return "CLERIC"; + else return "MONSTER"; + } + else if(stCount.MAGE_LEVELS >= stCount.MONSTER_LEVELS) return "MAGE"; + else return "MONSTER"; + return ""; +} +void ai_EquipBestWeapons(object oCreature, object oTarget = OBJECT_INVALID) +{ + // Lets not check for weapons on creatures that can't use them! + int nRacialType = GetRacialType(oCreature); + if(nRacialType == RACIAL_TYPE_ANIMAL || + nRacialType == RACIAL_TYPE_DRAGON || + nRacialType == RACIAL_TYPE_MAGICAL_BEAST || + nRacialType == RACIAL_TYPE_OOZE || + nRacialType == RACIAL_TYPE_VERMIN) return; + //if(Polymorphed()) return; + if(AI_DEBUG) ai_Debug("0i_combat", "2669", GetName(OBJECT_SELF) + " is equiping best weapon!"); + // Determine if I am wielding a ranged weapon, melee weapon, or none. + int bIsWieldingRanged = ai_HasRangedWeaponWithAmmo(oCreature); + int bIsWieldingMelee = ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); + if(AI_DEBUG) ai_Debug("0i_combat", "2673", "bIsWieldingRanged: " + IntToString(bIsWieldingRanged) + + " bIsWieldingMelee: " + IntToString(bIsWieldingMelee)); + // If we are hidden then change to a melee weapon so we can move in to attack. + if(ai_GetIsHidden(oCreature)) + { + // Equip a melee weapon unless we already have one. + if(!bIsWieldingMelee) ai_EquipBestMeleeWeapon(oCreature, oTarget); + return; + } + // Equip the appropriate weapon for the distance of the enemy. + int nEnemyGroup = ai_GetNumOfEnemiesInGroup(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "2684", GetName(oCreature) + " has " + IntToString(nEnemyGroup) + " enemies within 5.0f them! PointBlank: " + + IntToString(GetHasFeat(FEAT_POINT_BLANK_SHOT, oCreature))); + // We are in melee combat. + if(nEnemyGroup > 0) + { + if(bIsWieldingRanged) + { + // We have the point blank shot feat or there are more than one enemy on us. + // Note: Point Blank shot feat is bad once we have more than one enemy on us. + if(!GetHasFeat(FEAT_POINT_BLANK_SHOT, oCreature) || nEnemyGroup > 1) + { + // If I'm not using a melee weapon. + if(!bIsWieldingMelee) + { + ai_EquipBestMeleeWeapon(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "2699", GetName(oCreature) + " is equiping melee weapon due to close enemies!"); + } + } + } + } + // We are not in melee range. + else + { + if(AI_DEBUG) ai_Debug("0i_combat", "2707", GetName(oCreature) + " is not in melee combat with an enemy!"); + // If are at range with the enemy then equip a ranged weapon. + if(!bIsWieldingRanged) + { + ai_EquipBestRangedWeapon(oTarget); + // Make sure that they equiped a range weapon. + bIsWieldingRanged = ai_HasRangedWeaponWithAmmo(oCreature); + bIsWieldingMelee = ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature)); + if(AI_DEBUG) ai_Debug("0i_combat", "2719", GetName(oCreature) + " is attempting to equip a ranged weapon: " + IntToString(bIsWieldingRanged)); + // If we equiped a ranged weapon then drop out. + } + } + // We don't have a weapon out so equip one! We are in combat! + if(!bIsWieldingRanged && !bIsWieldingMelee) ai_EquipBestMeleeWeapon(OBJECT_INVALID); +} +int ai_EquipBestMeleeWeapon(object oCreature, object oTarget = OBJECT_INVALID) +{ + if(ai_GetAIMode(oCreature, AI_MODE_EQUIP_WEAPON_OFF)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_combat", "3049", GetName(oCreature) + " is equiping best melee weapon!"); + float fItemPower, fOffItemPower, fRightPower, fLeftPower, f2HandedPower; + int nItemPower, nShieldPower, nShieldValue, nItemValue, nRightValue; + int n2HandedValue, nLeftValue, bTwoWeaponUser; + int nMaxItemValue = ai_GetMaxItemValueThatCanBeEquiped(GetHitDice(oCreature)); + if(AI_DEBUG) ai_Debug("0i_combat", "3054", "nMaxItemValue: " + IntToString(nMaxItemValue)); + bTwoWeaponUser = GetHasFeat(374/*FEAT_DUAL_WIELD*/, oCreature) || GetHasFeat(FEAT_TWO_WEAPON_FIGHTING, oCreature); + object oShield = OBJECT_INVALID; + object oRight = OBJECT_INVALID; + object oLeft = OBJECT_INVALID; + object o2Handed = OBJECT_INVALID; + object o2HandedHand = OBJECT_INVALID; + object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND); + if(oRightHand != OBJECT_INVALID) + { + // Setup the item in our right hand's avg dmg and gold value as our base. + if(ai_GetIsTwoHandedWeapon(oRightHand, oCreature)) + { + if(ai_GetIsDoubleWeapon(oRightHand)) + { + f2HandedPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRightHand, TRUE, FALSE, oRightHand); + } + else f2HandedPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRightHand, TRUE); + n2HandedValue = GetGoldPieceValue(oRightHand); + if(AI_DEBUG) ai_Debug("0i_combat", "3073", " 2Handed oRightHand: " + GetName(oRightHand) + + " f2HandPower: " + FloatToString(f2HandedPower, 0, 2) + + " n2HandedValue: " + IntToString(n2HandedValue)); + } + else if(ai_GetIsSingleHandedWeapon(oRightHand, oCreature)) + { + fRightPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRightHand); + nRightValue = GetGoldPieceValue(oRightHand); + if(AI_DEBUG) ai_Debug("0i_combat", "3081", " 1Handed oRightHand: " + GetName(oRightHand) + + " fRightPower: " + FloatToString(fRightPower, 0, 2) + + " nRightValue: " + IntToString(nRightValue)); + } + } + object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature); + if(oLeftHand != OBJECT_INVALID) + { + // Setup the item in our left hand's Shield AC and gold value as our base. + if(ai_GetIsShield(oLeftHand)) + { + nShieldPower = ai_SetShieldAC(oCreature, oLeftHand); + nShieldValue = GetGoldPieceValue(oLeftHand); + if(AI_DEBUG) ai_Debug("0i_combat", "3098", " Shield oLeftHand: " + GetName(oLeftHand) + + " fShieldPower: " + IntToString(nShieldPower) + + " nShieldValue: " + IntToString(nShieldValue)); + } + // Setup the item in our left hand's avg dmg and gold value as our base. + else + { + fLeftPower = ai_GetMeleeWeaponAvgDmg(oCreature, oLeftHand, FALSE, TRUE); + nLeftValue = GetGoldPieceValue(oLeftHand); + if(AI_DEBUG) ai_Debug("0i_combat", "3103", " 1Handed oLeftHand: " + GetName(oLeftHand) + + " fLeftPower: " + FloatToString(fLeftPower, 0, 2) + + " nLeftValue: " + IntToString(nLeftValue)); + } + } + int nWeaponSize, nType, nCreatureSize = GetCreatureSize(oCreature); + // Get the best weapons they have in their inventory. + object oItem = GetFirstItemInInventory(oCreature); + // If they don't have any items then lets stop, we can't equip a weapon/shield. + if(oItem == OBJECT_INVALID) return FALSE; + while(oItem != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3114", GetName(oItem) + " MeleeWeapon: " + + IntToString(ai_GetIsMeleeWeapon(oItem)) + " Proficient: " + + IntToString(ai_GetIsProficientWith(oCreature, oItem)) + + " Identified: " + IntToString(GetIdentified(oItem))); + if(ai_GetIsProficientWith(oCreature, oItem) && + GetIdentified(oItem) && ai_CheckIfCanUseItem(oCreature, oItem)) + { + nItemValue = GetGoldPieceValue(oItem); + if(AI_DEBUG) ai_Debug("0i_combat", "3122", " nItemValue: " + IntToString(nItemValue)); + if(!GetLocalInt(GetModule(), AI_RULE_ILR) || nMaxItemValue >= nItemValue) + { + if(ai_GetIsShield(oItem)) + { + nItemPower = ai_SetShieldAC(oCreature, oItem); + if(nItemPower > nShieldPower || + (nItemPower == nShieldPower && nItemValue > nShieldValue)) + { oShield = oItem; nShieldPower = nItemPower; nShieldValue = nItemValue; } + } + else if(ai_GetIsMeleeWeapon(oItem)) + { + // Make sure the creature and weapon are close enough in size. + // Can wield a weapon up to one size larger than their size. + // Can wield a weapon down to two sizes smaller than their size. + nType = GetBaseItemType(oItem); + nWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nType)); + if(nWeaponSize >= nCreatureSize - 2 && nWeaponSize <= nCreatureSize + 1) + { + // Get item avg damage based on if it is 2handed or 1handed. + if(ai_GetIsSingleHandedWeapon(oItem, oCreature)) + { + fItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oItem); + fOffItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oItem, FALSE, TRUE); + // If the new weapon is better than the weapon in our right hand. + if(fItemPower > fRightPower || + (fItemPower == fRightPower && nItemValue > nRightValue)) + { + // We need to check if the weapon in the right hand is + // better than the weapon in the left hand since we are + // replacing our right hand weapon. + // Note: we must find out if we have selected a weapon for the + // right hand i.e. oRight or the best weapon is in our + // right hand i.e. oRightHand! + fOffItemPower = 0.0; + if(oRight != OBJECT_INVALID && ai_GetIsSingleHandedWeapon(oRight, oCreature)) + { + fOffItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRight, FALSE, TRUE); + } + else if(oRightHand != OBJECT_INVALID && ai_GetIsSingleHandedWeapon(oRightHand, oCreature)) + { + fOffItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRightHand, FALSE, TRUE); + } + // If the right hand weapon is better than the weapon in our left hand. + if(fOffItemPower > fLeftPower || (fOffItemPower > 0.0 && + fOffItemPower == fLeftPower && nRightValue > nLeftValue)) + { + if(oRight != OBJECT_INVALID) oLeft = oRight; + else oLeft = oRightHand; + fLeftPower = fOffItemPower; + nLeftValue = nRightValue; + } + oRight = oItem; + fRightPower = fItemPower; + nRightValue = nItemValue; + } + // If the new weapon is better than the weapon in our left hand. + else if(fOffItemPower > fLeftPower || + (fOffItemPower == fLeftPower && nItemValue > nLeftValue)) + { oLeft = oItem; fLeftPower = fOffItemPower; nLeftValue = nItemValue; } + } + else if(ai_GetIsTwoHandedWeapon(oItem, oCreature)) + { + if(ai_GetIsDoubleWeapon(oItem)) + { + fItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oItem, TRUE, FALSE, oItem); + } + else fItemPower = ai_GetMeleeWeaponAvgDmg(oCreature, oItem, TRUE); + // If the new weapon is better than the selected weapon. + if(fItemPower > f2HandedPower || + (fItemPower == f2HandedPower && nItemValue > n2HandedValue)) + { + o2Handed = oItem; + f2HandedPower = fItemPower; + n2HandedValue = nItemValue; + } + } + } + } + } + } + oItem = GetNextItemInInventory(); + } + if(AI_DEBUG) ai_Debug("0i_combat", "3197", "oRight: " + GetName(oRight) + " oLeft:" + + GetName(oLeft) + " oShield: " + GetName(oShield) + + "o2Handed: " + GetName(o2Handed)); + // First check for two weapons first. + if(bTwoWeaponUser && oRight != OBJECT_INVALID && oLeft != OBJECT_INVALID) + { + fRightPower = ai_GetMeleeWeaponAvgDmg(oCreature, oRight, FALSE, FALSE, oLeft); + fRightPower += ai_GetMeleeWeaponAvgDmg(oCreature, oLeft, FALSE, TRUE); + if(AI_DEBUG) ai_Debug("0i_combat", "3205", " Right/Left Power: " + + FloatToString(fRightPower, 0, 2) + " 2HandedPower: " + + FloatToString(f2HandedPower, 0, 2)); + if(fRightPower > f2HandedPower) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3210", GetName(oCreature) + " is equiping " + + GetName(oRight) + " in the right hand and " + GetName(oLeft) + + " in the left hand."); + ActionEquipItem(oRight, INVENTORY_SLOT_RIGHTHAND); + ActionEquipItem(oLeft, INVENTORY_SLOT_LEFTHAND); + return TRUE; + } + } + if(f2HandedPower > fRightPower && o2Handed != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3220", GetName(oCreature) + " is equiping " + + GetName(o2Handed) + " in both hands."); + ActionEquipItem(o2Handed, INVENTORY_SLOT_RIGHTHAND); + return TRUE; + } + // Now lets just equip the best weapon for the right hand. + if(oRight != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3228", GetName(oCreature) + " is equiping " + + GetName(oRight) + " in the right hand. "); + ActionEquipItem(oRight, INVENTORY_SLOT_RIGHTHAND); + } + // Make sure we are not equiping a 2handed weapon and + // If not can we equip a shield? + if((oRight == OBJECT_INVALID || ai_GetIsSingleHandedWeapon(oRight, oCreature) || + !ai_GetIsTwoHandedWeapon(oRightHand, oCreature)) && + oShield != OBJECT_INVALID && GetHasFeat(FEAT_SHIELD_PROFICIENCY, oCreature)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3238", GetName(oCreature) + " is equiping " + + GetName(oShield) + " in the left hand."); + ActionEquipItem(oShield, INVENTORY_SLOT_LEFTHAND); + return TRUE; + } + // Finally if we don't have a weapon to equip so check to see if we are + // holding a bow. + else if(oRight == OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3247", GetName(oCreature) + " did not equip a melee weapon"); + // We couldn't find a melee weapon but we are looking to go into melee + // I'm holding a ranged weapon! We better put it up. + if(GetWeaponRanged(oRightHand)) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3252", GetName(oCreature) + " is unequiping " + GetName(oRightHand)); + ActionUnequipItem(oRightHand); + return TRUE; + } + } + if(AI_DEBUG) ai_Debug("0i_combat", "3257", GetName(oCreature) + " is not equiping a weapon!"); + return FALSE; +} +int ai_EquipBestRangedWeapon(object oCreature, object oTarget = OBJECT_INVALID) +{ + if(ai_GetAIMode(oCreature, AI_MODE_EQUIP_WEAPON_OFF)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_combat", "3267", GetName(oCreature) + " is looking for best ranged weapon!"); + int nAmmo, nAmmoSlot, nBestType1, nBestType2, nType, nFeat, nItemValue, nRangedValue; + int nMaxItemValue = ai_GetMaxItemValueThatCanBeEquiped(GetHitDice(oCreature)); + string sAmmo; + object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + if(oRightHand != OBJECT_INVALID && ai_GetIsRangeWeapon(oRightHand)) + { + // Setup the item in our right hand as our base gold value to check against. + if(ai_GetIsRangeWeapon(oRightHand)) nRangedValue = GetGoldPieceValue(oRightHand); + } + object oRanged = OBJECT_INVALID, oAmmo = OBJECT_INVALID; + // Find the best type of ranged weapon for this player. + if(GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oCreature)) + { nBestType1 = BASE_ITEM_LONGBOW; nAmmo = BASE_ITEM_ARROW; nAmmoSlot = INVENTORY_SLOT_ARROWS; sAmmo = "arrow";} + else if(GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oCreature)) + { nBestType1 = BASE_ITEM_SHORTBOW; nAmmo = BASE_ITEM_ARROW; nAmmoSlot = INVENTORY_SLOT_ARROWS; sAmmo = "arrow";} + else if(GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oCreature)) + { nBestType1 = BASE_ITEM_HEAVYCROSSBOW; nAmmo = BASE_ITEM_BOLT; nAmmoSlot = INVENTORY_SLOT_BOLTS; sAmmo = "bolt";} + else if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oCreature)) + { nBestType1 = BASE_ITEM_LIGHTCROSSBOW; nAmmo = BASE_ITEM_BOLT; nAmmoSlot = INVENTORY_SLOT_BOLTS; sAmmo = "bolt";} + else if(GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oCreature)) + { nBestType1 = BASE_ITEM_SLING; nAmmo = BASE_ITEM_BULLET; nAmmoSlot = INVENTORY_SLOT_BULLETS; sAmmo = "bullet";} + else if(GetHasFeat(FEAT_WEAPON_FOCUS_DART, oCreature)) + { nBestType1 = BASE_ITEM_DART; } + else if(GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN, oCreature)) + { nBestType1 = BASE_ITEM_SHURIKEN; } + else if(GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE, oCreature)) + { nBestType1 = BASE_ITEM_THROWINGAXE; } + // These feats require a bow. + else if(GetHasFeat(FEAT_RAPID_SHOT, oCreature)) + { nBestType1 = BASE_ITEM_LONGBOW; nBestType2 = BASE_ITEM_SHORTBOW; + nAmmo = BASE_ITEM_ARROW; nAmmoSlot = INVENTORY_SLOT_ARROWS; sAmmo = "arrow"; } + // This feat requires a xbow. + else if(GetHasFeat(FEAT_RAPID_RELOAD, oCreature)) + { nBestType1 = BASE_ITEM_HEAVYCROSSBOW; nBestType2 = BASE_ITEM_LIGHTCROSSBOW; + nAmmo = BASE_ITEM_BOLT; nAmmoSlot = INVENTORY_SLOT_BOLTS; sAmmo = "bolt"; } + if(AI_DEBUG) ai_Debug("0i_combat", "3262", "nBestType1: " + IntToString(nBestType1) + " nBestType2: " + IntToString(nBestType2) + + " nAmmo: " + IntToString(nAmmo)); + int nCreatureSize = GetCreatureSize(oCreature) + 1; + // Cycle through the inventory looking for a ranged weapon. + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + nType = GetBaseItemType(oItem); + if(AI_DEBUG) ai_Debug("0i_combat", "3269", "oItem: " + GetName(oItem) + + " Identified: " + IntToString(GetIdentified(oItem)) + + " Ranged Weapon: " + Get2DAString("baseitems", "RangedWeapon", nType)); + // Make sure it is identified and it is a ranged weapon. + if(GetIdentified(oItem) && Get2DAString("baseitems", "RangedWeapon", nType) != "") + { + if(AI_DEBUG) ai_Debug("0i_combat", "3278", " Proficient: " + + IntToString(ai_GetIsProficientWith(oCreature, oItem)) + + " nMaxItemValue: " + IntToString(nMaxItemValue)); + if(ai_GetIsProficientWith(oCreature, oItem)) + { + if(ai_CheckIfCanUseItem(oCreature, oItem)) + { + nItemValue = GetGoldPieceValue(oItem); + if(AI_DEBUG) ai_Debug("0i_combat", "3284", "nItemValue: " + IntToString(nItemValue)); + if(!GetLocalInt(GetModule(), AI_RULE_ILR) || nMaxItemValue >= nItemValue) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3287", " Creature Size: " + IntToString(nCreatureSize) + + " Weapon Size: " + Get2DAString("baseitems", "WeaponSize", nType)); + // Make sure they are large enough to use it. + if(StringToInt(Get2DAString("baseitems", "WeaponSize", nType)) <= nCreatureSize) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3292", "nItemValue: " + IntToString(nItemValue) + + " nRangedValue: " + IntToString(nRangedValue) + " nType: " + IntToString(nType)); + // Is it of the best range weapon type? 0 is any range weapon. + // Also grab any range weapon until we have a best type. + if(nType == nBestType1 || nType == nBestType2 || + nBestType1 == 0 || oRanged == OBJECT_INVALID) + { + if(nItemValue > nRangedValue) + { + if(ai_GetHasItemProperty(oItem, ITEM_PROPERTY_UNLIMITED_AMMUNITION)) + { + oRanged = oItem; nRangedValue = nItemValue; + if(AI_DEBUG) ai_Debug("0i_combat", "3304", "Selecting oRanged: " + GetName(oRanged) + + " nRangedValue: " + IntToString(nRangedValue) + " and doesn't need ammo!"); + } + else + { + if(nBestType1 == 0) + { + if(nType == BASE_ITEM_LONGBOW || nType == BASE_ITEM_SHORTBOW) + { nAmmo = BASE_ITEM_ARROW; sAmmo = "arrow"; nAmmoSlot = INVENTORY_SLOT_ARROWS; } + else if(nType == BASE_ITEM_HEAVYCROSSBOW || nType == BASE_ITEM_LIGHTCROSSBOW) + { nAmmo = BASE_ITEM_BOLT; sAmmo = "bolt"; nAmmoSlot = INVENTORY_SLOT_BOLTS; } + else if(nType == BASE_ITEM_SLING) + { nAmmo = BASE_ITEM_BULLET; sAmmo = "bullet"; nAmmoSlot = INVENTORY_SLOT_BULLETS; } + else nAmmo = 0; + } + // Now do we have ammo for it? + if(AI_DEBUG) ai_Debug("0i_combat", "3320", "nAmmo: " + IntToString(nAmmo)); + if(nAmmo > 0) + { + if(nAmmo == BASE_ITEM_ARROW || + nAmmo == BASE_ITEM_BOLT || + nAmmo == BASE_ITEM_BULLET) oAmmo = GetItemInSlot(nAmmoSlot); + if(oAmmo == OBJECT_INVALID) + { + // We don't have ammo equiped so lets see if we have any in our inventory. + oAmmo = GetFirstItemInInventory(); + while(oAmmo != OBJECT_INVALID) + { + if(GetBaseItemType(oAmmo) == nAmmo) break; + oAmmo = GetNextItemInInventory(); + } + if(oAmmo != OBJECT_INVALID) ActionEquipItem(oAmmo, nAmmoSlot); + } + } + if(oAmmo != OBJECT_INVALID) + { + oRanged = oItem; nRangedValue = nItemValue; + if(AI_DEBUG) ai_Debug("0i_combat", "3307", "Selecting oRanged: " + GetName(oRanged) + + " nRangedValue: " + IntToString(nRangedValue)); + } + } + } + } + } + } + } + } + } + oItem = GetNextItemInInventory(oCreature); + } + // They don't have a range weapon so lets break out. + if(oRanged == OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3357", GetName(oCreature) + " did not equip a ranged weapon!"); + return FALSE; + } + ActionEquipItem(oRanged, INVENTORY_SLOT_RIGHTHAND); + return TRUE; +} +int ai_EquipBestMonkMeleeWeapon(object oCreature, object oTarget = OBJECT_INVALID) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "2949", GetName(OBJECT_SELF) + " is equiping best monk melee weapon!"); + int nValue, nRightValue; + int nMaxItemValue = ai_GetMaxItemValueThatCanBeEquiped(GetHitDice(oCreature)); + object oRight = OBJECT_INVALID; + object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + if(oRightHand != OBJECT_INVALID) + { + nRightValue = GetGoldPieceValue(oRightHand); + } + // Get the best kama they have in their inventory. + object oItem = GetFirstItemInInventory(oCreature); + // If they don't have any kamas then lets stop, we can't equip a weapon. + if(oItem == OBJECT_INVALID) return FALSE; + while(oItem != OBJECT_INVALID) + { + nValue = GetGoldPieceValue(oItem); + // Make sure they are high enough level to equip this item. + if(nMaxItemValue >= nValue && nValue > 1) + { + // Is it a single handed weapon? + if(GetBaseItemType(oItem) == BASE_ITEM_KAMA) + { + // Replace the lowest value right weapon. + if(nValue > nRightValue) + { + oRight = oItem; nRightValue = nValue; + } + } + } + oItem = GetNextItemInInventory(oCreature); + } + // Finally lets just equip the kama if we have one. + if(oRight == OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "2983", GetName(oCreature) + " did not equip a melee weapon!"); + return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_combat", "2986", GetName(oCreature) + " is equiping " + GetName(oRight) + " in the right hand."); + ActionEquipItem(oRight, INVENTORY_SLOT_RIGHTHAND); + return TRUE; +} +int ai_IsInADangerousAOE(object oCreature, float fMaxRange = AI_RANGE_BATTLEFIELD, int bMove = FALSE) +{ + int bDangerous, nSpell, nCnt = 1; + string sAOEType; + object oAOE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCreature, nCnt); + float fRadius, fDistance = GetDistanceBetween(oCreature, oAOE); + while(oAOE != OBJECT_INVALID && fDistance <= fMaxRange) + { + // AOE's have the tag set to the "LABEL" in vfx_persistent.2da + // I check vs those labels to see if the AOE is offensive. + // Below is the list of Offensive AOE effects. + sAOEType = GetTag(oAOE); + if(sAOEType == "VFX_PER_WEB") { fRadius = 6.7; nSpell = SPELL_WEB; } + else if(sAOEType == "VFX_PER_ENTANGLE") { fRadius = 5.0; nSpell = SPELL_ENTANGLE; } + else if(sAOEType == "VFX_PER_GREASE") { fRadius = 6.0; nSpell = SPELL_GREASE; } + else if(sAOEType == "VFX_PER_EVARDS_BLACK_TENTACLES") + { fRadius = 5.0; nSpell = SPELL_EVARDS_BLACK_TENTACLES; } + //else if(sAOEType == "VFX_PER_DARKNESS") { fRadius = 6.7; nSpell = SPELL_DARKNESS; } + //else if(sAOEType == "VFX_MOB_SILENCE") { fRadius = 4.0; nSpell = SPELL_SILENCE; } + else if(sAOEType == "VFX_PER_FOGSTINK") { fRadius = 6.7; nSpell = SPELL_STINKING_CLOUD; } + else if(sAOEType == "VFX_PER_FOGFIRE") { fRadius = 5.0; nSpell = SPELL_INCENDIARY_CLOUD; } + else if(sAOEType == "VFX_PER_FOGKILL") { fRadius = 5.0; nSpell = SPELL_CLOUDKILL; } + else if(sAOEType == "VFX_PER_FOGMIND") { fRadius = 5.0; nSpell = SPELL_MIND_FOG; } + else if(sAOEType == "VFX_PER_CREEPING_DOOM") { fRadius = 6.7; nSpell = SPELL_CREEPING_DOOM; } + else if(sAOEType == "VFX_PER_FOGACID") { fRadius = 5.0; nSpell = SPELL_ACID_FOG; } + else if(sAOEType == "VFX_PER_FOGBEWILDERMENT") { fRadius = 5.0; nSpell = SPELL_CLOUD_OF_BEWILDERMENT; } + else if(sAOEType == "VFX_PER_WALLFIRE") { fRadius = 10.0; nSpell = SPELL_WALL_OF_FIRE; } + else if(sAOEType == "VFX_PER_WALLBLADE") { fRadius = 10.0; nSpell = SPELL_BLADE_BARRIER; } + else if(sAOEType == "VFX_PER_DELAY_BLAST_FIREBALL") { fRadius = 2.0; nSpell = SPELL_DELAYED_BLAST_FIREBALL; } + else if(sAOEType == "VFX_PER_GLYPH") { fRadius = 2.5; nSpell = SPELL_GLYPH_OF_WARDING; } + else fRadius = 0.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3088", GetName(oCreature) + " distance from AOE is " + FloatToString(fDistance, 0, 2) + + " AOE Radius: " + FloatToString(fRadius, 0, 2) + + " AOE Type: " + GetTag(oAOE)); + // fRadius > 0.0 keeps them from tiggering that they are in a dangerous + // AOE due to having an AOE on them. + if(fRadius > 0.0 && fDistance <= fRadius && + !ai_CreatureImmuneToEffect(GetAreaOfEffectCreator(oAOE), oCreature, nSpell)) + { + bDangerous = TRUE; + if(nSpell == SPELL_WEB || nSpell == SPELL_ENTANGLE) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) bDangerous = FALSE; + if(GetReflexSavingThrow(oCreature) + GetAbilityModifier(ABILITY_DEXTERITY, oCreature) >= ai_GetCharacterLevels(oCreature)) + bDangerous = FALSE; + } + break; + } + oAOE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCreature, ++nCnt); + fDistance = GetDistanceBetween(oCreature, oAOE); + } + if(bDangerous && bMove) + { + location lLocation; + object oTarget; + if(ai_GetIsInCombat(oCreature)) + { + object oMaster = GetMaster(oCreature); + // If we have a ranged weapon then backout and use that. + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + lLocation = GetRandomLocation(GetArea(oCreature), oCreature, fRadius + 1.0); + } + else // we must find a target out of the AOE or fight in the AOE. + { + oTarget = ai_GetNearestTargetNotInAOE(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, TRUE); + if(oTarget != OBJECT_INVALID) lLocation = GetLocation(oTarget); + } + } + else lLocation = GetRandomLocation(GetArea(oCreature), oCreature, fRadius + 1.0); + ai_ClearCreatureActions(); + if(AI_DEBUG) ai_Debug("0i_combat", "3035", GetName(oCreature) + " is moving out of area of effect!"); + ActionMoveToLocation(lLocation, TRUE); + return TRUE; + } + else if(bDangerous) return TRUE; + return FALSE; +} +int ai_GetIsHidden(object oHidden) +{ + int nEffectType; + effect eEffect = GetFirstEffect(oHidden); + while(GetIsEffectValid(eEffect)) + { + nEffectType = GetEffectType(eEffect); + if(nEffectType == EFFECT_TYPE_INVISIBILITY) return 1; + else if(nEffectType == EFFECT_TYPE_IMPROVEDINVISIBILITY) return 1; + else if(nEffectType == EFFECT_TYPE_DARKNESS) return 2; + else if(nEffectType == EFFECT_TYPE_SANCTUARY) return 3; + else if(nEffectType == EFFECT_TYPE_ETHEREAL) return 3; + eEffect = GetNextEffect(oHidden); + } + if(GetActionMode(oHidden, ACTION_MODE_STEALTH)) return 4; + return FALSE; +} +int ai_CastOffensiveSpellVsTarget(object oCaster, object oCreature, int nSpell) +{ + // Check saves. + string sSave = Get2DAString("ai_spells", "SaveType", nSpell); + // There is no save! + if(sSave == "") return TRUE; + // Get the level of the spell. + int nSpellLvl = StringToInt(Get2DAString("spells", "Innate", nSpell)); + // Randomize our check. + nSpellLvl += Random(AI_SPELL_CHECK_DIE) + AI_SPELL_CHECK_BONUS; + // Check feats that might increase our DC. + string sSchool = Get2DAString("spells", "School", nSpell); + if(sSchool == "V") + { + if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_EVOCATION, oCaster)) nSpellLvl += 4; + else if(GetHasFeat(FEAT_SPELL_FOCUS_EVOCATION, oCaster)) nSpellLvl += 2; + } + else if(sSchool == "C") + { + if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_CONJURATION, oCaster)) nSpellLvl += 4; + else if(GetHasFeat(FEAT_SPELL_FOCUS_CONJURATION, oCaster)) nSpellLvl += 2; + } + else if(sSchool == "N") + { + if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_NECROMANCY, oCaster)) nSpellLvl += 4; + else if(GetHasFeat(FEAT_SPELL_FOCUS_NECROMANCY, oCaster)) nSpellLvl += 2; + } + else if(sSchool == "E") + { + if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_ENCHANTMENT, oCaster)) nSpellLvl += 4; + else if(GetHasFeat(FEAT_SPELL_FOCUS_ENCHANTMENT, oCaster)) nSpellLvl += 2; + } + else if(sSchool == "I") + { + if(GetHasFeat(FEAT_GREATER_SPELL_FOCUS_ILLUSION, oCaster)) nSpellLvl += 4; + else if(GetHasFeat(FEAT_SPELL_FOCUS_ILLUSION, oCaster)) nSpellLvl += 2; + } + else if(sSave == "Reflex") + { + string sImmunityType = Get2DAString("ai_spells", "ImmunityType", nSpell); + // Give a bonus to our check for half dmg spells unless they can dodge it! + if((sImmunityType == "Fire" || sImmunityType == "Electricity" || sImmunityType == "Acid" || + sImmunityType == "Cold" || sImmunityType == "Sonic") && + !GetHasFeat(FEAT_IMPROVED_EVASION, oCreature)) nSpellLvl += AI_SPELL_CHECK_NO_EVASION_BONUS; + if(AI_DEBUG) ai_Debug("0i_combat", "3050", " nSpellLvl: " + IntToString(nSpellLvl) + + " > nMagic: " + IntToString(GetReflexSavingThrow(oCreature))); + return (nSpellLvl > GetReflexSavingThrow(oCreature)); + } + else if(sSave == "Fortitude") return (nSpellLvl > GetFortitudeSavingThrow(oCreature)); + else if(sSave == "Will") return (nSpellLvl > GetWillSavingThrow(oCreature)); + return TRUE; +} +int ai_GetDragonDC(object oCreature) +{ + int nDC, nHitDice = GetHitDice(oCreature); + if(nHitDice < 4) { nDC = 12; } + else if(nHitDice < 7) { nDC = 13; } + else if(nHitDice < 10) { nDC = 14; } + else if(nHitDice < 13) { nDC = 16; } + else if(nHitDice < 16) { nDC = 18; } + else if(nHitDice < 19) { nDC = 20; } + else if(nHitDice < 22) { nDC = 22; } + else if(nHitDice < 25) { nDC = 24; } + else if(nHitDice < 28) { nDC = 26; } + else if(nHitDice < 31) { nDC = 28; } + else if(nHitDice < 34) { nDC = 30; } + else if(nHitDice < 37) { nDC = 32; } + else if(nHitDice < 39) { nDC = 34; } + else { nDC = 36; } + string sTag = GetTag(oCreature); + if(sTag == "gold_dragon") nDC += 5; + if(sTag == "red_dragon" || sTag == "silver_dragon") return nDC + 4; + else if(sTag == "black_dragon" || sTag == "brass_dragon") return nDC + 3; + else if(sTag == "green_dragon" || sTag == "copper_dragon") return nDC + 2; + else if(sTag == "blue_dragon" || sTag == "bronze_dragon") return nDC + 1; + //else if(sTag == "white_dragon") nDC += 0; + return nDC; +} +void ai_SetCreatureAIScript(object oCreature) +{ + string sCombatAI = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + // Non-Hostile NPC's do not need to use special tactics by default. + if(sCombatAI == "" && GetLocalInt(GetModule(), AI_RULE_AMBUSH) && d100() < 34) + { + // They should have skill ranks equal to their level + 1 to use a special AI. + int nSkillNeeded = GetHitDice(oCreature) + 1; + /*/ Ambusher: requires either Improved Invisibility or Invisibility. + if(GetHasSpell(SPELL_IMPROVED_INVISIBILITY, oCreature) || + GetHasSpell(SPELL_INVISIBILITY, oCreature)) + { + int bCast = ai_TryToCastSpell(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature); + if(!bCast) bCast = ai_TryToCastSpell(oCreature, SPELL_INVISIBILITY, oCreature); + if(bCast) sCombatAI = "ai_ambusher"; + } */ + if(GetHasFeat(FEAT_SNEAK_ATTACK, oCreature, TRUE)) + { + sCombatAI = "ai_flanker"; + } + // Ambusher: Requires a Hide and Move silently skill equal to your level + 1. + else if(GetSkillRank(SKILL_HIDE, oCreature) >= nSkillNeeded && + GetSkillRank(SKILL_MOVE_SILENTLY, oCreature) >= nSkillNeeded) + { + sCombatAI = "ai_ambusher"; + } + // Defensive : requires Parry skill equal to your level or Expertise. + else if(GetSkillRank(SKILL_PARRY, oCreature) >= nSkillNeeded || + GetHasFeat(FEAT_EXPERTISE, oCreature) || + GetHasFeat(FEAT_IMPROVED_EXPERTISE, oCreature)) + { + sCombatAI = "ai_defensive"; + } + else if(GetHasSpell(SPELL_LESSER_DISPEL, oCreature) || + GetHasSpell(SPELL_DISPEL_MAGIC, oCreature) || GetHasSpell(SPELL_GREATER_DISPELLING, oCreature)) + { + sCombatAI = "ai_cntrspell"; + } + else if(ai_CheckClassType(oCreature, AI_CLASS_TYPE_ARCANE) && + ai_GetCharacterLevels(oCreature) > 4) sCombatAI = "ai_ranged"; + else if(ai_EquipBestRangedWeapon(oCreature)) sCombatAI = "ai_ranged"; + else if(GetSkillRank(SKILL_TAUNT, oCreature) >= nSkillNeeded) sCombatAI = "ai_taunter"; + } + if(sCombatAI == "") + { + int nAssociateType = GetAssociateType(oCreature); + if (nAssociateType == ASSOCIATE_TYPE_FAMILIAR) + { + sCombatAI = "ai_default"; + } + else + { + // Select the best ai for this henchmen based on class. + int nClass = GetClassByPosition(1, oCreature); + // If they have more than one class use the default ai. + if(GetClassByPosition(2, oCreature) != CLASS_TYPE_INVALID) sCombatAI = "ai_default"; + else if(nClass == CLASS_TYPE_BARBARIAN) sCombatAI = "ai_barbarian"; + else if(nClass == CLASS_TYPE_BARD) sCombatAI = "ai_bard"; + else if(nClass == CLASS_TYPE_CLERIC) sCombatAI = "ai_cleric"; + else if(nClass == CLASS_TYPE_DRUID) sCombatAI = "ai_druid"; + else if(nClass == CLASS_TYPE_FIGHTER) sCombatAI = "ai_fighter"; + else if(nClass == CLASS_TYPE_MONK) sCombatAI = "ai_monk"; + else if(nClass == CLASS_TYPE_PALADIN) sCombatAI = "ai_paladin"; + else if(nClass == CLASS_TYPE_RANGER) sCombatAI = "ai_ranger"; + else if(nClass == CLASS_TYPE_ROGUE) sCombatAI = "ai_rogue"; + else if(nClass == CLASS_TYPE_SORCERER) sCombatAI = "ai_sorcerer"; + else if(nClass == CLASS_TYPE_WIZARD) sCombatAI = "ai_wizard"; + //else if(nClass == CLASS_TYPE_ABERRATION) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_ANIMAL) sCombatAI = "ai_animal"; + //else if(nClass == CLASS_TYPE_CONSTRUCT) sCombatAI = "ai_animal"; + else if(nClass == CLASS_TYPE_DRAGON) sCombatAI = "ai_dragon"; + //else if(nClass == CLASS_TYPE_ELEMENTAL) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_FEY) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_GIANT) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_HUMANOID) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_MAGICAL_BEAST) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_MONSTROUS) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_OOZE) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_OUTSIDER) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_UNDEAD) sCombatAI = "ai_default"; + //else if(nClass == CLASS_TYPE_VERMIN) sCombatAI = "ai_animal"; + else sCombatAI = "ai_default"; + } + } + if(AI_DEBUG) ai_Debug("0i_combat", "3740", GetName(oCreature) + " is setting AI to " + sCombatAI); + SetLocalString(oCreature, AI_DEFAULT_SCRIPT, sCombatAI); + SetLocalString(oCreature, AI_COMBAT_SCRIPT, sCombatAI); +} +int ai_IsImmuneToSneakAttacks(object oCreature, object oTarget) +{ + if(GetHasFeat(FEAT_UNCANNY_DODGE_2, oTarget) && + GetLevelByClass(CLASS_TYPE_ROGUE, oCreature) + 3 < GetLevelByClass(CLASS_TYPE_ROGUE, oTarget)) return TRUE; + if(GetIsImmune(oTarget, IMMUNITY_TYPE_SNEAK_ATTACK)) return TRUE; + object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTarget); + if(ai_GetHasItemProperty(oSkin, ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS, IP_CONST_IMMUNITYMISC_BACKSTAB)) return TRUE; + return FALSE; +} +int ai_IsStrongerThanMe(object oCreature, int nIndex) +{ + int nEnemyCombat = GetLocalInt(oCreature, AI_ENEMY_COMBAT + IntToString(nIndex)); + int nCreatureCombat = ai_GetMyCombatRating(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "3955", "IsStrongerThanMe: nCreatureCombat: " + + IntToString(nCreatureCombat) + " nEnemyCombat: " + IntToString(nEnemyCombat)); + return (nEnemyCombat > nCreatureCombat); +} +int ai_StrongOpponent(object oCreature, object oTarget, int nAdj = 2) +{ + int nLevel = GetHitDice(oCreature); + if(AI_DEBUG) ai_Debug("0i_combat", "3220", "ai_StrongOpponent"); + nAdj = nAdj *((nAdj + nLevel) / 10); + if(AI_DEBUG) ai_Debug("0i_combat", "3222", "Is the opponent strong? Target CR >= Our level - nAdj(" + + FloatToString(GetChallengeRating(oTarget), 0, 2) + " >= " + IntToString(nLevel - nAdj) + ")"); + return (FloatToInt(GetChallengeRating(oTarget)) >= nLevel - nAdj); +} +int ai_PowerAttackGood(object oCreature, object oTarget, float fAdj) +{ + int nAvgDmg = ai_GetWeaponDamage(oCreature, 2); + if(AI_DEBUG) ai_Debug("0i_combat", "3412", "PowerAttack: (nAvgDmg: " + IntToString(nAvgDmg) + + " > Target HP: " + IntToString(GetCurrentHitPoints(oTarget)) + + ") Skip: " + IntToString(nAvgDmg > GetCurrentHitPoints(oTarget))); + if(nAvgDmg > GetCurrentHitPoints(oTarget)) return FALSE; + float fAvgDmg = IntToFloat(nAvgDmg); + float fTargetAC = IntToFloat(GetAC(oTarget)); + float fCreatureAtk = IntToFloat(ai_GetCreatureAttackBonus(oCreature)); + float fNormalChance = (21.0 - (fTargetAC - fCreatureAtk)) / 20.0; + // Our chance to hit is already minimum of 5% so this doesn't hurt our chance! + if(fNormalChance <= 0.05) return TRUE; + float fAdjDamage = (fAvgDmg + fAdj) * ((21.0-(fTargetAC - fCreatureAtk + fAdj))/20); + if(AI_DEBUG) ai_Debug("0i_combat", "3420", "fNormalDamage: " + FloatToString(fNormalChance * fAvgDmg, 0, 2) + + " < fAdjDamage: " + FloatToString(fAdjDamage, 0, 2) + " = " + IntToString(fNormalChance * fAvgDmg < fAdjDamage)); + return fNormalChance * fAvgDmg < fAdjDamage; +} +int ai_AttackPenaltyOk(object oCreature, object oTarget, float fAtkAdj) +{ + float fTargetAC = IntToFloat(GetAC(oTarget)); + float fCreatureAtk = IntToFloat(ai_GetCreatureAttackBonus(oCreature)); + float fNormalChance = (21.0-(fTargetAC - fCreatureAtk))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3431", "Normal Avg Chance: " + FloatToString(fNormalChance, 0, 2) + " <= 0.05"); + // We already need a 20 to hit so this doesn't hurt our chances! + if(fNormalChance <= 0.05) return TRUE; + float fAdjChance = (21.0-(fTargetAC - fCreatureAtk + fAtkAdj))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3435", "Adjusted Avg Chance: " + FloatToString(fAdjChance, 0, 2) + " > 0.55"); + // if our chance is 55% or better to hit then use it. + return fAdjChance > 0.55; +} +int ai_AttackBonusGood(object oCreature, object oTarget, float fAtkAdj) +{ + float fTargetAC = IntToFloat(GetAC(oTarget)); + float fCreatureAtk = IntToFloat(ai_GetCreatureAttackBonus(oCreature)); + float fNormalChance = (21.0-(fTargetAC - fCreatureAtk))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3450", "Normal Avg Chance: " + FloatToString(fNormalChance, 0, 2) + " > 0.99"); + // We already hit them with any roll so this will not help. + if(fNormalChance > 0.99) return FALSE; + float fAdjChance = (21.0-(fTargetAC - fCreatureAtk - fAtkAdj))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3454", "Adjusted Avg Chance: " + FloatToString(fAdjChance, 0, 2) + " < 0.0"); + // if our chance increases our to hit then this is good. + return fAdjChance > 0.0; +} +int ai_ACAdjustmentGood(object oCreature, object oTarget, float fACAdj) +{ + float fCreatureAC = IntToFloat(GetAC(oCreature)); + float fTargetAtk = IntToFloat(ai_GetCreatureAttackBonus(oTarget)); + float fNormalChance = (21.0-(fCreatureAC - fTargetAtk))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3444", "Normal Chance To Hit: " + FloatToString(fNormalChance, 0, 2) + " <= 0.05"); + // They already need a 20 to hit so adding more AC is worthless. + if(fNormalChance <= 0.05) return FALSE; + float fAdjChance = (21.0-(fCreatureAC - fTargetAtk + fACAdj))/20.0; + if(AI_DEBUG) ai_Debug("0i_combat", "3448", "Adjusted Chance To Hit: " + FloatToString(fAdjChance, 0, 2) + " < 1.00"); + // Anything less than 1 helps are AC! + return fAdjChance < 1.00; +} +int ai_CanIMoveInCombat(object oCreature) +{ + // DC 15 tumble check is required to not give attacks of opportunity. + return (GetHasFeat(FEAT_MOBILITY, oCreature) || GetHasFeat(FEAT_SPRING_ATTACK, oCreature) || + GetSkillRank(SKILL_TUMBLE, oCreature) > 9); +} +int ai_CanIUseRangedWeapon(object oCreature, int nInMelee) +{ + return (!nInMelee || ai_GetEnemyAttackingMe(oCreature) == OBJECT_INVALID); +} +int ai_CheckRangedCombatPosition(object oCreature, object oTarget, int nAction) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "3559", "Ranged attack: See oTarget? " + + IntToString(GetObjectSeen(oTarget, oCreature)) + " Line of Sight? " + + IntToString(LineOfSightObject(oCreature, oTarget))); + if(nAction == AI_LAST_ACTION_RANGED_ATK) + { + // Watch the nearest enemy instead of our target as they could move toward us. + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + float fDistance = GetDistanceBetween(oCreature, oNearestEnemy); + if(AI_DEBUG) ai_Debug("0i_combat", "3337", "oNearestEnemy: " + GetName(oNearestEnemy) + + " fDistance: " + FloatToString(fDistance, 0, 2)); + // If we have sneak attack then we want to be within 30'. + if(GetHasFeat(FEAT_SNEAK_ATTACK, oCreature)) + { + if(fDistance > AI_RANGE_CLOSE) + { + // We check this because if the enemy is moving or has not + // started acting then we don't want to move up on them as they + // might move towards us. Just attack! Only sneak attack if they are busy. + int nAction = GetCurrentAction(oNearestEnemy); + if(AI_DEBUG) ai_Debug("0i_combat", "3353", GetName(oNearestEnemy) + " current action: " + IntToString(nAction)); + if(nAction == ACTION_MOVETOPOINT || + nAction == ACTION_INVALID || + nAction == ACTION_RANDOMWALK) return FALSE; + // If they are attacking make sure it is in melee? + // If not then don't move since they might be moving toward us. + if(nAction == ACTION_ATTACKOBJECT) + { + if(!ai_GetNumOfEnemiesInRange(oNearestEnemy)) return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_combat", "3355", GetName(oCreature) + " is moving closer [8.0] to " + + GetName(oNearestEnemy) + " to sneak attack with a ranged weapon."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + ActionMoveToObject(oNearestEnemy, TRUE, AI_RANGE_CLOSE); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + } + else if(fDistance < AI_RANGE_LONG) + { + // Lets move back a little, too far and we miss attacks! + if(AI_DEBUG) ai_Debug("0i_combat", "3374", GetName(oCreature) + " is moving away from " + + GetName(oNearestEnemy) + "[2.0] to use a ranged weapon."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + ActionMoveAwayFromObject(oNearestEnemy, TRUE, 2.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + } + // If we are casting a hostile spell then check positioning. + else if(nAction > -1 && Get2DAString("ai_spells", "HostileSetting", nAction) == "1") + { + // We are out of melee and casting a spell on an ally so don't move. + if(GetReputation(oCreature, oTarget) > 89) return FALSE; + float fSpellRange = ai_GetSpellRange(nAction); + float fTargetRange = GetDistanceBetween(oCreature, oTarget); + if(AI_DEBUG) ai_Debug("0i_combat", "3389", "fSpellRange: " + FloatToString(fSpellRange, 0, 2) + + " fTargetRange: " + FloatToString(fTargetRange, 0, 2)); + // Adjust the ranges to see if we are too close. + if(fSpellRange == 5.0) fSpellRange = 4.5f; + //else if(fSpellRange == 8.0) fSpellRange = 8.0f; + else if(fSpellRange > 10.0f) fSpellRange = 10.0f; + if(AI_DEBUG) ai_Debug("0i_combat", "3395", "Adjusted spell range is " + + FloatToString(fSpellRange, 0, 2) + " : " + GetName(oTarget) + " range is " + + FloatToString(fTargetRange, 0, 2) + "."); + // We are closer than we have to be to cast our spell. + if(fTargetRange < fSpellRange) + { + // Lets move back a little, too far and we miss attacks! + if(AI_DEBUG) ai_Debug("0i_combat", "3402", GetName(oCreature) + " is moving away from " + + GetName(oTarget) + "[2.0] to cast a spell."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + ActionMoveAwayFromObject(oTarget, FALSE, 2.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } +} + return FALSE; +} +int ai_CheckMeleeCombatPosition(object oCreature, object oTarget, int nAction, int nBaseItemType = 0) +{ + // If we are not being attacked then we might want to back out of combat. + if(ai_GetEnemyAttackingMe(oCreature) != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3417", "I am being attacked so stand my ground!"); + return FALSE; + } + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + float fDistance = GetDistanceBetween(oCreature, oNearestEnemy); + if(AI_DEBUG) ai_Debug("0i_combat", "3422", "oNearestEnemy: " + GetName(oNearestEnemy) + " fDistance " + FloatToString(fDistance, 0, 2)); + if(nAction == AI_LAST_ACTION_RANGED_ATK) + { + if(AI_DEBUG) ai_Debug("0i_combat", "3425", GetName(oCreature) + " is moving away from " + GetName(oNearestEnemy) + + "[" + FloatToString(AI_RANGE_MELEE - fDistance + 1.0, 0, 2) + "]" + " to use a ranged weapon."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + // Lets move just out of melee range! + int bRun = ai_CanIMoveInCombat(oCreature); + ActionMoveAwayFromObject(oNearestEnemy, bRun, AI_RANGE_MELEE - fDistance + 1.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + // If we want to cast a spell this round then back away! + else if(nAction > -1) + { + // Some items we don't need to move on such as wands, staves, and rods. + if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == BASE_ITEM_MAGICSTAFF || + nBaseItemType == BASE_ITEM_MAGICROD) return FALSE; + float fSpellRange = ai_GetSpellRange(nAction); + // A Touch spell means we should not move if we are not the target. + if(fSpellRange <= 5.0 && oCreature != oTarget) return FALSE; + if(AI_DEBUG) ai_Debug("0i_combat", "3446", GetName(oCreature) + " is moving away from " + + GetName(oTarget) + "[" + FloatToString(AI_RANGE_MELEE - fDistance + 1.0, 0, 2) + "] to cast a spell."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + SetActionMode(oCreature, ACTION_MODE_DEFENSIVE_CAST, FALSE); + // Lets move just out of melee range! + int bRun = ai_CanIMoveInCombat(oCreature); + ActionMoveAwayFromObject(oNearestEnemy, bRun, AI_RANGE_MELEE - fDistance + 1.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return TRUE; + } + return FALSE; +} +int ai_CheckCombatPosition(object oCreature, object oTarget, int nInMelee, int nAction, int nBaseItemType = 0) +{ + if(AI_DEBUG) ai_Debug("0i_combat", "3460", "|-----> Checking position in combat: " + + GetName(oCreature) + " nMelee: " + IntToString(nInMelee) + + " Action: " + IntToString(nAction) + + " Hold mode: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND)) + + " Use Advanced Movement: " + IntToString(GetLocalInt(GetModule(), AI_RULE_ADVANCED_MOVEMENT))); + // We don't want to move around in combat if we were told to hold. + if(ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND)) return FALSE; + if(!GetLocalInt(GetModule(), AI_RULE_ADVANCED_MOVEMENT)) return FALSE; + if(ai_CompareLastAction(oCreature, AI_LAST_ACTION_MOVE)) return FALSE; + // We are not in melee combat so lets see how close we should get. + if(!nInMelee) return ai_CheckRangedCombatPosition(oCreature, oTarget, nAction); + // If we are in melee we might need to move out of combat. + return ai_CheckMeleeCombatPosition(oCreature, oTarget, nAction, nBaseItemType); +} diff --git a/src/module/nss/0i_constants.nss b/src/module/nss/0i_constants.nss new file mode 100644 index 0000000..5413ac4 --- /dev/null +++ b/src/module/nss/0i_constants.nss @@ -0,0 +1,667 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Name: 0i_constants +// Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Include script for handling all constants for the ai. + These constants are static and can only be changed in the toolset. + Changes to any constants will not take effect until the scripts are recompiled. +*/////////////////////////////////////////////////////////////////////////////// + +const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:07.12.25"; +// The following constants are designed to be changed to allow the AI to work +// differently based on what a developer wants. +// If you change these constants make sure the database has been removed +// so the ai_SetAIRules() will rewrite the new server rule values. +// File Name: peps_database.sqlite3 +//********************************** SERVER *********************************** +// Turn On/Off Debug. You can only use the debug with the pi_debug/pe_debug scripts. +// This will only work if you are using the PEPS menu system. +const int AI_DEBUG = FALSE; +// Defines if we are compiling for single player or a server. Always on for servers! +const int AI_SERVER = FALSE; +// The number of classes allowed for a creature to take in the server/module. +const int AI_MAX_CLASSES_PER_CHARACTER = 8; +// Taunts cool down time before the AI attemps another Taunt. +const int AI_TAUNT_COOLDOWN = 3; +// Animal Empathy cool down time before the AI attemps another check. +const int AI_EMPATHY_COOLDOWN = 3; +// Arcane Spell failure% or less than, for a caster to still try to cast a spell. +const int AI_ASF_WILL_USE = 15; +// Monsters chance to heal while in combat per round. +const int AI_MONSTER_HEAL_IN_COMBAT_CHANCE = 70; +// Monsters chance to heal when out of combat per heart beat. +const int AI_MONSTER_HEAL_OUT_COMBAT_CHANCE = 70; +// Allows Henchman to have a widget if using the henchman AI. +const int AI_HENCHMAN_WIDGET = TRUE; +// Change the Custom token number if it conflicts with your server. +const int AI_BASE_CUSTOM_TOKEN = 1000; +// Delay between creatures casting Buff spells. Must be minimum of 0.1 seconds. +const float AI_HENCHMAN_BUFF_DELAY = 0.2; + +//******************* These can be changed within the game ******************* +// Moral checks on or off. If wounded they will make Will saves, if they fail the flee. +const int AI_MORAL_CHECKS = FALSE; +// Allows monsters to prebuff before combat starts. +const int AI_PREBUFF = TRUE; +// Allows monsters cast summons spells when prebuffing. +const int AI_PRESUMMONS = TRUE; +// Allows monsters to use tactical AI scripts such as ambush, flanker, ranged. +const int AI_TACTICAL = TRUE; +// Enemies may summon familiars and Animal companions and will be randomized. +const int AI_SUMMON_COMPANIONS = FALSE; +// Allow the AI to move during combat base on the situation and action taking. +const int AI_ADVANCED_MOVEMENT = TRUE; +// Follow Item Level Restrictions for AI. +const int AI_ITEM_LEVEL_RESTRICTIONS = FALSE; +// Allow the AI to use Use Magic Device. +const int AI_USE_MAGIC_DEVICE = TRUE; +// Allow the AI to use healing kits. +const int AI_HEALING_KITS = TRUE; +// Associates are permanent and don't get removed when the master dies. +const int AI_COMPANIONS_PERMANENT = FALSE; +// Monster AI's chance (0 to 100) to attack the weakest target instead of the nearest. +// The higher the number the harder the encounter with monsters! +const int AI_TARGET_WEAKEST = 0; +// Variable that can change the distance creatures will come and attack after +// hearing a shout from an ally that sees or hears an enemy. +// Or when searching for an invisible, heard enemy. +// 10.0 Short, 30.0 Average, 40.0 Long, 60.0 Huge. +const float AI_SEARCH_DISTANCE = 30.0; +// Enemy corpses remain on the floor instead of dissappearing. +const int AI_CORPSE_REMAIN = FALSE; +// Monsters will wander around when not in combat. +const int AI_WANDER = FALSE; +// Variable distance monsters can wander away from their spawn point. +const float AI_WANDER_DISTANCE = 0.0; +// Variable that allows monsters to open doors when wandering around out of combat. +const int AI_OPEN_DOORS = FALSE; +// Monster's actual perception distance. +// 8 Short(10 sight/listen) 9 Medium(20 sight/listen) 10 Long(35 sight/20 listen) +// 11 Default(Based on appearance.2da Most creatures use 9, bosses use 10). +const int AI_MONSTER_PERCEPTION = 11; +// Should the AI auto adjust the XP scale to remove party size penalty? +const int AI_PARTY_SCALE = FALSE; + +//**************************** DM Based Constants **************************** +// The constant the server wants set to allow players to use specific widgets buttons. +// 0 Allows all buttons. See ASSOCIATE_WIDGET_BUTTONS below for values needed to be +// added to block those buttons. +// Example: BTN_CMD_GHOST_MODE = 0x00000800; To remove you would put 2048 below. +// Since Hex 800 is Decimal 2048. +const int AI_DM_WIDGET_ACCESS_BUTTONS = 0; +// The constant the server wants set to allow players to use specific AI buttons. +// 0 Allows all buttons. See ASSOCIATE_AI_BUTTONS below for values needed to be +// added to block those buttons. +// Example: BTN_AI_MAGIC_LEVEL = 0x00000040; To remove you would put 64 below. +// Since Hex 40 is Decimal 64. Adding BTN_AI_LOOT = 0x00001000; to that would be +// 64 + 4096 = 4160 to Block Magic Level and Auto Looting. +const int AI_DM_AI_ACCESS_BUTTONS = 0; +//************************** CONVERSATION CONSTANTS ************************** +// Player's can tell their associates to ignore enemy associates. +const int AI_IGNORE_ASSOCIATES_ON = TRUE; +// Associates with a Taunt skill higher than their level can be told to taunt. +const int AI_TAUNTING_ON = TRUE; +// Associates that cast spells can be told to use counterspell. +const int AI_COUNTERSPELLING_ON = TRUE; +// Associates with lore skill higher than the master can identify items. +const int AI_IDENTIFY_ON = TRUE; +// Associates can be called upon to scout ahead for monsters. +const int AI_SCOUT_AHEAD_ON = TRUE; +// A player can open a henchmen's inventory. +const int AI_OPEN_INVENTORY = TRUE; +// Allows players to have associates pickup loot. +const int AI_PICKUP_LOOT = TRUE; +// Allows players to remove a henchman. +const int AI_REMOVE_HENCHMAN_ON = FALSE; +//***************************** Health Constants ***************************** +// % of health for when a creature is considered wounded. +const int AI_HEALTH_WOUNDED = 50; +// % of health when creature is considered badly wounded. +const int AI_HEALTH_BLOODY = 25; +//***************************** MORAL CONSTANTS ****************************** +// Moral checks are only made once a creature is below AI_HEALTH_WOUNDED. +// The moral DC is AI_MORAL_DC - the number of Allies. Default: 5 +const int AI_WOUNDED_MORAL_DC = 5; +// Once a creature goes below AI_HEALTHY_BLOODY then it uses this moral DC. Default: 15 +const int AI_BLOODY_MORAL_DC = 15; +//******************************* WINDOW CONSTANTS ***************************** +const string AI_MAIN_NUI = "ai_main_nui"; +const string AI_COMMAND_NUI = "_command_nui"; +const string AI_NUI = "_ai_nui"; +const string AI_WIDGET_NUI = "_widget_nui"; +const string AI_LOOTFILTER_NUI = "_lootfilter_nui"; +const string AI_COPY_NUI = "_copy_nui"; +const string AI_PLUGIN_NUI = "ai_plugin_nui"; +const string AI_QUICK_WIDGET_NUI = "_quick_widget_nui"; +const string AI_SPELL_MEMORIZE_NUI = "_spell_memorize_nui"; +const string AI_SPELL_KNOWN_NUI = "_spell_known_nui"; +const string AI_SPELL_DESCRIPTION_NUI = "ai_spell_desc_nui"; +const string AI_EFFECT_ICON_NUI = "ai_effect_icon_nui"; +//******************************* CORE CONSTANTS ******************************* +// The following constants are core constants and changing any of these without +// understanding the whole system could cause unforseen results. +// CHANGE AT YOUR OWN RISK. +// Variable used to asave a monster object for changing. +const string AI_MONSTER_OBJECT = "AI_MONSTER_OBJECT"; +// Variable used to save a monsters json for changing. +const string AI_MONSTER_JSON = "AI_MONSTER_JSON"; +// Variable used to let PEPS know that a monster plugin changed the monster. +const string AI_MONSTER_CHANGED = "AI_MONSTER_CHANGED"; +// Variable used to save an associates class list to change known list json. +const string AI_CLASS_LIST_JSON = "AI_CLASS_LIST_JSON"; +// Startup variable to tell plugins that we have started. +const string AI_STARTING_UP = "AI_STARTING_UP"; +// Add plugin variable to tell plugins that we are adding them to PEPS. +const string AI_ADD_PLUGIN = "AI_ADD_PLUGIN"; +// Startup variable to tell plugins what json array to add their plugin to. +const string AI_JSON_PLUGINS = "AI_JSON_PLUGINS"; +// Plugin variable to have plugins return if they setup the plugin in the json for PEPS. +const string AI_PLUGIN_SET = "AI_PLUGIN_SET"; +// Monster modification variable to let PEPS know what mods are available. +const string AI_MONSTER_MOD_JSON = "AI_MONSTER_MOD_JSON"; +// The maximum number of henchman the code works with. +const int AI_MAX_HENCHMAN = 12; +// Delay between Henchman casting Healing spells. Must be minimum of 0.5 seconds. +const float AI_HENCHMAN_HEALING_DELAY = 6.0; +// A variable that can be set on creatures to stop mobile animations. +const string AI_NO_ANIMATION = "AI_NO_ANIMATION"; +// How many seconds in a combat round. +const int AI_COMBAT_ROUND_IN_SECONDS = 6; +// Used for actions that take x seconds but don't have an action constant. +const string AI_COMBAT_WAIT_IN_SECONDS = "AI_COMBAT_WAIT_IN_SECONDS"; +// Constants used to define the difficulty of the battle for associates. +// 20+ : Impossible - Cannot win. +// 17 to 19 : Overpowering - Use all of our powers. +// 15 to 16 : Very Difficult - Use all of our power (Highest level spells). +// 11 to 14 : Challenging - Use most of our power (Higher level powers). +// 8 to 10 : Moderate - Use half of our power (Mid level powers and less). +// 5 to 7 : Easy - Use our weaker powers (Lowest level powers). +// 2 to 4 : Effortless - Don't waste spells and powers on this. +// 1 or less: Pointless - We probably should ignore these dangers. +const int AI_COMBAT_IMPOSSIBLE = 21; +const int AI_COMBAT_OVERPOWERING = 17; +const int AI_COMBAT_VERY_DIFFICULT = 15; +const int AI_COMBAT_CHALLENGING = 11; +const int AI_COMBAT_MODERATE = 10; +const int AI_COMBAT_EASY = 7; +const int AI_COMBAT_EFFORTLESS = 4; +// Variables used to keep track of enemies in combat. +const string AI_ENEMY = "AI_ENEMY"; // The enemy objects. +const string AI_ENEMY_DISABLED = "AI_ENEMY_DISABLED"; // Int if they are disabled. +const string AI_ENEMY_PERCEIVED = "AI_ENEMY_PERCEIVED"; // TRUE if we have seen or heard them, FALSE if not. +const string AI_ENEMY_RANGE = "AI_ENEMY_RANGE"; // The range from OBJECT_SELF. +const string AI_ENEMY_COMBAT = "AI_ENEMY_COMBAT"; // Combat rating: (BAB + AC - 10) / 2 +const string AI_ENEMY_MELEE = "AI_ENEMY_MELEE"; // Enemies within 5 meters - Allies within 5 meters. +const string AI_ENEMY_HEALTH = "AI_ENEMY_HEALTH"; // % of hitpoints. +const string AI_ENEMY_NUMBERS = "AI_ENEMY_NUM"; // Number of enemies in combat. +const string AI_ENEMY_POWER = "AI_ENEMY_POWER"; // (Level * Health %) / 100 added for each enemy to this. +const string AI_ENEMY_NEAREST = "AI_ENEMY_NEAREST"; // Nearest enemy to OBJECT_SELF. +// Variables used to keep track of allies in combat. +const string AI_ALLY = "AI_ALLY"; // All friendly creatures +const string AI_ALLY_DISABLED = "AI_ALLY_DISABLED"; // Int if they are disabled. +const string AI_ALLY_PERCEIVED = "AI_ALLY_PERCEIVED"; // All allies are set to be seen and heard. +const string AI_ALLY_RANGE = "AI_ALLY_RANGE"; // The range from OBJECT_SELF. +const string AI_ALLY_COMBAT = "AI_ALLY_COMBAT"; // Combat rating: (BAB + AC - 10) / 2 +const string AI_ALLY_MELEE = "AI_ALLY_MELEE"; // Enemies within 5 meters - Allies within 5 meters. +const string AI_ALLY_HEALTH = "AI_ALLY_HEALTH"; // % of hitpoints. +const string AI_ALLY_NUMBERS = "AI_ALLY_NUM"; // Number of allies in combat. +const string AI_ALLY_POWER = "AI_ALLY_POWER"; // (Level * Health %) / 100 added for each enemy to this. +// Variable name used to define the ai scripts being used by creatures. +const string AI_DEFAULT_SCRIPT = "AI_DEFAULT_SCRIPT"; +const string AI_COMBAT_SCRIPT = "AI_COMBAT_SCRIPT"; +// Constants used in a creatures listening patterns. +const string AI_I_SEE_AN_ENEMY = "AI_I_SEE_AN_ENEMY"; +const string AI_I_HEARD_AN_ENEMY = "AI_I_HEARD_AN_ENEMY"; +const string AI_ATKED_BY_WEAPON = "AI_ATK_BY_WEAPON"; +const string AI_ATKED_BY_SPELL = "AI_ATK_BY_SPELL"; +const string AI_I_AM_WOUNDED = "AI_I_AM_WOUNDED"; +const string AI_I_AM_DEAD = "AI_I_AM_DEAD"; +const string AI_I_AM_DISEASED = "AI_I_AM_DISEASED"; +const string AI_I_AM_POISONED = "AI_I_AM_POISONED"; +const string AI_I_AM_WEAK = "AI_I_AM_WEAK"; +const int AI_ALLY_SEES_AN_ENEMY = 1; +const int AI_ALLY_HEARD_AN_ENEMY = 2; +const int AI_ALLY_ATKED_BY_WEAPON = 3; +const int AI_ALLY_ATKED_BY_SPELL = 4; +const int AI_ALLY_IS_WOUNDED = 5; +const int AI_ALLY_IS_DEAD = 6; +const int AI_ALLY_IS_DISEASED = 7; +const int AI_ALLY_IS_POISONED = 8; +const int AI_ALLY_IS_WEAK = 9; +const string AI_MY_TARGET = "AI_MY_TARGET"; +// Constant used by monsters to reduce checks while searching for unseen targets. +const string AI_AM_I_SEARCHING = "AI_AM_I_SEARCHING"; +// Used to keep track of oCreature attempting to hide. +const string AI_TRIED_TO_HIDE = "AI_TRIED_TO_HIDE"; +// Constant used by creatures to keep track of invisible creatures. +const string AI_IS_INVISIBLE = "AI_IS_INVISIBLE"; +// Constants used in combat to keep track of a creatures last action. +// 0+ is the last spell cast from the line number in Spells.2da. +const string sLastActionVarname = "AI_LAST_ACTION"; +const int AI_LAST_ACTION_CAST_SPELL = -1; +const int AI_LAST_ACTION_NONE = -2; +const int AI_LAST_ACTION_MELEE_ATK = -3; +const int AI_LAST_ACTION_RANGED_ATK = -4; +const int AI_LAST_ACTION_USED_FEAT = -5; +const int AI_LAST_ACTION_USED_ITEM = -6; +const int AI_LAST_ACTION_USED_SKILL = -7; +const int AI_LAST_ACTION_MOVE = -8; +// Variable name used to keep track of Action Modes. +const string AI_CURRENT_ACTION_MODE = "AI_CURRENT_ACTION_MODE"; +// Variable name used to keep track of object usage by the AI. +const string AI_OBJECT_IN_USE = "AI_OBJECT_IN_USE"; +// Variable name used to keep a creatures attacked targets. +const string AI_ATTACKED_PHYSICAL = "AI_ATTACKED_PHYSICAL"; +const string AI_ATTACKED_SPELL = "AI_ATTACKED_SPELL"; +// Variable name used to keep track of a creatures normal polymorph form. +const string AI_NORMAL_FORM = "AI_NORMAL_FORM"; +// Variable name used to keep track if a creature has been buffed yet. +const string AI_CASTER_BUFFS_SET = "AI_CASTER_BUFFS_SET"; +// Variable name used to keep track of rounds in combat for a custom ai script. +const string AI_ROUND = "AI_ROUND"; +// Combat Ranges +const float AI_RANGE_MELEE = 5.0f; // Anyone within this is considered to be in melee. +const float AI_RANGE_CLOSE = 8.0f; // For anything requiring to be within 30'. +const float AI_RANGE_LONG = 15.0f; // Mainly used for distance ranged attacks. +const float AI_RANGE_PERCEPTION = 35.0f; // This is the distance for perception in battle. +const float AI_RANGE_BATTLEFIELD = 40.0f; // This is the size of the battlefield area. +// Spell ranges. +const float AI_SHORT_DISTANCE = 8.0f; +const float AI_MEDIUM_DISTANCE = 20.0f; +const float AI_LONG_DISTANCE = 40.0f; +// When computer checks if a creature should cast a specific spell at a target. +// Computer makes a spell check vs the targets saving throw. +// Spell check roll for the caster is +// [Innate spell Level + Random (AI_SPELL_CHECK_DIE) + AI_SPELL_CHECK_BONUS] +// If the spell gives a save for half (i.e. FireBall) and the target does not have +// Evasion then they get an additional bonus of AI_SPELL_CHECK_NO_EVASION_BONUS. +const int AI_SPELL_CHECK_DIE = 6; +const int AI_SPELL_CHECK_BONUS = 3; +const int AI_SPELL_CHECK_NO_EVASION_BONUS = 10; +// When the computer checks if a creature should use defensive casting it looks +// at the spell level + AI_DEFENSIVE_CASTING_DC vs casters concentration +// and feat bonuses (i.e. COMBAT_CASTING) + Random (AI_DEFENSIVE_CASTING_ROLL). +const int AI_DEFENSIVE_CASTING_DC = 19; // 19 will allow them to use it at 50% effectiveness. +const int AI_DEFENSIVE_CASTING_DIE = 10; +// When the computer checks to see if it should cast in melee combat it looks +// at CASTING_IN_MELEE_DC + SpellLevel + (Num of creatures in melee * GetHitDice (NearestEnemy)); +// vs the casters concentration + Random (AI_CASTING_IN_MELEE_ROLL). +const int AI_CASTING_IN_MELEE_DC = 10; +const int AI_CASTING_IN_MELEE_ROLL = 10; +// For getting a specific class the following constants were added to flesh out +// the CLASS_TYPE_* +const int AI_CLASS_TYPE_CASTER = -1; +const int AI_CLASS_TYPE_DIVINE = -2; +const int AI_CLASS_TYPE_ARCANE = -3; +const int AI_CLASS_TYPE_WARRIOR = -4; +// For getting a specific race the following constants were added to flesh out +// the RACIAL_TYPE_* +const int AI_RACIAL_TYPE_ANIMAL_BEAST = -1; +const int AI_RACIAL_TYPE_HUMANOID = -2; +// Bitwise constants for negative conditions we might want to try to cure +const int AI_CONDITION_POISON = 0x00000001; +const int AI_CONDITION_DISEASE = 0x00000002; +const int AI_CONDITION_BLINDDEAF = 0x00000004; +const int AI_CONDITION_ATK_DECREASE = 0x00000008; +const int AI_CONDITION_DMG_DECREASE = 0x00000010; +const int AI_CONDITION_DMG_I_DECREASE = 0x00000020; +const int AI_CONDITION_SKILL_DECREASE = 0x00000040; +const int AI_CONDITION_SAVE_DECREASE = 0x00000080; +const int AI_CONDITION_SR_DECREASE = 0x00000100; +const int AI_CONDITION_AC_DECREASE = 0x00000200; +const int AI_CONDITION_SLOW = 0x00000400; +const int AI_CONDITION_ABILITY_DRAIN = 0x00000800; +const int AI_CONDITION_LEVEL_DRAIN = 0x00001000; +const int AI_CONDITION_CHARMED = 0x00002000; +const int AI_CONDITION_DAZED = 0x00004000; +const int AI_CONDITION_STUNNED = 0x00008000; +const int AI_CONDITION_FRIGHTENED = 0x00010000; +const int AI_CONDITION_CONFUSED = 0x00020000; +const int AI_CONDITION_CURSE = 0x00040000; +const int AI_CONDITION_PARALYZE = 0x00080000; +const int AI_CONDITION_DOMINATED = 0x00100000; +// Database constants for Associate modes. +const string AI_MODE_DB_TABLE = "AI_MODE_DB_TABLE"; +// Bitwise constants for Associate modes that are used with Get/SetAssociateMode(). +const string sAIModeVarname = "ASSOCIATE_MODES"; +//const int AI_MODE_DISTANCE_CLOSE = 0x00000001; // Stays within AI_DISTANCE_CLOSE of master. +//const int AI_MODE_DISTANCE_MEDIUM = 0x00000002; // Stays within AI_DISTANCE_MEDIUM of master. +const int AI_MODE_ACTION_GHOST = 0x00000004; // Defines if the player is using Ghost mode when using associate actions. +const int AI_MODE_SELF_HEALING_OFF = 0x00000008; // Creature will not use healing items or spells on self. +const int AI_MODE_PARTY_HEALING_OFF = 0x00000010; // Creature will not use healing items or spells on party. +const int AI_MODE_GHOST = 0x00000020; // Creature can move through other creatures. +const int AI_MODE_OPEN_DOORS = 0x00000040; // Creature will attempted to open all doors. +const int AI_MODE_EQUIP_WEAPON_OFF = 0x00000080; // The AI will not equip weapons. +const int AI_MODE_BASH_LOCKS = 0x00000100; // Will bash locks if cannot open door/placeable. +const int AI_MODE_AGGRESSIVE_SEARCH = 0x00000200; // Sets associate to continuous search mode. +const int AI_MODE_AGGRESSIVE_STEALTH = 0x00000400; // Sets associate to continuous stealth mode. +const int AI_MODE_PICK_LOCKS = 0x00000800; // Will pick locks if possible. +const int AI_MODE_DISARM_TRAPS = 0x00001000; // Will disarm traps. +const int AI_MODE_SCOUT_AHEAD = 0x00002000; // Will move ahead of master and scout. +const int AI_MODE_DEFEND_MASTER = 0x00004000; // Will attack enemies attacking our master. +const int AI_MODE_STAND_GROUND = 0x00008000; // Will stay in one place until new command. +const int AI_MODE_STOP_RANGED = 0x00010000; // Will not use ranged weapons. +const int AI_MODE_FOLLOW = 0x00020000; // Keeps associate following master ignoring combat. +const int AI_MODE_PICKUP_ITEMS = 0x00040000; // Will pickup up all items for master. +const int AI_MODE_COMMANDED = 0x00080000; // In Command mode then don't follow, search, etc. +const int AI_MODE_IGNORE_TRAPS = 0x00100000; // Creature will ignore traps on the floor. +const int AI_MODE_NO_STEALTH = 0x00200000; // Will not cast invisibilty or use stealth. +const int AI_MODE_DO_NOT_SPEAK = 0x00400000; // Tells the henchmen to be silent and not talk. +const int AI_MODE_CHECK_ATTACK = 0x00800000; // Will only engage in combats they think they can win. +const int AI_MODE_IGNORE_ASSOCIATES = 0x01000000; // Will ignore associates in combat. +//const int AI_MODE_ = 0x02000000; // Not used. +//const int AI_MODE_ = 0x04000000; // Not used. +//const int AI_MODE_ = 0x08000000; // Not used. +//const int AI_MODE_ = 0x10000000; // Not used. +//const int AI_MODE_ = 0x20000000; // Not used. +//const int AI_MODE_ = 0x40000000; // Not used. +//const int AI_MODE_ = 0x80000000; // Not used. +// Bitwise constants for Associate magic modes that are used with Get/SetAssociateMagicMode(). +const string sMagicModeVarname = "ASSOCIATE_MAGIC_MODES"; +const int AI_MAGIC_BUFF_MASTER = 0x00000001; // Buffs master before other allies. +const int AI_MAGIC_NO_MAGIC = 0x00000002; // Will not use any magic (Spells, abilities). +const int AI_MAGIC_DEFENSIVE_CASTING = 0x00000004; // Will only cast defensive spells. +const int AI_MAGIC_OFFENSIVE_CASTING = 0x00000008; // Will only cast offensive spells. +const int AI_MAGIC_STOP_DISPEL = 0x00000010; // Will not cast dispel type spells. +const int AI_MAGIC_BUFF_AFTER_REST = 0x00000020; // Will buff the party after resting. +const int AI_MAGIC_NO_MAGIC_ITEMS = 0x00000040; // Will not use magic items in combat. +const int AI_MAGIC_CURE_SPELLS_OFF = 0x00000080; // Will not cast cure spells. +const int AI_MAGIC_EFFECT_ICON_REPORT = 0x00000100; // Sets each player to report Effect Icons to chat. +//const int = 0x00000200; // Not used. +//const int = 0x00000400; // Not used. +const int AI_MAGIC_NO_SPONTANEOUS_CURE = 0x00000800; // Caster will stop using spontaneous cure spells. +//const int AI_MAGIC_ = 0x00001000; // Not used. +//const int AI_MAGIC_ = 0x00002000; // Not used. +//const int AI_MAGIC_ = 0x00004000; // Not used. +//const int AI_MAGIC_ = 0x00008000; // Not used. +//const int AI_MAGIC_ = 0x00010000; // Not used. +//const int AI_MAGIC_ = 0x00020000; // Not used. +//const int AI_MAGIC_ = 0x00040000; // Not used. +//const int AI_MAGIC_ = 0x00080000; // Not used. +//const int AI_MAGIC_ = 0x00100000; // Not used. +//const int AI_MAGIC_ = 0x00200000; // Not used. +//const int AI_MAGIC_ = 0x00400000; // Not used. +//const int AI_MAGIC_ = 0x00800000; // Not used. +//const int AI_MAGIC_ = 0x01000000; // Not used. +//const int AI_MAGIC_ = 0x02000000; // Not used. +//const int AI_MAGIC_ = 0x04000000; // Not used. +//const int AI_MAGIC_ = 0x08000000; // Not used. +//const int AI_MAGIC_ = 0x10000000; // Not used. +//const int AI_MAGIC_ = 0x20000000; // Not used. +//const int AI_MAGIC_ = 0x40000000; // Not used. +//const int AI_MAGIC_ = 0x80000000; // Not used. +// Use by NUI windows to stop saving move states while loading. +const string AI_NO_NUI_SAVE = "AI_NO_NUI_SAVE"; +// Bitwise menu constants for Widget buttons that are used with Get/SetAssociateWidgetButtons(). +const string sWidgetButtonsVarname = "ASSOCIATE_WIDGET_BUTTONS"; +const int BTN_WIDGET_OFF = 0x00000001; // Removes the widget from the screen, For PC it removes all associates. +const int BTN_WIDGET_LOCK = 0x00000002; // Locks the widget to the current coordinates. +const int BTN_CMD_GUARD = 0x00000004; // Command associates to Guard Me. PC widget only. +const int BTN_CMD_FOLLOW = 0x00000008; // Command associates to Follow. PC widget only. +const int BTN_CMD_HOLD = 0x00000010; // Command associates to Stand Ground. PC widget only. +const int BTN_CMD_ATTACK = 0x00000020; // Command associates to Attack Nearest. PC widget only. +const int BTN_BUFF_REST = 0x00000040; // Buffs with long duration spells after resting. Associate widget only. +const int BTN_BUFF_SHORT = 0x00000080; // Buffs with short duration spells. +const int BTN_BUFF_LONG = 0x00000100; // Buffs with long duration spells. +const int BTN_BUFF_ALL = 0x00000200; // Buffs with all spells. +const int BTN_CMD_ACTION = 0x00000400; // Command associate to do an action. +const int BTN_CMD_GHOST_MODE = 0x00000800; // Toggle's associates ghost mode. +const int BTN_CMD_AI_SCRIPT = 0x00001000; // Toggle's special tactics ai scripts. +const int BTN_CMD_PLACE_TRAP = 0x00002000; // A trapper may place traps. +const int BTN_CMD_CAMERA = 0x00004000; // Places camera view on associate. +const int BTN_CMD_INVENTORY = 0x00008000; // Opens inventory of associate. +const int BTN_CMD_FAMILIAR = 0x00010000; // Summons familiar. +const int BTN_CMD_COMPANION = 0x00020000; // Summons Companion. +const int BTN_CMD_SEARCH = 0x00040000; // Command all associates to use search mode. PC widget only. +const int BTN_CMD_STEALTH = 0x00080000; // Command all associates to use stealth mode. PC widget only. +const int BTN_CMD_SCOUT = 0x00100000; // Command associate to scout ahead of the part. +const int BTN_CMD_SPELL_WIDGET = 0x00200000; // Allows adding or removing spells from Spell Widget. +const int BTN_CMD_JUMP_TO = 0x00400000; // Player can make associates jump to them. +const int BTN_WIDGET_VERTICAL = 0x80000000; // Widget will be displayed vertical. +// Bitwise menu constants for Associate AI buttons that are used with Get/SetAssociateAIButtons(). +const string sAIButtonsVarname = "ASSOCIATE_AI_BUTTONS"; +const int BTN_AI_FOR_PC = 0x00000001; // PC use AI. PC widget only. +const int BTN_AI_USE_RANGED = 0x00000002; // AI uses ranged attacks. +const int BTN_AI_USE_SEARCH = 0x00000004; // AI uses Search. +const int BTN_AI_USE_STEALTH = 0x00000008; // AI uses Stealth. +const int BTN_AI_REMOVE_TRAPS = 0x00000010; // AI seeks out and removes traps. +const int BTN_AI_PICK_LOCKS = 0x00000020; // AI will attempt to pick locks. +const int BTN_AI_MAGIC_LEVEL = 0x00000040; // Increase chance to use magic in battle. +const int BTN_AI_NO_SPONTANEOUS = 0x00000080; // Stops the use of spontaneous spells. +const int BTN_AI_NO_MAGIC_USE = 0x00000100; // Will not use magic in battle. +const int BTN_AI_NO_MAGIC_ITEM_USE = 0x00000200; // Will not use magic items in battle. +const int BTN_AI_DEF_MAGIC_USE = 0x00000400; // Will use Defensive spells only in battle. +const int BTN_AI_OFF_MAGIC_USE = 0x00000800; // Will use Offensive spells only in battle. +const int BTN_AI_LOOT = 0x00001000; // Auto picking up loot on/off. +const int BTN_AI_FOLLOW_TARGET = 0x00002000; // Selects a target to follow. +const int BTN_AI_HEAL_OUT = 0x00004000; // Increase minimum hp required before ai heals out of combat. +const int BTN_AI_PERC_RANGE = 0x00008000; // Adjust the perception range of the henchman. +const int BTN_AI_HEAL_IN = 0x00010000; // Increase minimum hp required before ai heals in combat. +const int BTN_AI_OPEN_DOORS = 0x00020000; // AI will open all closed doors. +const int BTN_AI_STOP_SELF_HEALING = 0x00040000; // Stops AI from using any healing on self. +const int BTN_AI_STOP_PARTY_HEALING = 0x00080000; // Stops AI from using any healing on party. +const int BTN_AI_IGNORE_ASSOCIATES = 0x00100000; // AI will deprioritize enemy associates. +const int BTN_AI_STOP_CURE_SPELLS = 0x00200000; // AI uses cure spells. +const int BTN_AI_STOP_WEAPON_EQUIP = 0x00400000; // AI can equip different weapons. +const int BTN_AI_IGNORE_TRAPS = 0x00800000; // AI will ignore traps on the floor. +//const int BTN_AI = 0x01000000; // Not used. +//const int BTN_AI = 0x02000000; // Not used. +const int BTN_AI_BASH_LOCKS = 0x04000000; // AI will attempt to bash any locks they can't get past. +const int BTN_AI_REDUCE_SPEECH = 0x08000000; // Reduce the associates speaking. +// Bitwise menu constants for DM access for players Widget buttons uses BTN_CMD and BTN_BUFF bitwise see above. +const string sDMWidgetAccessVarname = "AI_RULES_WIDGET_BUTTONS_ACCESS"; +// Bitwise menu constants for DM access for players AI buttons uses BTN_AI bitwise see above. +const string sDMAIAccessVarname = "AI_RULES_AI_BUTTONS_ACCESS"; +// Variable name for DM widget buttons. +const string sDMWidgetButtonVarname = "DM_WIDGET_BUTTONS"; +// DM Widget buttons states. +const int BTN_DM_WIDGET_OFF = 0x00000001; // Removes the widget from the screen, For PC it removes all associates. +const int BTN_DM_WIDGET_LOCK = 0x00000002; // Locks the widget to the current coordinates. +const int BTN_DM_CMD_GROUP1 = 0x00000004; // Does all the group 1 commands. +const int BTN_DM_CMD_GROUP2 = 0x00000008; // Does all the group 2 commands. +const int BTN_DM_CMD_GROUP3 = 0x00000010; // Does all the group 3 commands. +const int BTN_DM_CMD_GROUP4 = 0x00000020; // Does all the group 4 commands. +const int BTN_DM_CMD_GROUP5 = 0x00000040; // Does all the group 5 commands. +const int BTN_DM_CMD_GROUP6 = 0x00000080; // Does all the group 6 commands. +const int BTN_DM_CMD_CAMERA = 0x00000100; // Selects new object to hold the camera view. +const int BTN_DM_CMD_INVENTORY = 0x00000200; // Selects a creature to open the inventory of. +const int BTN_DM_CMD_MEMORIZE = 0x00000400; // Allows associate to change memorized spells. +// Bitwise constants for Associate loot options that are used with Get/SetAssociateLootMode(). +const string sLootFilterVarname = "ASSOCIATE_LOOT_MODES"; +const int AI_LOOT_PLOT = 0x00000001; +const int AI_LOOT_WEAPONS = 0x00000002; +const int AI_LOOT_ARMOR = 0x00000004; +const int AI_LOOT_SHIELDS = 0x00000008; +const int AI_LOOT_HEADGEAR = 0x00000010; +const int AI_LOOT_BELTS = 0x00000020; +const int AI_LOOT_BOOTS = 0x00000040; +const int AI_LOOT_CLOAKS = 0x00000080; +const int AI_LOOT_GLOVES = 0x00000100; +const int AI_LOOT_JEWELRY = 0x00000200; +const int AI_LOOT_POTIONS = 0x00000400; +const int AI_LOOT_SCROLLS = 0x00000800; +const int AI_LOOT_WANDS_RODS_STAVES = 0x00001000; +const int AI_LOOT_GEMS = 0x00002000; +const int AI_LOOT_MISC = 0x00004000; +const int AI_LOOT_ARROWS = 0x00008000; +const int AI_LOOT_BOLTS = 0x00010000; +const int AI_LOOT_BULLETS = 0x00020000; +const int AI_LOOT_GIVE_TO_PC = 0x80000000; +// Default value for all loot filters to be on. +const int AI_LOOT_ALL_ON = 262143; +// Variable to keep track of who is in ghost mode. +const string sGhostModeVarname = "AI_GHOST_MODE_ON"; +// Variables for gold piece value to pickup items. +const string AI_MIN_GOLD_ = "AI_MIN_GOLD_"; +// Variable used to limit the spamming of NUI buttons. +const string AI_DELAY_NUI_USE = "AI_DELAY_NUI_USE"; +// Variable for maximum weight to pickup from looting. +const string AI_MAX_LOOT_WEIGHT = "AI_MAX_LOOT_WEIGHT"; +// Variable to change the size of the widget buttons. +const string AI_WIDGET_BUTTON_SIZE = "AI_WIDGET_BUTTON_SIZE"; +// Variable to change the difficulty so a player can adjust spell usage. +const string AI_DIFFICULTY_ADJUSTMENT = "AI_DIFFICULTY_ADJUSTMENT"; +// Variable to change the Healing % limit for out of combat. +const string AI_HEAL_OUT_OF_COMBAT_LIMIT = "AI_HEAL_OUT_OF_COMBAT_LIMIT"; +// Variable to change the Healing % limit for in combat. +const string AI_HEAL_IN_COMBAT_LIMIT = "AI_HEAL_IN_COMBAT_LIMIT"; +// Variable to change the looting range. +const string AI_LOOT_CHECK_RANGE = "AI_LOOT_CHECK_RANGE"; +// Variable to change the lock checking range. +const string AI_LOCK_CHECK_RANGE = "AI_LOCK_CHECK_RANGE"; +// Variable to change the trap checking range. +const string AI_TRAP_CHECK_RANGE = "AI_TRAP_CHECK_RANGE"; +// Variable to change the range an associate follows the pc. +const string AI_FOLLOW_RANGE = "AI_FOLLOW_RANGE"; +// Variable that holds the target for an associate to follow. +const string AI_FOLLOW_TARGET = "AI_FOLLOW_TARGET"; +// Variable that holds the perception range of associates i.e. 8, 9, 10, 11. +const string AI_ASSOCIATE_PERCEPTION = "AI_PERCEPTION_RANGE"; +// Variable that holds the perception distance of associates i.e. 30.0 meters. +const string AI_ASSOC_PERCEPTION_DISTANCE = "AI_ASSOC_PERCEPTION_DISTANCE"; +// Variable that holds the open doors range of the henchman. +const string AI_OPEN_DOORS_RANGE = "AI_OPEN_DOORS_RANGE"; +// Variable that holds the Spell widgets json data. +const string AI_SPELLS_WIDGET = "AI_SPELLS_WIDGET"; +// The number of Buff Groups +const int AI_BUFF_GROUPS = -17; +// Variable name used to keep track if we have set our talents. +const string AI_TALENTS_SET = "AI_TALENTS_SET"; +// New talent categories +const string AI_TALENT_ENHANCEMENT = "E"; +const string AI_TALENT_PROTECTION = "P"; +const string AI_TALENT_SUMMON = "S"; +const string AI_TALENT_HEALING = "H"; +const string AI_TALENT_CURE = "C"; +const string AI_TALENT_INDISCRIMINANT_AOE = "I"; +const string AI_TALENT_DISCRIMINANT_AOE = "D"; +const string AI_TALENT_RANGED = "R"; +const string AI_TALENT_TOUCH = "T"; +// Talent types. +const int AI_TALENT_TYPE_SPELL = 1; +const int AI_TALENT_TYPE_SP_ABILITY = 2; +const int AI_TALENT_TYPE_FEAT = 3; +const int AI_TALENT_TYPE_ITEM = 4; +// Variable name used to have associates fight the pc's selected target. +const string AI_PC_LOCKED_TARGET = "AI_PC_LOCKED_TARGET"; +// Variable name of json talent immunity. +const string AI_TALENT_IMMUNITY = "AI_TALENT_IMMUNITY"; +// Variables keeps track of the maximum level for the talent category. +const string AI_MAX_TALENT = "AI_MAX_TALENT_"; +// Backward compatability constants. +const int X2_EVENT_CONCENTRATION_BROKEN = 12400; +// Variable set on the module if the module is using PRC. +const string AI_USING_PRC = "AI_USING_PRC"; +// Variable that sets if the rules have been added to the module. +const string AI_RULES_SET = "AI_RULES_SET"; +// Variable that tells us that oCreature has run our OnSpawn event. +const string AI_ONSPAWN_EVENT = "AI_ONSPAWN_EVENT"; +// Variable used to define a creatures unique Tag for widgets. +const string AI_TAG = "AI_TAG"; +// Variable that saves any module target event script so we can pass it along. +const string AI_MODULE_TARGET_EVENT = "AI_MODULE_TARGET_EVENT"; +// Variable for plugins to inject Targeting mode code into PEPS. +const string AI_PLUGIN_TARGET_SCRIPT = "AI_PLUGIN_TARGET_SCRIPT"; +// Variable for PEPS to inject effect icons NUI information. +const string AI_MODULE_GUI_EVENT = "AI_MODULE_GUI_EVENT"; +// Variable used on the player to define the targeting action in the OnPlayerTarget event script. +const string AI_TARGET_MODE = "AI_TARGET_MODE"; +// Variable used on the player to define which associate triggered the OnPlayer Target. +const string AI_TARGET_ASSOCIATE = "AI_TARGET_ASSOCIATE"; +// Bitwise constants for immune damage item properties that is used with Get/SetItemProperty(). +const string sIPImmuneVarname = "AI_IP_IMMUNE"; +// Bitwise constants for resisted damage item properties that is used with Get/SetItemProperty(). +const string sIPResistVarname = "AI_IP_RESIST"; +// Variable name for the Int constant for reduced damage item property set to the bonus of the weapon required. +const string sIPReducedVarname = "AI_IP_REDUCED"; +// Variable name for the Int (Bool) constant for the haste item property. +const string sIPHasHasteVarname = "AI_IP_HAS_HASTE"; +// Variable name used to hold the party xp base needed to adjust party xp. +const string AI_BASE_PARTY_SCALE_XP = "AI_BASE_PARTY_SCALE_XP"; +//***************************** AI RULES CONSTANTS ***************************** +// Variable name set to a creatures full name to set debugging on. +const string AI_RULE_DEBUG_CREATURE = "AI_RULE_DEBUG_CREATURE"; +// Moral checks on or off. +const string AI_RULE_MORAL_CHECKS = "AI_RULE_MORAL_CHECKS"; +// Allows monsters to prebuff before combat starts. +const string AI_RULE_BUFF_MONSTERS = "AI_RULE_BUFF_MONSTERS"; +// Allows monsters to use the ambush AI scripts. +const string AI_RULE_AMBUSH = "AI_RULE_AMBUSH"; +// Enemies may summon familiars and Animal companions and will be randomized. +const string AI_RULE_SUMMON_COMPANIONS = "AI_RULE_SUMMON_COMPANIONS"; +// Allows monsters cast summons spells when prebuffing. +const string AI_RULE_PRESUMMON = "AI_RULE_PRESUMMON"; +// Allow the AI move during combat base on the situation and action taking. +const string AI_RULE_ADVANCED_MOVEMENT = "AI_RULE_ADVANCED_MOVEMENT"; +// Follow Item Level Restrictions for monsters/associates. +// Usually off in Single player and on in Multi player. +const string AI_RULE_ILR = "AI_RULE_ILR"; +// Allow the AI to use Use Magic Device. +const string AI_RULE_ALLOW_UMD = "AI_RULE_ALLOW_UMD"; +// Allow the AI to use healing kits. +const string AI_RULE_HEALERSKITS = "AI_RULE_HEALERSKITS"; +// Summoned associates are permanent and don't disappear when the caster dies. +const string AI_RULE_PERM_ASSOC = "AI_RULE_PERM_ASSOC"; +// Monster AI's chance to attack the weakest target instead of the nearest. +const string AI_RULE_AI_DIFFICULTY = "AI_RULE_AI_DIFFICULTY"; +// Variable that can change the distance creatures will come and attack after +// hearing a shout from an ally that sees or hears an enemy. +// Or when searching for an invisible, heard enemy. +// 10.0 Short, 30.0 Average, 40.0 Long, 60.0 Huge. +const string AI_RULE_PERCEPTION_DISTANCE = "AI_RULE_PERCEPTION_DISTANCE"; +// Enemy corpses remain on the floor instead of dissappearing. +const string AI_RULE_CORPSES_STAY = "AI_RULE_CORPSES_STAY"; +// Monsters will wander around when not in combat. +const string AI_RULE_WANDER = "AI_RULE_WANDER"; +// Increase the number of encounter creatures. +const string AI_INCREASE_ENC_MONSTERS = "AI_INCREASE_ENC_MONSTERS"; +// Increase all monsters hitpoints by this percentage. +const string AI_INCREASE_MONSTERS_HP = "AI_INCREASE_MONSTERS_HP"; +// Variable that can change the distance monsters can hear and see. +const string AI_RULE_MON_PERC_DISTANCE = "AI_RULE_MON_PERC_DISTANCE"; +// Variable name set to hold the maximum number of henchman the player wants. +const string AI_RULE_MAX_HENCHMAN = "AI_RULE_MAX_HENCHMAN"; +// Variable name set to hold the distance monsters can wander away. +const string AI_RULE_WANDER_DISTANCE = "AI_RULE_WANDER_DISTANCE"; +// Variable name set to allow wandering monsters to open doors. +const string AI_RULE_OPEN_DOORS = "AI_RULE_OPEN_DOORS"; +// Variable name set to hold the modules default xp scale for use later. +const string AI_RULE_DEFAULT_XP_SCALE = "AI_RULE_DEFAULT_XP_SCALE"; +// Variable name set to allow the game to regulate experience based on party size. +const string AI_RULE_PARTY_SCALE = "AI_RULE_PARTY_SCALE"; +// Variable name set to restrict the AI's use of Darkness. +const string AI_RULE_RESTRICTED_SPELLS = "AI_RULE_RESTRICTED_SPELLS"; +/*/ Special behavior constants from x0_i0_behavior +const int NW_FLAG_BEHAVIOR_SPECIAL = 0x00000001; +//Will always attack regardless of faction +const int NW_FLAG_BEHAVIOR_CARNIVORE = 0x00000002; +//Will only attack if approached +const int NW_FLAG_BEHAVIOR_OMNIVORE = 0x00000004; +//Will never attack. Will alway flee. +const int NW_FLAG_BEHAVIOR_HERBIVORE = 0x00000008; +// This is the name of the local variable that holds the spawn-in conditions +const string sSpawnCondVarname = "NW_GENERIC_MASTER"; +// The available spawn-in conditions from x0_i0_spawncond +const int NW_FLAG_ESCAPE_RETURN = 0x00000020; //Failed +const int NW_FLAG_ESCAPE_LEAVE = 0x00000040; +const int NW_FLAG_TELEPORT_RETURN = 0x00000080; //Failed +const int NW_FLAG_TELEPORT_LEAVE = 0x00000100; +const int NW_FLAG_END_COMBAT_ROUND_EVENT = 0x00004000; +const int NW_FLAG_ON_DIALOGUE_EVENT = 0x00008000; +const int NW_FLAG_AMBIENT_ANIMATIONS = 0x00080000; +const int NW_FLAG_HEARTBEAT_EVENT = 0x00100000; +const int NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS = 0x00200000; +const int NW_FLAG_DAY_NIGHT_POSTING = 0x00400000; +const int NW_FLAG_AMBIENT_ANIMATIONS_AVIAN = 0x00800000; +const string sWalkwayVarname = "NW_WALK_CONDITION"; +// If set, the creature's waypoints have been initialized. +const int NW_WALK_FLAG_INITIALIZED = 0x00000001; +// If set, the creature will walk its waypoints constantly, +// moving on in each OnHeartbeat event. Otherwise, +// it will walk to the next only when triggered by an +// OnPerception event. +const int NW_WALK_FLAG_CONSTANT = 0x00000002; +// Set when the creature is walking day waypoints. +const int NW_WALK_FLAG_IS_DAY = 0x00000004; +// Set when the creature is walking back +const int NW_WALK_FLAG_BACKWARDS = 0x00000008; diff --git a/src/module/nss/0i_gui_events.nss b/src/module/nss/0i_gui_events.nss new file mode 100644 index 0000000..4628cf3 --- /dev/null +++ b/src/module/nss/0i_gui_events.nss @@ -0,0 +1,1032 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_gui_events +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts for all gui events. See also 0e_gui_events + + GUI Events: + GUIEVENT_EFFECTICON_CLICK: For displaying icon information. + + This was built by DAZ all credit to him. + I just changed it from PostString to a NUI menu. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_constants" +#include "0i_nui" +void ai_SetupModuleGUIEvents(object oCreature) +{ + object oModule = GetModule(); + string sModuleGUIEvents = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_GUIEVENT); + if(sModuleGUIEvents != "" || sModuleGUIEvents != "0e_gui_events") + { + SetLocalString(oModule, AI_MODULE_GUI_EVENT, sModuleGUIEvents); + } + SetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_GUIEVENT, "0e_gui_events"); +} +int EffectIconToEffectType(int nEffectIcon) +{ + switch (nEffectIcon) + { + case EFFECT_ICON_INVALID: return EFFECT_TYPE_INVALIDEFFECT; + + // *** No Extra Stats + case EFFECT_ICON_BLIND: return EFFECT_TYPE_BLINDNESS; + case EFFECT_ICON_CHARMED: return EFFECT_TYPE_CHARMED; + case EFFECT_ICON_CONFUSED: return EFFECT_TYPE_CONFUSED; + case EFFECT_ICON_FRIGHTENED: return EFFECT_TYPE_FRIGHTENED; + case EFFECT_ICON_DOMINATED: return EFFECT_TYPE_DOMINATED; + case EFFECT_ICON_PARALYZE: return EFFECT_TYPE_PARALYZE; + case EFFECT_ICON_DAZED: return EFFECT_TYPE_DAZED; + case EFFECT_ICON_STUNNED: return EFFECT_TYPE_STUNNED; + case EFFECT_ICON_SLEEP: return EFFECT_TYPE_SLEEP; + case EFFECT_ICON_SILENCE: return EFFECT_TYPE_SILENCE; + case EFFECT_ICON_TURNED: return EFFECT_TYPE_TURNED; + case EFFECT_ICON_HASTE: return EFFECT_TYPE_HASTE; + case EFFECT_ICON_SLOW: return EFFECT_TYPE_SLOW; + case EFFECT_ICON_ENTANGLE: return EFFECT_TYPE_ENTANGLE; + case EFFECT_ICON_DEAF: return EFFECT_TYPE_DEAF; + case EFFECT_ICON_DARKNESS: return EFFECT_TYPE_DARKNESS; + case EFFECT_ICON_POLYMORPH: return EFFECT_TYPE_POLYMORPH; + case EFFECT_ICON_SANCTUARY: return EFFECT_TYPE_SANCTUARY; + case EFFECT_ICON_TRUESEEING: return EFFECT_TYPE_TRUESEEING; + case EFFECT_ICON_SEEINVISIBILITY: return EFFECT_TYPE_SEEINVISIBLE; + case EFFECT_ICON_ETHEREALNESS: return EFFECT_TYPE_ETHEREAL; + case EFFECT_ICON_PETRIFIED: return EFFECT_TYPE_PETRIFY; + // *** + + case EFFECT_ICON_DAMAGE_RESISTANCE: return EFFECT_TYPE_DAMAGE_RESISTANCE; + case EFFECT_ICON_REGENERATE: return EFFECT_TYPE_REGENERATE; + case EFFECT_ICON_DAMAGE_REDUCTION: return EFFECT_TYPE_DAMAGE_REDUCTION; + case EFFECT_ICON_TEMPORARY_HITPOINTS: return EFFECT_TYPE_TEMPORARY_HITPOINTS; + case EFFECT_ICON_IMMUNITY: return EFFECT_TYPE_IMMUNITY; + case EFFECT_ICON_POISON: return EFFECT_TYPE_POISON; + case EFFECT_ICON_DISEASE: return EFFECT_TYPE_DISEASE; + case EFFECT_ICON_CURSE: return EFFECT_TYPE_CURSE; + case EFFECT_ICON_ATTACK_INCREASE: return EFFECT_TYPE_ATTACK_INCREASE; + case EFFECT_ICON_ATTACK_DECREASE: return EFFECT_TYPE_ATTACK_DECREASE; + case EFFECT_ICON_DAMAGE_INCREASE: return EFFECT_TYPE_DAMAGE_INCREASE; + case EFFECT_ICON_DAMAGE_DECREASE: return EFFECT_TYPE_DAMAGE_DECREASE; + case EFFECT_ICON_AC_INCREASE: return EFFECT_TYPE_AC_INCREASE; + case EFFECT_ICON_AC_DECREASE: return EFFECT_TYPE_AC_DECREASE; + case EFFECT_ICON_MOVEMENT_SPEED_INCREASE: return EFFECT_TYPE_MOVEMENT_SPEED_INCREASE; + case EFFECT_ICON_MOVEMENT_SPEED_DECREASE: return EFFECT_TYPE_MOVEMENT_SPEED_DECREASE; + case EFFECT_ICON_SAVING_THROW_DECREASE: return EFFECT_TYPE_SAVING_THROW_DECREASE; + case EFFECT_ICON_SPELL_RESISTANCE_INCREASE: return EFFECT_TYPE_SPELL_RESISTANCE_INCREASE; + case EFFECT_ICON_SPELL_RESISTANCE_DECREASE: return EFFECT_TYPE_SPELL_RESISTANCE_DECREASE; + case EFFECT_ICON_SKILL_INCREASE: return EFFECT_TYPE_SKILL_INCREASE; + case EFFECT_ICON_SKILL_DECREASE: return EFFECT_TYPE_SKILL_DECREASE; + case EFFECT_ICON_ELEMENTALSHIELD: return EFFECT_TYPE_ELEMENTALSHIELD; + case EFFECT_ICON_LEVELDRAIN: return EFFECT_TYPE_NEGATIVELEVEL; + case EFFECT_ICON_SPELLLEVELABSORPTION: return EFFECT_TYPE_SPELLLEVELABSORPTION; + case EFFECT_ICON_SPELLIMMUNITY: return EFFECT_TYPE_SPELL_IMMUNITY; + case EFFECT_ICON_CONCEALMENT: return EFFECT_TYPE_CONCEALMENT; + case EFFECT_ICON_EFFECT_SPELL_FAILURE: return EFFECT_TYPE_SPELL_FAILURE; + + case EFFECT_ICON_INVISIBILITY: + case EFFECT_ICON_IMPROVEDINVISIBILITY: return EFFECT_TYPE_INVISIBILITY; + + case EFFECT_ICON_ABILITY_INCREASE_STR: + case EFFECT_ICON_ABILITY_INCREASE_DEX: + case EFFECT_ICON_ABILITY_INCREASE_CON: + case EFFECT_ICON_ABILITY_INCREASE_INT: + case EFFECT_ICON_ABILITY_INCREASE_WIS: + case EFFECT_ICON_ABILITY_INCREASE_CHA: return EFFECT_TYPE_ABILITY_INCREASE; + + case EFFECT_ICON_ABILITY_DECREASE_STR: + case EFFECT_ICON_ABILITY_DECREASE_CHA: + case EFFECT_ICON_ABILITY_DECREASE_DEX: + case EFFECT_ICON_ABILITY_DECREASE_CON: + case EFFECT_ICON_ABILITY_DECREASE_INT: + case EFFECT_ICON_ABILITY_DECREASE_WIS: return EFFECT_TYPE_ABILITY_DECREASE; + + case EFFECT_ICON_IMMUNITY_ALL: + case EFFECT_ICON_IMMUNITY_MIND: + case EFFECT_ICON_IMMUNITY_POISON: + case EFFECT_ICON_IMMUNITY_DISEASE: + case EFFECT_ICON_IMMUNITY_FEAR: + case EFFECT_ICON_IMMUNITY_TRAP: + case EFFECT_ICON_IMMUNITY_PARALYSIS: + case EFFECT_ICON_IMMUNITY_BLINDNESS: + case EFFECT_ICON_IMMUNITY_DEAFNESS: + case EFFECT_ICON_IMMUNITY_SLOW: + case EFFECT_ICON_IMMUNITY_ENTANGLE: + case EFFECT_ICON_IMMUNITY_SILENCE: + case EFFECT_ICON_IMMUNITY_STUN: + case EFFECT_ICON_IMMUNITY_SLEEP: + case EFFECT_ICON_IMMUNITY_CHARM: + case EFFECT_ICON_IMMUNITY_DOMINATE: + case EFFECT_ICON_IMMUNITY_CONFUSE: + case EFFECT_ICON_IMMUNITY_CURSE: + case EFFECT_ICON_IMMUNITY_DAZED: + case EFFECT_ICON_IMMUNITY_ABILITY_DECREASE: + case EFFECT_ICON_IMMUNITY_ATTACK_DECREASE: + case EFFECT_ICON_IMMUNITY_DAMAGE_DECREASE: + case EFFECT_ICON_IMMUNITY_DAMAGE_IMMUNITY_DECREASE: + case EFFECT_ICON_IMMUNITY_AC_DECREASE: + case EFFECT_ICON_IMMUNITY_MOVEMENT_SPEED_DECREASE: + case EFFECT_ICON_IMMUNITY_SAVING_THROW_DECREASE: + case EFFECT_ICON_IMMUNITY_SPELL_RESISTANCE_DECREASE: + case EFFECT_ICON_IMMUNITY_SKILL_DECREASE: + case EFFECT_ICON_IMMUNITY_KNOCKDOWN: + case EFFECT_ICON_IMMUNITY_NEGATIVE_LEVEL: + case EFFECT_ICON_IMMUNITY_SNEAK_ATTACK: + case EFFECT_ICON_IMMUNITY_CRITICAL_HIT: + case EFFECT_ICON_IMMUNITY_DEATH_MAGIC: return EFFECT_TYPE_IMMUNITY; + + case EFFECT_ICON_SAVING_THROW_INCREASE: + case EFFECT_ICON_REFLEX_SAVE_INCREASED: + case EFFECT_ICON_FORT_SAVE_INCREASED: + case EFFECT_ICON_WILL_SAVE_INCREASED: return EFFECT_TYPE_SAVING_THROW_INCREASE; + + case EFFECT_ICON_DAMAGE_IMMUNITY_INCREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_MAGIC: + case EFFECT_ICON_DAMAGE_IMMUNITY_ACID: + case EFFECT_ICON_DAMAGE_IMMUNITY_COLD: + case EFFECT_ICON_DAMAGE_IMMUNITY_DIVINE: + case EFFECT_ICON_DAMAGE_IMMUNITY_ELECTRICAL: + case EFFECT_ICON_DAMAGE_IMMUNITY_FIRE: + case EFFECT_ICON_DAMAGE_IMMUNITY_NEGATIVE: + case EFFECT_ICON_DAMAGE_IMMUNITY_POSITIVE: + case EFFECT_ICON_DAMAGE_IMMUNITY_SONIC: return EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE; + + case EFFECT_ICON_DAMAGE_IMMUNITY_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_MAGIC_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_ACID_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_COLD_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_DIVINE_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_ELECTRICAL_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_FIRE_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_NEGATIVE_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_POSITIVE_DECREASE: + case EFFECT_ICON_DAMAGE_IMMUNITY_SONIC_DECREASE: return EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE; + + //case EFFECT_ICON_INVULNERABLE: return EFFECT_TYPE_INVULNERABLE; + //case EFFECT_ICON_WOUNDING: return EFFECT_TYPE_INVALIDEFFECT; + //case EFFECT_ICON_TAUNTED: return EFFECT_TYPE_INVALIDEFFECT; + //case EFFECT_ICON_TIMESTOP: return EFFECT_TYPE_TIMESTOP; + //case EFFECT_ICON_BLINDNESS: return EFFECT_TYPE_BLINDNESS; + //case EFFECT_ICON_DISPELMAGICBEST: return EFFECT_TYPE_INVALIDEFFECT; + //case EFFECT_ICON_DISPELMAGICALL: return EFFECT_TYPE_INVALIDEFFECT; + //case EFFECT_ICON_ENEMY_ATTACK_BONUS: return EFFECT_TYPE_INVALIDEFFECT; + //case EFFECT_ICON_FATIGUE: return EFFECT_TYPE_INVALIDEFFECT; + } + return EFFECT_TYPE_INVALIDEFFECT; +} +int AbilityTypeFromEffectIconAbility(int nEffectIcon) +{ + switch (nEffectIcon) + { + case EFFECT_ICON_ABILITY_INCREASE_STR: + case EFFECT_ICON_ABILITY_DECREASE_STR: + return ABILITY_STRENGTH; + case EFFECT_ICON_ABILITY_INCREASE_DEX: + case EFFECT_ICON_ABILITY_DECREASE_DEX: + return ABILITY_DEXTERITY; + case EFFECT_ICON_ABILITY_INCREASE_CON: + case EFFECT_ICON_ABILITY_DECREASE_CON: + return ABILITY_CONSTITUTION; + case EFFECT_ICON_ABILITY_INCREASE_INT: + case EFFECT_ICON_ABILITY_DECREASE_INT: + return ABILITY_INTELLIGENCE; + case EFFECT_ICON_ABILITY_INCREASE_WIS: + case EFFECT_ICON_ABILITY_DECREASE_WIS: + return ABILITY_WISDOM; + case EFFECT_ICON_ABILITY_INCREASE_CHA: + case EFFECT_ICON_ABILITY_DECREASE_CHA: + return ABILITY_CHARISMA; + } + return -1; +} +int DamageTypeFromEffectIconDamageImmunity(int nEffectIcon) +{ + switch (nEffectIcon) + { + case EFFECT_ICON_DAMAGE_IMMUNITY_MAGIC: + case EFFECT_ICON_DAMAGE_IMMUNITY_MAGIC_DECREASE: + return DAMAGE_TYPE_MAGICAL; + case EFFECT_ICON_DAMAGE_IMMUNITY_ACID: + case EFFECT_ICON_DAMAGE_IMMUNITY_ACID_DECREASE: + return DAMAGE_TYPE_ACID; + case EFFECT_ICON_DAMAGE_IMMUNITY_COLD: + case EFFECT_ICON_DAMAGE_IMMUNITY_COLD_DECREASE: + return DAMAGE_TYPE_COLD; + case EFFECT_ICON_DAMAGE_IMMUNITY_DIVINE: + case EFFECT_ICON_DAMAGE_IMMUNITY_DIVINE_DECREASE: + return DAMAGE_TYPE_DIVINE; + case EFFECT_ICON_DAMAGE_IMMUNITY_ELECTRICAL: + case EFFECT_ICON_DAMAGE_IMMUNITY_ELECTRICAL_DECREASE: + return DAMAGE_TYPE_ELECTRICAL; + case EFFECT_ICON_DAMAGE_IMMUNITY_FIRE: + case EFFECT_ICON_DAMAGE_IMMUNITY_FIRE_DECREASE: + return DAMAGE_TYPE_FIRE; + case EFFECT_ICON_DAMAGE_IMMUNITY_NEGATIVE: + case EFFECT_ICON_DAMAGE_IMMUNITY_NEGATIVE_DECREASE: + return DAMAGE_TYPE_NEGATIVE; + case EFFECT_ICON_DAMAGE_IMMUNITY_POSITIVE: + case EFFECT_ICON_DAMAGE_IMMUNITY_POSITIVE_DECREASE: + return DAMAGE_TYPE_POSITIVE; + case EFFECT_ICON_DAMAGE_IMMUNITY_SONIC: + case EFFECT_ICON_DAMAGE_IMMUNITY_SONIC_DECREASE: + return DAMAGE_TYPE_SONIC; + } + return -1; +} + +int ImmunityTypeFromEffectIconImmunity(int nEffectIcon) +{ + switch (nEffectIcon) + { + case EFFECT_ICON_IMMUNITY_MIND: return IMMUNITY_TYPE_MIND_SPELLS; + case EFFECT_ICON_IMMUNITY_POISON: return IMMUNITY_TYPE_POISON; + case EFFECT_ICON_IMMUNITY_DISEASE: return IMMUNITY_TYPE_DISEASE; + case EFFECT_ICON_IMMUNITY_FEAR: return IMMUNITY_TYPE_FEAR; + case EFFECT_ICON_IMMUNITY_TRAP: return IMMUNITY_TYPE_TRAP; + case EFFECT_ICON_IMMUNITY_PARALYSIS: return IMMUNITY_TYPE_PARALYSIS; + case EFFECT_ICON_IMMUNITY_BLINDNESS: return IMMUNITY_TYPE_BLINDNESS; + case EFFECT_ICON_IMMUNITY_DEAFNESS: return IMMUNITY_TYPE_DEAFNESS; + case EFFECT_ICON_IMMUNITY_SLOW: return IMMUNITY_TYPE_SLOW; + case EFFECT_ICON_IMMUNITY_ENTANGLE: return IMMUNITY_TYPE_ENTANGLE; + case EFFECT_ICON_IMMUNITY_SILENCE: return IMMUNITY_TYPE_SILENCE; + case EFFECT_ICON_IMMUNITY_STUN: return IMMUNITY_TYPE_STUN; + case EFFECT_ICON_IMMUNITY_SLEEP: return IMMUNITY_TYPE_SLEEP; + case EFFECT_ICON_IMMUNITY_CHARM: return IMMUNITY_TYPE_CHARM; + case EFFECT_ICON_IMMUNITY_DOMINATE: return IMMUNITY_TYPE_DOMINATE; + case EFFECT_ICON_IMMUNITY_CONFUSE: return IMMUNITY_TYPE_CONFUSED; + case EFFECT_ICON_IMMUNITY_CURSE: return IMMUNITY_TYPE_CURSED; + case EFFECT_ICON_IMMUNITY_DAZED: return IMMUNITY_TYPE_DAZED; + case EFFECT_ICON_IMMUNITY_ABILITY_DECREASE: return IMMUNITY_TYPE_ABILITY_DECREASE; + case EFFECT_ICON_IMMUNITY_ATTACK_DECREASE: return IMMUNITY_TYPE_ATTACK_DECREASE; + case EFFECT_ICON_IMMUNITY_DAMAGE_DECREASE: return IMMUNITY_TYPE_DAMAGE_DECREASE; + case EFFECT_ICON_IMMUNITY_DAMAGE_IMMUNITY_DECREASE: return IMMUNITY_TYPE_DAMAGE_IMMUNITY_DECREASE; + case EFFECT_ICON_IMMUNITY_AC_DECREASE: return IMMUNITY_TYPE_AC_DECREASE; + case EFFECT_ICON_IMMUNITY_MOVEMENT_SPEED_DECREASE: return IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE; + case EFFECT_ICON_IMMUNITY_SAVING_THROW_DECREASE: return IMMUNITY_TYPE_SAVING_THROW_DECREASE; + case EFFECT_ICON_IMMUNITY_SPELL_RESISTANCE_DECREASE: return IMMUNITY_TYPE_SPELL_RESISTANCE_DECREASE; + case EFFECT_ICON_IMMUNITY_SKILL_DECREASE: return IMMUNITY_TYPE_SKILL_DECREASE; + case EFFECT_ICON_IMMUNITY_KNOCKDOWN: return IMMUNITY_TYPE_KNOCKDOWN; + case EFFECT_ICON_IMMUNITY_NEGATIVE_LEVEL: return IMMUNITY_TYPE_NEGATIVE_LEVEL; + case EFFECT_ICON_IMMUNITY_SNEAK_ATTACK: return IMMUNITY_TYPE_SNEAK_ATTACK; + case EFFECT_ICON_IMMUNITY_CRITICAL_HIT: return IMMUNITY_TYPE_CRITICAL_HIT; + case EFFECT_ICON_IMMUNITY_DEATH_MAGIC: return IMMUNITY_TYPE_DEATH; + } + return -1; +} +void ClearLines(object oPlayer) +{ + int nLine, nLines = GetLocalInt(oPlayer, "BUFFINFO_LAST_NUM_LINES"); + for (nLine = 1; nLine <= nLines; nLine++) + { + PostString(oPlayer, "", 10, nLine + 3, SCREEN_ANCHOR_TOP_RIGHT, 0.1f, 0xFFFFFF00, 0xFFFFFF00, nLine); + } +} +void DisplayLine(object oPlayer, int nLine, string sText, int nColor) +{ + PostString(oPlayer, sText, 10, nLine + 3, SCREEN_ANCHOR_TOP_RIGHT, 10.0f, nColor, 0xFFFFFF00, nLine); +} +string SecondsToTimestamp(int nSeconds) +{ + sqlquery sql; + if (nSeconds > 86400) sql = SqlPrepareQueryObject(GetModule(), "SELECT (@seconds / 3600) || ':' || strftime('%M:%S', @seconds / 86400.0);"); + else sql = SqlPrepareQueryObject(GetModule(), "SELECT time(@seconds, 'unixepoch');"); + SqlBindInt(sql, "@seconds", nSeconds); + SqlStep(sql); + return SqlGetString(sql, 0); +} +string Get2DAStrRef(string s2DA, string sColumn, int nRow) +{ + return GetStringByStrRef(StringToInt(Get2DAString(s2DA, sColumn, nRow))); +} +string GetVersusRacialTypeAndAlignment(int nRacialType, int nLawfulChaotic, int nGoodEvil) +{ + string sRacialType = nRacialType == RACIAL_TYPE_INVALID ? "" : Get2DAStrRef("racialtypes", "NamePlural", nRacialType); + string sLawfulChaotic = nLawfulChaotic == ALIGNMENT_LAWFUL ? "Lawful" : nLawfulChaotic == ALIGNMENT_CHAOTIC ? "Chaotic" : ""; + string sGoodEvil = nGoodEvil == ALIGNMENT_GOOD ? "Good" : nGoodEvil == ALIGNMENT_EVIL ? "Evil" : ""; + string sAlignment = sLawfulChaotic + (sLawfulChaotic == "" ? sGoodEvil : (sGoodEvil == "" ? "" : " " + sGoodEvil)); + return (sRacialType != "" || sAlignment != "") ? (" vs. " + sAlignment + (sAlignment == "" ? sRacialType : (sRacialType == "" ? "" : " " + sRacialType))) : ""; +} +string GetModifierType(int nEffectType, int nPlus, int nMinus) +{ + return nEffectType == nPlus ? "+" : nEffectType == nMinus ? "-" : ""; +} +string ACTypeToString(int nACType) +{ + switch (nACType) + { + case AC_DODGE_BONUS: return "Dodge"; + case AC_NATURAL_BONUS: return "Natural"; + case AC_ARMOUR_ENCHANTMENT_BONUS: return "Armor"; + case AC_SHIELD_ENCHANTMENT_BONUS: return "Shield"; + case AC_DEFLECTION_BONUS: return "Deflection"; + } + return ""; +} + +string SavingThrowToString(int nSavingThrow) +{ + switch (nSavingThrow) + { + case SAVING_THROW_ALL: return "All"; + case SAVING_THROW_FORT: return "Fortitude"; + case SAVING_THROW_REFLEX: return "Reflex"; + case SAVING_THROW_WILL: return "Will"; + } + return ""; +} +string SavingThrowTypeToString(int nSavingThrowType) +{ + switch (nSavingThrowType) + { + case SAVING_THROW_TYPE_MIND_SPELLS: return "Mind Spells"; + case SAVING_THROW_TYPE_POISON: return "Poison"; + case SAVING_THROW_TYPE_DISEASE: return "Disease"; + case SAVING_THROW_TYPE_FEAR: return "Fear"; + case SAVING_THROW_TYPE_SONIC: return "Sonic"; + case SAVING_THROW_TYPE_ACID: return "Acid"; + case SAVING_THROW_TYPE_FIRE: return "Fire"; + case SAVING_THROW_TYPE_ELECTRICITY: return "Electricity"; + case SAVING_THROW_TYPE_POSITIVE: return "Positive"; + case SAVING_THROW_TYPE_NEGATIVE: return "Negative"; + case SAVING_THROW_TYPE_DEATH: return "Death"; + case SAVING_THROW_TYPE_COLD: return "Cold"; + case SAVING_THROW_TYPE_DIVINE: return "Divine"; + case SAVING_THROW_TYPE_TRAP: return "Traps"; + case SAVING_THROW_TYPE_SPELL: return "Spells"; + case SAVING_THROW_TYPE_GOOD: return "Good"; + case SAVING_THROW_TYPE_EVIL: return "Evil"; + case SAVING_THROW_TYPE_LAW: return "Lawful"; + case SAVING_THROW_TYPE_CHAOS: return "Chaotic"; + } + return ""; +} +string AbilityToString(int nAbility) +{ + switch (nAbility) + { + case ABILITY_STRENGTH: return "Strength"; + case ABILITY_DEXTERITY: return "Dexterity"; + case ABILITY_CONSTITUTION: return "Constitution"; + case ABILITY_INTELLIGENCE: return "Intelligence"; + case ABILITY_WISDOM: return "Wisdom"; + case ABILITY_CHARISMA: return "Charisma"; + } + return ""; +} +string DamageTypeToString(int nDamageType) +{ + switch (nDamageType) + { + case DAMAGE_TYPE_BLUDGEONING: return "Bludgeoning"; + case DAMAGE_TYPE_PIERCING: return "Piercing"; + case DAMAGE_TYPE_SLASHING: return "Slashing"; + case DAMAGE_TYPE_MAGICAL: return "Magical"; + case DAMAGE_TYPE_ACID: return "Acid"; + case DAMAGE_TYPE_COLD: return "Cold"; + case DAMAGE_TYPE_DIVINE: return "Divine"; + case DAMAGE_TYPE_ELECTRICAL: return "Electrical"; + case DAMAGE_TYPE_FIRE: return "Fire"; + case DAMAGE_TYPE_NEGATIVE: return "Negative"; + case DAMAGE_TYPE_POSITIVE: return "Positive"; + case DAMAGE_TYPE_SONIC: return "Sonic"; + case DAMAGE_TYPE_BASE_WEAPON: return "Base Weapon"; + } + return ""; +} +string SpellSchoolToString(int nSpellSchool) +{ + switch (nSpellSchool) + { + case SPELL_SCHOOL_GENERAL: return "General"; + case SPELL_SCHOOL_ABJURATION: return "Abjuration"; + case SPELL_SCHOOL_CONJURATION: return "Conjuration"; + case SPELL_SCHOOL_DIVINATION: return "Divination"; + case SPELL_SCHOOL_ENCHANTMENT: return "Enchantment"; + case SPELL_SCHOOL_EVOCATION: return "Evocation"; + case SPELL_SCHOOL_ILLUSION: return "Illusion"; + case SPELL_SCHOOL_NECROMANCY: return "Necromancy"; + case SPELL_SCHOOL_TRANSMUTATION: return "Transmutation"; + } + return ""; +} +string MissChanceToString(int nMissChance) +{ + switch (nMissChance) + { + case MISS_CHANCE_TYPE_VS_RANGED: return "vs. Ranged"; + case MISS_CHANCE_TYPE_VS_MELEE: return "vs. Melee"; + } + return ""; +} +void ai_CreateEffectChatReport(object oPlayer, int nEffectIconID) +{ + int nIconEffectType = EffectIconToEffectType(nEffectIconID); + if(nIconEffectType == EFFECT_TYPE_INVALIDEFFECT) return; + int nLine, nIndex, nEffectIndex; + string sColor = AI_COLOR_YELLOW; + int bSkipDisplay, bHasEffect; + int nEffectType, bIsSpellLevelAbsorptionPretendingToBeSpellImmunity; + string sText; + json jEffectID = JsonArray(); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 27 + sText = Get2DAStrRef("effecticons", "StrRef", nEffectIconID); + ai_SendMessages(sText, AI_COLOR_YELLOW, oPlayer); + effect eEffect = GetFirstEffect(oPlayer); + while(GetIsEffectValid(eEffect)) + { + bSkipDisplay = FALSE; + nEffectType = GetEffectType(eEffect); + // Unlimited EffectSpellLevelAbsorption has a SpellImmunity Icon + if (nIconEffectType == EFFECT_TYPE_SPELL_IMMUNITY && GetEffectInteger(eEffect, 3)) + { + bIsSpellLevelAbsorptionPretendingToBeSpellImmunity = TRUE; + nIconEffectType = EFFECT_TYPE_SPELLLEVELABSORPTION; + } + if (nEffectType == nIconEffectType) + { + bHasEffect = TRUE; + int nSpellID = GetEffectSpellId(eEffect); + string sSpellName = nSpellID == -1 ? "" : Get2DAStrRef("spells", "Name", nSpellID); + int bIsPermanentEffect = GetEffectDurationType(eEffect) == DURATION_TYPE_PERMANENT; + int nDurationRemaining = GetEffectDurationRemaining(eEffect); + string sDurationRemaining = bIsPermanentEffect ? "(Permanent)" : "(" + SecondsToTimestamp(nDurationRemaining) + ")"; + if(bIsPermanentEffect) sColor = AI_COLOR_WHITE; + else + { + if(nDurationRemaining < 61) sColor = AI_COLOR_RED; + else if(nDurationRemaining < 300) sColor = AI_COLOR_YELLOW; + else sColor = AI_COLOR_GREEN; + } + string sStats = ""; + string sRacialTypeAlignment = ""; + switch (nEffectType) + { + case EFFECT_TYPE_AC_INCREASE: + case EFFECT_TYPE_AC_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_AC_INCREASE, EFFECT_TYPE_AC_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + ACTypeToString(GetEffectInteger(eEffect, 0)) + " AC"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_ATTACK_INCREASE: + case EFFECT_TYPE_ATTACK_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_ATTACK_INCREASE, EFFECT_TYPE_ATTACK_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) +" AB"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_SAVING_THROW_INCREASE: + case EFFECT_TYPE_SAVING_THROW_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SAVING_THROW_INCREASE, EFFECT_TYPE_SAVING_THROW_DECREASE); + string sSavingThrow = SavingThrowToString(GetEffectInteger(eEffect, 1)); + string sSavingThrowType = SavingThrowTypeToString(GetEffectInteger(eEffect, 2)); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + " " + sSavingThrow + (sSavingThrowType == "" ? "" : " (vs. " + sSavingThrowType + ")"); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4), GetEffectInteger(eEffect, 5)); + break; + } + case EFFECT_TYPE_ABILITY_INCREASE: + case EFFECT_TYPE_ABILITY_DECREASE: + { + int nAbility = AbilityTypeFromEffectIconAbility(nEffectIconID); + + if (nAbility != GetEffectInteger(eEffect, 0)) + bSkipDisplay = TRUE; + else + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_ABILITY_INCREASE, EFFECT_TYPE_ABILITY_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + AbilityToString(nAbility); + } + break; + } + case EFFECT_TYPE_DAMAGE_INCREASE: + case EFFECT_TYPE_DAMAGE_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_DAMAGE_INCREASE, EFFECT_TYPE_DAMAGE_DECREASE); + sStats = sModifier + Get2DAStrRef("iprp_damagecost", "Name", GetEffectInteger(eEffect, 0)) + " (" + DamageTypeToString(GetEffectInteger(eEffect, 1)) + ")"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_SKILL_INCREASE: + case EFFECT_TYPE_SKILL_DECREASE: + { + int nSkill = GetEffectInteger(eEffect, 0); + string sSkill = nSkill == 255 ? "All Skills" : Get2DAStrRef("skills", "Name", nSkill); + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SKILL_INCREASE, EFFECT_TYPE_SKILL_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + sSkill; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_TEMPORARY_HITPOINTS: + { + sStats = "+" + IntToString(GetEffectInteger(eEffect, 0)) + " HitPoints"; + break; + } + case EFFECT_TYPE_DAMAGE_REDUCTION: + { + int nAmount = GetEffectInteger(eEffect, 0); + int nDamagePower = GetEffectInteger(eEffect, 1); + nDamagePower = nDamagePower > 6 ? --nDamagePower : nDamagePower; + int nRemaining = GetEffectInteger(eEffect, 2); + sStats = IntToString(nAmount) + "/+" + IntToString(nDamagePower) + " (" + (nRemaining == 0 ? "Unlimited" : IntToString(nRemaining) + " Damage Remaining") + ")"; + break; + } + case EFFECT_TYPE_DAMAGE_RESISTANCE: + { + int nAmount = GetEffectInteger(eEffect, 1); + int nRemaining = GetEffectInteger(eEffect, 2); + sStats = IntToString(nAmount) + "/- " + DamageTypeToString(GetEffectInteger(eEffect, 0)) + " Resistance (" + (nRemaining == 0 ? "Unlimited" : IntToString(nRemaining) + " Damage Remaining") + ")"; + break; + } + case EFFECT_TYPE_IMMUNITY: + { + int nImmunity = ImmunityTypeFromEffectIconImmunity(nEffectIconID); + + if (nImmunity != GetEffectInteger(eEffect, 0)) + bSkipDisplay = TRUE; + else + { + sStats = Get2DAStrRef("effecticons", "StrRef", nEffectIconID); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + } + break; + } + case EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE: + case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE: + { + int nDamageType = GetEffectInteger(eEffect, 0); + int nDamageTypeFromIcon = DamageTypeFromEffectIconDamageImmunity(nEffectIconID); + + if (nDamageTypeFromIcon != -1 && nDamageType != nDamageTypeFromIcon) + bSkipDisplay = TRUE; + + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE, EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + "% " + DamageTypeToString(nDamageType) + " Damage Immunity"; + break; + } + case EFFECT_TYPE_SPELL_IMMUNITY: + { + sStats = "Spell Immunity: " + Get2DAStrRef("spells", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_SPELLLEVELABSORPTION: + { + int nMaxSpellLevelAbsorbed = GetEffectInteger(eEffect, 0); + int bUnlimited = GetEffectInteger(eEffect, 3); + string sSpellLevel; + switch (nMaxSpellLevelAbsorbed) + { + case 0: sSpellLevel = "Cantrip"; break; + case 1: sSpellLevel = "1st"; break; + case 2: sSpellLevel = "2nd"; break; + case 3: sSpellLevel = "3rd"; break; + default: sSpellLevel = IntToString(nMaxSpellLevelAbsorbed) + "th"; break; + } + sSpellLevel += " Level" + (nMaxSpellLevelAbsorbed == 0 ? "" : " and Below"); + string sSpellSchool = SpellSchoolToString(GetEffectInteger(eEffect, 2)); + string sRemainingSpellLevels = bUnlimited ? "" : "(" + IntToString(GetEffectInteger(eEffect, 1)) + " Spell Levels Remaining)"; + sStats = sSpellLevel + " " + sSpellSchool + " Spell Immunity " + sRemainingSpellLevels; + + if (bIsSpellLevelAbsorptionPretendingToBeSpellImmunity) + nIconEffectType = EFFECT_TYPE_SPELL_IMMUNITY; + else if (bUnlimited && !bIsSpellLevelAbsorptionPretendingToBeSpellImmunity) + bSkipDisplay = TRUE; + + break; + } + case EFFECT_TYPE_REGENERATE: + { + sStats = "+" + IntToString(GetEffectInteger(eEffect, 0)) + " HP / " + FloatToString((GetEffectInteger(eEffect, 1) / 1000.0f), 0, 2) + "s"; + break; + } + case EFFECT_TYPE_POISON: + { + sStats = "Poison: " + Get2DAStrRef("poison", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_DISEASE: + { + sStats = "Disease: " + Get2DAStrRef("disease", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_CURSE: + { + int nAbility; + string sAbilityDecrease; + for (nAbility = 0; nAbility < 6; nAbility++) + { + int nAbilityMod = GetEffectInteger(eEffect, nAbility); + if (nAbilityMod > 0) + { + string sAbility = GetStringLeft(AbilityToString(nAbility), 3); + sAbilityDecrease += "-" + IntToString(nAbilityMod) + " " + sAbility + ", "; + } + } + sAbilityDecrease = GetStringLeft(sAbilityDecrease, GetStringLength(sAbilityDecrease) - 2); + sStats = sAbilityDecrease; + break; + } + case EFFECT_TYPE_MOVEMENT_SPEED_INCREASE: + case EFFECT_TYPE_MOVEMENT_SPEED_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_MOVEMENT_SPEED_INCREASE, EFFECT_TYPE_MOVEMENT_SPEED_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + "% Movement Speed"; + break; + } + case EFFECT_TYPE_ELEMENTALSHIELD: + { + sStats = IntToString(GetEffectInteger(eEffect, 0)) + " + " + Get2DAStrRef("iprp_damagecost", "Name", GetEffectInteger(eEffect, 1)) + " (" + DamageTypeToString(GetEffectInteger(eEffect, 2)) + ")"; + break; + } + case EFFECT_TYPE_NEGATIVELEVEL: + { + sStats = "-" + IntToString(GetEffectInteger(eEffect, 0)) + " Levels"; + break; + } + case EFFECT_TYPE_CONCEALMENT: + { + string sMissChance = MissChanceToString(GetEffectInteger(eEffect, 4) - 1); + sStats = IntToString(GetEffectInteger(eEffect, 0)) + "% Concealment" + (sMissChance == "" ? "" : " (" + sMissChance + ")"); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + break; + } + case EFFECT_TYPE_SPELL_RESISTANCE_INCREASE: + case EFFECT_TYPE_SPELL_RESISTANCE_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SPELL_RESISTANCE_INCREASE, EFFECT_TYPE_SPELL_RESISTANCE_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + " Spell Resistance"; + break; + } + case EFFECT_TYPE_SPELL_FAILURE: + { + sStats = IntToString(GetEffectInteger(eEffect, 0)) + "% Spell Failure (Spell School: " + SpellSchoolToString(GetEffectInteger(eEffect, 1)) + ")"; + break; + } + case EFFECT_TYPE_INVISIBILITY: + { + int nInvisibilityType = GetEffectInteger(eEffect, 0); + if (nEffectIconID == EFFECT_ICON_INVISIBILITY) + bSkipDisplay = nInvisibilityType != INVISIBILITY_TYPE_NORMAL; + else if (nEffectIconID == EFFECT_ICON_IMPROVEDINVISIBILITY) + bSkipDisplay = nInvisibilityType != INVISIBILITY_TYPE_IMPROVED; + if (!bSkipDisplay) + { + sStats = (nInvisibilityType == INVISIBILITY_TYPE_IMPROVED ? "Improved " : "") + "Invisibility"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + } + break; + } + case EFFECT_TYPE_HASTE: + { + sStats = "Hasted"; + } + } + if(!bSkipDisplay) + { + sText = sSpellName + " " + sDurationRemaining + (sStats == "" ? "" : " -> " + sStats + sRacialTypeAlignment); + if(sText != "") + { + ai_SendMessages(sText, sColor, oPlayer); + object oSource = GetEffectCreator(eEffect); + if(GetIsObjectValid(oSource)) + { + sText = GetObjectType(oSource) ? GetName(oSource) : ""; + sText = " Creator: " + sText; + float fLength = IntToFloat(GetStringLength(sText) * 8); + ai_SendMessages(sText, AI_COLOR_YELLOW, oPlayer); + } + } + } + } + nIndex++; + eEffect = GetNextEffect(oPlayer); + } +} +void ai_CreateEffectIconMenu(object oPlayer, int nEffectIconID) +{ + int nIconEffectType = EffectIconToEffectType(nEffectIconID); + if(nIconEffectType == EFFECT_TYPE_INVALIDEFFECT) return; + int nLine, nColor, nIndex, nEffectIndex; + int bSkipDisplay, bHasEffect; + int nEffectType, bIsSpellLevelAbsorptionPretendingToBeSpellImmunity; + string sText; + json jEffectID = JsonArray(); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 27 + sText = Get2DAStrRef("effecticons", "StrRef", nEffectIconID); + json jRow = CreateLabel(JsonArray(), "Effect: " + sText, "lbl_buff_name", 700.0f, 15.0f, NUI_HALIGN_LEFT, NUI_VALIGN_MIDDLE, 0.0); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + float fHeight = 27.0; + effect eEffect = GetFirstEffect(oPlayer); + while(GetIsEffectValid(eEffect)) + { + bSkipDisplay = FALSE; + nEffectType = GetEffectType(eEffect); + // Unlimited EffectSpellLevelAbsorption has a SpellImmunity Icon + if (nIconEffectType == EFFECT_TYPE_SPELL_IMMUNITY && GetEffectInteger(eEffect, 3)) + { + bIsSpellLevelAbsorptionPretendingToBeSpellImmunity = TRUE; + nIconEffectType = EFFECT_TYPE_SPELLLEVELABSORPTION; + } + if (nEffectType == nIconEffectType) + { + bHasEffect = TRUE; + int nSpellID = GetEffectSpellId(eEffect); + string sSpellName = nSpellID == -1 ? "" : Get2DAStrRef("spells", "Name", nSpellID); + int bIsPermanentEffect = GetEffectDurationType(eEffect) == DURATION_TYPE_PERMANENT; + int nDurationRemaining = GetEffectDurationRemaining(eEffect); + string sDurationRemaining = bIsPermanentEffect ? "(Permanent)" : "(" + SecondsToTimestamp(nDurationRemaining) + ")"; + if(bIsPermanentEffect) nColor = 0x0000FFFF; + else + { + float fPercentage = IntToFloat(nDurationRemaining) / IntToFloat(GetEffectDuration(eEffect)); + if(fPercentage > 0.5f) nColor = 0x00FF00FF; + else if(fPercentage < 0.25f) nColor = 0xFF0000FF; + else nColor = 0xFFFF00FF; + } + string sStats = ""; + string sRacialTypeAlignment = ""; + switch (nEffectType) + { + case EFFECT_TYPE_AC_INCREASE: + case EFFECT_TYPE_AC_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_AC_INCREASE, EFFECT_TYPE_AC_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + ACTypeToString(GetEffectInteger(eEffect, 0)) + " AC"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_ATTACK_INCREASE: + case EFFECT_TYPE_ATTACK_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_ATTACK_INCREASE, EFFECT_TYPE_ATTACK_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) +" AB"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_SAVING_THROW_INCREASE: + case EFFECT_TYPE_SAVING_THROW_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SAVING_THROW_INCREASE, EFFECT_TYPE_SAVING_THROW_DECREASE); + string sSavingThrow = SavingThrowToString(GetEffectInteger(eEffect, 1)); + string sSavingThrowType = SavingThrowTypeToString(GetEffectInteger(eEffect, 2)); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + " " + sSavingThrow + (sSavingThrowType == "" ? "" : " (vs. " + sSavingThrowType + ")"); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4), GetEffectInteger(eEffect, 5)); + break; + } + case EFFECT_TYPE_ABILITY_INCREASE: + case EFFECT_TYPE_ABILITY_DECREASE: + { + int nAbility = AbilityTypeFromEffectIconAbility(nEffectIconID); + + if (nAbility != GetEffectInteger(eEffect, 0)) + bSkipDisplay = TRUE; + else + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_ABILITY_INCREASE, EFFECT_TYPE_ABILITY_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + AbilityToString(nAbility); + } + break; + } + case EFFECT_TYPE_DAMAGE_INCREASE: + case EFFECT_TYPE_DAMAGE_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_DAMAGE_INCREASE, EFFECT_TYPE_DAMAGE_DECREASE); + sStats = sModifier + Get2DAStrRef("iprp_damagecost", "Name", GetEffectInteger(eEffect, 0)) + " (" + DamageTypeToString(GetEffectInteger(eEffect, 1)) + ")"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_SKILL_INCREASE: + case EFFECT_TYPE_SKILL_DECREASE: + { + int nSkill = GetEffectInteger(eEffect, 0); + string sSkill = nSkill == 255 ? "All Skills" : Get2DAStrRef("skills", "Name", nSkill); + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SKILL_INCREASE, EFFECT_TYPE_SKILL_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + " " + sSkill; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3), GetEffectInteger(eEffect, 4)); + break; + } + case EFFECT_TYPE_TEMPORARY_HITPOINTS: + { + sStats = "+" + IntToString(GetEffectInteger(eEffect, 0)) + " HitPoints"; + break; + } + case EFFECT_TYPE_DAMAGE_REDUCTION: + { + int nAmount = GetEffectInteger(eEffect, 0); + int nDamagePower = GetEffectInteger(eEffect, 1); + nDamagePower = nDamagePower > 6 ? --nDamagePower : nDamagePower; + int nRemaining = GetEffectInteger(eEffect, 2); + sStats = IntToString(nAmount) + "/+" + IntToString(nDamagePower) + " (" + (nRemaining == 0 ? "Unlimited" : IntToString(nRemaining) + " Damage Remaining") + ")"; + break; + } + case EFFECT_TYPE_DAMAGE_RESISTANCE: + { + int nAmount = GetEffectInteger(eEffect, 1); + int nRemaining = GetEffectInteger(eEffect, 2); + sStats = IntToString(nAmount) + "/- " + DamageTypeToString(GetEffectInteger(eEffect, 0)) + " Resistance (" + (nRemaining == 0 ? "Unlimited" : IntToString(nRemaining) + " Damage Remaining") + ")"; + break; + } + case EFFECT_TYPE_IMMUNITY: + { + int nImmunity = ImmunityTypeFromEffectIconImmunity(nEffectIconID); + + if (nImmunity != GetEffectInteger(eEffect, 0)) + bSkipDisplay = TRUE; + else + { + sStats = Get2DAStrRef("effecticons", "StrRef", nEffectIconID); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + } + break; + } + case EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE: + case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE: + { + int nDamageType = GetEffectInteger(eEffect, 0); + int nDamageTypeFromIcon = DamageTypeFromEffectIconDamageImmunity(nEffectIconID); + + if (nDamageTypeFromIcon != -1 && nDamageType != nDamageTypeFromIcon) + bSkipDisplay = TRUE; + + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE, EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 1)) + "% " + DamageTypeToString(nDamageType) + " Damage Immunity"; + break; + } + case EFFECT_TYPE_SPELL_IMMUNITY: + { + sStats = "Spell Immunity: " + Get2DAStrRef("spells", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_SPELLLEVELABSORPTION: + { + int nMaxSpellLevelAbsorbed = GetEffectInteger(eEffect, 0); + int bUnlimited = GetEffectInteger(eEffect, 3); + string sSpellLevel; + switch (nMaxSpellLevelAbsorbed) + { + case 0: sSpellLevel = "Cantrip"; break; + case 1: sSpellLevel = "1st"; break; + case 2: sSpellLevel = "2nd"; break; + case 3: sSpellLevel = "3rd"; break; + default: sSpellLevel = IntToString(nMaxSpellLevelAbsorbed) + "th"; break; + } + sSpellLevel += " Level" + (nMaxSpellLevelAbsorbed == 0 ? "" : " and Below"); + string sSpellSchool = SpellSchoolToString(GetEffectInteger(eEffect, 2)); + string sRemainingSpellLevels = bUnlimited ? "" : "(" + IntToString(GetEffectInteger(eEffect, 1)) + " Spell Levels Remaining)"; + sStats = sSpellLevel + " " + sSpellSchool + " Spell Immunity " + sRemainingSpellLevels; + + if (bIsSpellLevelAbsorptionPretendingToBeSpellImmunity) + nIconEffectType = EFFECT_TYPE_SPELL_IMMUNITY; + else if (bUnlimited && !bIsSpellLevelAbsorptionPretendingToBeSpellImmunity) + bSkipDisplay = TRUE; + + break; + } + case EFFECT_TYPE_REGENERATE: + { + sStats = "+" + IntToString(GetEffectInteger(eEffect, 0)) + " HP / " + FloatToString((GetEffectInteger(eEffect, 1) / 1000.0f), 0, 2) + "s"; + break; + } + case EFFECT_TYPE_POISON: + { + sStats = "Poison: " + Get2DAStrRef("poison", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_DISEASE: + { + sStats = "Disease: " + Get2DAStrRef("disease", "Name", GetEffectInteger(eEffect, 0)); + break; + } + case EFFECT_TYPE_CURSE: + { + int nAbility; + string sAbilityDecrease; + for (nAbility = 0; nAbility < 6; nAbility++) + { + int nAbilityMod = GetEffectInteger(eEffect, nAbility); + if (nAbilityMod > 0) + { + string sAbility = GetStringLeft(AbilityToString(nAbility), 3); + sAbilityDecrease += "-" + IntToString(nAbilityMod) + " " + sAbility + ", "; + } + } + sAbilityDecrease = GetStringLeft(sAbilityDecrease, GetStringLength(sAbilityDecrease) - 2); + sStats = sAbilityDecrease; + break; + } + case EFFECT_TYPE_MOVEMENT_SPEED_INCREASE: + case EFFECT_TYPE_MOVEMENT_SPEED_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_MOVEMENT_SPEED_INCREASE, EFFECT_TYPE_MOVEMENT_SPEED_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + "% Movement Speed"; + break; + } + case EFFECT_TYPE_ELEMENTALSHIELD: + { + sStats = IntToString(GetEffectInteger(eEffect, 0)) + " + " + Get2DAStrRef("iprp_damagecost", "Name", GetEffectInteger(eEffect, 1)) + " (" + DamageTypeToString(GetEffectInteger(eEffect, 2)) + ")"; + break; + } + case EFFECT_TYPE_NEGATIVELEVEL: + { + sStats = "-" + IntToString(GetEffectInteger(eEffect, 0)) + " Levels"; + break; + } + case EFFECT_TYPE_CONCEALMENT: + { + string sMissChance = MissChanceToString(GetEffectInteger(eEffect, 4) - 1); + sStats = IntToString(GetEffectInteger(eEffect, 0)) + "% Concealment" + (sMissChance == "" ? "" : " (" + sMissChance + ")"); + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + break; + } + case EFFECT_TYPE_SPELL_RESISTANCE_INCREASE: + case EFFECT_TYPE_SPELL_RESISTANCE_DECREASE: + { + string sModifier = GetModifierType(nEffectType, EFFECT_TYPE_SPELL_RESISTANCE_INCREASE, EFFECT_TYPE_SPELL_RESISTANCE_DECREASE); + sStats = sModifier + IntToString(GetEffectInteger(eEffect, 0)) + " Spell Resistance"; + break; + } + case EFFECT_TYPE_SPELL_FAILURE: + { + sStats = IntToString(GetEffectInteger(eEffect, 0)) + "% Spell Failure (Spell School: " + SpellSchoolToString(GetEffectInteger(eEffect, 1)) + ")"; + break; + } + case EFFECT_TYPE_INVISIBILITY: + { + int nInvisibilityType = GetEffectInteger(eEffect, 0); + if (nEffectIconID == EFFECT_ICON_INVISIBILITY) + bSkipDisplay = nInvisibilityType != INVISIBILITY_TYPE_NORMAL; + else if (nEffectIconID == EFFECT_ICON_IMPROVEDINVISIBILITY) + bSkipDisplay = nInvisibilityType != INVISIBILITY_TYPE_IMPROVED; + if (!bSkipDisplay) + { + sStats = (nInvisibilityType == INVISIBILITY_TYPE_IMPROVED ? "Improved " : "") + "Invisibility"; + sRacialTypeAlignment = GetVersusRacialTypeAndAlignment(GetEffectInteger(eEffect, 1), GetEffectInteger(eEffect, 2), GetEffectInteger(eEffect, 3)); + } + break; + } + case EFFECT_TYPE_HASTE: + { + sStats = "Hasted"; + } + } + if(!bSkipDisplay) + { + sText = sSpellName + " " + sDurationRemaining + (sStats == "" ? "" : " -> " + sStats + sRacialTypeAlignment); + if(sText != "") + { + jRow = CreateLabel(JsonArray(), " " + sText, "lbl_buff_info" + IntToString(nIndex), 700.0f, 10.0f, NUI_HALIGN_LEFT, NUI_VALIGN_TOP, 0.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 10.0; + object oSource = GetEffectCreator(eEffect); + if(GetIsObjectValid(oSource)) + { + sText = GetObjectType(oSource) ? GetName(oSource) : ""; + sText = " Creator: " + sText; + float fLength = IntToFloat(GetStringLength(sText) * 8); + jRow = CreateLabel(JsonArray(), sText, "lbl_buff_source" + IntToString(nIndex), fLength, 15.0f, NUI_HALIGN_LEFT, NUI_VALIGN_BOTTOM, 0.0); + if(oSource == oPlayer) + { + CreateButton(jRow, "Remove", "btn_remove_effect_" + IntToString(nEffectIndex++), 70.0f, 20.0f, 0.0); + jEffectID = JsonArrayInsert(jEffectID, JsonString(GetEffectLinkId(eEffect))); + fHeight += 20.0; + } + else fHeight += 15.0; + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + } + } + } + } + nIndex++; + eEffect = GetNextEffect(oPlayer); + } + float fScale = IntToFloat(GetPlayerDeviceProperty(oPlayer, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0; + float fX = IntToFloat(GetPlayerDeviceProperty(oPlayer, PLAYER_DEVICE_PROPERTY_GUI_WIDTH)); + fX = fX - (700.0 * fScale); + float fY = 50 * fScale; + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPlayer, jLayout, AI_EFFECT_ICON_NUI, "Effect Icon Menu", + fX, fY, 700.0, fHeight * fScale, FALSE, FALSE, FALSE, TRUE, FALSE, "0e_nui"); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oPlayer))); + jData = JsonArrayInsert(jData, JsonInt(nEffectIconID)); + jData = JsonArrayInsert(jData, jEffectID); + NuiSetUserData(oPlayer, nToken, jData); + NuiSetBind(oPlayer, nToken, "lbl_buff_name_event", JsonBool(TRUE)); + while(nIndex >= 0) + { + NuiSetBind(oPlayer, nToken, "lbl_buff_info" + IntToString(nIndex) + "_event", JsonBool(TRUE)); + NuiSetBind(oPlayer, nToken, "lbl_buff_source" + IntToString(nIndex) + "_event", JsonBool(TRUE)); + nIndex--; + } + while(nEffectIndex >= 0) + { + NuiSetBind(oPlayer, nToken, "btn_remove_effect_" + IntToString(nEffectIndex) + "_event", JsonBool(TRUE)); + NuiSetBind(oPlayer, nToken, "btn_remove_effect_" + IntToString(nEffectIndex), JsonInt(TRUE)); + nEffectIndex--; + } +} diff --git a/src/module/nss/0i_items.nss b/src/module/nss/0i_items.nss new file mode 100644 index 0000000..87d3ce7 --- /dev/null +++ b/src/module/nss/0i_items.nss @@ -0,0 +1,1243 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +Script Name: 0i_items +Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts for use with items. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +//#include "0i_main" +#include "0i_messages" +// Returns TRUE if oItem is a weapon. +int ai_GetIsWeapon(object oItem); +// Returns TRUE if oItem is a melee weapon. +int ai_GetIsMeleeWeapon(object oItem); +// Returns TRUE if oItem is a slashing weapon. +int ai_GetIsSlashingWeapon(object oItem); +// Returns TRUE if oItem is a piercing weapon. +int ai_GetIsPiercingWeapon(object oItem); +// Returns TRUE if oItem is a bludgeoning weapon. +int ai_GetIsBludgeoningWeapon(object oItem); +// Returns TRUE if oItem is an ammo. +int ai_GetIsAmmo(object oItem); +// Returns TRUE if oItem is a thrown weapon. +int ai_GetIsThrownWeapon(object oItem); +// Returns TRUE if oItem is able to be used single handed by oCreature. +int ai_GetIsSingleHandedWeapon(object oItem, object oCreature); +// Returns TRUE if oItem is a light weapon for oCreature. +int ai_GetIsLightWeapon(object oItem, object oCreature); +// Returns TRUE if oItem is able to be used two handed by oCreature. +int ai_GetIsTwoHandedWeapon(object oItem, object oCreature); +// Returns TRUE if oItem is a double weapon. +int ai_GetIsDoubleWeapon(object oItem); +// Returns TRUE if oCreature has a ranged weapon equiped and has ammo for it. +int ai_HasRangedWeaponWithAmmo(object oCreature); +// Returns TRUE if oItem is a ranged weapon. +int ai_GetIsRangeWeapon(object oItem); +// Returns the amount of damage the weapon oCreature is holding. +// nDamageAmount tells the function the amount of damage to return; +// 1 - Minimum, 2- Average, 3 Maximum. +// bMelee If it is not a melee weapon then return 0; +int ai_GetWeaponDamage(object oCreature, int nDamageAmount = 3, int bMelee = FALSE); +// Returns TRUE if oItem is a shield. +int ai_GetIsShield(object oItem); +// Returns the size of oItem using 1 = small to 6 = large. +int ai_GetItemSize(object oItem); +// Returns TRUE if the caller has a potion that is identified of nSpell. +int ai_CheckPotionIsIdentified(object oCreature, int nSpell); +// Returns an item from oCreature's inventory with sTag. +// bCheckEquiped will also look through the creatures equiped items. +// Returns OBJECT_INVALID if the items does not exist with sTag. +object ai_GetCreatureHasItem(object oCreature, string sTag, int bCheckEquiped = FALSE); +// Returns TRUE if oCreature can identify oItem based on the file SkillVsItemCost.2da +// Reports the findings to oPC unless oPC = OBJECT_INVALID. +// If the item can be identified by oCreature then it will be identified. +int ai_IdentifyItemVsKnowledge(object oCreature, object oItem, object oPC = OBJECT_INVALID); +// Identifies all items on oObject based on the file SkillVsItemCost.2da +// Reports the findings to oPC unless oPC = OBJECT_INVALID +// bIdentifyAll ignores the chart and does what it says! +void ai_IdentifyAllVsKnowledge(object oCreature, object oContainer, object oPC = OBJECT_INVALID); +// Will (Un)Identify all items on oCreature. +// If bIdentify is TRUE they will all be Identified, FALSE Unidentifies them. +void ai_SetIdentifyAllItems(object oCreature, int bIdentify = TRUE); +// Returns oWeapons attack bonus from either Enhancment or Attack bonus. +int ai_GetWeaponAtkBonus(object oWeapon); +// Returns oArmors armor bonus. +int ai_GetArmorBonus(object oArmor); +// Returns the maximum gold value that an item can have to be equiped. +int ai_GetMaxItemValueThatCanBeEquiped(int nLevel); +// Returns the minimum level that is required to equip this item. +int ai_GetMinimumEquipLevel(object oItem); +// Returns oCreatures total attack bonus with melee weapon (Mostly). +int ai_GetCreatureAttackBonus(object oCreature); +// Returns TRUE if oCreature can use oItem based on Class, Race, and Alignment +// restrictions. Also checks UseMagicDevice of oCreature. +int ai_CheckIfCanUseItem(object oCreature, object oItem); +// Returns TRUE if oCreature can use oItem due to feats. +int ai_GetIsProficientWith(object oCreature, object oItem); +// Gets the Average Damage on the weapon for Main and Off Hand to allow +// us to check which weapon is better for oCreature to equip. +// b2Handed set to TRUE returns only checks main avg damage. +// bOffHand set to TRUE returns the OffHand avg damage. +// if b2Handed & bOffHand are set to TRUE it returns main & offhand added together. +// if oOffWeapon is Set then it will return the Avg Damage assuming oItem is +// the Main weapon and oOffWeapon is in the Offhand. +float ai_GetMeleeWeaponAvgDmg(object oCreature, object oItem, int b2Handed = FALSE, int bOffHand = FALSE, object oOffWeapon = OBJECT_INVALID); +// Sets shield AC on the shield to allow us to check which shield is better +// for oCreature to equip. +int ai_SetShieldAC(object oCreature, object oItem); +// Returns TRUE if oItem has nItemPropertyType. +// nItemPropertySubType will not be used if its below 0. +int ai_GetHasItemProperty(object oItem, int nItemPropertyType, int nItemPropertySubType = -1); +// Returns the highest bonus Lock Picks needed to unlock nLockDC in oCreatures inventory. +object ai_GetBestPicks(object oCreature, int nLockDC); +// Removes all items from oCreature. +void ai_RemoveInventory(object oCreature); +// Copies all equiped and inventory items from oOldHenchman to oNewHenchman. +void ai_MoveInventory(object oOldHenchman, object oNewHenchman); +// Returns if oCreature is proficient with nBaseItem. +// PRC lets the creature use any weapon, but gives -4 penalty if not proficient. +int prc_IsProficient(object oCreature, int nBaseItem); + +int ai_GetIsWeapon(object oItem) +{ + int nType = GetBaseItemType(oItem); + int nWeaponType = StringToInt(Get2DAString("baseitems", "WeaponType", nType)); + if(nWeaponType) return TRUE; + return FALSE; +} +int ai_GetIsMeleeWeapon(object oItem) +{ + int nType = GetBaseItemType(oItem); + if(StringToInt(Get2DAString("baseitems", "WeaponType", nType)) > 0) + { + if(StringToInt(Get2DAString("baseitems", "RangedWeapon", nType)) == 0) return TRUE; + } + return FALSE; +} +int ai_GetIsSingleHandedWeapon(object oItem, object oCreature) +{ + if(!ai_GetIsMeleeWeapon(oItem)) return FALSE; + int nBaseItemType = GetBaseItemType(oItem); + // Weapon Size in the baseitems.2da is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nBaseItemType)); + // Creature size is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nCreatureSize = GetCreatureSize(oCreature); + return nWeaponSize <= nCreatureSize; +} +int ai_GetIsLightWeapon(object oItem, object oCreature) +{ + if(!ai_GetIsMeleeWeapon(oItem)) return FALSE; + int nBaseItemType = GetBaseItemType(oItem); + // Weapon Size in the baseitems.2da is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nBaseItemType)); + // Creature size is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nCreatureSize = GetCreatureSize(oCreature); + return nWeaponSize < nCreatureSize; +} +int ai_GetIsTwoHandedWeapon(object oItem, object oCreature) +{ + if(!ai_GetIsMeleeWeapon(oItem)) return FALSE; + int nBaseItemType = GetBaseItemType(oItem); + // Weapon Size in the baseitems.2da is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nBaseItemType)); + // Ranged weapons have a value greater than 0 in this field. So melee weapons have 0. + int nWeaponMelee = StringToInt(Get2DAString("baseitems", "RangedWeapon", nBaseItemType)); + // Creature size is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nCreatureSize = GetCreatureSize(oCreature); + return (nWeaponMelee == 0 && nWeaponSize > nCreatureSize); +} +int ai_GetIsDoubleWeapon(object oItem) +{ + int iType = GetBaseItemType(oItem); + switch(iType) + { + case BASE_ITEM_DIREMACE: + case BASE_ITEM_DOUBLEAXE: + case BASE_ITEM_TWOBLADEDSWORD: return TRUE; + } + return FALSE; +} +int ai_GetIsSlashingWeapon(object oItem) +{ + int iBaseItemType = GetBaseItemType(oItem); + int iWeaponType = StringToInt(Get2DAString("baseitems", "WeaponType", iBaseItemType)); + // Weapon Type in the baseitems.2da is 1 = Piercing, 2 = Bludgeoning, 3 = Slashing. + return (iWeaponType == 3); +} +int ai_GetIsPiercingWeapon(object oItem) +{ + int iBaseItemType = GetBaseItemType(oItem); + int iWeaponType = StringToInt(Get2DAString("baseitems", "WeaponType", iBaseItemType)); + // Weapon Type in the baseitems.2da is 1 = Piercing, 2 = Bludgeoning, 3 = Slashing. + return (iWeaponType == 1); +} +int ai_GetIsBludgeoningWeapon(object oItem) +{ + int iBaseItemType = GetBaseItemType(oItem); + int iWeaponType = StringToInt(Get2DAString("baseitems", "WeaponType", iBaseItemType)); + // Weapon Type in the baseitems.2da is 1 = Piercing, 2 = Bludgeoning, 3 = Slashing. + return (iWeaponType == 2); +} +int ai_GetIsAmmo(object oItem) +{ + switch(GetBaseItemType(oItem)) + { + case BASE_ITEM_ARROW: return TRUE; + case BASE_ITEM_BOLT: return TRUE; + case BASE_ITEM_BULLET: return TRUE; + } + return FALSE; +} +int ai_GetIsThrownWeapon(object oItem) +{ + switch(GetBaseItemType(oItem)) + { + case BASE_ITEM_DART: return TRUE; + case BASE_ITEM_SHURIKEN: return TRUE; + case BASE_ITEM_THROWINGAXE: return TRUE; + } + return FALSE; +} +int ai_HasRangedWeaponWithAmmo(object oCreature) +{ + object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + if(!GetWeaponRanged(oWeapon)) return FALSE; + int nAmmoType, nWeaponType = GetBaseItemType(oWeapon); + object oAmmo = OBJECT_INVALID; + if(nWeaponType == BASE_ITEM_LONGBOW || nWeaponType == BASE_ITEM_SHORTBOW) + { + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_UNLIMITED_AMMUNITION)) return TRUE; + if(GetItemInSlot(INVENTORY_SLOT_ARROWS, oCreature) != OBJECT_INVALID) return TRUE; + nAmmoType = BASE_ITEM_ARROW; + } + else if(nWeaponType == BASE_ITEM_LIGHTCROSSBOW || nWeaponType == BASE_ITEM_HEAVYCROSSBOW) + { + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_UNLIMITED_AMMUNITION)) return TRUE; + if(GetItemInSlot(INVENTORY_SLOT_BOLTS, oCreature) != OBJECT_INVALID) return TRUE; + nAmmoType = BASE_ITEM_BOLT; + } + else if(nWeaponType == BASE_ITEM_SLING) + { + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_UNLIMITED_AMMUNITION)) return TRUE; + if(GetItemInSlot(INVENTORY_SLOT_BULLETS, oCreature) != OBJECT_INVALID) return TRUE; + nAmmoType = BASE_ITEM_BULLET; + } + else if(nWeaponType == BASE_ITEM_THROWINGAXE) return TRUE; + else if(nWeaponType == BASE_ITEM_SHURIKEN) return TRUE; + else if(nWeaponType == BASE_ITEM_DART) return TRUE; + // They don't have any ammo in the slot, but do they have ammo in the inventory? + oAmmo = GetFirstItemInInventory(oCreature); + while(oAmmo != OBJECT_INVALID) + { + if(GetBaseItemType(oAmmo) == nAmmoType) + { + if(nAmmoType == BASE_ITEM_ARROW) ActionEquipItem(oAmmo, INVENTORY_SLOT_ARROWS); + else if(nAmmoType == BASE_ITEM_BOLT) ActionEquipItem(oAmmo, INVENTORY_SLOT_BOLTS); + else if(nAmmoType == BASE_ITEM_BULLET) ActionEquipItem(oAmmo, INVENTORY_SLOT_BULLETS); + return TRUE; + } + oAmmo = GetNextItemInInventory(oCreature); + } + //ai_Debug("0i_items", "254", "They are out of ammo!"); + return FALSE; +} +int ai_GetIsRangeWeapon(object oItem) +{ + switch(GetBaseItemType(oItem)) + { + case BASE_ITEM_DART: return TRUE; + case BASE_ITEM_HEAVYCROSSBOW: return TRUE; + case BASE_ITEM_LIGHTCROSSBOW: return TRUE; + case BASE_ITEM_LONGBOW: return TRUE; + case BASE_ITEM_SHORTBOW: return TRUE; + case BASE_ITEM_SHURIKEN: return TRUE; + case BASE_ITEM_SLING: return TRUE; + case BASE_ITEM_THROWINGAXE: return TRUE; + } + return FALSE; +} +int ai_GetIsFinesseWeapon(object oCreature, object oItem) +{ + switch(GetBaseItemType(oItem)) + { + case BASE_ITEM_DAGGER: return TRUE; + case BASE_ITEM_HANDAXE: return TRUE; + case BASE_ITEM_KAMA: return TRUE; + case BASE_ITEM_KUKRI: return TRUE; + case BASE_ITEM_LIGHTHAMMER: return TRUE; + case BASE_ITEM_LIGHTMACE: return TRUE; + case BASE_ITEM_RAPIER: + { + if(GetCreatureSize(oCreature) > CREATURE_SIZE_SMALL) return TRUE; + return FALSE; + } + case BASE_ITEM_SHORTSWORD: return TRUE; + case BASE_ITEM_SICKLE: return TRUE; + case BASE_ITEM_WHIP: return TRUE; + } + return FALSE; +} +int ai_GetWeaponDamage(object oCreature, int nDamageAmount = 3, int bMelee = FALSE) +{ + object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + if(bMelee && ai_GetIsRangeWeapon(oItem)) return 0; + int nWeaponDamage = GetLocalInt(oItem, "AI_WEAPON_DAMAGE"); + if(!nWeaponDamage) + { + if(ai_GetIsMeleeWeapon(oItem)) + { + nWeaponDamage = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(ai_GetIsTwoHandedWeapon(oItem, oCreature)) nWeaponDamage += nWeaponDamage / 2; + } + int nWeaponDice = StringToInt(Get2DAString("baseitems", "NumDice", GetBaseItemType(oItem))); + int nWeaponDie = StringToInt(Get2DAString("baseitems", "DieToRoll", GetBaseItemType(oItem))); + if(nDamageAmount == 1) + { + nWeaponDamage += nWeaponDice; + } + else if(nDamageAmount == 2) + { + nWeaponDamage += nWeaponDice * nWeaponDie / 2; + } + else + { + nWeaponDamage += nWeaponDice * nWeaponDie; + } + SetLocalInt(oItem, "AI_WEAPON_DAMAGE", nWeaponDamage); + } + return nWeaponDamage; +} +int ai_GetIsShield(object oItem) +{ + switch(GetBaseItemType(oItem)) + { + case BASE_ITEM_SMALLSHIELD: return TRUE; + case BASE_ITEM_LARGESHIELD: return TRUE; + case BASE_ITEM_TOWERSHIELD: return TRUE; + } + return FALSE; + } +int ai_GetItemSize(object oItem) +{ + int nBaseItemType = GetBaseItemType(oItem); + int nWidth = StringToInt(Get2DAString("baseitems", "InvSlotWidth", nBaseItemType)); + int nHeight = StringToInt(Get2DAString("baseitems", "InvSlotHeight", nBaseItemType)); + return nWidth + nHeight - 1; +} +int ai_CheckPotionIsIdentified(object oCreature, int nSpell) +{ + int nPotionSpell; + itemproperty ipPotion; + object oPotion = GetFirstItemInInventory(oCreature); + while(oPotion != OBJECT_INVALID) + { + if(GetIdentified(oPotion)) + { + ipPotion = GetFirstItemProperty(oPotion); + nPotionSpell = GetItemPropertySubType(ipPotion); + nPotionSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nPotionSpell)); + //ai_Debug("0i_talents", "318", "Potion ID'ed? nSpell: " + IntToString(nSpell) + " nPotionSpell: " + IntToString(nPotionSpell)); + if(nSpell == nPotionSpell) return TRUE; + } + oPotion = GetNextItemInInventory(oCreature); + } + return FALSE; +} +object ai_GetCreatureHasItem(object oCreature, string sTag, int bCheckEquiped = FALSE) +{ + // Cycle through the creatures unequiped items. + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetTag(oItem) == sTag) return oItem; + oItem = GetNextItemInInventory(oCreature); + } + // Should we check the creatures equiped items. + // If we have already found it then stop looking. + int nSlot = 0; + if(bCheckEquiped) + { + // Check all of the creatures slots(0 - 17). + while(nSlot <= 17) + { + oItem = GetItemInSlot(nSlot, oCreature); + if(GetTag(oItem) == sTag) return oItem; + nSlot ++; + } + } + return OBJECT_INVALID; +} +int ai_IdentifyItemVsKnowledge(object oCreature, object oItem, object oPC = OBJECT_INVALID) +{ + if(GetIdentified(oItem)) return FALSE; + int nKnowledge = GetSkillRank(SKILL_LORE, oCreature); + int nItemValue; // gold value of item + string sBaseName; + string sMaxValue = Get2DAString("SkillVsItemCost", "DeviceCostMax", nKnowledge); + int nMaxValue = StringToInt(sMaxValue); + // * Handle overflow(November 2003 - BK) + if(sMaxValue == "") nMaxValue = 0; + // Setting TRUE to get the true value of the item. + SetIdentified(oItem, TRUE); + nItemValue = GetGoldPieceValue(oItem); + if(nMaxValue <= nItemValue) + { + SetIdentified(oItem, FALSE); + if(oPC != OBJECT_INVALID) + { + sBaseName = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "name", GetBaseItemType(oItem)))); + ai_SendMessages(GetName(oCreature) + " cannot identify " + sBaseName, AI_COLOR_RED, oPC); + } + } + else + { + if(oPC != OBJECT_INVALID) ai_SendMessages(GetName(oCreature) + " has identified " + GetName(oItem), AI_COLOR_GREEN, oPC); + return TRUE; + } + return FALSE; +} +void ai_IdentifyAllVsKnowledge(object oCreature, object oContainer, object oPC = OBJECT_INVALID) +{ + // SkillVsItemCost 2da starts 1 at 0 ... go figure! + int nKnowledge = GetSkillRank(SKILL_LORE, oCreature) - 1; + int nItemValue; // gold value of item + string sBaseName; + string sMaxValue = Get2DAString("SkillVsItemCost", "DeviceCostMax", nKnowledge); + int nMaxValue = StringToInt(sMaxValue); + // * Handle overflow(November 2003 - BK) + if(sMaxValue == "") nMaxValue = 0; + object oItem = GetFirstItemInInventory(oContainer); + while(oItem != OBJECT_INVALID) + { + if(!GetIdentified(oItem)) + { + // setting TRUE to get the true value of the item. + SetIdentified(oItem, TRUE); + nItemValue = GetGoldPieceValue(oItem); + if(nMaxValue < nItemValue) + { + SetIdentified(oItem, FALSE); + sBaseName = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "name", GetBaseItemType(oItem)))); + if(oPC != OBJECT_INVALID) ai_SendMessages(GetName(oCreature) + " cannot identify " + sBaseName, AI_COLOR_RED, oPC); + } + else if(oPC != OBJECT_INVALID) ai_SendMessages(GetName(oCreature) + " has identified " + GetName(oItem), AI_COLOR_GREEN, oPC); + } + oItem = GetNextItemInInventory(oContainer); + } +} +void ai_SetIdentifyAllItems(object oCreature, int bIdentify = TRUE) +{ + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(!GetIdentified(oItem)) SetIdentified(oItem, bIdentify); + oItem = GetNextItemInInventory(oCreature); + } + int nSlot; + oItem = GetItemInSlot(nSlot, oCreature); + while(nSlot < 11) + { + if(!GetIdentified(oItem)) SetIdentified(oItem, bIdentify); + oItem = GetItemInSlot(++nSlot, oCreature); + } +} +int ai_GetWeaponAtkBonus(object oWeapon) +{ + int nCounter = 1, nPropertyType, nBonus; + // Get first property + itemproperty ipProperty = GetFirstItemProperty(oWeapon); + while(GetIsItemPropertyValid(ipProperty)) + { + // Check to see if the property type matches. + nPropertyType = GetItemPropertyType(ipProperty); + if(nPropertyType == 6/*ITEMPROPERTY_ENHANCEMENT*/ || + nPropertyType == 56/*ITEMPROPERTY_ATTACKBONUS*/) + { + nBonus += GetItemPropertyCostTableValue(ipProperty); + } + // Get the next property. + ipProperty = GetNextItemProperty(oWeapon); + } + //ai_Debug("0i_items", "438", GetName(oWeapon) + " attack bonus is " + IntToString(nBonus)); + return nBonus; +} +int ai_GetArmorBonus(object oArmor) +{ + int nTorsoValue = GetItemAppearance(oArmor, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO); + //ai_Debug("0i_items", "444", "Armor Bonus: " + Get2DAString("parts_chest.2da", "ACBONUS", nTorsoValue)); + return StringToInt(Get2DAString("parts_chest", "ACBONUS", nTorsoValue)); +} +int ai_GetMaxItemValueThatCanBeEquiped(int nLevel) +{ + return StringToInt(Get2DAString("itemvalue", "MAXSINGLEITEMVALUE", nLevel - 1)); +} +int ai_GetMinimumEquipLevel(object oItem) +{ + int nIndex, nUnIdentified; + if(!GetIdentified(oItem)) + { + nUnIdentified = TRUE; + SetIdentified(oItem, TRUE); + } + int nGoldValue = GetGoldPieceValue(oItem); + if(nUnIdentified) SetIdentified(oItem, FALSE); + int n2daMaxRow = Get2DARowCount("itemvalue"); + while(nIndex < n2daMaxRow) + { + if(nGoldValue <= StringToInt(Get2DAString("itemvalue", "MAXSINGLEITEMVALUE", nIndex))) + { + return nIndex + 1; + } + nIndex++; + } + return nIndex; +} +int ai_GetCreatureAttackBonus(object oCreature) +{ + object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature); + int nAtkBonus = GetBaseAttackBonus(oCreature); + if((GetHasFeat(FEAT_WEAPON_FINESSE, oCreature) && ai_GetIsFinesseWeapon(oCreature, oWeapon)) || + ai_GetIsRangeWeapon(oWeapon)) + { + nAtkBonus += GetAbilityModifier(ABILITY_DEXTERITY, oCreature); + } + else nAtkBonus += GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(ai_GetIsMeleeWeapon(oWeapon)) nAtkBonus += ai_GetWeaponAtkBonus(oWeapon); + return nAtkBonus; + } +int ai_CheckUseMagicDevice(object oCreature, string sColumn, object oItem) +{ + if(!GetLocalInt(GetModule(), AI_RULE_ALLOW_UMD)) return FALSE; + int nUMD = GetSkillRank(SKILL_USE_MAGIC_DEVICE, oCreature); + //ai_Debug("0i_talents", "1600", GetName(oCreature) + " is check UMD: " + IntToString(nUMD)); + if(nUMD < 1) return FALSE; + int nDC, nIndex, nItemValue = GetGoldPieceValue(oItem); + while(nIndex < 55) + { + //ai_Debug("0i_talents", "1605", GetName(oItem) + " has a value of " + + // Get2DAString("skillvsitemcost", "DeviceCostMax", nIndex) + + // " nIndex: " + IntToString(nIndex)); + if(nItemValue < StringToInt(Get2DAString("skillvsitemcost", "DeviceCostMax", nIndex))) + { + //ai_Debug("0i_talents", "1610", "nUMD >= " + Get2DAString("skillvsitemcost", sColumn, nIndex)); + if(nUMD >= StringToInt(Get2DAString("skillvsitemcost", sColumn, nIndex))) return TRUE; + return FALSE; + } + nIndex++; + } + return FALSE; +} +int ai_CheckIfCanUseItem(object oCreature, object oItem) +{ + int bAlign, bClass, bRace, bAlignLimit, bClassLimit, bRaceLimit; + int nIprpSubType, nItemPropertyType; + // Check to see if this item is limited to a specific alignment, class, or race. + int nAlign1 = GetAlignmentLawChaos(oCreature); + int nAlign2 = GetAlignmentGoodEvil(oCreature); + int nRace = GetRacialType(oCreature); + //ai_Debug("0i_items", "615", "nAlign1: " + IntToString(nAlign1) + + // " nAlign2: " + IntToString(nAlign2) + " nRace: " + IntToString(nRace)); + itemproperty ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + nItemPropertyType = GetItemPropertyType(ipProp); + //ai_Debug("0i_items", "620", "ItempropertyType(62/63/64/65): " + IntToString(nItemPropertyType)); + if(nItemPropertyType == ITEM_PROPERTY_USE_LIMITATION_ALIGNMENT_GROUP) + { + bAlignLimit = TRUE; + // SubType is the group index for iprp_aligngrp.2da + nIprpSubType = GetItemPropertySubType(ipProp); + //ai_Debug("0i_items", "626", "nIprpSubType: " + IntToString(nIprpSubType)); + if(nIprpSubType == nAlign1 || nIprpSubType == nAlign2) bAlign = TRUE; + } + else if(nItemPropertyType == ITEM_PROPERTY_USE_LIMITATION_SPECIFIC_ALIGNMENT) + { + bAlignLimit = TRUE; + // SubType is the alignment index for iprp_alignment.2da + nIprpSubType = GetItemPropertySubType(ipProp); + //ai_Debug("0i_items", "634", "nIprpSubType: " + IntToString(nIprpSubType)); + if(nIprpSubType == 0 && nAlign1 == 2 && nAlign2 == 4) bAlign = TRUE; + else if(nIprpSubType == 1 && nAlign1 == 2 && nAlign2 == 1) bAlign = TRUE; + else if(nIprpSubType == 2 && nAlign1 == 2 && nAlign2 == 5) bAlign = TRUE; + else if(nIprpSubType == 3 && nAlign1 == 1 && nAlign2 == 4) bAlign = TRUE; + else if(nIprpSubType == 4 && nAlign1 == 1 && nAlign2 == 1) bAlign = TRUE; + else if(nIprpSubType == 5 && nAlign1 == 1 && nAlign2 == 5) bAlign = TRUE; + else if(nIprpSubType == 6 && nAlign1 == 3 && nAlign2 == 4) bAlign = TRUE; + else if(nIprpSubType == 7 && nAlign1 == 3 && nAlign2 == 1) bAlign = TRUE; + else if(nIprpSubType == 8 && nAlign1 == 3 && nAlign2 == 5) bAlign = TRUE; + } + else if(nItemPropertyType == ITEM_PROPERTY_USE_LIMITATION_CLASS) + { + bClassLimit = TRUE; + // SubType is the class index for classes.2da + nIprpSubType = GetItemPropertySubType(ipProp); + //ai_Debug("0i_items", "650", "nIprpSubType: " + IntToString(nIprpSubType)); + int nClassPosition = 1; + int nClass = GetClassByPosition(nClassPosition, oCreature); + while(nClassPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + if(nIprpSubType == nClass) bClass = TRUE; + nClass = GetClassByPosition(++nClassPosition, oCreature); + } + } + else if(nItemPropertyType == ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE) + { + bRaceLimit = TRUE; + // SubType is the race index for racialtypes.2da + nIprpSubType = GetItemPropertySubType(ipProp); + //ai_Debug("0i_items", "664", "nIprpSubType: " + IntToString(nIprpSubType)); + if(nIprpSubType == nRace) bRace = TRUE; + } + ipProp = GetNextItemProperty(oItem); + } + //ai_Debug("0i_items", "669", "bAlignLimit: " + IntToString(bAlignLimit) + " bAlign: " + IntToString(bAlign) + + // " bClassLimit: " + IntToString(bClassLimit) + " bClass: " + IntToString(bClass) + + // " bRaceLimit: " + IntToString(bRaceLimit) + " bRace: " + IntToString(bRace)); + if(bClassLimit && !bClass && !ai_CheckUseMagicDevice(oCreature, "SkillReq_Class", oItem)) return FALSE; + if(bRaceLimit && !bRace && !ai_CheckUseMagicDevice(oCreature, "SkillReq_Race", oItem)) return FALSE; + if(bAlignLimit && !bAlign && !ai_CheckUseMagicDevice(oCreature, "SkillReq_Align", oItem)) return FALSE; + return TRUE; +} +int ai_GetIsProficientWith(object oCreature, object oItem) +{ + int nWeaponType = GetBaseItemType(oItem); + // In the PRC you can equip any weapon. + if(GetLocalInt(GetModule(), AI_USING_PRC)) return TRUE; + int nFeat = StringToInt(Get2DAString("baseitems", "ReqFeat0", nWeaponType)); + // If it is 0 then it doesn't require a feat or we are at the end of the + // feat requirements. + if(nFeat == 0) return TRUE; + if(GetHasFeat(nFeat, oCreature)) return TRUE; + nFeat = StringToInt(Get2DAString("baseitems", "ReqFeat1", nWeaponType)); + if(nFeat == 0) return FALSE; + if(GetHasFeat(nFeat, oCreature)) return TRUE; + nFeat = StringToInt(Get2DAString("baseitems", "ReqFeat2", nWeaponType)); + if(nFeat == 0) return FALSE; + if(GetHasFeat(nFeat, oCreature)) return TRUE; + nFeat = StringToInt(Get2DAString("baseitems", "ReqFeat3", nWeaponType)); + if(nFeat == 0) return FALSE; + if(GetHasFeat(nFeat, oCreature)) return TRUE; + nFeat = StringToInt(Get2DAString("baseitems", "ReqFeat4", nWeaponType)); + if(nFeat == 0) return FALSE; + if(GetHasFeat(nFeat, oCreature)) return TRUE; + return FALSE; +} +float ai_GetMeleeWeaponAvgDmg(object oCreature, object oItem, int b2Handed = FALSE, int bOffHand = FALSE, object oOffWeapon = OBJECT_INVALID) +{ + // Has this weapon already been calculated for this creature? + if(oCreature == GetLocalObject(oItem, "AI_CREATURE_POSSESSION")) + { + // Return the Main weapons Avg Damage while using a weapon in the off hand. + if(oOffWeapon != OBJECT_INVALID) + { + // We recalculate all OffWeapon avg damage unless its a double weapon. + if(oOffWeapon == oItem) + { + float fMain2WDmg = GetLocalFloat(oItem, "AI_MAIN_2W_HAND_AVG_DMG"); + // If they passed that this is a 2handed weapon then return the total + // Avg Dmg for oItem. Used for double weapons. + if(b2Handed) + { + fMain2WDmg += ai_GetMeleeWeaponAvgDmg(oCreature, oItem, FALSE, TRUE); + } + if(AI_DEBUG) ai_Debug("0i_items", "611", GetName(oItem) + " avg dmg with Offhand weapon (" + GetName(oOffWeapon) + ") " + FloatToString(fMain2WDmg, 0, 2)); + return fMain2WDmg; + } + } + // Return the avg dmg for oItem assuming it is in the OffHand. + else if(bOffHand) + { + float fOffHandDmg = GetLocalFloat(oItem, "AI_OFFHAND_AVG_DMG"); + if(AI_DEBUG) ai_Debug("0i_items", "618", GetName(oItem) + " fOffHandAvgDmg: " + FloatToString(fOffHandDmg, 0, 2)); + return fOffHandDmg; + } + // If we get here then Return the avg dmg for oItem assuming its in the main hand. + else + { + float fMainDmg = GetLocalFloat(oItem, "AI_AVG_DMG"); + if(AI_DEBUG)ai_Debug("0i_items", "623", GetName(oItem) + " fMainDmg: " + FloatToString(fMainDmg, 0, 2)); + return fMainDmg; + } + } + // Set the creature to this item that we are calculationg the avg damages for. + SetLocalObject(oItem, "AI_CREATURE_POSSESSION", oCreature); + int nItemType = GetBaseItemType(oItem); + // Figure average damage for one attack, or two with two weapons. + // We are keeping it simple to reduce time and checks. + // Get the weapons base stats. + int nMinDmg = StringToInt(Get2DAString("baseitems", "NumDice", nItemType)); + int nMaxDmg = nMinDmg * StringToInt(Get2DAString("baseitems", "DieToRoll", nItemType)); + int nThreat = StringToInt(Get2DAString("baseitems", "CritThreat", nItemType)); + int nMultiplier = StringToInt(Get2DAString("baseitems", "CritHitMult", nItemType)); + int nIndex, nBonusMinDmg, nBonusMaxDmg, nItemPropertyType, nNumDice; + // We set ToHit to 10 for a 50% chance to hit without modifiers. + float fCritBonusDmg, fToHit = 10.0; + if(GetLocalInt(GetModule(), AI_USING_PRC)) + { + if(!prc_IsProficient(oCreature, nItemType)) fToHit -= 4.0; + } + // Check oCreature's feats. + if(GetHasFeat(FEAT_WEAPON_FINESSE, oCreature) && + ai_GetIsLightWeapon(oItem, oCreature)) + { + // Add Dexterity modifier to the Attack bonus. + nIndex = GetAbilityModifier(ABILITY_DEXTERITY, oCreature); + } + else + { + // Add Strength modifier to the attack bonus. + nIndex = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + // Add 1/2 strength modifier to damage for 2handed weapons, but not Double weapons. + if(b2Handed && !bOffHand) + { + nMinDmg += nIndex / 2; + nMaxDmg += nIndex / 2; + } + } + fToHit += nIndex; + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "WeaponFocusFeat", nItemType)), oCreature, TRUE)) + { + fToHit += 1.0; + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "WeaponSpecializationFeat", nItemType)), oCreature, TRUE)) + { + nMinDmg += 2; + nMaxDmg += 2; + } + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "EpicWeaponFocusFeat", nItemType)), oCreature, TRUE)) + { + fToHit += 2.0; + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "EpicWeaponSpecializationFeat", nItemType)), oCreature, TRUE)) + { + nMinDmg += 4; + nMaxDmg += 4; + } + } + } + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "WeaponImprovedCriticalFeat", nItemType)), oCreature, TRUE)) + { + nMultiplier += nMultiplier; + if(GetHasFeat(StringToInt(Get2DAString("baseitems", "EpicWeaponOverwhelmingCriticalFeat", nItemType)), oCreature, TRUE)) + { + if(nMultiplier > 3) fCritBonusDmg = 10.5; + else if(nMultiplier == 3) fCritBonusDmg = 7.0; + else fCritBonusDmg = 3.5; + } + } + // Check oItem's properties. + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + nItemPropertyType = GetItemPropertyType(ipProperty); + if(nItemPropertyType == ITEM_PROPERTY_ENHANCEMENT_BONUS) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nBonusMinDmg += nIndex; + nBonusMaxDmg += nIndex; + fToHit += IntToFloat(nIndex); + } + else if(nItemPropertyType == ITEM_PROPERTY_DAMAGE_BONUS) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nNumDice = StringToInt(Get2DAString("iprp_damagecost", "NumDice", nIndex)); + nBonusMinDmg += nNumDice; + nBonusMaxDmg += nNumDice * StringToInt(Get2DAString("iprp_damagecost", "Die", nIndex)); + } + else if(nItemPropertyType == ITEM_PROPERTY_ATTACK_BONUS) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + fToHit += IntToFloat(nIndex); + } + else if(nItemPropertyType == ITEM_PROPERTY_KEEN) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nMultiplier += nMultiplier; + } + else if(nItemPropertyType == ITEM_PROPERTY_HASTE) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nMinDmg += nMinDmg; + nMaxDmg += nMaxDmg; + nBonusMinDmg += nBonusMinDmg; + nBonusMaxDmg += nBonusMaxDmg; + nMultiplier += nMultiplier; + } + else if(nItemPropertyType == ITEM_PROPERTY_MASSIVE_CRITICALS) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nNumDice = StringToInt(Get2DAString("iprp_damagecost", "NumDice", nIndex)); + fCritBonusDmg += IntToFloat(nNumDice) + IntToFloat(nNumDice * StringToInt(Get2DAString("iprp_damagecost", "Die", nIndex))) / 2.0; + } + else if(nItemPropertyType == ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nBonusMinDmg -= nIndex; + nBonusMaxDmg -= nIndex; + fToHit -= IntToFloat(nIndex); + } + else if(nItemPropertyType == ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + fToHit -= IntToFloat(nIndex); + } + else if(nItemPropertyType == ITEM_PROPERTY_DECREASED_DAMAGE) + { + nIndex = GetItemPropertyCostTableValue(ipProperty); + nBonusMinDmg -= nIndex; + nBonusMaxDmg -= nIndex; + } + else if(nItemPropertyType == ITEM_PROPERTY_NO_DAMAGE) + { + // A weapon always does a minimum of 1 pnt of damage. + nMinDmg = 1; + nMaxDmg = 1; + } + ipProperty = GetNextItemProperty(oItem); + } + float fAvgDmg = IntToFloat(nMinDmg + nMaxDmg + nBonusMinDmg + nBonusMaxDmg) / 2; + // Set value for Offhand chance to hit. + float fOffHandToHit = fToHit - 10.0; + float fOffHandAvgDmg = fAvgDmg; + // Set value for Main hand chance to hit with a weapon in Off hand. + float fMain2HandToHit = fToHit - 6.0; + float fMain2HandAvgDmg = fAvgDmg; + // Calculate the avg dmg for oItem used in the main hand with no Off hand weapon. + fToHit = fToHit / 20.0; + float fThreatChance = (IntToFloat(nThreat) / 20.0) * fToHit; + fAvgDmg = (fAvgDmg * fToHit) + ((fAvgDmg * IntToFloat(nMultiplier) + fCritBonusDmg) * fThreatChance); + SetLocalFloat(oItem, "AI_AVG_DMG", fAvgDmg); + if(AI_DEBUG) ai_Debug("0i_items", "768", GetName(oItem) + " fSingleAvgDmg: " + FloatToString(fAvgDmg, 0, 2)); + if(!b2Handed || (b2Handed && oOffWeapon != OBJECT_INVALID)) + { + // Calculate chance to hit based on two weapon feats and main hand vs off hand. + if(GetHasFeat(374/*Dual_Wield*/, oCreature)) + { + if(ai_GetArmorBonus(GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature)) < 4) + { + fMain2HandToHit += 2.0; + fOffHandToHit += 6.0; + } + } + else + { + if(GetHasFeat(FEAT_AMBIDEXTERITY, oCreature)) fOffHandToHit += 4.0; + if(GetHasFeat(FEAT_TWO_WEAPON_FIGHTING, oCreature)) + { + fMain2HandToHit += 2.0; + fOffHandToHit += 2.0; + } + } + if(ai_GetIsLightWeapon(oItem, oCreature)) fOffHandToHit += 2.0; + if(oOffWeapon != OBJECT_INVALID && + (ai_GetIsLightWeapon(oOffWeapon, oCreature) || ai_GetIsDoubleWeapon(oItem))) + { + fMain2HandToHit += 2.0; + } + // Calculate the avg dmg for oItem used in the main hand with an off hand weapon. + fMain2HandToHit = fMain2HandToHit / 20.0; + fThreatChance = (IntToFloat(nThreat) / 20.0) * fMain2HandToHit; + fMain2HandAvgDmg = (fMain2HandAvgDmg * fMain2HandToHit) + ((fMain2HandAvgDmg * IntToFloat(nMultiplier) + fCritBonusDmg) * fThreatChance); + SetLocalFloat(oItem, "AI_MAIN_2W_HAND_AVG_DMG", fMain2HandAvgDmg); + if(AI_DEBUG) ai_Debug("0i_items", "768", GetName(oItem) + " fMain2HandAvgDmg: " + FloatToString(fMain2HandAvgDmg, 0, 2)); + // Calculate the avg dmg for oItem used in the off hand. + fOffHandToHit = fOffHandToHit / 20.0; + fThreatChance = (IntToFloat(nThreat) / 20.0) * fOffHandToHit; + fOffHandAvgDmg = (fOffHandAvgDmg * fOffHandToHit) + ((fOffHandAvgDmg * IntToFloat(nMultiplier) + fCritBonusDmg) * fThreatChance); + SetLocalFloat(oItem, "AI_OFFHAND_AVG_DMG", fOffHandAvgDmg); + if(AI_DEBUG) ai_Debug("0i_items", "790", GetName(oItem) + " fOffHandAvgDmg: " + FloatToString(fOffHandAvgDmg, 0, 2)); + // Return the correct value based on params passed. + if(oOffWeapon != OBJECT_INVALID) + { + // This is used only for double weapons! Must pass b2Handed = TRUE and + // oOffWeapon = the double weapon that was passes as oItem. + if(b2Handed) return fMain2HandAvgDmg + fOffHandAvgDmg; + return fMain2HandAvgDmg; + } + if(bOffHand) return fOffHandAvgDmg; + } + return fAvgDmg; +} +int ai_SetShieldAC(object oCreature, object oItem) +{ + if(oCreature == GetLocalObject(oItem, "AI_CREATURE_POSSESSION")) + { + return GetLocalInt(oItem, "AI_SHIELD_AC"); + } + // Set the creature who has this item for setting the power of. + SetLocalObject(oItem, "AI_CREATURE_POSSESSION", oCreature); + int nItemType = GetBaseItemType(oItem); + int nAC, nItemPropertyType; + if(nItemType == BASE_ITEM_SMALLSHIELD) nAC = 1; + else if(nItemType == BASE_ITEM_LARGESHIELD) nAC = 2; + else if(nItemType == BASE_ITEM_TOWERSHIELD) nAC = 3; + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + nItemPropertyType = GetItemPropertyType(ipProperty); + if(nItemPropertyType == ITEM_PROPERTY_AC_BONUS) + { + nAC += GetItemPropertyCostTableValue(ipProperty); + } + else if(nItemPropertyType == ITEM_PROPERTY_DECREASED_AC) + { + nAC -= GetItemPropertyCostTableValue(ipProperty); + } + else if(nItemPropertyType == ITEM_PROPERTY_HASTE) + { + nAC += 4; + } + ipProperty = GetNextItemProperty(oItem); + } + SetLocalInt(oItem, "AI_SHIELD_AC", nAC); + if(AI_DEBUG) ai_Debug("0i_items", "718", GetName(oItem) + " nAC: " + IntToString(nAC)); + return nAC; +} +int ai_GetHasItemProperty(object oItem, int nItemPropertyType, int nItemPropertySubType = -1) +{ + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(GetItemPropertyType(ipProperty) == nItemPropertyType) + { + if(nItemPropertySubType > -1) + { + if(GetItemPropertySubType(ipProperty) == nItemPropertySubType) return TRUE; + } + else return TRUE; + } + ipProperty = GetNextItemProperty(oItem); + } + return FALSE; +} +object ai_GetBestPicks(object oCreature, int nLockDC) +{ + int nSkill = GetSkillRank(SKILL_OPEN_LOCK, oCreature); + int nBonus, nBestBonus = 99, nNeededBonus = nLockDC - nSkill - 20; + //ai_Debug("0i_items", "651", "nNeededBonus: " + IntToString(nNeededBonus)); + // We don't need to use any picks! + if(nNeededBonus < 1) return OBJECT_INVALID; + object oBestItem = OBJECT_INVALID; + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetBaseItemType(oItem) == BASE_ITEM_THIEVESTOOLS) + { + // Get the tools bonus. + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(GetItemPropertyType(ipProperty) == ITEM_PROPERTY_THIEVES_TOOLS) + { + nBonus = GetItemPropertyCostTableValue(ipProperty); + if(nBonus >= nNeededBonus && nBonus < nBestBonus) + { + nBestBonus = nBonus; + oBestItem = oItem; + SetLocalInt(oBestItem, "AI_BONUS", nBestBonus); + break; + } + } + ipProperty = GetNextItemProperty(oItem); + } + } + oItem = GetNextItemInInventory(oCreature); + } + return oBestItem; +} +void ai_RemoveInventory(object oCreature) +{ + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + DestroyObject(oItem); + oItem = GetNextItemInInventory(oCreature); + } + int nIndex; + for(nIndex = 0; nIndex <= 13; nIndex++) + { + oItem = GetItemInSlot(nIndex, oCreature); + DestroyObject(oItem); + } +} +void ai_MoveInventory(object oOldHenchman, object oNewHenchman) +{ + // Move all inventory items. + object oItem = GetFirstItemInInventory(oOldHenchman); + while(oItem != OBJECT_INVALID) + { + CopyItem(oItem, oNewHenchman, TRUE); + oItem = GetNextItemInInventory(oOldHenchman); + } + // Move all equiped items and equip on oNewHenchman. + int nIndex; + object oNewItem; + for(nIndex = 0; nIndex <= 13; nIndex++) + { + oItem = GetItemInSlot(nIndex, oOldHenchman); + if(oItem != OBJECT_INVALID) + { + oNewItem = CopyItem(oItem, oNewHenchman, TRUE); + if(!GetIdentified(oNewItem)) SetIdentified(oNewItem, TRUE); + ActionEquipItem(oNewItem, nIndex); + } + } +} +int prc_IsProficient(object oCreature, int nBaseItem) +{ + switch(nBaseItem) + { + //special case: counts as simple for chitine + case BASE_ITEM_SHORTSWORD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(3600/*FEAT_MINDBLADE*/, oCreature) + || (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + && GetRacialType(oCreature) == 76/*RACIAL_TYPE_CHITINE*/) + || GetHasFeat(7901/*FEAT_WEAPON_PROFICIENCY_SHORTSWORD*/, oCreature); + + case BASE_ITEM_LONGSWORD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(3600/*FEAT_MINDBLADE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oCreature) + || GetHasFeat(7902/*FEAT_WEAPON_PROFICIENCY_LONGSWORD*/, oCreature); + + case BASE_ITEM_BATTLEAXE: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + && GetRacialType(oCreature) == 216/*RACIAL_TYPE_GNOLL*/) + || GetHasFeat(7903/*FEAT_WEAPON_PROFICIENCY_BATTLEAXE*/, oCreature); + + case BASE_ITEM_BASTARDSWORD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature) + || GetHasFeat(3600/*FEAT_MINDBLADE*/, oCreature) + || GetHasFeat(7904/*FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD*/, oCreature); + + case BASE_ITEM_LIGHTFLAIL: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(7905/*FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL*/, oCreature); + + case BASE_ITEM_WARHAMMER: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(7906/*FEAT_WEAPON_PROFICIENCY_WARHAMMER*/, oCreature); + + case BASE_ITEM_LONGBOW: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oCreature) + || GetHasFeat(7907/*FEAT_WEAPON_PROFICIENCY_LONGBOW*/, oCreature); + + case BASE_ITEM_LIGHTMACE: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(7908/*FEAT_WEAPON_PROFICIENCY_LIGHT_MACE*/, oCreature); + + case BASE_ITEM_HALBERD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(7909/*FEAT_WEAPON_PROFICIENCY_HALBERD*/, oCreature); + + case BASE_ITEM_SHORTBOW: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oCreature) + || (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + && GetRacialType(oCreature) == 216/*RACIAL_TYPE_GNOLL*/) + || GetHasFeat(7910/*FEAT_WEAPON_PROFICIENCY_SHORTBOW*/, oCreature); + + case BASE_ITEM_TWOBLADEDSWORD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature) + || GetHasFeat(7911/*FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD*/, oCreature); + + case BASE_ITEM_GREATSWORD: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(7912/*FEAT_WEAPON_PROFICIENCY_GREATSWORD*/, oCreature); + + case BASE_ITEM_GREATAXE: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(7913/*FEAT_WEAPON_PROFICIENCY_GREATAXE*/, oCreature); + + case BASE_ITEM_DART: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature) + || GetHasFeat(7914/*FEAT_WEAPON_PROFICIENCY_DART*/, oCreature); + + case BASE_ITEM_DIREMACE: + return GetHasFeat(7915/*FEAT_WEAPON_PROFICIENCY_DIRE_MACE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_DOUBLEAXE: + return GetHasFeat(7916/*FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_HEAVYFLAIL: + return GetHasFeat(7917/*FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case BASE_ITEM_LIGHTHAMMER: + return GetHasFeat(7918/*FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case BASE_ITEM_HANDAXE: + return GetHasFeat(7919/*FEAT_WEAPON_PROFICIENCY_HANDAXE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature); + + case BASE_ITEM_KAMA: + return GetHasFeat(7920/*FEAT_WEAPON_PROFICIENCY_KAMA*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_KATANA: + return GetHasFeat(7921/*FEAT_WEAPON_PROFICIENCY_KATANA*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_KUKRI: + return GetHasFeat(7922/*FEAT_WEAPON_PROFICIENCY_KUKRI*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_MORNINGSTAR: + return GetHasFeat(7923/*FEAT_WEAPON_PROFICIENCY_MORNINGSTAR*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature); + + case BASE_ITEM_QUARTERSTAFF: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oCreature); + + case BASE_ITEM_RAPIER: + return GetHasFeat(7924/*FEAT_WEAPON_PROFICIENCY_RAPIER*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oCreature); + + case BASE_ITEM_SCIMITAR: + return GetHasFeat(7925/*FEAT_WEAPON_PROFICIENCY_SCIMITAR*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature); + + case BASE_ITEM_SCYTHE: + return GetHasFeat(7926/*FEAT_WEAPON_PROFICIENCY_SCYTHE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case BASE_ITEM_SHORTSPEAR: + return GetHasFeat(7927/*FEAT_WEAPON_PROFICIENCY_SHORTSPEAR*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature); + + case BASE_ITEM_SHURIKEN: + return GetHasFeat(7928/*FEAT_WEAPON_PROFICIENCY_SHURIKEN*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature); + + case BASE_ITEM_SICKLE: + return GetHasFeat(7929/*FEAT_WEAPON_PROFICIENCY_SICKLE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature); + + case BASE_ITEM_SLING: + return GetHasFeat(7930/*FEAT_WEAPON_PROFICIENCY_SLING*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature); + + case BASE_ITEM_THROWINGAXE: + return GetHasFeat(7931/*FEAT_WEAPON_PROFICIENCY_THROWING_AXE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + || GetHasFeat(3600/*FEAT_MINDBLADE*/, oCreature); + + case BASE_ITEM_CSLASHWEAPON: + case BASE_ITEM_CPIERCWEAPON: + case BASE_ITEM_CBLUDGWEAPON: + case BASE_ITEM_CSLSHPRCWEAP: + return GetHasFeat(FEAT_WEAPON_PROFICIENCY_CREATURE, oCreature); + + case BASE_ITEM_TRIDENT: + return GetHasFeat(7932/*FEAT_WEAPON_PROFICIENCY_TRIDENT*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oCreature); + + case 124://BASE_ITEM_DOUBLE_SCIMITAR: + return GetHasFeat(7948/*FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case 119://BASE_ITEM_FALCHION: + return GetHasFeat(7943/*FEAT_WEAPON_PROFICIENCY_FALCHION*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case 125://BASE_ITEM_GOAD: + return GetHasFeat(7949/*FEAT_WEAPON_PROFICIENCY_GOAD*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature); + + case 122://BASE_ITEM_HEAVY_MACE: + return GetHasFeat(7946/*FEAT_WEAPON_PROFICIENCY_HEAVY_MACE*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oCreature); + + case 115://BASE_ITEM_HEAVY_PICK: + return GetHasFeat(7939/*FEAT_WEAPON_PROFICIENCY_HEAVY_PICK*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case 116://BASE_ITEM_LIGHT_PICK: + return GetHasFeat(7940/*FEAT_WEAPON_PROFICIENCY_LIGHT_PICK*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case 121://BASE_ITEM_KATAR: + return GetHasFeat(7945/*FEAT_WEAPON_PROFICIENCY_KATAR*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case 123://BASE_ITEM_MAUL: + return GetHasFeat(7947/*FEAT_WEAPON_PROFICIENCY_MAUL*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + case 118://BASE_ITEM_NUNCHAKU: + return GetHasFeat(7942/*FEAT_WEAPON_PROFICIENCY_NUNCHAKU*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case 117://BASE_ITEM_SAI: + return GetHasFeat(7941/*FEAT_WEAPON_PROFICIENCY_SAI*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case 120://BASE_ITEM_SAP: + return GetHasFeat(7944/*FEAT_WEAPON_PROFICIENCY_SAP*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature); + + //special case: counts as martial for dwarves + case BASE_ITEM_DWARVENWARAXE: + return GetHasFeat(7933/*FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE*/, oCreature) + || (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oCreature) + && GetHasFeat(4710/*FEAT_DWARVEN*/, oCreature)) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + + case BASE_ITEM_WHIP: + return GetHasFeat(7934/*FEAT_WEAPON_PROFICIENCY_WHIP*/, oCreature) + || GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oCreature); + } + return TRUE; +} +int ai_GetItemUses(object oItem, int nItemPropertySubType) +{ + int nUses; + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(GetItemPropertyType(ipProperty) == ITEM_PROPERTY_HEALERS_KIT) return GetItemStackSize(oItem); + if(nItemPropertySubType > -1) + { + if(GetItemPropertySubType(ipProperty) == nItemPropertySubType) + { + // Get how they use the item (charges or uses per day). + nUses = GetItemPropertyCostTableValue(ipProperty); + if(nUses == 1) return GetItemStackSize(oItem); + else if(nUses > 1 && nUses < 7) return GetItemCharges(oItem); + else if(nUses == 7 || nUses == 13) return 999; + else if(nUses > 7 && nUses < 13) return GetItemPropertyUsesPerDayRemaining(oItem, ipProperty); + } + } + else return TRUE; + ipProperty = GetNextItemProperty(oItem); + } + return FALSE; +} + diff --git a/src/module/nss/0i_main.nss b/src/module/nss/0i_main.nss new file mode 100644 index 0000000..a0a4674 --- /dev/null +++ b/src/module/nss/0i_main.nss @@ -0,0 +1,1328 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_main +//////////////////////////////////////////////////////////////////////////////// + Include script for handling main/basic functions not defined by other includes. + + Database structure: Json with indexes. + name (string) - The associatetype to link the data. "pc", "familiar", etc. + modes (jsonarray) - 0-aimodes (int), 1-magicmodes (int) + buttons (jsonarray) - 0-widgetbuttons (int), 1-aibuttons (int) + aidata (jsonarray) - 0-difficulty (int), 1-healoutcombat (int), 2-healincombat (int), + 3-lootrange (float), 4-lockrange (float), 5-traprange (float), + 6-Follow range (float). + lootfilters (jsonarray) - 0-maxweight (int), 1-lootfilters (int), + Item filters in min gold json array; 2-plot, 3-armor, 4-belts, 5-boots, + 6-cloaks, 7-gems, 8-gloves, 9-headgear, 10-jewelry, 11-misc, 12-potions, + 13-scrolls, 14-shields, 15-wands, 16-weapons, 17-arrow, 18-bolt, 19-bullet. + plugins (jsonarray) - 0+ (string). * Only used in the "pc" data. + location (jsonobject) - geometry (json), used in widgets for pc and associates. +*/////////////////////////////////////////////////////////////////////////////// +const string AI_TABLE = "PEPS_TABLE"; +const string AI_CAMPAIGN_DATABASE = "peps_database"; +const string AI_DM_TABLE = "DM_TABLE"; +#include "0i_constants" +#include "0i_messages" +// Sets PEPS RULES from the database to the module. +// Creates default rules if they do not exist. +void ai_SetAIRules(); +// Returns TRUE if oCreature is controlled by a player. +int ai_GetIsCharacter(object oCreature); +// Returns TRUE if oCreature is controlled by a dungeon master. +int ai_GetIsDungeonMaster(object oCreature); +// Returns the Player of oAssociate even if oAssociate is the player. +// If there is no player associated with oAssociate then it returns OBJECT_INVALID. +object ai_GetPlayerMaster(object oAssociate); +// Returns the percentage of hit points oCreature has left. +int ai_GetPercHPLoss(object oCreature); +// Returns a rolled result from sDice string. +// Example: "1d6" will be 1-6 or "3d6" will be 3-18 or 1d6+5 will be 6-11. +int ai_RollDiceString(string sDice); +// Returns the int number of a encoded 0x00000000 hex number from a string. +int ai_HexStringToInt(string sString); +// Returns cosine of the angle between oObject1 and oObject2 +float ai_GetCosAngleBetween(object oObject1, object oObject2); +// Returns a string from sString with only characters in sLegal. +// Used to remove illegal characters for databases. +string ai_RemoveIllegalCharacters(string sString, string sLegal = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); +// Returns the total levels of oCreature. +int ai_GetCharacterLevels(object oCreature); +// Returns a string where sFind is replaced in any occurrence of sSource with sReplace. +string ai_StringReplaceText(string sSource, string sFind, string sReplace); +// Returns a string of characters between the nIndex of predefined markers of +// sSeperator in sText. +// nIndex is the number of the data we are searching for in the array. +// A 0 nIndex is the first item in the text array. +// sSeperator is the character that seperates the array(Usefull for Multiple arrays). +string ai_GetStringArray(string sText, int nIndex, string sSeperator = ":"); +// Returns a string of characters between the nIndex of predefined markers of +// sSeperator in sText where sField has been set. +// sText is the text holding the array. +// nIndex is the array number in the data we are searching for. +// A 0 nIndex is the first item in the text array. +// sField is the field of characters to replace that index. +// sSeperator is the character that seperates the array(Usefull for Multiple arrays). +string ai_SetStringArray(string sText, int nIndex, string sField, string sSeperator = ":"); +// Returns the number of magical properties oItem has. +int ai_GetNumberOfProperties(object oItem); +// Checks if the campaign database table has been created and initialized. +void ai_CheckCampaignDataAndInitialize(); +// Checks if the dm database table and data has been created and initialized of oDM. +void ai_CheckDMDataAndInitialize(object oDM); +// Sets json to a campaign database. +void ai_SetCampaignDbJson(string sDataField, json jData, string sName = "PEPS_DATA", string sTable = AI_TABLE); +// Gets json from a campaign database. +json ai_GetCampaignDbJson(string sDataField, string sName = "PEPS_DATA", string sTable = AI_TABLE); +// Checks if oMaster has the Table created for Associate data. +// If no table found then the table is created and then initialized. +void ai_CheckAssociateDataAndInitialize(object oPlayer, string sAssociateType); +// Returns the associatetype int string format for oAssociate. +// They are pc, familar, companion, summons, henchman is the henchmans tag +string ai_GetAssociateType(object oPlayer, object oAssociate); +// Sets nData to sDataField for sAssociateType that is on oPlayer. +// sDataField can be modes, magicmodes, lootmodes, widgetbuttons, aibuttons, magic, +// healoutcombat, healincombat, mingold*. +void ai_SetAssociateDbInt(object oPlayer, string sAssociateType, string sDataField, int nData, string sTable = AI_TABLE); +// Returns nData from sDataField for sAssociateType that is on oPlayer. +// sDataField can be modes, magicmodes, lootmodes, widgetbuttons, aibuttons, magic, +// healoutcombat, healincombat, mingold*. +int ai_GetAssociateDbInt(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE); +// Sets fData to sDataField for sAssociateType that is on oPlayer. +// sDataField can be lootrange, lockrange, traprange. +void ai_SetAssociateDbFloat(object oPlayer, string sAssociatetype, string sDataField, float fData, string sTable = AI_TABLE); +// Returns fData from sDataField for sAssociateType that is on oPlayer. +// sDataField can be lootrange, lockrange, traprange. +float ai_GetAssociateDbFloat(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE); +// sDataField should be one of the data fields for that table. +// jData is the json data to be saved. +void ai_SetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, json jData, string sTable = AI_TABLE); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +json ai_GetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE); +// Saves Associate AIModes and MagicModes to the database. +void aiSaveAssociateModesToDb(object oPlayer, object oAssociate); +// Checks Associate local data and if none is found will initialize or load the +// correct data for oAssociate. +void ai_CheckAssociateData(object oPlayer, object oAssociate, string sAssociateType, int bLoad = FALSE); +// Checks DM's local data and if none is found will initizlize or load the +// correct data for oPlayer. +void ai_CheckDMData(object oPlayer); +// Adds to jPlugins functions after checking if the plugin can be installed. +json ai_Plugin_Add(object oPC, json jPlugins, string sPluginScript); +// Updates the players Plugin list and saves to the database. +json ai_UpdatePluginsForPC(object oPC); +// Updates the DM's Plugin list and saves to the database. +json ai_UpdatePluginsForDM (object oPC); +// Runs all plugins that are loaded into the database. +void ai_StartupPlugins(object oPC); +void ai_SetAIRules() +{ + object oModule = GetModule(); + ai_CheckCampaignDataAndInitialize(); + json jRules = ai_GetCampaignDbJson("rules"); + if(JsonGetType(JsonObjectGet(jRules, AI_RULE_MORAL_CHECKS)) == JSON_TYPE_NULL) + { + jRules = JsonObject(); + // Variable name set to a creatures full name to set debugging on. + jRules = JsonObjectSet(jRules, AI_RULE_DEBUG_CREATURE, JsonString("")); + // Moral checks on or off. + SetLocalInt(oModule, AI_RULE_MORAL_CHECKS, AI_MORAL_CHECKS); + jRules = JsonObjectSet(jRules, AI_RULE_MORAL_CHECKS, JsonInt(AI_MORAL_CHECKS)); + // Allows monsters to prebuff before combat starts. + SetLocalInt(oModule, AI_RULE_BUFF_MONSTERS, AI_PREBUFF); + jRules = JsonObjectSet(jRules, AI_RULE_BUFF_MONSTERS, JsonInt(AI_PREBUFF)); + // Allows monsters cast summons spells when prebuffing. + SetLocalInt(oModule, AI_RULE_PRESUMMON, AI_PRESUMMONS); + jRules = JsonObjectSet(jRules, AI_RULE_PRESUMMON, JsonInt(AI_PRESUMMONS)); + // Allows monsters to use tactical AI scripts. + SetLocalInt(oModule, AI_RULE_AMBUSH, AI_TACTICAL); + jRules = JsonObjectSet(jRules, AI_RULE_AMBUSH, JsonInt(AI_TACTICAL)); + // Enemies may summon familiars and Animal companions and will be randomized. + SetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS, AI_SUMMON_COMPANIONS); + jRules = JsonObjectSet(jRules, AI_RULE_SUMMON_COMPANIONS, JsonInt(AI_SUMMON_COMPANIONS)); + // Allow the AI to move during combat base on the situation and action taking. + SetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT, AI_ADVANCED_MOVEMENT); + jRules = JsonObjectSet(jRules, AI_RULE_ADVANCED_MOVEMENT, JsonInt(AI_ADVANCED_MOVEMENT)); + // Follow Item Level Restrictions for monsters/associates. + SetLocalInt(oModule, AI_RULE_ILR, AI_ITEM_LEVEL_RESTRICTIONS); + jRules = JsonObjectSet(jRules, AI_RULE_ILR, JsonInt(AI_ITEM_LEVEL_RESTRICTIONS)); + // Allow the AI to use Use Magic Device. + SetLocalInt(oModule, AI_RULE_ALLOW_UMD, AI_USE_MAGIC_DEVICE); + jRules = JsonObjectSet(jRules, AI_RULE_ALLOW_UMD, JsonInt(AI_USE_MAGIC_DEVICE)); + // Allow the AI to use healing kits. + SetLocalInt(oModule, AI_RULE_HEALERSKITS, AI_HEALING_KITS); + jRules = JsonObjectSet(jRules, AI_RULE_HEALERSKITS, JsonInt(AI_HEALING_KITS)); + // Associates are permanent and don't get removed when the master dies. + SetLocalInt(oModule, AI_RULE_PERM_ASSOC, AI_COMPANIONS_PERMANENT); + jRules = JsonObjectSet(jRules, AI_RULE_PERM_ASSOC, JsonInt(AI_COMPANIONS_PERMANENT)); + // Monster AI's chance to attack the weakest target instead of the nearest. + SetLocalInt(oModule, AI_RULE_AI_DIFFICULTY, AI_TARGET_WEAKEST); + jRules = JsonObjectSet(jRules, AI_RULE_AI_DIFFICULTY, JsonInt(AI_TARGET_WEAKEST)); + // Monster AI's distance they can search for the enemy. + SetLocalFloat(oModule, AI_RULE_PERCEPTION_DISTANCE, AI_SEARCH_DISTANCE); + jRules = JsonObjectSet(jRules, AI_RULE_PERCEPTION_DISTANCE, JsonFloat(AI_SEARCH_DISTANCE)); + // Enemy corpses remain on the floor instead of dissappearing. + SetLocalInt(oModule, AI_RULE_CORPSES_STAY, AI_CORPSE_REMAIN); + jRules = JsonObjectSet(jRules, AI_RULE_CORPSES_STAY, JsonInt(AI_CORPSE_REMAIN)); + // Monsters will wander around when not in combat. + SetLocalInt(oModule, AI_RULE_WANDER, AI_WANDER); + jRules = JsonObjectSet(jRules, AI_RULE_WANDER, JsonInt(AI_WANDER)); + // Increase the number of encounter creatures. + SetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS, 0.0); + jRules = JsonObjectSet(jRules, AI_INCREASE_ENC_MONSTERS, JsonFloat(0.0)); + // Increase all monsters hitpoints by this percentage. + SetLocalInt(oModule, AI_INCREASE_MONSTERS_HP, 0); + jRules = JsonObjectSet(jRules, AI_INCREASE_MONSTERS_HP, JsonInt(0)); + // Monster's perception distance. + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, AI_MONSTER_PERCEPTION); + jRules = JsonObjectSet(jRules, AI_RULE_MON_PERC_DISTANCE, JsonInt(AI_MONSTER_PERCEPTION)); + // Variable name set to hold the maximum number of henchman the player wants. + int nMaxHenchmen = GetMaxHenchmen(); + SetLocalInt(oModule, AI_RULE_MAX_HENCHMAN, nMaxHenchmen); + jRules = JsonObjectSet(jRules, AI_RULE_MAX_HENCHMAN, JsonInt(nMaxHenchmen)); + // Monster AI's distance they can wander away from their spawn point. + SetLocalFloat(oModule, AI_RULE_WANDER_DISTANCE, AI_WANDER_DISTANCE); + jRules = JsonObjectSet(jRules, AI_RULE_WANDER_DISTANCE, JsonFloat(AI_WANDER_DISTANCE)); + // Monsters will open doors when wandering around and not in combat. + SetLocalInt(oModule, AI_RULE_OPEN_DOORS, AI_WANDER); + jRules = JsonObjectSet(jRules, AI_RULE_OPEN_DOORS, JsonInt(AI_OPEN_DOORS)); + // If the modules default XP has not been set then we do it here. + int nDefaultXP = GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE); + if(nDefaultXP == 0) + { + int nValue = GetModuleXPScale(); + if(nValue != 0) SetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE, nValue); + } + // Variable name set to allow the game to regulate experience based on party size. + SetLocalInt(oModule, AI_RULE_PARTY_SCALE, AI_PARTY_SCALE); + jRules = JsonObjectSet(jRules, AI_RULE_PARTY_SCALE, JsonInt(AI_PARTY_SCALE)); + SetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS, JsonArray()); + jRules = JsonObjectSet(jRules, AI_RULE_RESTRICTED_SPELLS, JsonArray()); + // Variable name set to allow access to widget buttons for the players. + SetLocalInt(oModule, sDMWidgetAccessVarname, AI_DM_WIDGET_ACCESS_BUTTONS); + jRules = JsonObjectSet(jRules, sDMWidgetAccessVarname, JsonInt(AI_DM_WIDGET_ACCESS_BUTTONS)); + // Variable name set to allow access to widget buttons for the players. + SetLocalInt(oModule, sDMAIAccessVarname, AI_DM_AI_ACCESS_BUTTONS); + jRules = JsonObjectSet(jRules, sDMAIAccessVarname, JsonInt(AI_DM_AI_ACCESS_BUTTONS)); + ai_SetCampaignDbJson("rules", jRules); + } + else + { + // Variable name set to a creatures full name to set debugging on. + string sValue = JsonGetString(JsonObjectGet(jRules, AI_RULE_DEBUG_CREATURE)); + SetLocalString(oModule, AI_RULE_DEBUG_CREATURE, sValue); + // Moral checks on or off. + int bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_MORAL_CHECKS)); + SetLocalInt(oModule, AI_RULE_MORAL_CHECKS, bValue); + // Allows monsters to prebuff before combat starts. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_BUFF_MONSTERS)); + SetLocalInt(oModule, AI_RULE_BUFF_MONSTERS, bValue); + // Allows monsters cast summons spells when prebuffing. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_PRESUMMON)); + SetLocalInt(oModule, AI_RULE_PRESUMMON, bValue); + // Allows monsters to use ambush AI scripts. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_AMBUSH)); + SetLocalInt(oModule, AI_RULE_AMBUSH, bValue); + // Enemies may summon familiars and Animal companions and will be randomized. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_SUMMON_COMPANIONS)); + SetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS, bValue); + // Allow the AI to move during combat base on the situation and action taking. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_ADVANCED_MOVEMENT)); + SetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT, bValue); + // Follow Item Level Restrictions for monsters/associates. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_ILR)); + SetLocalInt(oModule, AI_RULE_ILR, bValue); + // Allow the AI to use Use Magic Device. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_ALLOW_UMD)); + SetLocalInt(oModule, AI_RULE_ALLOW_UMD, bValue); + // Allow the AI to use healing kits. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_HEALERSKITS)); + SetLocalInt(oModule, AI_RULE_HEALERSKITS, bValue); + // Associates are permanent and don't get removed when the owner dies. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_PERM_ASSOC)); + SetLocalInt(oModule, AI_RULE_PERM_ASSOC, bValue); + // Monster AI's chance to attack the weakest target instead of the nearest. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_AI_DIFFICULTY)); + SetLocalInt(oModule, AI_RULE_AI_DIFFICULTY, bValue); + // Monster AI's perception distance from player. + float fValue = JsonGetFloat(JsonObjectGet(jRules, AI_RULE_PERCEPTION_DISTANCE)); + SetLocalFloat(oModule, AI_RULE_PERCEPTION_DISTANCE, fValue); + // Enemy corpses remain on the floor instead of dissappearing. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_CORPSES_STAY)); + SetLocalInt(oModule, AI_RULE_CORPSES_STAY, bValue); + // Monsters will wander around when not in combat. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_WANDER)); + SetLocalInt(oModule, AI_RULE_WANDER, bValue); + // Increase the number of encounter creatures. + fValue = JsonGetFloat(JsonObjectGet(jRules, AI_INCREASE_ENC_MONSTERS)); + SetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS, fValue); + // Increase all monsters hitpoints by this percentage. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_INCREASE_MONSTERS_HP)); + SetLocalInt(oModule, AI_INCREASE_MONSTERS_HP, bValue); + // Monster's perception distance. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_MON_PERC_DISTANCE)); + if(bValue < 8 || bValue > 11) bValue = 11; + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, bValue); + // Variable name set to hold the maximum number of henchman the player wants. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_MAX_HENCHMAN)); + if(bValue == 0) bValue = GetMaxHenchmen(); + else SetMaxHenchmen(bValue); + SetLocalInt(oModule, AI_RULE_MAX_HENCHMAN, bValue); + // Monster AI's wander distance from their spawn point. + fValue = JsonGetFloat(JsonObjectGet(jRules, AI_RULE_WANDER_DISTANCE)); + SetLocalFloat(oModule, AI_RULE_WANDER_DISTANCE, fValue); + // Monsters will open doors while wandering around and not in combat. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_OPEN_DOORS)); + SetLocalInt(oModule, AI_RULE_OPEN_DOORS, bValue); + // If the modules default XP has not been set then we do it here. + int nDefaultXP = GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE); + if(nDefaultXP == 0) + { + bValue = GetModuleXPScale(); + if(bValue != 0) SetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE, bValue); + } + // Variable name set to allow the game to regulate experience based on party size. + bValue = JsonGetInt(JsonObjectGet(jRules, AI_RULE_PARTY_SCALE)); + if(bValue) + { + int nBasePartyXP = GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP); + if(nBasePartyXP == 0) + { + nDefaultXP = GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE); + SetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP, nDefaultXP); + } + } + SetLocalInt(oModule, AI_RULE_PARTY_SCALE, bValue); + json jRSpells = JsonObjectGet(jRules, AI_RULE_RESTRICTED_SPELLS); + if(JsonGetType(jRSpells) == JSON_TYPE_NULL) + { + jRSpells = JsonArray(); + jRules = JsonObjectSet(jRules, AI_RULE_RESTRICTED_SPELLS, jRSpells); + ai_SetCampaignDbJson("rules", jRules); + } + SetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS, jRSpells); + // Variable name set to allow access to widget buttons for the players. + bValue = JsonGetInt(JsonObjectGet(jRules, sDMWidgetAccessVarname)); + SetLocalInt(oModule, sDMWidgetAccessVarname, bValue); + // Variable name set to allow access to widget buttons for the players. + bValue = JsonGetInt(JsonObjectGet(jRules, sDMAIAccessVarname)); + SetLocalInt(oModule, sDMAIAccessVarname, bValue); + } +} +int ai_GetIsCharacter(object oCreature) +{ + return (GetIsPC(oCreature) && !GetIsDM(oCreature) && !GetIsDMPossessed(oCreature)); +} +int ai_GetIsDungeonMaster(object oCreature) +{ + return (GetIsDM(oCreature) || GetIsDMPossessed(oCreature)); +} +object ai_GetPlayerMaster(object oAssociate) +{ + if(ai_GetIsCharacter(oAssociate)) return oAssociate; + object oMaster = GetMaster(oAssociate); + if(ai_GetIsCharacter(oMaster)) return oMaster; + return OBJECT_INVALID; +} +int ai_GetPercHPLoss(object oCreature) +{ + int nHP = GetCurrentHitPoints(oCreature); + if(nHP < 1) return 0; + return(nHP * 100) / GetMaxHitPoints(oCreature); +} +int ai_RollDiceString(string sDice) +{ + int nNegativePos, nBonus = 0; + string sRight = GetStringRight(sDice, GetStringLength(sDice) - FindSubString(sDice, "d") - 1); + int nPlusPos = FindSubString(sRight, "+"); + if(nPlusPos != -1) + { + nBonus = StringToInt(GetStringRight(sRight, GetStringLength(sRight) - nPlusPos - 1)); + sRight = GetStringLeft(sRight, nPlusPos); + } + else + { + nNegativePos = FindSubString(sRight, "-"); + if(nNegativePos != -1) + { + nBonus = StringToInt(GetStringRight(sRight, GetStringLength(sRight) - nNegativePos - 1)); + sRight = GetStringLeft(sRight, nNegativePos); + nBonus = nBonus * -1; + } + } + int nDie = StringToInt(sRight); + int nNumOfDie = StringToInt(GetStringLeft(sDice, FindSubString(sDice, "d"))); + int nResult; + while(nNumOfDie > 0) + { + nResult += Random(nDie) + 1; + nNumOfDie --; + } + return nResult + nBonus; +} +int ai_HexStringToInt(string sString) +{ + sString = GetStringLowerCase(sString); + int nInt = 0; + int nLength = GetStringLength(sString); + int i; + for(i = nLength - 1; i >= 0; i--) + { + int n = FindSubString("0123456789abcdef", GetSubString(sString, i, 1)); + if(n == -1) return nInt; + nInt |= n << ((nLength - i - 1) * 4); + } + return nInt; +} +float ai_GetCosAngleBetween(object oObject1, object oObject2) +{ + vector v1 = GetPositionFromLocation(GetLocation(oObject1)); + vector v2 = GetPositionFromLocation(GetLocation(oObject2)); + vector v3 = GetPositionFromLocation(GetLocation(OBJECT_SELF)); + + v1.x -= v3.x; v1.y -= v3.y; v1.z -= v3.z; + v2.x -= v3.x; v2.y -= v3.y; v2.z -= v3.z; + + float dotproduct = v1.x*v2.x+v1.y*v2.y+v1.z*v2.z; + + return dotproduct/(VectorMagnitude(v1)*VectorMagnitude(v2)); +} +string ai_RemoveIllegalCharacters(string sString, string sLegal = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") +{ + string sOut, sValue; + sString = ai_StripColorCodes(sString); + int nLength = GetStringLength(sString); + int Cnt; + for(Cnt = 0; Cnt != nLength; ++Cnt) + { + sValue = GetSubString(sString, Cnt, 1); + if(TestStringAgainstPattern("**" + sValue + "**", sLegal)) + sOut += sValue; + } + return sOut; +} +int ai_GetCharacterLevels(object oCreature) +{ + int nLevels, nPosition = 1; + while(nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + nLevels += GetLevelByPosition(nPosition, oCreature); + nPosition++; + } + return nLevels; +} +string ai_StringReplaceText(string sSource, string sFind, string sReplace) +{ + int nFindLength = GetStringLength(sFind); + int nPosition = 0; + string sReturnValue = ""; + // Locate all occurences of sFind. + int nFound = FindSubString(sSource, sFind); + while(nFound >= 0 ) + { + // Build the return string, replacing this occurence of sFind with sReplace. + sReturnValue += GetSubString(sSource, nPosition, nFound - nPosition) + sReplace; + nPosition = nFound + nFindLength; + nFound = FindSubString(sSource, sFind, nPosition); + } + // Tack on the end of sSource and return. + return sReturnValue + GetStringRight(sSource, GetStringLength(sSource) - nPosition); +} +string ai_GetStringArray(string sArray, int nIndex, string sSeperator = ":") +{ + int nCnt = 0, nMark = 0, nStringLength = GetStringLength(sArray); + string sCharacter; + // Search the string. + while(nCnt < nStringLength) + { + sCharacter = GetSubString(sArray, nCnt, 1); + // Look for the mark. + if(sCharacter == sSeperator) + { + // If we have not found it then lets see if this mark is the one. + if(nMark < 1) + { + // If we are down to 0 in the index then we have found the mark. + if(nIndex > 0) nIndex --; + // Mark the start of the string we need. + else nMark = nCnt + 1; + } + else + { + // We have the first mark so the next mark will mean we have the string we need. + // Now pull it and return. + sArray = GetSubString(sArray, nMark, nCnt - nMark); + return sArray; + } + } + nCnt ++; + } + // If we hit the end without finding it then return "" as an error. + return ""; +} +string ai_SetStringArray(string sArray, int nIndex, string sField, string sSeperator = ":") +{ + int nCnt = 1, nMark = 1, nStringLength = GetStringLength(sArray); + int nIndexCounter = 0; + string sCharacter, sNewArray = sSeperator, sText; + // Check to make sure this is not a new array. + // If it is new then set it with 1 slot. + if(nStringLength < 2) + { + sArray = sSeperator + " " + sSeperator; + nStringLength = 3; + } + // Search the string. + while(nCnt <= nStringLength) + { + sCharacter = GetSubString(sArray, nCnt, 1); + // Look for the mark. + if(sCharacter == sSeperator) + { + // First check to see if this is the index we are replacing. + if(nIndex == nIndexCounter) sText = sField; + else + { + // Get the original text for this field. + sText = GetSubString(sArray, nMark, nCnt - nMark); + } + // Add the field to the new index. + sNewArray = sNewArray + sText + sSeperator; + // Now set the marker to the new starting point. + nMark = nCnt + 1; + // Increase the index counter as well. + nIndexCounter ++; + } + nCnt ++; + } + // if we are at the end of the array and still have not set the data + // then add blank data until we get to the correct index. + while(nIndexCounter <= nIndex) + { + // If they match add the field. + if(nIndexCounter == nIndex) sNewArray = sNewArray + sField + sSeperator; + // Otherwise just add a blank field. + else sNewArray = sNewArray + " " + sSeperator; + nIndexCounter ++; + } + // When done return the new array. + return sNewArray; +} +int ai_GetNumberOfProperties(object oItem) +{ + int nNumOfProperties = 0, nPropertyType, nPropertySubType; + // Get first property + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + // Ignore double type properties such as bane. + nPropertyType = GetItemPropertyType(ipProperty); + switch(nPropertyType) + { + // Skip these properties as they don't count. + case 8 : break; // EnhanceAlignmentGroup + case 44 : break; // Light + case 62 : break; // UseLimitationAlignmentGroup + case 63 : break; // UseLimitationClass + case 64 : break; // UseLimitationRacial + case 65 : break; // UseLimitationSpecificAlignment + case 66 : break; // UseLimitationTerrain + case 86 : break; // Quality + case 150 : break; // UseLimitationGender + case 15 : + { + nPropertySubType = GetItemPropertySubType(ipProperty); + if(nPropertySubType == IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY) break; + if(nPropertySubType == IP_CONST_CASTSPELL_UNIQUE_POWER) break; + } + default : nNumOfProperties ++; + } + // Get the next property + ipProperty = GetNextItemProperty(oItem); + } + // Reduce the number of properties by one on whips. + if(GetBaseItemType(oItem) == BASE_ITEM_WHIP) nNumOfProperties --; + return nNumOfProperties; +} +void ai_CreateCampaignDataTable() +{ + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, + "CREATE TABLE IF NOT EXISTS " + AI_TABLE + "(" + + "name TEXT, " + + "plugins TEXT, " + + "rules TEXT, " + + "PRIMARY KEY(name));"); + SqlStep(sql); + //if(AI_DEBUG) ai_Debug("0i_main", "343", We are creating a campaign table [" + + // AI_TABLE + "] in the database."); +} +void ai_CheckCampaignDataTableAndCreateTable() +{ + string sQuery = "SELECT name FROM sqlite_master WHERE type ='table' " + + "AND name =@table;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@table", AI_TABLE); + if(!SqlStep(sql)) ai_CreateCampaignDataTable(); +} +void ai_InitializeCampaignData() +{ + string sQuery = "INSERT INTO " + AI_TABLE + "(name, plugins, rules) " + + "VALUES(@name, @plugins, @rules);"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@name", "PEPS_DATA"); + SqlBindJson(sql, "@plugins", JsonArray()); + SqlBindJson(sql, "@rules", JsonObject()); + SqlStep(sql); +} +void ai_CheckCampaignDataAndInitialize() +{ + ai_CheckCampaignDataTableAndCreateTable(); + string sQuery = "SELECT name FROM " + AI_TABLE + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@name", "PEPS_DATA"); + if(!SqlStep(sql)) ai_InitializeCampaignData(); +} +void ai_CreateDMDataTable() +{ + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, + "CREATE TABLE IF NOT EXISTS " + AI_DM_TABLE + "(" + + "name TEXT, " + + "buttons TEXT, " + + "plugins TEXT, " + + "locations TEXT, " + + "options TEXT, " + + "saveslots TEXT, " + + "PRIMARY KEY(name));"); + SqlStep(sql); +} +void ai_CheckDMDataTableAndCreateTable() +{ + string sQuery = "SELECT name FROM sqlite_master WHERE type ='table' " + + "AND name =@table;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@table", AI_DM_TABLE); + if(!SqlStep(sql)) ai_CreateDMDataTable(); +} +void ai_InitializeDMData(string sName) +{ + string sQuery = "INSERT INTO " + AI_DM_TABLE + "(name, buttons, plugins, " + + "locations, options, saveslots) " + + "VALUES(@name, @buttons, @plugins, @locations, @options, @saveslots);"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindJson(sql, "@buttons", JsonArray()); + SqlBindJson(sql, "@plugins", JsonArray()); + SqlBindJson(sql, "@locations", JsonObject()); + SqlBindJson(sql, "@options", JsonObject()); + SqlBindJson(sql, "@saveslots", JsonObject()); + SqlStep(sql); +} +void ai_CheckDMDataAndInitialize(object oDM) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oDM))); + string sQuery = "SELECT name FROM " + AI_DM_TABLE + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@name", sName); + if(!SqlStep(sql)) + { + ai_CheckDMDataTableAndCreateTable(); + ai_InitializeDMData(sName); + } +} +void ai_SetCampaignDbJson(string sDataField, json jData, string sName = "PEPS_DATA", string sTable = AI_TABLE) +{ + string sQuery = "UPDATE " + sTable + " SET " + sDataField + + " = @data WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindJson(sql, "@data", jData); + SqlBindString(sql, "@name", sName); + SqlStep(sql); +} +json ai_GetCampaignDbJson(string sDataField, string sName = "PEPS_DATA", string sTable = AI_TABLE) +{ + string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryCampaign(AI_CAMPAIGN_DATABASE, sQuery); + SqlBindString(sql, "@name", sName); + json jReturn; + if(SqlStep(sql)) return SqlGetJson (sql, 0); + else return JsonArray(); + return jReturn; +} +void ai_CreateAssociateDataTable(object oPlayer) +{ + sqlquery sql = SqlPrepareQueryObject(oPlayer, + "CREATE TABLE IF NOT EXISTS " + AI_TABLE + "(" + + "name TEXT, " + + "modes TEXT, " + + "buttons TEXT, " + + "aidata TEXT, " + + "lootfilters TEXT, " + + "plugins TEXT, " + + "locations TEXT, " + + "PRIMARY KEY(name));"); + SqlStep(sql); + //ai_Debug("0i_main", "665", GetName(oPlayer) + " is creating a table [" + + // AI_TABLE + "] in the database."); +} +void ai_CheckDataTableAndCreateTable(object oPlayer) +{ + string sQuery = "SELECT name FROM sqlite_master WHERE type ='table' " + + "AND name =@table;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@table", AI_TABLE); + if(!SqlStep(sql)) ai_CreateAssociateDataTable (oPlayer); + //else SendMessageToPC(oPlayer, "0i_main, 675, " + GetName(oPlayer) + " has a database with table [" + AI_TABLE + "]."); +} +void ai_InitializeAssociateData(object oPlayer, string sAssociateType) +{ + string sQuery = "INSERT INTO " + AI_TABLE + "(name, modes, buttons, " + + "aidata, lootfilters, plugins, locations) " + + "VALUES(@name, @modes, @buttons, @aidata, @lootfilters, @plugins, @locations);"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociateType); + SqlBindJson(sql, "@modes", JsonArray()); + SqlBindJson(sql, "@buttons", JsonArray()); + SqlBindJson(sql, "@aidata", JsonArray()); + SqlBindJson(sql, "@lootfilters", JsonArray()); + SqlBindJson(sql, "@plugins", JsonArray()); + SqlBindJson(sql, "@locations", JsonObject()); + //SendMessageToPC(oPlayer, "0i_main, 690, " + GetName(oPlayer) + " is initializing associate " + + // sAssociateType + " data for table [" + AI_TABLE + "]."); + SqlStep(sql); +} +void ai_CheckAssociateDataAndInitialize(object oPlayer, string sAssociateType) +{ + ai_CheckDataTableAndCreateTable(oPlayer); + string sQuery = "SELECT name FROM " + AI_TABLE + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject (oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociateType); + if(!SqlStep(sql)) ai_InitializeAssociateData(oPlayer, sAssociateType); + //else SendMessageToPC(oPlayer, "0i_main, 701, sAssociateType: " + sAssociateType + + // " returns: " + SqlGetString(sql, 0)); +} +string ai_GetAssociateType(object oPlayer, object oAssociate) +{ + if(GetIsPC(oAssociate)) return "pc"; + string sAITag = GetLocalString(oAssociate, AI_TAG); + if(sAITag == "") + { + int nAssociateType = GetAssociateType(oAssociate); + if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) sAITag = "companion"; + else if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) sAITag = "familiar"; + else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED) sAITag = "summons"; + else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) sAITag = "dominated"; + else if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) sAITag = GetTag(oAssociate); + string sCurrentAITag; + // Check for duplicate tags and change. + int nIndex; + object oCreature; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oCreature = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPlayer, nIndex); + if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000)); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oCreature = GetAssociate(nIndex, oPlayer, 1); + if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000)); + } + SetLocalString(oAssociate, AI_TAG, sAITag); + } + return sAITag; +} +void ai_SetAssociateDbInt(object oPlayer, string sAssociatetype, string sDataField, int nData, string sTable = AI_TABLE) +{ + string sQuery = "UPDATE " + sTable + " SET " + sDataField + + " = @data WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociatetype); + SqlBindInt(sql, "@data", nData); + //ai_Debug("0i_main", "368", "SETTING DATA: " + GetName(oPlayer) + " sAssociatetype: " + + // sAssociatetype + " sDataField: " + sDataField + " nData: " + IntToString(nData)); + SqlStep(sql); +} +int ai_GetAssociateDbInt(object oPlayer, string sAssociatetype, string sDataField, string sTable = AI_TABLE) +{ + string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociatetype); + //ai_Debug("0i_main", "377", "GETTING DATA: " + GetName(oPlayer) + " sAssociatetype: " + + // sAssociatetype + " sDataField: " + sDataField); + if(SqlStep(sql)) return SqlGetInt(sql, 0); + else return 0; +} +void ai_SetAssociateDbFloat(object oPlayer, string sAssociatetype, string sDataField, float fData, string sTable = AI_TABLE) +{ + string sQuery = "UPDATE " + sTable + " SET " + sDataField + + " = @data WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociatetype); + SqlBindFloat(sql, "@data", fData); + //ai_Debug("0i_main", "368", "SETTING DATA: " + GetName(oPlayer) + " sAssociatetype: " + + // sAssociatetype + " sDataField: " + sDataField + " fData: " + FloatToString(fData, 0, 0)); + SqlStep(sql); +} +float ai_GetAssociateDbFloat(object oPlayer, string sAssociatetype, string sDataField, string sTable = AI_TABLE) +{ + string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sAssociatetype); + //ai_Debug("0i_main", "377", "GETTING DATA: " + GetName(oPlayer) + " sAssociatetype: " + + // sAssociatetype + " sDataField: " + sDataField); + if(SqlStep(sql)) return SqlGetFloat(sql, 0); + else return 0.0; +} +void ai_SetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, json jData, string sTable = AI_TABLE) +{ + //SendMessageToPC(oPlayer, "0i_main, 629, Set DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField + " jData: " + JsonDump(jData)); + string sQuery = "UPDATE " + sTable + " SET " + sDataField + + " = @data WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindJson(sql, "@data", jData); + SqlBindString(sql, "@name", sAssociateType); + SqlStep(sql); +} +json ai_GetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE) +{ + //SendMessageToPC(oPlayer, "0i_main, 638, Get DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField); + string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString (sql, "@name", sAssociateType); + if(SqlStep(sql)) + { + json jReturn = SqlGetJson(sql, 0); + //SendMessageToPC(oPlayer, "0i_main, 646 jReturn: " + JsonDump(jReturn, 1)); + if(JsonGetType(jReturn) == JSON_TYPE_NULL) return JsonArray(); + return jReturn; + } + else return JsonNull(); +} +void aiSaveAssociateModesToDb(object oPlayer, object oAssociate) +{ + string sAssociateType = ai_GetAssociateType(oPlayer, oAssociate); + json jModes = ai_GetAssociateDbJson(oPlayer, sAssociateType, "modes"); + int nAIMode = GetLocalInt(oAssociate, sAIModeVarname); + jModes = JsonArraySet(jModes, 0, JsonInt(nAIMode)); + int nMagicMode = GetLocalInt(oAssociate, sMagicModeVarname); + jModes = JsonArraySet(jModes, 1, JsonInt(nMagicMode)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "modes", jModes); +} +void ai_SetupModes(object oPlayer, object oAssociate, string sAssociateType) +{ + json jModes = JsonArray(); + jModes = JsonArrayInsert(jModes, JsonInt(0)); // AI Modes. + // Set magic modes to use Normal magic, Bit 256. + jModes = JsonArrayInsert(jModes, JsonInt(256)); // Magic Modes. + SetLocalInt(oAssociate, sMagicModeVarname, 256); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "modes", jModes, AI_TABLE); +} +void ai_SetupButtons(object oPlayer, object oAssociate, string sAssociateType) +{ + json jButtons = JsonArray(); + jButtons = JsonArrayInsert(jButtons, JsonInt(0)); // Command buttons. + jButtons = JsonArrayInsert(jButtons, JsonInt(0)); // AI buttons. + jButtons = JsonArrayInsert(jButtons, JsonInt(0)); // AI buttons 2. + ai_SetAssociateDbJson(oPlayer, sAssociateType, "buttons", jButtons, AI_TABLE); +} +void ai_SetupAIData(object oPlayer, object oAssociate, string sAssociateType) +{ + json jAIData = JsonArray(); + jAIData = JsonArrayInsert(jAIData, JsonInt(0)); // 0 - Difficulty adjustment. + jAIData = JsonArrayInsert(jAIData, JsonInt(70)); // 1 - Heal out of combat. + SetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT, 70); + jAIData = JsonArrayInsert(jAIData, JsonInt(50)); // 2 - Heal in combat. + SetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT, 50); + jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); // 3 - Loot check range. + SetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE, 20.0); + jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); // 4 - Lock check range. + SetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE, 20.0); + jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); // 5 - Trap check range. + SetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE, 20.0); + jAIData = JsonArrayInsert(jAIData, JsonFloat(3.0)); // 6 - Associate Distance. + SetLocalFloat(oAssociate, AI_FOLLOW_RANGE, 3.0); + // This can be replaced as it is not used in the database. + // We keep it for now as we don't want to move other data. + jAIData = JsonArrayInsert(jAIData, JsonInt(11)); // 7 - Associate Perception DistanceDistance. + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, 11); + SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, 20.0); + jAIData = JsonArrayInsert(jAIData, JsonString("")); // 8 - Associate Combat Tactics. + jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); // 9 - Open Doors check range. + SetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE, 20.0); + json jSpells = JsonArray(); + jAIData = JsonArrayInsert(jAIData, jSpells); // 10 - Castable spells. + ai_SetAssociateDbJson(oPlayer, sAssociateType, "aidata", jAIData, AI_TABLE); +} +void ai_SetupLootFilters(object oPlayer, object oAssociate, string sAssociateType) +{ + json jLootFilters = JsonArray(); + // Maximum weight to pickup an item. + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(200)); + SetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT, 200); + // Bitwise int for checkbox pickup filter. + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(AI_LOOT_ALL_ON)); + SetLocalInt(oAssociate, sLootFilterVarname, AI_LOOT_ALL_ON); + // Minimum gold value to pickup. + int nIndex; + for(nIndex = 2; nIndex < 20; nIndex++) + { + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(0)); + } + ai_SetAssociateDbJson(oPlayer, sAssociateType, "lootfilters", jLootFilters, AI_TABLE); +} +void ai_SetupLocations(object oPlayer, object oAssociate, string sAssociateType) +{ + json jLocations = JsonObject(); + json jNUI = JsonObject(); + jNUI = JsonObjectSet(jNUI, "x", JsonFloat(-1.0)); + jNUI = JsonObjectSet(jNUI, "y", JsonFloat(-1.0)); + if(ai_GetIsCharacter(oAssociate)) + { + jLocations = JsonObjectSet(jLocations, AI_MAIN_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, AI_PLUGIN_NUI, jNUI); + } + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_COMMAND_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_LOOTFILTER_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_COPY_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_QUICK_WIDGET_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_SPELL_MEMORIZE_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_SPELL_KNOWN_NUI, jNUI); + jNUI = JsonObjectSet(jNUI, "x", JsonFloat(0.0)); + jNUI = JsonObjectSet(jNUI, "y", JsonFloat(0.0)); + jLocations = JsonObjectSet(jLocations, sAssociateType + AI_WIDGET_NUI, jNUI); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "locations", jLocations, AI_TABLE); +} +void ai_SetupAssociateData(object oPlayer, object oAssociate, string sAssociateType) +{ + //ai_Debug("0i_main", "744", GetName(oAssociate) + " is initializing associate data."); + ai_CheckAssociateDataAndInitialize(oPlayer, sAssociateType); + // Default behavior for associates at start. + ai_SetupModes(oPlayer, oAssociate, sAssociateType); + ai_SetupButtons(oPlayer, oAssociate, sAssociateType); + ai_SetupAIData(oPlayer, oAssociate, sAssociateType); + ai_SetupLootFilters(oPlayer, oAssociate, sAssociateType); + // ********** Plugins ************ + // These are pulled straight from the database. + ai_SetupLocations(oPlayer, oAssociate, sAssociateType); +} +void ai_RestoreDatabase(object oPlayer, object oAssociate, string sAssociateType) +{ + // ********** Modes ********** + json jModes = JsonArray(); + // AI Modes (0). + int nValue = GetLocalInt(oAssociate, sAIModeVarname); + jModes = JsonArrayInsert(jModes, JsonInt(nValue)); + // Magic Modes (1). + nValue = GetLocalInt(oAssociate, sMagicModeVarname); + jModes = JsonArrayInsert(jModes, JsonInt(nValue)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "modes", jModes, AI_TABLE); + // ********** Buttons ********** + json jButtons = JsonArray(); + // Command buttons (0). + nValue = GetLocalInt(oAssociate, sWidgetButtonsVarname); + jButtons = JsonArrayInsert(jButtons, JsonInt(nValue)); + // AI buttons Group 1 (1). + nValue = GetLocalInt(oAssociate, sAIButtonsVarname); + jButtons = JsonArrayInsert(jButtons, JsonInt(nValue)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "buttons", jButtons, AI_TABLE); + // ********** AI Data ********** + json jAIData = JsonArray(); + nValue = GetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT); + jAIData = JsonArrayInsert(jAIData, JsonInt(nValue)); + nValue = GetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT); + jAIData = JsonArrayInsert(jAIData, JsonInt(nValue)); + nValue = GetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT); + jAIData = JsonArrayInsert(jAIData, JsonInt(nValue)); + float fValue = GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE); + jAIData = JsonArrayInsert(jAIData, JsonFloat(fValue)); + fValue = GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE); + jAIData = JsonArrayInsert(jAIData, JsonFloat(fValue)); + fValue = GetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE); + jAIData = JsonArrayInsert(jAIData, JsonFloat(fValue)); + fValue = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE); + jAIData = JsonArrayInsert(jAIData, JsonFloat(fValue)); + nValue = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION); + jAIData = JsonArrayInsert(jAIData, JsonInt(nValue)); + float fRange = 20.0; + if(nValue == 8) fRange = 10.0; + else if(nValue == 10) fRange = 35.0; + SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, fRange); + string sValue = GetLocalString(oAssociate, AI_DEFAULT_SCRIPT); + jAIData = JsonArrayInsert(jAIData, JsonString(sValue)); + fValue = GetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE); + jAIData = JsonArrayInsert(jAIData, JsonFloat(fValue)); + json jValue = GetLocalJson(oPlayer, AI_SPELLS_WIDGET); + if(JsonGetType(jValue) == JSON_TYPE_NULL) + { + jValue = JsonArray(); + jValue = JsonArrayInsert(jValue, JsonInt(1)); // 0 - Class selected. + jValue = JsonArrayInsert(jValue, JsonInt(10)); // 1 - Level selected. + jValue = JsonArrayInsert(jValue, JsonArray()); // Spell list for widget. + SetLocalJson(oPlayer, AI_SPELLS_WIDGET, jValue); + } + jAIData = JsonArrayInsert(jAIData, jValue); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "aidata", jAIData); + // ********** LootFilters ********** + json jLootFilters = JsonArray(); + nValue = GetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT); + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(nValue)); + nValue = GetLocalInt(oAssociate, sLootFilterVarname); + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(nValue)); + int nIndex; + for(nIndex = 2; nIndex < 20; nIndex++) + { + nValue = GetLocalInt(oAssociate, AI_MIN_GOLD_ + IntToString(nIndex)); + jLootFilters = JsonArrayInsert(jLootFilters, JsonInt(nValue)); + } + ai_SetAssociateDbJson(oPlayer, sAssociateType, "lootfilters", jLootFilters, AI_TABLE); + // ********** Plugins ************ + // These are pulled straight from the database. + // ********** Locations ********** + // These are only in the database. +} +void ai_CheckAssociateData(object oPlayer, object oAssociate, string sAssociateType, int bLoad = FALSE) +{ + //ai_Debug("0i_main", "810", "Checking data for oAssociate: " + GetName(oAssociate)); + // Do quick check to see if they have a variable saved if so then exit. + if(GetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE) != 0.0) + { + if(!bLoad) return; + // If the database gets destroyed lets drop an error and restore values + // from the locals. + ai_CheckAssociateDataAndInitialize(oPlayer, sAssociateType); + ai_RestoreDatabase(oPlayer, oAssociate, sAssociateType); + return; + } + ai_CheckAssociateDataAndInitialize(oPlayer, sAssociateType); + // ********** Modes ********** + json jModes = ai_GetAssociateDbJson(oPlayer, sAssociateType, "modes"); + if(JsonGetType(JsonArrayGet(jModes, 0)) == JSON_TYPE_NULL) + { + ai_SetupModes(oPlayer, oAssociate, sAssociateType); + } + else + { + SetLocalInt(oAssociate, sAIModeVarname, JsonGetInt(JsonArrayGet(jModes, 0))); + SetLocalInt(oAssociate, sMagicModeVarname, JsonGetInt(JsonArrayGet(jModes, 1))); + } + // ********** Buttons ********** + json jButtons = ai_GetAssociateDbJson(oPlayer, sAssociateType, "buttons"); + if(JsonGetType(JsonArrayGet(jButtons, 0)) == JSON_TYPE_NULL) + { + ai_SetupButtons(oPlayer, oAssociate, sAssociateType); + } + else + { + // ********** Associate Command Buttons ********** + int nWidgetButtons = JsonGetInt(JsonArrayGet(jButtons, 0)); + if(nWidgetButtons) SetLocalInt(oAssociate, sWidgetButtonsVarname, nWidgetButtons); + // ********** Associate AI Buttons ********** + int nAIButtons = JsonGetInt(JsonArrayGet(jButtons, 1)); + if(nAIButtons) SetLocalInt(oAssociate, sAIButtonsVarname, nAIButtons); + } + // ********** AI Data ********** + json jAIData = ai_GetAssociateDbJson(oPlayer, sAssociateType, "aidata"); + if(JsonGetType(JsonArrayGet(jAIData, 0)) == JSON_TYPE_NULL) + { + ai_SetupAIData(oPlayer, oAssociate, sAssociateType); + } + else + { + SetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT, JsonGetInt(JsonArrayGet(jAIData, 0))); + SetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT, JsonGetInt(JsonArrayGet(jAIData, 1))); + SetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT, JsonGetInt(JsonArrayGet(jAIData, 2))); + SetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE, JsonGetFloat(JsonArrayGet(jAIData, 3))); + SetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE, JsonGetFloat(JsonArrayGet(jAIData, 4))); + SetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE, JsonGetFloat(JsonArrayGet(jAIData, 5))); + SetLocalFloat(oAssociate, AI_FOLLOW_RANGE, JsonGetFloat(JsonArrayGet(jAIData, 6))); + int nPercRange = JsonGetInt(JsonArrayGet(jAIData, 7)); + if(nPercRange < 8 || nPercRange > 11) nPercRange = 11; + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, nPercRange); + float fRange = 20.0; + if(nPercRange == 8) fRange = 10.0; + else if(nPercRange == 10) fRange = 35.0; + SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, fRange); + string sScript = JsonGetString(JsonArrayGet(jAIData, 8)); + if(sScript != "") SetLocalString(oAssociate, AI_DEFAULT_SCRIPT, sScript); + json jDoorRange = JsonArrayGet(jAIData, 9); + if(JsonGetType(jDoorRange) == JSON_TYPE_NULL) + { + jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "aidata", jAIData); + SetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE, 20.0); + } + else SetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE, JsonGetFloat(jDoorRange)); + json jSpellsWidget = JsonArrayGet(jAIData, 10); + if(JsonGetType(jSpellsWidget) == JSON_TYPE_NULL) + { + jSpellsWidget = JsonArray(); + jSpellsWidget = JsonArrayInsert(jSpellsWidget, JsonInt(0)); // 0 - Class selected. + jSpellsWidget = JsonArrayInsert(jSpellsWidget, JsonInt(0)); // 1 - Level selected. + jAIData = JsonArrayInsert(jAIData, jSpellsWidget); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "aidata", jAIData); + SetLocalJson(oPlayer, AI_SPELLS_WIDGET, jSpellsWidget); + } + } + // ********** LootFilters ********** + json jLootFilters = ai_GetAssociateDbJson(oPlayer, sAssociateType, "lootfilters"); + if(JsonGetType(JsonArrayGet(jLootFilters, 0)) == JSON_TYPE_NULL) + { + ai_SetupLootFilters(oPlayer, oAssociate, sAssociateType); + } + else + { + SetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT, JsonGetInt(JsonArrayGet(jLootFilters, 0))); + SetLocalInt(oAssociate, sLootFilterVarname, JsonGetInt(JsonArrayGet(jLootFilters, 1))); + int nIndex; + for(nIndex = 2; nIndex < 20; nIndex++) + { + SetLocalInt(oAssociate, AI_MIN_GOLD_ + IntToString(nIndex), JsonGetInt(JsonArrayGet(jLootFilters, nIndex))); + } + } + // ********** Plugins ************ + // These are pulled straight from the database. + // ********** Locations ********** + json jLocations = ai_GetAssociateDbJson(oPlayer, sAssociateType, "locations"); + if(JsonGetType(JsonObjectGet(jLocations, AI_WIDGET_NUI)) == JSON_TYPE_NULL) + { + ai_SetupLocations(oPlayer, oAssociate, sAssociateType); + } + // They are always pulled from the database, so no copies to local variables. +} +void ai_SetupDMData(object oPlayer, string sName) +{ + //ai_Debug("0i_main", "870", GetName(oPlayer) + " is initializing DM data."); + ai_CheckDMDataAndInitialize(oPlayer); + // ********** Buttons ********** + json jButtons = JsonArray(); + jButtons = JsonArrayInsert(jButtons, JsonInt(0)); // DM Widget Buttons. + ai_SetCampaignDbJson("buttons", jButtons, sName, AI_DM_TABLE); + // ********** Plugins ************ + // These are pulled straight from the database. + json jPlugins = JsonArray(); + ai_SetCampaignDbJson("plugins", jPlugins, sName, AI_DM_TABLE); + // ********** Locations ********** + json jLocations = JsonObject(); + json jNUI = JsonObject(); + jNUI = JsonObjectSet(jNUI, "x", JsonFloat(-1.0)); + jNUI = JsonObjectSet(jNUI, "y", JsonFloat(-1.0)); + jLocations = JsonObjectSet(jLocations, AI_MAIN_NUI, jNUI); + jLocations = JsonObjectSet(jLocations, AI_PLUGIN_NUI, jNUI); + jNUI = JsonObjectSet(jLocations, "x", JsonFloat(1.0)); + jNUI = JsonObjectSet(jLocations, "y", JsonFloat(1.0)); + jLocations = JsonObjectSet(jLocations, AI_WIDGET_NUI, jNUI); + ai_SetCampaignDbJson("locations", jLocations, sName, AI_DM_TABLE); + // ********** Options ********** + json jOptions = JsonArray(); + ai_SetCampaignDbJson("options", jOptions, sName, AI_DM_TABLE); + // ********** SaveSlots ********** + json jSaveSlots = JsonObject(); + ai_SetCampaignDbJson("saveslots", jSaveSlots, sName, AI_DM_TABLE); +} +void ai_CheckDMData(object oPlayer) +{ + //ai_Debug("0i_main", "898", "Checking data for DM: " + GetName(oPlayer)); + string sName = ai_RemoveIllegalCharacters(GetName(oPlayer)); + // ********** Buttons ********** + json jButtons = ai_GetCampaignDbJson("buttons", sName, AI_DM_TABLE); + // if there is no saved AImodes then set the defaults. + if(JsonGetType(JsonArrayGet(jButtons, 0)) == JSON_TYPE_NULL) + { + ai_SetupDMData(oPlayer, sName); + } + else + { + //ai_Debug("0i_main", "909", GetName(oPlayer) + " is loading DM data from the database."); + // Get data from the database and place on to the associates and player. + // ********** Buttons ********** + json jButtons = ai_GetCampaignDbJson("buttons", sName, AI_DM_TABLE); + if(JsonGetType(JsonArrayGet(jButtons, 0)) == JSON_TYPE_NULL) + { + ai_SetupDMData(oPlayer, sName); + } + SetLocalInt(oPlayer, sDMWidgetButtonVarname, JsonGetInt(JsonArrayGet(jButtons, 0))); + // ********** Associate Command Buttons ********** + int nWidgetButtons = JsonGetInt(JsonArrayGet(jButtons, 0)); + SetLocalInt(oPlayer, sDMWidgetButtonVarname, nWidgetButtons); + // ********** Plugins ************ + // These are pulled straight from the database. + // ********** Locations ********** + // These are pulled straight from the database. + // ********** Options ********** + // ********** SaveSltos ********** + } +} +json ai_Plugin_Add(object oPC, json jPlugins, string sPluginScript) +{ + if(ResManGetAliasFor(sPluginScript, RESTYPE_NCS) == "") + { + ai_SendMessages("The script (" + sPluginScript + ") was not found by ResMan!", AI_COLOR_RED, oPC); + return jPlugins; + } + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + if(JsonGetString(JsonArrayGet(jPlugin, 0)) == sPluginScript) + { + ai_SendMessages("Plugin (" + sPluginScript + ") is already installed!", AI_COLOR_RED, oPC); + return jPlugins; + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + SetLocalInt(oPC, AI_ADD_PLUGIN, TRUE); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugins); + ExecuteScript(sPluginScript, oPC); + int nPluginSet = GetLocalInt(oPC, AI_PLUGIN_SET); + // Setting AI_PLUGIN_SET to -1 means the plugin failed to load. + if(nPluginSet == -1) return jPlugins; + if(nPluginSet) + { + jPlugin = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + } + else + { + jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString(sPluginScript)); + jPlugin = JsonArrayInsert(jPlugin, JsonBool(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString(sPluginScript)); + int nCount = JsonGetLength(jPlugins) + 1; + string sIcon = "is_summon" + IntToString(nCount); + jPlugin = JsonArrayInsert(jPlugin, JsonString(sIcon)); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + } + DeleteLocalInt(oPC, AI_ADD_PLUGIN); + DeleteLocalInt(oPC, AI_PLUGIN_SET); + DeleteLocalJson(oPC, AI_JSON_PLUGINS); + return jPlugins; +} +// Temporary function to addapt old plugin json to new plugin json. +json ai_CheckOldPluginJson(object oPC) +{ + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + // If the first array is not an array then this is the old version. + if(JsonGetType(jPlugin) != JSON_TYPE_ARRAY) + { + string sScript; + json jNewPlugins = JsonArray(); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sScript = JsonGetString(jPlugin); + if(sScript != "") jNewPlugins = ai_Plugin_Add(oPC, jNewPlugins, sScript); + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + + } + ai_SetAssociateDbJson(oPC, "pc", "plugins", jNewPlugins); + return jNewPlugins; + } + return jPlugins; +} +json ai_UpdatePluginsForPC(object oPC) +{ + // Check if the server is running or single player. + if(!AI_SERVER) return ai_CheckOldPluginJson(oPC); + int nJsonType, nCounter, nIndex, bWidget, bAllow; + string sScript, sName, sIcon; + json jServerPlugins = ai_GetCampaignDbJson("plugins"); + json jPCPlugin, jPCPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + json jNewPCPlugins = JsonArray(); + json jServerPlugin = JsonArrayGet(jServerPlugins, nIndex); + while(JsonGetType(jServerPlugin) != JSON_TYPE_NULL) + { + bAllow = JsonGetInt(JsonArrayGet(jServerPlugin, 1)); + if(bAllow) + { + sName = JsonGetString(JsonArrayGet(jServerPlugin, 0)); + nCounter = 0; + jPCPlugin = JsonArrayGet(jPCPlugins, nCounter); + nJsonType = JsonGetType(jPCPlugin); + while(nJsonType != JSON_TYPE_NULL) + { + if(sName == JsonGetString(JsonArrayGet(jPCPlugin, 0))) + { + // Boolean - Add to widget. + bWidget = JsonGetInt(JsonArrayGet(jPCPlugin, 1)); + jServerPlugin = JsonArraySet(jServerPlugin, 1, JsonBool(bWidget)); + break; + } + jPCPlugin = JsonArrayGet(jPCPlugins, ++nCounter); + nJsonType = JsonGetType(jPCPlugin); + } + if(nJsonType == JSON_TYPE_NULL) + { + jServerPlugin = JsonArraySet(jServerPlugin, 1, JsonBool(FALSE)); + } + jNewPCPlugins = JsonArrayInsert(jNewPCPlugins, jServerPlugin); + } + jServerPlugin = JsonArrayGet(jServerPlugins, ++nIndex); + } + ai_SetAssociateDbJson(oPC, "pc", "plugins", jNewPCPlugins); + return jNewPCPlugins; +} +json ai_UpdatePluginsForDM(object oPC) +{ + int nJsonType, nCounter, nIndex, bWidget, bAllow; + string sName, sIcon, sDbName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jServerPlugins = ai_GetCampaignDbJson("plugins"); + ai_CheckDMDataAndInitialize(oPC); + json jDMPlugin, jDMPlugins = ai_GetCampaignDbJson("plugins", sDbName, AI_DM_TABLE); + json jNewDMPlugins = JsonArray(); + json jServerPlugin = JsonArrayGet(jServerPlugins, nIndex); + while(JsonGetType(jServerPlugin) != JSON_TYPE_NULL) + { + sName = JsonGetString(JsonArrayGet(jServerPlugin, 0)); + nCounter = 0; + jDMPlugin = JsonArrayGet(jDMPlugins, nCounter); + nJsonType = JsonGetType(jDMPlugin); + while(nJsonType != JSON_TYPE_NULL) + { + if(sName == JsonGetString(JsonArrayGet(jDMPlugin, 0))) + { + // Boolean - Add to widget. + bWidget = JsonGetInt(JsonArrayGet(jDMPlugin, 1)); + jServerPlugin = JsonArraySet(jServerPlugin, 1, JsonBool(bWidget)); + break; + } + jDMPlugin = JsonArrayGet(jDMPlugins, ++nCounter); + nJsonType = JsonGetType(jDMPlugin); + } + if(nJsonType == JSON_TYPE_NULL) + { + jServerPlugin = JsonArraySet(jServerPlugin, 1, JsonBool(FALSE)); + } + jNewDMPlugins = JsonArrayInsert(jNewDMPlugins, jServerPlugin); + jServerPlugin = JsonArrayGet(jServerPlugins, ++nIndex); + } + ai_SetCampaignDbJson("plugins", jNewDMPlugins, sDbName, AI_DM_TABLE); + return jNewDMPlugins; +} +void ai_StartupPlugins(object oPC) +{ + SetLocalInt(oPC, AI_STARTING_UP, TRUE); + int bUpdatePlugins; + string sScript; + json jPlugins; + if(GetIsDM(oPC)) jPlugins = ai_UpdatePluginsForDM(oPC); + else jPlugins = ai_UpdatePluginsForPC(oPC); + // We delete this so each mod can be added that legally loads. + DeleteLocalJson(GetModule(), AI_MONSTER_MOD_JSON); + int nIndex; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sScript = JsonGetString(JsonArrayGet(jPlugin, 0)); + ExecuteScript(sScript, oPC); + // -1 means if failed to load so lets make sure to remove it from the list. + if(GetLocalInt(oPC, AI_PLUGIN_SET) == -1) + { + jPlugins = JsonArrayDel(jPlugins, nIndex); + bUpdatePlugins = TRUE; + nIndex--; + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + if(bUpdatePlugins) ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins); + DeleteLocalInt(oPC, AI_STARTING_UP); +} diff --git a/src/module/nss/0i_menus.nss b/src/module/nss/0i_menus.nss new file mode 100644 index 0000000..8d6834c --- /dev/null +++ b/src/module/nss/0i_menus.nss @@ -0,0 +1,4823 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_menus +//////////////////////////////////////////////////////////////////////////////// + Include script for handling NUI menus. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "0i_associates" +// Maximum number of Plugins allowed on the players widget. +const int WIDGET_MAX_PLUGINS = 5; + +// Set one of the BTN_* "Widget" bitwise constants on oPlayer to bValid. +void ai_SetWidgetButton(object oPlayer, int nButton, object oAssociate, string sAssociateType, int bOn = TRUE); +// Return if nButton is set on oPlayer. Uses the BTN_* "Widget" bitwise constants. +int ai_GetWidgetButton(object oPlayer, int nButton, object oAssociate, string sAssociateType); +// Set one of the BTN_AI_* bitwise constants on oPlayer to bValid. +void ai_SetAIButton(object oPlayer, int nButton, object oAssociate, string sAssociateType, int bOn = TRUE); +// Return if nButton is set on oPlayer. Uses the BTN_AI_* "Widget" bitwise constants. +int ai_GetAIButton(object oPlayer, int nButton, object oAssociate, string sAssociateType); +// Set one of the BTN2_AI_* bitwise constants on oPlayer to bValid. +void ai_SetAIButton2(object oPlayer, int nButton, object oAssociate, string sAssociateType, int bOn = TRUE); +// Return if nButton is set on oPlayer. Uses the BTN2_AI_* "Widget" bitwise constants. +int ai_GetAIButton2(object oPlayer, int nButton, object oAssociate, string sAssociateType); +// Creates the json array required to build a companion drop down box for +// Animal Companions or Familiars. +// sCompanion2da should be either "hen_companion" or "hen_familiar". +json ai_CreateCompanionJson(object oPC, string sCompanion2da); +// Return any Metamagic or Domain attributes to place on a spell icon image. +string ai_GetSpellIconAttributes(object oCaster, int nMetaMagic, int nDomain); +// Creates the AI options menu. +void ai_CreateAIMainNUI(object oPC); +// Creates the AI options menu. +void ai_CreateAssociateCommandNUI(object oPC, object oAssociate); +// Creates an associates AI NUI. +void ai_CreateAssociateAINUI(object oPC, object oAssociate); +// Creates a widget for the player or associate. +void ai_CreateWidgetNUI(object oPC, object oAssociate); +// Creates the Loot filter menu. +void ai_CreateLootFilterNUI(object oPC, object oAssociate); +// Creates the Plugin Manager menu. +void ai_CreatePluginNUI(object oPC); +// Creates the Spell menu that selects the spells to go on the Spell Widget. +void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate); +// Creates the Spell menu that lets the player to select the associates castable spells. +void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate); +// Creates the spell description menu so a player can see what a spell does. +// If nSpell > 0 then use that value for the spells description. +void ai_CreateDescriptionNUI(object oPC, json jSpell, int nSpell = 0); + +string ai_GetRandomTip() +{ + int nRoll; + if(AI_SERVER) nRoll = Random(26); + else nRoll = Random(46); + return Get2DAString("ai_messages", "Text", nRoll); +} +void ai_SetWidgetButton(object oPlayer, int nButton, object oAssociate, string sAssociateType, int bOn = TRUE) +{ + int nWidgetButtons = GetLocalInt(oAssociate, sWidgetButtonsVarname); + json jButtons = ai_GetAssociateDbJson(oPlayer, sAssociateType, "buttons"); + if(bOn) nWidgetButtons = nWidgetButtons | nButton; + else nWidgetButtons = nWidgetButtons & ~nButton; + SetLocalInt(oAssociate, sWidgetButtonsVarname, nWidgetButtons); + jButtons = JsonArraySet(jButtons, 0, JsonInt(nWidgetButtons)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "buttons", jButtons); +} +int ai_GetWidgetButton(object oPlayer, int nButton, object oAssociate, string sAssociateType) +{ + // This is the DM access switch that uses the same bitwise as the players + // to control what widget buttons they can use. + if(ai_GetDMWAccessButton(nButton)) return FALSE; + int nWidgetButtons = GetLocalInt(oAssociate, sWidgetButtonsVarname); + return nWidgetButtons & nButton; +} +void ai_SetAIButton(object oPlayer, int nButton, object oAssociate, string sAssociateType, int bOn = TRUE) +{ + int nAIButtons = GetLocalInt(oAssociate, sAIButtonsVarname); + json jButtons = ai_GetAssociateDbJson(oPlayer, sAssociateType, "buttons"); + if(bOn) nAIButtons = nAIButtons | nButton; + else nAIButtons = nAIButtons & ~nButton; + SetLocalInt(oAssociate, sAIButtonsVarname, nAIButtons); + jButtons = JsonArraySet(jButtons, 1, JsonInt(nAIButtons)); + ai_SetAssociateDbJson(oPlayer, sAssociateType, "buttons", jButtons); +} +int ai_GetAIButton(object oPlayer, int nButton, object oAssociate, string sAssociateType) +{ + // This is the DM access switch that uses the same bitwise as the players + // to control what AI widget buttons they can use. + if(ai_GetDMAIAccessButton(nButton)) return FALSE; + int nAIButtons = GetLocalInt(oAssociate, sAIButtonsVarname); + return nAIButtons & nButton; +} +json ai_CreateAIScriptJson(object oPC) +{ + json jScript = JsonArrayInsert(JsonArray(), NuiComboEntry("", 0)); + int nNth = 1; + string sScript = ResManFindPrefix("ai_a_", RESTYPE_NCS, nNth); + while(sScript != "") + { + jScript = JsonArrayInsert(jScript, NuiComboEntry(sScript, nNth)); + sScript = ResManFindPrefix("ai_a_", RESTYPE_NCS, ++nNth); + } + return jScript; +} +json ai_CreateCompanionJson(object oPC, string sCompanion2da) +{ + int nCnt, nMaxRowCount = Get2DARowCount(sCompanion2da); + string sName; + json jCompanion = JsonArray(); + while(nCnt < nMaxRowCount) + { + sName = GetStringByStrRef(StringToInt(Get2DAString(sCompanion2da, "STRREF", nCnt))); + jCompanion = JsonArrayInsert(jCompanion, NuiComboEntry(sName, nCnt++)); + } + return JsonArrayInsert(jCompanion, NuiComboEntry("Random", nCnt)); +} +string ai_GetSpellIconAttributes(object oCaster, int nMetaMagic, int nDomain) +{ + string sAttributeText; + if(nMetaMagic != METAMAGIC_ANY && nMetaMagic != METAMAGIC_NONE) + { + if(nMetaMagic == METAMAGIC_EXTEND) sAttributeText = "X"; + if(nMetaMagic == METAMAGIC_EMPOWER) sAttributeText = "P"; + if(nMetaMagic == METAMAGIC_MAXIMIZE) sAttributeText = "M"; + if(nMetaMagic == METAMAGIC_QUICKEN) sAttributeText = "Q"; + if(nMetaMagic == METAMAGIC_SILENT) sAttributeText = "I"; + if(nMetaMagic == METAMAGIC_STILL) sAttributeText = "T"; + } + else sAttributeText = ""; + if(nDomain > 0) sAttributeText += "D"; + return sAttributeText; +} +void ai_CreateAIMainNUI(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int nMonsterAI = (ResManGetAliasFor("ai_default", RESTYPE_NCS) != ""); + int nAssociateAI = (ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != ""); + string sText = " [Single player]"; + if(AI_SERVER) sText = " [Server]"; + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, PHILOS_VERSION + sText, "lbl_version ", 510.0f, 20.0f, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 101 + jRow = CreateLabel(JsonArray(), "", "lbl_ai_info", 510.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 500 / 129 + jRow = CreateButton(JsonArray(), "Plugin Manager", "btn_plugin_manager", 120.0f, 20.0f, -1.0, "btn_plugin_manager_tooltip"); + if(nAssociateAI) jRow = CreateButtonSelect(jRow, "Associate Widgets", "btn_toggle_assoc_widget", 140.0f, 20.0f, "btn_assoc_widget_tooltip"); + jRow = CreateButtonSelect(jRow, "Action Ghost Mode", "btn_action_ghost", 160.0f, 20.0f, "btn_action_ghost_tooltip"); + jRow = CreateButtonSelect(jRow, "Effect Icons", "btn_effect_icon", 100.0f, 20.0f, "btn_effect_icon_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 500 / 157 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "MODULE RULES", "lbl_ai_rules", 200.0f, 20.0f, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 157.0; + // Row 5 ******************************************************************* 500 / --- (28) + // Make the AI options a Group. + json jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_max_henchman", 2, FALSE, 30.0f, 20.0f, "txt_max_henchman_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "Max number of henchmen that is allowed in your party.", "lbl_max_hench", 416.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_max_henchman_tooltip"); + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_xp_scale", 3, FALSE, 40.0f, 20.0f, "txt_xp_scale_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "Modules experience scale.", "lbl_xp_scale", 175.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_xp_scale_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " scale to party.", "chbx_party_scale", 150.0, 20.0, "chbx_party_scale_tooltip"); + jGroupRow = CreateButton(jGroupRow, "Default", "btn_default_xp", 70.0f, 20.0f, -1.0, "btn_default_xp_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 78.0; + if(nMonsterAI || nAssociateAI) + { + jGroupRow = CreateCheckBox(JsonArray(), " Creatures will use advanced combat movement.", "chbx_advanced_movement", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Use item level restrictions for creatures [Default is off].", "chbx_ilr", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Creatures can use the skill Use Magic Device.", "chbx_umd", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Creatures can use Healing kits.", "chbx_use_healingkits", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Moral checks, wounded creatures may flee during combat.", "chbx_moral", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), " Spells the AI will not use:", "lbl_restrict_spells", 190.0, 20.0, NUI_HALIGN_LEFT); + jGroupRow = CreateCheckBox(jGroupRow, " Darkness", "chbx_darkness", 90.0, 20.0, "chbx_darkness_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " Dispels", "chbx_dispels", 90.0, 20.0, "chbx_dispels_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " Time Stop", "chbx_timestop", 90.0, 20.0, "chbx_timestop_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 196.0; + } + if(nMonsterAI) + { + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_ai_difficulty", 3, FALSE, 40.0f, 20.0f, "txt_ai_difficulty_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "% chance monsters will attack the weakest target.", "lbl_ai_difficulty", 406.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_ai_difficulty_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_perception_distance", 2, FALSE, 35.0f, 20.0f, "txt_perception_distance_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "meters is the distance a monster can respond to allies.", "lbl_perception_distance", 411.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "txt_perception_distance_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can prebuff before combat starts.", "chbx_buff_monsters", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can use summons before combat starts.", "chbx_buff_summons", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can use tactics (ambush, defensive, flanker, etc).", "chbx_ambush_monsters", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "Add ", "lbl_inc_enc", 30.0, 20.0, NUI_HALIGN_LEFT, 0, -1.0); + jGroupRow = CreateTextEditBox(jGroupRow, "sPlaceHolder", "txt_inc_enc", 4, FALSE, 55.0f, 20.0f, "txt_inc_enc_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "monsters per spawned encounter monster.", "lbl_inc_enc", 357.0, 20.0, NUI_HALIGN_LEFT, NUI_VALIGN_MIDDLE, 0.0, "txt_inc_enc_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_inc_hp", 3, FALSE, 40.0f, 20.0f, "txt_inc_hp_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "% increase in all monster's hitpoints.", "lbl_inc_hp", 406.0, 20.0, NUI_HALIGN_LEFT); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "***** WARNING! The options below may break the module! *****", "lbl_warning", 450.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can wander upto ", "chbx_wander", 220.0, 20.0, "chbx_warning_tooltip"); + jGroupRow = CreateTextEditBox(jGroupRow, "sPlaceHolder", "txt_wander_distance", 2, FALSE, 35.0f, 20.0f, "chbx_warning_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "meters and ", "lbl_wander_distance", 80.0f, 20.0f, NUI_HALIGN_LEFT, NUI_VALIGN_MIDDLE, 0.0, "chbx_warning_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, "open doors.", "chbx_open_doors", 100.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can summon companions.", "chbx_companions", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Summoned associates to remain after masters death.", "chbx_perm_assoc", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Make enemy corpses remain.", "chbx_corpses_stay", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_perc_dist", 450.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "lbl_perc_dist_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 336.0; + } + jRow = JsonArrayInsert(JsonArray(), NuiGroup(NuiCol(jGroupCol))); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + json jLocations = ai_GetAssociateDbJson(oPC, "pc", "locations"); + jLocations = JsonObjectGet(jLocations, AI_MAIN_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, AI_MAIN_NUI, sName + " PEPS Main Menu", + fX, fY, 534.0f, fHeight, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArray(); + jData = JsonArrayInsert(jData, JsonString(ObjectToString(oPC))); + NuiSetUserData(oPC, nToken, jData); + object oModule = GetModule(); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 - Version label. + // Row 2 + int nUsing; + // Check the monster AI. + string sLocation = ResManGetAliasFor("ai_default", RESTYPE_NCS); + if(sLocation != "") + { + nUsing = TRUE; + string sLocation = ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS); + if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE; + if(nUsing) sText = "Monster AI working"; + else sText = "Monster AI not working"; + } + else sText = "Monster AI not loaded"; + // Check the associate AI. + sLocation = ResManGetAliasFor("ai_a_default", RESTYPE_NCS); + if(sLocation != "") + { + nUsing = TRUE; + string sLocation = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS); + if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE; + if(nUsing) sText += ", Associate AI working"; + else sText += ", Associate AI not working"; + } + else sText += ", Associate AI not loaded"; + // Check for PRC. + sLocation = ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS); + if(sLocation != "") sText += ", PRC loaded."; + else + { + // Check the player AI. + sLocation = ResManGetAliasFor("xx_pc_1_hb", RESTYPE_NCS); + if(sLocation != "") sText += ", Player AI loaded."; + else sText += ", Player AI not loaded."; + } + NuiSetBind(oPC, nToken, "lbl_ai_info_label", JsonString(sText)); + // Row 3 + NuiSetBind(oPC, nToken, "btn_plugin_manager_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_plugin_manager_tooltip", JsonString(" Manages external executable scripts.")); + if(nAssociateAI) + { + NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_event", JsonBool(TRUE)); + int bWidgetOn = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, OBJECT_INVALID, "pc"); + NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget", JsonBool(bWidgetOn)); + NuiSetBind(oPC, nToken, "btn_assoc_widget_tooltip", JsonString(" Turns On/Off all associate widgets.")); + } + int bActionGhost = ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST); + NuiSetBind(oPC, nToken, "btn_action_ghost", JsonBool (bActionGhost)); + NuiSetBind(oPC, nToken, "btn_action_ghost_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_action_ghost_tooltip", JsonString(" Allows associates to move through creatures while in command mode.")); + int bEffectIcon = ai_GetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT); + NuiSetBind(oPC, nToken, "btn_effect_icon", JsonBool (bEffectIcon)); + NuiSetBind(oPC, nToken, "btn_effect_icon_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_effect_icon_tooltip", JsonString(" When on sends effect icon reports to the chat screen.")); + // Row 3 Label for AI RULES + // Row 4 + NuiSetBind(oPC, nToken, "txt_max_henchman", JsonString(IntToString(GetLocalInt(oModule, AI_RULE_MAX_HENCHMAN)))); + NuiSetBindWatch (oPC, nToken, "txt_max_henchman", TRUE); + NuiSetBind(oPC, nToken, "txt_max_henchman_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_max_henchman_tooltip", JsonString(" Set max number of henchman allowed (1-12).")); + NuiSetBind(oPC, nToken, "txt_xp_scale", JsonString(IntToString(GetModuleXPScale()))); + NuiSetBindWatch (oPC, nToken, "txt_xp_scale", TRUE); + NuiSetBind(oPC, nToken, "txt_xp_scale_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_xp_scale_tooltip", JsonString(" Set the modules XP scale (0 - 200) Normal D&D is 10.")); + NuiSetBind(oPC, nToken, "chbx_party_scale_check", JsonBool(GetLocalInt(oModule, AI_RULE_PARTY_SCALE))); + NuiSetBindWatch(oPC, nToken, "chbx_party_scale_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_party_scale_event", JsonBool(TRUE)); + sText = IntToString(GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP)); + NuiSetBind(oPC, nToken, "chbx_party_scale_tooltip", JsonString(" PEPS adjusts your XP based on party size from (" + sText + ").")); + NuiSetBind(oPC, nToken, "btn_default_xp_event", JsonBool(TRUE)); + sText = IntToString(GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE)); + NuiSetBind(oPC, nToken, "btn_default_xp_tooltip", JsonString(" Reset the Modules XP to (" + sText + ").")); + NuiSetBind(oPC, nToken, "chbx_warning_tooltip", JsonString(" ** This will break some modules! ** See Readme for issues!")); + if(nMonsterAI) + { + NuiSetBind(oPC, nToken, "txt_ai_difficulty", JsonString(IntToString(GetLocalInt(oModule, AI_RULE_AI_DIFFICULTY)))); + NuiSetBindWatch(oPC, nToken, "txt_ai_difficulty", TRUE); + NuiSetBind(oPC, nToken, "txt_ai_difficulty_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_buff_monsters_check", JsonBool(GetLocalInt(oModule, AI_RULE_BUFF_MONSTERS))); + NuiSetBindWatch(oPC, nToken, "chbx_buff_monsters_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_monsters_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_buff_summons_check", JsonBool(GetLocalInt(oModule, AI_RULE_PRESUMMON))); + NuiSetBindWatch(oPC, nToken, "chbx_buff_summons_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_summons_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_ambush_monsters_check", JsonBool(GetLocalInt(oModule, AI_RULE_AMBUSH))); + NuiSetBindWatch(oPC, nToken, "chbx_ambush_monsters_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ambush_monsters_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_companions_check", JsonBool(GetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS))); + NuiSetBindWatch(oPC, nToken, "chbx_companions_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_companions_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_perm_assoc_check", JsonBool(GetLocalInt(oModule, AI_RULE_PERM_ASSOC))); + string sModuleName = GetModuleName(); + if(!GetLocalInt(oModule, AI_USING_PRC) && + (sModuleName != "Neverwinter Nights - Infinite Dungeons" || + sModuleName != "Infinite Dungeons [PRC8]")) + { + NuiSetBindWatch(oPC, nToken, "chbx_perm_assoc_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_perm_assoc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_corpses_stay_check", JsonBool(GetLocalInt(oModule, AI_RULE_CORPSES_STAY))); + NuiSetBindWatch(oPC, nToken, "chbx_corpses_stay_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_corpses_stay_event", JsonBool(TRUE)); + } + NuiSetBind(oPC, nToken, "txt_perception_distance", JsonString(FloatToString(GetLocalFloat(oModule, AI_RULE_PERCEPTION_DISTANCE), 0, 0))); + NuiSetBindWatch(oPC, nToken, "txt_perception_distance", TRUE); + NuiSetBind(oPC, nToken, "txt_perception_distance_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_perception_distance_tooltip", JsonString(" Range [10 to 60 meters] from the player.")); + NuiSetBindWatch(oPC, nToken, "lbl_perc_dist", TRUE); + int nPercDist = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE); + if(nPercDist < 8 || nPercDist > 11) + { + nPercDist = 11; + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, 11); + } + if(nPercDist == 8) sText = " Monster perception: Short [10 Sight / 10 Listen]"; + else if(nPercDist == 9) sText = " Monster perception: Medium [20 Sight / 20 Listen]"; + else if(nPercDist == 10) sText = " Monster perception: Long [35 Sight / 20 Listen]"; + else sText = " Monster perception: Default [Monster's default values]"; + NuiSetBind(oPC, nToken, "lbl_perc_dist_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "lbl_perc_dist_tooltip", JsonString(" Use the mouse wheel to change values.")); + int bWander = GetLocalInt(oModule, AI_RULE_WANDER); + NuiSetBind(oPC, nToken, "chbx_wander_check", JsonBool(bWander)); + NuiSetBindWatch(oPC, nToken, "chbx_wander_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_wander_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_wander_distance", JsonString(FloatToString(GetLocalFloat(oModule, AI_RULE_WANDER_DISTANCE), 0, 0))); + NuiSetBindWatch(oPC, nToken, "txt_wander_distance", TRUE); + NuiSetBind(oPC, nToken, "txt_wander_distance_event", JsonBool(bWander)); + NuiSetBind(oPC, nToken, "chbx_open_doors_check", JsonBool(GetLocalInt(oModule, AI_RULE_OPEN_DOORS))); + NuiSetBindWatch(oPC, nToken, "chbx_open_doors_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_open_doors_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_open_doors_tooltip", JsonString(" This allows monsters to open doors to hunt you down!")); + NuiSetBind(oPC, nToken, "txt_inc_enc_tooltip", JsonString(" Spawns one extra monster per counter above 1. Adds value to counter per encounter monster spawned.")); + NuiSetBind(oPC, nToken, "txt_inc_enc", JsonString(FloatToString(GetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS), 0, 2))); + NuiSetBindWatch(oPC, nToken, "txt_inc_enc", TRUE); + NuiSetBind(oPC, nToken, "txt_inc_enc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_inc_hp", JsonString(IntToString(GetLocalInt(oModule, AI_INCREASE_MONSTERS_HP)))); + NuiSetBindWatch(oPC, nToken, "txt_inc_hp", TRUE); + NuiSetBind(oPC, nToken, "txt_inc_hp_event", JsonBool(TRUE)); + } + if(nMonsterAI || nAssociateAI) + { + NuiSetBind(oPC, nToken, "chbx_moral_check", JsonBool(GetLocalInt(oModule, AI_RULE_MORAL_CHECKS))); + NuiSetBindWatch (oPC, nToken, "chbx_moral_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_moral_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_advanced_movement_check", JsonBool(GetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT))); + NuiSetBindWatch (oPC, nToken, "chbx_advanced_movement_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_advanced_movement_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_ilr_check", JsonBool(GetLocalInt(oModule, AI_RULE_ILR))); + NuiSetBindWatch (oPC, nToken, "chbx_ilr_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ilr_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_umd_check", JsonBool(GetLocalInt(oModule, AI_RULE_ALLOW_UMD))); + NuiSetBindWatch (oPC, nToken, "chbx_umd_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_umd_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_use_healingkits_check", JsonBool(GetLocalInt(oModule, AI_RULE_HEALERSKITS))); + NuiSetBindWatch (oPC, nToken, "chbx_use_healingkits_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_use_healingkits_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_darkness_check", JsonBool(ai_SpellRestricted(SPELL_DARKNESS))); + NuiSetBindWatch (oPC, nToken, "chbx_darkness_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_darkness_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_darkness_tooltip", JsonString(" AI will not use the Darkness spell in combat.")); + NuiSetBind(oPC, nToken, "chbx_dispels_check", JsonBool(ai_SpellRestricted(SPELL_DISPEL_MAGIC))); + NuiSetBindWatch (oPC, nToken, "chbx_dispels_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_dispels_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_dispels_tooltip", JsonString(" AI will not use any of the Dispel spells in combat.")); + NuiSetBind(oPC, nToken, "chbx_timestop_check", JsonBool(ai_SpellRestricted(SPELL_TIME_STOP))); + NuiSetBindWatch (oPC, nToken, "chbx_timestop_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_timestop_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_timestop_tooltip", JsonString(" AI will not use the Time Stop spell in combat.")); + } +} +void ai_CreateAssociateCommandNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int bRight, bLeft; + int bIsPC = ai_GetIsCharacter(oAssociate); + int bUsingPCAI = ResManGetAliasFor("xx_pc_1_hb", RESTYPE_NCS) != ""; + int bUsingHenchAI = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS) != ""; + float fHeight = 73.0; + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 73 + json jRow = JsonArray(); + json jCol = JsonArray(); + // If all the AI buttons are blocked then don't load the menu. + if(GetLocalInt(GetModule(), sDMAIAccessVarname) != 203423743) + { + if(bIsPC) + { + if(bUsingPCAI || !AI_SERVER) + { + if(bUsingPCAI) + { + jRow = CreateButton(jRow, "AI Menu", "btn_ai_menu", 232.0, 20.0, -1.0, "btn_ai_menu_tooltip"); + } + if(!AI_SERVER) + { + jRow = CreateButton(jRow, "Main Menu", "btn_main_menu", 232.0, 20.0, -1.0, "btn_main_menu_tooltip"); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + } + else + { + if(bUsingHenchAI) + { + jRow = CreateButton(jRow, "AI Menu", "btn_ai_menu", 232.0, 20.0, -1.0, "btn_ai_menu_tooltip"); + } + jRow = CreateButtonSelect(jRow, "", "btn_widget_onoff", 232.0, 20.0, "btn_widget_onoff_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + } + // Row 2 ******************************************************************* 500 / 101 + jRow = JsonArray(); + jRow = CreateButtonSelect(jRow, "Lock Widget", "btn_widget_lock", 154.0, 20.0, "btn_widget_lock_tooltip"); + jRow = CreateButton(jRow, "Copy Settings", "btn_copy_settings", 154.0, 20.0, -1.0, "btn_copy_settings_tooltip"); + jRow = CreateButtonSelect(jRow, "Vertical Widget", "btn_vertical_widget", 154.0, 20.0, "btn_vertical_widget_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 500 / 129 + bRight = !ai_GetDMWAccessButton(BTN_CMD_ACTION); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_GUARD); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "", "btn_cmd_action", 200.0, 20.0, -1.0, "btn_cmd_action_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_action", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "", "btn_cmd_guard", 200.0, 20.0, -1.0, "btn_cmd_guard_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_guard", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 4 ******************************************************************* 500 / 157 + jRow = JsonArray(); + bRight = !ai_GetDMWAccessButton(BTN_CMD_HOLD); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_ATTACK); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "", "btn_cmd_hold", 200.0, 20.0, -1.0, "btn_cmd_hold_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_hold", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "", "btn_cmd_attack", 200.0, 20.0, -1.0, "btn_cmd_attack_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_attack", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 5 ******************************************************************* 500 / 213 + bRight = !ai_GetDMWAccessButton(BTN_CMD_FOLLOW); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_FOLLOW_TARGET); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "", "btn_cmd_follow", 200.0, 20.0, -1.0, "btn_cmd_follow_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_follow", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Select follow target", "btn_follow_target", 200.0, 20.0, -1.0, "btn_follow_target_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_follow_target", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 6 ******************************************************************* 500 / 185 + if(bIsPC) + { + bRight = !ai_GetDMWAccessButton(BTN_CMD_SEARCH); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_STEALTH); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "All Search Mode", "btn_cmd_search", 200.0, 20.0, -1.0, "btn_cmd_search_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_search", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "All Stealth Mode", "btn_cmd_stealth", 200.0, 20.0, -1.0, "btn_cmd_stealth_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_stealth", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + } + // Row 7 ******************************************************************* 500 / 241 + bRight = !ai_GetDMWAccessButton(BTN_CMD_AI_SCRIPT); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_PLACE_TRAP); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Combat Tactics", "btn_cmd_ai_script", 200.0, 20.0, -1.0, "btn_cmd_ai_script_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_ai_script", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Place a Trap", "btn_cmd_place_trap", 200.0, 20.0, -1.0, "btn_cmd_place_trap_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_place_trap", 25.0, 20.0); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 8 ******************************************************************* 500 / --- + int bMemorize = ai_GetIsSpellCaster(oAssociate); + int bSpellbook = ai_GetIsSpellBookRestrictedCaster(oAssociate); + bRight = !ai_GetDMWAccessButton(BTN_CMD_SPELL_WIDGET); + bLeft = !ai_GetDMWAccessButton(BTN_DM_CMD_MEMORIZE); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Set Quick Widget", "btn_quick_widget", 200.0, 20.0, -1.0, "btn_quick_widget_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_quick_widget", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) // Memorizes their spells. + { + if(bMemorize == 2 && bSpellbook) + { + jRow = CreateButton(jRow, "Memorize Spells", "btn_spell_memorize", 114.0, 20.0, -1.0, "btn_spell_memorize_tooltip"); + jRow = CreateButton(jRow, "Known Spells", "btn_spell_known", 110.0, 20.0, -1.0, "btn_spell_known_tooltip"); + } + else if(bMemorize == 2) + { + jRow = CreateButton(jRow, "Set Memorize Spells", "btn_spell_memorize", 200.0, 20.0, -1.0, "btn_spell_memorize_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_1", 25.0, 20.0); + } + else if(bSpellbook && !ai_GetIsCharacter(oAssociate)) + { + jRow = CreateButton(jRow, "Set Known Spells", "btn_spell_known", 200.0, 20.0, -1.0, "btn_spell_known_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_1", 25.0, 20.0); + } + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 9 ******************************************************************* 500 / 269 + bRight = !ai_GetDMWAccessButton(BTN_BUFF_SHORT); + bLeft = !ai_GetDMWAccessButton(BTN_BUFF_LONG); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Cast Short Buff spells", "btn_buff_short", 200.0, 20.0, -1.0, "btn_buff_short_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_short", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Cast Long Buff spells", "btn_buff_long", 200.0, 20.0, -1.0, "btn_buff_long_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_long", 25.0, 20.0); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 10 ******************************************************************* 500 / 297 + bRight = !ai_GetDMWAccessButton(BTN_BUFF_ALL); + bLeft = !ai_GetDMWAccessButton(BTN_BUFF_REST); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Cast All Buff spells", "btn_buff_all", 200.0, 20.0, -1.0, "btn_buff_all_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_all", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Buff after resting", "btn_buff_rest", 200.0, 20.0, -1.0, "btn_buff_rest_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_rest", 25.0, 20.0); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 11 ******************************************************************* 500 / 325 + bRight = !ai_GetDMWAccessButton(BTN_CMD_JUMP_TO); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_GHOST_MODE); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "", "btn_jump_to", 200.0, 20.0, -1.0, "btn_jump_to"); + jRow = CreateCheckBox(jRow, "", "chbx_jump_to", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Ghost Mode", "btn_ghost_mode", 200.0, 20.0, -1.0, "btn_ghost_mode_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ghost_mode", 25.0, 20.0); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 12 ****************************************************************** 500 / 353 + bRight = !ai_GetDMWAccessButton(BTN_CMD_CAMERA); + bLeft = !ai_GetDMWAccessButton(BTN_CMD_INVENTORY); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Toggle Camera Focus", "btn_camera", 200.0, 20.0, -1.0, "btn_camera_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_camera", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Open/Close Inventory", "btn_inventory", 200.0, 20.0, -1.0, "btn_inventory_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_inventory", 25.0, 20.0); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 13 ******************************************************************* 500 / --- + int bFamiliar = GetHasFeat(FEAT_SUMMON_FAMILIAR, oAssociate, TRUE); + if(!ai_GetDMWAccessButton(BTN_CMD_FAMILIAR) && bFamiliar) + { + jRow = JsonArray(); + jRow = CreateLabel(jRow, "", "lbl_familiar_type", 225.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "", "lbl_familiar_name", 225.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + // Row 14 ******************************************************************* 500 / --- + jRow = JsonArray(); + jRow = CreateCombo(jRow, ai_CreateCompanionJson(oPC, "hen_familiar"), "cmb_familiar", 200.0, 20.0); + jRow = CreateCheckBox(jRow, "", "chbx_familiar", 25.0, 20.0); + jRow = CreateTextEditBox(jRow, "txtbox", "txt_familiar_name", 50, FALSE, 178.0, 20.0); + jRow = CreateButton(jRow, "", "btn_familiar_name", 55.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 15 ******************************************************************* 500 / --- + int bCompanion = GetHasFeat(FEAT_ANIMAL_COMPANION, oAssociate, TRUE); + if(!ai_GetDMWAccessButton(BTN_CMD_COMPANION) && bCompanion) + { + jRow = JsonArray(); + jRow = CreateLabel(jRow, "", "lbl_companion_type", 225.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "", "lbl_companion_name", 225.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + // Row 16 ******************************************************************* 500 / --- + jRow = JsonArray(); + jRow = CreateCombo(jRow, ai_CreateCompanionJson(oPC, "hen_companion"), "cmb_companion", 200.0, 20.0); + jRow = CreateCheckBox(jRow, "", "chbx_companion", 25.0, 20.0); + jRow = CreateTextEditBox(jRow, "txtbox", "txt_companion_name", 50, FALSE, 178.0, 20.0); + jRow = CreateButton(jRow, "", "btn_companion_name", 55.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + } + // Row 17+ ****************************************************************** 500 / --- + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jPCPlugins; + if(bIsPC) + { + jPCPlugins = ai_UpdatePluginsForPC(oPC); + // Set the plugins the player can use. + int nIndex; + string sButton, sName; + json jPlugin = JsonArrayGet(jPCPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + jRow = JsonArray(); + sButton = IntToString(nIndex); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(jRow, sName, "btn_plugin_" + sButton, 200.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0, "chbx_plugin_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jPlugin = JsonArrayGet(jPCPlugins, ++nIndex); + if(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(jRow, sName, "btn_plugin_" + sButton, 200.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0, "chbx_plugin_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + else + { + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + break; + } + jPlugin = JsonArrayGet(jPCPlugins, ++nIndex); + } + } + // Row 18 ****************************************************************** 500 / --- + jRow = JsonArray(); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "", "lbl_info_1", 475.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_COMMAND_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_COMMAND_NUI, sName + " Command Menu", + fX, fY, 500.0, fHeight + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Get which buttons are activated. + int bAIWidgetLock = ai_GetWidgetButton(oPC, BTN_WIDGET_LOCK, oAssociate, sAssociateType); + int bCmdAction = ai_GetWidgetButton(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType); + int bCmdGuard = ai_GetWidgetButton(oPC, BTN_CMD_GUARD, oAssociate, sAssociateType); + int bCmdHold = ai_GetWidgetButton(oPC, BTN_CMD_HOLD, oAssociate, sAssociateType); + int bCmdSearch = ai_GetWidgetButton(oPC, BTN_CMD_SEARCH, oAssociate, sAssociateType); + int bCmdStealth = ai_GetWidgetButton(oPC, BTN_CMD_STEALTH, oAssociate, sAssociateType); + int bCmdAttack = ai_GetWidgetButton(oPC, BTN_CMD_ATTACK, oAssociate, sAssociateType); + int bCmdFollow = ai_GetWidgetButton(oPC, BTN_CMD_FOLLOW, oAssociate, sAssociateType); + int bFollowTarget = ai_GetAIButton(oPC, BTN_AI_FOLLOW_TARGET, oAssociate, sAssociateType); + int bCmdAIScript = ai_GetWidgetButton(oPC, BTN_CMD_AI_SCRIPT, oAssociate, sAssociateType); + int bCmdPlacetrap = ai_GetWidgetButton(oPC, BTN_CMD_PLACE_TRAP, oAssociate, sAssociateType); + int bSpellWidget = ai_GetWidgetButton(oPC, BTN_CMD_SPELL_WIDGET, oAssociate, sAssociateType); + int bBuffRest = ai_GetWidgetButton(oPC, BTN_BUFF_REST, oAssociate, sAssociateType); + int bBuffShort = ai_GetWidgetButton(oPC, BTN_BUFF_SHORT, oAssociate, sAssociateType); + int bBuffLong = ai_GetWidgetButton(oPC, BTN_BUFF_LONG, oAssociate, sAssociateType); + int bBuffAll = ai_GetWidgetButton(oPC, BTN_BUFF_ALL, oAssociate, sAssociateType); + int bJumpTo = ai_GetWidgetButton(oPC, BTN_CMD_JUMP_TO, oAssociate, sAssociateType); + int bGhostMode = ai_GetWidgetButton(oPC, BTN_CMD_GHOST_MODE, oAssociate, sAssociateType); + int bCamera = ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType); + int bInventory = ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType); + int bBtnFamiliar = ai_GetWidgetButton(oPC, BTN_CMD_FAMILIAR, oAssociate, sAssociateType); + int bBtnCompanion = ai_GetWidgetButton(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType); + int bVertical = ai_GetWidgetButton(oPC, BTN_WIDGET_VERTICAL, oAssociate, sAssociateType); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArray(); + jData = JsonArrayInsert(jData, JsonString(ObjectToString(oAssociate))); + NuiSetUserData(oPC, nToken, jData); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + string sText; + // Row 1 + // If all the AI buttons are blocked then don't load the menu. + if(GetLocalInt(GetModule(), sDMAIAccessVarname) != 203423743) + { + if(bIsPC) + { + if(bUsingPCAI) + { + NuiSetBind(oPC, nToken, "btn_ai_menu_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_menu_tooltip", JsonString(" " + sName + " AI options")); + } + NuiSetBind(oPC, nToken, "btn_copy_settings_event", JsonBool (TRUE)); + sText = " Copy AI and command settings for one creature to others."; + NuiSetBind(oPC, nToken, "btn_copy_settings_tooltip", JsonString(sText)); + if(!AI_SERVER) + { + NuiSetBind(oPC, nToken, "btn_main_menu_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_main_menu_tooltip", JsonString(" Module Options")); + } + } + else + { + if(bUsingHenchAI) + { + NuiSetBind(oPC, nToken, "btn_ai_menu_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_menu_tooltip", JsonString(" " + sName + " AI options")); + } + NuiSetBind(oPC, nToken, "btn_copy_settings_event", JsonBool (TRUE)); + sText = " Copy AI and command settings for one creature to others."; + NuiSetBind(oPC, nToken, "btn_copy_settings_tooltip", JsonString(sText)); + string sText2; + if(ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType)) + { + sText = "Off"; sText2 = "on"; + NuiSetBind(oPC, nToken, "btn_widget_onoff", JsonBool(FALSE)); + } + else + { + sText = "On"; sText2 = "off"; + NuiSetBind(oPC, nToken, "btn_widget_onoff", JsonBool(TRUE)); + } + NuiSetBind(oPC, nToken, "btn_widget_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_onoff_label", JsonString("Widget " + sText)); + NuiSetBind(oPC, nToken, "btn_widget_onoff_tooltip", JsonString( + " Turn " + sName + " widget " + sText2)); + } + } + // Row 2 + NuiSetBind(oPC, nToken, "btn_widget_lock_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_lock", JsonBool(bAIWidgetLock)); + NuiSetBind(oPC, nToken, "btn_widget_lock_tooltip", JsonString( + " Locks " + sName + " widget to the current location.")); + NuiSetBind(oPC, nToken, "btn_widget_size_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_size_tooltip", JsonString( + " Adjusts the size of " + sName + " widget buttons")); + NuiSetBind(oPC, nToken, "btn_vertical_widget_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_vertical_widget", JsonBool(bVertical)); + NuiSetBind(oPC, nToken, "btn_vertical_widget_tooltip", JsonString( + " " + sName + " widget will display vertically")); + // Row 3 + NuiSetBind(oPC, nToken, "chbx_cmd_action_check", JsonBool (bCmdAction)); + NuiSetBindWatch(oPC, nToken, "chbx_cmd_action_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_action_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_action_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_guard_check", JsonBool (bCmdGuard)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_guard_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_guard_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_guard_event", JsonBool (TRUE)); + // Row 4 + NuiSetBind(oPC, nToken, "chbx_cmd_hold_check", JsonBool (bCmdHold)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_hold_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_hold_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_hold_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_attack_check", JsonBool (bCmdAttack)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_attack_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_attack_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_attack_event", JsonBool (TRUE)); + // Row 5 + NuiSetBind(oPC, nToken, "chbx_cmd_follow_check", JsonBool (bCmdFollow)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_follow_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_follow_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_follow_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_follow_target_check", JsonBool (bFollowTarget)); + NuiSetBindWatch (oPC, nToken, "chbx_follow_target_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_follow_target_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_follow_target_event", JsonBool (TRUE)); + // Row 6 + if(bIsPC) + { + NuiSetBind(oPC, nToken, "chbx_cmd_search_check", JsonBool (bCmdSearch)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_search_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_search_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_search_event", JsonBool (TRUE)); + if(ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_SEARCH)) sText = " leave "; + else sText = " enter "; + NuiSetBind(oPC, nToken, "btn_cmd_search_tooltip", JsonString(" Everyone" + sText + "search mode")); + NuiSetBind(oPC, nToken, "chbx_cmd_stealth_check", JsonBool (bCmdStealth)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_stealth_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_stealth_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_stealth_event", JsonBool (TRUE)); + if(ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_STEALTH)) sText = " leave "; + else sText = " enter "; + NuiSetBind(oPC, nToken, "btn_cmd_stealth_tooltip", JsonString(" Everyone" + sText + "stealth mode")); + } + // Command labels + if(bIsPC) sText = " All "; + else sText = " "; + NuiSetBind(oPC, nToken, "btn_cmd_action_label", JsonString(sText + "Action")); + NuiSetBind(oPC, nToken, "btn_cmd_guard_label", JsonString(sText + "Guard Mode")); + NuiSetBind(oPC, nToken, "btn_cmd_hold_label", JsonString(sText + "Hold Mode")); + NuiSetBind(oPC, nToken, "btn_cmd_attack_label", JsonString(sText + "Normal Mode")); + NuiSetBind(oPC, nToken, "btn_cmd_follow_label", JsonString(sText + "Follow Mode")); + NuiSetBind(oPC, nToken, "btn_follow_target_label", JsonString(" Follow Target")); + float fRange = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE) + + StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oAssociate))); + string sRange = FloatToString(fRange, 0, 0); + if(bIsPC) + { + sText = " All associates"; + NuiSetBind(oPC, nToken, "btn_cmd_follow_tooltip", JsonString(sText + " enter follow mode")); + } + else + { + sText = " " + GetName(oAssociate); + NuiSetBind(oPC, nToken, "btn_cmd_follow_tooltip", JsonString(sText + " enter follow mode [" + sRange + " meters]")); + } + NuiSetBind(oPC, nToken, "btn_cmd_action_tooltip", JsonString(sText + " do actions")); + NuiSetBind(oPC, nToken, "btn_cmd_guard_tooltip", JsonString(sText + " enter guard mode")); + NuiSetBind(oPC, nToken, "btn_cmd_hold_tooltip", JsonString(sText + " enter hold mode")); + NuiSetBind(oPC, nToken, "btn_cmd_attack_tooltip", JsonString(sText + " enter normal mode")); + object oTarget = GetLocalObject(oAssociate, AI_FOLLOW_TARGET); + string sTarget; + if(oTarget != OBJECT_INVALID) sTarget = GetName(oTarget); + else + { + if(ai_GetIsCharacter(oAssociate)) sTarget = "nobody"; + else sTarget = GetName(oPC); + } + NuiSetBind(oPC, nToken, "btn_follow_target_tooltip", JsonString(" " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]")); + // Row 7 + NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_check", JsonBool (bCmdAIScript)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_ai_script_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_event", JsonBool (TRUE)); + sText = " Using normal tactics"; + if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != "") + { + string sScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + if(sScript == "ai_a_ambusher") sText = " Ambusher: Attacks from a hidden position"; + else if(sScript == "ai_a_flanker") sText = " Flanker: Attacks enemies engaged with allies"; + else if(sScript == "ai_a_peaceful") sText = " Peaceful: Avoids attacking any enemies if possible"; + else if(sScript == "ai_a_defensive") sText = " Defensive: Attacks then uses Expertise/Parry"; + else if(sScript == "ai_a_ranged") sText = " Ranged: Attacks from range as much as possible"; + else if(sScript == "ai_a_cntrspell") sText = " Counter Spell: Tries to counter enemy spells"; + } + else + { + if(GetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, oAssociate)) sText = "Using ambush tactics"; + else if(GetCombatCondition(X0_COMBAT_FLAG_COWARDLY, oAssociate)) sText = "Using coward tactics"; + else if(GetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, oAssociate)) sText = "Using defensive tactics"; + else if(GetCombatCondition(X0_COMBAT_FLAG_RANGED, oAssociate)) sText = "Using ranged tactics"; + } + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_tooltip", JsonString(sText)); + if(GetSkillRank(SKILL_SET_TRAP, oAssociate, TRUE) > 0) + { + NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_check", JsonBool (bCmdPlacetrap)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_place_trap_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_tooltip", JsonString ( + " Place a trap at the location selected")); + } + // Row 8 + NuiSetBind(oPC, nToken, "btn_quick_widget_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_quick_widget_tooltip", JsonString( + " Add/Remove abilities and spells from creatures widget")); + NuiSetBind(oPC, nToken, "chbx_quick_widget_check", JsonBool (bSpellWidget)); + NuiSetBindWatch (oPC, nToken, "chbx_quick_widget_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_quick_widget_event", JsonBool(TRUE)); + if(bMemorize == 2) // Memorizes their spells. + { + NuiSetBind(oPC, nToken, "btn_spell_memorize_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_spell_memorize_tooltip", JsonString( + " Change memorized spell list.")); + } + if(bSpellbook) // Change known spells. + { + NuiSetBind(oPC, nToken, "btn_spell_known_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_spell_known_tooltip", JsonString( + " Change known spell list.")); + } + // Row 9 + NuiSetBind(oPC, nToken, "chbx_buff_short_check", JsonBool (bBuffShort)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_short_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_short_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_short_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_buff_short_tooltip", JsonString ( + " Buff the party with short duration spells")); + NuiSetBind(oPC, nToken, "chbx_buff_long_check", JsonBool (bBuffLong)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_long_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_long_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_long_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_long_tooltip", JsonString ( + " Buff the party with long duration spells")); + // Row 10 + NuiSetBind(oPC, nToken, "chbx_buff_all_check", JsonBool (bBuffAll)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_all_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_all_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_all_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_all_tooltip", JsonString ( + " Buff the party with all our defensive spells")); + if(!bIsPC && ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS) == "") + { + NuiSetBind(oPC, nToken, "chbx_buff_rest_check", JsonBool (bBuffRest)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_rest_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_rest_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_rest_event", JsonBool (TRUE)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST)) sText = " [On] Turn buffing after resting off"; + else sText = " [Off] Turn buffing after resting on"; + NuiSetBind (oPC, nToken, "btn_buff_rest_tooltip", JsonString (sText)); + } + // Row 11 + NuiSetBind(oPC, nToken, "chbx_jump_to_check", JsonBool(bJumpTo)); + NuiSetBindWatch (oPC, nToken, "chbx_jump_to_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_jump_to_event", JsonBool(TRUE)); + sText = GetName(oPC); + if(oPC == oAssociate) sName = "everyone"; + else sName = GetName(oAssociate); + NuiSetBind(oPC, nToken, "btn_jump_to_label", JsonString("Jump to " + sText)); + NuiSetBind(oPC, nToken, "btn_jump_to_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_jump_to_tooltip", JsonString ( + " Jump " + sName + " to " + sText)); + + NuiSetBind(oPC, nToken, "chbx_ghost_mode_check", JsonBool (bGhostMode)); + NuiSetBindWatch (oPC, nToken, "chbx_ghost_mode_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ghost_mode_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ghost_mode_event", JsonBool (TRUE)); + sText = "On"; + if(ai_GetAIMode(oAssociate, AI_MODE_GHOST)) sText = "Off"; + NuiSetBind(oPC, nToken, "btn_ghost_mode_tooltip", JsonString ( + " Turn " + sText + " clipping through creatures for " + GetName(oAssociate))); + // Row 12 + NuiSetBind(oPC, nToken, "chbx_camera_check", JsonBool (bCamera)); + NuiSetBindWatch (oPC, nToken, "chbx_camera_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_camera_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString ( + " Toggle camera view for " + sName)); + NuiSetBind(oPC, nToken, "chbx_inventory_check", JsonBool (bInventory)); + NuiSetBindWatch (oPC, nToken, "chbx_inventory_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_inventory_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString ( + " Open " + sName + " inventory")); + // Row 13 & 14 + if(bFamiliar) + { + NuiSetBind(oPC, nToken, "chbx_familiar_check", JsonBool(bBtnFamiliar)); + NuiSetBindWatch (oPC, nToken, "chbx_familiar_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_familiar_event", JsonBool(TRUE)); + int nFamiliar = GetFamiliarCreatureType(oAssociate); + NuiSetBind(oPC, nToken, "cmb_familiar_selected", JsonInt(nFamiliar)); + string sFamiliarName = GetFamiliarName(oAssociate); + NuiSetBind(oPC, nToken, "txt_familiar_name", JsonString(sFamiliarName)); + if(!bIsPC) + { + NuiSetBind(oPC, nToken, "lbl_familiar_type_label", JsonString("Change familiar type")); + NuiSetBind(oPC, nToken, "lbl_familiar_name_label", JsonString("Change familiar name")); + NuiSetBind(oPC, nToken, "cmb_familiar_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "cmb_familiar_selected", TRUE); + NuiSetBind(oPC, nToken, "txt_familiar_name_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "txt_familiar_name", TRUE); + NuiSetBind(oPC, nToken, "btn_familiar_name_label", JsonString("Save")); + } + else + { + NuiSetBind(oPC, nToken, "lbl_familiar_type_label", JsonString("Familiar type")); + NuiSetBind(oPC, nToken, "lbl_familiar_name_label", JsonString("Familiar name")); + } + } + // Row 15 & 16 + if(bCompanion) + { + NuiSetBind(oPC, nToken, "chbx_companion_check", JsonBool(bBtnCompanion)); + NuiSetBindWatch (oPC, nToken, "chbx_companion_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_companion_event", JsonBool(TRUE)); + int nCompanion = GetAnimalCompanionCreatureType(oAssociate); + NuiSetBind(oPC, nToken, "cmb_companion_selected", JsonInt(nCompanion)); + string sCompanionName = GetAnimalCompanionName(oAssociate); + NuiSetBind(oPC, nToken, "txt_companion_name", JsonString(sCompanionName)); + if(!bIsPC) + { + NuiSetBind(oPC, nToken, "lbl_companion_type_label", JsonString("Change Companion type")); + NuiSetBind(oPC, nToken, "lbl_companion_name_label", JsonString("Change Companion name")); + NuiSetBind(oPC, nToken, "cmb_companion_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "cmb_companion_selected", TRUE); + NuiSetBind(oPC, nToken, "txt_companion_name_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "txt_companion_name", TRUE); + NuiSetBind(oPC, nToken, "btn_companion_name_label", JsonString("Save")); + } + else + { + NuiSetBind(oPC, nToken, "lbl_companion_type_label", JsonString("Companion type")); + NuiSetBind(oPC, nToken, "lbl_companion_name_label", JsonString("Companion name")); + } + } + if(bIsPC) + { + // Row 17+ + int nIndex, bWidget; + string sButton, sText; + json jPlugin = JsonArrayGet(jPCPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_event", JsonBool(TRUE)); + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bWidget < 3) + { + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_check", JsonBool(bWidget)); + NuiSetBindWatch (oPC, nToken, "chbx_plugin_" + sButton + "_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_event", JsonBool(TRUE)); + } + sText = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_tooltip", JsonString(sText)); + jPlugin = JsonArrayGet(jPCPlugins, ++nIndex); + } + NuiSetBind(oPC, nToken, "chbx_plugin_tooltip", JsonString(" Adds the plugin to your widget.")); + } + // Row 18 + sText = ai_GetRandomTip(); + NuiSetBind(oPC, nToken, "lbl_info_1_label", JsonString(sText)); +} +void ai_CreateAssociateAINUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int bRight, bLeft; + float fHeight = 45.0; + // ************************************************************************* Width / Height + int bIsPC = ai_GetIsCharacter(oAssociate); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jRow = JsonArray(); + json jCol = JsonArray(); + // Row 1 ******************************************************************* 500 / 73 + // If all the AI buttons are blocked then don't load the menu. + if(bIsPC) + { + bRight = GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028; + if(!AI_SERVER || bRight) + { + // If all the Command buttons are blocked then don't load the menu. + if(bRight) + { + jRow = CreateButton(jRow, "Command Menu", "btn_command_menu", 200.0, 20.0, -1.0, "btn_command_menu_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(!AI_SERVER) + { + CreateButton(jRow, "Main Menu", "btn_main_menu", 200.0, 20.0, -1.0, "btn_main_menu_tooltip"); + CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + } + // Row 2 ******************************************************************* 500 / 73 + bRight = !ai_GetDMAIAccessButton(BTN_AI_LOOT); + if(bRight || !bIsPC) + { + jRow = JsonArray(); + if(!bIsPC) + { + jRow = CreateButton(jRow, "Command Menu", "btn_command_menu", 200.0, 20.0, -1.0, "btn_command_menu_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bRight) + { + jRow = CreateButton(jRow, "Loot Filter", "btn_loot_filter", 200.0, 20.0); + jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 3 ******************************************************************* 500 / 101 + bRight = !ai_GetDMAIAccessButton(BTN_AI_FOR_PC); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_REDUCE_SPEECH); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Player AI On/Off", "btn_ai", 200.0, 20.0, -1.0, "btn_ai_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ai", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Reduce Speech", "btn_quiet", 200.0, 20.0, -1.0, "btn_quiet_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_quiet", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 4 ******************************************************************* 500 / 129 + bRight = !ai_GetDMAIAccessButton(BTN_AI_USE_RANGED); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_STOP_WEAPON_EQUIP); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Ranged Combat", "btn_ranged", 200.0, 20.0, -1.0, "btn_ranged_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ranged", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Equip Best Weapons", "btn_equip_weapon", 200.0, 20.0, -1.0, "btn_equip_weapon_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_equip_weapon", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 5 ******************************************************************* 500 / 157 + bRight = !ai_GetDMAIAccessButton(BTN_AI_USE_SEARCH); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_USE_STEALTH); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Search Mode", "btn_search", 200.0, 20.0, -1.0, "btn_search_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_search", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Stealth Mode", "btn_stealth", 200.0, 20.0, -1.0, "btn_stealth_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_stealth", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 6 ******************************************************************* 500 / 185 + bRight = !ai_GetDMAIAccessButton(BTN_AI_OPEN_DOORS); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_REMOVE_TRAPS); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Open Door Mode", "btn_open_door", 200.0, 20.0, -1.0, "btn_open_door_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_open_door", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Disarm Traps Mode", "btn_traps", 200.0, 20.0, -1.0, "btn_traps_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_traps", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 7 ******************************************************************* 500 / 213 + bRight = !ai_GetDMAIAccessButton(BTN_AI_PICK_LOCKS); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_BASH_LOCKS); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Pick Locks Mode", "btn_pick_locks", 200.0, 20.0, -1.0, "btn_pick_locks_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_pick_locks", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Bash Mode", "btn_bash_locks", 200.0, 20.0, -1.0, "btn_bash_locks_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_bash_locks", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 8 ******************************************************************* 500 / 241 + bRight = !ai_GetDMAIAccessButton(BTN_AI_MAGIC_LEVEL); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_NO_SPONTANEOUS); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Magic usage level", "btn_magic_level", 200.0, 20.0f, -1.0, "btn_magic_level_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic_level", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Cleric Spontaneous Casting", "btn_spontaneous", 200.0, 20.0, -1.0, "btn_spontaneous_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_spontaneous", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 9 ******************************************************************* 500 / 269 + bRight = !ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_USE); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_ITEM_USE); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Use Magic", "btn_magic", 200.0, 20.0, -1.0, "btn_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Use Magic Items", "btn_magic_items", 200.0, 20.0, -1.0, "btn_magic_items_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic_items", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 10 ****************************************************************** 500 / 297 + bRight = !ai_GetDMAIAccessButton(BTN_AI_DEF_MAGIC_USE); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_OFF_MAGIC_USE); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Use Defensive Magic Only", "btn_def_magic", 200.0, 20.0, -1.0, "btn_def_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_def_magic", 25.0, 20.0f); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Use Offensive Magic Only", "btn_off_magic", 200.0, 20.0, -1.0, "btn_off_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_off_magic", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 11 ****************************************************************** 500 / 325 + bRight = !ai_GetDMAIAccessButton(BTN_AI_HEAL_OUT); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_HEAL_IN); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Heal % Out of Combat", "btn_heal_out", 200.0, 20.0, -1.0, "btn_heal_out_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heal_out", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Heal % in Combat", "btn_heal_in", 200.0, 20.0, -1.0, "btn_heal_in_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heal_in", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 12 ****************************************************************** 500 / 353 + bRight = !ai_GetDMAIAccessButton(BTN_AI_STOP_SELF_HEALING); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_STOP_PARTY_HEALING); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Self Healing", "btn_heals_onoff", 200.0, 20.0, -1.0, "btn_heals_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heals_onoff", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Party Healing", "btn_healp_onoff", 200.0, 20.0, -1.0, "btn_healp_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_healp_onoff", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 13 ****************************************************************** 500 / 391 + bRight = !ai_GetDMAIAccessButton(BTN_AI_STOP_CURE_SPELLS); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_LOOT); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Cast Cure Spells", "btn_cure_onoff", 200.0, 20.0, -1.0, "btn_cure_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cure_onoff", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + if(sAssociateType != "summons" && sAssociateType != "dominated") + { + jRow = CreateButton(jRow, "Auto Looting", "btn_loot", 200.0, 20.0, -1.0, "btn_loot_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_loot", 25.0, 20.0); + } + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 14 ****************************************************************** 500 / --- + bRight = !ai_GetDMAIAccessButton(BTN_AI_IGNORE_ASSOCIATES); + bLeft = !ai_GetDMAIAccessButton(BTN_AI_IGNORE_TRAPS); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + jRow = CreateButton(jRow, "Ignore Associates", "btn_ignore_assoc", 200.0, 20.0, -1.0, "btn_ignore_assoc_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ignore_assoc", 25.0, 20.0); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + jRow = CreateButton(jRow, "Ignore floor Traps", "btn_ignore_traps", 200.0, 20.0, -1.0, "btn_ignore_traps_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ignore_traps", 25.0, 20.0); + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 15 ****************************************************************** 500 / --- + bRight = !ai_GetDMAIAccessButton(BTN_AI_PERC_RANGE); + bLeft = FALSE; //!ai_GetDMAIAccessButton(BTN_AI_PERC_RANGE); + if(bRight || bLeft) + { + jRow = JsonArray(); + if(bRight) + { + if(GetAssociateType(oAssociate) == ASSOCIATE_TYPE_HENCHMAN) + { + jRow = CreateButton(jRow, "Perception Range", "btn_perc_range", 200.0, 20.0, -1.0, "btn_perc_range_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_perc_range", 25.0, 20.0); + } + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + if(bLeft) + { + } + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 16 ****************************************************************** 500 / --- + bRight = !ai_GetDMWAccessButton(BTN_CMD_AI_SCRIPT); + if(bRight) + { + jRow = JsonArray(); + jRow = CreateButton(jRow, "Set Current AI:", "btn_ai_script", 175.0f, 20.0f, -1.0, "btn_ai_script_tooltip"); + jRow = CreateTextEditBox(jRow, "sPlaceHolder", "txt_ai_script", 16, FALSE, 145.0f, 20.0f, "txt_ai_script_tooltip"); + jRow = CreateCombo(jRow, ai_CreateAIScriptJson(oPC), "cmb_ai_script", 146.0, 20.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + // Row 17 ****************************************************************** 500 / --- + jRow = JsonArray(); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "", "lbl_info", 475.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sText, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_NUI, sName + " AI Menu", + fX, fY, 500.0, fHeight + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Get which buttons are activated. + int bAI = ai_GetAIButton(oPC, BTN_AI_FOR_PC, oAssociate, sAssociateType); + int bReduceSpeech = ai_GetAIButton(oPC, BTN_AI_REDUCE_SPEECH, oAssociate, sAssociateType); + int bRanged = ai_GetAIButton(oPC, BTN_AI_USE_RANGED, oAssociate, sAssociateType); + int bEquipWeapons = ai_GetAIButton(oPC, BTN_AI_STOP_WEAPON_EQUIP, oAssociate, sAssociateType); + int bSearch = ai_GetAIButton(oPC, BTN_AI_USE_SEARCH, oAssociate, sAssociateType); + int bStealth = ai_GetAIButton(oPC, BTN_AI_USE_STEALTH, oAssociate, sAssociateType); + int bOpenDoors = ai_GetAIButton(oPC, BTN_AI_OPEN_DOORS, oAssociate, sAssociateType); + int bTraps = ai_GetAIButton(oPC, BTN_AI_REMOVE_TRAPS, oAssociate, sAssociateType); + int bPickLocks = ai_GetAIButton(oPC, BTN_AI_PICK_LOCKS, oAssociate, sAssociateType); + int bBashLocks = ai_GetAIButton(oPC, BTN_AI_BASH_LOCKS, oAssociate, sAssociateType); + int bMagicLevel = ai_GetAIButton(oPC, BTN_AI_MAGIC_LEVEL, oAssociate, sAssociateType); + int bSpontaneous = ai_GetAIButton(oPC, BTN_AI_NO_SPONTANEOUS, oAssociate, sAssociateType); + int bNoMagic = ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_USE, oAssociate, sAssociateType); + int bNoMagicItems = ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_ITEM_USE, oAssociate, sAssociateType); + int bDefMagic = ai_GetAIButton(oPC, BTN_AI_DEF_MAGIC_USE, oAssociate, sAssociateType); + int bOffMagic = ai_GetAIButton(oPC, BTN_AI_OFF_MAGIC_USE, oAssociate, sAssociateType); + int bHealOut = ai_GetAIButton(oPC, BTN_AI_HEAL_OUT, oAssociate, sAssociateType); + int bHealIn = ai_GetAIButton(oPC, BTN_AI_HEAL_IN, oAssociate, sAssociateType); + int bSelfHealOnOff = ai_GetAIButton(oPC, BTN_AI_STOP_SELF_HEALING, oAssociate, sAssociateType); + int bPartyHealOnOff = ai_GetAIButton(oPC, BTN_AI_STOP_PARTY_HEALING, oAssociate, sAssociateType); + int bCureOnOff = ai_GetAIButton(oPC, BTN_AI_STOP_CURE_SPELLS, oAssociate, sAssociateType); + int bIgnoreAssociates = ai_GetAIButton(oPC, BTN_AI_IGNORE_ASSOCIATES, oAssociate, sAssociateType); + int bIgnoreTraps = ai_GetAIButton(oPC, BTN_AI_IGNORE_TRAPS, oAssociate, sAssociateType); + int bLoot = ai_GetAIButton(oPC, BTN_AI_LOOT, oAssociate, sAssociateType); + int bPercRange = ai_GetAIButton(oPC, BTN_AI_PERC_RANGE, oAssociate, sAssociateType); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArray(); + jData = JsonArrayInsert(jData, JsonString(ObjectToString(oAssociate))); + NuiSetUserData(oPC, nToken, jData); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 + // If all the AI buttons are blocked then don't load the menu. + if(bIsPC) + { + bRight = GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028; + if(!AI_SERVER || bRight) + { + // If all the Command buttons are blocked then don't load the menu. + if(bRight) + { + NuiSetBind(oPC, nToken, "btn_command_menu_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_command_menu_tooltip", JsonString(" " + sName + " Command options")); + } + if(!AI_SERVER) + { + NuiSetBind(oPC, nToken, "btn_main_menu_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_main_menu_tooltip", JsonString(" Module Options")); + } + fHeight += 28.0; + } + } + // Row 2 + if(!bIsPC) + { + NuiSetBind(oPC, nToken, "btn_command_menu_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_command_menu_tooltip", JsonString(" " + sName + " Command options")); + } + NuiSetBind(oPC, nToken, "btn_loot_filter_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_filter", JsonInt(TRUE)); + // Row 3 + // Only activate ai on/off if this is for the pc. + if(bIsPC && ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS) == "") + { + NuiSetBind(oPC, nToken, "chbx_ai_check", JsonBool(bAI)); + NuiSetBindWatch (oPC, nToken, "chbx_ai_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ai_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_event", JsonBool(TRUE)); + if(GetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT) == "xx_pc_1_hb") sText = " AI On"; + else sText = " AI Off"; + NuiSetBind(oPC, nToken, "btn_ai_tooltip", JsonString(sText)); + } + NuiSetBind(oPC, nToken, "chbx_quiet_check", JsonBool(bReduceSpeech)); + NuiSetBindWatch (oPC, nToken, "chbx_quiet_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_quiet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_quiet_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK)) sText = " Reduced Speech On"; + else sText = " Reduces Speech Off"; + NuiSetBind (oPC, nToken, "btn_quiet_tooltip", JsonString(sText)); + // Row 4 + NuiSetBind(oPC, nToken, "chbx_ranged_check", JsonBool(bRanged)); + NuiSetBindWatch(oPC, nToken, "chbx_ranged_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ranged_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ranged_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_STOP_RANGED)) sText = " Ranged Off"; + else sText = " Ranged On"; + NuiSetBind (oPC, nToken, "btn_ranged_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "chbx_equip_weapon_check", JsonBool(bEquipWeapons)); + NuiSetBindWatch(oPC, nToken, "chbx_equip_weapon_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_equip_weapon_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_equip_weapon_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_EQUIP_WEAPON_OFF)) sText = " Equiping Best Weapons Off"; + else sText = " Equiping Best Weapons On"; + NuiSetBind (oPC, nToken, "btn_equip_weapon_tooltip", JsonString(sText)); + // Row 5 + if(GetRacialType(oAssociate) != RACIAL_TYPE_ELF) + { + NuiSetBind(oPC, nToken, "chbx_search_check", JsonBool(bSearch)); + NuiSetBindWatch (oPC, nToken, "chbx_search_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_search_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_search_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH)) sText = " Search mode On"; + else sText = " Search mode Off"; + NuiSetBind (oPC, nToken, "btn_search_tooltip", JsonString(sText)); + } + NuiSetBind(oPC, nToken, "chbx_stealth_check", JsonBool(bStealth)); + NuiSetBindWatch(oPC, nToken, "chbx_stealth_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_stealth_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_stealth_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH)) sText = " Stealth mode On"; + else sText = " Stealth mode Off"; + NuiSetBind (oPC, nToken, "btn_stealth_tooltip", JsonString(sText)); + // Row 6 + string sRange = FloatToString(GetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "chbx_open_door_check", JsonBool(bOpenDoors)); + NuiSetBindWatch (oPC, nToken, "chbx_open_door_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_open_door_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_open_door_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_OPEN_DOORS)) sText = " Open Doors On [" + sRange + " meters]"; + else sText = " Open Doors Off [" + sRange + " meters]"; + NuiSetBind (oPC, nToken, "btn_open_door_tooltip", JsonString(sText)); + sRange = FloatToString(GetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "chbx_traps_check", JsonBool(bTraps)); + NuiSetBindWatch (oPC, nToken, "chbx_traps_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_traps_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_traps_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_DISARM_TRAPS)) sText = " Disable Traps On [" + sRange + " meters]"; + else sText = " Disable Traps Off [" + sRange + " meters]"; + NuiSetBind (oPC, nToken, "btn_traps_tooltip", JsonString(sText)); + // Row 7 + sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "chbx_pick_locks_check", JsonBool(bPickLocks)); + NuiSetBindWatch(oPC, nToken, "chbx_pick_locks_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_pick_locks_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_pick_locks_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_PICK_LOCKS)) sText = " Pick locks On [" + sRange + " meters]"; + else sText = " Pick Locks Off [" + sRange + " meters]"; + NuiSetBind (oPC, nToken, "btn_pick_locks_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "chbx_bash_locks_check", JsonBool(bBashLocks)); + NuiSetBindWatch(oPC, nToken, "chbx_bash_locks_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_bash_locks_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_bash_locks_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS)) sText = " Bash On [" + sRange + " meters]"; + else sText = " Bash Off [" + sRange + " meters]"; + NuiSetBind (oPC, nToken, "btn_bash_locks_tooltip", JsonString(sText)); + // Row 8 + string sMagic = IntToString(GetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT)); + NuiSetBind(oPC, nToken, "chbx_magic_level_check", JsonBool(bMagicLevel)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_level_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_level_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_level_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_magic_level_tooltip", JsonString(" Magic level [" + sMagic + "]")); + sText = " Spontaneous casting On"; + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_SPONTANEOUS_CURE)) sText = " Spontaneous casting Off"; + NuiSetBind(oPC, nToken, "chbx_spontaneous_check", JsonBool(bSpontaneous)); + NuiSetBindWatch (oPC, nToken, "chbx_spontaneous_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_spontaneous_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spontaneous_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spontaneous_tooltip", JsonString(sText)); + // Row 9 + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC)) sText = " Magic Off"; + else sText = " Magic On"; + NuiSetBind(oPC, nToken, "chbx_magic_check", JsonBool(bNoMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_tooltip", JsonString(sText)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS)) sText = " Magic Items Off"; + else sText = " Magic Items On"; + NuiSetBind(oPC, nToken, "chbx_magic_items_check", JsonBool(bNoMagicItems)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_items_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_items_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_items_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_items_tooltip", JsonString(sText)); + // Row 10 + if(ai_GetMagicMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING)) sText = " Defensive Magic On"; + else sText = " Defensive Magic Off"; + NuiSetBind(oPC, nToken, "chbx_def_magic_check", JsonBool (bDefMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_def_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_def_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_def_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_def_magic_tooltip", JsonString(sText)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING)) sText = " Offensive Magic On"; + else sText = " Offensive Magic Off"; + NuiSetBind(oPC, nToken, "chbx_off_magic_check", JsonBool(bOffMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_off_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_off_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_off_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_off_magic_tooltip", JsonString(sText)); + // Row 11 + int nHeal = GetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT); + NuiSetBind(oPC, nToken, "chbx_heal_out_check", JsonBool(bHealOut)); + NuiSetBindWatch (oPC, nToken, "chbx_heal_out_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heal_out_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_out_event", JsonBool(TRUE)); + sText = " Will heal at or below [" + IntToString(nHeal) + "%] health out of combat"; + NuiSetBind(oPC, nToken, "btn_heal_out_tooltip", JsonString(sText)); + nHeal = GetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT); + NuiSetBind(oPC, nToken, "chbx_heal_in_check", JsonBool(bHealIn)); + NuiSetBindWatch (oPC, nToken, "chbx_heal_in_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heal_in_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_in_event", JsonBool (TRUE)); + sText = " Will heal at or below [" + IntToString(nHeal) + "%] health in combat"; + NuiSetBind(oPC, nToken, "btn_heal_in_tooltip", JsonString(sText)); + // Row 12 + NuiSetBind(oPC, nToken, "chbx_heals_onoff_check", JsonBool(bSelfHealOnOff)); + NuiSetBindWatch (oPC, nToken, "chbx_heals_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heals_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heals_onoff_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_SELF_HEALING_OFF)) sText = " Self healing Off"; + else sText = " Self healing On"; + NuiSetBind(oPC, nToken, "btn_heals_onoff_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "chbx_healp_onoff_check", JsonBool(bPartyHealOnOff)); + NuiSetBind(oPC, nToken, "chbx_healp_onoff_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_healp_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "btn_healp_onoff_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_PARTY_HEALING_OFF)) sText = " Party healing Off"; + else sText = " Party healing On"; + NuiSetBind(oPC, nToken, "btn_healp_onoff_tooltip", JsonString(sText)); + // Row 13 + NuiSetBind(oPC, nToken, "btn_cure_onoff_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "chbx_cure_onoff_check", JsonBool(bCureOnOff)); + NuiSetBind(oPC, nToken, "chbx_cure_onoff_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_cure_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cure_onoff_event", JsonBool(TRUE)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF)) sText = " Cast Cure Spells Off"; + else sText = " Cast Cure Spells On"; + NuiSetBind(oPC, nToken, "btn_cure_onoff_tooltip", JsonString(sText)); + if(sAssociateType != "summons" && sAssociateType != "dominated") + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE), 0, 0); + if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sText = " Looting On [" + sRange + " meters]"; + else sText = " Looting Off [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "chbx_loot_check", JsonBool(bLoot)); + NuiSetBindWatch (oPC, nToken, "chbx_loot_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_tooltip", JsonString(sText)); + } + // Row 14 + NuiSetBind(oPC, nToken, "chbx_ignore_assoc_check", JsonBool(bIgnoreAssociates)); + NuiSetBindWatch(oPC, nToken, "chbx_ignore_assoc_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ignore_assoc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ignore_assoc_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES)) sText = " Ignore Enemy Associates On"; + else sText = " Ignore Enemy Associates Off"; + NuiSetBind (oPC, nToken, "btn_ignore_assoc_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "chbx_ignore_traps_check", JsonBool(bIgnoreTraps)); + NuiSetBindWatch(oPC, nToken, "chbx_ignore_traps_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ignore_traps_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ignore_traps_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_TRAPS)) sText = " Ignore Floor Traps On"; + else sText = " Ignore Floor Traps Off"; + NuiSetBind (oPC, nToken, "btn_ignore_traps_tooltip", JsonString(sText)); + // Row 15 + if(!bIsPC) + { + int nRange = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU"); + if(nRange < 8 || nRange > 11) + { + nRange = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION); + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU", nRange); + } + if(nRange == 8) sText = " Perception Range Short [10 meters Sight / 10 meters Listen]"; + else if(nRange == 9) sText = " Perception Range Medium [20 meters Sight / 20 meters Listen]"; + else if(nRange == 10) sText = " Perception Range Long [35 meters Sight / 20 meters Listen]"; + else sText = " Perception Range Default [20 meters Sight / 20 meters Listen]"; + NuiSetBind(oPC, nToken, "chbx_perc_range_check", JsonBool(bPercRange)); + NuiSetBindWatch (oPC, nToken, "chbx_perc_range_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_perc_range_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_perc_range_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_perc_range_tooltip", JsonString(sText)); + } + // Row 16 + string sScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + if(sScript == "") sScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + NuiSetBind(oPC, nToken, "btn_ai_script_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_script_tooltip", JsonString(" Sets " + GetName(oAssociate) + " to use the ai script in the text box.")); + NuiSetBind(oPC, nToken, "txt_ai_script_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_ai_script", JsonString(sScript)); + NuiSetBind(oPC, nToken, "txt_ai_script_tooltip", JsonString(" Associate AI scripts must start with ai_a_")); + NuiSetBind(oPC, nToken, "cmb_ai_script_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "cmb_ai_script_selected", TRUE); + // Row 17 + sText = ai_GetRandomTip(); + NuiSetBind (oPC, nToken, "lbl_info_label", JsonString(sText)); +} +void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int nToken, string sName) +{ + int bBool, bIsPC = ai_GetIsCharacter(oAssociate); + string sText, sRange, sHeal; + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set the buttons to show events. + NuiSetBind(oPC, nToken, "btn_open_main_image", JsonString(GetPortraitResRef(oAssociate) + "s")); + NuiSetBind(oPC, nToken, "btn_open_main_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_open_main_tooltip", JsonString(" " + sName + " widget menu")); + if(bIsPC) sText = " All associates"; + else sText = " " + GetName(oAssociate); + if(ai_GetWidgetButton(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_action_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_action_tooltip", JsonString(sText + " do actions")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_GUARD, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_guard_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_guard_tooltip", JsonString(sText + " enter guard mode")); + bBool = ai_GetAIMode(oAssociate, AI_MODE_DEFEND_MASTER); + NuiSetBind(oPC, nToken, "btn_cmd_guard_encouraged", JsonBool(bBool)); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_HOLD, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_hold_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_hold_tooltip", JsonString(sText + " enter hold mode")); + bBool = ai_GetAIMode(oAssociate, AI_MODE_STAND_GROUND); + NuiSetBind(oPC, nToken, "btn_cmd_hold_encouraged", JsonBool(bBool)); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_ATTACK, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_attack_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_attack_tooltip", JsonString(sText + " enter normal mode")); + if(!bIsPC) + { + if(!ai_GetAIMode(oAssociate, AI_MODE_DEFEND_MASTER) && + !ai_GetAIMode(oAssociate, AI_MODE_STAND_GROUND) && + !ai_GetAIMode(oAssociate, AI_MODE_FOLLOW)) bBool = TRUE; + else bBool = FALSE; + if(!bIsPC) NuiSetBind(oPC, nToken, "btn_cmd_attack_encouraged", JsonBool(bBool)); + } + } + if(ai_GetWidgetButton(oPC, BTN_CMD_FOLLOW, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_follow_event", JsonBool(TRUE)); + float fRange = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE) + + StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oAssociate))); + string sRange = FloatToString(fRange, 0, 0); + if(bIsPC) + { + sText = " All associates"; + NuiSetBind(oPC, nToken, "btn_cmd_follow_tooltip", JsonString(sText + " enter follow mode")); + } + else + { + sText = " " + GetName(oAssociate); + NuiSetBind(oPC, nToken, "btn_cmd_follow_tooltip", JsonString(sText + " enter follow mode [" + sRange + " meters]")); + } + bBool = ai_GetAIMode(oAssociate, AI_MODE_FOLLOW); + if(!bIsPC) NuiSetBind(oPC, nToken, "btn_cmd_follow_encouraged", JsonBool(bBool)); + } + if(ai_GetAIButton(oPC, BTN_AI_FOLLOW_TARGET, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_follow_target_event", JsonBool(TRUE)); + object oTarget = GetLocalObject(oAssociate, AI_FOLLOW_TARGET); + string sTarget; + if(oTarget != OBJECT_INVALID) sTarget = GetName(oTarget); + else + { + if(ai_GetIsCharacter(oAssociate)) sTarget = "nobody"; + else sTarget = GetName(oPC); + } + float fRange = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE) + + StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oAssociate))); + string sRange = FloatToString(fRange, 0, 0); + NuiSetBind(oPC, nToken, "btn_follow_target_tooltip", JsonString(" " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_SEARCH, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_search_event", JsonBool(TRUE)); + if(ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_SEARCH)) sText = " leave "; + else sText = " enter "; + NuiSetBind(oPC, nToken, "btn_cmd_search_tooltip", JsonString(" Everyone" + sText + "search mode")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_STEALTH, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_stealth_event", JsonBool(TRUE)); + if(ai_GetAIMode(oPC, AI_MODE_AGGRESSIVE_STEALTH)) sText = " leave "; + else sText = " enter "; + NuiSetBind(oPC, nToken, "btn_cmd_stealth_tooltip", JsonString(" Everyone" + sText + "stealth mode")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_AI_SCRIPT, oAssociate, sAssociateType)) + { + sText = " Default tactics: Using the creatures base AI script"; + string sIcon = "ir_scommand"; + if(ResManGetAliasFor("0e_ch_1_hb", RESTYPE_NCS) != "") + { + string sScript = GetLocalString(oAssociate, AI_COMBAT_SCRIPT); + if(sScript == "ai_a_ambusher") + { + sText = " Ambusher: Attacks from a hidden position"; + sIcon = "ir_rogue"; + } + else if(sScript == "ai_a_flanker") + { + sText = " Flanker: Attacks enemies engaged with allies"; + sIcon = "ir_invite"; + } + else if(sScript == "ai_a_peaceful") + { + sText = " Peaceful: Avoids attacking any enemies if possible"; + sIcon = "ir_ignore"; + } + else if(sScript == "ai_a_defensive") + { + sText = " Defensive: Attacks then uses Expertise/Parry"; + sIcon = "ir_knockdwn"; + } + else if(sScript == "ai_a_ranged") + { + sText = " Ranged: Attacks from range as much as possible"; + sIcon = "ir_ranger"; + } + else if(sScript == "ai_a_cntrspell") + { + sText = " Counter Spell: Tries to counter enemy spells"; + sIcon = "ir_dcaster"; + } + } + else + { + if(GetCombatCondition(X0_COMBAT_FLAG_AMBUSHER, oAssociate)) sText = "Using ambush tactics"; + if(GetCombatCondition(X0_COMBAT_FLAG_COWARDLY, oAssociate)) sText = "Using coward tactics"; + if(GetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE, oAssociate)) sText = "Using defensive tactics"; + if(GetCombatCondition(X0_COMBAT_FLAG_RANGED, oAssociate)) sText = "Using ranged tactics"; + } + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_image", JsonString(sIcon)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_tooltip", JsonString(sText)); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_PLACE_TRAP, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_tooltip", JsonString(" Place a trap at the location selected")); + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_SHORT, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_buff_short_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_short_tooltip", JsonString(" Buff the party with short duration spells")); + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_LONG, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_buff_long_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_long_tooltip", JsonString(" Buff the party with long duration spells")); + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_ALL, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_buff_all_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_all_tooltip", JsonString(" Buff the party with all our defensive spells")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_JUMP_TO, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_jump_to_event", JsonBool(TRUE)); + sText = GetName(oPC); + if(oPC == oAssociate) sName = "everyone"; + else sName = GetName(oAssociate); + NuiSetBind(oPC, nToken, "btn_jump_to_tooltip", JsonString(" Jump " + sName + " to " + sText)); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_GHOST_MODE, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_ghost_mode_event", JsonBool (TRUE)); + sText = "On"; + if(ai_GetAIMode(oAssociate, AI_MODE_GHOST)) sText = "Off"; + NuiSetBind(oPC, nToken, "btn_ghost_mode_tooltip", JsonString ( + " Turn " + sText + " clipping through creatures for " + GetName(oAssociate))); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Toggle camera view for " + sName)); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString(" Open " + sName + " inventory")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_FAMILIAR, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_familiar_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_familiar_tooltip", JsonString(" Summon " + sName + " familiar.")); + } + if(ai_GetWidgetButton(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_companion_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_companion_tooltip", JsonString(" Open " + sName + " Animal Companion.")); + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_REST, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_buff_rest_event", JsonBool(TRUE)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST)) sText = " Turn buffing after resting off"; + else sText = " Turn buffing after resting on."; + NuiSetBind(oPC, nToken, "btn_buff_rest_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_FOR_PC, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_ai_event", JsonBool(TRUE)); + if(GetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT) == "xx_pc_1_hb") sText = " AI [On] Turn off"; + else sText = " AI [Off] Turn on"; + NuiSetBind(oPC, nToken, "btn_ai_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_REDUCE_SPEECH, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_quiet_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_DO_NOT_SPEAK)) sText = " Reduced Speech On"; + else sText = " Reduced Speech Off"; + NuiSetBind(oPC, nToken, "btn_quiet_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_USE_RANGED, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_ranged_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_STOP_RANGED)) sText = " Ranged Off"; + else sText = " Ranged On"; + NuiSetBind(oPC, nToken, "btn_ranged_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_WEAPON_EQUIP, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_equip_weapon_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_EQUIP_WEAPON_OFF)) sText = " Equiping Best Weapons Off"; + else sText = " Equiping Best Weapons On"; + NuiSetBind(oPC, nToken, "btn_equip_weapon_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_USE_SEARCH, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_search_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH)) sText = " Search On"; + else sText = " Search Off"; + NuiSetBind(oPC, nToken, "btn_search_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_USE_STEALTH, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_stealth_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH)) sText = " Stealth On"; + else sText = " Stealth Off"; + NuiSetBind(oPC, nToken, "btn_stealth_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_OPEN_DOORS, oAssociate, sAssociateType)) + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "btn_open_door_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_OPEN_DOORS)) sText = " Open Doors On [" + sRange + " meters]"; + else sText = " Open Doors Off [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "btn_open_door_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_REMOVE_TRAPS, oAssociate, sAssociateType)) + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_TRAP_CHECK_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "btn_traps_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_DISARM_TRAPS)) sText = " Disable Traps On [" + sRange + " meters]"; + else sText = " Disable Traps Off [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "btn_traps_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_PICK_LOCKS, oAssociate, sAssociateType)) + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "btn_pick_locks_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_PICK_LOCKS)) sText = " Pick locks On [" + sRange + " meters]"; + else sText = " Pick Locks Off [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "btn_pick_locks_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_BASH_LOCKS, oAssociate, sAssociateType)) + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOCK_CHECK_RANGE), 0, 0); + NuiSetBind(oPC, nToken, "btn_bash_locks_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS)) sText = " Bash On [" + sRange + " meters]"; + else sText = " Bash Off [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "btn_bash_locks_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_MAGIC_LEVEL, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_magic_level_event", JsonBool(TRUE)); + string sMagic = IntToString(GetLocalInt(oAssociate, AI_DIFFICULTY_ADJUSTMENT)); + NuiSetBind(oPC, nToken, "btn_magic_level_tooltip", JsonString(" Magic Level [" + sMagic + "]")); + } + if(ai_GetAIButton(oPC, BTN_AI_NO_SPONTANEOUS, oAssociate, sAssociateType)) + { + string sCasting = " Spontaneous casting On"; + if(ai_GetMagicMode(oAssociate, AI_MAGIC_NO_SPONTANEOUS_CURE)) sCasting = " Spontaneous casting Off"; + NuiSetBind(oPC, nToken, "btn_spontaneous_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spontaneous_tooltip", JsonString(sCasting)); + } + if(ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_USE, oAssociate, sAssociateType)) + { + if(ai_GetAIMode(oAssociate, AI_MAGIC_NO_MAGIC)) sText = " Magic Off"; + else sText = " Magic On"; + NuiSetBind(oPC, nToken, "btn_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_ITEM_USE, oAssociate, sAssociateType)) + { + if(ai_GetAIMode(oAssociate, AI_MAGIC_NO_MAGIC_ITEMS)) sText = " Magic Items Off"; + else sText = " Magic Items On"; + NuiSetBind(oPC, nToken, "btn_magic_items_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_items_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_DEF_MAGIC_USE, oAssociate, sAssociateType)) + { + if(ai_GetAIMode(oAssociate, AI_MAGIC_DEFENSIVE_CASTING)) sText = " Defensive Magic On"; + else sText = " Defensive Magic Off"; + NuiSetBind(oPC, nToken, "btn_def_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_def_magic_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_OFF_MAGIC_USE, oAssociate, sAssociateType)) + { + if(ai_GetAIMode(oAssociate, AI_MAGIC_OFFENSIVE_CASTING)) sText = " Offensive Magic On"; + else sText = " Offensive Magic Off"; + NuiSetBind(oPC, nToken, "btn_off_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_off_magic_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_HEAL_OUT, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_heal_out_event", JsonBool(TRUE)); + sHeal = IntToString(GetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT)); + sText = " Will heal at or below [" + sHeal + "%] health out of combat"; + NuiSetBind(oPC, nToken, "btn_heal_out_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_HEAL_IN, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_heal_in_event", JsonBool(TRUE)); + sHeal = IntToString(GetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT)); + sText = " Will heal at or below [" + sHeal + "%] health in combat"; + NuiSetBind(oPC, nToken, "btn_heal_in_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_SELF_HEALING, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_heals_onoff_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_SELF_HEALING_OFF)) sText = " Self healing Off"; + else sText = " Self healing On"; + NuiSetBind(oPC, nToken, "btn_heals_onoff_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_PARTY_HEALING, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_healp_onoff_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_PARTY_HEALING_OFF)) sText = " Party healing Off"; + else sText = " Party healing On"; + NuiSetBind(oPC, nToken, "btn_healp_onoff_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_CURE_SPELLS, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_cure_onoff_event", JsonBool(TRUE)); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF)) sText = " Cast Cure Spells Off"; + else sText = " Cast Cure Spells On"; + NuiSetBind(oPC, nToken, "btn_cure_onoff_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_LOOT, oAssociate, sAssociateType)) + { + sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE), 0, 0); + string sLoot = " Looting Off [" + sRange + " meters]"; + if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sLoot = " Looting On [" + sRange + " meters]"; + NuiSetBind(oPC, nToken, "btn_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_tooltip", JsonString(sLoot)); + } + if(ai_GetAIButton(oPC, BTN_AI_IGNORE_ASSOCIATES, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_ignore_assoc_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_ASSOCIATES)) sText = " Ignore Enemy Associates On"; + else sText = " Ignore Enemy Associates Off"; + NuiSetBind(oPC, nToken, "btn_ignore_assoc_tooltip", JsonString(sText)); + } + if(ai_GetAIButton(oPC, BTN_AI_IGNORE_TRAPS, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_ignore_traps_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_IGNORE_TRAPS)) sText = " Ignore Floor Traps On"; + else sText = " Ignore Floor Traps Off"; + NuiSetBind(oPC, nToken, "btn_ignore_traps_tooltip", JsonString(sText)); + } + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + if(ai_GetAIButton(oPC, BTN_AI_PERC_RANGE, oAssociate, sAssociateType)) + { + int nRange = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION); + if(nRange < 8 || nRange > 11) + { + nRange = 11; + SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, 11); + jAIData = JsonArraySet(jAIData, 7, JsonInt(11)); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + if(nRange == 8) sText = " Perception Range Short [10 meters Sight / 10 meters Listen]"; + if(nRange == 9) sText = " Perception Range Medium [20 meters Sight / 20 meters Listen]"; + if(nRange == 10) sText = " Perception Range Long [35 meters Sight / 20 meters Listen]"; + else sText = " Perception Range Default [20 meters Sight / 20 meters Listen]"; + NuiSetBind(oPC, nToken, "btn_perc_range_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_perc_range_tooltip", JsonString(sText)); + } + if(bIsPC) + { + int nIndex, bWidget; + string sButton, sName, sText, sScript; + json jPCPlugins = ai_UpdatePluginsForPC(oPC); + json jPlugin = JsonArrayGet(jPCPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bWidget) + { + sButton = IntToString(nIndex); + sScript = JsonGetString(JsonArrayGet(jPlugin, 0)); + if(ResManGetAliasFor(sScript, RESTYPE_NCS) == "") + { + sText = " " + sScript + " not found by ResMan!"; + } + else sName = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_exe_plugin_" + sButton + "_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_exe_plugin_" + sButton + "_tooltip", JsonString(sName)); + } + jPlugin = JsonArrayGet(jPCPlugins, ++nIndex); + } + } + if(ai_GetWidgetButton(oPC, BTN_CMD_SPELL_WIDGET, oAssociate, sAssociateType)) + { + NuiSetBind(oPC, nToken, "btn_update_widget_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_update_widget_tooltip", JsonString(" Updates Quick Use Widget")); + json jSpell, jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + object oItem; + if(JsonGetType(jWidget) != JSON_TYPE_NULL) + { + int nLevel, nSpell, nIndex, nClass, nMetaMagic, nDomain, nSubSpell, nFeat; + string sSpellIcon, sMetaMagicText, sSubSpell, sClass, sIndex; + while(nIndex < 10) + { + jSpell = JsonArrayGet(jWidget, nIndex); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + sIndex = IntToString(nIndex); + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + if(nClass == -1) // This is an Item. + { + string sBaseName; + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3)); + int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4)); + if(nSpell == SPELL_HEALINGKIT) + { + sName = "Healer's Kit +" + IntToString(nIprpSubType); + sSpellIcon = "isk_heal"; + sBaseName = "Healer's Kit"; + } + else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL) + { + sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType); + sBaseName = "Scroll"; + } + else + { + if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion"; + else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand"; + else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + int nUses = ai_GetItemUses(oItem, nIprpSubType); + if(nUses) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(nUses == 999) sText = "Unlimited"; + else sText = IntToString(nUses); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")")); + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + else + { + nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nFeat) // This is a feat. + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + sSpellIcon = ""; + if(nSpell) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + if(sSpellIcon == "" || sSpellIcon == "IR_USE") + { + sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + sSpellIcon = Get2DAString("feat", "ICON", nFeat); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + if(GetHasFeat(nFeat, oAssociate)) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName)); + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + else // This is a spell. + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nLevel = JsonGetInt(JsonArrayGet(jSpell, 2)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + if(GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain)) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + } + } + else break; + ++nIndex; + } + while(nIndex < 20) + { + jSpell = JsonArrayGet(jWidget, nIndex); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + sIndex = IntToString(nIndex); + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nClass == -1) // This is an Item. + { + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + if(oItem != OBJECT_INVALID) + { + string sBaseName; + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3)); + int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4)); + if(nSpell == SPELL_HEALINGKIT) + { + sName = "Healer's Kit +" + IntToString(nIprpSubType); + sSpellIcon = "isk_heal"; + sBaseName = "Healer's Kit"; + } + else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL) + { + sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType); + sBaseName = "Scroll"; + } + else + { + if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion"; + else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand"; + else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + int nUses = ai_GetItemUses(oItem, nIprpSubType); + if(nUses) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(nUses == 999) sText = "Unlimited"; + else sText = IntToString(nUses); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")")); + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + else jWidget = JsonArrayDel(jWidget, nIndex--); + } + else if(nFeat) // This is a feat. + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + sSpellIcon = ""; + if(nSpell) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + if(sSpellIcon == "" || sSpellIcon == "IR_USE") + { + sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + sSpellIcon = Get2DAString("feat", "ICON", nFeat); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + if(GetHasFeat(nFeat, oAssociate)) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName)); + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + else // This is a spell. + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + //SendMessageToPC(oPC, GetName(oAssociate) + " nSpell: " + IntToString(nSpell) + + // " nClass: " + IntToString(nClass) + " nMetaMagic: " + IntToString(nMetaMagic) + + // " nDomain: " + IntToString(nDomain) + " nLevel: " + IntToString(nLevel)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + sSubSpell = Get2DAString("spells", "Master", nSpell); + if(sSubSpell != "") nSpell = StringToInt(sSubSpell); + if(nDomain == -1 || GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain)) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(nDomain == -1) NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName)); + else + { + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + } + } + else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + } + else break; + ++nIndex; + } + } + } +} +void ai_CreateWidgetNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + if(sAssociateType == "") return; + int bAIWidgetLock = ai_GetWidgetButton(oPC, BTN_WIDGET_LOCK, oAssociate, sAssociateType); + int bVertical = ai_GetWidgetButton(oPC, BTN_WIDGET_VERTICAL, oAssociate, sAssociateType); + float fButtons; + // ************************************************************************* Width / Height + // Row 1 (buttons)********************************************************** + // Setup the main associate button to use their portrait. + json jButton = NuiEnabled(NuiId (NuiButtonImage(NuiBind("btn_open_main_image")), "btn_open_main"), NuiBind("btn_open_main_event")); + jButton = NuiWidth(jButton, 35.0); + jButton = NuiHeight(jButton, 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind ("btn_open_main_tooltip")); + jButton = NuiImageRegion(jButton, NuiRect(0.0, 0.0, 32.0, 35.0)); + json jRow = JsonArrayInsert(JsonArray(), jButton); + if(ai_GetWidgetButton(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_action", "btn_cmd_action", 35.0f, 35.0f, 0.0, "btn_cmd_action_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_GUARD, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_guard", "btn_cmd_guard", 35.0f, 35.0f, 0.0, "btn_cmd_guard_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_HOLD, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_standground", "btn_cmd_hold", 35.0f, 35.0f, 0.0, "btn_cmd_hold_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_ATTACK, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_attacknearest", "btn_cmd_attack", 35.0f, 35.0f, 0.0, "btn_cmd_attack_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_FOLLOW, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_follow", "btn_cmd_follow", 35.0f, 35.0f, 0.0, "btn_cmd_follow_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_FOLLOW_TARGET, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_dmchat", "btn_follow_target", 35.0f, 35.0f, 0.0, "btn_follow_target_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_SEARCH, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ife_foc_search", "btn_cmd_search", 35.0f, 35.0f, 0.0, "btn_cmd_search_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_STEALTH, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ife_foc_hide", "btn_cmd_stealth", 35.0f, 35.0f, 0.0, "btn_cmd_stealth_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_AI_SCRIPT, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "", "btn_cmd_ai_script", 35.0f, 35.0f, 0.0, "btn_cmd_ai_script_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_PLACE_TRAP, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_settrap", "btn_cmd_place_trap", 35.0f, 35.0f, 0.0, "btn_cmd_place_trap_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_SHORT, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_cantrips", "btn_buff_short", 35.0f, 35.0f, 0.0, "btn_buff_short_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_LONG, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_cast", "btn_buff_long", 35.0f, 35.0f, 0.0, "btn_buff_long_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_ALL, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_level789", "btn_buff_all", 35.0f, 35.0f, 0.0, "btn_buff_all_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_BUFF_REST, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_rest", "btn_buff_rest", 35.0f, 35.0f, 0.0, "btn_buff_rest_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_JUMP_TO, oAssociate, sAssociateType)) + { + string sImage; + if(oPC == oAssociate) sImage = "dm_jumpall"; + else sImage = "dm_jump"; + jRow = CreateButtonImage(jRow, sImage, "btn_jump_to", 35.0f, 35.0f, 0.0, "btn_jump_to_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_GHOST_MODE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "dm_limbo", "btn_ghost_mode", 35.0f, 35.0f, 0.0, "btn_ghost_mode_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_FAMILIAR, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ife_familiar", "btn_familiar", 35.0f, 35.0f, 0.0, "btn_familiar_tooltip"); + fButtons += 1.0; + } + if(ai_GetWidgetButton(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ife_animal", "btn_companion", 35.0f, 35.0f, 0.0, "btn_companion_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_FOR_PC, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "dm_ai", "btn_ai", 35.0f, 35.0f, 0.0, "btn_ai_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_REDUCE_SPEECH, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_movsilent", "btn_quiet", 35.0f, 35.0f, 0.0, "btn_quiet_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_USE_RANGED, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_archer", "btn_ranged", 35.0f, 35.0f, 0.0, "btn_ranged_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_WEAPON_EQUIP, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "dm_takeitem", "btn_equip_weapon", 35.0f, 35.0f, 0.0, "btn_equip_weapon_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_USE_SEARCH, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_search", "btn_search", 35.0f, 35.0f, 0.0, "btn_search_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_USE_STEALTH, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_hide", "btn_stealth", 35.0f, 35.0f, 0.0, "btn_stealth_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_OPEN_DOORS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_open", "btn_open_door", 35.0f, 35.0f, 0.0, "btn_open_door_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_REMOVE_TRAPS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_distrap", "btn_traps", 35.0f, 35.0f, 0.0, "btn_traps_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_PICK_LOCKS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_olock", "btn_pick_locks", 35.0f, 35.0f, 0.0, "btn_pick_locks_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_BASH_LOCKS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_bash", "btn_bash_locks", 35.0f, 35.0f, 0.0, "btn_bash_locks_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_MAGIC_LEVEL, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "dm_control", "btn_magic_level", 35.0f, 35.0f, 0.0, "btn_magic_level_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_NO_SPONTANEOUS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_xability", "btn_spontaneous", 35.0f, 35.0f, 0.0, "btn_spontaneous_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_USE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_cntrspell", "btn_magic", 35.0f, 35.0f, 0.0, "btn_magic_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_NO_MAGIC_ITEM_USE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_moreattacks", "btn_magic_items", 35.0f, 35.0f, 0.0, "btn_magic_items_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_DEF_MAGIC_USE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_orisons", "btn_def_magic", 35.0f, 35.0f, 0.0, "btn_def_magic_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_OFF_MAGIC_USE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_metamagic", "btn_off_magic", 35.0f, 35.0f, 0.0, "btn_off_magic_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_HEAL_OUT, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "isk_heal", "btn_heal_out", 35.0f, 35.0f, 0.0, "btn_heal_out_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_HEAL_IN, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "dm_heal", "btn_heal_in", 35.0f, 35.0f, 0.0, "btn_heal_in_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_SELF_HEALING, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_heal", "btn_heals_onoff", 35.0f, 35.0f, 0.0, "btn_heals_onoff_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_PARTY_HEALING, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_party", "btn_healp_onoff", 35.0f, 35.0f, 0.0, "btn_healp_onoff_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_STOP_CURE_SPELLS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_accept", "btn_cure_onoff", 35.0f, 35.0f, 0.0, "btn_cure_onoff_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_LOOT, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_barter", "btn_loot", 35.0f, 35.0f, 0.0, "btn_loot_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_IGNORE_ASSOCIATES, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_ignore", "btn_ignore_assoc", 35.0f, 35.0f, 0.0, "btn_ignore_assoc_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_IGNORE_TRAPS, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_abort", "btn_ignore_traps", 35.0f, 35.0f, 0.0, "btn_ignore_traps_tooltip"); + fButtons += 1.0; + } + if(ai_GetAIButton(oPC, BTN_AI_PERC_RANGE, oAssociate, sAssociateType)) + { + jRow = CreateButtonImage(jRow, "ir_dmchat", "btn_perc_range", 35.0f, 35.0f, 0.0, "btn_perc_range_tooltip"); + fButtons += 1.0; + } + int bIsPC = ai_GetIsCharacter(oAssociate); + if(bIsPC) + { + json jPCPlugins = ai_UpdatePluginsForPC(oPC); + // Plug in buttons ***************************************************** + int nIndex, bWidget; + string sIcon, sButton; + json jPlugin = JsonArrayGet(jPCPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bWidget == 1) + { + sIcon = JsonGetString(JsonArrayGet(jPlugin, 3)); + sButton = IntToString(nIndex); + jRow = CreateButtonImage(jRow, sIcon, "btn_exe_plugin_" + sButton, 35.0f, 35.0f, 0.0, "btn_exe_plugin_" + sButton + "_tooltip"); + fButtons += 1.0; + } + jPlugin = JsonArrayGet(jPCPlugins, ++nIndex); + } + } + float fHeight, fWidth; + if(bAIWidgetLock) + { + fWidth = 50.0f; + fHeight = 50.0; + } + else if(bVertical) + { + fWidth = 88.0f; + fHeight = 55.0f; + } + else + { + fWidth = 55.0f; + fHeight = 88.0f; + } + // Quick Widget. + int nIndex, nSpell, nLevel, nMetaMagic; + float fQuickWidgetColumns; + string sClass, sLevel, sIndex; + object oItem; + json jSpell; + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jCol = JsonArray(); + if(ai_GetWidgetButton(oPC, BTN_CMD_SPELL_WIDGET, oAssociate, sAssociateType) && + JsonGetLength(jWidget) > 0) + { + // Row 2 (Widget Row 1)************************************************* + if(JsonGetType(jWidget) != JSON_TYPE_NULL) + { + fQuickWidgetColumns += 1.0; + int bAdd; + float fSpellButtons; + json jButton, jRectangle, jMetaMagic, jDrawList; + // Add row to the column. + if(bVertical) jCol = JsonArrayInsert(jCol, NuiCol(jRow)); + else jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + jRow = CreateButtonImage(JsonArray(), "ir_back", "btn_update_widget", 35.0f, 35.0f, 0.0, "btn_update_widget_tooltip"); + //CreateLabel(jRow, "", "blank_label", 35.0, 35.0, 0, 0, 0.0); + while(nIndex < 10) + { + bAdd = TRUE; + jSpell = JsonArrayGet(jWidget, nIndex); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + if(JsonGetInt(JsonArrayGet(jSpell, 1)) == -1) + { + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + if(oItem == OBJECT_INVALID) + { + bAdd = FALSE; + jWidget = JsonArrayDel(jWidget, nIndex--); + jSpells = JsonArrayInsert(jSpells, jWidget, 2); + jAIData = JsonArrayInsert(jAIData, jSpells, 10); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + } + if(bAdd) + { + sIndex = IntToString(nIndex); + jButton = NuiButtonImage(NuiBind("btn_widget_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_widget_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_widget_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_widget_" + sIndex + "_tooltip")); + jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + fSpellButtons += 1.0; + } + } + else break; + ++nIndex; + } + if(fSpellButtons > fButtons) fButtons = fSpellButtons; + // Row 3 (Widget Row 2)************************************************* + if(nIndex > 9 && JsonGetLength(jWidget) > 10) + { + fQuickWidgetColumns += 1.0; + // Add row to the column. + if(bVertical) jCol = JsonArrayInsert(jCol, NuiCol(jRow)); + else jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + jRow = CreateLabel(JsonArray(), "", "blank_label", 35.0, 35.0, 0, 0, 0.0); + while(nIndex < 20) + { + jSpell = JsonArrayGet(jWidget, nIndex); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + if(JsonGetInt(JsonArrayGet(jSpell, 1)) == -1) + { + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + if(oItem == OBJECT_INVALID) + { + bAdd = FALSE; + jWidget = JsonArrayDel(jWidget, nIndex--); + jSpells = JsonArrayInsert(jSpells, jWidget, 2); + jAIData = JsonArrayInsert(jAIData, jSpells, 10); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + } + if(bAdd) + { + sIndex = IntToString(nIndex); + jButton = NuiButtonImage(NuiBind("btn_widget_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_widget_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_widget_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_widget_" + sIndex + "_tooltip")); + jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + fSpellButtons += 1.0; + } + } + else break; + ++nIndex; + } + } + } + // Add the row to the column. + if(nIndex > 0) + { + if(bVertical) jCol = JsonArrayInsert(jCol, NuiCol(jRow)); + else jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + } + } + else + { + // Add the row to the column. + if(bVertical) jCol = JsonArrayInsert(jCol, NuiCol(jRow)); + else jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + } + float fScale = GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE) / 100.0; + float fButtonScale; + // 1.1 = 2.5 2.0 = 6.0 Ranges we need for scales to work correctly. + if(fScale > 1.0) fButtonScale = (fScale - 1.1) / (2.0 - 1.1) * 3.5 + 2.5; + else fButtonScale = 1.0; + if(fButtons > 0.0f) + { + if(bVertical) fWidth = fWidth + fButtons * 35.0f + fButtons * fButtonScale; + else fWidth = fWidth + fButtons * 35.0f; + } + if(fQuickWidgetColumns > 0.0f) + { + if(bVertical) fHeight = fHeight + fQuickWidgetColumns * 39.0f; + else fHeight = fHeight + fQuickWidgetColumns * 39.0f + fQuickWidgetColumns * fButtonScale; + } + // Get the window location to restore it from the database. + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + //SendMessageToPC(oPC, "0i_menu, 2124, sAssociateType: " + sAssociateType + " jLocations: " + JsonDump(jLocations, 1)); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) + { + ai_SetupAssociateData(oPC, oAssociate, sAssociateType); + jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + } + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_WIDGET_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Keeps the widgets from bunching up in the top corner. + if(fY == 0.0 && fX == 0.0) + { + if(sAssociateType == "pc") fY = 1.0; + else if(sAssociateType == "familiar") fY = 96.0 * fScale; + else if(sAssociateType == "companion") fY = 192.0 * fScale; + else if(sAssociateType == "summons") fY = 288.0 * fScale; + else if(sAssociateType == "dominated") fY = 384.0 * fScale; + else + { + int nIndex = 1; + string sAssociateName = GetName(oAssociate); + while(nIndex < AI_MAX_HENCHMAN) + { + if(sAssociateName == GetName(GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex))) + { + fY = (88.0 + 88.0 * IntToFloat(nIndex - 1)); + break; + } + nIndex++; + } + } + fY = fY * fScale; + } + if(bAIWidgetLock) + { + fX += 4.0f; + // GUI scales are a mess, I just figured them out per scale to keep the widget from moving. + if(fScale == 1.0) fY += 37.0; + else if(fScale == 1.1) fY += 38.0; + else if(fScale == 1.2) fY += 40.0; + else if(fScale == 1.3) fY += 42.0; + else if(fScale == 1.4) fY += 43.0; + else if(fScale == 1.5) fY += 45.0; + else if(fScale == 1.6) fY += 47.0; + else if(fScale == 1.7) fY += 48.0; + else if(fScale == 1.8) fY += 50.0; + else if(fScale == 1.9) fY += 52.0; + else if(fScale == 2.0) fY += 54.0; + } + // Set the layout of the window. + json jLayout; + int nToken, bBool; + string sHeal, sText, sRange; + string sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + if(bVertical) + { + jLayout = NuiRow(jCol); + if(bAIWidgetLock) nToken = SetWindow(oPC, jLayout, sAssociateType + AI_WIDGET_NUI, "AI Widget", fX, fY, fHeight, fWidth, FALSE, FALSE, FALSE, TRUE, FALSE, "0e_nui"); + else nToken = SetWindow(oPC, jLayout, sAssociateType + AI_WIDGET_NUI, sName + " Widget", fX, fY, fHeight, fWidth, FALSE, FALSE, FALSE, TRUE, TRUE, "0e_nui"); +} + else + { + jLayout = NuiCol(jCol); + if(bAIWidgetLock) nToken = SetWindow(oPC, jLayout, sAssociateType + AI_WIDGET_NUI, "AI Widget", fX, fY, fWidth, fHeight, FALSE, FALSE, FALSE, TRUE, FALSE, "0e_nui"); + else nToken = SetWindow(oPC, jLayout, sAssociateType + AI_WIDGET_NUI, sName + " Widget", fX, fY, fWidth, fHeight, FALSE, FALSE, FALSE, TRUE, TRUE, "0e_nui"); + } + // Save the associate to the nui. + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + NuiSetUserData(oPC, nToken, jData); + ai_SetWidgetBinds(oPC, oAssociate, sAssociateType, nToken, sName); +} +json ai_CreateLootFilterRow(json jRow, string sLabel, int nIndex) +{ + string sIndex = IntToString(nIndex); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateTextEditBox(jRow, "plc_hold", "txt_gold_" + sIndex, 9, FALSE, 90.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateCheckBox(jRow, sLabel, "chbx_" + sIndex, 200.0, 20.0); + return JsonArrayInsert(jRow, NuiSpacer()); +} +void ai_SetupLootElements(object oPC, object oAssociate, int nToken, int nLootBit, int nIndex) +{ + string sIndex = IntToString(nIndex); + int bLoot = ai_GetLootFilter(oAssociate, nLootBit); + NuiSetBind(oPC, nToken, "chbx_" + sIndex + "_check", JsonBool(bLoot)); + NuiSetBindWatch (oPC, nToken, "chbx_" + sIndex + "_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_" + sIndex + "_event", JsonBool(TRUE)); + string sGold = IntToString(GetLocalInt(oAssociate, AI_MIN_GOLD_ + sIndex)); + NuiSetBind(oPC, nToken, "txt_gold_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_gold_" + sIndex, JsonString(sGold)); + NuiSetBindWatch (oPC, nToken, "txt_gold_" + sIndex, TRUE); +} +void ai_CreateLootFilterNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 318 / 73 + int bIsPC = ai_GetIsCharacter(oAssociate); + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateCheckBox(jRow, "Give all loot to the player", "chbx_give_loot", 200.0, 20.0, "chbx_give_loot_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 *************************************************************** 388 / 101 + jRow = JsonArray(); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateTextEditBox(jRow, "plc_hold", "txt_max_weight", 9, FALSE, 50.0, 20.0, "txt_max_weight_tooltip"); + jRow = CreateLabel(jRow, "Maximum Weight to pickup", "lbl_weight", 200.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 *************************************************************** 388 / 129 + jRow = JsonArray(); + jRow = CreateButton(jRow, "Set All", "btn_set_all", 110.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear All", "btn_clear_all", 110.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 *************************************************************** 388 / 157 + jRow = JsonArray(); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "Minimum Gold", "lbl_min_gold", 100.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateLabel(jRow, "Items to Pickup", "lbl_pickup", 140.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 *************************************************************** 388 / 185 + jRow = ai_CreateLootFilterRow(JsonArray(), "Plot items", 2); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 6 *************************************************************** 388 / 213 + jRow = ai_CreateLootFilterRow(JsonArray(), "Armor", 3); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 7 *************************************************************** 388 / 241 + jRow = ai_CreateLootFilterRow(JsonArray(), "Belts", 4); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 8 *************************************************************** 388 / 269 + jRow = ai_CreateLootFilterRow(JsonArray(), "Boots", 5); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 9 *************************************************************** 388 / 297 + jRow = ai_CreateLootFilterRow(JsonArray(), "Cloaks", 6); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 10 *************************************************************** 388 / 325 + jRow = ai_CreateLootFilterRow(JsonArray(), "Gems", 7); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 11 *************************************************************** 388 / 353 + jRow = ai_CreateLootFilterRow(JsonArray(), "Gloves and Bracers", 8); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 12 *************************************************************** 388 / 381 + jRow = ai_CreateLootFilterRow(JsonArray(), "Headgear", 9); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 13 *************************************************************** 388 / 409 + jRow = ai_CreateLootFilterRow(JsonArray(), "Jewelry", 10); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 14 *************************************************************** 388 / 437 + jRow = ai_CreateLootFilterRow(JsonArray(), "Miscellaneous items", 11); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 15 *************************************************************** 388 / 465 + jRow = ai_CreateLootFilterRow(JsonArray(), "Potions", 12); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 16 *************************************************************** 388 / 493 + jRow = ai_CreateLootFilterRow(JsonArray(), "Scrolls", 13); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 17 *************************************************************** 388 / 521 + jRow = ai_CreateLootFilterRow(JsonArray(), "Shields", 14); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 18 *************************************************************** 388 / 549 + jRow = ai_CreateLootFilterRow(JsonArray(), "Wands, Rods, and Staves", 15); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 19 ************************************************************** 388 / 577 + jRow = ai_CreateLootFilterRow(JsonArray(), "Weapons", 16); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 20 ************************************************************** 388 / 605 + jRow = ai_CreateLootFilterRow(JsonArray(), "Arrows", 17); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 21 ************************************************************** 388 / 633 + jRow = ai_CreateLootFilterRow(JsonArray(), "Bolts", 18); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 22 ************************************************************** 388 / 661 + jRow = ai_CreateLootFilterRow(JsonArray(), "Bullets", 19); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_LOOTFILTER_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sText, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_LOOTFILTER_NUI, sName + " Loot Filter", + fX, fY, 318.0, 673.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Save the associate to the nui. + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + NuiSetUserData(oPC, nToken, jData); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 + int bGiveLoot = ai_GetLootFilter(oAssociate, AI_LOOT_GIVE_TO_PC); + NuiSetBind(oPC, nToken, "chbx_give_loot_check", JsonBool (bGiveLoot)); + NuiSetBindWatch (oPC, nToken, "chbx_give_loot_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_give_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_give_loot_tooltip", JsonString( + " Check this to make henchman give any loot picked up to the player.")); + // Row 2 + int nWeight = GetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT); + if(nWeight == 0) + { + nWeight = 200; + SetLocalInt(oAssociate, AI_MAX_LOOT_WEIGHT, nWeight); + } + NuiSetBind(oPC, nToken, "txt_max_weight_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_max_weight", JsonString(IntToString(nWeight))); + NuiSetBindWatch (oPC, nToken, "txt_max_weight", TRUE); + NuiSetBind(oPC, nToken, "txt_max_weight_tooltip", JsonString(" Max weighted item you will pickup from 1 to 1,000")); + // Row 3 + NuiSetBind(oPC, nToken, "btn_set_all_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_set_all", JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_all_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_all", JsonInt(TRUE)); + // Row 4 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_PLOT, 2); + // Row 5 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_ARMOR, 3); + // Row 6 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_BELTS, 4); + // Row 7 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_BOOTS, 5); + // Row 8 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_CLOAKS, 6); + // Row 9 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_GEMS, 7); + // Row 10 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_GLOVES, 8); + // Row 11 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_HEADGEAR, 9); + // Row 12 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_JEWELRY, 10); + // Row 13 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_MISC, 11); + // Row 14 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_POTIONS, 12); + // Row 15 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_SCROLLS, 13); + // Row 16 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_SHIELDS, 14); + // Row 17 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_WANDS_RODS_STAVES, 15); + // Row 18 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_WEAPONS, 16); + // Row 19 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_ARROWS, 17); + // Row 20 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_BOLTS, 18); + // Row 21 + ai_SetupLootElements(oPC, oAssociate, nToken, AI_LOOT_BULLETS, 19); +} +void ai_CreateCopySettingsNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 244 / 73 + string sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "Copy settings to", "lbl_paste", 220.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 244 / 101 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "All Associates", "btn_paste_all", 220.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 2 ******************************************************************* 244 / 129 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Familiar", "btn_paste_familiar", 220.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 244 / 157 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Companion", "btn_paste_companion", 220.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 244 / 185 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Summons", "btn_paste_summons", 220.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 ******************************************************************* 244 / 213 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Dominated", "btn_paste_dominated", 220.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5+ ****************************************************************** 244 / 241 + float fHeight = 241.0; + int nIndex; + string sAssocName; + object oAssoc; + for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++) + { + oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssoc != OBJECT_INVALID) + { + sAssocName = GetName(oAssoc); + if(GetStringRight(sAssocName, 1) == "s") sAssocName = sAssocName + "'"; + else sAssocName = sAssocName + "'s"; + jRow = CreateButton(JsonArray(), sAssocName, "btn_paste_henchman" + IntToString(nIndex), 220.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + else break; + } + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_COPY_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_COPY_NUI, sName + " Copy Settings Menu", + fX, fY, 244.0, fHeight + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Save the associate to the nui. + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + NuiSetUserData(oPC, nToken, jData); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 + NuiSetBind(oPC, nToken, "btn_paste_all_event", JsonBool (TRUE)); + oAssoc = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC); + NuiSetBind(oPC, nToken, "btn_paste_familiar_event", JsonBool(oAssoc != oAssociate && oAssoc != OBJECT_INVALID)); + oAssoc = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC); + NuiSetBind(oPC, nToken, "btn_paste_companion_event", JsonBool(oAssoc != oAssociate && oAssoc != OBJECT_INVALID)); + oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC); + NuiSetBind(oPC, nToken, "btn_paste_summons_event", JsonBool(oAssoc != oAssociate && oAssoc != OBJECT_INVALID)); + oAssoc = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC); + NuiSetBind(oPC, nToken, "btn_paste_dominated_event", JsonBool(oAssoc != oAssociate && oAssoc != OBJECT_INVALID)); + for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++) + { + oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssoc != OBJECT_INVALID) + { + NuiSetBind(oPC, nToken, "btn_paste_henchman" + IntToString(nIndex) + "_event", JsonBool(oAssoc != oAssociate)); + } + else break; + } +} +void ai_CreatePluginNUI(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int nIndex, nButton; + string sButton; + // Row 1 ******************************************************************* 500 / 73 + json jRow = CreateButton(JsonArray(), "Load Plugins", "btn_load_plugins", 150.0f, 20.0f, -1.0, "btn_load_plugins_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Load Monster Mods", "btn_load_m_mods", 150.0f, 20.0f, -1.0, "btn_load_m_mods_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Check All", "btn_check_plugins", 80.0f, 20.0f, -1.0, "btn_check_plugins_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear All", "btn_clear_plugins", 80.0f, 20.0f, -1.0, "btn_clear_plugins_tooltip"); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 101 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Add Plugin", "btn_add_plugin", 150.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateTextEditBox(jRow, "sPlaceHolder", "txt_plugin", 16, FALSE, 310.0f, 20.0f, "txt_plugin_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 101.0; + // Row 3+ ****************************************************************** 500 / --- + json jPlugins = ai_GetAssociateDbJson(oPC, "pc", "plugins"); + nIndex = 0; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + string sName; + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Remove Plugin", "btn_remove_plugin_" + sButton, 150.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(jRow, sName, "btn_plugin_" + sButton, 290.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + // Get the window location to restore it from the database. + json jLocations = ai_GetAssociateDbJson(oPC, "pc", "locations"); + float fX, fY; + jLocations = JsonObjectGet(jLocations, AI_PLUGIN_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, AI_PLUGIN_NUI, sName + " PEPS Plugin Manager", + fX, fY, 500.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oPC))); + NuiSetUserData(oPC, nToken, jData); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Row 1 + NuiSetBind(oPC, nToken, "btn_load_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_load_plugins_tooltip", JsonString(" Load all known PEPS plugins that are in the game files.")); + NuiSetBind(oPC, nToken, "btn_load_m_mods_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_load_m_mods_tooltip", JsonString(" Load all known PEPS monster mods that are in the game files.")); + NuiSetBind(oPC, nToken, "btn_check_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_check_plugins_tooltip", JsonString(" Add all plugins to the players widget.")); + NuiSetBind(oPC, nToken, "btn_clear_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_plugins_tooltip", JsonString(" Remove all plugins from the players widget.")); + // Row 2 + NuiSetBind(oPC, nToken, "btn_add_plugin_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_plugin_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_plugin_tooltip", JsonString(" Enter an executable script name.")); + // Row 3+ + nIndex = 0; + int bCheck; + string sText; + jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_remove_plugin_" + sButton + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_event", JsonBool(TRUE)); + bCheck = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bCheck < 3) + { + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_check", JsonBool(bCheck)); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_plugin_" + sButton + "_check", TRUE); + } + sText = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_tooltip", JsonString(sText)); + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } +} +int ai_SpellNotInList(int nSpell, json jSpellArray) +{ + int nMaxArray = JsonGetLength(jSpellArray); + int nIndex; + while(nIndex < nMaxArray) + { + if(nSpell == JsonGetInt(JsonArrayGet(JsonArrayGet(jSpellArray, nIndex), 0))) return FALSE; + nIndex++; + } + return TRUE; +} +json ai_CheckItemAbilities(json jQuickListArray, object oCreature, object oItem, json jSpell_Icon, json jSpell_Text, int bEquiped = FALSE) +{ + // We have established that we can use the item if it is equiped. + if(!bEquiped && !ai_CheckIfCanUseItem(oCreature, oItem)) return jQuickListArray; + int nPerDay, nCharges, nUses, bSaveTalent, nBaseItemType; + int nIprpSubType, nSpell, nLevel, nIPType, nIndex; + string sSpellIcon, sSpellName; + itemproperty ipProp = GetFirstItemProperty(oItem); + json jSpell; + // Lets skip this if there are no properties. + if(!GetIsItemPropertyValid(ipProp)) return jQuickListArray; + // Check for cast spell property and add them to the talent list. + while(GetIsItemPropertyValid(ipProp)) + { + nIPType = GetItemPropertyType(ipProp); + if(nIPType == ITEM_PROPERTY_CAST_SPELL) + { + bSaveTalent = TRUE; + // Get how they use the item (charges or uses per day). + nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses > 1 && nUses < 7) + { + nCharges = GetItemCharges(oItem); + if((nUses == IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE && nCharges < 1) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE && nCharges < 2) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_3_CHARGES_PER_USE && nCharges < 3) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_4_CHARGES_PER_USE && nCharges < 4) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_5_CHARGES_PER_USE && nCharges < 5)) bSaveTalent = FALSE; + } + else if(nUses > 7 && nUses < 13) + { + nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(AI_DEBUG) ai_Debug("0i_talents", "1676", "Item uses: " + IntToString(nPerDay)); + if(nPerDay == 0) bSaveTalent = FALSE; + } + if(bSaveTalent) + { + // SubType is the ip spell index for iprp_spells.2da + nIprpSubType = GetItemPropertySubType(ipProp); + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + nBaseItemType = GetBaseItemType(oItem); + if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL) + { + sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType); + sSpellName = ai_StripColorCodes(GetName(oItem)); + nUses = GetNumStackedItems(oItem); + } + else + { + if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) + { + sSpellName = ai_StripColorCodes(GetName(oItem)); + nUses = GetNumStackedItems(oItem); + } + else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == FEAT_CRAFT_WAND) + { + sSpellName = ai_StripColorCodes(GetName(oItem)); + nUses = nCharges; + } + else + { + sSpellName = ai_StripColorCodes(GetName(oItem)) + ": "; + sSpellName += GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(nCharges) nUses = nCharges; + else nUses = nPerDay; + } + sSpellIcon = Get2DAString("spells", "iConResRef", nSpell); + } + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(-1)); // Class is set to -1 for items + jSpell = JsonArrayInsert(jSpell, JsonInt(nUses)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nBaseItemType)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nIprpSubType)); + jSpell = JsonArrayInsert(jSpell, JsonString(GetObjectUUID(oItem))); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + } + else if(nIPType == ITEM_PROPERTY_HEALERS_KIT) + { + // Must also have ranks in healing kits. + if(GetSkillRank(SKILL_HEAL, oCreature) > 0) + { + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString("isk_heal")); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(ai_StripColorCodes(GetName(oItem)))); + json jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(SPELL_HEALINGKIT)); + jSpell = JsonArrayInsert(jSpell, JsonInt(-1)); // Class is set to -1 for items + jSpell = JsonArrayInsert(jSpell, JsonInt(GetNumStackedItems(oItem))); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jSpell = JsonArrayInsert(jSpell, JsonInt(GetItemPropertyCostTableValue(ipProp))); + jSpell = JsonArrayInsert(jSpell, JsonString(GetObjectUUID(oItem))); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + } + nIndex++; + ipProp = GetNextItemProperty(oItem); + } + SetLocalJson(oCreature, "JSPELL_ICON", jSpell_Icon); + SetLocalJson(oCreature, "JSPELL_NAME", jSpell_Text); + return jQuickListArray; +} +void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) +{ + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + json jRow = JsonArray(); + // Row 1 Classes************************************************************ 414 / 88 + int nClass, nLevel, nIndex; + string sIndex, sClassIcon, sLevelIcon; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass != CLASS_TYPE_INVALID) + { + // This saves the class position in the button id so we can get it later. + sIndex = IntToString(nIndex); + sClassIcon = Get2DAString("classes", "Icon", nClass); + jRow = CreateButtonImage(jRow, sClassIcon, "btn_class_" + sIndex, 35.0f, 35.0f, 0.0, "btn_class_" + sIndex + "_tooltip"); + } + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Levels) ********************************************************** 414 / 131 + jRow = CreateButtonImage(JsonArray(), "", "btn_level_11" , 35.0f, 35.0f, 0.0, "btn_level_11_tooltip"); + jRow = CreateButtonImage(jRow, "", "btn_level_10" , 35.0f, 35.0f, 0.0, "btn_level_10_tooltip"); + for(nIndex = 0; nIndex <= 9; nIndex++) + { + // This saves the level in the button id so we can get it later. + sIndex = IntToString(nIndex); + jRow = CreateButtonImage(jRow, "", "btn_level_" + sIndex, 35.0f, 35.0f, 0.0, "btn_level_" + sIndex + "_tooltip"); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Spell List)******************************************************* 414 / 433 + json jButton = JsonArray(); + jButton = NuiButton(NuiBind("text_spell")); + jButton = NuiId(jButton, "btn_text_spell"); + json jRectangle = NuiRect(4.0, 4.0, 27.0, 27.0); + json jDrawList = JsonArrayInsert(JsonArray(), NuiDrawListImage(JsonBool(TRUE), NuiBind("icon_spell"), jRectangle, JsonInt(NUI_ASPECT_FILL), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE))); + jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_text")); + jDrawList = JsonArrayInsert(jDrawList, jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + json jListTemplate = JsonArrayInsert(JsonArray(), NuiListTemplateCell(jButton, 345.0, FALSE)); + json jInfo = NuiButtonImage(JsonString("gui_cg_qstn_mark")); + jInfo = NuiId(jInfo, "btn_info_spell"); + jListTemplate = JsonArrayInsert(jListTemplate, NuiListTemplateCell(jInfo, 35.0, FALSE)); + jRow = JsonArrayInsert(JsonArray(), NuiHeight(NuiList(jListTemplate, NuiBind("icon_spell"), 35.0), 282.0)); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (Widget Label)***************************************************** 414 / 461 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "Quick Widget List", "lbl_quick_list", 150.0, 20.0, 0, 0, 0.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 (Widget row 1)***************************************************** 414 / 504 + jRow = JsonArray(); + for(nIndex = 0; nIndex < 10; nIndex++) + { + // This saves the index location in the json jWidget in the button id for later use. + sIndex = IntToString(nIndex); + json jButton = NuiButtonImage(NuiBind("btn_widget_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_widget_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_widget_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_widget_" + sIndex + "_tooltip")); + json jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 6 (Widget row 2)***************************************************** 414 / 543 + jRow = JsonArray(); + for(nIndex = 10; nIndex < 20; nIndex++) + { + // This saves the index location in the json jWidget in the button id for later use. + sIndex = IntToString(nIndex); + json jButton = NuiButtonImage(NuiBind("btn_widget_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_widget_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_widget_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_widget_" + sIndex + "_tooltip")); + json jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_QUICK_WIDGET_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sText, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_QUICK_WIDGET_NUI, sName + " Quick Widget Menu", + fX, fY, 414.0, 543.0 + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Set the Layout of the window. + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + json jSpells; + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + // Temporary fix for error! :/ + if(JsonGetLength(jAIData) == 0) + { + ai_CheckAssociateData(oPC, oAssociate, sAssociateType, TRUE); + jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(10)); + jAIData = JsonArrayInsert(jAIData, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + nLevel = 10; + } + if(JsonGetLength(jAIData) == 9) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(10)); + jSpells = JsonArrayInsert(jSpells, JsonArray()); + jAIData = JsonArrayInsert(jAIData, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + nLevel = 10; + } + else + { + jSpells = JsonArrayGet(jAIData, 10); + if(JsonGetLength(jSpells) == 0) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(10)); + jSpells = JsonArrayInsert(jSpells, JsonArray()); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + nLevel = 10; + } + else + { + nClass = JsonGetInt(JsonArrayGet(jSpells, 0)); + nLevel = JsonGetInt(JsonArrayGet(jSpells, 1)); + } + } + if(nClass < 1 || nClass > AI_MAX_CLASSES_PER_CHARACTER) nClass = 1; + nClass = GetClassByPosition(nClass, oAssociate); + // Row 1 & 2 Class & Level + int nSpellLevel, nLevelIndex, nClassIndex, nMaxSpellLevel; + string sClass, sLevel, sLevelImage, sLevelIndex; + NuiSetBind(oPC, nToken, "btn_level_11_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_11_tooltip", JsonString(" Item Powers")); + NuiSetBind(oPC, nToken, "btn_level_11_image", JsonString("ir_attack")); + NuiSetBind(oPC, nToken, "btn_level_10_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_10_tooltip", JsonString(" Special Abilities")); + NuiSetBind(oPC, nToken, "btn_level_10_image", JsonString("dm_god")); + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClassIndex = GetClassByPosition(nIndex, oAssociate); + if(nClassIndex != CLASS_TYPE_INVALID) + { + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClassIndex))); + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass)); + if(nClass == nClassIndex) + { + if(StringToInt(Get2DAString("classes", "SpellCaster", nClass))) + { + int nClassLevel = GetLevelByClass(nClass, oAssociate); + string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); + int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); + for(nLevelIndex = 0; nLevelIndex <= 9; nLevelIndex++) + { + sLevelIndex = IntToString(nLevelIndex); + if(nLevelIndex < nMaxSpellLevel) + { + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_event", JsonBool(TRUE)); + if(nLevelIndex == 0) sLevelImage = "ir_cantrips"; + else if(nLevelIndex < 7)sLevelImage = "ir_level" + sLevelIndex; + else sLevelImage = "ir_level789"; + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_image", JsonString(sLevelImage)); + if(nLevelIndex == 0) sLevel = " Cantrips"; + else if(nLevelIndex == 1) sLevel = " First level"; + else if(nLevelIndex == 2) sLevel = " Second level"; + else if(nLevelIndex == 3) sLevel = " Third level"; + else if(nLevelIndex == 4) sLevel = " Fourth level"; + else if(nLevelIndex == 5) sLevel = " Fifth level"; + else if(nLevelIndex == 6) sLevel = " Sixth level"; + else if(nLevelIndex == 7) sLevel = " Seventh level"; + else if(nLevelIndex == 8) sLevel = " Eighth level"; + else if(nLevelIndex == 9) sLevel = " Ninth level"; + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_tooltip", JsonString(" " + sLevel)); + } + else + { + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_event", JsonBool(FALSE)); + } + } + NuiSetBind(oPC, nToken, "btn_level_" + IntToString(nLevel) + "_encouraged", JsonBool(TRUE)); + } + // Default to the abilities tab since they are not a caster. + else + { + if(nLevel < 10) nLevel = 10; + for(nLevelIndex = 0; nLevelIndex <= 9; nLevelIndex++) + { + sLevelIndex = IntToString(nLevelIndex); + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_level_" + sLevelIndex + "_event", JsonBool(FALSE)); + } + NuiSetBind(oPC, nToken, "btn_level_10_encouraged", JsonBool(TRUE)); + } + NuiSetBind(oPC, nToken, "btn_class_" + IntToString(nClass) + "_encouraged", JsonBool(TRUE)); + } + } + } + // Row 3 Items/Abilities/Skills/Spells + int nSpell, nMetaMagic, nDomain, nSubSpell, nSubSpellIndex; + int nSpellSlot, nCounter, nMax2daRow, nFeat; + string sSpellIcon, sSpellName, sMetaMagicText, sClassFeats, sSubSpellIndex; + object oItem; + json jQuickListArray = JsonArray(); + json jSpell; + json jSpell_Icon = JsonArray(); + json jSpell_Text = JsonArray(); + SetLocalJson(oAssociate, "JSPELL_ICON", jSpell_Icon); + SetLocalJson(oAssociate, "JSPELL_NAME", jSpell_Text); + json jMetaMagic_Text = JsonArray(); + // Item powers + if(nLevel == 11) + { + string sSlots; + // Cycle through all the creatures inventory items. + oItem = GetFirstItemInInventory(oAssociate); + while(oItem != OBJECT_INVALID) + { + if(GetIdentified(oItem)) + { + // Does the item need to be equiped to use its powers? + sSlots = Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)); + if(sSlots == "0x00000") + { + jQuickListArray = ai_CheckItemAbilities(jQuickListArray, oAssociate, oItem, jSpell_Icon, jSpell_Text, FALSE); + jSpell_Icon = GetLocalJson(oAssociate, "JSPELL_ICON"); + jSpell_Text = GetLocalJson(oAssociate, "JSPELL_NAME"); + WriteTimestampedLogEntry("0i_menus, 3643, oAssociate: " + GetName(oAssociate) + + " jSpell_Text: " + JsonDump(jSpell_Text, 4)); + } + } + oItem = GetNextItemInInventory(oAssociate); + } + int nSlot; + // Cycle through all the creatures equiped items. + oItem = GetItemInSlot(nSlot, oAssociate); + while(nSlot < 11) + { + if(oItem != OBJECT_INVALID) + { + jQuickListArray = ai_CheckItemAbilities(jQuickListArray, oAssociate, oItem, jSpell_Icon, jSpell_Text, TRUE); + jSpell_Icon = GetLocalJson(oAssociate, "JSPELL_ICON"); + jSpell_Text = GetLocalJson(oAssociate, "JSPELL_NAME"); + } + oItem = GetItemInSlot(++nSlot, oAssociate); + } + oItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oAssociate); + if(oItem != OBJECT_INVALID) + { + jQuickListArray = ai_CheckItemAbilities(jQuickListArray, oAssociate, oItem, jSpell_Icon, jSpell_Text, TRUE); + jSpell_Icon = GetLocalJson(oAssociate, "JSPELL_ICON"); + jSpell_Text = GetLocalJson(oAssociate, "JSPELL_NAME"); + } + DeleteLocalJson(oAssociate, "JSPELL_ICON"); + DeleteLocalJson(oAssociate, "JSPELL_NAME"); + } + // Special abilities and skills. + else if(nLevel == 10) + { + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClassIndex = GetClassByPosition(nIndex, oAssociate); + if(nClassIndex != CLASS_TYPE_INVALID) + { + nCounter = 0; + sClassFeats = Get2DAString("classes", "FeatsTable", nClassIndex); + nMax2daRow = Get2DARowCount(sClassFeats); + while(nCounter < nMax2daRow) + { + if(Get2DAString(sClassFeats, "OnMenu", nCounter) != "0") + { + nFeat = StringToInt(Get2DAString(sClassFeats, "FeatIndex", nCounter)); + if(GetHasFeat(nFeat, oAssociate, TRUE)) + { + // Check for subfeats. + nSpell = StringToInt(Get2DAString("feat", "SPELLID", nFeat)); + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell)); + //SendMessageToPC(oPC, "nFeat: " + IntToString(nFeat) + + // " nSpell: " + IntToString(nSpell) + + // " nSubSpell: " + IntToString(nSubSpell)); + if(nSubSpell) + { + for(nSubSpellIndex = 1; nSubSpellIndex <= 5; nSubSpellIndex++) + { + sSubSpellIndex = IntToString(nSubSpellIndex); + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell)); + //SendMessageToPC(oPC, " nSpell: " + IntToString(nSpell) + + // " nSubSpell: " + IntToString(nSubSpell)); + if(nSubSpell != 0) + { + sSpellIcon = Get2DAString("spells", "iConResRef", nSubSpell); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSubSpell))); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSubSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jSpell = JsonArrayInsert(jSpell, JsonInt(255)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + } + } + else if((nFeat < 71 || nFeat > 81)) + { + sSpellIcon = Get2DAString("feat", "ICON", nFeat); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jSpell = JsonArrayInsert(jSpell, JsonInt(255)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + } + } + nCounter++; + } + } + } + // Used in the execution script to get the special abilities. + //jData = JsonArrayInsert(jData, jQuickListArray); + } + else // Anything else is for spells. + { + // Search all memorized spells for the spell. + //SendMessageToPC(oPC, GetName(oAssociate) + " nClass: " + IntToString(nClass) + + // " nLevelSelected: " + IntToString(nLevel) + + // " nMemorizesSpells: " + Get2DAString("classes", "MemorizesSpells", nClass)); + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + int nMaxSlot = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevel); + while(nSpellSlot < nMaxSlot) + { + nSpell = GetMemorizedSpellId(oAssociate, nClass, nLevel, nSpellSlot); + if(nSpell != -1 && ai_SpellNotInList(nSpell, jQuickListArray)) + { + nMetaMagic = GetMemorizedSpellMetaMagic(oAssociate, nClass, nLevel, nSpellSlot); + nDomain = GetMemorizedSpellIsDomainSpell(oAssociate, nClass, nLevel, nSpellSlot); + // Check for subspells. + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell)); + if(nSubSpell) + { + for(nSubSpellIndex = 1; nSubSpellIndex < 6; nSubSpellIndex++) + { + sSubSpellIndex = IntToString(nSubSpellIndex); + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell)); + if(nSubSpell && ai_SpellNotInList(nSubSpell, jQuickListArray)) + { + sSpellIcon = Get2DAString("spells", "IconResRef", nSubSpell); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSubSpell))); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + jMetaMagic_Text = JsonArrayInsert(jMetaMagic_Text, JsonString(sMetaMagicText)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSubSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nMetaMagic)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nDomain)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + } + } + else + { + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + jMetaMagic_Text = JsonArrayInsert(jMetaMagic_Text, JsonString(sMetaMagicText)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nMetaMagic)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nDomain)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + //SendMessageToPC(oPC, "nSpell: " + IntToString(nSpell) + + // " sSpellIcon: " + sSpellIcon + + // " sSpellName: " + sSpellName+ + // " nMaxSlot: " + IntToString(nMaxSlot) + + // " nSpellSlot: " + IntToString(nSpellSlot)); + } + } + ++nSpellSlot; + } + } + // Non-memorized spells. + else + { + int nMaxSlot = GetKnownSpellCount(oAssociate, nClass, nLevel); + while(nSpellSlot < nMaxSlot) + { + nSpell = GetKnownSpellId(oAssociate, nClass, nLevel, nSpellSlot); + if(nSpell != -1)// && ai_SpellNotInList(nSpell, jQuickListArray)) + { + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel)); + jSpell = JsonArrayInsert(jSpell, JsonInt(255)); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + } + ++nSpellSlot; + } + } + } + NuiSetBind(oPC, nToken, "icon_spell", jSpell_Icon); + NuiSetBind(oPC, nToken, "text_spell", jSpell_Text); + NuiSetBind(oPC, nToken, "metamagic_text", jMetaMagic_Text); + jData = JsonArrayInsert(jData, jQuickListArray); + NuiSetUserData(oPC, nToken, jData); + // Row 4 Quick widget list label. + // Row 5 Quick widget List 1 + json jWidget = JsonArrayGet(jSpells, 2); + nIndex = 0; + while(nIndex < 10) + { + jSpell = JsonArrayGet(jWidget, nIndex); + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nClass == -1) // This is an Item. + { + string sBaseName; + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3)); + int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4)); + if(nSpell == SPELL_HEALINGKIT) + { + sName = "Healer's Kit +" + IntToString(nIprpSubType); + sSpellIcon = "isk_heal"; + sBaseName = "Healer's Kit"; + } + else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL) + { + sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType); + sBaseName = "Scroll"; + } + else + { + if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion"; + else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand"; + else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + int nUses = ai_GetItemUses(oItem, nIprpSubType); + if(nUses) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(nUses == 999) sText = "Unlimited"; + else sText = IntToString(nUses); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")")); + } + } + else if(nFeat) // This is a feat. + { + sSpellIcon = ""; + if(nSpell) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + if(sSpellIcon == "" || sSpellIcon == "IR_USE") + { + sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + sSpellIcon = Get2DAString("feat", "ICON", nFeat); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName)); + } + else // This is a spell. + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + nLevel = JsonGetInt(JsonArrayGet(jSpell, 2)); + nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + } + } + else + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString("")); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + ++nIndex; + } + if(nIndex < 10) return; + // Row 6 Quick widget List2 + while(nIndex < 20) + { + jSpell = JsonArrayGet(jWidget, nIndex); + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nClass == -1) // This is an Item. + { + string sBaseName; + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3)); + int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4)); + if(nSpell == SPELL_HEALINGKIT) + { + sName = "Healer's Kit +" + IntToString(nIprpSubType); + sSpellIcon = "isk_heal"; + sBaseName = "Healer's Kit"; + } + else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || + nBaseItemType == BASE_ITEM_SCROLL || + nBaseItemType == BASE_ITEM_SPELLSCROLL) + { + sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType); + sBaseName = "Scroll"; + } + else + { + if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion"; + else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND || + nBaseItemType == BASE_ITEM_MAGICWAND || + nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand"; + else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + int nUses = ai_GetItemUses(oItem, nIprpSubType); + if(nUses) + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE)); + if(nUses == 999) sText = "Unlimited"; + else sText = IntToString(nUses); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")")); + } + } + else if(nFeat) // This is a feat. + { + sSpellIcon = ""; + if(nSpell) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + } + if(sSpellIcon == "" || sSpellIcon == "IR_USE") + { + sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + sSpellIcon = Get2DAString("feat", "ICON", nFeat); + } + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName)); + } + else // This is a spell. + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + nLevel = JsonGetInt(JsonArrayGet(jSpell, 2)); + nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); + sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + } + } + else + { + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString("")); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE)); + } + ++nIndex; + } +} +void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jRow = JsonArray(); + // Row 1 Classes************************************************************ 414 / 73 + int nClass, bCaster, nIndex; + string sIndex, sClassIcon, sLevelIcon; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass != CLASS_TYPE_INVALID) + { + if(StringToInt(Get2DAString("classes", "MemorizesSpells", nClass))) + { + // This saves the class position in the button id so we can get it later. + sIndex = IntToString(nIndex); + sClassIcon = Get2DAString("classes", "Icon", nClass); + jRow = CreateButtonImage(jRow, sClassIcon, "btn_class_" + sIndex, 35.0f, 35.0f, 0.0, "btn_class_" + sIndex + "_tooltip"); + } + } + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Levels) ********************************************************** 414 / 116 + jRow = JsonArray(); + for(nIndex = 0; nIndex <= 9; nIndex++) + { + // This saves the level in the button id so we can get it later. + sIndex = IntToString(nIndex); + jRow = CreateButtonImage(jRow, "", "btn_level_" + sIndex, 35.0f, 35.0f, 0.0, "btn_level_" + sIndex + "_tooltip"); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Spell List)******************************************************* 414 / 398 + json jButton = JsonArray(); + jButton = NuiButton(NuiBind("text_spell")); + jButton = NuiId(jButton, "btn_text_spell"); + json jRectangle = NuiRect(4.0, 4.0, 27.0, 27.0); + json jDrawList = JsonArrayInsert(JsonArray(), NuiDrawListImage(JsonBool(TRUE), NuiBind("icon_spell"), jRectangle, JsonInt(NUI_ASPECT_FILL), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE))); + //jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + //json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_text")); + //jDrawList = JsonArrayInsert(jDrawList, jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + json jListTemplate = JsonArrayInsert(JsonArray(), NuiListTemplateCell(jButton, 275.0, FALSE)); + json jInfo = NuiButtonImage(JsonString("gui_cg_qstn_mark")); + jInfo = NuiId(jInfo, "btn_info_spell"); + jListTemplate = JsonArrayInsert(jListTemplate, NuiListTemplateCell(jInfo, 35.0, FALSE)); + jRow = JsonArrayInsert(JsonArray(), NuiHeight(NuiList(jListTemplate, NuiBind("icon_spell"), 35.0), 282.0)); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (Widget Label)***************************************************** 414 / 426 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + CreateLabel(jRow, "Memorized Spell List", "lbl_spell_list", 150.0, 20.0, 0, 0, 0.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 (Memorize slots)*************************************************** 414 / 469 + // Get the class and level selected from the database. + int nClassSelected, nLevelSelected; + json jSpells; + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + // Temporary fix for error! :/ + if(JsonGetLength(jAIData) == 0) + { + ai_CheckAssociateData(oPC, oAssociate, sAssociateType, TRUE); + jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + } + if(JsonGetLength(jAIData) == 9) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(0)); + jAIData = JsonArrayInsert(jAIData, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + else + { + jSpells = JsonArrayGet(jAIData, 10); + if(JsonGetType(jSpells) == JSON_TYPE_NULL) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(0)); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + else + { + nClassSelected = JsonGetInt(JsonArrayGet(jSpells, 0)); + nLevelSelected = JsonGetInt(JsonArrayGet(jSpells, 1)); + } + } + // If we left the Quick Use widget on Special Abilities (10) or Items (11) goto level 0 + if(nLevelSelected == 10 || nLevelSelected == 11) + { + nLevelSelected = 0; + jSpells = JsonArraySet(jSpells, 1, JsonInt(0)); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER) nClassSelected = 1; + nClass = GetClassByPosition(nClassSelected, oAssociate); + int nMaxMemorizationSlots = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevelSelected); + jRow = JsonArray(); + for(nIndex = 0; nIndex < nMaxMemorizationSlots; nIndex++) + { + // This saves the index location of the spell in the list. + sIndex = IntToString(nIndex); + json jButton = NuiButtonImage(NuiBind("btn_memorized_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_memorized_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_memorized_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_memorized_" + sIndex + "_tooltip")); + //json jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + //json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + //jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + //jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_SPELL_MEMORIZE_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + string sText, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_SPELL_MEMORIZE_NUI, sName + " Spell Memorization Menu", + fX, fY, 375.0, 504.0 + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Set the Layout of the window. + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Row 1 & 2 Class & Level + int nSpellLevel, nIndexLevel, nMaxSpellLevel; + string sClass, sLevel, sLevelImage, sIndexLevel; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass != CLASS_TYPE_INVALID) + { + bCaster = StringToInt(Get2DAString("classes", "SpellCaster", nClass)); + if(bCaster) + { + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass)); + if(nClassSelected == nIndex) + { + int nClassLevel = GetLevelByClass(nClass, oAssociate); + string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); + int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); + for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++) + { + sIndexLevel = IntToString(nIndexLevel); + if(nIndexLevel < nMaxSpellLevel) + { + if(nIndexLevel == 0) sLevelImage = "ir_cantrips"; + else if(nIndexLevel < 7)sLevelImage = "ir_level" + sIndexLevel; + else sLevelImage = "ir_level789"; + if(nIndexLevel == 0) sLevel = " Cantrips"; + else if(nIndexLevel == 1) sLevel = " First level"; + else if(nIndexLevel == 2) sLevel = " Second level"; + else if(nIndexLevel == 3) sLevel = " Third level"; + else if(nIndexLevel == 4) sLevel = " Fourth level"; + else if(nIndexLevel == 5) sLevel = " Fifth level"; + else if(nIndexLevel == 6) sLevel = " Sixth level"; + else if(nIndexLevel == 7) sLevel = " Seventh level"; + else if(nIndexLevel == 8) sLevel = " Eighth level"; + else if(nIndexLevel == 9) sLevel = " Ninth level"; + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_tooltip", JsonString(" " + sLevel)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_image", JsonString(sLevelImage)); + } + else + { + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(FALSE)); + } + } + NuiSetBind(oPC, nToken, "btn_level_" + IntToString(nLevelSelected) + "_encouraged", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_class_" + IntToString(nClassSelected) + "_encouraged", JsonBool(TRUE)); + } + } + } + } + // Row 3 Spells + int nSpellSlot, nSpell, nMetamagic; + json jSpell; + json jWidget = JsonArrayGet(jSpells, 2); + nClass = GetClassByPosition(nClassSelected, oAssociate); + string sSpellIcon, sSpellName, sMetaMagicText; + json jSpellArray = JsonArray(); + json jSpell_Icon = JsonArray(); + json jSpell_Text = JsonArray(); + json jMetaMagic_Text = JsonArray(); + // List the spells they know from their spellbook. + if(Get2DAString("classes", "SpellbookRestricted", nClass) == "1") + { + int nMaxSpells = GetKnownSpellCount(oAssociate, nClass, nLevelSelected); + //WriteTimestampedLogEntry("Maxspells: " + IntToString(nMaxSpells) + + // " nClass: " + IntToString(nClass) + + // " nLevelSelected: " + IntToString(nLevelSelected)); + while(nSpellSlot < nMaxSpells) + { + nSpell = GetKnownSpellId(oAssociate, nClass, nLevelSelected, nSpellSlot); + if(nSpell != -1) + { + jSpellArray = JsonArrayInsert(jSpellArray, JsonInt(nSpell)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + //SendMessageToPC(oPC, "SpellBook: nSpell: " + IntToString(nSpell) + + // " sSpellIcon: " + sSpellIcon + + // " sSpellName: " + sSpellName+ + // " nMaxSpells: " + IntToString(nMaxSpells) + + // " nSpellSlot: " + IntToString(nSpellSlot)); + //sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nClass, nLevelSelected, nSpellSlot); + //jMetaMagic_Text = JsonArrayInsert(jMetaMagic_Text, JsonString(sMetaMagicText)); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + } + ++nSpellSlot; + } + } + // List the spells from the spells.2da file (they get to choose from them all!). + else + { + string sSpellTableColumn = Get2DAString("classes", "SpellTableColumn", nClass); + int nMaxSpells = Get2DARowCount("spells"); + while(nSpell < nMaxSpells) + { + sLevel = Get2DAString("spells", sSpellTableColumn, nSpell); + if(sLevel != "") + { + if(StringToInt(sLevel) == nLevelSelected) + { + jSpellArray = JsonArrayInsert(jSpellArray, JsonInt(nSpell)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + } + } + ++nSpell; + } + } + jData = JsonArrayInsert(jData, jSpellArray); + NuiSetUserData(oPC, nToken, jData); + NuiSetBind(oPC, nToken, "icon_spell", jSpell_Icon); + NuiSetBind(oPC, nToken, "text_spell", jSpell_Text); + NuiSetBind(oPC, nToken, "metamagic_text", jMetaMagic_Text); + // Row 4 Spell memorized list label. + // Row 5 Spell memorized List + int nMetaMagic, nDomain; + nIndex = 0; + while(nIndex < nMaxMemorizationSlots) + { + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(TRUE)); + if(GetMemorizedSpellId(oAssociate, nClass, nLevelSelected, nIndex) > -1) + { + nSpell = GetMemorizedSpellId(oAssociate, nClass, nLevelSelected, nIndex); + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + //nMetaMagic = 255; + //nDomain = 0; + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevelSelected) + ")")); + //sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, -1, -1, -1, nMetaMagic, nDomain); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + } + else + { + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString("")); + NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(FALSE)); + } + ++nIndex; + } +} +void ai_CreateSpellKnownNUI(object oPC, object oAssociate) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jRow = JsonArray(); + // Row 1 Classes************************************************************ 414 / 73 + int nClass, bCaster, nIndex; + string sIndex, sClassIcon, sLevelIcon; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass != CLASS_TYPE_INVALID) + { + if(StringToInt(Get2DAString("classes", "SpellbookRestricted", nClass))) + { + // This saves the class position in the button id so we can get it later. + sIndex = IntToString(nIndex); + sClassIcon = Get2DAString("classes", "Icon", nClass); + jRow = CreateButtonImage(jRow, sClassIcon, "btn_class_" + sIndex, 35.0f, 35.0f, 0.0, "btn_class_" + sIndex + "_tooltip"); + } + } + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Levels) ********************************************************** 414 / 116 + jRow = JsonArray(); + for(nIndex = 0; nIndex <= 9; nIndex++) + { + // This saves the level in the button id so we can get it later. + sIndex = IntToString(nIndex); + jRow = CreateButtonImage(jRow, "", "btn_level_" + sIndex, 35.0f, 35.0f, 0.0, "btn_level_" + sIndex + "_tooltip"); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Spell List)******************************************************* 414 / 398 + json jButton = JsonArray(); + jButton = NuiButton(NuiBind("text_spell")); + jButton = NuiId(jButton, "btn_text_spell"); + json jRectangle = NuiRect(4.0, 4.0, 27.0, 27.0); + json jDrawList = JsonArrayInsert(JsonArray(), NuiDrawListImage(JsonBool(TRUE), NuiBind("icon_spell"), jRectangle, JsonInt(NUI_ASPECT_FILL), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE))); + //jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + //json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_text")); + //jDrawList = JsonArrayInsert(jDrawList, jMetaMagic); + jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + json jListTemplate = JsonArrayInsert(JsonArray(), NuiListTemplateCell(jButton, 275.0, FALSE)); + json jInfo = NuiButtonImage(JsonString("gui_cg_qstn_mark")); + jInfo = NuiId(jInfo, "btn_info_spell"); + jListTemplate = JsonArrayInsert(jListTemplate, NuiListTemplateCell(jInfo, 35.0, FALSE)); + jRow = JsonArrayInsert(JsonArray(), NuiHeight(NuiList(jListTemplate, NuiBind("icon_spell"), 35.0), 282.0)); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (Widget Label)***************************************************** 414 / 426 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + CreateLabel(jRow, "Known Spell List", "lbl_spell_list", 150.0, 20.0, 0, 0, 0.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 (Memorize slots)*************************************************** 414 / 469 + // Get the class and level selected from the database. + int nClassSelected, nLevelSelected; + json jSpells; + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + // Temporary fix for error! :/ + if(JsonGetLength(jAIData) == 0) + { + ai_CheckAssociateData(oPC, oAssociate, sAssociateType, TRUE); + jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + } + if(JsonGetLength(jAIData) == 9) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(0)); + jAIData = JsonArrayInsert(jAIData, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + else + { + jSpells = JsonArrayGet(jAIData, 10); + if(JsonGetType(jSpells) == JSON_TYPE_NULL) + { + jSpells = JsonArray(); + jSpells = JsonArrayInsert(jSpells, JsonInt(1)); + jSpells = JsonArrayInsert(jSpells, JsonInt(0)); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + else + { + nClassSelected = JsonGetInt(JsonArrayGet(jSpells, 0)); + nLevelSelected = JsonGetInt(JsonArrayGet(jSpells, 1)); + } + } + // If we left the Quick Use widget on Special Abilities (10) or Items (11) goto level 0 + if(nLevelSelected == 10 || nLevelSelected == 11) + { + nLevelSelected = 0; + jSpells = JsonArraySet(jSpells, 1, JsonInt(0)); + jAIData = JsonArraySet(jAIData, 10, jSpells); + ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData); + } + if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER) nClassSelected = 1; + nClass = GetClassByPosition(nClassSelected, oAssociate); + jRow = JsonArray(); + for(nIndex = 0; nIndex < 10; nIndex++) + { + // This saves the index location of the spell in the list. + sIndex = IntToString(nIndex); + json jButton = NuiButtonImage(NuiBind("btn_known_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_known_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_known_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_known_" + sIndex + "_tooltip")); + //json jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + //json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + //jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + //jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Do the second row. + jRow = JsonArray(); + for(nIndex = 10; nIndex < 20; nIndex++) + { + // This saves the index location of the spell in the list. + sIndex = IntToString(nIndex); + json jButton = NuiButtonImage(NuiBind("btn_known_" + sIndex + "_image")); + jButton = NuiEnabled(jButton, NuiBind("btn_known_" + sIndex + "_event")); + jButton = NuiId(jButton, "btn_known_" + sIndex); + jButton = NuiWidth(NuiHeight(jButton, 35.0), 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind("btn_known_" + sIndex + "_tooltip")); + //json jRectangle = NuiRect(4.0, 4.0, 10.0, 10.0); + //json jMetaMagic = NuiDrawListText(JsonBool(TRUE), NuiColor(255, 255, 0), jRectangle, NuiBind("metamagic_" + sIndex + "_text")); + //jDrawList = JsonArrayInsert(JsonArray(), jMetaMagic); + //jButton = NuiDrawList(jButton, JsonBool(TRUE), jDrawList); + jRow = JsonArrayInsert(jRow, jButton); + } + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + float fX, fY; + json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations"); + jLocations = JsonObjectGet(jLocations, sAssociateType + AI_SPELL_KNOWN_NUI); + if(JsonGetType(jLocations) == JSON_TYPE_NULL) { fX = -1.0; fY = -1.0; } + else + { + fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + } + string sText, sName = GetName(oAssociate); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_SPELL_KNOWN_NUI, sName + " Spell Known Menu", + fX, fY, 375.0, 539.0 + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + // Set the Layout of the window. + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oAssociate))); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Row 1 & 2 Class & Level + int nSpellLevel, nIndexLevel, nMaxSpellLevel, nClassLevel; + string sClass, sLevel, sLevelImage, sIndexLevel, sSpellsGained; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass != CLASS_TYPE_INVALID) + { + bCaster = StringToInt(Get2DAString("classes", "SpellbookRestricted", nClass)); + if(bCaster) + { + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass)); + if(nClassSelected == nIndex) + { + nClassLevel = GetLevelByClass(nClass, oAssociate); + sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); + nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); + for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++) + { + sIndexLevel = IntToString(nIndexLevel); + if(nIndexLevel < nMaxSpellLevel) + { + if(nIndexLevel == 0) sLevelImage = "ir_cantrips"; + else if(nIndexLevel < 7)sLevelImage = "ir_level" + sIndexLevel; + else sLevelImage = "ir_level789"; + if(nIndexLevel == 0) sLevel = " Cantrips"; + else if(nIndexLevel == 1) sLevel = " First level"; + else if(nIndexLevel == 2) sLevel = " Second level"; + else if(nIndexLevel == 3) sLevel = " Third level"; + else if(nIndexLevel == 4) sLevel = " Fourth level"; + else if(nIndexLevel == 5) sLevel = " Fifth level"; + else if(nIndexLevel == 6) sLevel = " Sixth level"; + else if(nIndexLevel == 7) sLevel = " Seventh level"; + else if(nIndexLevel == 8) sLevel = " Eighth level"; + else if(nIndexLevel == 9) sLevel = " Ninth level"; + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_tooltip", JsonString(" " + sLevel)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_image", JsonString(sLevelImage)); + } + else + { + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_level_" + sIndexLevel + "_event", JsonBool(FALSE)); + } + } + NuiSetBind(oPC, nToken, "btn_level_" + IntToString(nLevelSelected) + "_encouraged", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_class_" + IntToString(nClassSelected) + "_encouraged", JsonBool(TRUE)); + } + } + } + } + // Row 3 Spells + int nSpellSlot, nSpell, nMetamagic; + json jSpell; + json jWidget = JsonArrayGet(jSpells, 2); + nClass = GetClassByPosition(nClassSelected, oAssociate); + string sSpellIcon, sSpellName, sMetaMagicText; + json jSpellArray = JsonArray(); + json jSpell_Icon = JsonArray(); + json jSpell_Text = JsonArray(); + json jMetaMagic_Text = JsonArray(); + // List the spells from the spells.2da file (they get to choose from them all!). + string sSpellTableColumn = Get2DAString("classes", "SpellTableColumn", nClass); + int nMaxSpells = Get2DARowCount("spells"); + while(nSpell < nMaxSpells) + { + sLevel = Get2DAString("spells", sSpellTableColumn, nSpell); + if(sLevel != "") + { + if(StringToInt(sLevel) == nLevelSelected) + { + jSpellArray = JsonArrayInsert(jSpellArray, JsonInt(nSpell)); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon)); + jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName)); + } + } + ++nSpell; + } + jData = JsonArrayInsert(jData, jSpellArray); + NuiSetUserData(oPC, nToken, jData); + NuiSetBind(oPC, nToken, "icon_spell", jSpell_Icon); + NuiSetBind(oPC, nToken, "text_spell", jSpell_Text); + NuiSetBind(oPC, nToken, "metamagic_text", jMetaMagic_Text); + // Row 4 Spell known list label. + // Row 5 Spell known List + int nMetaMagic, nDomain, nMaxKnownSlots; + json jClassList = GetLocalJson(oAssociate, AI_CLASS_LIST_JSON); + if(JsonGetType(jClassList) == JSON_TYPE_NULL) + { + jClassList = ObjectToJson(oAssociate); + jClassList = GffGetList(jClassList, "ClassList"); + SetLocalJson(oAssociate, AI_CLASS_LIST_JSON, jClassList); + } + // Get the correct class array. + nIndex = 0; + json jClass = JsonArrayGet(jClassList, nIndex); + while(JsonGetInt(GffGetInt(jClass, "Class")) != nClass) + { + jClass = JsonArrayGet(jClassList, ++nIndex); + } + json jKnownList = GffGetList(jClass, "KnownList" + IntToString(nLevelSelected)); + string sSpellKnownTable = Get2DAString("classes", "SpellKnownTable", nClass); + if(sSpellKnownTable != "") nMaxKnownSlots = StringToInt(Get2DAString(sSpellKnownTable, "SpellLevel" + IntToString(nLevelSelected), nClassLevel - 1)); + else nMaxKnownSlots = 20; + nIndex = 0; + while(nIndex < 20) + { + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(TRUE)); + if(nIndex < nMaxKnownSlots) + { + jSpell = JsonArrayGet(jKnownList, nIndex); + if(JsonGetType(jSpell) == JSON_TYPE_NULL) + { + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" Empty known spell slot")); + } + else + { + nSpell = JsonGetInt(GffGetWord(jSpell, "Spell")); + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + //nMetaMagic = 255; + //nDomain = 0; + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevelSelected) + ")")); + //sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, -1, -1, -1, nMetaMagic, nDomain); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText)); + } + } + else + { + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl")); + //NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString("")); + NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(FALSE)); + } + ++nIndex; + } +} +void ai_CreateDescriptionNUI(object oPC, json jSpell, int nSpell = 0) +{ + // Row 1 ******************************************************************* 500 / 469 + json jRow = CreateImage(JsonArray(), "", "spell_icon", NUI_ASPECT_FIT, NUI_HALIGN_CENTER, NUI_VALIGN_MIDDLE, 40.0, 40.0); + jRow = CreateTextBox(jRow, "spell_text", 380.0, 400.0, FALSE, NUI_SCROLLBARS_Y); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 1 ******************************************************************* 500 / 522 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "OK", "btn_ok", 150.0f, 45.0f); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sName, sIcon, sDescription; + int nFeat, nDescription; + int nClass; + if(nSpell) nClass = 0; + else + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + } + if(nClass == -1) + { + if(nSpell == SPELL_HEALINGKIT) + { + sName = "Healer's Kit"; + sIcon = "isk_heal"; + sDescription = GetStringByStrRef(1720); + } + else + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sIcon = Get2DAString("spells", "IconResRef", nSpell); + nDescription = StringToInt(Get2DAString("spells", "SpellDesc", nSpell)); + if(nDescription) sDescription = GetStringByStrRef(nDescription); + else + { + object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + sDescription = GetDescription(oItem); + } + } + } + else + { + nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nFeat) + { + if(nSpell) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sIcon = Get2DAString("spells", "IconResRef", nSpell); + } + else + { + sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))); + sIcon = Get2DAString("feat", "ICON", nFeat); + } + sDescription = GetStringByStrRef(StringToInt(Get2DAString("feat", "DESCRIPTION", nFeat))); + } + else + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sIcon = Get2DAString("spells", "IconResRef", nSpell); + nDescription = StringToInt(Get2DAString("spells", "SpellDesc", nSpell)); + if(nDescription) sDescription = GetStringByStrRef(nDescription); + else + { + object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + sDescription = GetDescription(oItem); + } + } + } + int nToken = SetWindow(oPC, jLayout, AI_SPELL_DESCRIPTION_NUI, sName, + -1.0, -1.0, 460.0f, 537.0 + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui"); + json jData = JsonArray(); + jData = JsonArrayInsert(jData, JsonString(ObjectToString(oPC))); + NuiSetUserData(oPC, nToken, jData); + // Row 1 + NuiSetBind(oPC, nToken, "spell_icon_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "spell_icon_image", JsonString(sIcon)); + NuiSetBind(oPC, nToken, "spell_text_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "spell_text", JsonString(sDescription)); + // Row 2 + NuiSetBind(oPC, nToken, "btn_ok_event", JsonBool(TRUE)); +} + diff --git a/src/module/nss/0i_menus_dm.nss b/src/module/nss/0i_menus_dm.nss new file mode 100644 index 0000000..a2a2cfc --- /dev/null +++ b/src/module/nss/0i_menus_dm.nss @@ -0,0 +1,1386 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_menus_dm +//////////////////////////////////////////////////////////////////////////////// + Include script for handling NUI menus for DMs. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "0i_associates" +string ai_GetRandomDMTip() +{ + int nRoll = Random(44); + return Get2DAString("ai_messages", "Text", nRoll); +} +void ai_SetDMWidgetButton(object oPlayer, int nButton, int bOn = TRUE) +{ + int nWidgetButtons = GetLocalInt(oPlayer, sDMWidgetButtonVarname); + string sName = ai_RemoveIllegalCharacters(GetName(oPlayer)); + json jButtons = ai_GetCampaignDbJson("buttons", sName, AI_DM_TABLE); + if(nWidgetButtons == 0) nWidgetButtons = JsonGetInt(JsonArrayGet(jButtons, 0)); + if(bOn) nWidgetButtons = nWidgetButtons | nButton; + else nWidgetButtons = nWidgetButtons & ~nButton; + SetLocalInt(oPlayer, sDMWidgetButtonVarname, nWidgetButtons); + jButtons = JsonArraySet(jButtons, 0, JsonInt(nWidgetButtons)); + ai_SetCampaignDbJson("buttons", jButtons, sName, AI_DM_TABLE); +} +int ai_GetDMWidgetButton(object oPlayer, int nButton) +{ + int nWidgetButtons = GetLocalInt(oPlayer, sDMWidgetButtonVarname); + if(nWidgetButtons == 0) + { + string sName = ai_RemoveIllegalCharacters(GetName(oPlayer)); + json jButtons = ai_GetCampaignDbJson("buttons", sName, AI_DM_TABLE); + nWidgetButtons = JsonGetInt(JsonArrayGet(jButtons, 0)); + } + return nWidgetButtons & nButton; +} +void ai_CreateDMWidgetNUI(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int bAIWidgetLock = ai_GetDMWidgetButton(oPC, BTN_DM_WIDGET_LOCK); + int bCmdGroup1 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP1); + int bCmdGroup2 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP2); + int bCmdGroup3 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP3); + int bCmdGroup4 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP4); + int bCmdGroup5 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP5); + int bCmdGroup6 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP6); + int bCmdCamera = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_CAMERA); + int bCmdInventory = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_INVENTORY); + // Get which buttons are activated. + float fHeight = 92.0f; + if(bAIWidgetLock) fHeight = 59.0f; + float fButtons, fWidth = 86.0f; + // ************************************************************************* Width / Height + // Row 1 (buttons)********************************************************** + // Setup the main associate button to use their portrait. + json jButton = NuiEnabled(NuiId (NuiButtonImage(NuiBind("btn_open_main_image")), "btn_open_main"), NuiBind("btn_open_main_event")); + jButton = NuiWidth(jButton, 35.0); + jButton = NuiHeight(jButton, 35.0); + jButton = NuiMargin(jButton, 0.0); + jButton = NuiTooltip(jButton, NuiBind ("btn_open_main_tooltip")); + jButton = NuiImageRegion(jButton, NuiRect(0.0, 0.0, 32.0, 35.0)); + json jRow = JsonArrayInsert(JsonArray(), jButton); + if(bCmdGroup1) + { + jRow = CreateButtonImage(jRow, "ir_level1", "btn_cmd_group1", 35.0f, 35.0f, 0.0, "btn_cmd_group1_tooltip"); + fButtons += 1.0; + } + if(bCmdGroup2) + { + jRow = CreateButtonImage(jRow, "ir_level2", "btn_cmd_group2", 35.0f, 35.0f, 0.0, "btn_cmd_group2_tooltip"); + fButtons += 1.0; + } + if(bCmdGroup3) + { + jRow = CreateButtonImage(jRow, "ir_level3", "btn_cmd_group3", 35.0f, 35.0f, 0.0, "btn_cmd_group3_tooltip"); + fButtons += 1.0; + } + if(bCmdGroup4) + { + jRow = CreateButtonImage(jRow, "ir_level4", "btn_cmd_group4", 35.0f, 35.0f, 0.0, "btn_cmd_group4_tooltip"); + fButtons += 1.0; + } + if(bCmdGroup5) + { + jRow = CreateButtonImage(jRow, "ir_level5", "btn_cmd_group5", 35.0f, 35.0f, 0.0, "btn_cmd_group5_tooltip"); + fButtons += 1.0; + } + if(bCmdGroup6) + { + jRow = CreateButtonImage(jRow, "ir_level6", "btn_cmd_group6", 35.0f, 35.0f, 0.0, "btn_cmd_group6_tooltip"); + fButtons += 1.0; + } + if(bCmdCamera) + { + jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip"); + fButtons += 1.0; + } + if(bCmdInventory) + { + jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip"); + fButtons += 1.0; + } + // Plug in buttons ********************************************************* + int nIndex, bWidget; + string sButton, sIcon; + json jPlugins = ai_UpdatePluginsForDM(oPC); + json jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bWidget) + { + sIcon = JsonGetString(JsonArrayGet(jPlugin, 3)); + sButton = IntToString(nIndex); + jRow = CreateButtonImage(jRow, sIcon, "btn_exe_plugin_" + sButton, 35.0f, 35.0f, 0.0, "btn_exe_plugin_" + sButton + "_tooltip"); + fButtons += 1.0; + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + if(fButtons > 1.0f) fWidth = fWidth + ((fButtons - 1.0) * 39.0f); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Get the window location to restore it from the database. + string sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + jLocations = JsonObjectGet(jLocations, "dm" + AI_WIDGET_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + if(bAIWidgetLock) + { + fX = fX + 4.0f; + fY = fY + 37.0f; + } + // Set the layout of the window. + json jLayout = NuiCol(jCol); + int nToken; + string sHeal, sText, sRange; + string sDisplayName = GetName(oPC); + if(GetStringRight(sDisplayName, 1) == "s") sDisplayName = sDisplayName + "'"; + else sDisplayName = sDisplayName + "'s"; + if(bAIWidgetLock) nToken = SetWindow(oPC, jLayout, "dm" + AI_WIDGET_NUI, sDisplayName + " Widget", fX, fY, fWidth + 8.0f, fHeight, FALSE, FALSE, FALSE, TRUE, FALSE, "0e_nui_dm"); + else nToken = SetWindow(oPC, jLayout, "dm" + AI_WIDGET_NUI, sDisplayName + " Widget", fX, fY, fWidth + 12.0f, fHeight, FALSE, FALSE, FALSE, TRUE, TRUE, "0e_nui_dm"); + // Set event watches for window inspector and save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set the buttons to show events. + NuiSetBind(oPC, nToken, "btn_open_main_image", JsonString(GetPortraitResRef(oPC) + "s")); + NuiSetBind(oPC, nToken, "btn_open_main_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_open_main_tooltip", JsonString(" " + sDisplayName + " widget menu")); + string sUUID, sText2, sSpeed; + string sAction = " (Left Action/Right Add)"; + if(bCmdGroup1) + { + NuiSetBind(oPC, nToken, "btn_cmd_group1_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP1"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 1"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group1_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdGroup2) + { + NuiSetBind(oPC, nToken, "btn_cmd_group2_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP2"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 2"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group2_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdGroup3) + { + NuiSetBind(oPC, nToken, "btn_cmd_group3_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP3"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 3"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group3_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdGroup4) + { + NuiSetBind(oPC, nToken, "btn_cmd_group4_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP4"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 4"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group4_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdGroup5) + { + NuiSetBind(oPC, nToken, "btn_cmd_group5_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP5"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 5"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group5_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdGroup6) + { + NuiSetBind(oPC, nToken, "btn_cmd_group6_event", JsonBool(TRUE)); + json jGroup = GetLocalJson(oPC, "DM_GROUP6"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 6"; sText2 = sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group6_tooltip", JsonString(" " + sText + sText2)); + } + if(bCmdCamera) + { + NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Select new object to have the camera view.")); + } + if(bCmdInventory) + { + NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString(" Open selected creatures inventory.")); + } + /*if(bSearch) + { + NuiSetBind(oPC, nToken, "btn_search_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_SEARCH)) sText = " Search On"; + else sText = " Search Off"; + NuiSetBind(oPC, nToken, "btn_search_tooltip", JsonString(sText)); + } + if(bStealth) + { + NuiSetBind(oPC, nToken, "btn_stealth_event", JsonBool(TRUE)); + if(ai_GetAIMode(oAssociate, AI_MODE_AGGRESSIVE_STEALTH)) sText = " Stealth On"; + else sText = " Stealth Off"; + NuiSetBind(oPC, nToken, "btn_stealth_tooltip", JsonString(sText)); + } */ + nIndex = 0; + string sScript; + jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + if(bWidget) + { + sButton = IntToString(nIndex); + sScript = JsonGetString(JsonArrayGet(jPlugin, 0)); + if(ResManGetAliasFor(sScript, RESTYPE_NCS) == "") + { + sText = " " + sScript + " not found by ResMan!"; + } + else sName = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_exe_plugin_" + sButton + "_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_exe_plugin_" + sButton + "_tooltip", JsonString(sName)); + } + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } +} +void ai_CreateDMOptionsNUI(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + int nMonsterAI = (ResManGetAliasFor("ai_default", RESTYPE_NCS) != ""); + int nAssociateAI = (ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != ""); + string sText = " [Single player]"; + if(AI_SERVER) sText = " [Server]"; + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, PHILOS_VERSION + sText, "lbl_version ", 510.0f, 20.0f, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 101 + jRow = CreateLabel(JsonArray(), "", "lbl_ai_info", 510.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 500 / 129 + jRow = CreateButton(JsonArray(), "Plugin Manager", "btn_plugin_manager", 160.0f, 20.0f, -1.0, "btn_plugin_manager_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Widget Manager", "btn_widget_manager", 160.0f, 20.0f, -1.0, "btn_widget_manager_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 500 / 157 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "SERVER RULES", "lbl_ai_rules", 100.0f, 20.0f, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 112.0; + // Row 5 ******************************************************************* 500 / --- (28) + // Make the AI options a Group. + json jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_max_henchman", 2, FALSE, 30.0f, 20.0f, "txt_max_henchman_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "Max number of henchmen that is allowed in your party.", "lbl_max_hench", 416.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_max_henchman_tooltip"); + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_xp_scale", 3, FALSE, 40.0f, 20.0f, "txt_xp_scale_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "Modules experience scale.", "lbl_xp_scale", 175.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_xp_scale_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " scale to party.", "chbx_party_scale", 130.0, 20.0, "chbx_party_scale_tooltip"); + jGroupRow = CreateButton(jGroupRow, "Default", "btn_default_xp", 70.0f, 20.0f, -1.0, "btn_default_xp_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 112.0; + if(nMonsterAI || nAssociateAI) + { + jGroupRow = CreateCheckBox(JsonArray(), " Creatures will use advanced combat movement.", "chbx_advanced_movement", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Use item level restrictions for creatures [Default is off].", "chbx_ilr", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Creatures can use the skill Use Magic Device.", "chbx_umd", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Creatures can use Healing kits.", "chbx_use_healingkits", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Moral checks, wounded creatures may flee during combat.", "chbx_moral", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), " Spells the AI will not use:", "lbl_restrict_spells", 190.0, 20.0, NUI_HALIGN_LEFT); + jGroupRow = CreateCheckBox(jGroupRow, " Darkness", "chbx_darkness", 90.0, 20.0, "chbx_darkness_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " Dispels", "chbx_dispels", 90.0, 20.0, "chbx_dispels_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, " Time Stop", "chbx_timestop", 90.0, 20.0, "chbx_timestop_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 168.0; + } + if(nMonsterAI) + { + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_ai_difficulty", 3, FALSE, 40.0f, 20.0f, "txt_ai_difficulty_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "% chance monsters will attack the weakest target.", "lbl_ai_difficulty", 406.0f, 20.0f, NUI_HALIGN_LEFT, 0, -1.0, "txt_ai_difficulty_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_perception_distance", 2, FALSE, 35.0f, 20.0f, "txt_perception_distance_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "meters is the distance a monster can respond to allies.", "lbl_perception_distance", 411.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "txt_perception_distance_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can prebuff before combat starts.", "chbx_buff_monsters", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can use summons before combat starts.", "chbx_buff_summons", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can use tactics (ambush, defensive, flanker, etc).", "chbx_ambush_monsters", 450.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "Add ", "lbl_inc_enc", 30.0, 20.0, NUI_HALIGN_LEFT, 0, -1.0); + jGroupRow = CreateTextEditBox(jGroupRow, "sPlaceHolder", "txt_inc_enc", 4, FALSE, 55.0f, 20.0f, "txt_inc_enc_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "monsters per spawned encounter monster.", "lbl_inc_enc", 357.0, 20.0, NUI_HALIGN_LEFT, NUI_VALIGN_MIDDLE, 0.0, "txt_inc_enc_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateTextEditBox(JsonArray(), "sPlaceHolder", "txt_inc_hp", 3, FALSE, 40.0f, 20.0f, "txt_inc_hp_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "% increase in all monster's hitpoints.", "lbl_inc_hp", 406.0, 20.0, NUI_HALIGN_LEFT); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "***** WARNING! The options below may break the module! *****", "lbl_warning", 450.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can wander upto ", "chbx_wander", 220.0, 20.0, "chbx_warning_tooltip"); + jGroupRow = CreateTextEditBox(jGroupRow, "sPlaceHolder", "txt_wander_distance", 2, FALSE, 35.0f, 20.0f, "chbx_warning_tooltip"); + jGroupRow = CreateLabel(jGroupRow, "meters and ", "lbl_wander_distance", 80.0f, 20.0f, NUI_HALIGN_LEFT, NUI_VALIGN_MIDDLE, 0.0, "chbx_warning_tooltip"); + jGroupRow = CreateCheckBox(jGroupRow, "open doors.", "chbx_open_doors", 100.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Monsters can summon companions.", "chbx_companions", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Summoned associates to remain after masters death.", "chbx_perm_assoc", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateCheckBox(JsonArray(), " Make enemy corpses remain.", "chbx_corpses_stay", 450.0, 20.0, "chbx_warning_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_perc_dist", 450.0f, 20.0f, NUI_HALIGN_LEFT, 0, 0.0, "lbl_perc_dist_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight += 364.0; + } + jRow = JsonArrayInsert(JsonArray(), NuiGroup(NuiCol(jGroupCol))); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + string sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + jLocations = JsonObjectGet(jLocations, "dm" + AI_MAIN_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, "dm" + AI_MAIN_NUI, sName + " PEPS Main Menu", + fX, fY, 534.0f, fHeight, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui_dm"); + // Save the associate to the nui for use in 0e_nui + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oPC))); + NuiSetUserData(oPC, nToken, jData); + object oModule = GetModule(); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 - Version label. + // Row 2 + int nUsing; + // Check the monster AI. + string sLocation = ResManGetAliasFor("ai_default", RESTYPE_NCS); + if(sLocation != "") + { + nUsing = TRUE; + string sLocation = ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS); + if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE; + if(nUsing) sText = "Monster AI working"; + else sText = "Monster AI not working"; + } + else sText = "Monster AI not loaded"; + // Check the associate AI. + sLocation = ResManGetAliasFor("ai_a_default", RESTYPE_NCS); + if(sLocation != "") + { + nUsing = TRUE; + string sLocation = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS); + if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE; + if(nUsing) sText += ", Associate AI working"; + else sText += ", Associate AI not working"; + } + else sText += ", Associate AI not loaded"; + // Check for PRC. + sLocation = ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS); + if(sLocation != "") sText += ", PRC loaded."; + else + { + // Check the player AI. + sLocation = ResManGetAliasFor("xx_pc_1_hb", RESTYPE_NCS); + if(sLocation != "") sText += ", Player AI loaded."; + else sText += ", Player AI not loaded."; + } + NuiSetBind(oPC, nToken, "lbl_ai_info_label", JsonString(sText)); + // Row 3 + NuiSetBind(oPC, nToken, "btn_plugin_manager_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_plugin_manager_tooltip", JsonString(" Manages external executable scripts.")); + NuiSetBind(oPC, nToken, "btn_widget_manager_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_manager_tooltip", JsonString(" Manages widgets the players have access to.")); + // Row 3 Label for AI RULES + // Row 4 + NuiSetBind(oPC, nToken, "txt_max_henchman_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_max_henchman", JsonString(IntToString(GetLocalInt(oModule, AI_RULE_MAX_HENCHMAN)))); + NuiSetBindWatch (oPC, nToken, "txt_max_henchman", TRUE); + NuiSetBind(oPC, nToken, "txt_max_henchman_tooltip", JsonString(" Set max number of henchman allowed (1-12).")); + NuiSetBind(oPC, nToken, "txt_xp_scale_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_xp_scale", JsonString(IntToString(GetModuleXPScale()))); + NuiSetBindWatch (oPC, nToken, "txt_xp_scale", TRUE); + NuiSetBind(oPC, nToken, "txt_xp_scale_tooltip", JsonString(" Set the modules XP scale (0 - 200) Normal D&D is 10.")); + NuiSetBind(oPC, nToken, "chbx_party_scale_check", JsonBool(GetLocalInt(oModule, AI_RULE_PARTY_SCALE))); + NuiSetBindWatch(oPC, nToken, "chbx_party_scale_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_party_scale_event", JsonBool(TRUE)); + sText = IntToString(GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP)); + NuiSetBind(oPC, nToken, "chbx_party_scale_tooltip", JsonString(" PEPS adjusts your XP based on party size from (" + sText + ").")); + NuiSetBind(oPC, nToken, "btn_default_xp_event", JsonBool(TRUE)); + sText = IntToString(GetLocalInt(oModule, AI_RULE_DEFAULT_XP_SCALE)); + NuiSetBind(oPC, nToken, "btn_default_xp_tooltip", JsonString(" Reset the Modules XP to (" + sText + ").")); + if(nMonsterAI) + { + NuiSetBind(oPC, nToken, "txt_ai_difficulty_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_ai_difficulty", JsonString(IntToString(GetLocalInt(oModule, AI_RULE_AI_DIFFICULTY)))); + NuiSetBindWatch(oPC, nToken, "txt_ai_difficulty", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_monsters_check", JsonBool(GetLocalInt(oModule, AI_RULE_BUFF_MONSTERS))); + NuiSetBindWatch(oPC, nToken, "chbx_buff_monsters_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_monsters_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_buff_summons_check", JsonBool(GetLocalInt(oModule, AI_RULE_PRESUMMON))); + NuiSetBindWatch(oPC, nToken, "chbx_buff_summons_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_summons_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_ambush_monsters_check", JsonBool(GetLocalInt(oModule, AI_RULE_AMBUSH))); + NuiSetBindWatch(oPC, nToken, "chbx_ambush_monsters_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ambush_monsters_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_companions_check", JsonBool(GetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS))); + NuiSetBindWatch(oPC, nToken, "chbx_companions_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_companions_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_companions_tooltip", JsonString(" ** This will break some modules! ** See Readme for issues!")); + NuiSetBind(oPC, nToken, "chbx_perm_assoc_check", JsonBool(GetLocalInt(oModule, AI_RULE_PERM_ASSOC))); + NuiSetBindWatch(oPC, nToken, "chbx_perm_assoc_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_perm_assoc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_corpses_stay_check", JsonBool(GetLocalInt(oModule, AI_RULE_CORPSES_STAY))); + NuiSetBindWatch(oPC, nToken, "chbx_corpses_stay_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_corpses_stay_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_corpses_stay_tooltip", JsonString(" ** This will break some modules! ** See Readme for issues!")); + NuiSetBind(oPC, nToken, "txt_perception_distance_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_perception_distance", JsonString(FloatToString(GetLocalFloat(oModule, AI_RULE_PERCEPTION_DISTANCE), 0, 0))); + NuiSetBindWatch(oPC, nToken, "txt_perception_distance", TRUE); + NuiSetBind(oPC, nToken, "txt_perception_distance_tooltip", JsonString(" Range [10 to 60 meters] from the player.")); + NuiSetBindWatch(oPC, nToken, "lbl_perc_dist", TRUE); + int nPercDist = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE); + if(nPercDist < 8 || nPercDist > 11) + { + nPercDist = 11; + SetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE, 11); + } + if(nPercDist == 8) sText = " Monster perception: Short [10 Sight / 10 Listen]"; + else if(nPercDist == 9) sText = " Monster perception: Medium [20 Sight / 20 Listen]"; + else if(nPercDist == 10) sText = " Monster perception: Long [35 Sight / 20 Listen]"; + else sText = " Monster perception: Default [Monster's default values]"; + NuiSetBind(oPC, nToken, "lbl_perc_dist_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "lbl_perc_dist_tooltip", JsonString(" Use the mouse wheel to change values.")); + int bWander = GetLocalInt(oModule, AI_RULE_WANDER); + NuiSetBind(oPC, nToken, "chbx_wander_check", JsonBool(bWander)); + NuiSetBindWatch(oPC, nToken, "chbx_wander_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_wander_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_wander_distance_event", JsonBool(bWander)); + NuiSetBind(oPC, nToken, "txt_wander_distance", JsonString(FloatToString(GetLocalFloat(oModule, AI_RULE_WANDER_DISTANCE), 0, 0))); + NuiSetBindWatch(oPC, nToken, "txt_wander_distance", TRUE); + NuiSetBind(oPC, nToken, "chbx_wander_tooltip", JsonString(" ** This will break some modules! ** See Readme for issues!")); + NuiSetBind(oPC, nToken, "chbx_open_doors_check", JsonBool(GetLocalInt(oModule, AI_RULE_OPEN_DOORS))); + NuiSetBindWatch(oPC, nToken, "chbx_open_doors_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_open_doors_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_open_doors_tooltip", JsonString(" This allows monsters to open doors to hunt you down!")); + NuiSetBind(oPC, nToken, "txt_inc_enc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_inc_enc_tooltip", JsonString(" Spawns one extra monster per counter above 1. Adds value to counter per encounter monster spawned.")); + NuiSetBind(oPC, nToken, "txt_inc_enc", JsonString(FloatToString(GetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS), 0, 2))); + NuiSetBindWatch(oPC, nToken, "txt_inc_enc", TRUE); + NuiSetBind(oPC, nToken, "txt_inc_hp_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_inc_hp", JsonString(IntToString(GetLocalInt(oModule, AI_INCREASE_MONSTERS_HP)))); + NuiSetBindWatch(oPC, nToken, "txt_inc_hp", TRUE); + } + if(nMonsterAI || nAssociateAI) + { + NuiSetBind(oPC, nToken, "chbx_moral_check", JsonBool(GetLocalInt(oModule, AI_RULE_MORAL_CHECKS))); + NuiSetBindWatch (oPC, nToken, "chbx_moral_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_moral_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_advanced_movement_check", JsonBool(GetLocalInt(oModule, AI_RULE_ADVANCED_MOVEMENT))); + NuiSetBindWatch (oPC, nToken, "chbx_advanced_movement_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_advanced_movement_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_ilr_check", JsonBool(GetLocalInt(oModule, AI_RULE_ILR))); + NuiSetBindWatch (oPC, nToken, "chbx_ilr_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ilr_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_umd_check", JsonBool(GetLocalInt(oModule, AI_RULE_ALLOW_UMD))); + NuiSetBindWatch (oPC, nToken, "chbx_umd_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_umd_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_use_healingkits_check", JsonBool(GetLocalInt(oModule, AI_RULE_HEALERSKITS))); + NuiSetBindWatch (oPC, nToken, "chbx_use_healingkits_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_use_healingkits_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_darkness_check", JsonBool(ai_SpellRestricted(SPELL_DARKNESS))); + NuiSetBindWatch (oPC, nToken, "chbx_darkness_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_darkness_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_darkness_tooltip", JsonString(" AI will not use the Darkness spell in combat.")); + NuiSetBind(oPC, nToken, "chbx_dispels_check", JsonBool(ai_SpellRestricted(SPELL_DISPEL_MAGIC))); + NuiSetBindWatch (oPC, nToken, "chbx_dispels_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_dispels_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_dispels_tooltip", JsonString(" AI will not use any of the Dispel spells in combat.")); + NuiSetBind(oPC, nToken, "chbx_timestop_check", JsonBool(ai_SpellRestricted(SPELL_TIME_STOP))); + NuiSetBindWatch (oPC, nToken, "chbx_timestop_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_timestop_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_timestop_tooltip", JsonString(" AI will not use the Time Stop spell in combat.")); + } +} +void ai_CreateDMCommandNUI(object oPC) +{ + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 73 + json jRow = CreateButtonSelect(JsonArray(), "Lock Widget", "btn_widget_lock", 200.0, 20.0, "btn_widget_lock_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_1", 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Main Menu", "btn_main_menu", 200.0, 20.0, -1.0, "btn_main_menu_tooltip"); + jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0); + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 101 + jRow = CreateButton(JsonArray(), "", "btn_cmd_group1", 200.0, 20.0, -1.0, "btn_cmd_group1_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group1", 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "", "btn_cmd_group2", 200.0, 20.0, -1.0, "btn_cmd_group2_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group2", 25.0, 20.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 500 / 129 + jRow = CreateButton(JsonArray(), "", "btn_cmd_group3", 200.0, 20.0, -1.0, "btn_cmd_group3_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group3", 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "", "btn_cmd_group4", 200.0, 20.0, -1.0, "btn_cmd_group4_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group4", 25.0, 20.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 500 / 157 + jRow = CreateButton(JsonArray(), "", "btn_cmd_group5", 200.0, 20.0, -1.0, "btn_cmd_group5_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group5", 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "", "btn_cmd_group6", 200.0, 20.0, -1.0, "btn_cmd_group6_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_group6", 25.0, 20.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 157.0; + // Row 5 ******************************************************************* 500 / --- + jRow = CreateButton(JsonArray(), "Toggle Camera Focus", "btn_camera", 200.0, 20.0, -1.0, "btn_camera_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_camera", 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Open/Close Inventory", "btn_inventory", 200.0, 20.0, -1.0, "btn_inventory_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_inventory", 25.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + // Row 6+ ****************************************************************** 500 / --- + json jDMPlugins = ai_UpdatePluginsForDM(oPC); + // Set the plugins the dm can use. + int nIndex; + string sButton, sName; + json jPlugin = JsonArrayGet(jDMPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(JsonArray(), sName, "btn_plugin_" + sButton, 200.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0, "chbx_plugin_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jPlugin = JsonArrayGet(jDMPlugins, ++nIndex); + if(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(jRow, sName, "btn_plugin_" + sButton, 200.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0, "chbx_plugin_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + else + { + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + break; + } + jPlugin = JsonArrayGet(jDMPlugins, ++nIndex); + } + // Row 7 ****************************************************************** 500 / --- + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "", "lbl_info_1", 475.0, 20.0, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight = fHeight + 28.0; + // Get the window location to restore it from the database. + sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + jLocations = JsonObjectGet(jLocations, "dm" + AI_COMMAND_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sDMName = GetName(oPC); + if(GetStringRight(sDMName, 1) == "s") sDMName = sDMName + "'"; + else sDMName = sDMName + "'s"; + int nToken = SetWindow(oPC, jLayout, "dm" + AI_COMMAND_NUI, sDMName + " Command Menu", + fX, fY, 500.0, fHeight + 12.0, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui_dm"); + // Get which buttons are activated. + int bAIWidgetLock = ai_GetDMWidgetButton(oPC, BTN_DM_WIDGET_LOCK); + int bCmdGroup1 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP1); + int bCmdGroup2 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP2); + int bCmdGroup3 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP3); + int bCmdGroup4 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP4); + int bCmdGroup5 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP5); + int bCmdGroup6 = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_GROUP6); + int bCmdCamera = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_CAMERA); + int bCmdInventory = ai_GetDMWidgetButton(oPC, BTN_DM_CMD_INVENTORY); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set all binds, events, and watches. + // Row 1 + NuiSetBind(oPC, nToken, "btn_widget_lock_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_widget_lock", JsonBool(bAIWidgetLock)); + NuiSetBind(oPC, nToken, "btn_widget_lock_tooltip", JsonString( + " Locks widget to the current location.")); + NuiSetBind(oPC, nToken, "btn_main_menu_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_main_menu", JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_main_menu_tooltip", JsonString(" Server menu options")); + NuiSetBind(oPC, nToken, "btn_group_options_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_group_options", JsonInt(TRUE)); + //NuiSetBind(oPC, nToken, "btn_empty_button_event", JsonBool (TRUE)); + //NuiSetBind(oPC, nToken, "btn_empty_button", JsonInt(TRUE)); + //sText = " Copy AI and command settings for one creature to others."; + //NuiSetBind(oPC, nToken, "btn_empty_button_tooltip", JsonString(sText)); + // Row 2 + NuiSetBind(oPC, nToken, "chbx_cmd_group1_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group1_check", JsonBool (bCmdGroup1)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group1_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group1_event", JsonBool (TRUE)); + string sText, sText2, sSpeed; + string sAction = " (Left Action/Right Add)"; + json jGroup = GetLocalJson(oPC, "DM_GROUP1"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + string sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 1"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group1_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group1_tooltip", JsonString(" " + sText2)); + NuiSetBind(oPC, nToken, "chbx_cmd_group2_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group2_check", JsonBool (bCmdGroup2)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group2_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group2_event", JsonBool (TRUE)); + jGroup = GetLocalJson(oPC, "DM_GROUP2"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 2"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group2_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group2_tooltip", JsonString(" " + sText2)); + // Row 3 + NuiSetBind(oPC, nToken, "chbx_cmd_group3_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group3_check", JsonBool (bCmdGroup3)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group3_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group3_event", JsonBool (TRUE)); + jGroup = GetLocalJson(oPC, "DM_GROUP3"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 3"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group3_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group3_tooltip", JsonString(" " + sText2)); + NuiSetBind(oPC, nToken, "chbx_cmd_group4_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group4_check", JsonBool (bCmdGroup4)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group4_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group4_event", JsonBool (TRUE)); + jGroup = GetLocalJson(oPC, "DM_GROUP4"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 4"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group4_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group4_tooltip", JsonString(" " + sText2)); + // Row 4 + NuiSetBind(oPC, nToken, "chbx_cmd_group5_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group5_check", JsonBool (bCmdGroup5)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group5_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group5_event", JsonBool (TRUE)); + jGroup = GetLocalJson(oPC, "DM_GROUP5"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 5"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group5_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group5_tooltip", JsonString(" " + sText2)); + NuiSetBind(oPC, nToken, "chbx_cmd_group6_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_cmd_group6_check", JsonBool (bCmdGroup6)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_group6_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cmd_group6_event", JsonBool (TRUE)); + jGroup = GetLocalJson(oPC, "DM_GROUP6"); + if(JsonGetInt(JsonArrayGet(jGroup, 0)) == 0) sSpeed = " [Walk]"; + else sSpeed = " [Run]"; + sUUID = JsonGetString(JsonArrayGet(jGroup, 1)); + if(sUUID == "") { sText = "Group 6"; sText2 = sText + sAction; } + else { sText = GetName(GetObjectByUUID(sUUID)) + "'s group"; sText2 = sText + sSpeed; } + NuiSetBind(oPC, nToken, "btn_cmd_group6_label", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_cmd_group6_tooltip", JsonString(" " + sText2)); + // Row 5 + NuiSetBind(oPC, nToken, "chbx_camera_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_camera_check", JsonBool (bCmdCamera)); + NuiSetBindWatch (oPC, nToken, "chbx_camera_check", TRUE); + NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString ( + " Toggle camera view for " + sDMName)); + NuiSetBind(oPC, nToken, "chbx_inventory_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "chbx_inventory_check", JsonBool (bCmdInventory)); + NuiSetBindWatch (oPC, nToken, "chbx_inventory_check", TRUE); + NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString ( + " Open " + sDMName + " inventory")); + // Row 6+ + nIndex = 0; + int bWidget; + jPlugin = JsonArrayGet(jDMPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_event", JsonBool(TRUE)); + bWidget = JsonGetInt(JsonArrayGet(jPlugin, 1)); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_check", JsonBool(bWidget)); + NuiSetBindWatch (oPC, nToken, "chbx_plugin_" + sButton + "_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_event", JsonBool(TRUE)); + sText = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_tooltip", JsonString(sText)); + jPlugin = JsonArrayGet(jDMPlugins, ++nIndex); + } + NuiSetBind(oPC, nToken, "chbx_plugin_tooltip", JsonString(" Adds the plugin to your widget.")); + // Row 7 + sText = ai_GetRandomDMTip(); + NuiSetBind(oPC, nToken, "lbl_info_1_label", JsonString(sText)); +} +void ai_CreateDMPluginManagerNUI(object oPC) +{ + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // Row 1 ******************************************************************* 500 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Load All Plugins", "btn_load_plugins", 150.0f, 20.0f, -1.0, "btn_load_plugins_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Check All", "btn_check_plugins", 150.0f, 20.0f, -1.0, "btn_check_plugins_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear All", "btn_clear_plugins", 150.0f, 20.0f, -1.0, "btn_clear_plugins_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 101 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Add Plugin", "btn_add_plugin", 150.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateTextEditBox(jRow, "sPlaceHolder", "txt_plugin", 16, FALSE, 310.0f, 20.0f, "txt_plugin_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 101.0; + // Row 3+ ****************************************************************** 500 / --- + json jPlugins = ai_GetCampaignDbJson("plugins"); + int nIndex = 0; + json jPlugin = JsonArrayGet(jPlugins, nIndex); + string sName, sButton; + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Remove Plugin", "btn_remove_plugin_" + sButton, 150.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + sName = JsonGetString(JsonArrayGet(jPlugin, 2)); + jRow = CreateButton(jRow, sName, "btn_plugin_" + sButton, 290.0f, 20.0f, -1.0, "btn_plugin_" + sButton + "_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_plugin_" + sButton, 25.0, 20.0); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + // Get the window location to restore it from the database. + sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + jLocations = JsonObjectGet(jLocations, "dm" + AI_PLUGIN_NUI); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, "dm" + AI_PLUGIN_NUI, sName + " PEPS Plugin Manager", + fX, fY, 500.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui_dm"); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Row 1 + NuiSetBind(oPC, nToken, "btn_load_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_load_plugins_tooltip", JsonString(" Load all known PEPS plugins that are in the game files.")); + NuiSetBind(oPC, nToken, "btn_check_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_check_plugins_tooltip", JsonString(" Add all plugins to the players widget.")); + NuiSetBind(oPC, nToken, "btn_clear_plugins_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_plugins_tooltip", JsonString(" Remove all plugins from the players widget.")); + // Row 2 + NuiSetBind(oPC, nToken, "btn_add_plugin_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_plugin_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_plugin_tooltip", JsonString(" Enter an executable script name.")); + // Row 3+ + nIndex = 0; + int bCheck; + string sText; + jPlugin = JsonArrayGet(jPlugins, nIndex); + while(JsonGetType(jPlugin) != JSON_TYPE_NULL) + { + sButton = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_remove_plugin_" + sButton + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_event", JsonBool(TRUE)); + bCheck = JsonGetInt(JsonArrayGet(jPlugin, 1)); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_check", JsonBool(bCheck)); + NuiSetBind(oPC, nToken, "chbx_plugin_" + sButton + "_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_plugin_" + sButton + "_check", TRUE); + sText = " " + JsonGetString(JsonArrayGet(jPlugin, 2)); + NuiSetBind(oPC, nToken, "btn_plugin_" + sButton + "_tooltip", JsonString(sText)); + jPlugin = JsonArrayGet(jPlugins, ++nIndex); + } + NuiSetBind(oPC, nToken, "chbx_plugin_tooltip", JsonString(" Allows players to use this plugin.")); +} +void ai_CreateDMWidgetManagerNUI(object oPC) +{ + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // Row 1 ******************************************************************* 575 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Check All", "btn_check_buttons", 150.0f, 20.0f, -1.0, "btn_check_buttons_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear All", "btn_clear_buttons", 150.0f, 20.0f, -1.0, "btn_clear_buttons_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 575 / 96 + jRow = CreateLabel(JsonArray(), "This menu manages the PEPS buttons a player may have access to.", "lbl_info1", 636.0, 15.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 575 / 119 + jRow = CreateLabel(JsonArray(), "Having a check next to a button will remove that button from the players menus.", "lbl_info2", 636.0, 15.0); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 575 / 162 + jRow = CreateButtonImage(JsonArray(), "ir_action", "btn_cmd_action", 35.0f, 35.0f, 0.0, "btn_cmd_action_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_action", 25.0, 20.0, "btn_cmd_action_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_guard", "btn_cmd_guard", 35.0f, 35.0f, 0.0, "btn_cmd_guard_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_guard", 25.0, 20.0, "btn_cmd_guard_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_standground", "btn_cmd_hold", 35.0f, 35.0f, 0.0, "btn_cmd_hold_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_hold", 25.0, 20.0, "btn_cmd_hold_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_attacknearest", "btn_cmd_attack", 35.0f, 35.0f, 0.0, "btn_cmd_attack_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_attack", 25.0, 20.0, "btn_cmd_attack_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_follow", "btn_cmd_follow", 35.0f, 35.0f, 0.0, "btn_cmd_follow_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_follow", 25.0, 20.0, "btn_cmd_follow_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_dmchat", "btn_follow_target", 35.0f, 35.0f, 0.0, "btn_follow_target_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_follow_target", 25.0, 20.0, "btn_follow_target_tooltip"); + + jRow = CreateButtonImage(jRow, "ife_foc_search", "btn_cmd_search", 35.0f, 35.0f, 0.0, "btn_cmd_search_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_search", 25.0, 20.0, "btn_cmd_search_tooltip"); + + jRow = CreateButtonImage(jRow, "ife_foc_hide", "btn_cmd_stealth", 35.0f, 35.0f, 0.0, "btn_cmd_stealth_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_stealth", 25.0, 20.0, "btn_cmd_stealth_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_scommand", "btn_cmd_ai_script", 35.0f, 35.0f, 0.0, "btn_cmd_ai_script_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_ai_script", 25.0, 20.0, "btn_cmd_ai_script_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_settrap", "btn_cmd_place_trap", 35.0f, 35.0f, 0.0, "btn_cmd_place_trap_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cmd_place_trap", 25.0, 20.0, "btn_cmd_place_trap_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 ******************************************************************* 575 / 205 + jRow = CreateButtonImage(JsonArray(), "isk_spellcraft", "btn_quick_widget", 35.0f, 35.0f, 0.0, "btn_quick_widget_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_quick_widget", 25.0, 20.0, "btn_quick_widget_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_lore", "btn_spell_memorize", 35.0f, 35.0f, 0.0, "btn_spell_memorize_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_spell_memorize", 25.0, 20.0, "btn_spell_memorize_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_cantrips", "btn_buff_short", 35.0f, 35.0f, 0.0, "btn_buff_short_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_short", 25.0, 20.0, "btn_buff_short_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_cast", "btn_buff_long", 35.0f, 35.0f, 0.0, "btn_buff_long_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_long", 25.0, 20.0, "btn_buff_long_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_level789", "btn_buff_all", 35.0f, 35.0f, 0.0, "btn_buff_all_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_all", 25.0, 20.0, "btn_buff_all_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_rest", "btn_buff_rest", 35.0f, 35.0f, 0.0, "btn_buff_rest_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_buff_rest", 25.0, 20.0, "btn_buff_rest_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_jump", "btn_jump_to", 35.0f, 35.0f, 0.0, "btn_jump_to_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_jump_to", 25.0, 20.0, "btn_jump_to_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_limbo", "btn_ghost_mode", 35.0f, 35.0f, 0.0, "btn_ghost_mode_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ghost_mode", 25.0, 20.0, "btn_ghost_mode_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_camera", 25.0, 20.0, "btn_camera_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_inventory", 25.0, 20.0, "btn_inventory_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 6 ******************************************************************* 575 / 248 + + jRow = CreateButtonImage(JsonArray(), "ife_familiar", "btn_familiar", 35.0f, 35.0f, 0.0, "btn_familiar_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_familiar", 25.0, 20.0, "btn_familiar_tooltip"); + + jRow = CreateButtonImage(jRow, "ife_animal", "btn_companion", 35.0f, 35.0f, 0.0, "btn_companion_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_companion", 25.0, 20.0, "btn_companion_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_ai", "btn_ai", 35.0f, 35.0f, 0.0, "btn_ai_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ai", 25.0, 20.0, "btn_companion_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_movsilent", "btn_quiet", 35.0f, 35.0f, 0.0, "btn_quiet_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_quiet", 25.0, 20.0, "btn_quiet_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_archer", "btn_ranged", 35.0f, 35.0f, 0.0, "btn_ranged_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ranged", 25.0, 20.0, "btn_ranged_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_takeitem", "btn_equip_weapon", 35.0f, 35.0f, 0.0, "btn_equip_weapon_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_equip_weapon", 25.0, 20.0, "btn_equip_weapon_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_search", "btn_search", 35.0f, 35.0f, 0.0, "btn_search_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_search", 25.0, 20.0, "btn_search_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_hide", "btn_stealth", 35.0f, 35.0f, 0.0, "btn_stealth_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_stealth", 25.0, 20.0, "btn_stealth_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_open", "btn_open_door", 35.0f, 35.0f, 0.0, "btn_open_door_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_open_door", 25.0, 20.0, "btn_open_door_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_distrap", "btn_traps", 35.0f, 35.0f, 0.0, "btn_traps_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_traps", 25.0, 20.0, "btn_traps_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 7 ******************************************************************* 575 / 291 + + jRow = CreateButtonImage(JsonArray(), "isk_olock", "btn_pick_locks", 35.0f, 35.0f, 0.0, "btn_pick_locks_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_pick_locks", 25.0, 20.0, "btn_pick_locks_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_bash", "btn_bash_locks", 35.0f, 35.0f, 0.0, "btn_bash_locks_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_bash_locks", 25.0, 20.0, "btn_bash_locks_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_control", "btn_magic_level", 35.0f, 35.0f, 0.0, "btn_magic_level_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic_level", 25.0, 20.0, "btn_magic_level_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_xability", "btn_spontaneous", 35.0f, 35.0f, 0.0, "btn_spontaneous_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_spontaneous", 25.0, 20.0, "btn_spontaneous_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_cntrspell", "btn_magic", 35.0f, 35.0f, 0.0, "btn_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic", 25.0, 20.0, "btn_magic_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_moreattacks", "btn_magic_items", 35.0f, 35.0f, 0.0, "btn_magic_items_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_magic_items", 25.0, 20.0, "btn_magic_items_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_orisons", "btn_def_magic", 35.0f, 35.0f, 0.0, "btn_def_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_def_magic", 25.0, 20.0, "btn_def_magic_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_metamagic", "btn_off_magic", 35.0f, 35.0f, 0.0, "btn_off_magic_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_off_magic", 25.0, 20.0, "btn_off_magic_tooltip"); + + jRow = CreateButtonImage(jRow, "isk_heal", "btn_heal_out", 35.0f, 35.0f, 0.0, "btn_heal_out_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heal_out", 25.0, 20.0, "btn_heal_out_tooltip"); + + jRow = CreateButtonImage(jRow, "dm_heal", "btn_heal_in", 35.0f, 35.0f, 0.0, "btn_heal_in_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heal_in", 25.0, 20.0, "btn_heal_in_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 8 ******************************************************************* 575 / 334 + jRow = CreateButtonImage(JsonArray(), "ir_heal", "btn_heals_onoff", 35.0f, 35.0f, 0.0, "btn_heals_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_heals_onoff", 25.0, 20.0, "btn_heals_onoff_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_party", "btn_healp_onoff", 35.0f, 35.0f, 0.0, "btn_healp_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_healp_onoff", 25.0, 20.0, "btn_healp_onoff_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_accept", "btn_cure_onoff", 35.0f, 35.0f, 0.0, "btn_cure_onoff_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_cure_onoff", 25.0, 20.0, "btn_cure_onoff_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_barter", "btn_loot", 35.0f, 35.0f, 0.0, "btn_loot_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_loot", 25.0, 20.0, "btn_loot_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_ignore", "btn_ignore_assoc", 35.0f, 35.0f, 0.0, "btn_ignore_assoc_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ignore_assoc", 25.0, 20.0, "btn_ignore_assoc_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_abort", "btn_ignore_traps", 35.0f, 35.0f, 0.0, "btn_ignore_traps_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_ignore_traps", 25.0, 20.0, "btn_ignore_traps_tooltip"); + + jRow = CreateButtonImage(jRow, "ir_dmchat", "btn_perc_range", 35.0f, 35.0f, 0.0, "btn_perc_range_tooltip"); + jRow = CreateCheckBox(jRow, "", "chbx_perc_range", 25.0, 20.0, "btn_perc_range_tooltip"); + + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 334.0; + // Get the window location to restore it from the database. + string sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + jLocations = JsonObjectGet(jLocations, "dm_widget_manager_nui"); + float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); + float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, "dm_widget_manager_nui", sName + " PEPS DM Widget Manager", + fX, fY, 660.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "0e_nui_dm"); + // Set event watches for save window location. + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Row 1 + NuiSetBind(oPC, nToken, "btn_check_buttons_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_check_buttons_tooltip", JsonString(" Check all buttons, removing them for all players.")); + NuiSetBind(oPC, nToken, "btn_clear_buttons_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_buttons_tooltip", JsonString(" Clear all buttons, allowing use for all players.")); + // Row 2 & 3 Labels. + // Load all the buttons states. + //int bAIWidgetLock = ai_GetDMWAccessButton(BTN_WIDGET_LOCK); + int bCmdAction = ai_GetDMWAccessButton(BTN_CMD_ACTION); + int bCmdGuard = ai_GetDMWAccessButton(BTN_CMD_GUARD); + int bCmdHold = ai_GetDMWAccessButton(BTN_CMD_HOLD); + int bCmdSearch = ai_GetDMWAccessButton(BTN_CMD_SEARCH); + int bCmdStealth = ai_GetDMWAccessButton(BTN_CMD_STEALTH); + int bCmdAttack = ai_GetDMWAccessButton(BTN_CMD_ATTACK); + int bCmdFollow = ai_GetDMWAccessButton(BTN_CMD_FOLLOW); + int bCmdAIScript = ai_GetDMWAccessButton(BTN_CMD_AI_SCRIPT); + int bCmdPlacetrap = ai_GetDMWAccessButton(BTN_CMD_PLACE_TRAP); + int bSpellWidget = ai_GetDMWAccessButton(BTN_CMD_SPELL_WIDGET); + int bMemorizeSpells = ai_GetDMWAccessButton(BTN_DM_CMD_MEMORIZE); + int bBuffShort = ai_GetDMWAccessButton(BTN_BUFF_SHORT); + int bBuffLong = ai_GetDMWAccessButton(BTN_BUFF_LONG); + int bBuffAll = ai_GetDMWAccessButton(BTN_BUFF_ALL); + int bBuffRest = ai_GetDMWAccessButton(BTN_BUFF_REST); + int bJumpTo = ai_GetDMWAccessButton(BTN_CMD_JUMP_TO); + int bGhostMode = ai_GetDMWAccessButton(BTN_CMD_GHOST_MODE); + int bCamera = ai_GetDMWAccessButton(BTN_CMD_CAMERA); + int bInventory = ai_GetDMWAccessButton(BTN_CMD_INVENTORY); + int bFamiliar = ai_GetDMWAccessButton(BTN_CMD_FAMILIAR); + int bCompanion = ai_GetDMWAccessButton(BTN_CMD_COMPANION); + int bFollowTarget = ai_GetDMAIAccessButton(BTN_AI_FOLLOW_TARGET); + int bAI = ai_GetDMAIAccessButton(BTN_AI_FOR_PC); + int bReduceSpeech = ai_GetDMAIAccessButton(BTN_AI_REDUCE_SPEECH); + int bRanged = ai_GetDMAIAccessButton(BTN_AI_USE_RANGED); + int bEquipWeapons = ai_GetDMAIAccessButton(BTN_AI_STOP_WEAPON_EQUIP); + int bSearch = ai_GetDMAIAccessButton(BTN_AI_USE_SEARCH); + int bStealth = ai_GetDMAIAccessButton(BTN_AI_USE_STEALTH); + int bOpenDoors = ai_GetDMAIAccessButton(BTN_AI_OPEN_DOORS); + int bTraps = ai_GetDMAIAccessButton(BTN_AI_REMOVE_TRAPS); + int bPickLocks = ai_GetDMAIAccessButton(BTN_AI_PICK_LOCKS); + int bBashLocks = ai_GetDMAIAccessButton(BTN_AI_BASH_LOCKS); + int bMagicLevel = ai_GetDMAIAccessButton(BTN_AI_MAGIC_LEVEL); + int bSpontaneous = ai_GetDMAIAccessButton(BTN_AI_NO_SPONTANEOUS); + int bNoMagic = ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_USE); + int bNoMagicItems = ai_GetDMAIAccessButton(BTN_AI_NO_MAGIC_ITEM_USE); + int bDefMagic = ai_GetDMAIAccessButton(BTN_AI_DEF_MAGIC_USE); + int bOffMagic = ai_GetDMAIAccessButton(BTN_AI_OFF_MAGIC_USE); + int bHealOut = ai_GetDMAIAccessButton(BTN_AI_HEAL_OUT); + int bHealIn = ai_GetDMAIAccessButton(BTN_AI_HEAL_IN); + int bSelfHealOnOff = ai_GetDMAIAccessButton(BTN_AI_STOP_SELF_HEALING); + int bPartyHealOnOff = ai_GetDMAIAccessButton(BTN_AI_STOP_PARTY_HEALING); + int bCureOnOff = ai_GetDMAIAccessButton(BTN_AI_STOP_CURE_SPELLS); + int bLoot = ai_GetDMAIAccessButton(BTN_AI_LOOT); + int bIgnoreAssociates = ai_GetDMAIAccessButton(BTN_AI_IGNORE_ASSOCIATES); + int bIgnoreTraps = ai_GetDMAIAccessButton(BTN_AI_IGNORE_TRAPS); + int bPercRange = ai_GetDMAIAccessButton(BTN_AI_PERC_RANGE); + int bBtnFamiliar = ai_GetDMWAccessButton(BTN_CMD_FAMILIAR); + int bBtnCompanion = ai_GetDMWAccessButton(BTN_CMD_COMPANION); + SetLocalInt(oPC, "CHBX_SKIP", TRUE); + DelayCommand(2.0, DeleteLocalInt(oPC, "CHBX_SKIP")); + // Row 4 + NuiSetBind(oPC, nToken, "chbx_cmd_action_check", JsonBool (bCmdAction)); + NuiSetBindWatch(oPC, nToken, "chbx_cmd_action_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_action_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_action_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_action_tooltip", JsonString(" Action button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_guard_check", JsonBool (bCmdGuard)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_guard_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_guard_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_guard_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_guard_tooltip", JsonString(" Guard button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_hold_check", JsonBool (bCmdHold)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_hold_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_hold_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_hold_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_hold_tooltip", JsonString(" Hold button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_attack_check", JsonBool (bCmdAttack)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_attack_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_attack_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_attack_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_attack_tooltip", JsonString(" Attack button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_follow_check", JsonBool (bCmdFollow)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_follow_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_follow_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_follow_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_follow_tooltip", JsonString(" Follow button")); + + NuiSetBind(oPC, nToken, "chbx_follow_target_check", JsonBool (bFollowTarget)); + NuiSetBindWatch (oPC, nToken, "chbx_follow_target_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_follow_target_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_follow_target_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_follow_target_tooltip", JsonString(" Follow Target button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_search_check", JsonBool (bCmdSearch)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_search_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_search_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_search_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_search_tooltip", JsonString(" Search All button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_stealth_check", JsonBool (bCmdStealth)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_stealth_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_stealth_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_stealth_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_stealth_tooltip", JsonString(" Stealth All button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_check", JsonBool (bCmdAIScript)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_ai_script_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_ai_script_tooltip", JsonString(" Combat Tactics button")); + + NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_check", JsonBool (bCmdPlacetrap)); + NuiSetBindWatch (oPC, nToken, "chbx_cmd_place_trap_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_cmd_place_trap_tooltip", JsonString (" Place Trap button")); + // Row 5 + NuiSetBind(oPC, nToken, "chbx_quick_widget_check", JsonBool (bSpellWidget)); + NuiSetBindWatch (oPC, nToken, "chbx_quick_widget_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_quick_widget_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_quick_widget_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_quick_widget_tooltip", JsonString(" Quick Use button")); + + NuiSetBind(oPC, nToken, "chbx_spell_memorize_check", JsonBool (bMemorizeSpells)); + NuiSetBindWatch (oPC, nToken, "chbx_spell_memorize_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_spell_memorize_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spell_memorize_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_spell_memorize_tooltip", JsonString(" Memorize Spells button")); + + NuiSetBind(oPC, nToken, "chbx_buff_short_check", JsonBool (bBuffShort)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_short_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_short_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_short_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_buff_short_tooltip", JsonString(" Short Buffing button")); + + NuiSetBind(oPC, nToken, "chbx_buff_long_check", JsonBool (bBuffLong)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_long_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_long_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_long_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_long_tooltip", JsonString(" Long Buffing button")); + + NuiSetBind(oPC, nToken, "chbx_buff_all_check", JsonBool (bBuffAll)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_all_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_all_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_all_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_all_tooltip", JsonString(" All Buffing button")); + + NuiSetBind(oPC, nToken, "chbx_buff_rest_check", JsonBool (bBuffRest)); + NuiSetBindWatch (oPC, nToken, "chbx_buff_rest_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_buff_rest_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_rest_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_buff_rest_tooltip", JsonString(" Rest Buffing button")); + + NuiSetBind(oPC, nToken, "chbx_jump_to_check", JsonBool(bJumpTo)); + NuiSetBindWatch (oPC, nToken, "chbx_jump_to_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_jump_to_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_jump_to_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_jump_to_tooltip", JsonString(" Jump Associates button")); + + NuiSetBind(oPC, nToken, "chbx_ghost_mode_check", JsonBool (bGhostMode)); + NuiSetBindWatch (oPC, nToken, "chbx_ghost_mode_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ghost_mode_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ghost_mode_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_ghost_mode_tooltip", JsonString(" Ghost mode button")); + + NuiSetBind(oPC, nToken, "chbx_camera_check", JsonBool (bCamera)); + NuiSetBindWatch (oPC, nToken, "chbx_camera_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_camera_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Change Camera button")); + + NuiSetBind(oPC, nToken, "chbx_inventory_check", JsonBool (bInventory)); + NuiSetBindWatch (oPC, nToken, "chbx_inventory_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_inventory_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString(" Open Inventory button")); + // Row 6 + NuiSetBind(oPC, nToken, "chbx_familiar_check", JsonBool(bBtnFamiliar)); + NuiSetBindWatch (oPC, nToken, "chbx_familiar_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_familiar_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_familiar_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_familiar_tooltip", JsonString(" Change Familiar buttons")); + + NuiSetBind(oPC, nToken, "chbx_companion_check", JsonBool(bBtnCompanion)); + NuiSetBindWatch (oPC, nToken, "chbx_companion_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_companion_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_companion_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_companion_tooltip", JsonString(" Change Animal Companion buttons")); + + NuiSetBind(oPC, nToken, "chbx_ai_check", JsonBool(bAI)); + NuiSetBindWatch (oPC, nToken, "chbx_ai_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ai_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ai_tooltip", JsonString(" Player AI button")); + + NuiSetBind(oPC, nToken, "chbx_quiet_check", JsonBool(bReduceSpeech)); + NuiSetBindWatch (oPC, nToken, "chbx_quiet_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_quiet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_quiet_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_quiet_tooltip", JsonString(" Reduce Speech button")); + + NuiSetBind(oPC, nToken, "chbx_ranged_check", JsonBool(bRanged)); + NuiSetBindWatch(oPC, nToken, "chbx_ranged_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ranged_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ranged_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_ranged_tooltip", JsonString(" Ranged button")); + + NuiSetBind(oPC, nToken, "chbx_equip_weapon_check", JsonBool(bEquipWeapons)); + NuiSetBindWatch(oPC, nToken, "chbx_equip_weapon_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_equip_weapon_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_equip_weapon_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_equip_weapon_tooltip", JsonString(" Auto Equip Weapons button")); + + NuiSetBind(oPC, nToken, "chbx_search_check", JsonBool(bSearch)); + NuiSetBindWatch (oPC, nToken, "chbx_search_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_search_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_search_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_search_tooltip", JsonString(" Search button")); + + NuiSetBind(oPC, nToken, "chbx_stealth_check", JsonBool(bStealth)); + NuiSetBindWatch(oPC, nToken, "chbx_stealth_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_stealth_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_stealth_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_stealth_tooltip", JsonString(" Stealth button")); + + NuiSetBind(oPC, nToken, "chbx_open_door_check", JsonBool(bOpenDoors)); + NuiSetBindWatch (oPC, nToken, "chbx_open_door_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_open_door_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_open_door_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_open_door_tooltip", JsonString(" Open Door button")); + + NuiSetBind(oPC, nToken, "chbx_traps_check", JsonBool(bTraps)); + NuiSetBindWatch (oPC, nToken, "chbx_traps_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_traps_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_traps_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_traps_tooltip", JsonString(" Disable Traps button")); + // Row 7 + NuiSetBind(oPC, nToken, "chbx_pick_locks_check", JsonBool(bPickLocks)); + NuiSetBindWatch(oPC, nToken, "chbx_pick_locks_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_pick_locks_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_pick_locks_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_pick_locks_tooltip", JsonString(" Pick Locks button")); + + NuiSetBind(oPC, nToken, "chbx_bash_locks_check", JsonBool(bBashLocks)); + NuiSetBindWatch(oPC, nToken, "chbx_bash_locks_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_bash_locks_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_bash_locks_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_bash_locks_tooltip", JsonString(" Bash button")); + + NuiSetBind(oPC, nToken, "chbx_magic_level_check", JsonBool(bMagicLevel)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_level_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_level_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_level_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_magic_level_tooltip", JsonString(" Magic Level button")); + + NuiSetBind(oPC, nToken, "chbx_spontaneous_check", JsonBool(bSpontaneous)); + NuiSetBindWatch (oPC, nToken, "chbx_spontaneous_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_spontaneous_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spontaneous_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spontaneous_tooltip", JsonString(" Spontaneous Spells button")); + + NuiSetBind(oPC, nToken, "chbx_magic_check", JsonBool(bNoMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_tooltip", JsonString(" Use Magic button")); + + NuiSetBind(oPC, nToken, "chbx_magic_items_check", JsonBool(bNoMagicItems)); + NuiSetBindWatch (oPC, nToken, "chbx_magic_items_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_magic_items_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_items_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_magic_items_tooltip", JsonString(" Use Magic Items button")); + + NuiSetBind(oPC, nToken, "chbx_def_magic_check", JsonBool (bDefMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_def_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_def_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_def_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_def_magic_tooltip", JsonString(" Use Defensive Magic button")); + + NuiSetBind(oPC, nToken, "chbx_off_magic_check", JsonBool(bOffMagic)); + NuiSetBindWatch (oPC, nToken, "chbx_off_magic_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_off_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_off_magic_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_off_magic_tooltip", JsonString(" Use Offensive Magic button")); + + NuiSetBind(oPC, nToken, "chbx_heal_out_check", JsonBool(bHealOut)); + NuiSetBindWatch (oPC, nToken, "chbx_heal_out_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heal_out_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_out_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_out_tooltip", JsonString(" Heal Out of Combat button")); + + NuiSetBind(oPC, nToken, "chbx_heal_in_check", JsonBool(bHealIn)); + NuiSetBindWatch (oPC, nToken, "chbx_heal_in_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heal_in_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_in_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_in_tooltip", JsonString(" Heal In Combat button")); + // Row 8 + NuiSetBind(oPC, nToken, "chbx_heals_onoff_check", JsonBool(bSelfHealOnOff)); + NuiSetBindWatch (oPC, nToken, "chbx_heals_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_heals_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heals_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heals_onoff_tooltip", JsonString(" Heal Self On/Off button")); + + NuiSetBind(oPC, nToken, "chbx_healp_onoff_check", JsonBool(bPartyHealOnOff)); + NuiSetBind(oPC, nToken, "chbx_healp_onoff_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_healp_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "btn_healp_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_healp_onoff_tooltip", JsonString(" Heal Party On/Off button")); + + NuiSetBind(oPC, nToken, "chbx_cure_onoff_check", JsonBool(bCureOnOff)); + NuiSetBind(oPC, nToken, "chbx_cure_onoff_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "chbx_cure_onoff_check", TRUE); + NuiSetBind(oPC, nToken, "btn_cure_onoff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cure_onoff_tooltip", JsonString(" Cure Spells On/Off button")); + + NuiSetBind(oPC, nToken, "chbx_loot_check", JsonBool(bLoot)); + NuiSetBindWatch (oPC, nToken, "chbx_loot_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_loot_tooltip", JsonString(" Auto Looting button")); + + NuiSetBind(oPC, nToken, "chbx_ignore_assoc_check", JsonBool(bIgnoreAssociates)); + NuiSetBindWatch(oPC, nToken, "chbx_ignore_assoc_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ignore_assoc_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ignore_assoc_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_ignore_assoc_tooltip", JsonString(" Ignore Associates On/Off button")); + + NuiSetBind(oPC, nToken, "chbx_ignore_traps_check", JsonBool(bIgnoreTraps)); + NuiSetBindWatch(oPC, nToken, "chbx_ignore_traps_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_ignore_traps_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_ignore_traps_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "btn_ignore_traps_tooltip", JsonString(" Ignore Floor Traps On/Off button")); + + NuiSetBind(oPC, nToken, "chbx_perc_range_check", JsonBool(bPercRange)); + NuiSetBindWatch (oPC, nToken, "chbx_perc_range_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_perc_range_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_perc_range_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_perc_range_tooltip", JsonString(" Perception Range button")); +} + diff --git a/src/module/nss/0i_messages.nss b/src/module/nss/0i_messages.nss new file mode 100644 index 0000000..ff01269 --- /dev/null +++ b/src/module/nss/0i_messages.nss @@ -0,0 +1,88 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_messages +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include script for sending messages to files and players on the server. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_constants" +#include "0i_color" +// Sets up a Message on the module to be sent to the log and/or players. +// sTextColor color of text sent to the players and DM's. +// Use AI_COLOR_*. Where * is WHITE, RED, GREEN, BLUE, GRAY, or YELLOW. +// If nLog is TRUE it will send the message to the log file. +// If nToDMs is TRUE it will send the message to all DM's. +// If oPC is set to a player then they will get the message as well. +// Messages delivered by script should be colored as follows. +// _Debug message = COLOR_WHITE +// Generic messages for the player = AI_COLOR_YELLOW +// Negative messages for the player = AI_COLOR_RED +// Positive messages for the player = AI_COLOR_GREEN +// System messages, things that are not part of Dnd = COLOR_GRAY +// Descriptive in game messages = COLOR_BLUE +void ai_SendMessages(string sMessage, string sTextColor = AI_COLOR_YELLOW, object oPC = OBJECT_INVALID, int nToDMs = FALSE, int nLog = FALSE); +// Used for _debugging. Keeps all the information organized. +// Sends info to first pc if true and sends information to log file. +// sScriptName is the name of the script calling this function. +// sLineNumber is the line number of the code calling this function. +// sMessage is the description of the debug being sent. +void ai_Debug(string sScriptName, string sLineNumber, string sMessage); +// A counter to track microseconds in code. Start saves the counter. +void ai_Counter_Start(); +// A counter to track microseconds in code. End displays the time between Start +// and End to the log file. +void ai_Counter_End(string sMessage = ""); + +void ai_SendMessages(string sMessage, string sTextColor = AI_COLOR_YELLOW, object oPC = OBJECT_INVALID, int nToDMs = FALSE, int nLog = FALSE) +{ + // if nLog is TRUE send the message to the log file. + if(nLog) + { + sMessage = ai_StripColorCodes(sMessage); + // Add PC name to log to know who it belongs to. + string sLogPCName; + if(oPC != OBJECT_INVALID) sLogPCName = "(" + GetName(oPC) + ") "; + WriteTimestampedLogEntry("*** MESSAGE: " + sLogPCName + " " + sMessage); + } + sMessage = ai_AddColorToText(sMessage, sTextColor); + if(oPC != OBJECT_INVALID) SendMessageToPC(oPC, sMessage); + // If nToDMs is true send message to the DM's online. + if(nToDMs) SendMessageToAllDMs(sMessage); +} +void ai_Debug(string sScriptName, string sLineNumber, string sMessage) +{ + string sName = GetName(OBJECT_SELF); + if(sName == GetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE) && + sName != "") + { + sMessage = "(((DEBUG)))[" + sScriptName + " - " + sLineNumber + " ]" + sMessage; + sMessage = ai_StripColorCodes(sMessage); + WriteTimestampedLogEntry(sMessage); + return; + } + //sMessage = "(((DEBUG)))[" + sScriptName + " - " + sLineNumber + " ]" + sMessage; + //sMessage = ai_StripColorCodes(sMessage); + //SendMessageToPC(GetFirstPC(), sMessage); + //WriteTimestampedLogEntry(sMessage); + //if(GetLocalInt(OBJECT_SELF, "AI_DEBUG")) WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Kirrin") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Dorna Trapspringer") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Dire Spider") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Shadow Priest") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Tomi Undergallows") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Thello Colds") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Gert Sigers") WriteTimestampedLogEntry(sMessage); + //if(GetName(OBJECT_SELF) == "Zombie") WriteTimestampedLogEntry(sMessage); +} +void ai_Counter_Start() +{ + SetLocalInt(GetModule(), "0_MSCounter", GetMicrosecondCounter()); +} +void ai_Counter_End(string sMessage = "") +{ + int nTime = GetMicrosecondCounter(); + nTime = nTime - GetLocalInt(GetModule(), "0_MSCounter"); + float fTime = nTime / 1000000.0; + if(AI_DEBUG) ai_Debug("MICROSECOND_COUNTER", "", "Seconds: " + FloatToString(fTime, 0, 10) + + " Microseconds: " + IntToString(nTime) + " " + sMessage); +} diff --git a/src/module/nss/0i_module.nss b/src/module/nss/0i_module.nss new file mode 100644 index 0000000..6d50182 --- /dev/null +++ b/src/module/nss/0i_module.nss @@ -0,0 +1,544 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_module +//////////////////////////////////////////////////////////////////////////////// + Include script for handling event scripts for injecting the systems into a + module for either single player or a server. +*/////////////////////////////////////////////////////////////////////////////// +#include "x2_inc_switches" +#include "0i_associates" +#include "0i_menus" +#include "0i_player_target" +#include "0i_gui_events" +// Add to nw_c2_default9 OnSpawn event script of monsters and +int ai_OnMonsterSpawn(object oCreature); +// Add to nw_ch_ac9 OnSpawn event script of henchman. +void ai_OnAssociateSpawn(object oCreature); +// Run all of the players starting scripts. +// If oPC is passed as Invalid then it will get the firt PC in the game. +void ai_CheckPCStart(object oPC = OBJECT_INVALID); +// Checks to see if we should change the monster via Json. +int ai_ChangeMonster(object oCreature, object oModule); +// Checks to see if we should change the associate via Json. +object ai_ChangeAssociate(object oCreature, object oModule); +// Sets the events for oCreature that is a Monster while playing Infinite Dungeons. +void ai_SetIDMonsterEventScripts(object oCreature); +// Sets the events for oCreature that is a monster in while using the PRC and +// playing Infinite Dungeons. +void ai_SetPRCIDMonsterEventScripts(object oCreature); +// Sets the events for oCreature that is an associate while using the PRC. +void ai_SetPRCAssociateEventScripts(object oCreature); +// Reverts single player monster event scripts back to their default. +void ai_ChangeEventScriptsForMonster(object oCreature); +// Reverts single player associates event scripts back to their default. +void ai_ChangeEventScriptsForAssociate(object oCreature); +// If using PRC this will replace some spells with PRC variants. +json ai_ReplaceSpellsWithPRCVariants(object oCreature, json jCreature); + +//****************************************************************************** +//********************* Creature event scripts ********************************* +//****************************************************************************** +int ai_OnMonsterSpawn(object oCreature) +{ + if(GetLocalInt(oCreature, AI_ONSPAWN_EVENT)) return FALSE; + SetLocalInt(oCreature, AI_ONSPAWN_EVENT, TRUE); + object oModule = GetModule(); + int nInfiniteDungeons; + int nPRC = GetLocalInt(oModule, AI_USING_PRC); + // If you are running a server this will not affect the module. + if(!AI_SERVER) + { + ai_CheckPCStart(); + string sModuleName = GetModuleName(); + if(sModuleName == "Neverwinter Nights - Infinite Dungeons" || + sModuleName == "Infinite Dungeons [PRC8]") + { + nInfiniteDungeons = TRUE; + if(nPRC) ai_SetPRCIDMonsterEventScripts(oCreature); + else ai_SetIDMonsterEventScripts(oCreature); + // Fix to get plot givers, finishers from getting killed a lot. + if(GetLocalString(oCreature, "sConversation") == "id1_plotgiver " || + GetLocalString(oCreature, "sConversation") == "id1_plotdest") + { + ChangeToStandardFaction(oCreature, STANDARD_FACTION_MERCHANT); + SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 50, oCreature); + } + } + } + // PRC and Infinite dungeons has issues with Ondeath script so we just leave it alone. + if(!nPRC && !nInfiniteDungeons) + { + // We change this script so we can setup permanent summons on/off. + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH); + SetLocalString(oCreature, "AI_ON_DEATH", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_c2_7_ondeath"); + } + if(GetCreatureFlag(oCreature, CREATURE_VAR_IS_INCORPOREAL)) + { + string sCombatAI = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + if (sCombatAI == "") SetLocalString(oCreature, AI_DEFAULT_SCRIPT, "ai_incorporeal"); + } + ai_SetListeningPatterns(oCreature); + ai_SetCreatureAIScript(oCreature); + ai_SetNormalAppearance(oCreature); + ai_SetAura(oCreature); + SetLocalInt(oCreature, AI_HEAL_IN_COMBAT_LIMIT, AI_MONSTER_HEAL_IN_COMBAT_CHANCE); + SetLocalInt(oCreature, AI_HEAL_OUT_OF_COMBAT_LIMIT, AI_MONSTER_HEAL_OUT_COMBAT_CHANCE); + int nMonsterHpIncrease = GetLocalInt(oModule, AI_INCREASE_MONSTERS_HP); + if(nMonsterHpIncrease) + { + int nHp = GetMaxHitPoints(oCreature); + nHp = (nHp * nMonsterHpIncrease) / 100; + effect eHp = EffectTemporaryHitpoints(nHp); + eHp = SupernaturalEffect(eHp); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHp, oCreature); + } + // Check if the monster should change how they search for targets. + if(d100() <= GetLocalInt(GetModule(), AI_RULE_AI_DIFFICULTY)) + { + SetLocalInt(oCreature, AI_RULE_AI_DIFFICULTY, TRUE); + } + // Do json changes after we have setup the creature. + if(ai_ChangeMonster(oCreature, oModule)) return TRUE; + return FALSE; +} +void ai_OnAssociateSpawn(object oCreature) +{ + if(GetLocalInt(oCreature, AI_ONSPAWN_EVENT)) return; + SetLocalInt(oCreature, AI_ONSPAWN_EVENT, TRUE); + int bPRC = GetLocalInt(GetModule(), AI_USING_PRC); + // If you are running a server this will not affect the module. + if(!AI_SERVER) + { + if(bPRC) ai_SetPRCAssociateEventScripts(oCreature); + } + // PRC has issues with Ondeath script so we just leave it alone. + if(!bPRC) + { + // We change this script so we can setup permanent summons on/off. + // If you don't use this you may remove the next three lines. + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH); + SetLocalString(oCreature, "AI_ON_DEATH", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_ch_7_ondeath"); + } + // Initialize Associate modes for basic use. + ai_SetListeningPatterns(oCreature); + ai_SetNormalAppearance(oCreature); + ai_SetAssociateAIScript(oCreature, FALSE); + ai_SetAura(oCreature); + if(GetLocalInt(GetModule(), AI_RULE_PARTY_SCALE)) ai_CheckXPPartyScale(oCreature); + // Bioware summoned shadows are not incorporeal, also set the ai code. + if (GetTag(OBJECT_SELF) == "NW_S_SHADOW") + { + SetLocalInt(OBJECT_SELF, "X2_L_IS_INCORPOREAL", TRUE); + SetLocalString(OBJECT_SELF, AI_DEFAULT_SCRIPT, "ai_shadow"); + } +} +void ai_CheckPCStart(object oPC = OBJECT_INVALID) +{ + if(oPC == OBJECT_INVALID) oPC = GetFirstPC(); + // There should always be a PC widget. If it doesn't exist then we assume + // that the module is being loaded or started. + if(!NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)) + { + object oModule = GetModule(); + // Do PRC check and save variable to the module. + if(ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS) != "") + SetLocalInt(oModule, AI_USING_PRC, TRUE); + ai_SetAIRules(); + ai_CheckAssociateData(oPC, oPC, "pc"); + ai_StartupPlugins(oPC); + ai_SetupPlayerTarget(oPC); + ai_SetupModuleGUIEvents(oPC); + ai_CreateWidgetNUI(oPC, oPC); + ai_SetNormalAppearance(oPC); + } +} +void ai_CopyMonster(object oCreature, object oModule) +{ + // After setting the monster lets see if we should copy it. + float fMonsterIncrease = GetLocalFloat(oModule, AI_INCREASE_ENC_MONSTERS); + if(GetIsEncounterCreature(oCreature) && fMonsterIncrease > 0.0) + { + int nMonsterIncrease; + float fMonsterCounter = GetLocalFloat(oModule, "AI_MONSTER_COUNTER"); + fMonsterCounter += fMonsterIncrease; + nMonsterIncrease = FloatToInt(fMonsterCounter); + if(nMonsterIncrease > 0) + { + fMonsterCounter = fMonsterCounter - IntToFloat(nMonsterIncrease); + } + SetLocalFloat(oModule, "AI_MONSTER_COUNTER", fMonsterCounter); + while(nMonsterIncrease > 0) + { + CopyObject(oCreature, GetLocation(oCreature), OBJECT_INVALID, "", TRUE); + nMonsterIncrease = nMonsterIncrease - 1; + } + } +} +void ai_CreateMonster(json jCreature, location lLocation, object oModule) +{ + //WriteTimestampedLogEntry("0i_module, 181, " + JsonDump(jCreature, 1)); + object oCreature = JsonToObject(jCreature, lLocation, OBJECT_INVALID, TRUE); + // Lets set the new version as spawned so we skip the initial setup again. + SetLocalInt(oCreature, AI_ONSPAWN_EVENT, TRUE); + /*if(GetLocalInt(oModule, AI_RULE_CORPSES_STAY)) + { + SetIsDestroyable(FALSE, FALSE, TRUE, oCreature); + SetLootable(oCreature, TRUE); + } */ + if(AI_DEBUG) ai_Debug("0i_module", "187", GetName(oCreature)); + ai_CopyMonster(oCreature, oModule); + return; +} +json ai_SetCompanionSummoning(object oCreature, json jCreature) +{ + if(GetHasFeat(FEAT_SUMMON_FAMILIAR, oCreature, TRUE)) + { + json jFamiliar = JsonObjectGet(jCreature, "FamiliarName"); + jFamiliar = JsonObjectSet(jFamiliar, "value", JsonString("Summoned Familiar")); + jCreature = JsonObjectSet(jCreature, "FamiliarName", jFamiliar); + jFamiliar = JsonObjectGet(jCreature, "FamiliarType"); + jFamiliar = JsonObjectSet(jFamiliar, "value", JsonInt(Random(11))); + return JsonObjectSet(jCreature, "FamiliarType", jFamiliar); + } + if(GetHasFeat(FEAT_ANIMAL_COMPANION , oCreature, TRUE)) + { + json jCompanion = JsonObjectGet(jCreature, "CompanionName"); + jCompanion = JsonObjectSet(jCompanion, "value", JsonString("Summoned Companion")); + jCreature = JsonObjectSet(jCreature, "CompanionName", jCompanion); + jCompanion = JsonObjectGet(jCreature, "CompanionType"); + jCompanion = JsonObjectSet(jCompanion, "value", JsonInt(Random(9))); + return JsonObjectSet(jCreature, "CompanionType", jCompanion); + } + return jCreature; +} +int ai_ChangeMonster(object oCreature, object oModule) +{ + object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oCreature); + // Lets not mess up the cutscenes with silly RULES. + if(GetCutsceneMode(oPC)) return FALSE; + //float fDistance = GetDistanceBetween(oCreature, oPC); + // Looks bad to see creatures wink in and out plus could cause module errors. + //if(fDistance != 0.0 && fDistance < AI_RANGE_PERCEPTION) return oCreature; + if(IsInConversation(oCreature)) return FALSE; + json jCreature = ObjectToJson(oCreature, TRUE); + // We now use plugins to mod our monsters. + json jMonsterMods = GetLocalJson(oModule, AI_MONSTER_MOD_JSON); + if(JsonGetType(jMonsterMods) != JSON_TYPE_NULL) + { + SetLocalJson(oModule, AI_MONSTER_JSON, jCreature); + SetLocalObject(oModule, AI_MONSTER_OBJECT, oCreature); + int nIndex; + string sMonsterMod = JsonGetString(JsonArrayGet(jMonsterMods, nIndex)); + while(sMonsterMod != "") + { + ExecuteScript(sMonsterMod, oPC); + sMonsterMod = JsonGetString(JsonArrayGet(jMonsterMods, ++nIndex)); + } + jCreature = GetLocalJson(oModule, AI_MONSTER_JSON); + } + int nSummon = GetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS) && + (GetHasFeat(FEAT_SUMMON_FAMILIAR, oCreature, TRUE)) || + GetHasFeat(FEAT_ANIMAL_COMPANION, oCreature, TRUE); + int nPercDist = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE) != 11 && + GetReputation(oCreature, oPC) < 11; + //WriteTimestampedLogEntry(GetName(oCreature) + ": fDistance: " + FloatToString(fDistance, 0, 2) + " nSummon: " + IntToString(nSummon) + + // " nPercDist: " + IntToString(nPercDist) + " Reputation: " + IntToString(GetReputation(oCreature, oPC))); + if(nSummon || nPercDist) + { + location lLocation = GetLocation(oCreature); + if(nPercDist) + { + json jPerception = JsonObjectGet(jCreature, "PerceptionRange"); + jPerception = JsonObjectSet(jPerception, "value", JsonInt(GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE))); + jCreature = JsonObjectSet(jCreature, "PerceptionRange", jPerception); + } + if(nSummon) jCreature = ai_SetCompanionSummoning(oCreature, jCreature); + SetLocalInt(oModule, AI_MONSTER_CHANGED, TRUE); + } + if(GetLocalInt(oModule, AI_MONSTER_CHANGED)) + { + SetIsDestroyable(TRUE, FALSE, FALSE, oCreature); + location lLocation = GetLocation(oCreature); + DestroyObject(oCreature); + AssignCommand(oModule, DelayCommand(1.0, ai_CreateMonster(jCreature, lLocation, oModule))); + DeleteLocalInt(oModule, AI_MONSTER_CHANGED); + return TRUE; + } + else ai_CopyMonster(oCreature, oModule); + DeleteLocalJson(oModule, AI_MONSTER_JSON); + DeleteLocalObject(oModule, AI_MONSTER_OBJECT); + return FALSE; +} +// Special event scripts for Infinite Dungeons! +void ai_SetIDMonsterEventScripts(object oCreature) +{ + //if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts."); + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + SetLocalString(oCreature, "AI_ON_HEARTBEAT", sScript); + if(sScript == "x2_def_heartbeat") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else if(sScript == "nw_c2_default1") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_HEARTBEAT SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Perception ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE); + SetLocalString(oCreature, "AI_ON_NOTICE", sScript); + if(sScript == "x2_def_percept") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_id_events"); + else if(sScript == "nw_c2_default2") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_NOTICE SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On End Combat Round ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + SetLocalString(oCreature, "AI_ON_END_COMBATROUND", sScript); + if(sScript == "x2_def_endcombat") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_id_events"); + else if(sScript == "nw_c2_default3") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_END_COMBATROUND SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Dialogue ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + SetLocalString(oCreature, "AI_ON_DIALOGUE", sScript); + if(sScript == "x2_def_onconv") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_id_events"); + else if(sScript == "nw_c2_default4") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DIALOGUE_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Melee Attacked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + SetLocalString(oCreature, "AI_ON_MELEE_ATTACKED", sScript); + if(sScript == "x2_def_attacked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_id_events"); + else if(sScript == "nw_c2_default5") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_MELEE_ATTACKED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Damaged ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + SetLocalString(oCreature, "AI_ON_DAMAGED", sScript); + if(sScript == "x2_def_ondamage") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_id_events"); + else if(sScript == "nw_c2_default6") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DAMAGED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + // We don't set OnDeath for Infinite Dungeons! + //********** On Death ********** + //sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH); + //SetLocalString(oCreature, "AI_ON_DEATH", sScript); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_id_events"); + //********** On Disturbed ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + SetLocalString(oCreature, "AI_ON_DISTURBED", sScript); + if(sScript == "x2_def_ondisturb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_id_events"); + else if(sScript == "nw_c2_default8") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DISTURBED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //********** On Rested ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED); + SetLocalString(oCreature, "AI_ON_RESTED", sScript); + if(sScript == "x2_def_rested") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_id_events"); + else if(sScript == "nw_c2_defaulta") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_RESTED SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Spell Cast At ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + SetLocalString(oCreature, "AI_ON_SPELLCASTAT", sScript); + if(sScript == "x2_def_spellcast") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_id_events"); + else if(sScript == "nw_c2_defaultb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_SPELLCASTAT_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Blocked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + SetLocalString(oCreature, "AI_ON_BLOCKED_BY_DOOR", sScript); + if(sScript == "x2_def_onblocked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_id_events"); + else if(sScript == "nw_c2_defaulte") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_BLOCKED_BY_DOOR SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); +} +// Special event scripts for Infinite Dungeons with PRC! +void ai_SetPRCIDMonsterEventScripts(object oCreature) +{ + //if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts for PRC."); + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + SetLocalString(oCreature, "AI_ON_HEARTBEAT", sScript); + if(sScript == "x2_def_heartbeat") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_prc_id_events"); + else if(sScript == "nw_c2_default1") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_HEARTBEAT SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Perception ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE); + SetLocalString(oCreature, "AI_ON_NOTICE", sScript); + if(sScript == "x2_def_percept") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_prc_id_events"); + else if(sScript == "nw_c2_default2") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_NOTICE SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On End Combat Round ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + SetLocalString(oCreature, "AI_ON_END_COMBATROUND", sScript); + if(sScript == "x2_def_endcombat") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_prc_id_events"); + else if(sScript == "nw_c2_default3") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_END_COMBATROUND SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Dialogue ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + SetLocalString(oCreature, "AI_ON_DIALOGUE", sScript); + if(sScript == "x2_def_onconv") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_prc_id_events"); + else if(sScript == "nw_c2_default4") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DIALOGUE_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Melee Attacked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + SetLocalString(oCreature, "AI_ON_MELEE_ATTACKED", sScript); + if(sScript == "x2_def_attacked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_prc_id_events"); + else if(sScript == "nw_c2_default5") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_MELEE_ATTACKED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Damaged ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + SetLocalString(oCreature, "AI_ON_DAMAGED", sScript); + if(sScript == "x2_def_ondamage") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_prc_id_events"); + else if(sScript == "nw_c2_default6") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DAMAGED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + // We don't set OnDeath for PRC or Infinite dungeons. + //********** On Death ********** + //sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH); + //SetLocalString(oCreature, "AI_ON_DEATH", sScript); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_prc_id_events"); + //********** On Disturbed ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + SetLocalString(oCreature, "AI_ON_DISTURBED", sScript); + if(sScript == "x2_def_ondisturb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_prc_id_events"); + else if(sScript == "nw_c2_default8") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_DISTURBED_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //********** On Rested ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED); + SetLocalString(oCreature, "AI_ON_RESTED", sScript); + if(sScript == "x2_def_rested") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_prc_id_events"); + else if(sScript == "nw_c2_defaulta") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_RESTED SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Spell Cast At ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + SetLocalString(oCreature, "AI_ON_SPELLCASTAT", sScript); + if(sScript == "x2_def_spellcast") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_prc_id_events"); + else if(sScript == "nw_c2_defaultb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_SPELLCASTAT_SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //********** On Blocked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + SetLocalString(oCreature, "AI_ON_BLOCKED_BY_DOOR", sScript); + if(sScript == "x2_def_onblocked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_prc_id_events"); + else if(sScript == "nw_c2_defaulte") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_prc_id_events"); + else if(sScript == "") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_id_events"); + else WriteTimestampedLogEntry("ON_BLOCKED_BY_DOOR SCRIPT ERROR: AI did not capture " + sScript + " script for " + GetName(oCreature) + "."); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); +} +// Special event scripts for PRC associates! +void ai_SetPRCAssociateEventScripts(object oCreature) +{ + //if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts for PRC."); + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + SetLocalString(oCreature, "AI_ON_HEARTBEAT", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac1") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "0e_prc_ch_events"); + //********** On Perception ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE); + SetLocalString(oCreature, "AI_ON_NOTICE", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac2") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "0e_prc_ch_events"); + //********** On End Combat Round ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + SetLocalString(oCreature, "AI_ON_END_COMBATROUND", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac3") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "0e_prc_ch_events"); + //********** On Dialogue ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + SetLocalString(oCreature, "AI_ON_DIALOGUE", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac4") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "0e_prc_ch_events"); + //********** On Melee Attacked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + SetLocalString(oCreature, "AI_ON_MELEE_ATTACKED", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac5") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "0e_prc_ch_events"); + //********** On Damaged ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + SetLocalString(oCreature, "AI_ON_DAMAGED", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac6") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "0e_prc_ch_events"); + //********** On Disturbed ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + SetLocalString(oCreature, "AI_ON_DISTURBED", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ac8") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "0e_prc_ch_events"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //********** On Rested ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED); + SetLocalString(oCreature, "AI_ON_RESTED", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_prc_ch_events"); + else if(sScript == "nw_ch_aca") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "0e_prc_ch_events"); + //********** On Spell Cast At ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + SetLocalString(oCreature, "AI_ON_SPELLCASTAT", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_prc_ch_events"); + else if(sScript == "nw_ch_acb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "0e_prc_ch_events"); + //********** On Blocked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + SetLocalString(oCreature, "AI_ON_BLOCKED_BY_DOOR", sScript); + if(sScript == "default") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_prc_ch_events"); + else if(sScript == "nw_ch_ace") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "0e_prc_ch_events"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); + if(!GetCommandable(oCreature)) SetCommandable(TRUE, oCreature); +} +void ai_ChangeEventScriptsForMonster(object oCreature) +{ + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + if(sScript == "0e_c2_1_hb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_c2_default1"); + //********** On Perception ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE); + if(sScript == "0e_c2_2_percept") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "nw_c2_default2"); + //********** On End Combat Round ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + if(sScript == "0e_c2_3_endround") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "nw_c2_default3"); + //********** On Dialogue ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + if(sScript == "0e_c2_4_convers") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "nw_c2_default4"); + //********** On Melee Attacked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + if(sScript == "0e_c2_5_phyatked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "nw_c2_default5"); + //********** On Damaged ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + if(sScript == "0e_c2_6_damaged") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "nw_c2_default6"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "nw_c2_deafult7"); + //********** On Disturbed ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + if(sScript == "0e_c2_8_disturb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "nw_c2_default8"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "nw_c2_defaulta"); + //********** On Spell Cast At ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + if(sScript == "0e_c2_b_castat") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "nw_c2_defaultb"); + //********** On Blocked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + if(sScript == "0e_c2_e_blocked") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "nw_c2_defaulte"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "nw_c2_defaulte"); +} +void ai_ChangeEventScriptsForAssociate(object oCreature) +{ + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_ch_ac1"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "nw_ch_ac2"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "nw_ch_ac3"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "nw_ch_ac4"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "nw_ch_ac5"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "nw_ch_ac6"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "nw_ch_ac7"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "nw_ch_ac8"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "nw_ch_aca"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "nw_ch_acb"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "nw_ch_ace"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "nw_ch_acd"); +} diff --git a/src/module/nss/0i_nui.nss b/src/module/nss/0i_nui.nss new file mode 100644 index 0000000..eab5ee7 --- /dev/null +++ b/src/module/nss/0i_nui.nss @@ -0,0 +1,434 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_nui +//////////////////////////////////////////////////////////////////////////////// + Include script for handling window displays. + + Use the following to get/set window information. + string sBind = NuiGetNthBind (oPlayer, nToken, FALSE, #); + json jMenuInfo = NuiGetBind (oPlayer, nToken, sBind); + # Gets json information for window : + 0 - string - "window_title" + 1 - json - "window_geometry" : "h", "w", "x", "y" + 2 - bool - "window_resizable" + 3 - bool - "window_closable" + 4 - bool - "window_transparent" + 5 - bool - "window_border" + + Layout pixel sizes: + Pixel height Title bar 33. + Pixel height Top border 10, between widgets 8, bottom border 10. + Pixel width Left border 10, between widgets 4, right border 10. + + Group outer lines add 12 to the vertical and horizontal lines. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +#include "nw_inc_nui" +struct stComboBox +{ + json jIndex; + json jCombo; + json jRow; + json jResRefArray; + json jWinArray; + json jCanSummon; // Index of all the summons in summons.2da +}; + +// Saves the menu to the campaign database. +void SaveMenuToCampaignDb(object oPC, int nToken, string sWndId); +// Returns the middle of the screen for the x position. +// oPC using the menu. +// fMenuWidth - the width of the menu to display. +float GetGUIWidthMiddle(object oPC, float fMenuWidth); + +// Returns the middle of the screen for the y position. +// oPC using the menu. +// fMenuHeight - the height of the menu to display. +float GetGUIHeightMiddle(object oPC, float fMenuHeight); + +// Checks to see if sWndId is open. +// If the window is open it removes it and returns FALSE +// If the window is closed it returns TRUE +int IsWindowClosed(object oPC, string sWndId); + +// Returns the Window ID (nToken). +// oPC is the PC using the menu. +// jLayout is the Layout of the menu. +// sWinID is the string ID for this window. +// sTitle is the Title of the menu. +// fX is the X position of the menu (-1.0: Centers, -2.0: UpperRight on Mouse, -3.0: Centers top of mouse). +// fY is the Y position of the menu (-1.0: Centers, -2.0: UpperRight on Mouse, -3.0: Centers top of mouse). +// fWidth is the width of the menu. +// fHeight is the height of the menu. +// bResize - TRUE will all it to be resized. +// bCollapse - TRUE will allow the window to be collapsable. +// bClose - TRUE will allow the window to be closed. +// bTransparent - TRUE makes the menu transparent. +// bBorder - TRUE makes the menu have a border. +// sEventScript will fire this event script for this window. +int SetWindow(object oPC, json jLayout, string sWinID, string sTitle, float fX, float fY, float fWidth, float fHeight, int bResize, int bCollapse, int bClose, int bTransparent, int bBorder, string sEventScript = ""); + +// Creates a label element in jRow. +// jRow is the row the label goes into. +// sLabel is the text placed in the label. +// If "" is passed then it will create a bind of sId + "_label". +// fWidth is the width of the label. +// fHeight is the Height of the label. +// nHAlign is horizonal align [NUI_HALING_*]. +// nVAlign is vertial align [NUI_VALING_*]. +// sId is the bind the event uses sId + "_event". +// sTooltip is the tooltip bind value. +json CreateLabel(json jRow, string sLabel, string sId, float fWidth, float fHeight, int nHAlign = 0, int nVAlign = 0, float fMargin = -1.0, string sTooltip = ""); + +// Creates a basic button element in jRow. +// jRow is the row the label goes into. +// sLabel is the text placed in the button. If "" is passed then it will +// create a bind of sId + "_label". +// sId is the binds for the button and the event uses sId + "_event". +// fWidth is the width of the button. +// fHeight is the Height of the button. +// fMargin is the space around the button. +// sTooltip is the tooltip bind value. +json CreateButton(json jRow, string sLabel, string sId, float fWidth, float fHeight, float fMargin = -1.0, string sTooltip = ""); + +// Creates a basic button select element in jRow. +// jRow is the row the label goes into. +// sLabel is the text placed in the button. If "" is passed then it will +// create a bind of sId + "_label". +// sId is the binds for the button and the event uses sId + "_event". +// fWidth is the width of the button. +// fHeight is the Height of the button. +// sTooltip is the tooltip bind value. +json CreateButtonSelect(json jRow, string sLabel, string sId, float fWidth, float fHeight, string sToolTip = ""); + +// Creates a button element with an image in jRow. +// jRow is the row the label goes into. +// sImage is the resref of the image to use. +// If "" is passed then it will create a bind of sId + "_image". +// sId is the binds for the button and the event uses sId + "_event". +// fWidth is the width of the button. +// fHeight is the Height of the button. +// fMargin is the space around the button. +// sTooltip is the tooltip bind value. +json CreateButtonImage(json jRow, string sResRef, string sId, float fWidth, float fHeight, float fMargin = -1.0, string sTooltip = ""); + +// Creates a basic text box that is not editable element in jRow. +// jRow is the row the TextEdit box goes into. +// sId is the bind variable so we can change the text. +// fWidth the width of the box. +// fHeight the height of the box. +// bBorder will add border TRUE or remove it FALSE. +// nScroll use NUI_SCROLLBARS_* +// sTooltip is the tooltip bind value. +json CreateTextBox(json jRow, string sId, float fWidth, float fHeight, int bBorder = TRUE, int nScroll = NUI_SCROLLBARS_AUTO, string sTooltip = ""); + +// Creates a basic text edit box element in jRow. +// jRow is the row the TextEdit box goes into. +// sPlaceHolderBind is the bind for Placeholder. +// sValueBind is the bind variable so we can change the text. +// nMaxLength is the maximum lenght of the text (1 - 65535) +// bMultiline - True or False that is has multiple lines. +// fWidth the width of the box. +// fHeight the height of the box. +// sTooltip is the tooltip bind value. +json CreateTextEditBox(json jRow, string sPlaceHolderBind, string sValueBind, int nMaxLength, int bMultiline, float fWidth, float fHeight, string sToolTip = ""); + +// Creates a combo box element in jRow. +// jRow is the row the combo goes into. +// jCombo is the elements/list for the combo box. Use NuiComboEntry to add. +// sId is the binds for the combo and the event uses sId + "_event" +// sId + "_selected" is the bind for the selection in the combo box. +// fWidth is the width of the combo. +// fHeight is the Height of the combo. +// sTooltip is the tooltip bind value. +json CreateCombo(json jRow, json jCombo, string sId, float fWidth, float fHeight, string sToolTip = ""); + +// Creates an image element in jRow. +// jRow is the row the Image goes into. +// sImage is the resref of the image to use. If "" is passed then it will +// create a bind of sId + "_image". +// nAspect is the aspect of the image NUI_ASPECT_*. +// nHAlign is the horizontal alignment of the image NUI_HALIGN_*. +// nVAlign is the vertical alignment of the image NUI_VALIGN_*. +// fWidth the width of the box. +// fHeight the height of the box. +// sTooltip is the tooltip bind value. +json CreateImage(json jRow, string sResRef, string sId, int nAspect, int nHAlign, int nVAlign, float fWidth, float fHeight, float fMargin = -1.0, string sToolTip = ""); + +// Creates a check box element in jRow. +// jRow is the row the Checkbox box goes into. +// sLabel is the text placed in the label. +// If "" is passed then it will create a bind of sId + "_label". +// sId is the bind variable so we can change the text. +// sId + "_check" is the Bind:bool for if it is checked or not. +// fWidth is the width of the label. +// fHeight is the Height of the label. +// sTooltip is the tooltip bind value. +json CreateCheckBox(json jRow, string sLabel, string sId, float fWidth, float fHeight, string sToolTip = ""); + +// Creates a slider (Int based) element in jRow +// jRow is the row the Check box goes into. +// sId is the bind name. +// The binds are as follows. +// Value: sId + "_value" +// Minimum: sId + "_min" +// Maximum: sId + "_max" +// Step size: sId + "_stepsize" +// fWidth is the width of the slider. +// fHeight is the Height of the slider. +// sTooltip is the tooltip bind value. +json CreateSlider(json jRow, string sId, float fWidth, float fHeight, string sToolTip = ""); + +// Creates an Options element in jRow. +// jRow is the row the Options will start on. +// sId is the bind name. +// The binds are as follows: +// Value: sId + "_value" +// Event is sId + "_event" +// nDirection: NUI_DIRECTION_* +// fWidth is the width of the options labels. +// fHeight is the height of the options labels. +// sTooltip is the tooltip bind value. +json CreateOptions(json jRow, string sId, int nDirection, json jLabels, float fWidth, float fHeight, string sToolTip = ""); + +// Creates a list element in jRow. +// jRow is the row the list will start on. +// jElements is the list of elements in the list. Use NuiListTemplateCell to add. +// sId is the bind name. +// The binds are Event is sId + "_event". +// Row count is bound to sId + "_count". +// fRowHeight is the height of the rendered rows. +// fWidth is the width of the options labels. +// fHeight is the height of the options labels. +// sTooltip is the tooltip bind value. +json CreateList(json jRow, json jElements, string sId, float fRowHeight, float fWidth, float fHeight, string sTooltip = ""); + +// Placed here temporarily until we can clean up our includes! +void ai_SetDMWAccessButton(int nButton, int bOn = TRUE); +int ai_GetDMWAccessButton(int nButton); +void ai_SetDMAIAccessButton(int nButton, int bOn = TRUE); +int ai_GetDMAIAccessButton(int nButton); + +void SaveMenuToCampaignDb(object oPC, int nToken, string sWndId) +{ + json jGeometry = NuiGetBind(oPC, nToken, "window_geometry"); + float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x")); + float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y")); + string sName = ai_RemoveIllegalCharacters(GetName(oPC)); + json jLocations = ai_GetCampaignDbJson("locations", sName, AI_DM_TABLE); + json jNUI = JsonObjectGet(jLocations, sWndId); + if(JsonGetType(jNUI) == JSON_TYPE_NULL) jNUI = JsonObject(); + jNUI = JsonObjectSet(jNUI, "x", JsonFloat(fX)); + jNUI = JsonObjectSet(jNUI, "y", JsonFloat(fY)); + jLocations = JsonObjectSet(jLocations, sWndId, jNUI); + ai_SetCampaignDbJson("locations", jLocations, sName, AI_DM_TABLE); +} + +float GetGUIWidthMiddle(object oPC, float fMenuWidth) +{ + // Get players window information. + float fGUI_Width = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_WIDTH)); + float fGUI_Scale = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0; + fMenuWidth = fMenuWidth * fGUI_Scale; + return (fGUI_Width / 2.0) - (fMenuWidth / 2.0); +} +float GetGUIHeightMiddle(object oPC, float fMenuHeight) +{ + // Get players window information. + float fGUI_Height = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_HEIGHT)); + float fGUI_Scale = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0; + fMenuHeight = fMenuHeight * fGUI_Scale; + return (fGUI_Height / 2.0) - (fMenuHeight / 2.0); +} +int IsWindowClosed(object oPC, string sWndId) +{ + int nToken = NuiFindWindow(oPC, sWndId); + if(nToken) + { + NuiDestroy(oPC, nToken); + return FALSE; + } + return TRUE; +} +int SetWindow(object oPC, json jLayout, string sWinID, string sTitle, float fX, float fY, float fWidth, float fHeight, int bResize, int bCollapse, int bClose, int bTransparent, int bBorder, string sEventScript = "") +{ + json jWindow; + if (bCollapse) jWindow = NuiWindow (jLayout, NuiBind ("window_title"), NuiBind ("window_geometry"), + NuiBind ("window_resizable"), JsonNull (), NuiBind ("window_closable"), + NuiBind ("window_transparent"), NuiBind ("window_border")); + + else jWindow = NuiWindow (jLayout, NuiBind ("window_title"), NuiBind ("window_geometry"), + NuiBind ("window_resizable"), JsonBool (FALSE), NuiBind ("window_closable"), + NuiBind ("window_transparent"), NuiBind ("window_border")); + + int nToken = NuiCreate (oPC, jWindow, sWinID, sEventScript); + if(!bCollapse && !bClose && !bBorder) NuiSetBind (oPC, nToken, "window_title", JsonBool (FALSE)); + else NuiSetBind (oPC, nToken, "window_title", JsonString (sTitle)); + if (fX == -1.0) fX = GetGUIWidthMiddle (oPC, fWidth); + if (fY == -1.0) fY = GetGUIHeightMiddle (oPC, fHeight); + int nScale = GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE); + if(nScale != 100) + { + fHeight = fHeight * (IntToFloat(1050 - nScale) / 1000.0); + fWidth = fWidth * (IntToFloat(1200 - nScale) / 1000.0); + } + NuiSetBind (oPC, nToken, "window_geometry", NuiRect (fX, + fY, fWidth, fHeight)); + NuiSetBind (oPC, nToken, "window_resizable", JsonBool (bResize)); + NuiSetBind (oPC, nToken, "window_closable", JsonBool (bClose)); + NuiSetBind (oPC, nToken, "window_transparent", JsonBool (bTransparent)); + NuiSetBind (oPC, nToken, "window_border", JsonBool (bBorder)); + return nToken; +} +json CreateLabel(json jRow, string sLabel, string sId, float fWidth, float fHeight, int nHAlign = 0, int nVAlign = 0, float fMargin = -1.0, string sTooltip = "") +{ + json jLabel; + if(sLabel == "") jLabel = NuiId(NuiLabel(NuiBind(sId + "_label"), JsonInt(nHAlign), JsonInt(nVAlign)), sId); + else jLabel = NuiId(NuiLabel(JsonString(sLabel), JsonInt(nHAlign), JsonInt(nVAlign)), sId); + jLabel = NuiWidth(jLabel, fWidth); + jLabel = NuiHeight(jLabel, fHeight); + if (fMargin > -1.0) jLabel = NuiMargin(jLabel, fMargin); + if(sTooltip != "") jLabel = NuiTooltip (jLabel, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jLabel); +} +json CreateButton(json jRow, string sLabel, string sId, float fWidth, float fHeight, float fMargin = -1.0, string sTooltip = "") +{ + json jButton; + if(sLabel == "") jButton = NuiEnabled(NuiId(NuiButton(NuiBind (sId + "_label")), sId), NuiBind(sId + "_event")); + else jButton = NuiEnabled(NuiId(NuiButton(JsonString(sLabel)), sId), NuiBind(sId + "_event")); + jButton = NuiWidth(jButton, fWidth); + jButton = NuiHeight(jButton, fHeight); + if (fMargin > -1.0) jButton = NuiMargin(jButton, fMargin); + if (sTooltip != "") jButton = NuiTooltip(jButton, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jButton); +} +json CreateButtonSelect(json jRow, string sLabel, string sId, float fWidth, float fHeight, string sTooltip = "") +{ + json jButton; + if(sLabel == "") jButton = NuiEnabled(NuiId(NuiButtonSelect(NuiBind (sId + "_label"), NuiBind(sId)), sId), NuiBind(sId + "_event")); + else jButton = NuiEnabled(NuiId(NuiButtonSelect(JsonString(sLabel), NuiBind(sId)), sId), NuiBind(sId + "_event")); + jButton = NuiWidth(jButton, fWidth); + jButton = NuiHeight(jButton, fHeight); + if(sTooltip != "") jButton = NuiTooltip(jButton, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jButton); +} +json CreateButtonImage(json jRow, string sResRef, string sId, float fWidth, float fHeight, float fMargin = -1.0, string sTooltip = "") +{ + json jButton; + if(sResRef == "") jButton = NuiEnabled(NuiId (NuiButtonImage(NuiBind(sId + "_image")), sId), NuiBind(sId + "_event")); + else jButton = NuiEnabled(NuiId(NuiButtonImage(JsonString(sResRef)), sId), NuiBind(sId + "_event")); + jButton = NuiWidth(jButton, fWidth); + jButton = NuiHeight(jButton, fHeight); + if(fMargin > -1.0) jButton = NuiMargin(jButton, fMargin); + if(sTooltip != "") jButton = NuiTooltip(jButton, NuiBind (sTooltip)); + jButton = NuiEncouraged(jButton, NuiBind(sId + "_encouraged")); + return JsonArrayInsert(jRow, jButton); +} +json CreateTextBox(json jRow, string sId, float fWidth, float fHeight, int bBorder = TRUE, int nScroll = NUI_SCROLLBARS_AUTO, string sTooltip = "") +{ + json jTextBox = NuiEnabled(NuiText(NuiBind(sId), bBorder, nScroll), NuiBind(sId + "_event")); + jTextBox = NuiWidth(jTextBox, fWidth); + jTextBox = NuiHeight(jTextBox, fHeight); + if(sTooltip != "") jTextBox = NuiTooltip(jTextBox, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, JsonObjectSet(jTextBox, "text_color", NuiColor (255, 0, 0))); +} +json CreateTextEditBox(json jRow, string sPlaceHolderBind, string sValueBind, int nMaxLength, int bMultiline, float fWidth, float fHeight, string sTooltip = "") +{ + json jObject = NuiEnabled(NuiTextEdit(NuiBind(sPlaceHolderBind), NuiBind(sValueBind), nMaxLength, bMultiline), NuiBind(sValueBind + "_event")); + jObject = NuiWidth(jObject, fWidth); + jObject = NuiHeight(jObject, fHeight); + if(sTooltip != "") jObject = NuiTooltip(jObject, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jObject); +} +json CreateCombo(json jRow, json jList, string sId, float fWidth, float fHeight, string sTooltip = "") +{ + json jCombo; + if(JsonGetType(jList) == JSON_TYPE_NULL) + { + jCombo = NuiId(NuiCombo(NuiBind(sId + "_list"), NuiBind(sId + "_selected")), sId + "_event"); + } + jCombo = NuiId(NuiCombo(jList, NuiBind (sId + "_selected")), sId); + jCombo = NuiEnabled(jCombo, NuiBind (sId + "_event")); + jCombo = NuiWidth(jCombo, fWidth); + jCombo = NuiHeight(jCombo, fHeight); + if(sTooltip != "") jCombo = NuiTooltip(jCombo, NuiBind(sTooltip)); + return JsonArrayInsert(jRow, jCombo); +} +json CreateImage(json jRow, string sResRef, string sId, int nAspect, int nHAlign, int nVAlign, float fWidth, float fHeight, float fMargin = -1.0, string sTooltip = "") +{ + json jImage; + if(sResRef == "") jImage = NuiEnabled(NuiId(NuiImage(NuiBind(sId + "_image"), JsonInt(nAspect), JsonInt(nHAlign), JsonInt(nVAlign)), sId), NuiBind(sId + "_event")); + else jImage = NuiEnabled(NuiId(NuiImage(JsonString(sResRef), JsonInt(nAspect), JsonInt(nHAlign), JsonInt(nVAlign)), sId), NuiBind(sId + "_event")); + jImage = NuiWidth(jImage, fWidth); + jImage = NuiHeight(jImage, fHeight); + if (fMargin > -1.0) jImage = NuiMargin(jImage, fMargin); + if(sTooltip != "") jImage = NuiTooltip(jImage, NuiBind(sTooltip)); + return JsonArrayInsert(jRow, jImage); +} +json CreateCheckBox(json jRow, string sLabel, string sId, float fWidth, float fHeight, string sTooltip = "") +{ + json jCheckBox; + if(sLabel == "") jCheckBox = NuiEnabled(NuiId(NuiCheck(NuiBind(sId + "_label"), NuiBind(sId + "_check")), sId), NuiBind(sId + "_event")); + else jCheckBox = NuiEnabled(NuiId(NuiCheck(JsonString(sLabel), NuiBind(sId + "_check")), sId), NuiBind(sId + "_event")); + jCheckBox = NuiWidth(jCheckBox, fWidth); + jCheckBox = NuiHeight(jCheckBox, fHeight); + if (sTooltip != "") jCheckBox = NuiTooltip (jCheckBox, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jCheckBox); +} +json CreateSlider(json jRow, string sId, float fWidth, float fHeight, string sTooltip = "") +{ + json jSlider; + jSlider = NuiEnabled(NuiId(NuiSlider(NuiBind(sId + "_value"), NuiBind(sId + "_min"), NuiBind(sId + "_max"), NuiBind(sId + "_stepsize")), sId), NuiBind(sId + "_event")); + jSlider = NuiWidth(jSlider, fWidth); + jSlider = NuiHeight(jSlider, fHeight); + if(sTooltip != "") jSlider = NuiTooltip(jSlider, NuiBind(sTooltip)); + return JsonArrayInsert(jRow, jSlider); +} +json CreateOptions(json jRow, string sId, int nDirection, json jLabels, float fWidth, float fHeight, string sTooltip = "") +{ + json jOption; + jOption = NuiEnabled(NuiId(NuiOptions(nDirection, jLabels, NuiBind(sId + "_value")), sId), NuiBind(sId + "_event")); + jOption = NuiWidth(jOption, fWidth); + jOption = NuiHeight(jOption, fHeight); + if(sTooltip != "") jOption = NuiTooltip (jOption, NuiBind (sTooltip)); + return JsonArrayInsert(jRow, jOption); +} +json CreateList(json jRow, json jElements, string sId, float fRowHeight, float fWidth, float fHeight, string sTooltip = "") +{ + json jList; + jList = NuiId(NuiList(jElements, NuiBind(sId), fRowHeight), sId + "_id"); + jList = NuiWidth(jList, fWidth); + jList = NuiHeight(jList, fHeight); + if (sTooltip != "") jList = NuiTooltip(jList, NuiBind(sTooltip)); + return JsonArrayInsert(jRow, jList); +} +void ai_SetDMWAccessButton(int nButton, int bOn = TRUE) +{ + json jRules = ai_GetCampaignDbJson("rules"); + int nWidgetButtons = JsonGetInt(JsonObjectGet(jRules, sDMWidgetAccessVarname)); + if(bOn) nWidgetButtons = nWidgetButtons | nButton; + else nWidgetButtons = nWidgetButtons & ~nButton; + SetLocalInt(GetModule(), sDMWidgetAccessVarname, nWidgetButtons); + jRules = JsonObjectSet(jRules, sDMWidgetAccessVarname, JsonInt(nWidgetButtons)); + ai_SetCampaignDbJson("rules", jRules); +} +int ai_GetDMWAccessButton(int nButton) +{ + int nWidgetButtons = GetLocalInt(GetModule(), sDMWidgetAccessVarname); + return nWidgetButtons & nButton; +} +void ai_SetDMAIAccessButton(int nButton, int bOn = TRUE) +{ + json jRules = ai_GetCampaignDbJson("rules"); + int nWidgetButtons = JsonGetInt(JsonObjectGet(jRules, sDMAIAccessVarname)); + if(bOn) nWidgetButtons = nWidgetButtons | nButton; + else nWidgetButtons = nWidgetButtons & ~nButton; + SetLocalInt(GetModule(), sDMAIAccessVarname, nWidgetButtons); + jRules = JsonObjectSet(jRules, sDMAIAccessVarname, JsonInt(nWidgetButtons)); + ai_SetCampaignDbJson("rules", jRules); +} +int ai_GetDMAIAccessButton(int nButton) +{ + int nWidgetButtons = GetLocalInt(GetModule(), sDMAIAccessVarname); + return nWidgetButtons & nButton; +} + diff --git a/src/module/nss/0i_player_target.nss b/src/module/nss/0i_player_target.nss new file mode 100644 index 0000000..bed4834 --- /dev/null +++ b/src/module/nss/0i_player_target.nss @@ -0,0 +1,793 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_player_target +//////////////////////////////////////////////////////////////////////////////// + Include script for handling player targeting functions. + +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +#include "0i_menus" +// Setup an AI OnPlayerTarget Event script while allowing any module onplayer +// target event script to still work. +void ai_SetupPlayerTarget(object oCreature); +// Selects a target for oAssocite to follow. +void ai_AllSelectTarget(object oPC, object oAssociate, object oTarget); +// Removes the Cutscene ghosts and variables from all associates. For original AI scripts. +void ai_OriginalRemoveAllActionMode(object oPC); +// Removes the Cutscene ghosts and Command mode from all associates. +void ai_RemoveAllActionMode(object oPC); +// Once a trap has been selected from the associates inventory move to placing the trap. +void ai_SelectTrap(object oPC, object oAssociate, object oItem); +// Place the selected trap at the location selected by the player for OBJECT_SELF. +void ai_PlaceTrap(object oPC, location lLocation); +// Adds a creature to nGroup for oDM +void ai_AddToGroup(object oDM, object oTarget, string sTargetMode); +// Has nGroup perform an action based on the selected target or location. +void ai_DMAction(object oDM, object oTarget, location lLocation, string sTargetMode); +// Get oPC to select a spell target for oAssociate. +void ai_SelectWidgetSpellTarget(object oPC, object oAssociate, string sElem); +// Updates oAssociates widget by destroying the current one and rebuilding. +void ai_UpdateAssociateWidget(object oPC, object oAssociate); +// Sets oAssociates action mode for nFeat from the quick widget menu +int ai_SetActionMode(object oAssociate, int nFeat); + +void ai_SetupPlayerTarget(object oCreature) +{ + object oModule = GetModule(); + string sModuleTargetEvent = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET); + if(sModuleTargetEvent != "") + { + if(sModuleTargetEvent != "0e_player_target") SetLocalString(oModule, AI_MODULE_TARGET_EVENT, sModuleTargetEvent); + } + SetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET, "0e_player_target"); +} +void ai_OriginalActionAssociate(object oPC, object oTarget, location lLocation) +{ + object oAssociate = OBJECT_SELF; + if(!GetLocalInt(oAssociate, sGhostModeVarname) && GetLocalInt(oPC, sGhostModeVarname)) + { + effect eGhost = EffectCutsceneGhost(); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, oAssociate); + SetLocalInt(oAssociate, sGhostModeVarname, TRUE); + } + int nObjectType = GetObjectType(oTarget); + ai_ClearCreatureActions(TRUE); + if(oTarget == GetArea(oPC)) + { + ActionMoveToLocation(lLocation, TRUE); + if(GetLocalObject(oPC, AI_FOLLOW_TARGET) == oAssociate) + { + float fFollowDistance = 3.0; + AssignCommand(oPC, ai_ClearCreatureActions()); + AssignCommand(oPC, ActionForceFollowObject(oAssociate, fFollowDistance)); + } + } + else if(nObjectType == OBJECT_TYPE_CREATURE) + { + if(oTarget != GetLocalObject(oPC, AI_TARGET_ASSOCIATE)) + { + if(GetMaster(oTarget) == oPC) + { + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION"); + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oTarget); + ai_SendMessages(GetName(oTarget) + " is now in Action Mode.", AI_COLOR_YELLOW, oPC); + } + else ActionMoveToObject(oTarget, TRUE); + } + } + else if(nObjectType == OBJECT_TYPE_DOOR) + { + if(GetIsTrapped(oTarget) && GetAssociateState(NW_ASC_DISARM_TRAPS, oAssociate)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) + { + bkAttemptToDisarmTrap(oTarget); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + } + if(GetLocked(oTarget)) bkAttemptToOpenLock(oTarget); + if(GetIsOpen(oTarget)) + { + ActionCloseDoor(oTarget, TRUE); + } + else ActionOpenDoor(oTarget, TRUE); + } + else if(nObjectType == OBJECT_TYPE_ITEM) + { + ActionPickUpItem(oTarget); + } + else if(nObjectType == OBJECT_TYPE_PLACEABLE) + { + ActionMoveToObject(oTarget, TRUE); + if(GetHasInventory(oTarget)) + { + if(GetIsTrapped(oTarget) && GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS, oAssociate)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) + { + bkAttemptToDisarmTrap(oTarget); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + if(GetLocked(oTarget)) + { + if(GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS, oAssociate)) + { + bkAttemptToOpenLock(oTarget); + } + else AssignCommand(oAssociate, ai_HaveCreatureSpeak(oAssociate, 0, "This " + GetName(oTarget) + " is locked!")); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE); + } + else if(GetLocked(oTarget)) + { + if(GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS, oAssociate)) + { + bkAttemptToOpenLock(oTarget); + } + else AssignCommand(oAssociate, ai_HaveCreatureSpeak(oAssociate, 0, "This " + GetName(oTarget) + " is locked!")); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE); + } + DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE); + } + else if(nObjectType == OBJECT_TYPE_TRIGGER) + { + if(GetIsTrapped(oTarget) && GetAssociateState(NW_ASC_RETRY_OPEN_LOCKS, oAssociate)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) bkAttemptToDisarmTrap(oTarget); + } + } + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_OriginalActionAllAssociates(object oPC, object oTarget, location lLocation) +{ + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_OriginalActionAssociate(oPC, oTarget, lLocation)); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_OriginalActionAssociate(oPC, oTarget, lLocation)); + } +} +void ai_ActionAssociate(object oPC, object oTarget, location lLocation) +{ + object oAssociate = OBJECT_SELF; + if(ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST) && + !ai_GetAIMode(oAssociate, AI_MODE_GHOST) && + !GetLocalInt(oAssociate, sGhostModeVarname)) + { + effect eGhost = EffectCutsceneGhost(); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, oAssociate); + SetLocalInt(oAssociate, sGhostModeVarname, TRUE); + } + int nObjectType = GetObjectType(oTarget); + ai_SetAIMode(oAssociate, AI_MODE_COMMANDED, TRUE); + ai_ClearCreatureActions(TRUE); + if(oTarget == GetArea(oPC)) + { + ActionMoveToLocation(lLocation, TRUE); + if(GetLocalObject(oPC, AI_FOLLOW_TARGET) == oAssociate) + { + float fFollowDistance = ai_GetFollowDistance(oPC); + if(GetDistanceBetween(oAssociate, oPC) <= fFollowDistance) + { + DelayCommand(fFollowDistance, AssignCommand(oPC, ActionMoveToObject(oAssociate, TRUE, fFollowDistance))); + } + else AssignCommand(oPC, ActionMoveToObject(oAssociate, TRUE, fFollowDistance)); + } + } + else if(nObjectType == OBJECT_TYPE_CREATURE) + { + if(GetIsDead(oTarget)) + { + AssignCommand(oAssociate, ActionDoCommand(ai_SearchObject(oAssociate, oTarget, oPC, TRUE))); + } + else if(GetIsEnemy(oTarget, oAssociate)) + { + // Lock them into attacking this target only. + SetLocalObject(oAssociate, AI_PC_LOCKED_TARGET, oTarget); + // This resets a henchmens failed Moral save in combat. + if(GetLocalString(oAssociate, AI_COMBAT_SCRIPT) == "ai_coward") + { + SetLocalString(oAssociate, AI_COMBAT_SCRIPT, GetLocalString(oAssociate, AI_DEFAULT_SCRIPT)); + } + if(ai_GetIsInCombat(oAssociate)) ai_DoAssociateCombatRound(oAssociate, oTarget); + else + { + ai_HaveCreatureSpeak(oAssociate, 5, ":0:1:2:3:6:"); + ai_StartAssociateCombat(oAssociate, oTarget); + } + ai_SendMessages(GetName(oAssociate) + " is attacking " + GetName(oTarget), AI_COLOR_RED, oPC); + } + else + { + ActionMoveToObject(oTarget, TRUE); + // Player will be stuck with this variable if they are not using the AI. + DeleteLocalInt(oTarget, "AI_I_AM_BEING_HEALED"); + ActionDoCommand(ai_ActionTryHealing(oAssociate, oTarget)); + } + } + else if(nObjectType == OBJECT_TYPE_DOOR) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) + { + int bStopAction = !GetLocalInt(oTarget, "AI_CANNOT_TRAP_" + GetTag(oAssociate)); + if(ai_ReactToTrap(oAssociate, oTarget, TRUE)) bStopAction = TRUE; + if(bStopAction) + { + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + } + } + if(GetLocked(oTarget)) ai_AttemptToByPassLock(oAssociate, oTarget, TRUE); + else if(GetIsOpen(oTarget)) ActionCloseDoor(oTarget, TRUE); + else ActionOpenDoor(oTarget, TRUE); + } + else if(nObjectType == OBJECT_TYPE_ITEM) + { + ActionPickUpItem(oTarget); + } + else if(nObjectType == OBJECT_TYPE_PLACEABLE) + { + ActionMoveToObject(oTarget, TRUE); + if(GetHasInventory(oTarget)) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) + { + if(ai_ReactToTrap(oAssociate, oTarget, TRUE)) + { + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + + } + } + if(GetLocked(oTarget)) ai_AttemptToByPassLock(oAssociate, oTarget, TRUE); + else ActionDoCommand(ai_SearchObject(oAssociate, oTarget, oPC, TRUE)); + } + else + { + if(ai_GetAIMode(oAssociate, AI_MODE_BASH_LOCKS)) + { + AssignCommand(oAssociate, ai_ClearCreatureActions()); + // Check to make sure we are using a melee weapon. + if(ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oAssociate)) || + ai_EquipBestMeleeWeapon(oAssociate)) + { + AssignCommand(oAssociate, ActionWait(1.0)); + AssignCommand(oAssociate, ActionAttack(oTarget)); + } + } + else AssignCommand(oAssociate, DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE)); + } + } + else if(nObjectType == OBJECT_TYPE_TRIGGER) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oPC)) SetTrapDetectedBy(oTarget, oAssociate); + if(GetTrapDetectedBy(oTarget, oAssociate)) ai_ReactToTrap(oAssociate, oTarget, TRUE); + } + } + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_ActionAllAssociates(object oPC, object oTarget, location lLocation) +{ + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_ActionAssociate(oPC, oTarget, lLocation)); + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, ai_ActionAssociate(oPC, oTarget, lLocation)); + } +} +void ai_SelectFollowTarget(object oPC, object oAssociate, object oTarget) +{ + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + int nToken = NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI); + float fRange = GetLocalFloat(oAssociate, AI_FOLLOW_RANGE) + + StringToFloat(Get2DAString("appearance", "PREFATCKDIST", GetAppearanceType(oAssociate))); + string sRange = FloatToString(fRange, 0, 0); + if(oAssociate == oTarget) + { + ai_SetAIMode(oAssociate, AI_MODE_FOLLOW, FALSE); + DeleteLocalObject(oAssociate, AI_FOLLOW_TARGET); + string sTarget; + if(ai_GetIsCharacter(oAssociate)) + { + sTarget = "nobody"; + ai_SendMessages(GetName(oAssociate) + " is not following anyone now!", AI_COLOR_YELLOW, oPC); + } + else + { + sTarget = GetName(oPC); + ai_SendMessages(GetName(oAssociate) + " is now following " + sTarget + "!", AI_COLOR_YELLOW, oPC); + } + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_follow_target_tooltip", " " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]"); + } + else + { + ai_SetAIMode(oAssociate, AI_MODE_FOLLOW, TRUE); + SetLocalObject(oAssociate, AI_FOLLOW_TARGET, oTarget); + ai_SendMessages(GetName(oAssociate) + " is now following " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + AssignCommand(oAssociate, ActionMoveToObject(oTarget, TRUE, ai_GetFollowDistance(oAssociate))); + ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_follow_target_tooltip", " " + GetName(oAssociate) + " following " + GetName(oTarget) + " [" + sRange + " meters]"); + } + aiSaveAssociateModesToDb(oPC, oAssociate); +} +void ai_OriginalRemoveAllActionMode(object oPC) +{ + if(!ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST)) return; + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID && + !ai_GetAIMode(oAssociate, AI_MODE_GHOST) && + GetLocalInt(oAssociate, sGhostModeVarname)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID && + !ai_GetAIMode(oAssociate, AI_MODE_GHOST) && + GetLocalInt(oAssociate, sGhostModeVarname)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + } +} +void ai_RemoveAllActionMode(object oPC) +{ + object oAssociate; + int nIndex; + for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) + { + ai_SetAIMode(oAssociate, AI_MODE_COMMANDED, FALSE); + if(ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST) && + !ai_GetAIMode(oAssociate, AI_MODE_GHOST) && + GetLocalInt(oAssociate, sGhostModeVarname)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + ExecuteScript("nw_ch_ac1", oAssociate); + } + } + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) + { + ai_SetAIMode(oAssociate, AI_MODE_COMMANDED, FALSE); + if(ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST) && + !ai_GetAIMode(oAssociate, AI_MODE_GHOST) && + GetLocalInt(oAssociate, sGhostModeVarname)) + { + ai_RemoveASpecificEffect(oAssociate, EFFECT_TYPE_CUTSCENEGHOST); + DeleteLocalInt(oAssociate, sGhostModeVarname); + } + ExecuteScript("nw_ch_ac1", oAssociate); + } + } +} +void ai_SelectTrap(object oPC, object oAssociate, object oItem) +{ + if(GetBaseItemType(oItem) != BASE_ITEM_TRAPKIT) + { + ai_SendMessages("A trap kit was not selected.", AI_COLOR_YELLOW, oPC); + return; + } + ai_SendMessages("Now select a location to place the trap.", AI_COLOR_YELLOW, oPC); + SetLocalObject(oAssociate, "AI_TRAP_KIT", oItem); + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_PLACE_TRAP"); + OpenInventory(oAssociate, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_PlaceTrap(object oPC, location lLocation) +{ + object oItem = GetLocalObject(OBJECT_SELF, "AI_TRAP_KIT"); + itemproperty ipTrap = GetFirstItemProperty(oItem); + if(GetItemPropertyType(ipTrap) == ITEM_PROPERTY_TRAP) + { + ActionUseItemAtLocation(oItem, ipTrap, lLocation); + } + else ai_SendMessages("This trap kit does not have a trap property!", AI_COLOR_YELLOW, oPC); +} +void ai_AddToGroup(object oDM, object oTarget, string sTargetMode) +{ + string sGroup = GetStringRight(sTargetMode, 1); + if(oDM == oTarget) + { + ai_SendMessages("Group " + sGroup + " has been cleared.", AI_COLOR_YELLOW, oDM); + string sText = "Group " + sGroup; + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText + " (Left Action/Right Add)")); + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_COMMAND_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText + " (Left Action/Right Add)")); + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_COMMAND_NUI), "btn_cmd_group" + sGroup + "_label", JsonString(sText)); + DeleteLocalJson(oDM, "DM_GROUP" + sGroup); + return; + } + string sName = GetName(oTarget); + json jGroup = GetLocalJson(oDM, "DM_GROUP" + sGroup); + if(JsonGetType(jGroup) == JSON_TYPE_NULL) + { + string sText = sName + "'s group"; + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText + " [Run]")); + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_COMMAND_NUI), "btn_cmd_group" + sGroup + "_tooltip", JsonString(sText + " [Run]")); + NuiSetBind(oDM, NuiFindWindow(oDM, "dm" + AI_COMMAND_NUI), "btn_cmd_group" + sGroup + "_label", JsonString(sText)); + jGroup = JsonArrayInsert(JsonArray(), JsonInt(1)); + } + string sUUID = GetObjectUUID(oTarget); + int nIndex = 1; + string sListUUID = JsonGetString(JsonArrayGet(jGroup, nIndex)); + while(sListUUID != "") + { + if(sListUUID == sUUID) + { + ai_SendMessages("This creature is already in the group!", AI_COLOR_RED, oDM); + return; + } + sListUUID = JsonGetString(JsonArrayGet(jGroup, ++nIndex)); + } + jGroup = JsonArrayInsert(jGroup, JsonString(sUUID)); + ai_SendMessages(sName + " has been saved to group" + sGroup, AI_COLOR_YELLOW, oDM); + SetLocalJson(oDM, "DM_GROUP" + sGroup, jGroup); + EnterTargetingMode(oDM, OBJECT_TYPE_CREATURE, MOUSECURSOR_PICKUP, MOUSECURSOR_PICKUP_DOWN); +} +void ai_MonsterAction(object oDM, object oTarget, location lLocation, int bRun, int nIndex) +{ + object oCreature = OBJECT_SELF; + int nObjectType = GetObjectType(oTarget); + ai_ClearCreatureActions(TRUE); + if(oTarget == GetArea(oDM)) + { + ActionMoveToLocation(lLocation, bRun); + } + else if(nObjectType == OBJECT_TYPE_CREATURE) + { + if(GetIsDead(oTarget)) return; + else if(GetIsEnemy(oTarget, oCreature)) + { + // Lock them into attacking this target only. + SetLocalObject(oCreature, AI_PC_LOCKED_TARGET, oTarget); + // This resets a creatures failed Moral save in combat. + if(GetLocalString(oCreature, AI_COMBAT_SCRIPT) == "ai_coward") + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, GetLocalString(oCreature, AI_DEFAULT_SCRIPT)); + } + if(ai_GetIsInCombat(oCreature)) ai_DoMonsterCombatRound(oCreature); + else + { + ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:"); + ai_StartMonsterCombat(oCreature); + } + if(nIndex == 1) + { + ai_SendMessages(GetName(oCreature) + "'s group is attacking " + GetName(oTarget), AI_COLOR_RED, oDM); + } + } + else if(oTarget == oDM) + { + if(GetLocalInt(oCreature, "AI_FOLLOWING_DM")) + { + ClearAllActions(FALSE, oCreature); + DeleteLocalInt(oCreature, "AI_FOLLOWING_DM"); + if(nIndex == 1) + { + ai_SendMessages(GetName(oCreature) + "'s group has stopped following you.", AI_COLOR_RED, oDM); + } + } + else + { + ActionForceFollowObject(oDM, 4.0); + SetLocalInt(oCreature, "AI_FOLLOWING_DM", TRUE); + if(nIndex == 1) + { + ai_SendMessages(GetName(oCreature) + "'s group is following you.", AI_COLOR_RED, oDM); + } + } + } + else + { + ActionMoveToObject(oTarget, TRUE); + // Player will be stuck with this variable if they are not using the AI. + DeleteLocalInt(oTarget, "AI_I_AM_BEING_HEALED"); + ActionDoCommand(ai_ActionTryHealing(oCreature, oTarget)); + if(nIndex == 1) + { + ai_SendMessages(GetName(oCreature) + "'s group is moving to and attempting to heal " + GetName(oTarget), AI_COLOR_RED, oDM); + } + } + } + else if(nObjectType == OBJECT_TYPE_DOOR) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oDM)) SetTrapDetectedBy(oTarget, oCreature); + if(GetTrapDetectedBy(oTarget, oCreature)) + { + ai_ReactToTrap(oCreature, oTarget, TRUE); + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + else if(GetLocked(oTarget)) ai_AttemptToByPassLock(oCreature, oTarget); + } + else if(GetLocked(oTarget)) ai_AttemptToByPassLock(oCreature, oTarget); + else if(GetIsOpen(oTarget)) + { + ActionCloseDoor(oTarget, TRUE); + } + else ActionOpenDoor(oTarget, TRUE); + } + else if(nObjectType == OBJECT_TYPE_ITEM) + { + ActionPickUpItem(oTarget); + } + else if(nObjectType == OBJECT_TYPE_PLACEABLE) + { + ActionMoveToObject(oTarget, TRUE); + if(GetHasInventory(oTarget)) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oDM)) SetTrapDetectedBy(oTarget, oCreature); + if(GetTrapDetectedBy(oTarget, oCreature)) + { + ai_ReactToTrap(oCreature, oTarget, TRUE); + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + if(GetLocked(oTarget)) + { + if(!ai_AttemptToByPassLock(oCreature, oTarget)) + { + AssignCommand(oCreature, ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oTarget) + " is locked!")); + } + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE); + } + else if(GetLocked(oTarget)) + { + if(ai_AttemptToByPassLock(oCreature, oTarget)) + { + AssignCommand(oCreature, ai_HaveCreatureSpeak(oCreature, 0, "This " + GetName(oTarget) + " is locked!")); + } + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); + return; + } + ActionDoCommand(ai_SearchObject(oCreature, oTarget, oDM, TRUE)); + } + DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE); + } + else if(nObjectType == OBJECT_TYPE_TRIGGER) + { + if(GetIsTrapped(oTarget)) + { + if(GetTrapDetectedBy(oTarget, oDM)) SetTrapDetectedBy(oTarget, oCreature); + if(GetTrapDetectedBy(oTarget, oCreature)) ai_ReactToTrap(oCreature, oTarget, TRUE); + } + } + EnterTargetingMode(oDM, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK); +} +void ai_DMAction(object oDM, object oTarget, location lLocation, string sTargetMode) +{ + string sGroup = GetStringRight(sTargetMode, 1); + json jGroup = GetLocalJson(oDM, "DM_GROUP" + sGroup); + int bRun = JsonGetInt(JsonArrayGet(jGroup, 0)); + int nIndex = 1; + string sUUID = JsonGetString(JsonArrayGet(jGroup, nIndex)); + object oCreature; + while(sUUID != "") + { + oCreature = GetObjectByUUID(sUUID); + AssignCommand(oCreature, ai_MonsterAction(oDM, oTarget, lLocation, bRun, nIndex)); + sUUID = JsonGetString(JsonArrayGet(jGroup, ++nIndex)); + } + if(nIndex == 0) ai_SendMessages("Group" + sGroup + " is empty!", AI_COLOR_RED, oDM); +} +void ai_SelectWidgetSpellTarget(object oPC, object oAssociate, string sElem) +{ + int nIndex; + if(GetStringLength(sElem) == 13) nIndex = StringToInt(GetStringRight(sElem, 2)); + else nIndex = StringToInt(GetStringRight(sElem, 1)); + SetLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX", nIndex); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jSpell = JsonArrayGet(jWidget, nIndex); + int nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + int nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + if(nClass == -1) // This is an Item. + { + object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5))); + int nBaseItemType = GetBaseItemType(oItem); + if(Get2DAString("spells", "Range", nSpell) == "P" || // Self + nBaseItemType == BASE_ITEM_ENCHANTED_POTION || + nBaseItemType == BASE_ITEM_POTIONS) + { + int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4)); + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(nIprpSubType == GetItemPropertySubType(ipProperty)) break; + ipProperty = GetNextItemProperty(oItem); + } + if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + AssignCommand(oAssociate, ActionUseItemOnObject(oItem, ipProperty, oAssociate)); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + return; + } + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_USE_ITEM"); + if(nSpell == SPELL_HEALINGKIT) + { + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_MAGIC, MOUSECURSOR_NOMAGIC); + return; + } + } + else // Feats, Spells, Special Abilities. + { + int nFeat = JsonGetInt(JsonArrayGet(jSpell, 5)); + if(nFeat) + { + if(!nSpell || Get2DAString("spells", "Range", nSpell) == "P" || // Self + nFeat == FEAT_SUMMON_FAMILIAR || nFeat == FEAT_ANIMAL_COMPANION || + nFeat == FEAT_TURN_UNDEAD) + { + if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + // Adjust the spell used for wild shape and other shape feats. + if(nFeat == FEAT_WILD_SHAPE) nSpell += 607; + if(nFeat == FEAT_ELEMENTAL_SHAPE) + { + if(nSpell == 397) nSpell == SUBFEAT_ELEMENTAL_SHAPE_FIRE; + else if(nSpell == 398) nSpell == SUBFEAT_ELEMENTAL_SHAPE_WATER; + else if(nSpell == 399) nSpell == SUBFEAT_ELEMENTAL_SHAPE_EARTH; + else if(nSpell == 400) nSpell == SUBFEAT_ELEMENTAL_SHAPE_AIR; + } + // Do special targeting for attack feats. + if(nFeat == FEAT_STUNNING_FIST || nFeat == FEAT_DIRTY_FIGHTING || + nFeat == FEAT_WHIRLWIND_ATTACK || nFeat == FEAT_QUIVERING_PALM || + nFeat == FEAT_KNOCKDOWN || nFeat == FEAT_IMPROVED_KNOCKDOWN || + nFeat == FEAT_SAP || nFeat == FEAT_KI_DAMAGE || + nFeat == FEAT_DISARM || nFeat == FEAT_IMPROVED_DISARM || + nFeat == FEAT_SMITE_EVIL || nFeat == FEAT_SMITE_GOOD) + { + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_USE_FEAT"); + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_ATTACK, MOUSECURSOR_NOATTACK); + } + // Check feat and adjust if it is an action mode feat. + if(ai_SetActionMode(oAssociate, nFeat)) return; + AssignCommand(oAssociate, ActionUseFeat(nFeat, oAssociate, nSpell)); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + return; + } + SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_USE_FEAT"); + } + else SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_CAST_SPELL"); + } + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate); + int nObjectType; + string sTarget = Get2DAString("spells", "TargetType", nSpell); + int nTarget = ai_HexStringToInt(sTarget); + //SendMessageToPC(GetFirstPC(), "nTarget: " + IntToString(nTarget)); + if((nTarget & 1) && !(nTarget & 2) &&!(nTarget & 4)) + { + if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + ai_CastWidgetSpell(oPC, oAssociate, oAssociate, GetLocation(oAssociate)); + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate)); + return; + } + if((nTarget & 1) || (nTarget & 2)) nObjectType += OBJECT_TYPE_CREATURE; + if(nTarget & 4) nObjectType += OBJECT_TYPE_TILE; + if(nTarget & 8) nObjectType += OBJECT_TYPE_ITEM; + if(nTarget & 16) nObjectType += OBJECT_TYPE_DOOR; + if(nTarget & 32) nObjectType += OBJECT_TYPE_PLACEABLE; + if(nTarget & 64) nObjectType += OBJECT_TYPE_TRIGGER; + string sShape = Get2DAString("spells", "TargetShape", nSpell); + int nShape, nSetData; + float fRange; + if(oPC == oAssociate) + { + nSetData = TRUE; + fRange = ai_GetSpellRange(nSpell); + if(fRange == 0.1) fRange = 0.0; + } + if(sShape == "sphere") + { + nShape = SPELL_TARGETING_SHAPE_SPHERE; + nSetData = TRUE; + } + else if(sShape == "rectangle") + { + nShape = SPELL_TARGETING_SHAPE_RECT; + nSetData = TRUE; + } + else if(sShape == "hsphere") + { + nShape = SPELL_TARGETING_SHAPE_HSPHERE; + nSetData = TRUE; + } + else if(sShape == "cone") nShape = SPELL_TARGETING_SHAPE_CONE; + else nShape = SPELL_TARGETING_SHAPE_NONE; + if(nSetData) + { + float fSizeX = StringToFloat(Get2DAString("spells", "TargetSizeX", nSpell)); + float fSizeY = StringToFloat(Get2DAString("spells", "TargetSizeY", nSpell)); + int nFlags = StringToInt(Get2DAString("spells", "TargetFlags", nSpell)); + SetEnterTargetingModeData(oPC, nShape, fSizeX, fSizeY, nFlags, fRange); + } + EnterTargetingMode(oPC, nObjectType, MOUSECURSOR_MAGIC, MOUSECURSOR_NOMAGIC); +} +void ai_UpdateAssociateWidget(object oPC, object oAssociate) +{ + int nUIToken = NuiFindWindow(oPC, ai_GetAssociateType(oPC, oAssociate) + AI_WIDGET_NUI); + if(nUIToken) + { + DelayCommand(0.0, NuiDestroy(oPC, nUIToken)); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate)); + /* Not sure why I did this? + if(oPC != oAssociate) + { + nUIToken = NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI); + if(nUIToken) + { + DelayCommand(0.0, NuiDestroy(oPC, nUIToken)); + DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC)); + } + } */ + } +} +int ai_SetActionMode(object oAssociate, int nFeat) +{ + int nMode; + if(nFeat == FEAT_POWER_ATTACK) nMode = ACTION_MODE_POWER_ATTACK; + else if(nFeat == FEAT_RAPID_SHOT) nMode = ACTION_MODE_RAPID_SHOT; + else if(nFeat == FEAT_FLURRY_OF_BLOWS) nMode = ACTION_MODE_FLURRY_OF_BLOWS; + else if(nFeat == FEAT_IMPROVED_POWER_ATTACK) nMode = ACTION_MODE_IMPROVED_POWER_ATTACK; + else if(nFeat == FEAT_EXPERTISE) nMode = ACTION_MODE_EXPERTISE; + else if(nFeat == FEAT_IMPROVED_EXPERTISE) nMode = ACTION_MODE_IMPROVED_EXPERTISE; + else if(nFeat == FEAT_DIRTY_FIGHTING) nMode = ACTION_MODE_DIRTY_FIGHTING; + if(nMode) + { + SetActionMode(oAssociate, nMode, !GetActionMode(oAssociate, nMode)); + return TRUE; + } + return FALSE; +} diff --git a/src/module/nss/0i_spells.nss b/src/module/nss/0i_spells.nss new file mode 100644 index 0000000..b7b75e2 --- /dev/null +++ b/src/module/nss/0i_spells.nss @@ -0,0 +1,2157 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// + Script Name: 0i_spells + Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts for base spells. + +Category: + Enhancement E + Protection P +Indiscriminant I + Discriminant D + Range R + Touch T + Summon S + Healing H + Cure C + +Buff Duration: +1 - All +2 - Short +3 - Long + +Buff Target: + 0 - Caster only + 1-6 Str, Dex, Con, Int, Wis, Cha: Highest Ability Score + 7 - Lowest AC + 8 - Lowest AC without AC Bonus + 9 - Highest Atk + 10 - Most Wounded + 11 - Lowest Fortitude + 12 - Lowest Reflex + 13 - Lowest Will + 14 - Lowest total saves + 15 - Buffs an Item + +Buff Groups: +-1 - Elemental Resistances. +-2 - Summons +-3 - AC (Non armor) +-4 - AC (for Armor/Shield) +-5 - Chance to Miss (Invisibility) +-6 - Regeneration +-7 - Globes of Invulnerablitity +-8 - Damage Reduction +-9 - Mantles +-10 - Alignment vs Chaos +-11 - Alignment vs Evil +-12 - Alignment vs Good +-13 - Alignment vs Law +-14 - Atk Bonus (for Weapon) +-15 - Light effects +-16 - Haste effects +-17 - Polymorph effects +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_messages" +#include "0i_states_cond" +#include "0i_items" +#include "X0_I0_POSITION" +struct stSpell +{ + object oPC; + object oCaster; + object oTarget; + int nBuffType; + int nTarget; + int nPosition; + int nClass; + int nLevel; + int nMaxSlots; + int nSlot; +}; +// Returns TRUE if oCreature can cast nSpell from nLevel. +int ai_GetCanCastSpell(object oCreature, int nSpell, int nClass, int nLevel, int nMetaMagic = 0, int nDomain = 0); +// Returns TRUE if oCreature is immune to petrification. +int ai_IsImmuneToPetrification(object oCaster, object oCreature); +// Returns TRUE if oCreature has an effect from a mind affecting spell. +int ai_DoIHaveAMindAffectingSpellOnMe(object oCreature); +// Returns TRUE if nSpell is a cure spell. +int ai_IsCureSpell(int nSpell); +// Returns TRUE if nSpell is an inflict spell. +int ai_IsInflictSpell(int nSpell); +// Returns TRUE if nSpell is an area of effect spell. +int ai_IsAreaOfEffectSpell(int nSpell); +// Returns 1(TRUE) if oAssociate is a spellcaster. +// Rturns 2(TRUE) if oAssociate is a memorizing spellcaster. +int ai_GetIsSpellCaster(object oAssociate); +// Returns TRUE if oCreature is immune to nSpells effects. +int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell); +// Returns the ranged of nSpell from the spells.2da(Column "Range"). +// S = 8.0f, M = 20.0f, L = 40.0f, T = 5.0f, else = 0.1f; +float ai_GetSpellRange(int nSpell); +// Returns TRUE if oTarget has a spell that we would want to dispel. +// Checks for harmful effects as well as buffing effects. +int ai_CreatureHasDispelableEffect(object oCaster, object oCreature); +// Remove nEffectType of Type specified on oCreature; +// nEffectType uses the constants EFFECT_TYPE_* +void ai_RemoveASpecificEffect(object oCreature, int nEffectType); +// Returns TRUE if oCreature has nEffectType. +// nEffectType uses the constants EFFECT_TYPE_* +int ai_GetHasEffectType(object oCreature, int nEffectType); +// Checks oCreature for special abilities have a long duration. +void ai_CheckCreatureSpecialAbilities(object oCreature); +// Checks oCreature for the silence effect and if the spell only has a somatic component. +int ai_IsSilenced(object oCreature, int nSpell); +// Returns TRUE if ArcaneSpellFailure is too high to chance casting the spell. +int ai_ArcaneSpellFailureTooHigh(object oCreature, int nClass, int nLevel, int nSlot); +// Returns TRUE if oCaster casts nSpell on oTarget. +// This will only cast the spell if oTarget DOES NOT already have the spell +// effect, and the caster has the spell ready. +int ai_TryToCastSpell(object oCaster, int nSpell, object oTarget); +// In "Buff_Target" column the value of 0 in the "ai_spells.2da" references the Caster. +// In "Buff_Target" column this is value 1-6(STR, DEX, CON, INT, WIS, CHA) in the "ai_spells.2da". +object ai_BuffHighestAbilityScoreTarget(object oCaster, int nSpell, int nAbilityScore, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 7 in the "ai_spells.2da". +object ai_BuffLowestACTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 8 in the "ai_spells.2da". +object ai_BuffLowestACWithOutACBonus(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 9 in the "ai_spells.2da". +object ai_BuffHighestAttackTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 10 in the "ai_spells.2da". +object ai_BuffMostWoundedTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 11 in the "ai_spells.2da". +object ai_BuffLowestFortitudeSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 12 in the "ai_spells.2da". +object ai_BuffLowestReflexSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 13 in the "ai_spells.2da". +object ai_BuffLowestWillSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 14 in the "ai_spells.2da". +object ai_BuffLowestSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// In "Buff_Target" column this is value 15 in the "ai_spells.2da". +object ai_BuffItemTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_"); +// Returns a target for nSpell cast by oCaster based on ai_spells.2da file. +object ai_GetBuffTarget(object oCaster, int nSpell); +// Casts a memorized spell from oCaster of nClass, nSpellLevel, nSpellSlot on oTarget. +void ai_CastMemorizedSpell(object oCaster, int nClass, int nSpellLevel, int nSpellSlot, object oTarget, int bInstant, object oPC = OBJECT_INVALID); +// Casts a known spell from oCaster of nClass, nSpell on oTarget. +void ai_CastKnownSpell(object oCaster, int nClass, int nSpell, object oTarget, int bInstant, object oPC = OBJECT_INVALID); +// Returns true if the spell is cast. +// Checks if they have the spell and will cast it if possible. +int ai_CheckAndCastSpell(object oCaster, int nSpell, int nSpellGroup, float fDelay, object oTarget, object oPC = OBJECT_INVALID); +// Setup monsters for oCaster to buff in ai_CastSpells. +void ai_SetupMonsterBuffTargets(object oCaster); +// Setup the targets for an NPC to buff one of the PC's members or the whole group. +void ai_SetupAllyTargets(object oCaster, object oPC); +// Setup the targets for an NPC to heal one of the PC's members. +void ai_SetupAllyHealingTargets(object oCaster, object oPC); +// Clears the casters buff targets. +void ai_ClearBuffTargets(object oCaster, string sVariable); +// Cycles through a casters spells casting all buffs via actions. +void ai_ActionCastMemorizedBuff(struct stSpell stSpell); +// Cycles through a casters spells casting all buffs via actions. +void ai_ActionCastKnownBuff(struct stSpell stSpell); +// Checks oCaster for buffing spells and casts them based on nTarget; +// These are cast as actions and will happen at the speed based on +// AI_HENCHMAN_BUFF_DELAY, but are still actions. +// nTarget is 0-9 where 0 is all targets, 1 is oPC, 2 is the caster +// 3 Familiar, 4 is Animal Companion, 5 is Summons, 6 is Dominated, and 7+ is henchman. +// Targets must be defined in variable AI_ALLY_TARGET_* where * is 1 to #. +// nBuffType is the duration 1 - all, 2 - short, 3 - long. +void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC); +// Returns TRUE if oCaster cast spontaneous cure spell on oTarget. +// This uses an action and must use AssignCommand or OBJECT_SELF is the caster! +int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC); +// Returns TRUE if oCaster casts a memorized cure spell on oTarget. +// This uses an action and must use AssignCommand or OBJECT_SELF is the caster! +int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass); +// Returns TRUE if oCaster casts a known cure spell on oTarget. +// This uses an action and must use AssignCommand or OBJECT_SELF is the caster! +int ai_CastKnownHealing(object oCreature, object oTarget, object oPC, int nClass); +// Returns TRUE if oCreature has an effect that will break their concentration. +int ai_ConcentrationCondition(object oCreature); +// Check to see if a spell's concentration has been broken, works for summons as well. +void ai_SpellConcentrationCheck(object oCaster); +// Returns TRUE if oCreature can safely cast nSpell defensively or has a good +// chance of casting while in melee. +int ai_CastInMelee(object oCreature, int nSpell, int nInMelee); +// Returns a float range for the caster to search for a target of an offensive spell. +float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell); +// Returns TRUE if nSpell is a cure spell and will not over heal for nDamage. +int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage); +// Casts the spell on the current target for oAssociate. +void ai_CastWidgetSpell(object oPC, object oAssociate, object oTarget, location lLocation); +// Uses the feat on the current target for oAssociate. +void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lLocation); +// Uses the item on the current target for oAssociate. +void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lLocation); +int ai_GetCanCastSpell(object oCreature, int nSpell, int nClass, int nLevel, int nMetaMagic = 0, int nDomain = 0) +{ + int nIndex, nSpellCount, nClassPosition, nSlot, nMaxSlots, nPosition = 1; + while(nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + nClassPosition = GetClassByPosition(nPosition, oCreature); + if(nClassPosition == CLASS_TYPE_INVALID) return FALSE; + if(nClass = nClassPosition) + { + if(Get2DAString("classes", "SpellCaster", nClass) == "1") + { + nSlot = 0; + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel); + while(nSlot < nMaxSlots) + { + if(GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot) == nSpell && + GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot)) return TRUE; + nSlot++; + } + } + else return GetSpellUsesLeft(oCreature, nClass, nSpell, nMetaMagic, nDomain); + } + } + nPosition++; + } + return FALSE; +} +int ai_IsImmuneToPetrification(object oCaster, object oCreature) +{ + int nAppearance = GetAppearanceType(oCreature); + switch(nAppearance) + { + case APPEARANCE_TYPE_BASILISK: + case APPEARANCE_TYPE_COCKATRICE: + case APPEARANCE_TYPE_MEDUSA: + case APPEARANCE_TYPE_ALLIP: + case APPEARANCE_TYPE_ELEMENTAL_AIR: + case APPEARANCE_TYPE_ELEMENTAL_AIR_ELDER: + case APPEARANCE_TYPE_ELEMENTAL_EARTH: + case APPEARANCE_TYPE_ELEMENTAL_EARTH_ELDER: + case APPEARANCE_TYPE_ELEMENTAL_FIRE: + case APPEARANCE_TYPE_ELEMENTAL_FIRE_ELDER: + case APPEARANCE_TYPE_ELEMENTAL_WATER: + case APPEARANCE_TYPE_ELEMENTAL_WATER_ELDER: + case APPEARANCE_TYPE_GOLEM_STONE: + case APPEARANCE_TYPE_GOLEM_IRON: + case APPEARANCE_TYPE_GOLEM_CLAY: + case APPEARANCE_TYPE_GOLEM_BONE: + case APPEARANCE_TYPE_GORGON: + case APPEARANCE_TYPE_HEURODIS_LICH: + case APPEARANCE_TYPE_LANTERN_ARCHON: + case APPEARANCE_TYPE_SHADOW: + case APPEARANCE_TYPE_SHADOW_FIEND: + case APPEARANCE_TYPE_SHIELD_GUARDIAN: + case APPEARANCE_TYPE_SKELETAL_DEVOURER: + case APPEARANCE_TYPE_SKELETON_CHIEFTAIN: + case APPEARANCE_TYPE_SKELETON_COMMON: + case APPEARANCE_TYPE_SKELETON_MAGE: + case APPEARANCE_TYPE_SKELETON_PRIEST: + case APPEARANCE_TYPE_SKELETON_WARRIOR: + case APPEARANCE_TYPE_SKELETON_WARRIOR_1: + case APPEARANCE_TYPE_SPECTRE: + case APPEARANCE_TYPE_WILL_O_WISP: + case APPEARANCE_TYPE_WRAITH: + case APPEARANCE_TYPE_BAT_HORROR: + case 405: // Dracolich: + case 415: // Alhoon + case 418: // shadow dragon + case 420: // mithral golem + case 421: // admantium golem + case 430: // Demi Lich + case 469: // animated chest + case 474: // golems + case 475: // golems + return TRUE; + } + // Petrification immunity can also be granted as an item property. + if(ResistSpell(oCaster, oCreature) == 2 ) return TRUE; + // Prevent people from petrifying DM, resulting in GUI even when effect is not successful. + if(!GetPlotFlag(oCreature) && GetIsDM(oCreature)) return TRUE; + return FALSE; +} +int ai_DoIHaveAMindAffectingSpellOnMe(object oCreature) +{ + if(GetHasSpellEffect(SPELL_SLEEP, oCreature) || + GetHasSpellEffect(SPELL_DAZE, oCreature) || + GetHasSpellEffect(SPELL_HOLD_ANIMAL, oCreature) || + GetHasSpellEffect(SPELL_HOLD_MONSTER, oCreature) || + GetHasSpellEffect(SPELL_HOLD_PERSON, oCreature) || + GetHasSpellEffect(SPELL_CHARM_MONSTER, oCreature) || + GetHasSpellEffect(SPELL_CHARM_PERSON, oCreature) || + GetHasSpellEffect(SPELL_CHARM_PERSON_OR_ANIMAL, oCreature) || + GetHasSpellEffect(SPELL_MASS_CHARM, oCreature) || + GetHasSpellEffect(SPELL_DOMINATE_ANIMAL, oCreature) || + GetHasSpellEffect(SPELL_DOMINATE_MONSTER, oCreature) || + GetHasSpellEffect(SPELL_DOMINATE_PERSON, oCreature) || + GetHasSpellEffect(SPELL_CONFUSION, oCreature) || + GetHasSpellEffect(SPELL_MIND_FOG, oCreature) || + GetHasSpellEffect(SPELL_CLOUD_OF_BEWILDERMENT, oCreature) || + GetHasSpellEffect(SPELLABILITY_BOLT_DOMINATE,oCreature) || + GetHasSpellEffect(SPELLABILITY_BOLT_CHARM,oCreature) || + GetHasSpellEffect(SPELLABILITY_BOLT_CONFUSE,oCreature) || + GetHasSpellEffect(SPELLABILITY_BOLT_DAZE,oCreature)) return TRUE; + return FALSE; +} +int ai_IsCureSpell(int nSpell) +{ + switch(nSpell) + { + case SPELL_CURE_CRITICAL_WOUNDS: + case SPELL_CURE_LIGHT_WOUNDS: + case SPELL_CURE_MINOR_WOUNDS: + case SPELL_CURE_MODERATE_WOUNDS: + case SPELL_CURE_SERIOUS_WOUNDS: + case SPELL_HEAL: return TRUE; break; + } + return FALSE; +} +int ai_IsInflictSpell(int nSpell) +{ + switch(nSpell) + { + case SPELL_INFLICT_CRITICAL_WOUNDS: + case SPELL_INFLICT_LIGHT_WOUNDS: + case SPELL_INFLICT_MINOR_WOUNDS: + case SPELL_INFLICT_MODERATE_WOUNDS: + case SPELL_INFLICT_SERIOUS_WOUNDS: + case SPELL_HARM: return TRUE; break; + } + return FALSE; +} +int ai_IsAreaOfEffectSpell(int nSpell) +{ + switch(nSpell) + { + case SPELL_ACID_FOG : + case SPELL_MIND_FOG : + case SPELL_STORM_OF_VENGEANCE: + case SPELL_WEB : + case SPELL_GREASE : + case SPELL_CREEPING_DOOM : +// case SPELL_DARKNESS : + case SPELL_SILENCE : + case SPELL_BLADE_BARRIER : + case SPELL_CLOUDKILL : + case SPELL_STINKING_CLOUD : + case SPELL_WALL_OF_FIRE : + case SPELL_INCENDIARY_CLOUD : + case SPELL_ENTANGLE : + case SPELL_EVARDS_BLACK_TENTACLES: + case SPELL_CLOUD_OF_BEWILDERMENT : + case SPELL_STONEHOLD : + case SPELL_VINE_MINE : + case SPELL_SPIKE_GROWTH : + case SPELL_DIRGE : + case 530 : // vine mine + case 531 : // vine mine + case 532 : // vine mine + case 961 : // Prismatic Sphere + return TRUE; + } + return FALSE; +} +int ai_GetIsSpellCaster(object oAssociate) +{ + int nIndex, nSpellCaster, nClass; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass == CLASS_TYPE_INVALID) return nSpellCaster; + if(Get2DAString("classes", "SpellCaster", nClass) == "1") + { + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") return 2; + else nSpellCaster = 1; + } + } + return nSpellCaster; +} +int ai_GetIsSpellBookRestrictedCaster(object oAssociate) +{ + int nIndex, nSpellCaster, nClass; + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++) + { + nClass = GetClassByPosition(nIndex, oAssociate); + if(nClass == CLASS_TYPE_INVALID) return FALSE; + if(Get2DAString("classes", "SpellbookRestricted", nClass) == "1") return TRUE; + } + return FALSE; +} +int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell) +{ + string sIType = Get2DAString("ai_spells", "ImmunityType", nSpell); + if(sIType != "") + { + if(AI_DEBUG) ai_Debug("0i_spells", "290", "Checking spell immunity type(" + sIType + ")."); + if(sIType == "Death" && GetIsImmune(oCreature, IMMUNITY_TYPE_DEATH)) return TRUE; + else if(sIType == "Level_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_NEGATIVE_LEVEL)) return TRUE; + else if(sIType == "Ability_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_ABILITY_DECREASE)) return TRUE; + else if(sIType == "Poison" && GetIsImmune(oCreature, IMMUNITY_TYPE_POISON)) return TRUE; + else if(sIType == "Disease" && GetIsImmune(oCreature, IMMUNITY_TYPE_DISEASE)) return TRUE; + else if(sIType == "Curse" && GetIsImmune(oCreature, IMMUNITY_TYPE_CURSED)) return TRUE; + else if(sIType == "Mind_Affecting" && GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS)) return TRUE; + else if(sIType == "Petrification" && ai_IsImmuneToPetrification(oCaster, oCreature)) return TRUE; + else if(sIType == "Fear" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_FEAR) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Sleep" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_SLEEP) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Paralysis" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_PARALYSIS) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Domination" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_DOMINATE) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Confusion" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_CONFUSED) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Blindness" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_BLINDNESS) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Dazed" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_DAZED) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + else if(sIType == "Charm" && + (GetIsImmune(oCreature, IMMUNITY_TYPE_CHARM) || + GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE; + // Check for damage immunities. + // Negative damage does not work on undead! + else if(sIType == "Negative" && GetRacialType(oCreature) == RACIAL_TYPE_UNDEAD) + { + if(AI_DEBUG) ai_Debug("0i_spell", "325", "Undead are immune to Negative energy!"); + return TRUE; + } + // Elemental damage resistances should be checked. + if(sIType == "Acid" || sIType == "Cold" || sIType == "Fire" || + sIType == "Electricty" || sIType == "Sonic") + { + if(ai_GetHasEffectType(oCreature, EFFECT_TYPE_DAMAGE_RESISTANCE)) + { + if(AI_DEBUG) ai_Debug("0i_spell", "334", GetName(oCreature) + " has damage resistance to my " + sIType + " spell!"); + return TRUE; + } + // Check for resistances and immunities. Treat resistance as immune. + int nIPResist = GetLocalInt(oCreature, sIPResistVarname); + if(AI_DEBUG) ai_Debug("0i_spell", "372", "nIPResist:" + IntToString(nIPResist)); + int nIPImmune = GetLocalInt(oCreature, sIPImmuneVarname) | nIPResist; + if(AI_DEBUG) ai_Debug("0i_spell", "374", "nIPImmune:" + IntToString(nIPImmune)); + if(nIPImmune > 0) + { + if(AI_DEBUG) ai_Debug("0i_spell", "391", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell through an item!"); + if(sIType == "Acid" && (nIPImmune & DAMAGE_TYPE_ACID)) return TRUE; + else if(sIType == "Cold" && (nIPImmune & DAMAGE_TYPE_COLD)) return TRUE; + else if(sIType == "Fire" && (nIPImmune & DAMAGE_TYPE_FIRE)) return TRUE; + else if(sIType == "Electricity" && (nIPImmune & DAMAGE_TYPE_ELECTRICAL)) return TRUE; + else if(sIType == "Sonic" && (nIPImmune & DAMAGE_TYPE_SONIC)) return TRUE; + } + } + } + int nLevel = StringToInt(Get2DAString("spells", "Innate", nSpell)); + // Globe spells should be checked... + if((GetHasSpellEffect(SPELL_MINOR_GLOBE_OF_INVULNERABILITY, oCreature) || + GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MINOR_GLOBE, oCreature)) && + nLevel < 4 && d100() < 75) return TRUE; + if(GetHasSpellEffect(SPELL_GLOBE_OF_INVULNERABILITY, oCreature) && + nLevel < 5 && d100() < 75) return TRUE; + // Check creatures items for immunity. + int nIndex; + json jSpellImmunity = GetLocalJson(oCreature, AI_TALENT_IMMUNITY); + json jSpell = JsonArrayGet(jSpellImmunity, nIndex); + while(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + if(nSpell == JsonGetInt(jSpell)) + { + if(AI_DEBUG) ai_Debug("0i_spells", "407", GetName(oCreature) + " is immune to the spell via an Item!"); + return TRUE; + } + jSpell = JsonArrayGet(jSpellImmunity, ++nIndex); + } + if(AI_DEBUG) ai_Debug("0i_spell", "347", GetName(oCreature) + " is not immune to the spell."); + return FALSE; +} +float ai_GetSpellRange(int nSpell) +{ + string sRange = Get2DAString("spells", "Range", nSpell); + if(sRange == "S") return AI_SHORT_DISTANCE; + else if(sRange == "M") return AI_MEDIUM_DISTANCE; + else if(sRange == "L") return AI_LONG_DISTANCE; + else if(sRange == "T") return AI_RANGE_MELEE; + return 0.1; +} +int ai_CreatureHasDispelableEffect(object oCaster, object oCreature) +{ + int nSpellID, nLastSpellID, bSpell, nDispelChance; + // Cycle through the targets effects. + effect eEffect = GetFirstEffect(oCreature); + if(AI_DEBUG) ai_Debug("0i_spells", "485", "nSpell: " + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", GetEffectSpellId(eEffect)))) + + " oCreature: " + GetName(oCreature)); + while(GetIsEffectValid(eEffect)) + { + nSpellID = GetEffectSpellId(eEffect); + // -1 is not a spell. + if(AI_DEBUG) ai_Debug("0i_spells", "491", "nSpell: (" + IntToString(nSpellID) + ") " + + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpellID)))); + if(nSpellID > -1 && nLastSpellID != nSpellID) + { + // We check if the spell is Hostile(-1) or Helpful(+1). + if(Get2DAString("ai_spells", "HostileSetting", nSpellID) == "1") nDispelChance--; + else nDispelChance++; + if(AI_DEBUG) ai_Debug("0i_spells", "497", "HostileSetting: " + Get2DAString("ai_spells", "HostileSetting", nSpellID) + + " nDispelChance: " + IntToString(nDispelChance)); + } + nLastSpellID = nSpellID; + eEffect = GetNextEffect(oCreature); + } + // if the target has more Helpful spells than harmful spells effecting them + // then use dispel! + if(AI_DEBUG) ai_Debug("0i_spells", "505", "nDispelChance: " + IntToString(nDispelChance)); + return (nDispelChance > 0); +} +void ai_RemoveASpecificEffect(object oCreature, int nEffectType) +{ + effect eEffect = GetFirstEffect(oCreature); + //Search for the effect. + while(GetIsEffectValid(eEffect)) + { + if(GetEffectType(eEffect) == nEffectType) + { + //Remove effect. + RemoveEffect(oCreature, eEffect); + eEffect = GetFirstEffect(oCreature); + } + else eEffect = GetNextEffect(oCreature); + } +} +int ai_GetHasEffectType(object oCreature, int nEffectType) +{ + effect eEffect = GetFirstEffect(oCreature); + while(GetIsEffectValid(eEffect)) + { + if(GetEffectType(eEffect, TRUE) == nEffectType) return TRUE; + eEffect = GetNextEffect(oCreature); + } + return FALSE; +} +void ai_CheckCreatureSpecialAbilities(object oCreature) +{ + int nMaxSpecialAbilities = GetSpellAbilityCount(oCreature); + if(nMaxSpecialAbilities) + { + int nIndex, bCanCast; + // Struct is id, ready, level. + int nSpell; + while(nIndex < nMaxSpecialAbilities) + { + nSpell = GetSpellAbilitySpell(oCreature, nIndex); + if(GetSpellAbilityReady(oCreature, nSpell)) + { + bCanCast = FALSE; + if(GetSpellAbilityCasterLevel(oCreature, nIndex) > 4) + { + // 1 Min/Lvl spell that is too low of level so it must be cast at 5th lvl or greater. + if(nSpell == SPELL_FLAME_WEAPON) bCanCast = TRUE; + else if(nSpell == SPELL_BLESS) bCanCast = TRUE; + else if(nSpell == SPELL_AID) bCanCast = TRUE; + else if(nSpell == SPELL_DEATH_WARD) bCanCast = TRUE; + } + if(nSpell == SPELL_ENERGY_BUFFER) bCanCast = TRUE; + else if(nSpell == SPELL_PROTECTION_FROM_ELEMENTS) bCanCast = TRUE; + else if(nSpell == SPELL_RESIST_ELEMENTS) bCanCast = TRUE; + else if(nSpell == SPELL_ENDURE_ELEMENTS) bCanCast = TRUE; + else if(nSpell == SPELL_MAGE_ARMOR) bCanCast = TRUE; + else if(nSpell == SPELL_MAGIC_VESTMENT) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_MAGIC_WEAPON) bCanCast = TRUE; + else if(nSpell == SPELL_MAGIC_WEAPON) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_IX) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_VIII) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_VII) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_VI) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_V) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_IV) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_III) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_II) bCanCast = TRUE; + else if(nSpell == SPELL_SUMMON_CREATURE_I) bCanCast = TRUE; + else if(nSpell == SPELL_BARKSKIN) bCanCast = TRUE; + else if(nSpell == SPELL_SHIELD) bCanCast = TRUE; + else if(nSpell == SPELL_ENTROPIC_SHIELD) bCanCast = TRUE; + else if(nSpell == SPELL_SHIELD_OF_FAITH) bCanCast = TRUE; + else if(nSpell == SPELL_REMOVE_FEAR) bCanCast = TRUE; + else if(nSpell == SPELL_IRONGUTS) bCanCast = TRUE; + else if(nSpell == SPELL_PREMONITION) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_STONESKIN) bCanCast = TRUE; + else if(nSpell == SPELL_GHOSTLY_VISAGE) bCanCast = TRUE; + else if(nSpell == SPELL_IMPROVED_INVISIBILITY) bCanCast = TRUE; + else if(nSpell == SPELL_INVISIBILITY_SPHERE) bCanCast = TRUE; + else if(nSpell == SPELL_INVISIBILITY) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_BULLS_STRENGTH) bCanCast = TRUE; + else if(nSpell == SPELL_BULLS_STRENGTH) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_CATS_GRACE) bCanCast = TRUE; + else if(nSpell == SPELL_CATS_GRACE) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_EAGLE_SPLENDOR) bCanCast = TRUE; + else if(nSpell == SPELL_EAGLE_SPLEDOR) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_ENDURANCE) bCanCast = TRUE; + else if(nSpell == SPELL_ENDURANCE) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_FOXS_CUNNING) bCanCast = TRUE; + else if(nSpell == SPELL_FOXS_CUNNING) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_OWLS_WISDOM) bCanCast = TRUE; + else if(nSpell == SPELL_OWLS_WISDOM) bCanCast = TRUE; + else if(nSpell == SPELL_KEEN_EDGE) bCanCast = TRUE; + else if(nSpell == SPELL_ANIMATE_DEAD) bCanCast = TRUE; + else if(nSpell == SPELL_INVISIBILITY_PURGE) bCanCast = TRUE; + else if(nSpell == SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE) bCanCast = TRUE; + else if(nSpell == SPELL_DARKFIRE) bCanCast = TRUE; + else if(nSpell == SPELL_NEGATIVE_ENERGY_PROTECTION) bCanCast = TRUE; + else if(nSpell == SPELL_MAGIC_CIRCLE_AGAINST_GOOD) bCanCast = TRUE; + else if(nSpell == SPELL_FREEDOM_OF_MOVEMENT) bCanCast = TRUE; + else if(nSpell == SPELL_NEUTRALIZE_POISON) bCanCast = TRUE; + else if(nSpell == SPELL_MIND_BLANK) bCanCast = TRUE; + else if(nSpell == SPELL_LESSER_MIND_BLANK) bCanCast = TRUE; + else if(nSpell == SPELL_SPELL_RESISTANCE) bCanCast = TRUE; + else if(nSpell == SPELL_PROTECTION_FROM_GOOD) bCanCast = TRUE; + else if(nSpell == SPELL_CREATE_UNDEAD) bCanCast = TRUE; + else if(nSpell == SPELL_PLANAR_ALLY) bCanCast = TRUE; + else if(nSpell == SPELL_LESSER_PLANAR_BINDING) bCanCast = TRUE; + else if(nSpell == SPELL_ETHEREALNESS) bCanCast = TRUE; + else if(nSpell == SPELL_PROTECTION_FROM_SPELLS) bCanCast = TRUE; + else if(nSpell == SPELL_SHADOW_SHIELD) bCanCast = TRUE; + else if(nSpell == SPELL_CREATE_GREATER_UNDEAD) bCanCast = TRUE; + else if(nSpell == SPELL_GREATER_PLANAR_BINDING) bCanCast = TRUE; + if(bCanCast && GetSpellAbilityReady(oCreature, nIndex)) + { + ActionCastSpellAtObject(nSpell, oCreature, 255, 0, 0, 0, TRUE); + } + } + nIndex++; + } + } +} +int ai_IsSilenced(object oCreature, int nSpell) +{ + if(Get2DAString("spells", "VS", nSpell) == "s") return FALSE; + if(ai_GetHasEffectType(oCreature, EFFECT_TYPE_SILENCE)) return TRUE; + return FALSE; +} +int ai_ArcaneSpellFailureTooHigh(object oCreature, int nClass, int nLevel, int nSlot) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "561", "Arcane Spells: " + Get2DAString("classes", "ASF", nClass) + + " Arcane Spell Failure: " + IntToString(GetArcaneSpellFailure(oCreature)) + + " AI_ASF_WILL_USE: " + IntToString(AI_ASF_WILL_USE)); + if(Get2DAString("classes", "ASF", nClass) == "1" && + GetArcaneSpellFailure(oCreature) > AI_ASF_WILL_USE) + { + if(GetMemorizedSpellMetaMagic(oCreature, nClass, nLevel, nSlot) == METAMAGIC_STILL) return FALSE; + return TRUE; + } + return FALSE; +} +int ai_TryToCastSpell(object oCaster, int nSpell, object oTarget) +{ + if(GetHasSpell(nSpell, oCaster) && !GetHasSpellEffect(nSpell, oTarget)) + { + ActionCastSpellAtObject(nSpell, oTarget); + return TRUE; + } + return FALSE; +} +int ai_SpellGroupNotCast(object oCreature, string sBuffGroup) +{ + return !GetLocalInt(oCreature, sBuffGroup); +} +void ai_ClearSpellsCastGroups(object oCreature) +{ + int nCounter; + for(nCounter = -1; nCounter <= AI_BUFF_GROUPS; nCounter--) + { + DeleteLocalInt(oCreature, "AI_USED_SPELL_GROUP_" + IntToString(nCounter)); + } +} +int ai_CanUseSpell(object oCaster, object oTarget, int nSpell, int nTargetType) +{ + // Should we ignore associates? + if(ai_GetAIMode(oCaster, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + // For ability scores we return a bonus to the ability to be checked against + // the target with the highest ability getting the spell first. + if(nTargetType == 1) // Ability score buff for strength. + { + // We don't want to buff the strength for someone using weapon finesse! + if(GetHasFeat(FEAT_WEAPON_FINESSE, oTarget)) return -5; + return TRUE; + } + if(nTargetType == 7) // Lowest AC. + { + // Stone bones only effects the undead. + if(nSpell == SPELL_STONE_BONES) + { + if(GetRacialType(oTarget) != RACIAL_TYPE_UNDEAD) return FALSE; + } + return TRUE; + } + if(nTargetType == 8) // Lowest AC without AC Bonus. + { + if(nSpell == SPELL_MAGIC_VESTMENT) + { + object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); + if(oArmor == OBJECT_INVALID) return FALSE; + } + return TRUE; + } + if(nTargetType == 9) // Highest Attack. + { + return TRUE; + } + if(nTargetType == 10) // Most wounded, Lowest Hp. + { + return TRUE; + } + if(nTargetType == 11) // Lowest Fortitude save. + { + return TRUE; + } + if(nTargetType == 12) // Lowest Reflex save. + { + return TRUE; + } + if(nTargetType == 13) // Lowest Will save. + { + return TRUE; + } + if(nTargetType == 14) // Lowest Save. + { + return TRUE; + } + if(nSpell == SPELL_MAGIC_FANG) + { + object oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCaster); + if(oTarget != oCompanion) return FALSE; + } + return TRUE; +} +// Used to check if the targets weapon can be buffed by the spells effects. +int ai_CanItemBeBuffed(int nSpell, object oTarget) +{ + object oWeapon, oArmor; + if(nSpell == SPELL_MAGIC_WEAPON || nSpell == SPELL_GREATER_MAGIC_WEAPON || + nSpell == SPELL_BLADE_THIRST) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_ENHANCEMENT_BONUS)) return FALSE; + } + else if(nSpell == SPELL_MAGIC_VESTMENT) + { + oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); + if(oArmor == OBJECT_INVALID) return FALSE; + if(ai_GetHasItemProperty(oArmor, ITEM_PROPERTY_AC_BONUS)) return FALSE; + } + else if(nSpell == SPELL_DARKFIRE) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_ON_HIT_PROPERTIES, 127)) return FALSE; + } + else if(nSpell == SPELL_FLAME_WEAPON) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_ON_HIT_PROPERTIES, 124)) return FALSE; + } + else if(nSpell == SPELL_KEEN_EDGE) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsSlashingWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_KEEN)) return FALSE; + } + else if(nSpell == SPELL_DEAFENING_CLANG) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_ON_HIT_PROPERTIES, 137)) return FALSE; + } + else if(nSpell == SPELL_BLESS_WEAPON) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP, IP_CONST_RACIALTYPE_UNDEAD)) return FALSE; + } + else if(nSpell == SPELL_HOLY_SWORD) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_HOLY_AVENGER)) return FALSE; + } + else if(nSpell == SPELL_BLACKSTAFF) + { + oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(GetBaseItemType(oWeapon) != BASE_ITEM_QUARTERSTAFF) return FALSE; + if(ai_GetHasItemProperty(oWeapon, ITEM_PROPERTY_ON_HIT_PROPERTIES, IP_CONST_ONHIT_DISPELMAGIC)) return FALSE; + } + return TRUE; +} +// In "Buff_Target" column the value of 0 in the "ai_spells.2da" references the Caster. +// In "Buff_Target" column this is value 1-6(STR, DEX, CON, INT, WIS, CHA) in the "ai_spells.2da". +object ai_BuffHighestAbilityScoreTarget(object oCaster, int nSpell, int nAbilityScore, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup)) return oMaster; + } + int nCntr = 1, nAB, nHighAB, nTarget, nUseSpell; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange) + { + nUseSpell = ai_CanUseSpell(oCaster, oTarget, nSpell, nAbilityScore + 1); + if(nUseSpell == 0) {} + else + { + nAB = GetAbilityScore(oTarget, nAbilityScore) + nUseSpell; + if(nAB > nHighAB) + {nHighAB = nAB; nTarget = nCntr; } + } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 7 in the "ai_spells.2da". +object ai_BuffLowestACTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + object oMaster = GetMaster(); + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 7)) return oMaster; + } + int nCntr = 1, nAC, nLowAC = 100, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nAC = GetAC(oTarget); + if(nAC < nLowAC && ai_CanUseSpell(oCaster, oTarget, nSpell, 7)) + {nLowAC = nAC; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); + return oTarget; +} +// In "Buff_Target" column this is value 8 in the "ai_spells.2da". +object ai_BuffLowestACWithOutACBonus(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 8)) return oMaster; + } + int nCntr = 1, nAC, nLowAC = 50, nTarget; + object oItem, oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nAC = GetAC(oTarget); + oItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); + if(nAC < nLowAC && ai_CanUseSpell(oCaster, oTarget, nSpell, 8) && + !GetItemHasItemProperty(oItem, ITEM_PROPERTY_AC_BONUS)) + { + nLowAC = nAC; + nTarget = nCntr; + } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 9 in the "ai_spells.2da". +object ai_BuffHighestAttackTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 9)) return oMaster; + } + int nCntr = 1, nAtk, nHighAtk, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nAtk = GetBaseAttackBonus(oTarget); + if(nAtk > nHighAtk && ai_CanUseSpell(oCaster, oTarget, nSpell, 9)) + {nHighAtk = nAtk; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); + return oTarget; +} +// In "Buff_Target" column this is value 10 in the "ai_spells.2da". +object ai_BuffMostWoundedTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 9)) return oMaster; + } + int nCntr = 1, nDmg, nMostDmg, nHp, nLowHp = 10000, nTarget, nHpTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && + ai_SpellGroupNotCast(oTarget, sBuffGroup) && + ai_CanUseSpell(oCaster, oTarget, nSpell, 10)) + { + nHp = GetCurrentHitPoints(oTarget); + nDmg = GetMaxHitPoints(oTarget) - nHp; + if(nDmg > nMostDmg) { nMostDmg = nDmg; nTarget = nCntr; } + if(nHp < nLowHp) { nLowHp = nHp; nHpTarget = nCntr; } + } + // If no one is damage then put regeneration on the lowest hp target. + if(nMostDmg == 0) nTarget = nHpTarget; + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 11 in the "ai_spells.2da". +object ai_BuffLowestFortitudeSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 11)) return oMaster; + } + int nCntr = 1, nSave, nLowSave = 100, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nSave = GetFortitudeSavingThrow(oTarget); + if(nSave < nLowSave && ai_CanUseSpell(oCaster, oTarget, nSpell, 11)) + {nLowSave = nSave; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 12 in the "ai_spells.2da". +object ai_BuffLowestReflexSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 12)) return oMaster; + } + int nCntr = 1, nSave, nLowSave = 100, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nSave = GetReflexSavingThrow(oTarget); + if(nSave < nLowSave && ai_CanUseSpell(oCaster, oTarget, nSpell, 12)) + {nLowSave = nSave; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 13 in the "ai_spells.2da". +object ai_BuffLowestWillSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 13)) return oMaster; + } + int nCntr = 1, nSave, nLowSave = 100, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nSave = GetWillSavingThrow(oTarget); + if(nSave < nLowSave && ai_CanUseSpell(oCaster, oTarget, nSpell, 13)) + {nLowSave = nSave; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 14 in the "ai_spells.2da". +object ai_BuffLowestSaveTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(!GetHasSpellEffect(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup) && + ai_CanUseSpell(oCaster, oMaster, nSpell, 14)) return oMaster; + } + int nCntr = 1, nSave, nLowSave = 200, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && !GetHasSpellEffect(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nSave = GetFortitudeSavingThrow(oTarget) + GetReflexSavingThrow(oTarget) + GetWillSavingThrow(oTarget); + if(nSave < nLowSave && ai_CanUseSpell(oCaster, oTarget, nSpell, 14)) + {nLowSave = nSave; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + else return GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); +} +// In "Buff_Target" column this is value 15 in the "ai_spells.2da". +object ai_BuffItemTarget(object oCaster, int nSpell, string sBuffGroup, float fRange, string sTargetType = "AI_ALLY_TARGET_") +{ + if(ai_GetMagicMode(oCaster, AI_MAGIC_BUFF_MASTER)) + { + object oMaster = GetMaster(); + if(ai_CanItemBeBuffed(nSpell, oMaster) && + ai_SpellGroupNotCast(oMaster, sBuffGroup)) return oMaster; + } + int nCntr = 1, nAtk, nHighAtk = -9999, nTarget; + object oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nCntr)); + while (nCntr < 10) + { + if(oTarget != OBJECT_INVALID && ai_CanItemBeBuffed(nSpell, oTarget) && + GetDistanceBetween(oCaster, oTarget) <= fRange && ai_SpellGroupNotCast(oTarget, sBuffGroup)) + { + nAtk = GetBaseAttackBonus(oTarget); + if(nAtk > nHighAtk) + { nHighAtk = nAtk; nTarget = nCntr; } + } + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(++nCntr)); + } + if(nTarget == 0) return OBJECT_INVALID; + oTarget = GetLocalObject(oCaster, sTargetType + IntToString(nTarget)); + return oTarget; +} +object ai_GetBuffTarget(object oCaster, int nSpell) +{ + object oTarget = OBJECT_INVALID; + string sGroup = Get2DAString("ai_spells", "Buff_Group", nSpell); + if(sGroup == "") sGroup = IntToString(nSpell); + string sBuffGroup = "AI_USED_SPELL_GROUP_" + sGroup; + string sBuffTarget = Get2DAString("ai_spells", "Buff_Target", nSpell); + if(AI_DEBUG) ai_Debug("0i_spells", "769", "BuffTarget: " + sBuffTarget); + if(sBuffTarget == "0") + { + if(ai_SpellGroupNotCast(oCaster, sBuffGroup) && + !GetHasSpellEffect(nSpell, oCaster) && + ai_CanUseSpell(oCaster, oTarget, nSpell, 0)) + { + oTarget = oCaster; + } + } + else if(sBuffTarget == "1") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_STRENGTH, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "2") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_DEXTERITY, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "3") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_CONSTITUTION, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "4") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_INTELLIGENCE, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "5") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_WISDOM, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "6") + oTarget = ai_BuffHighestAbilityScoreTarget(oCaster, nSpell, ABILITY_CHARISMA, "", AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "7") + oTarget = ai_BuffLowestACTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "8") + oTarget = ai_BuffLowestACWithOutACBonus(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "9") + oTarget = ai_BuffHighestAttackTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "10") + oTarget = ai_BuffMostWoundedTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "11") + oTarget = ai_BuffLowestFortitudeSaveTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "12") + oTarget = ai_BuffLowestReflexSaveTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "13") + oTarget = ai_BuffLowestWillSaveTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "14") + oTarget = ai_BuffLowestSaveTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + else if(sBuffTarget == "15") + oTarget = ai_BuffItemTarget(oCaster, nSpell, sBuffGroup, AI_RANGE_BATTLEFIELD); + if(oTarget != OBJECT_INVALID) + { + SetLocalInt(oTarget, sBuffGroup, TRUE); + DelayCommand(6.0, DeleteLocalInt(oTarget, sBuffGroup)); + } + if(AI_DEBUG) ai_Debug("0i_spells", "939", GetName(oCaster) + " is targeting " + GetName(oTarget) + + " with " + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))) + " spell" + + " sBuffGroup: " + sBuffGroup + "."); + return oTarget; +} +void ai_CastMemorizedSpell(object oCaster, int nClass, int nSpellLevel, int nSpellSlot, object oTarget, int bInstant, object oPC = OBJECT_INVALID) +{ + int nDomain; + int nSpell = GetMemorizedSpellId(oCaster, nClass, nSpellLevel, nSpellSlot); + if(GetMemorizedSpellIsDomainSpell(oCaster, nClass, nSpellLevel, nSpellSlot) == 1) nDomain = nSpellLevel; + else nDomain = 0; + int nMetaMagic = GetMemorizedSpellMetaMagic(oCaster, nClass, nSpellLevel, nSpellSlot); + if(AI_DEBUG) ai_Debug("0i_spells", "951", "nSpell: " + IntToString(nSpell) + " oTarget: " + GetName(oTarget) + + " nMetaMagic: " + IntToString(nMetaMagic) + " nDomain: " + IntToString(nDomain) + + " bInstant: " + IntToString(bInstant) + " nClass: " + IntToString(nClass)); + ActionCastSpellAtObject(nSpell, oTarget, nMetaMagic, FALSE, nDomain, 0, bInstant); + // Right now I cannot get nClass to work here... + //DelayCommand(fDelay, ActionCastSpellAtObject(nSpell, oTarget, nMetaMagic, FALSE, nDomain, 0, TRUE, nClass)); + if(oPC != OBJECT_INVALID) + { + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_SendMessages(GetName(oCaster) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_GREEN, oPC); + } +} +void ai_CastKnownSpell(object oCaster, int nClass, int nSpell, object oTarget, int bInstant, object oPC = OBJECT_INVALID) +{ + if(AI_DEBUG) ai_Debug("0i_Spells", "965", GetName(oCaster) + " is casting " + IntToString(nSpell)); + ActionCastSpellAtObject(nSpell, oTarget, 255, FALSE, 0, 0, bInstant); + // Right now I cannot get nClass to work here... + //ActionCastSpellAtObject(nSpell, oTarget, 255, FALSE, 0, 0, TRUE, nClass); + if(oPC != OBJECT_INVALID) + { + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_SendMessages(GetName(oCaster) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_GREEN, oPC); + } +} +int ai_CheckAndCastSpell(object oCaster, int nSpell, int nSpellGroup, float fDelay, object oTarget, object oPC = OBJECT_INVALID) +{ + int nClassCnt = 1, nClass, nMaxSlot, nSpellLevel, nSpellSlot, nMemorizedSpell, nDomain, nMetaMagic; + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + while(nClassCnt <= AI_MAX_CLASSES_PER_CHARACTER && nClass != CLASS_TYPE_INVALID) + { + nClass = GetClassByPosition(nClassCnt); + // Search all memorized spells for the spell. + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + // Check each level starting with the highest to lowest. + nSpellLevel = 0; + while(nSpellLevel < 10) + { + // Check each slot within each level. + nMaxSlot = GetMemorizedSpellCountByLevel(oCaster, nClass, nSpellLevel); + nSpellSlot = 0; + while(nSpellSlot < nMaxSlot) + { + if(GetMemorizedSpellReady(oCaster, nClass, nSpellLevel, nSpellSlot)) + { + nMemorizedSpell = GetMemorizedSpellId(oCaster, nClass, nSpellLevel, nSpellSlot); + if(nMemorizedSpell == nSpell) + { + ai_CastMemorizedSpell(oCaster, nClass, nSpellLevel, nSpellSlot, oTarget, FALSE, oPC); + return TRUE; + } + } + nSpellSlot++; + } + nSpellLevel++; + } + } + // Check non-memorized known lists for the spell. + else if(GetSpellUsesLeft(oCaster, nClass, nSpell)) + { + ai_CastKnownSpell(oCaster, nClass, nSpell, oTarget, FALSE, oPC); + return TRUE; + } + nClassCnt++; + } + return FALSE; +} +void ai_SetupMonsterBuffTargets(object oCaster) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1020", GetName(oCaster) + " is setting buff targets."); + SetLocalObject (oCaster, "AI_ALLY_TARGET_1" , oCaster); + SetLocalObject (oCaster, "AI_ALLY_TARGET_2", oCaster); + int nCntr = 1; + object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oCaster, nCntr); + if(AI_DEBUG) ai_Debug("0i_spells", "864", GetName(oCreature) + " nCntr: " + IntToString(nCntr) + + " Distance: " + FloatToString(GetDistanceBetween(oCaster, oCreature), 0, 2)); + while(oCreature != OBJECT_INVALID && nCntr < 8 && GetDistanceBetween(oCaster, oCreature) < AI_RANGE_CLOSE) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1133", "Setting " + GetName(oCreature) + " as AI_ALLY_TARGET_" + IntToString(nCntr + 2)); + SetLocalObject (oCaster, "AI_ALLY_TARGET_" + IntToString(nCntr + 2), oCreature); + oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oCaster, ++nCntr); + if(AI_DEBUG) ai_Debug("0i_spells", "1136", GetName(oCreature) + " nCntr: " + IntToString(nCntr) + + " Distance: " + FloatToString(GetDistanceBetween(oCaster, oCreature), 0, 2)); + } +} +void ai_SetupAllyTargets(object oCaster, object oPC) +{ + // Setup our targets. + int nTarget; + if(oCaster != oPC) SetLocalObject (oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oPC); + SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCaster); + object oCreature = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oCreature); + int nCntr = 1; + int nMaxHenchman = GetMaxHenchmen() + nTarget; + object oHenchman = GetHenchman(oPC, nCntr); + while(oHenchman != OBJECT_INVALID && nCntr <= nMaxHenchman) + { + if(oHenchman == OBJECT_INVALID) break; + if(oHenchman != oCaster) SetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(++nTarget), oHenchman); + oHenchman = GetHenchman(oPC, ++nCntr); + } + nCntr = 1; + while(nCntr <= nMaxHenchman) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1166", "AI_ALLY_TARGET_" + IntToString(nCntr) + ": " + + GetName(GetLocalObject(oCaster, "AI_ALLY_TARGET_" + IntToString(nCntr)))); + nCntr++; + } +} +void ai_SetupAllyHealingTargets(object oCaster, object oPC) +{ + int nMaxHenchman = 1; + if(oPC == OBJECT_INVALID) oPC = oCaster; + if(ai_GetAIMode(oCaster, AI_MODE_PARTY_HEALING_OFF)) + { + if(!ai_GetAIMode(oCaster, AI_MODE_SELF_HEALING_OFF)) SetLocalObject(oCaster, "AI_ALLY_HEAL_1", oCaster); + } + else + { + int nTarget; + if(oCaster != oPC) + { + SetLocalObject (oCaster, "AI_ALLY_HEAL_1", oPC); + nTarget++; + } + if(!ai_GetAIMode(oCaster, AI_MODE_SELF_HEALING_OFF)) + { + SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCaster); + } + object oCreature = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + oCreature = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oCaster); + if(oCreature != OBJECT_INVALID) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oCreature); + int nCntr = 1; + nMaxHenchman = GetMaxHenchmen() + nTarget; + object oHenchman = GetHenchman(oPC, nCntr); + while(oHenchman != OBJECT_INVALID && nTarget <= nMaxHenchman) + { + if(oHenchman == OBJECT_INVALID) break; + if(oHenchman != oCaster) SetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(++nTarget), oHenchman); + oHenchman = GetHenchman(oPC, ++nCntr); + } + } + int nCntr = 1; + while(nCntr <= nMaxHenchman) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1211", "AI_ALLY_HEAL_" + IntToString(nCntr) + ": " + + GetName(GetLocalObject(oCaster, "AI_ALLY_HEAL_" + IntToString(nCntr++)))); + } +} +void ai_ClearBuffTargets(object oCaster, string sVariable) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1216", GetName(oCaster) + " is clearing " + sVariable + " targets."); + int nIndex; + int nMaxTargets = GetMaxHenchmen() + 6; + for(nIndex = 1; nIndex < nMaxTargets; nIndex++) + { + DeleteLocalObject (oCaster, sVariable + IntToString(nIndex)); + } +} +void ai_CheckForPerDayProperties(object oCreature, object oItem, int nBuffType, int bEquiped = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1150", "Checking Item properties on " + GetName(oItem)); + // We have established that we can use the item if it is equiped. + if(!bEquiped && !ai_CheckIfCanUseItem(oCreature, oItem)) return; + int nPerDay, nCharges, nUses, nSpellBuffDuration; + int nIprpSubType, nSpell, nLevel, nIPType, nIndex; + object oTarget; + itemproperty ipProp = GetFirstItemProperty(oItem); + // Lets skip this if there are no properties. + if(!GetIsItemPropertyValid(ipProp)) return; + // Check for cast spell property and add them to the talent list. + while(GetIsItemPropertyValid(ipProp)) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1163", "ItempropertyType(15): " + IntToString(GetItemPropertyType(ipProp))); + nIPType = GetItemPropertyType(ipProp); + if(nIPType == ITEM_PROPERTY_CAST_SPELL) + { + // Get how they use the item (charges or uses per day). + nUses = GetItemPropertyCostTableValue(ipProp); + // We only check uses per day. + if(AI_DEBUG) ai_Debug("0i_spells", "1172", "Item uses: " + IntToString(nPerDay)); + if(nUses > 7 && nUses < 13) + { + nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(AI_DEBUG) ai_Debug("0i_spells", "1176", "Item uses per day: " + IntToString(nPerDay)); + if(nPerDay > 0) + { + // SubType is the ip spell index for iprp_spells.2da + nIprpSubType = GetItemPropertySubType(ipProp); + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + nSpellBuffDuration = StringToInt(Get2DAString("ai_spells", "Buff_Duration", nSpell)); + if(AI_DEBUG) ai_Debug("0i_spells", "1183", "nSpell: " + IntToString(nSpell) + + " nBuffType: " + IntToString(nBuffType) + + " nSpellBuffDuration: " + IntToString(nSpellBuffDuration)); + if(nBuffType == nSpellBuffDuration || nBuffType == 1) + { + oTarget = ai_GetBuffTarget(oCreature, nSpell); + if(oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1190", GetName(oCreature) + " is using" + + GetName(oItem) + " to cast " + IntToString(nSpell) + + " on " + GetName(oTarget)); + ActionUseItemOnObject(oItem, ipProp, oTarget); + } + } + } + } + } + ipProp = GetNextItemProperty(oItem); + } +} +void ai_CheckForPerDayItems(object oCreature, object oPC, int nBuffType) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1198", GetName(oCreature) + ": Checking items for per day buffs."); + if(!ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC_ITEMS)) + { + int bEquiped; + string sSlots; + // Cycle through all the creatures inventory items. + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetIdentified(oItem)) + { + // Does the item need to be equiped to use its powers? + sSlots = Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)); + if(AI_DEBUG) ai_Debug("0i_talents", "1211", GetName(oItem) + " requires " + Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)) + " slots."); + if(sSlots == "0x00000") ai_CheckForPerDayProperties(oCreature, oItem, nBuffType); + } + oItem = GetNextItemInInventory(oCreature); + } + int nSlot; + // Cycle through all the creatures equiped items. + oItem = GetItemInSlot(nSlot, oCreature); + while(nSlot < 11) + { + if(oItem != OBJECT_INVALID) ai_CheckForPerDayProperties(oCreature, oItem, nBuffType, TRUE); + oItem = GetItemInSlot(++nSlot, oCreature); + } + oItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oCreature); + if(oItem != OBJECT_SELF) ai_CheckForPerDayProperties(oCreature, oItem, nBuffType, TRUE); + } + // Clean up our variables. Must be done here since these are actions! + int nCntr; + object oTarget; + while(nCntr < 11) + { + oTarget = GetLocalObject(oCreature, "AI_ALLY_TARGET_" + IntToString(nCntr)); + if(oTarget != OBJECT_INVALID) + { + ai_ClearSpellsCastGroups(oTarget); + DeleteLocalObject(oCreature, "AI_ALLY_TARGET_" + IntToString(nCntr)); + } + nCntr++; + } +} +void ai_CheckForBuffSpells(struct stSpell stSpell) +{ + ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC); + stSpell.nPosition = 1; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + if(AI_DEBUG) ai_Debug("0i_spells", "1208", "nClass: " + IntToString(stSpell.nClass)); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + if(AI_DEBUG) ai_Debug("0i_spells", "1210", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + if(AI_DEBUG) ai_Debug("0i_spells", "1214", "Memorizes Spells: " + Get2DAString("classes", "MemorizesSpells", stSpell.nClass)); + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell)); + return; + } + else + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell)); + return; + } + } + stSpell.nPosition++; + } + ai_CheckForPerDayItems(stSpell.oCaster, stSpell.oPC, stSpell.nBuffType); +} +void ai_ActionCastMemorizedSummons(struct stSpell stSpell) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1122", "Start of ActionCastMemorizedSummons!"); + int nSpell; + string sBuffGroup, sBuffTarget; + object oTarget; + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + //ai_Debug("0i_spells", "1128", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + //ai_Debug("0i_spells", "1131", "nLevel: " + IntToString(stSpell.nLevel)); + while(stSpell.nLevel > -1) + { + //ai_Debug("0i_spells", "1134", "nMaxSlots: " + IntToString(stSpell.nMaxSlots) + + // " nSlots: " + IntToString(stSpell.nSlot)); + while(stSpell.nSlot < stSpell.nMaxSlots) + { + //ai_Debug("0i_spells", "1238", "Ready: " + IntToString(GetMemorizedSpellReady(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot))); + if(GetMemorizedSpellReady(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot)) + { + nSpell = GetMemorizedSpellId(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot); + //ai_Debug("0i_spells", "1142", "nSpell: " + IntToString(nSpell)); + if(Get2DAString("ai_spells", "Category", nSpell) == "S") + { + SetLocalInt(stSpell.oCaster, "AI_USED_SPELL_GROUP_-2", TRUE); + ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, stSpell.oCaster, TRUE, stSpell.oPC); + stSpell.nPosition = 1; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + DelayCommand(2.0, ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC)); + DelayCommand(2.0 + 0.5, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell))); + return; + } + } + stSpell.nSlot++; + } + stSpell.nLevel--; + //ai_Debug("0i_spells", "1153", "nLevel: " + IntToString(stSpell.nLevel)); + if(stSpell.nLevel > -1) + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + } + } + } + stSpell.nPosition++; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + //ai_Debug("0i_spells", "1164", "nClass: " + IntToString(stSpell.nClass)); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nSlot = 0; + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + } + else + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell)); + return; + } + } + } + ai_CheckForBuffSpells(stSpell); +} +void ai_ActionCastKnownSummons(struct stSpell stSpell) +{ + //ai_Debug("0i_spells", "1184", "Start of ActionCastKnownSummons!"); + int nSpell; + string sBuffGroup, sBuffTarget; + object oTarget; + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + //ai_Debug("0i_spells", "1190", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + //ai_Debug("0i_spells", "1193", "nLevel: " + IntToString(stSpell.nLevel)); + while(stSpell.nLevel > -1) + { + if(stSpell.nMaxSlots) + { + //ai_Debug("0i_spells", "1198", "nMaxSlots: " + IntToString(stSpell.nMaxSlots) + + // " nSlots: " + IntToString(stSpell.nSlot)); + while(stSpell.nSlot < stSpell.nMaxSlots) + { + nSpell = GetKnownSpellId(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot); + //ai_Debug("0i_spells", "1203", "Ready: " + IntToString(GetSpellUsesLeft(stSpell.oCaster, stSpell.nClass, nSpell))); + if(GetSpellUsesLeft(stSpell.oCaster, stSpell.nClass, nSpell)) + { + if(Get2DAString("ai_spells", "Category", nSpell) == "S") + { + SetLocalInt(stSpell.oCaster, "AI_USED_SPELL_GROUP_S", TRUE); + //ai_Debug("0i_spells", "1209", "nSpell: " + IntToString(nSpell)); + ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, stSpell.oCaster, TRUE, stSpell.oPC); + stSpell.nPosition = 1; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC); + DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell))); + return; + } + } + stSpell.nSlot++; + } + } + stSpell.nLevel--; + //ai_Debug("0i_spells", "1218", "nLevel: " + IntToString(stSpell.nLevel)); + if(stSpell.nLevel > -1) + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + } + } + } + stSpell.nPosition++; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + //ai_Debug("0i_spells", "1229", "nClass: " + IntToString(stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nSlot = 0; + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell)); + return; + } + else stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + } + } + ai_CheckForBuffSpells(stSpell); +} +void ai_ActionCastMemorizedBuff(struct stSpell stSpell) +{ + int nSpell; + string sBuffGroup, sBuffTarget; + object oTarget; + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + ai_Debug("0i_spells", "1252", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + ai_Debug("0i_spells", "1255", "nLevel: " + IntToString(stSpell.nLevel)); + while(stSpell.nLevel > -1) + { + ai_Debug("0i_spells", "1258", "nMaxSlots: " + IntToString(stSpell.nMaxSlots) + + " nSlots: " + IntToString(stSpell.nSlot)); + while(stSpell.nSlot < stSpell.nMaxSlots) + { + ai_Debug("0i_spells", "1262", "Ready: " + IntToString(GetMemorizedSpellReady(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot))); + if(GetMemorizedSpellReady(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot)) + { + nSpell = GetMemorizedSpellId(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot); + int nSpellBuffDuration = StringToInt(Get2DAString("ai_spells", "Buff_Duration", nSpell)); + ai_Debug("0i_spells", "1267", "nBuffType: " + IntToString(stSpell.nBuffType) + + " nSpellBuffDuration: " + IntToString(nSpellBuffDuration) + + " sBuffGroup: " + Get2DAString("ai_spells", "Buff_Group", nSpell)); + if(stSpell.nBuffType == nSpellBuffDuration || stSpell.nBuffType == 1) + { + if(stSpell.nTarget > 0) + { + sBuffTarget = Get2DAString("ai_spells", "Buff_Target", nSpell); + oTarget = GetLocalObject(stSpell.oCaster, "AI_ALLY_TARGET_" + IntToString(stSpell.nTarget)); + if(sBuffTarget != "0" || (sBuffTarget == "0" && stSpell.oCaster == oTarget)) + { + sBuffGroup = "AI_USED_SPELL_GROUP_" + Get2DAString("ai_spells", "Buff_Group", nSpell); + if(!ai_SpellGroupNotCast(oTarget, sBuffGroup)) oTarget == OBJECT_INVALID; + } + else oTarget == OBJECT_INVALID; + } + else oTarget = ai_GetBuffTarget(stSpell.oCaster, nSpell); + ai_Debug("0i_spells", "1284", "nSpell: " + IntToString(nSpell) + + " oTarget: " + GetName(oTarget)); + if(oTarget != OBJECT_INVALID) + { + ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, oTarget, TRUE, stSpell.oPC); + stSpell.nSlot++; + DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell))); + return; + } + } + } + stSpell.nSlot++; + } + stSpell.nLevel--; + ai_Debug("0i_spells", "1298", "nLevel: " + IntToString(stSpell.nLevel)); + if(stSpell.nLevel > -1) + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + } + } + } + stSpell.nPosition++; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + ai_Debug("0i_spells", "1309", "nClass: " + IntToString(stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nSlot = 0; + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + } + else + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell)); + return; + } + } + } + ai_CheckForPerDayItems(stSpell.oCaster, stSpell.oPC, stSpell.nBuffType); +} +void ai_ActionCastKnownBuff(struct stSpell stSpell) +{ + int nSpell; + string sBuffGroup, sBuffTarget; + object oTarget; + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + //ai_Debug("0i_spells", "1347", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + //ai_Debug("0i_spells", "1350", "nLevel: " + IntToString(stSpell.nLevel)); + while(stSpell.nLevel > -1) + { + if(stSpell.nMaxSlots) + { + //ai_Debug("0i_spells", "1356", "nMaxSlots: " + IntToString(stSpell.nMaxSlots) + + // " nSlots: " + IntToString(stSpell.nSlot)); + while(stSpell.nSlot < stSpell.nMaxSlots) + { + nSpell = GetKnownSpellId(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot); + int nSpellBuffDuration = StringToInt(Get2DAString("ai_spells", "Buff_Duration", nSpell)); + //ai_Debug("0i_spells", "1361", "nBuffType: " + IntToString(stSpell.nBuffType) + + // " nSpellBuffDuration: " + IntToString(nSpellBuffDuration) + + // " sBuffGroup: " + Get2DAString("ai_spells", "Buff_Group", nSpell)); + if(stSpell.nBuffType == nSpellBuffDuration || stSpell.nBuffType == 1) + { + //ai_Debug("0i_spells", "1367", "Ready: " + IntToString(GetSpellUsesLeft(stSpell.oCaster, stSpell.nClass, nSpell))); + if(GetSpellUsesLeft(stSpell.oCaster, stSpell.nClass, nSpell)) + { + if(stSpell.nTarget > 0) + { + sBuffTarget = Get2DAString("ai_spells", "Buff_Target", nSpell); + oTarget = GetLocalObject(stSpell.oCaster, "AI_ALLY_TARGET_" + IntToString(stSpell.nTarget)); + if(sBuffTarget != "0" || (sBuffTarget == "0" && stSpell.oCaster == oTarget)) + { + sBuffGroup = "AI_USED_SPELL_GROUP_" + Get2DAString("ai_spells", "Buff_Group", nSpell); + if(!ai_SpellGroupNotCast(oTarget, sBuffGroup)) oTarget == OBJECT_INVALID; + } + else oTarget == OBJECT_INVALID; + } + else oTarget = ai_GetBuffTarget(stSpell.oCaster, nSpell); + //ai_Debug("0i_spells", "1382", "nSpell: " + IntToString(nSpell) + + // " oTarget: " + GetName(oTarget)); + if(oTarget != OBJECT_INVALID) + { + ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, oTarget, TRUE, stSpell.oPC); + stSpell.nSlot++; + DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell))); + return; + } + } + } + stSpell.nSlot++; + } + } + stSpell.nLevel--; + //ai_Debug("0i_spells", "1396", "nLevel: " + IntToString(stSpell.nLevel)); + if(stSpell.nLevel > -1) + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + stSpell.nSlot = 0; + } + } + } + stSpell.nPosition++; + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + //ai_Debug("0i_spells", "921", "nClass: " + IntToString(stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + stSpell.nSlot = 0; + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell)); + return; + } + else stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + } + } + ai_CheckForPerDayItems(stSpell.oCaster, stSpell.oPC, stSpell.nBuffType); +} +void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC) +{ + // buff types: 1 - All, 2 - Short duration, 3 - Long duration + // Buff groups are used to prevent a henchmen to cast spells that have the same effect, + // for example: resist elements and protection from elements are similiar so the henchmen + // would cast only the most powerful among these if he has them both. + if(AI_DEBUG) ai_Debug("0i_spells", "1670", GetName(oCaster) + " is casting buffs: " + IntToString(nBuffType) + + " nTarget: " + IntToString(nTarget) + "!"); + struct stSpell stSpell; + stSpell.oPC = oPC; + stSpell.oCaster = oCaster; + stSpell.nBuffType = nBuffType; + stSpell.nTarget = nTarget; + stSpell.nPosition = 1; + // Look for summons spells on All, Long durations and the whole party. + if((nBuffType == 1 || nBuffType == 3) && nTarget == 0) + { + while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster); + if(AI_DEBUG) ai_Debug("0i_spells", "1684", "nClass: " + IntToString(stSpell.nClass)); + if(stSpell.nClass == CLASS_TYPE_INVALID) break; + if(AI_DEBUG) ai_Debug("0i_spells", "1686", "SpellCaster: " + Get2DAString("classes", "SpellCaster", stSpell.nClass)); + if(Get2DAString("classes", "SpellCaster", stSpell.nClass) == "1") + { + stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2; + if(AI_DEBUG) ai_Debug("0i_spells", "1692", "MemorizesSpells: " + Get2DAString("classes", "MemorizesSpells", stSpell.nClass)); + if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1") + { + stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedSummons(stSpell)); + return; + } + else + { + stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel); + AssignCommand(stSpell.oCaster, ai_ActionCastKnownSummons(stSpell)); + return; + } + } + stSpell.nPosition++; + } + // Exit here; if we summoned a monster then it linked off of that spell + // cast to continue the action queue for all buff spell cast actions. + } + ai_CheckForBuffSpells(stSpell); +} +int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC) +{ + if(ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) return FALSE; + if(ai_GetMagicMode(oCreature, AI_MAGIC_NO_SPONTANEOUS_CURE)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_spells", "1643", GetName(oCreature) + " is looking to cast a spontaneous cure spell."); + if(!GetLevelByClass(CLASS_TYPE_CLERIC, oCreature)) return FALSE; + int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + int nSpell, nSlot, nMaxSlots, nLevel = 4; + int nSpellSave, nSlotSave, nLevelSave = 5; + string sSpellName; + while(nLevel > -1) + { + // We check CLASS_TYPE_CLERIC as thats the only class with spontaneous cure spells. + nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, CLASS_TYPE_CLERIC, nLevel); + nSlot = 0; + if(AI_DEBUG) ai_Debug("0i_spells", "1653", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots)); + while(nSlot < nMaxSlots) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1656", "nSlot: " + IntToString(nSlot) + + " Spell Ready: " + IntToString(GetMemorizedSpellReady(oCreature, CLASS_TYPE_CLERIC, nLevel, nSlot))); + if(GetMemorizedSpellReady(oCreature, CLASS_TYPE_CLERIC, nLevel, nSlot)) + { + if(nLevel == 4) nSpell = SPELL_CURE_CRITICAL_WOUNDS; + else if(nLevel == 3) nSpell = SPELL_CURE_SERIOUS_WOUNDS; + else if(nLevel == 2) nSpell = SPELL_CURE_MODERATE_WOUNDS; + else if(nLevel == 1) nSpell = SPELL_CURE_LIGHT_WOUNDS; + else nSpell = 0; + if(AI_DEBUG) ai_Debug("0i_spells", "1665", "nSpell: " + IntToString(nSpell)); + if(nSpell) + { + if(ai_ShouldWeCastThisCureSpell(nSpell, nDamage)) + { + SetMemorizedSpellReady(oCreature, CLASS_TYPE_CLERIC, nLevel, nSlot, FALSE); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_SendMessages(GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_MAGENTA, oPC); + if(AI_DEBUG) ai_Debug("0i_spells", "1673", GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + "."); + ActionCastSpellAtObject(nSpell, oTarget, 255, TRUE); + return TRUE; + } + // Save the lowest level cure spell as we might need to cast it. + else if(nLevel < nLevelSave) + { + nSpellSave = nSpell; + nLevelSave = nLevel; + nSlotSave = nSlot; + } + } + } + nSlot++; + } + nLevel--; + } + // Did we find a cure spell? If we did then use it. + if(nSpellSave) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1693", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + "."); + SetMemorizedSpellReady(oCreature, CLASS_TYPE_CLERIC, nLevelSave, nSlotSave, FALSE); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpellSave))); + ai_SendMessages(GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_MAGENTA, oPC); + ActionCastSpellAtObject(nSpellSave, oTarget, 255, TRUE); + return TRUE; + } + return FALSE; +} +int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1702", GetName(oCreature) + " is looking to cast a memorized cure spell."); + int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + int nSpell, nSlot, nMaxSlots, nLevel = 9; + int nClassSave, nSlotSave, nLevelSave = 10; + while(nLevel > -1) + { + nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel); + nSlot = 0; + if(AI_DEBUG) ai_Debug("0i_spells", "1710", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots)); + while(nSlot < nMaxSlots) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1713", "nSlot: " + IntToString(nSlot) + + " Spell Ready: " + IntToString(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot))); + if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot)) + { + nSpell = GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot); + if(ai_ShouldWeCastThisCureSpell(nSpell, nDamage)) + { + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(AI_DEBUG) ai_Debug("0i_spells", "1721", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + "."); + ai_CastMemorizedSpell(oCreature, nClass, nLevel, nSlot, oTarget, FALSE, oPC); + return TRUE; + } + // Save the lowest level cure spell as we might need to cast it. + else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32)) + { + nClassSave = nClass; + nLevelSave = nLevel; + nSlotSave = nSlot; + } + } + nSlot++; + } + nLevel--; + } + // Did we find a cure spell? If we did then use it. + if(nLevelSave < 10) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1740", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + "."); + ai_CastMemorizedSpell(oCreature, nClassSave, nLevelSave, nSlotSave, oTarget, FALSE, oPC); + return TRUE; + } + return FALSE; +} +int ai_CastKnownHealing(object oCreature, object oTarget, object oPC, int nClass) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1748", GetName(oCreature) + " is looking to cast a known cure spell."); + int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + int nSpell, nSlot, nMaxSlots, nLevel = 9; + int nClassSave, nSpellSave, nLevelSave = 10; + while(nLevel > -1) + { + nMaxSlots = GetKnownSpellCount(oCreature, nClass, nLevel); + nSlot = 0; + if(AI_DEBUG) ai_Debug("0i_spells", "1756", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots)); + while(nSlot < nMaxSlots) + { + nSpell = GetKnownSpellId(oCreature, nClass, nLevel, nSlot); + if(AI_DEBUG) ai_Debug("0i_spells", "1760", "nSlot: " + IntToString(nSlot) + + " Spell Ready: " + IntToString(GetSpellUsesLeft(oCreature, nClass, nSpell))); + if(GetSpellUsesLeft(oCreature, nClass, nSpell)) + { + if(ai_ShouldWeCastThisCureSpell(nSpell, nDamage)) + { + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(AI_DEBUG) ai_Debug("0i_spells", "1767", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + "."); + ai_CastKnownSpell(oCreature, nClass, nSpell, oTarget, FALSE, oPC); + return TRUE; + } + // Save the lowest level cure spell as we might need to cast it. + else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32)) + { + nClassSave = nClass; + nLevelSave = nLevel; + nSpellSave = nSpell; + } + } + nSlot++; + } + nLevel--; + } + return FALSE; + // Did we find a cure spell? If we did then use it. + if(nLevelSave < 10) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1781", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + "."); + ai_CastKnownSpell(oCreature, nClassSave, nSpellSave, oTarget, FALSE, oPC); + return TRUE; + } +} +int ai_ConcentrationCondition(object oCreature) +{ + int nType; + effect eEffect = GetFirstEffect(oCreature); + while(GetIsEffectValid(eEffect)) + { + nType = GetEffectType(eEffect); + if(nType == EFFECT_TYPE_STUNNED || nType == EFFECT_TYPE_PARALYZE || + nType == EFFECT_TYPE_SLEEP || nType == EFFECT_TYPE_FRIGHTENED || + nType == EFFECT_TYPE_PETRIFY || nType == EFFECT_TYPE_CONFUSED || + nType == EFFECT_TYPE_DOMINATED || nType == EFFECT_TYPE_POLYMORPH) + { + return TRUE; + } + eEffect = GetNextEffect(oCreature); + } + return FALSE; +} +void ai_SpellConcentrationCheck(object oCaster = OBJECT_SELF) +{ + object oMaster = GetMaster(); + if(GetLocalInt(oCaster,"X2_L_CREATURE_NEEDS_CONCENTRATION")) + { + if(GetIsObjectValid(oMaster)) + { + int nAction = GetCurrentAction(oMaster); + // master doing anything that requires attention and breaks concentration + if(nAction == ACTION_DISABLETRAP || nAction == ACTION_TAUNT || + nAction == ACTION_PICKPOCKET || nAction ==ACTION_ATTACKOBJECT || + nAction == ACTION_COUNTERSPELL || nAction == ACTION_FLAGTRAP || + nAction == ACTION_CASTSPELL || nAction == ACTION_ITEMCASTSPELL) + { + SignalEvent(oCaster,EventUserDefined(X2_EVENT_CONCENTRATION_BROKEN)); + } + else if(ai_ConcentrationCondition(oMaster)) + { + SignalEvent(oCaster,EventUserDefined(X2_EVENT_CONCENTRATION_BROKEN)); + } + } + } +} +int ai_CastInMelee(object oCreature, int nSpell, int nInMelee) +{ + // If this is a spell and we are in melee. + if(nInMelee > 0 && !GetHasFeat(FEAT_EPIC_IMPROVED_COMBAT_CASTING, oCreature)) + { + // Using DC 19 so we will use with up to a 50% failure. + int nSpellLevel = StringToInt(Get2DAString("spells", "Innate", nSpell)); + int nDC = AI_DEFENSIVE_CASTING_DC + nSpellLevel; + int nRoll = Random(AI_DEFENSIVE_CASTING_DIE) + 1; + int nConcentration = GetSkillRank(SKILL_CONCENTRATION, oCreature); + if(GetHasFeat(FEAT_COMBAT_CASTING, oCreature)) nConcentration += 4; + if(AI_DEBUG) ai_Debug("0i_spells", "1081", "Use Defensive Casting? nDC: " + IntToString(nDC) + " FEAT_COMBAT_CASTING: " + + IntToString(GetHasFeat(FEAT_COMBAT_CASTING, oCreature)) + + " nConcentration: " + IntToString(nConcentration) + " + nRoll: " + IntToString(nRoll)); + if(nConcentration + nRoll > nDC) + { + if(AI_DEBUG) ai_Debug("0i_spells", "1086", GetName(oCreature) + " is casting defensively!"); + SetActionMode(oCreature, ACTION_MODE_DEFENSIVE_CAST, TRUE); + } + // Defensive casting is a bad idea so maybe casting anyspell is a bad idea. + else + { + object oMelee = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(GetIsObjectValid(oMelee)) + { + nRoll = Random(AI_CASTING_IN_MELEE_ROLL) + 1; + nDC = AI_CASTING_IN_MELEE_DC + nSpellLevel + nInMelee * ai_GetCreatureAttackBonus(oMelee); + if(AI_DEBUG) ai_Debug("0i_spells", "1097", "Cast anyway: nConcentration: " + IntToString(nConcentration) + + " nRoll: " + IntToString(nRoll) + " nDC: " + IntToString(nDC) + + " oMelee: " + GetName(oMelee)); + if(nConcentration + nRoll > nDC) return TRUE; + if(AI_DEBUG) ai_Debug("0i_spells", "1101", GetName(oCreature) + " is not casting in melee against " + GetName(oMelee)); + return FALSE; + } + } + } + // We don't need to cast defensively so lets make sure it's off. + else if(GetActionMode(oCreature, ACTION_MODE_DEFENSIVE_CAST)) + { + SetActionMode(oCreature, ACTION_MODE_DEFENSIVE_CAST, FALSE); + } + return TRUE; +} +float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell) +{ + // Search the spell range + the distance to the closest enemy - 7.5 meters). + // This will keep the caster from running up on an enemy to cast. + // But allow them to move up some if needed. + float fRange = ai_GetSpellRange(nSpell); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + float fEnemyDistance = GetDistanceBetween(oCreature, oNearestEnemy); + // Spell range is less than the nearest enemy. Restrict based on nearest enemy. + // Spell range is less than the nearestenemy. Check enemy action then adjust. + if(fRange < fEnemyDistance) + { + // We check this because if the enemy is moving or has not started acting + // then we don't want to move up on them as they might move towards us! + int nAction = GetCurrentAction(oNearestEnemy); + if(AI_DEBUG) ai_Debug("0i_spells", "1130", GetName(oNearestEnemy) + " current action: " + IntToString(nAction)); + if(nAction != ACTION_MOVETOPOINT || nAction != ACTION_ITEMCASTSPELL || + nAction != ACTION_INVALID || nAction != ACTION_USEOBJECT || + nAction != ACTION_RANDOMWALK) fRange = fEnemyDistance + (fRange - 7.5); + } + if(fRange > AI_RANGE_BATTLEFIELD) return AI_RANGE_BATTLEFIELD; + else if(fRange < 0.1f) return 0.1f; + return fRange; +} +int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage) +{ + if(AI_DEBUG) ai_Debug("0i_spells", "1127", "nSpell: " + IntToString(nSpell) + " nDamage: " + + IntToString(nDamage)); + if(nSpell == SPELL_HEAL && nDamage > 50) return TRUE; + else if(nSpell == SPELL_CURE_CRITICAL_WOUNDS && nDamage > 31) return TRUE; + else if(nSpell == SPELL_CURE_SERIOUS_WOUNDS && nDamage > 23) return TRUE; + else if(nSpell == SPELL_CURE_MODERATE_WOUNDS && nDamage > 15) return TRUE; + else if(nSpell == SPELL_CURE_LIGHT_WOUNDS && nDamage > 6) return TRUE; + else if(nSpell == SPELL_CURE_MINOR_WOUNDS) return TRUE; + return FALSE; +} +void ai_CastWidgetSpell(object oPC, object oAssociate, object oTarget, location lLocation) +{ + int nIndex = GetLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + DeleteLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jSpell = JsonArrayGet(jWidget, nIndex); + int nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + int nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + int nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + int nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + //SendMessageToPC(oPC, "nSpell: " + IntToString(nSpell) + + // " oTarget: " + GetName(oTarget) + + // " nMetaMagic: " + IntToString(nMetaMagic) + + // " nDomain: " + IntToString(nDomain)); + if(GetCurrentAction(oAssociate) != ACTION_CASTSPELL) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + if(!GetIsObjectValid(oTarget)) + { + AssignCommand(oAssociate, ActionCastSpellAtLocation(nSpell, lLocation, nMetaMagic, FALSE, 0, FALSE, -1, FALSE, nDomain)); + } + else AssignCommand(oAssociate, ActionCastSpellAtObject(nSpell, oTarget, nMetaMagic, FALSE, nDomain)); + +} +void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lLocation) +{ + int nIndex = GetLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + DeleteLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jFeat = JsonArrayGet(jWidget, nIndex); + int nFeat = JsonGetInt(JsonArrayGet(jFeat, 5)); + if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + //SendMessageToPC(oPC, "0i_spells, 2104, nFeat: " + IntToString(nFeat) + " oTarget: " + GetName(oTarget)); + if(!GetIsObjectValid(oTarget)) + { + AssignCommand(oAssociate, ActionUseFeat(nFeat, OBJECT_INVALID, 0, lLocation)); + } + else AssignCommand(oAssociate, ActionUseFeat(nFeat, oTarget)); +} +void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lLocation) +{ + int nIndex = GetLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + DeleteLocalInt(oAssociate, "AI_WIDGET_SPELL_INDEX"); + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata"); + json jSpells = JsonArrayGet(jAIData, 10); + json jWidget = JsonArrayGet(jSpells, 2); + json jItem = JsonArrayGet(jWidget, nIndex); + int nSpell = JsonGetInt(JsonArrayGet(jItem, 0)); + int nIprpSubType = JsonGetInt(JsonArrayGet(jItem, 4)); + object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jItem, 5))); + itemproperty ipProperty; + if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE)); + if(nSpell == SPELL_HEALINGKIT) + { + ipProperty = GetFirstItemProperty(oItem); + if(GetItemPropertyType(ipProperty) == ITEM_PROPERTY_HEALERS_KIT) + { + if(ai_GetIsCharacter(oPC)) ai_SendMessages(GetName(oAssociate) + " uses " + GetName(oItem) + " on " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC); + AssignCommand(oAssociate, ActionUseItemOnObject(oItem, ipProperty, oTarget)); + return; + } + } + ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(nIprpSubType == GetItemPropertySubType(ipProperty)) break; + ipProperty = GetNextItemProperty(oItem); + } + if(!GetIsObjectValid(oTarget)) + { + AssignCommand(oAssociate, ActionUseItemAtLocation(oItem, ipProperty, lLocation)); + } + else AssignCommand(oAssociate, ActionUseItemOnObject(oItem, ipProperty, oTarget)); +} diff --git a/src/module/nss/0i_states_cond.nss b/src/module/nss/0i_states_cond.nss new file mode 100644 index 0000000..4c77ccf --- /dev/null +++ b/src/module/nss/0i_states_cond.nss @@ -0,0 +1,423 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_states_cond +////////////////////////////////////////////////////////////////////////////////////////////////////// + Include scripts that handle states and conditions for combat. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +#include "0i_messages" +#include "0i_time" +//#include "X0_I0_COMBAT" +// Wrapper for ClearAllActions - we have added extra vars to be cleared as well. +// Note this references OBJECT_SELF! +void ai_ClearCreatureActions(int bClearCombatState = FALSE); +// Used in combat to keep track of the creatures last rounds action. +// One use is to make sure we don't use the same spell on the next round. +// 0+ is the spell that was cast, other actions use AI_LAST_ACTION_* constants. +void ai_SetLastAction(object oCreature, int nAction = AI_LAST_ACTION_NONE); +// Returns TRUE if oCreatures last rounds action is equal to nAction. +// 0+ is the spell that was cast, other actions use AI_LAST_ACTION_* constants. +int ai_CompareLastAction(object oCreature, int nAction); +// Sets the correct listen checks on oCreature. +void ai_SetListeningPatterns(object oCreature); +// Returns TRUE if oCreature is an elemental, undead, or golem i.e. non-living. +int ai_IsNonliving(int nRacialType); +// Returns TRUE if oCreature is in combat. +int ai_GetIsInCombat(object oCreature); +// Sets the time that this oCreature's current combat round started. +// Using action based combat rounds has an unfortunate side effect: +// Once you attack in melee you will continue to attack in melee do to hardcoded +// logic. This will "PUSH" your end of round back until it decides to stop attacking! +// We avoid this by setting the time and if we check for combat and 6 seconds has +// passed then we assume the current round is over, ClearAllActions, and start the next round. +void ai_SetCombatRound(object oCreature); +// Clears the current combat round timer by deleting the value. +void ai_EndCombatRound(object oCreature); +// Returns TRUE if AI_COMBAT_ROUND_IN_SECONDS has not passed since ai_SetCombatRound. +// If it returns FALSE then it will clear the current combat round timer. +int ai_IsInCombatRound(object oCreature, int nCombatRound = AI_COMBAT_ROUND_IN_SECONDS); +// Returns TRUE if oCreature is busy. +// This checks various actions to see if oCreature is busy; +// in combat, busy mode, Actions: attacking, casting spell, counterspelling, +// disabling trap, item casting spell, opening lock, resting, setting trap. +int ai_GetIsBusy(object oCreature); +// Returns a value based on the disabling effect. +// Dead = 1, Bleeding = 2, Dying = 2, Stunned = 29, Confused = 24, Paralyzed = 27 +// Frightened 25, Turned = 35, Petrified = 79, Charmed = 23, Disappearappear = 75, +// Time Stop = 66, Dazed = 28, Sleep = 30. +// Returns FALSE if not Disabled. +int ai_Disabled(object oCreature); +// Set one of the AI_MODE_* bitwise constants on oAssociate to bOn. +void ai_SetAIMode(object oAssociate, int nBit, int bOn = TRUE); +// Return if nMode is set on oAssociate. Uses the AI_MODE_* bitwise constants. +int ai_GetAIMode(object oAssociate, int nBit); +// Set one of the AI_MAGIC_* bitwise constants on oAssociate to bOn. +void ai_SetMagicMode(object oAssociate, int nBit, int bOn = TRUE); +// Return if nMode is set on oAssociate. Uses the AI_MAGIC_* bitwise constants. +int ai_GetMagicMode(object oAssociate, int nBit); +// This is based off of the PC's settings for an associate and other creatures use a default. +// Set one of the AI_LOOT_* bitwise constants on oAssociate to bOn. +void ai_SetLootFilter(object oAssociate, int nBit, int bOn = TRUE); +// Return if nMode is set on oAssociate. Uses the AI_LOOT_* bitwise constants. +int ai_GetLootFilter(object oAssociate, int nBit); +// Set one of the AI_IP_* bitwise constants on oCreature to bOn. +void ai_SetItemProperty(object oCreature, string sVarname, int nBit, int bOn = TRUE); +// Return if nMode is set on oCreature. Uses the AI_IP_* bitwise constants. +int ai_GetItemProperty(object oCreature, string sVarname, int nBit); +// Returns the number of hitpoints a creature must have to not be healed. +// This is based off of the PC's settings for an associate and other creatures use a default. +int ai_GetHealersHpLimit(object oCreature, int bInCombat = TRUE); +// Returns TRUE if nCondition is within nCurrentConditions. +// nCurrentConditions is setup in ai_GetNegativeConditions. +int ai_GetHasNegativeCondition(int nCondition, int nCurrentConditions); +// Returns an integer with bitwise flags set that represent the current negative +// conditions on oCreature. ai_GetHasNegativeCondition uses this function. +int ai_GetNegativeConditions(object oCreature); +// Returns TRUE if oObject is in the line of sight of oCreature. +// If the creature is close LineOfSight doesn't work well. +int ai_GetIsInLineOfSight(object oCreature, object oObject); +// Add the specified condition flag to the behavior state of the caller +void ai_SetBehaviorState(int nCondition, int bValid = TRUE); +// Returns TRUE if the specified behavior flag is set on the caller +int ai_GetBehaviorState(int nCondition); +// Highlights the current mode for the widget passed. +void ai_HighlightWidgetMode(object oPC, object oAssociate, int nToken); +// Checks to see if the party scale is correctly adjusted. +void ai_CheckXPPartyScale(object oCreature); + +void ai_ClearCreatureActions(int bClearCombatState = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_states_cond", "89", GetName(OBJECT_SELF) + " is clearing actions (" + + IntToString(bClearCombatState) + ")!"); + DeleteLocalInt(OBJECT_SELF, AI_CURRENT_ACTION_MODE); + ClearAllActions(bClearCombatState); +} +void ai_SetLastAction(object oCreature, int nAction = AI_LAST_ACTION_NONE) +{ + SetLocalInt(oCreature, sLastActionVarname, nAction); +} +int ai_CompareLastAction(object oCreature, int nAction) +{ + // Are we checking to see if we cast a spell? + if(nAction == AI_LAST_ACTION_CAST_SPELL && + GetLocalInt(oCreature, sLastActionVarname) > -1) return TRUE; + // Check other last actions. + return (nAction == GetLocalInt(oCreature, sLastActionVarname)); +} +void ai_SetListeningPatterns(object oCreature) +{ + SetListenPattern(oCreature, AI_I_SEE_AN_ENEMY, AI_ALLY_SEES_AN_ENEMY); + SetListenPattern(oCreature, AI_I_HEARD_AN_ENEMY, AI_ALLY_HEARD_AN_ENEMY); + SetListenPattern(oCreature, AI_ATKED_BY_WEAPON, AI_ALLY_ATKED_BY_WEAPON); + SetListenPattern(oCreature, AI_ATKED_BY_SPELL, AI_ALLY_ATKED_BY_SPELL); + SetListenPattern(oCreature, AI_I_AM_WOUNDED, AI_ALLY_IS_WOUNDED); + SetListenPattern(oCreature, AI_I_AM_DEAD, AI_ALLY_IS_DEAD); + SetListenPattern(oCreature, AI_I_AM_DISEASED, AI_ALLY_IS_DISEASED); + SetListenPattern(oCreature, AI_I_AM_POISONED, AI_ALLY_IS_POISONED); + SetListenPattern(oCreature, AI_I_AM_WEAK, AI_ALLY_IS_WEAK); + SetListening(oCreature, TRUE); +} +int ai_IsNonliving(int nRacialType) +{ + switch(nRacialType) + { + case RACIAL_TYPE_CONSTRUCT: + case RACIAL_TYPE_ELEMENTAL: + case RACIAL_TYPE_UNDEAD: return TRUE; + } + return FALSE; +} +int ai_GetIsInCombat(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_states_cond", "110", GetName(oCreature) + " is in Combat: Enemy Numbers = " + IntToString(GetLocalInt(oCreature, AI_ENEMY_NUMBERS))); + + return GetLocalInt(oCreature, AI_ENEMY_NUMBERS); +} +void ai_SetCombatRound(object oCreature) +{ + SetLocalInt(oCreature, "AI_COMBAT_ROUND_START", SQLite_GetTimeStamp()); + if(AI_DEBUG) ai_Debug("0i_states_cond", "116", " ===============> " + GetName(oCreature) + " ROUND START:" + IntToString(SQLite_GetTimeStamp()) + " <==============="); +} +void ai_EndCombatRound(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_states_cond", "120", " ===============> " + GetName(oCreature) + " ROUND END:" + IntToString(SQLite_GetTimeStamp()) + " <==============="); + DeleteLocalInt(oCreature, "AI_COMBAT_ROUND_START"); +} +int ai_IsInCombatRound(object oCreature, int nCombatRound = AI_COMBAT_ROUND_IN_SECONDS) +{ + int nCombatRoundStart = GetLocalInt(oCreature, "AI_COMBAT_ROUND_START"); + if(AI_DEBUG) ai_Debug("0i_states_cond", "148", " nCombatRoundStart: " + IntToString(nCombatRoundStart)); + if(!nCombatRoundStart) return FALSE; + // New combat round calculator. If 6 seconds has passed then we are on a new round! + int nSQLTime = SQLite_GetTimeStamp(); + int nCombatRoundTime = nSQLTime - nCombatRoundStart; + if(AI_DEBUG) ai_Debug("0i_states_cond", "153", " SQLite_GetTimeStamp: " + IntToString(nSQLTime) + + "(" + IntToString(nSQLTime - nCombatRoundStart) + ")"); + if(nCombatRoundTime < nCombatRound) return TRUE; + ai_EndCombatRound(oCreature); + return FALSE; +} +// Testing to see if we can fix some delaying in combat. +int ai_GetIsBusy(object oCreature) +{ + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("0i_states_cond", "140", GetName(oCreature) + " Get is Busy, action: " + + IntToString(nAction)); + switch(nAction) + { + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_OPENLOCK : + case ACTION_REST : + case ACTION_DISABLETRAP : + case ACTION_ATTACKOBJECT : + case ACTION_COUNTERSPELL : + case ACTION_SETTRAP : return TRUE; + case ACTION_WAIT : + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("0i_states_cond", "153", "nCombatWait: " + IntToString(nCombatWait) + + " AI_AM_I_SEARCHING: " + IntToString(GetLocalInt(oCreature, AI_AM_I_SEARCHING))); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return TRUE; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + else if(GetLocalInt(oCreature, AI_AM_I_SEARCHING)) DeleteLocalInt(oCreature, AI_AM_I_SEARCHING); + return FALSE; + } + case ACTION_MOVETOPOINT : + { + return ai_GetIsInCombat(oCreature); + } + } + return FALSE; +} +int ai_Disabled(object oCreature) +{ + if(GetIsDead(oCreature)) return 1; + // Check for effects. + effect eEffect = GetFirstEffect(oCreature); + while(GetIsEffectValid(eEffect)) + { + switch(GetEffectType(eEffect)) + { + case EFFECT_TYPE_DOMINATED : + { + if(!GetCommandable(oCreature)) SetCommandable(TRUE, oCreature); + return FALSE; + } + case EFFECT_TYPE_STUNNED : + case EFFECT_TYPE_DAZED : + case EFFECT_TYPE_SLEEP : + case EFFECT_TYPE_CONFUSED : + case EFFECT_TYPE_FRIGHTENED : + case EFFECT_TYPE_PARALYZE : + case EFFECT_TYPE_TURNED : + case EFFECT_TYPE_CHARMED : + case EFFECT_TYPE_PETRIFY : + case EFFECT_TYPE_TIMESTOP : + { + if(AI_DEBUG) ai_Debug("0i_stats_cond", "195", GetName(oCreature) + " is disabled(" + + IntToString(GetEffectType(eEffect)) + ")"); + return GetEffectType(eEffect); + } + } + eEffect = GetNextEffect(oCreature); + } + // Not Commandable is basically disabled as far as the AI is concerned. + if(!GetCommandable(oCreature)) + { + if(AI_DEBUG) ai_Debug("0i_stats_cond", "213", GetName(oCreature) + " is disabled(Not Commandable)!"); + return EFFECT_TYPE_PARALYZE; + } + if(AI_DEBUG) ai_Debug("0i_states_cond", "202", GetName(oCreature) + " is not disabled."); + return FALSE; +} +void ai_SetAIMode(object oAssociate, int nBit, int bOn = TRUE) +{ + int nAIModes = GetLocalInt(oAssociate, sAIModeVarname); + if(bOn) nAIModes = nAIModes | nBit; + else nAIModes = nAIModes & ~nBit; + SetLocalInt(oAssociate, sAIModeVarname, nAIModes); + // Set widget to show the mode they are in. + +} +int ai_GetAIMode(object oAssociate, int nBit) +{ + if(GetLocalInt(oAssociate, sAIModeVarname) & nBit) return TRUE; + return FALSE; +} +void ai_SetMagicMode(object oAssociate, int nBit, int bOn = TRUE) +{ + int nMagicModes = GetLocalInt(oAssociate, sMagicModeVarname); + if(bOn) nMagicModes = nMagicModes | nBit; + else nMagicModes = nMagicModes & ~nBit; + SetLocalInt(oAssociate, sMagicModeVarname, nMagicModes); +} +int ai_GetMagicMode(object oAssociate, int nBit) +{ + if(GetLocalInt(oAssociate, sMagicModeVarname) & nBit) return TRUE; + return FALSE; +} +void ai_SetLootFilter(object oAssociate, int nLootBit, int bOn = TRUE) +{ + int nLootFilter = GetLocalInt(oAssociate, sLootFilterVarname); + if(bOn) nLootFilter = nLootFilter | nLootBit; + else nLootFilter = nLootFilter & ~nLootBit; + SetLocalInt(oAssociate, sLootFilterVarname, nLootFilter); +} +int ai_GetLootFilter(object oAssociate, int nBit) +{ + if(GetLocalInt(oAssociate, sLootFilterVarname) & nBit) return TRUE; + return FALSE; +} +void ai_SetItemProperty(object oCreature, string sVarname, int nBit, int bOn = TRUE) +{ + int nItemProperties = GetLocalInt(oCreature, sVarname); + if(bOn) nItemProperties = nItemProperties | nBit; + else nItemProperties = nItemProperties & ~nBit; + SetLocalInt(oCreature, sVarname, nItemProperties); +} +int ai_GetItemProperty(object oCreature, string sVarname, int nBit) +{ + if(GetLocalInt(oCreature, sVarname) & nBit) return TRUE; + return FALSE; +} +int ai_GetHealersHpLimit(object oCreature, int bInCombat = TRUE) +{ + if(bInCombat) return GetLocalInt(oCreature, AI_HEAL_IN_COMBAT_LIMIT); + else return GetLocalInt(oCreature, AI_HEAL_OUT_OF_COMBAT_LIMIT); +} +int ai_GetHasNegativeCondition(int nCondition, int nCurrentConditions) +{ + return (nCurrentConditions & nCondition); +} +int ai_GetNegativeConditions(object oCreature) +{ + int nCondition, nEffectType; + effect eEffect = GetFirstEffect(oCreature); + while(GetIsEffectValid (eEffect)) + { + // Rage and maybe other abilities might come from the oCreature! + if(GetEffectCreator(eEffect) != oCreature) + { + nEffectType = GetEffectType(eEffect); + switch(nEffectType) + { + case EFFECT_TYPE_DISEASE: nCondition = nCondition | AI_CONDITION_DISEASE; break; + case EFFECT_TYPE_POISON: nCondition = nCondition | AI_CONDITION_POISON; break; + case EFFECT_TYPE_CURSE: nCondition = nCondition | AI_CONDITION_CURSE; break; + case EFFECT_TYPE_BLINDNESS: + case EFFECT_TYPE_DEAF: nCondition = nCondition | AI_CONDITION_BLINDDEAF; break; + case EFFECT_TYPE_ABILITY_DECREASE: nCondition = nCondition | AI_CONDITION_ABILITY_DRAIN; break; + case EFFECT_TYPE_NEGATIVELEVEL: nCondition = nCondition | AI_CONDITION_LEVEL_DRAIN; break; + case EFFECT_TYPE_AC_DECREASE: nCondition = nCondition | AI_CONDITION_AC_DECREASE; break; + case EFFECT_TYPE_ATTACK_DECREASE: nCondition = nCondition | AI_CONDITION_ATK_DECREASE; break; + case EFFECT_TYPE_CHARMED: nCondition = nCondition | AI_CONDITION_CHARMED; break; + case EFFECT_TYPE_CONFUSED: nCondition = nCondition | AI_CONDITION_CONFUSED; break; + case EFFECT_TYPE_DAZED: nCondition = nCondition | AI_CONDITION_DAZED; break; + case EFFECT_TYPE_DAMAGE_DECREASE: nCondition = nCondition | AI_CONDITION_DMG_DECREASE; break; + case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE: nCondition = nCondition | AI_CONDITION_DMG_I_DECREASE; break; + case EFFECT_TYPE_DOMINATED: nCondition = nCondition | AI_CONDITION_DOMINATED; break; + case EFFECT_TYPE_FRIGHTENED: nCondition = nCondition | AI_CONDITION_FRIGHTENED; break; + case EFFECT_TYPE_PARALYZE: nCondition = nCondition | AI_CONDITION_PARALYZE; break; + case EFFECT_TYPE_SAVING_THROW_DECREASE: nCondition = nCondition | AI_CONDITION_SAVE_DECREASE; break; + case EFFECT_TYPE_SKILL_DECREASE: nCondition = nCondition | AI_CONDITION_SKILL_DECREASE; break; + case EFFECT_TYPE_SLOW: nCondition = nCondition | AI_CONDITION_SLOW; break; + case EFFECT_TYPE_SPELL_RESISTANCE_DECREASE: nCondition = nCondition | AI_CONDITION_SR_DECREASE; break; + case EFFECT_TYPE_STUNNED: nCondition = nCondition | AI_CONDITION_STUNNED; break; + } + } + eEffect = GetNextEffect(oCreature); + } + return nCondition; +} +int ai_GetIsInLineOfSight(object oCreature, object oObject) +{ + // Creatures can block the line of sight so when close we shouldn't check. + if(GetDistanceBetween(oObject, oCreature) <= AI_RANGE_MELEE) return TRUE; + return LineOfSightObject(oCreature, oObject); +} +void ai_SetBehaviorState(int nCondition, int bValid = TRUE) +{ + int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER"); + if(bValid) + { + nPlot = nPlot | nCondition; + SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot); + } + else + { + nPlot = nPlot & ~nCondition; + SetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER", nPlot); + } +} +int ai_GetBehaviorState(int nCondition) +{ + int nPlot = GetLocalInt(OBJECT_SELF, "NW_BEHAVIOR_MASTER"); + if(nPlot & nCondition) return TRUE; + return FALSE; +} +void ai_HighlightWidgetMode(object oPC, object oAssociate, int nToken) +{ + if(oPC == oAssociate) return; + int bBool; + bBool = ai_GetAIMode(oAssociate,AI_MODE_DEFEND_MASTER); + NuiSetBind(oPC, nToken, "btn_cmd_guard_encouraged", JsonBool(bBool)); + bBool = ai_GetAIMode(oAssociate,AI_MODE_STAND_GROUND); + NuiSetBind(oPC, nToken, "btn_cmd_hold_encouraged", JsonBool(bBool)); + bBool = ai_GetAIMode(oAssociate,AI_MODE_FOLLOW); + NuiSetBind(oPC, nToken, "btn_cmd_follow_encouraged", JsonBool(bBool)); + if(!ai_GetAIMode(oAssociate, AI_MODE_DEFEND_MASTER) && + !ai_GetAIMode(oAssociate, AI_MODE_STAND_GROUND) && + !ai_GetAIMode(oAssociate, AI_MODE_FOLLOW)) bBool = TRUE; + else bBool = FALSE; + NuiSetBind(oPC, nToken, "btn_cmd_attack_encouraged", JsonBool(bBool)); +} +void ai_CheckXPPartyScale(object oCreature) +{ + object oModule = GetModule(); + if(!GetLocalInt(oModule, AI_RULE_PARTY_SCALE)) return; + object oMaster; + if(!ai_GetIsCharacter(oCreature)) + { + oMaster = GetMaster(oCreature); + while(oMaster != OBJECT_INVALID) + { + if(ai_GetIsCharacter(oMaster)) break; + oMaster = GetMaster(oMaster); + } + if(oMaster == OBJECT_INVALID) return; + } + else oMaster = oCreature; + float fDefaultXPScale = IntToFloat(GetLocalInt(oModule, AI_BASE_PARTY_SCALE_XP)); + float fPartySize = 4.0; + int nAssociateType, nHenchman, nHenchAssociate; + object oHenchman; + for(nAssociateType = 1; nAssociateType <= 5; nAssociateType++) + { + if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) + { + for(nHenchman = 1; nHenchman <= AI_MAX_HENCHMAN; nHenchman++) + { + oHenchman = GetAssociate(nAssociateType, oMaster, nHenchman); + if(oHenchman != OBJECT_INVALID) + { + fPartySize += 1.0; + for(nHenchAssociate = 2; nHenchAssociate <= 5; nHenchAssociate++) + { + if(GetAssociate(nHenchAssociate, oHenchman, 1) != OBJECT_INVALID) fPartySize += 1.0; + } + } + } + } + else if(GetAssociate(nAssociateType, oMaster, 1) != OBJECT_INVALID) fPartySize += 1.0; + } + int nXPScale = FloatToInt(fPartySize / 4.0 * fDefaultXPScale); + //SendMessageToPC(oMaster, GetName(oMaster) + " nXPScale = (3 + fPartySize / 4.0 * fDefaultXPScale)" + + // IntToString(nXPScale) + " = (" + FloatToString(fPartySize, 0, 1) + " / 4.0 * " + + // FloatToString(fDefaultXPScale, 0, 1) + ")"); + SetModuleXPScale(nXPScale); +} + diff --git a/src/module/nss/0i_talents.nss b/src/module/nss/0i_talents.nss new file mode 100644 index 0000000..fa773b9 --- /dev/null +++ b/src/module/nss/0i_talents.nss @@ -0,0 +1,3098 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0i_talents + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Fuctions to use a category of skills, feats, spells, or items. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_combat" +// ***************************************************************************** +// ************************* Try * Defensive Talents *************************** +// ***************************************************************************** +// These functions try to find and use a specific set of talents intelligently. + +// Returns TRUE if oCreature uses a healing talent on oTarge. +// nInMelee is the number of enemies the caller is in melee with. +// If oTarget is set then they will heal that target if they need it. +// Otherwise checks all allies to see who we should heal based on the talent. +int ai_TryHealingTalent(object oCreature, int nInMelee, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses a cure condition talent on an ally or self. +int ai_TryCureConditionTalent(object oCreature, int nInMelee, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses a defensive talent. +// Checks for a Defensive talent(Protection, Enhancement, or Summons). +// Randomizes the order to mix up spells in combat. +// if oTarget is set then the defensive talent will be cast on them or OBJECT_SELF. +int ai_TryDefensiveTalents(object oCreature, int nInMelee, int nMaxLevel, int nRound = 0, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses a defensive talent. +// Checks the enemy faction for most powerful class and picks a buff based on it. +//int ai_TryAdvancedBuffOnSelf(object oCreature, int nInMelee); +// Set any auras this oCreature has instantly. +// This can be done in the OnSpawn script, heart beat, or Perception. +void ai_SetAura(object oCreature); + +// ***************************************************************************** +// ************************ Try Physical Attack Talents ************************ +// ***************************************************************************** +// These functions try to find and use melee attack talents intelligently. + +// Wrapper for ActionAttack, oCreature uses nAction (attack) on oTarget. +// nInMelee is only used in AI_LAST_ACTION_RANGED_ATK actions. +// bPassive TRUE oCreature will not move while attacking. +// nActionMode, pass the action mode if one is being used. +void ai_ActionAttack(object oCreature, int nAction, object oTarget, int nInMelee = 0, int bPassive = FALSE, int nActionMode = 0); +// Returns TRUE if oCreature uses a dragons breath talent +// Check for dragon's attacks under TALENT_CATEGORY_DRAGONS_BREATH(19). +// nRound must be supplied so we can keep track of the breath uses. +int ai_TryDragonBreathAttack(object oCreature, int nRound, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses a dragons wing attacks. +// Checks to see if a dragon can use its wings on a nearby enemy. +// Checks the right side and then the left side to see if it can attack. +int ai_TryWingAttacks(object oCreature); +// Returns TRUE if oCreature uses a dragons tail slap. +// Looks behind the dragon to see if it can use it's tail slap on an enemy. +int ai_TryTailSlap(object oCreature); +// Returns TRUE if oCreature uses a dragons crush attack. +// Dragon can fly up and crash down on opponents to do bludgeoning damage. +// If 3 times smaller than the dragon they will take extra damage and be +// Knocked Down for 1 round if Reflex save is not made. +int ai_TryCrushAttack(object oCreature, object oTarget); +// Returns TRUE if oCreature uses a dragons tail sweep attack. +// If the enemy is 4 sizes smaller than it the dragon to use its tail to sweep +// behind it doing damage and knocking the opponents down. +int ai_TryTailSweepAttack(object oCreature); +// Returns TRUE if oCreature finds a good target and uses Sneak Attack. +int ai_TrySneakAttack(object oCreature, int nInMelee, int bAlwaysAtk = TRUE); +// Returns TRUE if oCreature finds a good ranged target and uses Sneak Attack. +int ai_TryRangedSneakAttack(object oCreature, int nInMelee); +// Returns TRUE if oCreature uses a harmful melee talent. +int ai_TryMeleeTalents(object oCreature, object oTarget); +// ***************************************************************************** +// ******************************* Try * Skills ******************************** +// ***************************************************************************** +// These functions try to find and use a specific set of skills intelligently. + +// Wrapper to have oCreature use nSkill on oTarget. +void ai_UseSkill(object oCreature, int nSkill, object oTarget); +// Returns TRUE if oCreature uses the parry skill on someone attacking them. +// Checks if doing a parry might be successful. +int ai_TryParry(object oCreature); +// Returns TRUE if oCreature uses the Taunt skill on oTarget. +// Checks if doing a taunt might be successful against oTarget. +int ai_TryTaunt(object oCreature, object oTarget); +// Returns TRUE if oCreature uses the Animial emapthy skill on oTarget. +// For it to work oTarget must be an Animal, Beast, or Magical Beast. +// Checks if doing Animal Empathy might be successful against oTarget. +int ai_TryAnimalEmpathy(object oCreature, object oTarget = OBJECT_INVALID); +// ***************************************************************************** +// ******************************** Try * Feats ******************************** +// ***************************************************************************** +// These functions try to find and use a specific set of feats intelligently. + +// Wrapper to have oCreature use nFeat on oTarget. +void ai_UseFeat(object oCreature, int nFeat, object oTarget, int nSubFeat = 0); +// Wrapper to have oCreature use nActionMode on oTarget. +// nInMelee is only used in AI_LAST_ACTION_RANGED_ATK actions. +// bPassive TRUE oCreature will not move while attacking. +void ai_UseFeatAttackMode(object oCreature, int nActionMode, int nAction, object oTarget, int nInMelee = 0, int bPassive = FALSE); +// Returns TRUE if oCreature uses Rage. +// This checks if they are already in a rage and if they have the Rage feat. +int ai_TryBarbarianRageFeat(object oCreature); +// Returns TRUE if oCreature uses Bard song. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TryBardSongFeat(object oCreature); +// Returns TRUE if oCreature uses Called shot. +// This checks if they have the feat and if its viable. +int ai_TryCalledShotFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Disarm. +// This checks if they have the feat and if its viable. +int ai_TryDisarmFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Divine Might. +// This only checks if they can use the feat and have turn undead uses left. +int ai_TryDivineMightFeat(object oCreature, int nInMelee); +// Returns TRUE if oCreature uses Divine Shield. +// This only checks if they can use the feat and have turn undead uses left. +int ai_TryDivineShieldFeat(object oCreature, int nInMelee); +// Returns TRUE if oCreature uses Expertise. +// This checks if they have the feat and if its viable. +// Also checks to see if the Improved Expertise feat would be better. +int ai_TryExpertiseFeat(object oCreature); +// Returns TRUE if oCreature uses Flurry of Blows. +// This checks if they have the feat and if its viable. +int ai_TryFlurryOfBlowsFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Improved Expertise. +// This checks if they have the feat and if its viable. +// Also checks to see if the Expertise feat would be better. +int ai_TryImprovedExpertiseFeat(object oCreature); +// Returns TRUE if oCreature uses Improved Power Attack. +// This checks if they have the feat and if its viable. +// Also checks to see if the Power Attack feat would be better. +int ai_TryImprovedPowerAttackFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Ki Damage. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TryKiDamageFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Knockdown. +// This checks if they have the feat and if its viable. +int ai_TryKnockdownFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses a polymorph self feat. +// This checks if they have the feat and will use the best one. +int ai_TryPolymorphSelfFeat(object oCreature); +// Returns TRUE if oCreature uses Power Attack. +// This checks if they have the feat and if its viable. +// Also checks to see if the Improved Power Attack would be better. +int ai_TryPowerAttackFeat(object oCreature, object oEnemy); +// Returns TRUE if oCreature uses Quivering palm. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TryQuiveringPalmFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Power Attack. +// This checks if they have the feat and if its viable. +// Using a bow and having arrows should be checked before calling this. +int ai_TryRapidShotFeat(object oCreature, object oTarget, int nInMelee); +// Returns TRUE if oCreature uses Sap. +// This checks if they have the feat and if its viable. +int ai_TrySapFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Smite evil. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TrySmiteEvilFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Smite good. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TrySmiteGoodFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses Stunning fists. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TryStunningFistFeat(object oCreature, object oTarget); +// Returns TRUE if oCreature uses a summon animal companion talent. +int ai_TrySummonAnimalCompanionTalent(object oCreature); +// Returns TRUE if oCreature uses a summon familiar talent. +int ai_TrySummonFamiliarTalent(object oCreature); +// Returns TRUE if oCreature uses the Lay on Hands feat talent. +int ai_TryLayOnHands(object oCreature); +// Returns TRUE if oCreature uses a turning talent. +int ai_TryTurningTalent(object oCreature); +// Returns TRUE if oCreature uses Whirlwind. +// This checks if they have the feat and if its viable. +int ai_TryWhirlwindFeat(object oCreature); +// Returns TRUE if oCreature uses Wholeness of Body. +// This checks if they have any uses left, have the feat and if its viable. +int ai_TryWholenessOfBodyFeat(object oCreature); +// ***************************************************************************** +// ***************************** TALENT SCRIPTS ****************************** +// ***************************************************************************** +// These functions do not fall into another section. + +// Returns the MaxLevel used in GetCreatureTalent for oCreature. +// This checks the intelligence and the level of oCreature. +// Returns either -1 (random) or 10 for all talents. +int ai_GetMonsterTalentMaxLevel(object oCreature); +// Returns the nMaxLevel used in GetCreatureTalent for oCreature. +// This checks the difficulty of the combat and the level of oCreature. +// Return a number equal to 1 and half the level of oCreature upto 10. +// The max spell level used is equal to nMaxLevel or less. +int ai_GetAssociateTalentMaxLevel(object oCreature, int nDifficulty); +// Returns TRUE if oCreature has nTalent. +// nTalent will be a spell in the spells.2da. +int ai_GetHasTalent(object oCreature, int nTalent); +// Saves a talent in JsonArray. +// Array: 0-Type (1-spell, 2-sp ability, 4-feat, 3-item) +// Type 1)spell 0-type, 1-spell, 2-class, 3-level, 4-slot. +// Type 2)sp Ability 0-type, 1-spell, 2-class, 3-level, 4-slot. +// Type 3)feat 0-type, 1-spell, 2- class, 3- level. +// Type 4)item 0-type, 1-spell, 2-item object, 3-level, 4-slot. +// jJsonLevel is the level to place the talent in the json array +// maybe different then the talents actual level which is passed in nLevel. +void ai_SaveTalent(object oCreature, int nClass, int nJsonLevel, int nLevel, int nSlot, int nSpell, int nType, int bBuff, object oItem = OBJECT_INVALID); +// Removes a talent nSlotIndex from jLevel in jCategory. +void ai_RemoveTalent(object oCreature, json jCategory, json jLevel, string sCategory, int nLevel, int nSlotIndex); +// Saves a creatures talents to variables upon them for combat use. +// bMonster will check to see if they should be buffed when we set the talents. +void ai_SetCreatureTalents(object oCreature, int bMonster); +// Return TRUE if oCreature spontaneously casts a cure spell from a talent in sCategory. +int ai_UseSpontaneousCureTalentFromCategory(object oCreature, string sCategory, int nInMelee, int nDamage, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses jTalent on oTarget. +// also Returns -1 if oCreature uses jTalent on oTarget with a memorized spell. +// This allows the user to remove jTalent from jLevel in jCategory. +int ai_UseCreatureSpellTalent(object oCreature, json jLevel, json jTalent, string sCategory, int nInMelee, object oTarget = OBJECT_INVALID); +// Return TRUE if oCreature uses a jTalent from oItem on oTarget. +int ai_UseCreatureItemTalent(object oCreature, json jLevel, json jTalent, string sCategory, int nInMelee, object oTarget = OBJECT_INVALID); +// Returns TRUE if oCreature uses a talent from sCategory of nLevel or less. +int ai_UseCreatureTalent(object oCreature, string sCategory, int nInMelee, int nLevel = 10, object oTarget = OBJECT_INVALID); +// Return TRUE if oCreature uses nTalent on oTarget. +int ai_UseTalent(object oCreature, int nTalent, object oTarget); +// Returns TRUE if jTalent is used on oTarget by oCaster. +// Checks the talent type and casts the correct spell. For items it checks uses. +int ai_UseTalentOnObject(object oCaster, json jTalent, object oTarget, int nInMelee); +// Returns TRUE if jTalent is used at lTarget location by oCaster. +// Checks the talent type and cast the correct spell. For items it checks uses. +int ai_UseTalentAtLocation(object oCaster, json jTalent, object oTarget, int nInMelee); +// Return TRUE if oCreature uses jTalent on oTarget after checking special cases. +int ai_CheckSpecialTalentsandUse(object oCreature, json jTalent, string sCategory, int nInMelee, object oTarget); + +int ai_TryHealingTalent(object oCreature, int nInMelee, object oTarget = OBJECT_INVALID) +{ + // First lets evaluate oTarget and see how strong of a spell we will need. + if(oTarget != OBJECT_INVALID) + { + if(oTarget == oCreature) + { + if(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF)) return FALSE; + } + else if(ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) return FALSE; + } + // We don't have a target so lets go check for one. + else + { + if(!ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) + { + // Lets not run past an enemy to heal unless we have the feats, bad tactics! + float fRange; + if(ai_CanIMoveInCombat(oCreature)) fRange = AI_RANGE_PERCEPTION; + else + { + fRange = GetDistanceBetween(oCreature, GetLocalObject(oCreature, AI_ENEMY_NEAREST)) - 3.0f; + // Looks bad when your right next to an ally, but technically the enemy is closer. + if(fRange < AI_RANGE_MELEE) fRange = AI_RANGE_MELEE; + } + oTarget = ai_GetAllyToHealTarget(oCreature, fRange); + } + else oTarget = oCreature; + if(oTarget == OBJECT_INVALID) return FALSE; + } + // Should we ignore associates? + if(ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + int nHp = ai_GetPercHPLoss(oTarget); + int nHpLimit = ai_GetHealersHpLimit(oCreature); + if(AI_DEBUG) ai_Debug("0i_talents", "256", "nHp: " + IntToString(nHp) + + "< nHpLimit: " + IntToString(nHpLimit)); + if(nHp > nHpLimit) return FALSE; + int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "260", GetName(oTarget) + " has lost " + IntToString(nDamage) + " hitpoints!"); + // Do they have Lay on Hands? + int bUseMagic = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC); + if(bUseMagic && GetHasFeat(FEAT_LAY_ON_HANDS, oCreature)) + { + int nCanHeal = GetAbilityModifier(ABILITY_CHARISMA, oCreature) * ai_GetCharacterLevels(oCreature); + if(nCanHeal <= nDamage) + { + ai_UseFeat(oCreature, FEAT_LAY_ON_HANDS, oTarget); + return TRUE; + } + } + int nMaxLevel = 9; + // If they are about to die then throw caution to the wind and HEAL! + if(nHp <= AI_HEALTH_BLOODY || nHp < 11) nInMelee = 0; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_HEALING, nInMelee, nMaxLevel, oTarget)) return TRUE; + if(AI_DEBUG) ai_Debug("0i_talents", "275", GetName(oCreature) + " has no healing spells!" + + " Cleric lvls: " + IntToString(GetLevelByClass(CLASS_TYPE_CLERIC, oCreature)) + + " Sontaneous casting: " + IntToString(ai_GetMagicMode(oCreature, AI_MAGIC_NO_SPONTANEOUS_CURE))); + if(bUseMagic && GetLevelByClass(CLASS_TYPE_CLERIC, oCreature) && + !ai_GetMagicMode(oCreature, AI_MAGIC_NO_SPONTANEOUS_CURE)) + { + // We need to check our talents and see what spells we can convert. + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_ENHANCEMENT, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_PROTECTION, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_TOUCH, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_RANGED, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_SUMMON, nInMelee, nDamage, oTarget)) return TRUE; + if(ai_UseSpontaneousCureTalentFromCategory(oCreature, AI_TALENT_CURE, nInMelee, nDamage, oTarget)) return TRUE; + } + return FALSE; +} +int ai_CheckTargetVsConditions(object oTarget, json jTalent, int nConditions) +{ + // Check nCondition for any negative effects based on the talent we have. + switch(JsonGetInt(JsonArrayGet(jTalent, 1))) + { + case SPELL_NEUTRALIZE_POISON : + if(ai_GetHasNegativeCondition(AI_CONDITION_POISON, nConditions)) return TRUE; + break; + case SPELL_REMOVE_DISEASE : + if(ai_GetHasNegativeCondition(AI_CONDITION_DISEASE, nConditions)) return TRUE; + break; + case SPELL_REMOVE_BLINDNESS_AND_DEAFNESS : + if(ai_GetHasNegativeCondition(AI_CONDITION_BLINDDEAF, nConditions)) return TRUE; + break; + case SPELL_REMOVE_FEAR : + if(ai_GetHasNegativeCondition(AI_CONDITION_FRIGHTENED, nConditions)) return TRUE; + break; + case SPELL_REMOVE_CURSE : + if(ai_GetHasNegativeCondition(AI_CONDITION_CURSE, nConditions)) return TRUE; + break; + case SPELL_REMOVE_PARALYSIS : + if(ai_GetHasNegativeCondition(AI_CONDITION_PARALYZE, nConditions)) return TRUE; + break; + case SPELL_CLARITY : + if(ai_GetHasNegativeCondition(AI_CONDITION_DAZED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_CHARMED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_CONFUSED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_STUNNED, nConditions)) return TRUE; + break; + case SPELL_GREATER_RESTORATION : + if(ai_GetHasNegativeCondition(AI_CONDITION_DAZED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_CONFUSED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_DOMINATED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_SLOW, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_FRIGHTENED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_STUNNED, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_CHARMED, nConditions)) return TRUE; + case SPELL_RESTORATION : + if(ai_GetHasNegativeCondition(AI_CONDITION_LEVEL_DRAIN, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_BLINDDEAF, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_PARALYZE, nConditions)) return TRUE; + case SPELL_LESSER_RESTORATION : + if(ai_GetHasNegativeCondition(AI_CONDITION_ABILITY_DRAIN, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_SAVE_DECREASE, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_SR_DECREASE, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_SKILL_DECREASE, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_AC_DECREASE , nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_ATK_DECREASE, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_DMG_DECREASE, nConditions)) return TRUE; + if(ai_GetHasNegativeCondition(AI_CONDITION_DMG_I_DECREASE, nConditions)) return TRUE; + } + return FALSE; +} +int ai_CheckTalentsVsConditions(object oCreature, int nConditions, int nInMelee, int nLevel, object oTarget) +{ + // Get the saved category from oCreature. + json jCategory = GetLocalJson(oCreature, AI_TALENT_CURE); + if(AI_DEBUG) ai_Debug("0i_talents", "357", "jCategory: " + AI_TALENT_CURE + " " + JsonDump(jCategory, 2)); + if(JsonGetType(jCategory) == JSON_TYPE_NULL) + { + SetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE, -1); + return FALSE; + } + // Get the max talent level so we can skip the higher ones and save time. + int nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE); + if(AI_DEBUG) ai_Debug("0i_talents", "365", AI_MAX_TALENT + AI_TALENT_CURE + ": " + + IntToString(nMaxTalentLevel) + + " nLevel: " + IntToString(nLevel)); + if(nMaxTalentLevel < nLevel) nLevel = nMaxTalentLevel; + if(nLevel < 0 || nLevel > 10) nLevel = 9; + json jLevel, jTalent; + int nClass, nSlot, nType, nSlotIndex, nMaxSlotIndex, nTalentUsed; + int bUseMagic = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC); + int bUseMagicItems = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC_ITEMS); + if(AI_DEBUG) ai_Debug("0i_talents", "374", "bUseMagic: " + IntToString(bUseMagic) + + " bUseMagicItems: " + IntToString(bUseMagicItems)); + // Loop through nLevels down to 0 looking for the first talent (i.e. the highest). + while(nLevel >= 0) + { + // Get the array of nLevel cycling down to 0. + jLevel = JsonArrayGet(jCategory, nLevel); + nMaxSlotIndex = JsonGetLength(jLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "382", "nLevel: " + IntToString(nLevel) + + " nMaxSlotIndex: " + IntToString(nMaxSlotIndex)); + if(nMaxSlotIndex > 0) + { + // Get the talent within nLevel cycling from the first to the last. + nSlotIndex = 0; + while (nSlotIndex <= nMaxSlotIndex) + { + jTalent= JsonArrayGet(jLevel, nSlotIndex); + if(AI_DEBUG) ai_Debug("0i_talents", "391", "nSlotIndex: " + IntToString(nSlotIndex) + + " jTalent Type: " + IntToString(JsonGetType(jTalent))); + // Check to see if the talent matches oTargets nConditionss. + if(ai_CheckTargetVsConditions(oTarget, jTalent, nConditions)) + { + nType = JsonGetInt(JsonArrayGet(jTalent, 0)); + if(bUseMagic) + { + if(nType == AI_TALENT_TYPE_SPELL) + { + if(ai_CastInMelee(oCreature, JsonGetInt(JsonArrayGet(jTalent, 1)), nInMelee)) + { + nTalentUsed = ai_UseCreatureSpellTalent(oCreature, jLevel, jTalent, AI_TALENT_CURE, nInMelee, oTarget); + // -1 means it was a memorized spell and we need to remove it. + if(nTalentUsed == -1) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, AI_TALENT_CURE, nLevel, nSlotIndex); + return TRUE; + } + else if(nTalentUsed) return TRUE; + } + } + else if(nType == AI_TALENT_TYPE_SP_ABILITY) + { + // Special ability spells do not need to concentrate?! + if(ai_CheckSpecialTalentsandUse(oCreature, jTalent, AI_TALENT_CURE, nInMelee, oTarget)) + { + // When the ability is used that slot is now not readied. + // Multiple uses of the same spell are stored in different slots. + ai_RemoveTalent(oCreature, jCategory, jLevel, AI_TALENT_CURE, nLevel, nSlotIndex); + return TRUE; + } + } + } + if(bUseMagicItems && nType == AI_TALENT_TYPE_ITEM) + { + // Items do not need to concentrate. + if(ai_UseCreatureItemTalent(oCreature, jLevel, jTalent, AI_TALENT_CURE, nInMelee, oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_talents", "430", "Checking if Item is used up: " + + IntToString(JsonGetInt(JsonArrayGet(jTalent, 4)))); + if(JsonGetInt(JsonArrayGet(jTalent, 4)) == -1) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, AI_TALENT_CURE, nLevel, nSlotIndex); + } + return TRUE; + } + } + } + nSlotIndex++; + } + } + else SetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE, nLevel - 1); + nLevel--; + } + return FALSE; +} +int ai_TryCureConditionTalent(object oCreature, int nInMelee, object oTarget = OBJECT_INVALID) +{ + // Is Casting Cure spells off? + if(ai_GetMagicMode(oCreature, AI_MAGIC_CURE_SPELLS_OFF)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "450", AI_MAX_TALENT + AI_TALENT_CURE + ": " + + IntToString(GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE))); + // If the creature doesn't have cure talents then we set it to -1. + if(GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE) == -1) return FALSE; + // We check targets to see if they need to be cured. + int nNegativeConditions, nTargetNegConds, nIndex, nCnt = 1; + object oTarget; + if(oTarget == OBJECT_INVALID) + { + oTarget = GetLocalObject(oCreature, AI_ALLY + "1"); + while(oTarget != OBJECT_INVALID) + { + nTargetNegConds = ai_GetNegativeConditions(oTarget); + // Should we ignore associates? + if(!ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) || + GetAssociateType(oTarget) < 2) + { + if(nNegativeConditions < nTargetNegConds) + { + nNegativeConditions = nTargetNegConds; + nIndex = nCnt; + } + } + oTarget = GetLocalObject(oCreature, AI_ALLY + IntToString(++nCnt)); + } + // No one has a negative condition then get out. + if(!nNegativeConditions) return FALSE; + oTarget = GetLocalObject(oCreature, AI_ALLY + IntToString(nIndex)); + } + else + { + nNegativeConditions = ai_GetNegativeConditions(oTarget); + if(!nNegativeConditions) return FALSE; + } + if(oTarget == oCreature) + { + if(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF)) return FALSE; + } + else if(ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "489", "nNegativeConditions: " + IntToString(nNegativeConditions) + + " on " + GetName(oTarget)); + if(ai_CheckTalentsVsConditions(oCreature, nNegativeConditions, nInMelee, 9, oTarget)) return TRUE; + return FALSE; +} +// ***************************************************************************** +// ************************* Try * Defensive Talents *************************** +// ***************************************************************************** +// These functions try to find and use a specific set of talents intelligently. + +int ai_TryDefensiveTalents(object oCreature, int nInMelee, int nMaxLevel, int nRound = 0, object oTarget = OBJECT_INVALID) +{ + // Summons are powerfull and should be used as much as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_SUMMON, nInMelee, nMaxLevel, oTarget)) return TRUE; + // Added to reduce casting defensive talents later in combat and constantly. + if(nRound >= d8()) return FALSE; + // Try to mix them up so we don't always cast spells in the same order. + int nRoll = d2(); + if(AI_DEBUG) ai_Debug("0i_talents", "507", "Lets help someone(Check Talents: " +IntToString(nRoll) + + " nMaxLevel: " + IntToString(nMaxLevel) + ")!"); + if(nRoll == 1) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_ENHANCEMENT, nInMelee, nMaxLevel, oTarget)) return TRUE; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_PROTECTION, nInMelee, nMaxLevel, oTarget)) return TRUE; + } + else if(nRoll == 2) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_PROTECTION, nInMelee, nMaxLevel, oTarget)) return TRUE; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_ENHANCEMENT, nInMelee, nMaxLevel, oTarget)) return TRUE; + } + return FALSE; +} +void ai_SetAura(object oCreature) +{ + // Cycle through a creatures special abilities and use any auras. + int bCanUse, nIndex = 0, nMaxSpAbility = GetSpellAbilityCount(oCreature); + int nSpell = GetSpellAbilitySpell(oCreature, nIndex); + while(nIndex < nMaxSpAbility) + { + bCanUse = FALSE; + if(GetSpellAbilityReady(oCreature, nIndex)) + { + if(nSpell == SPELLABILITY_AURA_BLINDING) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_COLD) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_ELECTRICITY) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_FEAR) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_FIRE) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_HORRIFICAPPEARANCE) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_MENACE) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_HORRIFICAPPEARANCE) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_PROTECTION) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_STUN) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_UNEARTHLY_VISAGE) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_UNNATURAL) bCanUse = TRUE; + else if(nSpell == SPELLABILITY_AURA_HORRIFICAPPEARANCE) bCanUse = TRUE; + else if(nSpell == 306 /*SPELLABILITY_AURA_TYRANT_FOG_MIST*/) bCanUse = TRUE; + else if(nSpell == 412 /*SPELLABILITY_AURA_DRAGON_FEAR*/) bCanUse = TRUE; + else if(nSpell == 761 /*SPELLABILITY_AURA_HELLFIRE*/) bCanUse = TRUE; + else if(nSpell == 805/*SPELLABILITY_AURA_TROGLODYTE_STENCH*/) bCanUse = TRUE; + } + if(bCanUse) ActionCastSpellAtObject(nSpell, oCreature, 255, FALSE, 0, 0, TRUE); + nSpell = GetSpellAbilitySpell(oCreature, ++nIndex); + } +} +// ***************************************************************************** +// ************************* Try * Skills ************************************** +// ***************************************************************************** +// These functions try to find and use a specific set of skills intelligently. + +void ai_UseSkill(object oCreature, int nSkill, object oTarget) +{ + ai_SetLastAction(oCreature, AI_LAST_ACTION_USED_SKILL); + if(GetIsEnemy(oTarget, oCreature)) SetLocalObject(oCreature, AI_ATTACKED_PHYSICAL, oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "498", GetName(oCreature) + " is using skill: " + + GetStringByStrRef(StringToInt(Get2DAString("skills", "Name", nSkill))) + + " on " + GetName(oTarget)); + ActionUseSkill(nSkill, oTarget); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); +} +int ai_TryParry(object oCreature) +{ + // Only use parry on an active melee attacker + object oTarget = GetLastHostileActor(oCreature); + // If we are already in parry mode then lets keep it up. + if(GetActionMode(oCreature, ACTION_MODE_PARRY) && + GetCurrentAction(oCreature) == ACTION_ATTACKOBJECT) return TRUE; + if(oTarget == OBJECT_INVALID || + ai_GetAttackedTarget(oTarget) != oCreature || + !ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget))) return FALSE; + // Only if our parry skill > their attack bonus + 5 + d10 + // Parry has a -4 atk adjustment. Our chance to hit should be 75% + d10. + // EnemyAtk(20) - OurParrySkill(10) = 0 + d10(75% to 25% chance to hit). + int nParrySkill = GetSkillRank(SKILL_PARRY, oCreature); + int nAtk = ai_GetCreatureAttackBonus(oTarget); + if(nAtk - nParrySkill >= 0 + d10()) return FALSE; + ai_EquipBestMeleeWeapon(oCreature, oTarget); + SetActionMode(oCreature, ACTION_MODE_PARRY, TRUE); + ai_SetLastAction(oCreature, AI_LAST_ACTION_USED_SKILL); + ActionAttack(oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "524", "Using parry against " + GetName(oTarget) + "!"); + return TRUE; +} +int ai_TryTaunt(object oCreature, object oTarget) +{ + int nCoolDown = GetLocalInt(oCreature, "AI_TAUNT_COOLDOWN"); + if(AI_DEBUG) ai_Debug("0i_talents", "530", "Has Taunt Effect? " + + IntToString(ai_GetHasEffectType(oTarget, EFFECT_TYPE_TAUNT)) + + " Cooldown: " + IntToString(nCoolDown)); + if(nCoolDown > 0) + { + SetLocalInt(oCreature, "AI_TAUNT_COOLDOWN", --nCoolDown); + return FALSE; + } + if(!ai_GetHasEffectType(oTarget, EFFECT_TYPE_TAUNT)) return FALSE; + // Check to see if we have a good chance for it to work. + int nTauntRnk = GetSkillRank(SKILL_TAUNT, oCreature); + if(AI_DEBUG) ai_Debug("0i_talents", "542", "Check Taunt: TauntRnk: " + IntToString(nTauntRnk) + + " HitDice + 1: " + IntToString(GetHitDice(oCreature) + 1) + + " Concentration: " + IntToString(GetSkillRank(SKILL_CONCENTRATION, oTarget)) + "."); + int nConcentration = GetSkillRank(SKILL_CONCENTRATION, oTarget); + // Our chance is greater than 50%. + if(nTauntRnk <= nConcentration) return FALSE; + ai_UseSkill(oCreature, SKILL_TAUNT, oTarget); + SetLocalInt(oCreature, "AI_TAUNT_COOLDOWN", AI_TAUNT_COOLDOWN); + return TRUE; +} +int ai_TryAnimalEmpathy(object oCreature, object oTarget = OBJECT_INVALID) +{ + if(!GetSkillRank(SKILL_ANIMAL_EMPATHY, oCreature)) return FALSE; + int nCoolDown = GetLocalInt(oCreature, "AI_EMPATHY_COOLDOWN"); + if(AI_DEBUG) ai_Debug("0i_talents", "556", "Has Dominate Effect? " + + IntToString(ai_GetHasEffectType(oTarget, EFFECT_TYPE_DOMINATED)) + + " Cooldown: " + IntToString(nCoolDown)); + if(nCoolDown > 0) + { + SetLocalInt(oCreature, "AI_EMPATHY_COOLDOWN", --nCoolDown); + return FALSE; + } + if(oTarget == OBJECT_INVALID) + { + oTarget = ai_GetNearestRacialTarget(oCreature, AI_RACIAL_TYPE_ANIMAL_BEAST); + if(oTarget == OBJECT_INVALID) return FALSE; + } + if(!GetObjectSeen(oCreature, oTarget)) return FALSE; + if(ai_GetHasEffectType(oTarget, EFFECT_TYPE_DOMINATED) || + GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS) || + GetIsImmune(oTarget, IMMUNITY_TYPE_DOMINATE) || + GetAssociateType(oTarget) != ASSOCIATE_TYPE_NONE) return FALSE; + // Get the race of the target, it only works on Animals, Beasts, and Magical Beasts. + int nRace = GetRacialType(oTarget); + int nDC; + if(nRace == RACIAL_TYPE_ANIMAL) nDC = 5; + else if(nRace == RACIAL_TYPE_BEAST || nRace == RACIAL_TYPE_MAGICAL_BEAST) nDC = 9; + else return FALSE; + // Check to see if we have a good chance for it to work. + int nEmpathyRnk = GetSkillRank(SKILL_ANIMAL_EMPATHY, oCreature); + nDC += GetHitDice(oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "632", "Check Animal Empathy: Rnk: " + IntToString(nEmpathyRnk) + + " nDC: " + IntToString(nDC) + "."); + // Our chance is greater than 50%. + if(nEmpathyRnk <= nDC) return FALSE; + ai_UseSkill(oCreature, SKILL_ANIMAL_EMPATHY, oTarget); + SetLocalInt(oCreature, "AI_EMPATHY_COOLDOWN", AI_EMPATHY_COOLDOWN); + return TRUE; +} +// ***************************************************************************** +// ************************* Try * Feats *************************************** +// ***************************************************************************** +// These functions try to find and use a specific set of feats intelligently. + +void ai_UseFeat(object oCreature, int nFeat, object oTarget, int nSubFeat = 0) +{ + ai_SetLastAction(oCreature, AI_LAST_ACTION_USED_FEAT); + if(GetIsEnemy(oTarget, oCreature)) SetLocalObject(oCreature, AI_ATTACKED_PHYSICAL, oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "600", GetName(oCreature) + " is using feat: " + + GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat))) + + " on " + GetName(oTarget)); + ActionUseFeat(nFeat, oTarget, nSubFeat); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); +} +void ai_UseFeatAttackMode(object oCreature, int nActionMode, int nAction, object oTarget, int nInMelee = 0, int bPassive = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "608", "Action mode (" + IntToString(nActionMode) + ") Is it set?: " + + IntToString(GetActionMode(oCreature, nActionMode))); + if(!GetActionMode(oCreature, nActionMode)) + { + if(AI_DEBUG) ai_Debug("0i_talents", "612", "Setting action mode: " + IntToString(nActionMode)); + SetActionMode(oCreature, nActionMode, TRUE); + SetLocalInt(oCreature, AI_CURRENT_ACTION_MODE, nActionMode); + } + ai_ActionAttack(oCreature, nAction, oTarget, nInMelee, bPassive, nActionMode); +} +int ai_TryBarbarianRageFeat(object oCreature) +{ + // Must not have rage already, must have the feat, and enemy must be strong enough. + if(GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) || + !GetHasFeat(FEAT_BARBARIAN_RAGE, oCreature)) return FALSE; + ai_UseFeat(oCreature, FEAT_BARBARIAN_RAGE, oCreature); + return TRUE; +} +int ai_TryBardSongFeat(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "629", "BardSong Effect: " + IntToString(GetHasSpellEffect(411/*SPELL_BARD_SONG*/)) + + " Level: " + IntToString(GetLevelByClass(CLASS_TYPE_BARD)) + + " HasFeat: " + IntToString(GetHasFeat(FEAT_BARD_SONGS))); + if(GetHasSpellEffect(411/*SPELL_BARD_SONG*/, oCreature) || + !GetHasFeat(FEAT_BARD_SONGS, oCreature)) return FALSE; + ai_UseFeat(oCreature, FEAT_BARD_SONGS, oCreature); + return TRUE; +} +int ai_TryCalledShotFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_CALLED_SHOT, oCreature)) return FALSE; + // Called shot has a -4 to hit adjustment. + if(!ai_AttackPenaltyOk(oCreature, oTarget, -4.0)) return FALSE; + ai_UseFeat(oCreature, FEAT_CALLED_SHOT, oTarget); + return TRUE; +} +int ai_TryDisarmFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_DISARM, oCreature)) return FALSE; + // If we can't disarm them then get out! + if(!GetIsCreatureDisarmable(oTarget)) return FALSE; + int nEAC = GetAC(oTarget); + int nOAtk = ai_GetCreatureAttackBonus(oCreature); + // The combatant with the larger weapon gains +4 per size category. + // Weapon Size in the baseitems.2da is 1 = Tiny, 2 = Small, 3 = Medium, 4 = Large. + int nOWeaponType = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND)); + int nOWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nOWeaponType)); + int nEWeaponType = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget)); + int nEWeaponSize = StringToInt(Get2DAString("baseitems", "WeaponSize", nEWeaponType)); + nOAtk +=(nOWeaponSize - nEWeaponSize) * 4; + // Do they have Improved Disarm? + if(GetHasFeat(FEAT_IMPROVED_DISARM, oCreature)) nOAtk += 2; + // Disarm has a -6 atk adjustment. + if(!ai_AttackPenaltyOk(oCreature, oTarget, -6.0)) return FALSE; + ai_UseFeat(oCreature, FEAT_DISARM, oTarget); + return TRUE; +} +int ai_TryDivineMightFeat(object oCreature, int nInMelee) +{ + if(!GetHasFeat(FEAT_TURN_UNDEAD)) return FALSE; + if(!GetHasFeat(FEAT_DIVINE_MIGHT)) return FALSE; + if(GetHasFeatEffect(FEAT_DIVINE_MIGHT, oCreature)) return FALSE; + if(!nInMelee) return FALSE; + object oTarget = ai_GetEnemyAttackingMe(oCreature); + if(oTarget == OBJECT_INVALID) return FALSE; + float fAtkAdj = IntToFloat(GetAbilityModifier(ABILITY_CHARISMA, oCreature)); + if(!ai_AttackBonusGood(oCreature, oTarget, fAtkAdj)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "722", "USING DIVINE MIGHT on " + GetName(oCreature) + "."); + ai_UseFeat(oCreature, FEAT_DIVINE_MIGHT, oCreature); + return TRUE; +} +int ai_TryDivineShieldFeat(object oCreature, int nInMelee) +{ + if(!GetHasFeat(FEAT_TURN_UNDEAD)) return FALSE; + if(!GetHasFeat(FEAT_DIVINE_SHIELD)) return FALSE; + if(GetHasFeatEffect(FEAT_DIVINE_SHIELD, oCreature)) return FALSE; + if(!nInMelee) return FALSE; + object oTarget = ai_GetEnemyAttackingMe(oCreature); + if(oTarget == OBJECT_INVALID) return FALSE; + float fACAdj = IntToFloat(GetAbilityModifier(ABILITY_CHARISMA, oCreature)); + if(!ai_ACAdjustmentGood(oCreature, oTarget, fACAdj)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "736", "USING DIVINE SHIELD on " + GetName(oCreature) + "."); + ai_UseFeat(oCreature, FEAT_DIVINE_SHIELD, oCreature); + return TRUE; +} +int ai_TryExpertiseFeat(object oCreature) +{ + if(!GetHasFeat(FEAT_EXPERTISE, oCreature)) return FALSE; + object oTarget = ai_GetEnemyAttackingMe(oCreature); + // Expertise has a -5 atk and a +5 AC adjustment. + if(oTarget == OBJECT_INVALID || + !ai_AttackPenaltyOk(oCreature, oTarget, -5.0) || + !ai_ACAdjustmentGood(oCreature, oTarget, 5.0)) + { + SetActionMode(oCreature, ACTION_MODE_EXPERTISE, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "704", "USING EXPERTISE on " + GetName(oTarget) + "."); + ai_UseFeatAttackMode(oCreature, ACTION_MODE_EXPERTISE, AI_LAST_ACTION_MELEE_ATK, oTarget); + return TRUE; +} +int ai_TryFlurryOfBlowsFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_FLURRY_OF_BLOWS, oCreature)) return FALSE; + // Flurry of Blows has a -2 atk adjustment. + if(!ai_AttackPenaltyOk(oCreature, oTarget, -2.0)) + { + SetActionMode(oCreature, ACTION_MODE_FLURRY_OF_BLOWS, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "718", "USING FLURRY OF BLOWS on " + GetName(oTarget) + "."); + ai_UseFeatAttackMode(oCreature, ACTION_MODE_FLURRY_OF_BLOWS, AI_LAST_ACTION_MELEE_ATK, oTarget, TRUE); + return TRUE; +} +int ai_TryImprovedExpertiseFeat(object oCreature) +{ + if(!GetHasFeat(FEAT_IMPROVED_EXPERTISE, oCreature)) return FALSE; + object oTarget = ai_GetEnemyAttackingMe(oCreature); + // Improved expertise has a -10 atk +10 AC adjustment. + if(oTarget == OBJECT_INVALID || + !ai_AttackPenaltyOk(oCreature, oTarget, -10.0) || + !ai_ACAdjustmentGood(oCreature, oTarget, 10.0)) + { + SetActionMode(oCreature, ACTION_MODE_IMPROVED_EXPERTISE, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "735", "USING IMPROVED EXPERTISE on " + GetName(oTarget) + "."); + ai_UseFeatAttackMode(oCreature, ACTION_MODE_IMPROVED_EXPERTISE, AI_LAST_ACTION_MELEE_ATK, oTarget); + return TRUE; +} +int ai_TryImprovedPowerAttackFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_IMPROVED_POWER_ATTACK, oCreature)) return FALSE; + // Improved Power Attack has a -10 atk adjustment. + // If we cannot hit or will kill in one hit then maybe we should use Power Attack instead. + if(ai_PowerAttackGood(oCreature, oTarget, 10.0)) + { + ai_UseFeatAttackMode(oCreature, ACTION_MODE_IMPROVED_POWER_ATTACK, AI_LAST_ACTION_MELEE_ATK, oTarget); + return TRUE; + } + SetActionMode(oCreature, ACTION_MODE_IMPROVED_POWER_ATTACK, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return ai_TryPowerAttackFeat(oCreature, oTarget); +} +int ai_TryKiDamageFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_KI_DAMAGE, oCreature)) return FALSE; + // Must have > 40 hitpoints AND + // Damage reduction OR damage resistance + // or just have over 200 hitpoints + int bHasDamageReduction = FALSE; + int bHasDamageResistance = FALSE; + int bHasHitpoints = FALSE; + int bHasMassiveHitpoints = FALSE; + int bOutNumbered; + int nCurrentHP = GetCurrentHitPoints(oTarget); + if(nCurrentHP > 40) bHasHitpoints = TRUE; + if(nCurrentHP > 200) bHasMassiveHitpoints = TRUE; + if(ai_GetHasEffectType(oTarget, EFFECT_TYPE_DAMAGE_REDUCTION)) bHasDamageReduction = TRUE; + if(ai_GetHasEffectType(oTarget, EFFECT_TYPE_DAMAGE_RESISTANCE)) bHasDamageResistance = TRUE; + if(ai_GetNearestEnemy(oCreature, 3, 7, 7) != OBJECT_INVALID) bOutNumbered = TRUE; + if((!bHasHitpoints || (!bHasDamageReduction && !bHasDamageResistance)) && + (!bHasMassiveHitpoints) && (!bHasHitpoints || !bOutNumbered)) return FALSE; + ai_UseFeat(oCreature, FEAT_KI_DAMAGE, oTarget); + return TRUE; +} +int ai_TryKnockdownFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_KNOCKDOWN, oCreature)) return FALSE; + int nMySize = GetCreatureSize(oCreature); + if(GetHasFeat(FEAT_IMPROVED_KNOCKDOWN, oCreature)) nMySize++; + // Prevent silly use of knockdown on immune or too-large targets. + // Knockdown has a -4 atk adjustment. + if(GetIsImmune(oTarget, IMMUNITY_TYPE_KNOCKDOWN) || + GetCreatureSize(oTarget) > nMySize + 1 || + !ai_AttackPenaltyOk(oCreature, oTarget, -4.0)) return FALSE; + ai_UseFeat(oCreature, FEAT_KNOCKDOWN, oTarget); + return TRUE; +} +int ai_TryPolymorphSelfFeat(object oCreature) +{ + if(GetHasFeat(FEAT_EPIC_OUTSIDER_SHAPE)) + { + int nSubFeat = Random(3) + 733; // 733 azer, 734 rakshasa, 735 Slaad. + if(ai_UseFeat(oCreature, FEAT_EPIC_OUTSIDER_SHAPE, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_EPIC_CONSTRUCT_SHAPE)) + { + int nSubFeat = Random(3) + 738; // 738 Stone, 739 Flesh, 740 Iron. + if(ai_UseFeat(oCreature, FEAT_EPIC_CONSTRUCT_SHAPE, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_EPIC_WILD_SHAPE_DRAGON)) + { + int nSubFeat = Random(3) + 707; // 707 Red, 708 Blue, 709 Green. + if(ai_UseFeat(oCreature, FEAT_EPIC_WILD_SHAPE_DRAGON, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_EPIC_WILD_SHAPE_UNDEAD)) + { + int nSubFeat = Random(3) + 704; // 704 Risen Lord, 705 Vampire, 706 Spectre. + if(ai_UseFeat(oCreature, FEAT_EPIC_WILD_SHAPE_UNDEAD, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_GREATER_WILDSHAPE_4)) + { + int nSubFeat; + int nRoll = d3(); + if(nRoll == 1) nSubFeat = 679; // Medusa + else if(nRoll == 2) nSubFeat = 691; // Mindflayer + else nSubFeat = 694; // DireTiger + if(ai_UseFeat(oCreature, FEAT_GREATER_WILDSHAPE_4, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_GREATER_WILDSHAPE_3)) + { + int nSubFeat; + int nRoll = d3(); + if(nRoll == 1) nSubFeat = 670; // Basilisk + else if(nRoll == 2) nSubFeat = 673; // Drider + else nSubFeat = 674; // Manticore + if(ai_UseFeat(oCreature, FEAT_GREATER_WILDSHAPE_3, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_GREATER_WILDSHAPE_2)) + { + int nSubFeat; + int nRoll = d3(); + if(nRoll == 1) nSubFeat = 672; // Harpy + else if(nRoll == 2) nSubFeat = 678; // Gargoyle + else nSubFeat = 680; // Minotaur + if(ai_UseFeat(oCreature, FEAT_GREATER_WILDSHAPE_2, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_GREATER_WILDSHAPE_1)) + { + int nSubFeat = Random(5) + 658; // Wyrmling + if(ai_UseFeat(oCreature, FEAT_GREATER_WILDSHAPE_1, oCreature, nSubFeat)) return TRUE; + } + if(GetHasFeat(FEAT_HUMANOID_SHAPE)) + { + int nSubFeat = Random(3) + 682; // 682 Drow, 683 Lizard, 684 Kobold. + if(ai_UseFeat(oCreature, FEAT_HUMANOID_SHAPE, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_ELEMENTAL_SHAPE)) + { + int nSubFeat = Random(4) + SUBFEAT_ELEMENTAL_SHAPE_EARTH; + if(ai_UseFeat(oCreature, FEAT_ELEMENTAL_SHAPE, oCreature, nSubFeat)) return TRUE; + } + else if(GetHasFeat(FEAT_WILD_SHAPE)) + { + int nSubFeat; + int nCompanionType = GetAnimalCompanionCreatureType(oCreature); + if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_NONE) + nSubFeat = Random(5) + SUBFEAT_WILD_SHAPE_BROWN_BEAR; + else + { + if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_BADGER) + nSubFeat = SUBFEAT_WILD_SHAPE_BADGER; + else if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_BOAR) + nSubFeat = SUBFEAT_WILD_SHAPE_BOAR; + else if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_BEAR) + nSubFeat = SUBFEAT_WILD_SHAPE_BROWN_BEAR; + else if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_PANTHER) + nSubFeat = SUBFEAT_WILD_SHAPE_PANTHER; + else if(nCompanionType == ANIMAL_COMPANION_CREATURE_TYPE_WOLF) + nSubFeat = SUBFEAT_WILD_SHAPE_WOLF; + else nSubFeat = Random(5) + SUBFEAT_WILD_SHAPE_BROWN_BEAR; + } + if(AI_DEBUG) ai_Debug("0i_talents", "885", " Using wild shape feat: " + IntToString(nSubFeat)); + ai_UseFeat(oCreature, FEAT_WILD_SHAPE, oCreature, nSubFeat); + return TRUE; + } + return FALSE; +} +int ai_TryPowerAttackFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_POWER_ATTACK, oCreature)) return FALSE; + // Power Attack has a -5 atk adjustment. + if(ai_PowerAttackGood(oCreature, oTarget, 5.0)) + { + ai_UseFeatAttackMode(oCreature, ACTION_MODE_POWER_ATTACK, AI_LAST_ACTION_MELEE_ATK, oTarget); + return TRUE; + } + SetActionMode(oCreature, ACTION_MODE_POWER_ATTACK, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return FALSE; +} +int ai_TryQuiveringPalmFeat(object oCreature, object oTarget) +{ + // Must have the feat, and enemy must be lower level, and not immune to crits. + if(!GetHasFeat(FEAT_QUIVERING_PALM, oCreature) || + GetHitDice(oTarget) >= GetHitDice(oCreature) || + GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) return FALSE; + ai_UseFeat(oCreature, FEAT_QUIVERING_PALM, oTarget); + return TRUE; +} +int ai_TryRapidShotFeat(object oCreature, object oTarget, int nInMelee) +{ + if(!GetHasFeat(FEAT_RAPID_SHOT, oCreature)) return FALSE; + // Rapidshot has a -4 atk adjustment. + if(!ai_AttackPenaltyOk(oCreature, oTarget, -4.0)) + { + SetActionMode(oCreature, ACTION_MODE_RAPID_SHOT, FALSE); + DeleteLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + return FALSE; + } + ai_UseFeatAttackMode(oCreature, ACTION_MODE_RAPID_SHOT, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return TRUE; +} +int ai_TrySapFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_SAP, oCreature)) return FALSE; + // Does not work on creatures that cannot be hit by criticals or stunned. + // Sap has a -4 atk adjustment. + if(GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT) || + GetIsImmune(oTarget, IMMUNITY_TYPE_STUN) || + !ai_AttackPenaltyOk(oCreature, oTarget, -4.0)) return FALSE; + ai_UseFeat(oCreature, FEAT_SAP, oTarget); + return TRUE; +} +int ai_TrySmiteEvilFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_SMITE_EVIL, oCreature) || + GetAlignmentGoodEvil(oTarget) != ALIGNMENT_EVIL || + !ai_StrongOpponent(oCreature, oTarget)) return FALSE; + ai_UseFeat(oCreature, FEAT_SMITE_EVIL, oTarget); + return TRUE; +} +int ai_TrySmiteGoodFeat(object oCreature, object oTarget) +{ + if(!GetHasFeat(FEAT_SMITE_GOOD, oCreature) || + GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD || + !ai_StrongOpponent(oCreature, oTarget)) return FALSE; + ai_UseFeat(oCreature, FEAT_SMITE_GOOD, oTarget); + return TRUE; +} +int ai_TryStunningFistFeat(object oCreature, object oTarget) +{ + // Cannot use if we have a weapon equiped. + if(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCreature) != OBJECT_INVALID) return FALSE; + // Does not work on creatures that cannot be hit by criticals or stunned. + // Stunning Fists has a -4 atk adjustment. + if(!GetHasFeat(FEAT_STUNNING_FIST, oCreature) || + GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT) || + GetIsImmune(oTarget, IMMUNITY_TYPE_STUN) || + !ai_StrongOpponent(oCreature, oTarget) || + !ai_AttackPenaltyOk(oCreature, oTarget, -4.0)) return FALSE; + ai_UseFeat(oCreature, FEAT_STUNNING_FIST, oTarget); + return TRUE; +} +void ai_NameAssociate(object oCreature, int nAssociateType, string sName) +{ + object oAssociate = GetAssociate(nAssociateType, oCreature); + if(GetName(oCreature) != "") return; + SetName(oAssociate, sName); + ChangeFaction(oAssociate, oCreature); +} +int ai_TrySummonAnimalCompanionTalent(object oCreature) +{ + if(!GetHasFeat(FEAT_ANIMAL_COMPANION, oCreature)) return FALSE; + if(GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCreature) != OBJECT_INVALID) return FALSE; + ai_UseFeat(oCreature, FEAT_ANIMAL_COMPANION, oCreature); + DelayCommand(0.0, ai_NameAssociate(oCreature, ASSOCIATE_TYPE_FAMILIAR, "Animal Companion")); + return TRUE; +} +int ai_TrySummonFamiliarTalent(object oCreature) +{ + if(!GetHasFeat(FEAT_SUMMON_FAMILIAR, oCreature)) return FALSE; + if(GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCreature) != OBJECT_INVALID) return FALSE; + ai_UseFeat(oCreature, FEAT_SUMMON_FAMILIAR, oCreature); + DelayCommand(0.0, ai_NameAssociate(oCreature, ASSOCIATE_TYPE_FAMILIAR, "Familiar")); + return TRUE; +} +int ai_TryLayOnHands(object oCreature) +{ + if(!GetHasFeat(FEAT_LAY_ON_HANDS, oCreature)) return FALSE; + // Lets not run past an enemy to use touch atk unless we have the feats, bad tactics! + float fRange; + if(ai_CanIMoveInCombat(oCreature)) fRange = AI_RANGE_PERCEPTION; + else + { + fRange = GetDistanceBetween(oCreature, GetLocalObject(oCreature, AI_ENEMY_NEAREST)) - 3.0f; + // Looks bad when your right next to an ally, but technically the enemy is closer. + if(fRange < AI_RANGE_MELEE) fRange = AI_RANGE_MELEE; + } + object oTarget = ai_GetLowestCRRacialTarget(oCreature, RACIAL_TYPE_UNDEAD, fRange); + if(oTarget == OBJECT_INVALID) return FALSE; + ai_UseFeat(oCreature, FEAT_LAY_ON_HANDS, oTarget); + return TRUE; +} +int ai_TryTurningTalent(object oCreature) +{ + if(!GetHasFeat(FEAT_TURN_UNDEAD, oCreature)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "1043", "Checking for Turning Targets."); + int nHDCount, nHDCount2, nRacial, nHD; + // Get characters levels. + int nClericLevel = GetLevelByClass(CLASS_TYPE_CLERIC, oCreature); + int nPaladinLevel = GetLevelByClass(CLASS_TYPE_PALADIN, oCreature); + int nBlackguardlevel = GetLevelByClass(CLASS_TYPE_BLACKGUARD, oCreature); + int nTotalLevel = GetHitDice(oCreature); + int nTurnLevel = nClericLevel; + int nClassLevel = nClericLevel; + // GZ: Since paladin levels stack when turning, blackguard levels should stack as well + // GZ: but not with the paladin levels (thus else if). + if(nBlackguardlevel - 2 > 0 && nBlackguardlevel > nPaladinLevel) + { + nClassLevel += (nBlackguardlevel - 2); + nTurnLevel += (nBlackguardlevel - 2); + } + else if(nPaladinLevel - 2 > 0) + { + nClassLevel += (nPaladinLevel - 2); + nTurnLevel += (nPaladinLevel - 2); + } + //Flags for bonus turning types + int nElemental = GetHasFeat(FEAT_AIR_DOMAIN_POWER, oCreature) + + GetHasFeat(FEAT_EARTH_DOMAIN_POWER, oCreature) + + GetHasFeat(FEAT_FIRE_DOMAIN_POWER, oCreature) + + GetHasFeat(FEAT_WATER_DOMAIN_POWER, oCreature); + int nVermin = GetHasFeat(FEAT_PLANT_DOMAIN_POWER, oCreature); + int nConstructs = GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER, oCreature); + int nGoodOrEvilDomain = GetHasFeat(FEAT_GOOD_DOMAIN_POWER, oCreature) + + GetHasFeat(FEAT_EVIL_DOMAIN_POWER, oCreature); + int nPlanar = GetHasFeat(854, oCreature); + // Get turning check average, modify if have the Sun Domain + int nChrMod = GetAbilityModifier(ABILITY_CHARISMA, oCreature); + int nTurnCheck = 15 + nChrMod; //The roll to apply to the max HD of undead that can be turned --> nTurnLevel + int nTurnHD = 12 + nChrMod + nClassLevel; //The number of HD of undead that can be turned. + if(GetHasFeat(FEAT_SUN_DOMAIN_POWER, oCreature)) + { + nTurnCheck += 2; + nTurnHD += 3; + } + //Determine the maximum HD of the undead that can be turned using a roll of 15 + ChrMod. + if(nTurnCheck == 15) nTurnLevel += 1; + else if(nTurnCheck >= 16 && nTurnCheck <= 18) nTurnLevel += 2; + else if(nTurnCheck >= 19 && nTurnCheck <= 21) nTurnLevel += 3; + else if(nTurnCheck >= 22) nTurnLevel += 4; + // Collect the number of HitDice we will affect. + int nCnt = 1; + object oEnemy = GetNearestCreature(7, 7, oCreature, nCnt); + while(oEnemy != OBJECT_INVALID && nHDCount < nTurnHD && GetDistanceBetween(oEnemy, oCreature) <= 20.0) + { + if(GetIsEnemy(oEnemy, oCreature) && !ai_Disabled(oEnemy)) + { + nRacial = GetRacialType(oEnemy); + nHD = 0; + if(nRacial == RACIAL_TYPE_UNDEAD) nHD = GetHitDice(oEnemy) + GetTurnResistanceHD(oEnemy); + else if(nRacial == RACIAL_TYPE_OUTSIDER && nGoodOrEvilDomain + nPlanar > 0) + { + //Planar turning decreases spell resistance against turning by 1/2 + if(nPlanar) nHD = GetHitDice(oEnemy) + (GetSpellResistance(oEnemy) / 2); + else nHD = GetHitDice(oEnemy) + GetSpellResistance(oEnemy); + } + else if(nRacial == RACIAL_TYPE_VERMIN && nVermin > 0) nHD = GetHitDice(oEnemy); + else if(nRacial == RACIAL_TYPE_ELEMENTAL && nElemental > 0) nHD = GetHitDice(oEnemy); + else if (nRacial == RACIAL_TYPE_CONSTRUCT && nConstructs > 0) nHD = GetHitDice(oEnemy); + // Only count undead we can defeat! + if(AI_DEBUG) ai_Debug("0i_talents", "1110", " nHD: " + IntToString(nHD) + + " nTurnLevel: " + IntToString(nTurnLevel) + + " nTurnHD: " + IntToString(nTurnHD) + + " nHDCount: " + IntToString(nHDCount)); + if(nHD > 0 && nHD <= nTurnLevel && nHD <= (nTurnHD - nHDCount)) nHDCount += nHD; + } + oEnemy = GetNearestCreature(7, 7, oCreature, ++nCnt); + } + if(AI_DEBUG) ai_Debug("0i_talents", "1089", "Found " + IntToString(nHDCount) + " hitdice to turn from my location."); + // Lets do one more check to see if we can get a better position to use TurnUndead. + nCnt = 1; + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(GetDistanceBetween(oCreature, oNearestEnemy) > AI_RANGE_MELEE) + { + oEnemy = oNearestEnemy; + if(AI_DEBUG) ai_Debug("0i_talents", "1126", GetName(oEnemy)); + while(oEnemy != OBJECT_INVALID && nHDCount2 < nTurnHD && GetDistanceBetween(oEnemy, oNearestEnemy) <= 20.0) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1129", GetName(oEnemy)); + if(GetIsEnemy(oEnemy, oCreature) && !ai_Disabled(oEnemy)) + { + nRacial = GetRacialType(oEnemy); + nHD = 0; + if(nRacial == RACIAL_TYPE_UNDEAD) nHD = GetHitDice(oEnemy) + GetTurnResistanceHD(oEnemy); + else if(nRacial == RACIAL_TYPE_OUTSIDER && nGoodOrEvilDomain + nPlanar > 0) + { + //Planar turning decreases spell resistance against turning by 1/2 + if(nPlanar) nHD = GetHitDice(oEnemy) + (GetSpellResistance(oEnemy) / 2); + else nHD = GetHitDice(oEnemy) + GetSpellResistance(oEnemy); + } + else if(nRacial == RACIAL_TYPE_VERMIN && nVermin > 0) nHD = GetHitDice(oEnemy); + else if(nRacial == RACIAL_TYPE_ELEMENTAL && nElemental > 0) nHD = GetHitDice(oEnemy); + else if (nRacial == RACIAL_TYPE_CONSTRUCT && nConstructs > 0) nHD = GetHitDice(oEnemy); + // Only count undead we can defeat! + if(AI_DEBUG) ai_Debug("0i_talents", "1140", " nHD: " + IntToString(nHD) + + " nTurnLevel: " + IntToString(nTurnLevel) + + " nTurnHD: " + IntToString(nTurnHD) + + " nHDCount2: " + IntToString(nHDCount2)); + if(nHD > 0 && nHD <= nTurnLevel && nHD <= (nTurnHD - nHDCount2)) nHDCount2 += nHD; + } + oEnemy = GetNearestCreature(7, 7, oNearestEnemy, ++nCnt); + } + } + if(AI_DEBUG) ai_Debug("0i_talents", "1148", "Found " + IntToString(nHDCount2) + " hitdice to turn from enemy location."); + if(nHDCount > nHDCount2) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1176", " My Location - nHDCount: " + IntToString(nHDCount) + + " >= nTurnHD / 2: " + IntToString(nTurnHD / 2)); + if(nHDCount < nTurnHD / 2) return FALSE; + ai_UseFeat(oCreature, FEAT_TURN_UNDEAD, oCreature); + return TRUE; + } + else + { + if(AI_DEBUG) ai_Debug("0i_talents", "1184", " Better location - nHDCount2: " + IntToString(nHDCount2) + + " >= nTurnHD / 2: " + IntToString(nTurnHD / 2)); + if(nHDCount2 < nTurnHD / 2) return FALSE; + ActionMoveToObject(oNearestEnemy, TRUE, 1.0f); + ai_UseFeat(oCreature, FEAT_TURN_UNDEAD, oCreature); + return TRUE; + } + return FALSE; +} +int ai_TryWhirlwindFeat(object oCreature) +{ + if(!GetHasFeat(FEAT_WHIRLWIND_ATTACK, oCreature)) return FALSE; + // Only worth using if there are 3+ targets. + if(AI_DEBUG) ai_Debug("0i_talents", "860", "WHIRLWIND : NumOfEnemies: " + IntToString(ai_GetNumOfEnemiesInGroup(oCreature, 3.0)) + "."); + // Shortened distance so its more effective(went from 5.0 to 2.0 and up to 3.0) + if(ai_GetNumOfEnemiesInGroup(oCreature, 3.0) < d3() + 1) return FALSE; + // * DO NOT WHIRLWIND if any of the targets are "large" or bigger + // * it seldom works against such large opponents. + // * Though its okay to use Improved Whirlwind against these targets + if((!GetHasFeat(FEAT_IMPROVED_WHIRLWIND, oCreature)) || + (GetCreatureSize(ai_GetNearestEnemy(oCreature, 1, 7, 7)) >= CREATURE_SIZE_LARGE && + GetCreatureSize(ai_GetNearestEnemy(oCreature, 2, 7, 7)) >= CREATURE_SIZE_LARGE)) + ai_UseFeat(oCreature, FEAT_WHIRLWIND_ATTACK, oCreature); + return TRUE; +} +int ai_TryWholenessOfBodyFeat(object oCreature) +{ + if(!GetHasFeat(FEAT_WHOLENESS_OF_BODY, oCreature)) return FALSE; + // Get when we are suppose to heal base off conversation with PC or + // on spawn generation. + int nHp = ai_GetPercHPLoss(oCreature); + if(nHp >= AI_HEALTH_WOUNDED) return FALSE; + ai_UseFeat(oCreature, FEAT_WHOLENESS_OF_BODY, oCreature); + return TRUE; +} +// ***************************************************************************** +// ******************** Try Physical Attack Talents **************************** +// ***************************************************************************** +// These functions try to find and use physical attack talents intelligently. + +void ai_ActionAttack(object oCreature, int nAction, object oTarget, int nInMelee = 0, int bPassive = FALSE, int nActionMode = 0) +{ + // If we are doing a ranged attack then check our position on the battlefield. + if(nAction == AI_LAST_ACTION_RANGED_ATK && ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nAction)) return; + ai_SetLastAction(oCreature, nAction); + SetLocalObject(oCreature, AI_ATTACKED_PHYSICAL, oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "894", GetName(oCreature) + " is attacking(" + IntToString(nAction) + + ") " + GetName(oTarget) + " Current Action: " + IntToString(GetCurrentAction(oCreature)) + + " Lastround Attacked Target: " + GetName(ai_GetAttackedTarget(oCreature)) + + " bPassive: " + IntToString(bPassive) + " nActionMode: " + IntToString(nActionMode)); + ActionAttack(oTarget, bPassive); + if(nActionMode == 0) ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); +} +void ai_FlyToAttacks(object oCreature, object oTarget) +{ + ai_TryWingAttacks(oCreature); + // If we don't do a Tail sweep attack then see if we can do a Tail slap! + if(!ai_TryTailSweepAttack(oCreature)) ai_TryTailSlap(oCreature); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); +} +void ai_FlyToTarget(object oCreature, object oTarget) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "908", GetName(OBJECT_SELF) + " is flying to " + GetName(oTarget) + "!"); + effect eFly = EffectDisappearAppear(GetLocation(oTarget)); + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFly, oCreature, 3.0f); + DelayCommand(4.0f, ai_FlyToAttacks(oCreature, oTarget)); + // Used to make creature wait before starting its next round. + SetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS, 5); +} +int ai_TryDragonBreathAttack(object oCreature, int nRound, object oTarget = OBJECT_INVALID) +{ + int nCnt = GetLocalInt(oCreature, "AI_DRAGONS_BREATH"); + if(AI_DEBUG) ai_Debug("0i_talents", "918", "Try Dragon Breath Attack: nRound(" + IntToString(nRound) + ")" + + " <= nCnt(" + IntToString(nCnt) + ")!"); + if(nRound <= nCnt) return FALSE; + talent tUse = GetCreatureTalentBest(TALENT_CATEGORY_DRAGONS_BREATH, 20, oCreature); + if(!GetIsTalentValid(tUse)) return FALSE; + if(oTarget == OBJECT_INVALID) + { + string sIndex = IntToString(ai_GetHighestMeleeIndexNotInAOE(oCreature)); + oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + if(oTarget == OBJECT_INVALID) return FALSE; + } + SetLocalInt(oCreature, "AI_DRAGONS_BREATH", d4() + nRound); + ActionCastSpellAtObject(GetIdFromTalent(tUse), oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "1019", GetName(oCreature) + " breaths on " + GetName(oTarget) + "!"); + return TRUE; +} +void ai_DragonMeleeAttack(object oCreature, object oTarget, string sDmgDice, string sText) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "941", "oAttacker: " + GetName(oCreature) + + " oTarget: " + GetName(oTarget)); + int nDmg, nCheck, nAB = ai_GetCreatureAttackBonus(oCreature) - 5; + int nAC = GetAC(oTarget); + int nRoll = d20(); + string sHit; + // nCheck is a hit if nCheck > -1 and a miss if < 0; + if(nRoll == 20) nCheck = 20; + // We add one to the check so a equal result is still a hit. + else if(nRoll > 1) nCheck = nRoll + nAB - nAC + 1; + else nCheck == 0; + if(nCheck > 0) + { + nDmg = ai_RollDiceString(sDmgDice); + if(nCheck == 20) nDmg = nDmg * 2; + } + if(nCheck > 0) sHit = "*hit*"; + else sHit = "*miss*"; + string sMessage = ai_AddColorToText(GetName(oCreature) + "'s", AI_COLOR_LIGHT_MAGENTA) + + ai_AddColorToText(sText + "attacks " + GetName(oTarget) + " : " + sHit + " :(" + + IntToString(nRoll) + " + " + IntToString(nAB) + + " = " + IntToString(nRoll + nAB) + ")", AI_COLOR_DARK_ORANGE); + if(ai_GetIsCharacter(oTarget)) SendMessageToPC(oCreature, sMessage); + if(ai_GetIsCharacter(oTarget)) SendMessageToPC(oTarget, sMessage); + if(AI_DEBUG) ai_Debug("0i_talents", "965", "nAB: " + IntToString(nAB) + + " nAC: " + IntToString(nAC) + " nRoll: " + IntToString(nRoll) + + " nCheck: " + IntToString(nCheck) + " nDmg: " + IntToString(nDmg)); + if(nCheck <= 0) return; + // Apply any damage to the target! + effect eDmg = EffectDamage(nDmg, DAMAGE_TYPE_BLUDGEONING); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); +} +// Checks to see if a dragon can use its wings on a nearby enemy. +// Checks the right side and then the left side to see if it can attack. +int ai_TryWingAttacks(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "977", GetName(oCreature) + " is checking for wing Attacks!"); + // Only Medium size dragons can use thier wings in combat. + // We use HitDice to base size S:1-5, M:6-11, L:12-17, H:18-29, G:30-39, C:40+. + int nHitDice = GetHitDice(oCreature); + if(nHitDice <= 5) return FALSE; + int nDragonSize; + string sDmgDice, sMessage; + float fSize; + // Get the stats based on the size of the dragon. + if(nHitDice < 12) { fSize = 5.0f; nDragonSize = 3; sDmgDice = "1d4"; } // Medium + else if(nHitDice < 18) { fSize = 10.0f; nDragonSize = 4; sDmgDice = "1d6"; } // Large + else if(nHitDice < 30) { fSize = 10.0f; nDragonSize = 5; sDmgDice = "1d8"; } // Huge + else if(nHitDice < 40) { fSize = 15.0f; nDragonSize = 6; sDmgDice = "2d6"; } // Gargantuan + else { fSize = 15.0f; nDragonSize = 7; sDmgDice = "2d8"; } // Colossal + // Add half the dragons strength modifier. + int nDmg = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(nDmg > 0) sDmgDice = sDmgDice + "+" + IntToString(nDmg / 2); + if(AI_DEBUG) ai_Debug("0i_talents", "994", "nHitDice: " + IntToString(nHitDice) + + " nDragonSize: " + IntToString(nDragonSize) + + " sDmgDice: " + sDmgDice + " nDmg: " + IntToString(nDmg)); + // Get the closest enemy to our right wing. + location lWing = GetFlankingRightLocation(oCreature); + object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fSize, lWing); + while(oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1002", "oTarget: " + GetName(oTarget)); + if(GetIsEnemy(oTarget, oCreature) && !GetIsDead(oTarget)) break; + oTarget = GetNextObjectInShape(SHAPE_SPHERE, fSize, lWing); + } + if(oTarget != OBJECT_INVALID) ai_DragonMeleeAttack(oCreature, oTarget, sDmgDice, " right wing "); + // Get the closest enemy to our left wing. + lWing = GetFlankingLeftLocation(oCreature); + oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fSize, lWing); + while(oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1012", "oTarget: " + GetName(oTarget)); + if(GetIsEnemy(oTarget, oCreature) && !GetIsDead(oTarget)) break; + oTarget = GetNextObjectInShape(SHAPE_SPHERE, fSize, lWing); + } + if(oTarget != OBJECT_INVALID) ai_DragonMeleeAttack(oCreature, oTarget, sDmgDice, " left wing "); + return TRUE; +} +// Looks behind the dragon to see if it can use it's tail slap on an enemy. +int ai_TryTailSlap(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1022", GetName(OBJECT_SELF) + " is checking for tail slap Attack!"); + // Only Large size dragons can use thier tail in combat. + // We use HitDice to base size S:1-5, M:6-11, L:12-17, H:18-29, G:30-39, C:40+. + int nHitDice = GetHitDice(oCreature); + if(nHitDice <= 11) return FALSE; + int nDragonSize; + string sDmgDice, sMessage; + float fSize; + // Get the stats based on the size of the dragon. + if(nHitDice < 12) { fSize = 5.0f; nDragonSize = 3; sDmgDice = "1d4"; } // Medium + else if(nHitDice < 18) { fSize = 10.0f; nDragonSize = 4; sDmgDice = "1d6"; } // Large + else if(nHitDice < 30) { fSize = 10.0f; nDragonSize = 5; sDmgDice = "1d8"; } // Huge + else if(nHitDice < 40) { fSize = 15.0f; nDragonSize = 6; sDmgDice = "2d6"; } // Gargantuan + else { fSize = 15.0f; nDragonSize = 7; sDmgDice = "2d8"; } // Colossal + // Add one and a half the dragons strength modifier. + int nDmg = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(nDmg > 0) sDmgDice = sDmgDice + "+" + IntToString(nDmg + nDmg / 2); + if(AI_DEBUG) ai_Debug("0i_talents", "1039", "nHitDice: " + IntToString(nHitDice) + + " nDragonSize: " + IntToString(nDragonSize) + + " sDmgDice: " + sDmgDice + " nDmg: " + IntToString(nDmg)); + // Get the closest enemy to our tail. + location lTail = GetBehindLocation(oCreature); + object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fSize, lTail); + while(oTarget != OBJECT_INVALID) + { + if(GetIsEnemy(oTarget, oCreature) && !GetIsDead(oTarget)) break; + oTarget = GetNextObjectInShape(SHAPE_SPHERE, fSize, lTail); + } + if(oTarget != OBJECT_INVALID) ai_DragonMeleeAttack(oCreature, oTarget, sDmgDice, " tail ");\ + return TRUE; +} +void ai_CrushEffect(object oCreature, object oBaseTarget, int nHitDice) +{ + int nDragonSize, nAtkValue, nDC = ai_GetDragonDC(oCreature); + string sDmgDice, sMessage; + location lImpact = GetLocation(oBaseTarget); + float fSize; + // Get the stats based on the size of the dragon. + if(nHitDice < 30) { fSize = 15.0f; nDragonSize = 5; sDmgDice = "2d8"; } // Huge + else if(nHitDice < 40) { fSize = 25.0f; nDragonSize = 6; sDmgDice = "4d6"; } // Gargantuan + else { fSize = 45.0f; nDragonSize = 7; sDmgDice = "4d8"; } // Colossal + // Add the dragons strength modifier 1.5 times. + int nDmgBonus = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(nDmgBonus > 0) sDmgDice = sDmgDice + "+" + IntToString(nDmgBonus + nDmgBonus / 2); + // Dragon flies up and then crushes the area below it. + effect eDmg, eKnockDown = EffectKnockdown(); + effect eImpact = EffectVisualEffect(VFX_FNF_SCREEN_SHAKE); + object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fSize, lImpact); + while(oTarget != OBJECT_INVALID) + { + if(ai_GetIsCharacter(oTarget)) DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpact, oTarget)); + // If they have evasion they automatically dodge the crush attack. + if(!GetHasFeat(FEAT_EVASION, oTarget) && oTarget != oCreature) + { + if(!ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_NONE, oCreature)) + { + eDmg =EffectDamage(ai_RollDiceString(sDmgDice), DAMAGE_TYPE_BLUDGEONING); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); + sMessage = ai_AddColorToText(GetName(oCreature), AI_COLOR_LIGHT_MAGENTA) + + ai_AddColorToText(" crushes " + GetName(oTarget) + ".", AI_COLOR_DARK_ORANGE); + if(ai_GetIsCharacter(oTarget)) SendMessageToPC(oTarget, sMessage); + // Must be 3 sizes smaller to be affected by extra damage and knockdown. + if(nDragonSize - 2 < GetCreatureSize(oTarget)) + { + if(!GetIsImmune(oTarget, IMMUNITY_TYPE_KNOCKDOWN)) + { + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockDown, oTarget, 6.0f); + } + } + } + } + else + { + if(ai_GetIsCharacter(oTarget)) + { + sMessage = ai_AddColorToText(GetName(oTarget), AI_COLOR_LIGHT_MAGENTA) + + ai_AddColorToText(" dodges the crush attack from " + GetName(oTarget) + ".", AI_COLOR_DARK_ORANGE); + if(ai_GetIsCharacter(oTarget)) SendMessageToPC(oTarget, sMessage); + } + } + oTarget = GetNextObjectInShape(SHAPE_SPHERE, fSize, lImpact); + } + // Now do normal attacks! + ai_FlyToAttacks(oCreature, oBaseTarget); +} +int ai_TryCrushAttack(object oCreature, object oTarget) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1110", GetName(OBJECT_SELF) + " is checking for crush Attack!"); + // Only Huge size dragons can use crush attack. + // We use HitDice to base size S:1-5, M:6-11, L:12-17, H:18-29, G:30-39, C:40+. + int nHitDice = GetHitDice(oCreature); + if(nHitDice <= 17) return FALSE; + int nCrush = GetLocalInt(oCreature, "0_DRAGON_CRUSH") - 1; + if(nCrush > 0) + { + SetLocalInt(oCreature, "0_DRAGON_CRUSH", nCrush); + return FALSE; + } + effect eFly = EffectDisappearAppear(GetLocation(oTarget)); + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFly, oCreature, 3.0f); + DelayCommand(4.0f, ai_CrushEffect(oCreature, oTarget, nHitDice)); + // Used to make creature wait before starting its next round. + SetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS, 5); + // We only crush every 3 rounds if we can. + SetLocalInt(oCreature, "0_DRAGON_CRUSH", 3); + return TRUE; +} +int ai_TryTailSweepAttack(object oCreature) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1132", GetName(oCreature) + " is checking for tail sweep Attack!"); + // Only Gargantuan size dragons can use tail sweep attack. + // We use HitDice to base size S:1-5, M:6-11, L:12-17, H:18-29, G:30-40, C:40+. + int nHitDice = GetHitDice(oCreature); + if(nHitDice <= 29) return FALSE; + int nSweep = GetLocalInt(oCreature, "0_DRAGON_SWEEP") - 1; + if(nSweep > 0) + { + SetLocalInt(oCreature, "0_DRAGON_SWEEP", nSweep); + return FALSE; + } + int nDragonSize, nAtkValue, nDC = ai_GetDragonDC(oCreature); + string sDmgDice, sMessage; + float fSize; + // Get the stats based on the size of the dragon. + if(nHitDice < 33) { fSize = 15.0f; nDragonSize = 6; sDmgDice = "2d6"; } // Gargantuan + else { fSize = 40.0f; nDragonSize = 7; sDmgDice = "2d8"; } // Colossal + location lImpact = GetBehindLocation(oCreature); + // We always sweep if we have the opportunity. + // Add the dragons strength modifier 1.5 times. + int nDmgBonus = GetAbilityModifier(ABILITY_STRENGTH, oCreature); + if(nDmgBonus > 0) sDmgDice = sDmgDice + "+" + IntToString(nDmgBonus + nDmgBonus / 2); + // Sweeps any creatures behind them. + effect eDmg; + effect eKnockDown = EffectKnockdown(); + object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fSize, lImpact); + while(oTarget != OBJECT_INVALID) + { + sMessage = ai_AddColorToText(GetName(oCreature), AI_COLOR_LIGHT_MAGENTA) + + ai_AddColorToText(" sweeps " + GetName(oTarget) + ".", AI_COLOR_ORANGE); + if(ai_GetIsCharacter(oTarget)) SendMessageToPC(oTarget, sMessage); + // If they have evasion they automatically dodge the sweep attack. + if(!GetHasFeat(FEAT_EVASION, oTarget) && oTarget != oCreature) + { + if(!ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_NONE, oCreature)) + { + eDmg = EffectDamage(ai_RollDiceString(sDmgDice), DAMAGE_TYPE_BLUDGEONING); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); + // Must be 4 sizes smaller to be affected by extra damage and knockdown. + if(nDragonSize - 3 < GetCreatureSize(oTarget)) + { + if(!GetIsImmune(oTarget, IMMUNITY_TYPE_KNOCKDOWN)) + { + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockDown, oTarget, 12.0f); + } + } + } + } + oTarget = GetNextObjectInShape(SHAPE_SPHERE, fSize, lImpact); + } + // We only sweep every 3 rounds if we can. + SetLocalInt(oCreature, "0_DRAGON_SWEEP", 3); + return TRUE; +} +int ai_TrySneakAttack(object oCreature, int nInMelee, int bAlwaysAtk = TRUE) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1188", GetName(OBJECT_SELF) + " is checking for melee Sneak Attack!"); + if(!GetHasFeat(FEAT_SNEAK_ATTACK, oCreature)) return FALSE; + // Lets get the nearest target that is attacking someone besides me. + object oTarget = OBJECT_INVALID; + oTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + string sIndex; + // Check if we have Mobility, Spring Attack or a good tumble. + // if we do then look for other targets besides who we are in melee with. + if(!nInMelee) sIndex = IntToString(ai_GetBestSneakAttackIndex(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk)); + // If there are few enemies then we can safely move around. + else if(nInMelee < 3 || ai_CanIMoveInCombat(oCreature)) + { + sIndex = IntToString(ai_GetBestSneakAttackIndex(oCreature, AI_RANGE_MELEE)); + } + // Ok we are in a serious fight so lets not give attack of opportunities. + else sIndex = IntToString(ai_GetNearestIndex(oCreature, AI_RANGE_MELEE)); + oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + } + if(oTarget == OBJECT_INVALID) return FALSE; + int nRacialType = GetRacialType(oTarget); + if(nRacialType == RACIAL_TYPE_CONSTRUCT || nRacialType == RACIAL_TYPE_UNDEAD) return FALSE; + if(ai_GetHasEffectType(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) return FALSE; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return TRUE; +} +int ai_TryRangedSneakAttack(object oCreature, int nInMelee) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1209", GetName(oCreature) + " is checking for a Ranged Sneak Attack!"); + // If we have Sneak Attack then we should be attacking targets that + // are busy fighting so we can get extra damage. + if(!GetHasFeat(FEAT_SNEAK_ATTACK, oCreature)) return FALSE; + object oTarget = OBJECT_INVALID; + oTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = GetLocalObject(oCreature, AI_ENEMY + IntToString(ai_GetBestSneakAttackIndex(oCreature))); + if(oTarget == OBJECT_INVALID) return FALSE; + int nRacialType = GetRacialType(oTarget); + if(nRacialType == RACIAL_TYPE_CONSTRUCT || nRacialType == RACIAL_TYPE_UNDEAD) return FALSE; + if(ai_GetHasEffectType(oTarget, IMMUNITY_TYPE_CRITICAL_HIT)) return FALSE; + // If we have a target and are not within 30' then move within 30'. + if(GetDistanceToObject(oTarget) > AI_RANGE_CLOSE) ActionMoveToObject(oTarget, TRUE, AI_RANGE_CLOSE); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return TRUE; +} +int ai_TryMeleeTalents(object oCreature, object oTarget) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1224", "Check category melee talents!"); + talent tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_MELEE, 20, oCreature); + if(!GetIsTalentValid(tUse)) return FALSE; + int nId = GetIdFromTalent(tUse); + if(AI_DEBUG) ai_Debug("0i_talents", "1228", "TALENT_CATEGORY_MELEE_TALENTS nId: " + IntToString(nId)); + if(nId == FEAT_POWER_ATTACK) { if(ai_TryPowerAttackFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_EXPERTISE) { if(ai_TryExpertiseFeat(oCreature)) return TRUE; } + else if(nId == FEAT_KNOCKDOWN) { if(ai_TryKnockdownFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_SMITE_EVIL) { if(ai_TrySmiteEvilFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_SMITE_GOOD) { if(ai_TrySmiteGoodFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_IMPROVED_POWER_ATTACK) { if(ai_TryImprovedPowerAttackFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_IMPROVED_EXPERTISE) { if(ai_TryImprovedExpertiseFeat(oCreature)) return TRUE; } + else if(nId == FEAT_FLURRY_OF_BLOWS) { if(ai_TryFlurryOfBlowsFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_STUNNING_FIST) { if(ai_TryStunningFistFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_SAP) { if(ai_TrySapFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_DISARM) { if(ai_TryDisarmFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_KI_DAMAGE) { if(ai_TryKiDamageFeat(oCreature, oTarget)) return TRUE; } + else if(nId == FEAT_CALLED_SHOT) { if(ai_TryCalledShotFeat(oCreature, oTarget)) return TRUE; } + return FALSE; +} +// ***************************************************************************** +// ***************************** TALENT SCRIPTS ****************************** +// ***************************************************************************** +// These functions do not fall into another section. + +int ai_GetMonsterTalentMaxLevel(object oCreature) +{ + // Monsters should use either the best spell they have or a random spell so + // they all don't look robotic. Mix it up based on an Intelligence check. + int nMaxLevel = (ai_GetCharacterLevels(oCreature) + 1) / 2; + if(nMaxLevel > 9) nMaxLevel = 9; + if(AI_DEBUG) ai_Debug("0i_talents", "1258", "nMaxLevel: " + IntToString(nMaxLevel)); + return nMaxLevel; +} +int ai_GetAssociateTalentMaxLevel(object oCreature, int nDifficulty) +{ + int nLevel = (ai_GetCharacterLevels(oCreature) + 1) / 2; + if(nLevel > 20) nLevel = 20; + int nMaxLevel = (nLevel * nDifficulty) / 20; + if(nMaxLevel < 1) nMaxLevel = 1; + if(AI_DEBUG) ai_Debug("0i_talents", "1267", "nLevel: " + IntToString(nLevel) + + " nMaxLevel: " + IntToString(nMaxLevel)); + return nMaxLevel; +} +int ai_GetHasTalent(object oCreature, int nTalent) +{ + string sCategory = Get2DAString("ai_spells", "Category", nTalent); + json jCategory = GetLocalJson(oCreature, sCategory); + if(JsonGetType(jCategory) == JSON_TYPE_NULL) return FALSE; + int nLevel, nSlot, nSlotIndex, nMaxSlotIndex, nSpell; + json jLevel, jTalent; + // Loop through nLevels looking for nTalent + while(nLevel <= 9) + { + // Get the array of nLevel. + jLevel = JsonArrayGet(jCategory, nLevel); + nMaxSlotIndex = JsonGetLength(jLevel); + if(nMaxSlotIndex > 0) + { + // Get the talent within nLevel cycling from the first to the last. + nSlotIndex = 0; + while (nSlotIndex < nMaxSlotIndex) + { + jTalent= JsonArrayGet(jLevel, nSlotIndex); + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + if(nSpell == nTalent) return TRUE; + nSlotIndex++; + } + } + nLevel++; + } + return FALSE; +} +object ai_CheckTalentForBuffing(object oCreature, string sCategory, int nSpell) +{ + // Should we buff this monster caster? Added legacy code just in case. + if((sCategory == "P" || sCategory == "E" || sCategory == "S") && + (GetLocalInt(GetModule(), AI_RULE_BUFF_MONSTERS) || + GetLocalInt(oCreature, "NW_GENERIC_MASTER") & 0x04000000)) return ai_GetBuffTarget(oCreature, nSpell); + //if(sCategory == "S" && GetLocalInt(GetModule(), AI_RULE_PRESUMMON)) return oCreature; + return OBJECT_INVALID; +} +int ai_UseBuffTalent(object oCreature, int nClass, int nLevel, int nSlot, int nSpell, int nType, object oTarget, object oItem) +{ + if(nType == AI_TALENT_TYPE_SPELL) + { + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot)) + { + ai_CastMemorizedSpell(oCreature, nClass, nLevel, nSlot, oTarget, TRUE); + return TRUE; + } + } + else if(GetSpellUsesLeft(oCreature, nClass, nSpell)) + { + ai_CastKnownSpell(oCreature, nClass, nSpell, oTarget, TRUE); + return TRUE; + } + } + else if(nType == AI_TALENT_TYPE_SP_ABILITY) + { + ActionCastSpellAtObject(nSpell, oTarget, 255, FALSE, 0, 0, TRUE, 255); + } + /* This will not work as there is no cheat option for using an item. + else if(nType == AI_TALENT_TYPE_ITEM) + { + int nBaseItem = GetBaseItemType(oItem); + if(!AI_BUFF_MONSTER_POTIONS && + (nBaseItem == BASE_ITEM_POTIONS || nBaseItem == BASE_ITEM_ENCHANTED_POTION)) return FALSE; + itemproperty ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + if(nIndex++ == nSlot) break; + ipProp = GetNextItemProperty(oItem); + } + // Cast items have the following: + // 1)Single_Use. + // 2-6) Charges/Use [Note: 7 is 0 charges per use]. + // 8-12) Uses/Day [Note: 13 is unlimited uses per day]. + // We set the slot to -1 to let the other function know we need this talent removed. + int nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses == 1) jTalent = JsonArrayInsert(jTalent, JsonInt(-1), 4); + else if(nUses > 1 && nUses < 7) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1319", "Item charges: " + IntToString(GetItemCharges(oItem))); + int nCharges = GetItemCharges(oItem); + if(nUses == 6 && nCharges == 1 || nUses == 5 && nCharges < 4 || + nUses == 4 && nCharges < 6 || nUses == 3 && nCharges < 8 || + nUses == 2 && nCharges < 10) return FALSE; + } + else if(nUses > 7 && nUses < 13) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1327", "Item uses: " + IntToString(GetItemPropertyUsesPerDayRemaining(oItem, ipProp))); + int nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(nUses == 8 && nPerDay == 1 || nUses == 9 && nPerDay < 4 || + nUses == 10 && nPerDay < 6 || nUses == 11 && nPerDay < 8 || + nUses == 12 && nPerDay < 10) return FASLE; + } + ActionUseItemOnObject(oItem, ipProp, oTarget, nSubIndex); + return TRUE; + } */ + return FALSE; +} +int ai_SpellRestricted(int nSpell) +{ + json jRSpells = GetLocalJson(GetModule(), AI_RULE_RESTRICTED_SPELLS); + int nIndex, nMaxIndex = JsonGetLength(jRSpells); + while(nIndex < nMaxIndex) + { + if(JsonGetInt(JsonArrayGet(jRSpells, nIndex)) == nSpell) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1703", IntToString(nSpell) + " is has been restricted and will be ignored!"); + return TRUE; + } + nIndex++; + } + return FALSE; +} +void ai_SaveTalent(object oCreature, int nClass, int nJsonLevel, int nLevel, int nSlot, int nSpell, int nType, int bMonster, object oItem = OBJECT_INVALID) +{ + // Players/Admins can restrict some spells. + if(ai_SpellRestricted(nSpell)) return; + // Get the talent category, we organize all talents by categories. + string sCategory = Get2DAString("ai_spells", "Category", nSpell); + // If it is a blank talent or it is an Area of Effect talent we skip. + if(sCategory == "" || sCategory == "A") return; + // Check to see if we should be prebuffing. + if(bMonster) + { + int nSpellBuffDuration = StringToInt(Get2DAString("ai_spells", "Buff_Duration", nSpell)); + if(nSpellBuffDuration == 3) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1600", GetName(oCreature) + " is buffing with spell " + IntToString(nSpell)); + object oTarget = ai_CheckTalentForBuffing(oCreature, sCategory, nSpell); + if(oTarget != OBJECT_INVALID && + ai_UseBuffTalent(oCreature, nClass, nLevel, nSlot, nSpell, nType, oTarget, oItem)) return; + } + } + json jCategory = GetLocalJson(oCreature, sCategory); + // With no jCategory then we make one with all 0-9 levels. + if(JsonGetType(jCategory) == JSON_TYPE_NULL) + { + jCategory = JsonArray(); + jCategory = JsonArrayInsert(jCategory, JsonArray(), 0); + int nNewLevel = 9; + while(nNewLevel > 0) + { + jCategory = JsonArrayInsert(jCategory, JsonArray()); + nNewLevel--; + } + } + // Get the current Level so we can save to it. + json jLevel = JsonArrayGet(jCategory, nJsonLevel); + json jTalent = JsonArray(); + if(nType == AI_TALENT_TYPE_SPELL || nType == AI_TALENT_TYPE_SP_ABILITY) + { + jTalent = JsonArrayInsert(jTalent, JsonInt(nType), 0); + jTalent = JsonArrayInsert(jTalent, JsonInt(nSpell)); + jTalent = JsonArrayInsert(jTalent, JsonInt(nClass)); + jTalent = JsonArrayInsert(jTalent, JsonInt(nLevel)); + jTalent = JsonArrayInsert(jTalent, JsonInt(nSlot)); + } + else if(nType == AI_TALENT_TYPE_ITEM) + { + jTalent = JsonArrayInsert(jTalent, JsonInt(nType), 0); + jTalent = JsonArrayInsert(jTalent, JsonInt(nSpell)); + jTalent = JsonArrayInsert(jTalent, JsonString(ObjectToString(oItem))); + jTalent = JsonArrayInsert(jTalent, JsonInt(nLevel)); + jTalent = JsonArrayInsert(jTalent, JsonInt(nSlot)); + } + jLevel = JsonArrayInsert(jLevel, jTalent); + jCategory = JsonArraySet(jCategory, nJsonLevel, jLevel); + SetLocalJson(oCreature, sCategory, jCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "1777", sCategory + ": " + JsonDump(jCategory, 1)); + if(AI_DEBUG) ai_Debug("0i_talents", "1778", "AI_MAX_TALENT: " + + IntToString(GetLocalInt(oCreature, AI_MAX_TALENT + sCategory)) + + " nJsonLevel: " + IntToString(nJsonLevel)); + // Set AI_MAX_TALENT if this talent is higher than the maximum. + if(nJsonLevel > GetLocalInt(oCreature, AI_MAX_TALENT + sCategory)) + { + SetLocalInt(oCreature, AI_MAX_TALENT + sCategory, nJsonLevel); + } +} +// For removing used up spell slots. +void ai_RemoveTalent(object oCreature, json jCategory, json jLevel, string sCategory, int nLevel, int nSlotIndex) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1400", "removing Talent from slot: " + IntToString(nSlotIndex)); + jLevel = JsonArrayDel(jLevel, nSlotIndex); + if(AI_DEBUG) ai_Debug("0i_talents", "1402", "jLevel: " + JsonDump(jLevel, 2)); + jCategory = JsonArraySet(jCategory, nLevel, jLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "1404", "jCategory: " + JsonDump(jCategory, 2)); + SetLocalJson(oCreature, sCategory, jCategory); +} +// For removing Sorcerer/Bard spell levels once used up. +void ai_RemoveTalentLevel(object oCreature, json jCategory, json jLevel, string sCategory, int nLevel) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1410", "removing Talent level: " + IntToString(nLevel)); + jCategory = JsonArrayDel(jCategory, nLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "1412", "jCategory: " + JsonDump(jCategory, 2)); + SetLocalJson(oCreature, sCategory, jCategory); +} +void ai_SetCreatureSpellTalents(object oCreature, int bMonster) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1417", GetName(oCreature) + ": Setting Spell Talents for combat [Buff: " + + IntToString(bMonster) + "]."); + // Cycle through all classes and spells. + int nClassPosition = 1, nMaxSlot, nLevel, nSlot, nSpell, nIndex, nMetaMagic; + int nClass = GetClassByPosition(nClassPosition, oCreature); + while(nClassPosition <= AI_MAX_CLASSES_PER_CHARACTER && nClass != CLASS_TYPE_INVALID) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1824", "nClass: " + IntToString(nClass) + + " nClassPosition: " + IntToString(nClassPosition) + + " SpellCaster: " + Get2DAString("classes", "SpellCaster", nClass) + + " Memorized: " + Get2DAString("classes", "MemorizesSpells", nClass)); + if(Get2DAString("classes", "SpellCaster", nClass) == "1") + { + // Search all memorized spells for the spell. + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + // Check each level organizing from highest to lowest. + nLevel = (GetLevelByPosition(nClassPosition, oCreature) + 1) / 2; + if(nLevel > 9) nLevel = 9; + while(nLevel > -1) + { + // Check each slot within each level. + nMaxSlot = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "1434", "nClass: " + IntToString(nClass) + + " nLevel: " + IntToString(nLevel) + " nMaxSlot: " + + IntToString(nMaxSlot)); + nSlot = 0; + while(nSlot < nMaxSlot) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1440", "nSlot: " + IntToString(nSlot) + " nSpell: " + + IntToString(GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot)) + " spell memorized: " + + IntToString(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot))); + if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot) == 1) + { + nSpell = GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot); + /* Spells are already at the higher level when saved as a talent. + // Move a spell up to a different JsonLevel as higher Jsonlevel + // spells usually get cast first. + nMetaMagic = GetMemorizedSpellMetaMagic(oCreature, nClass, nLevel, nSlot); + if(nMetaMagic > 0) + { + if(nMetaMagic == METAMAGIC_STILL) nMetaMagic = 1; + else if(nMetaMagic == METAMAGIC_EXTEND) nMetaMagic = 1; + else if(nMetaMagic == METAMAGIC_SILENT) nMetaMagic = 1; + else if(nMetaMagic == METAMAGIC_EMPOWER) nMetaMagic = 2; + else if(nMetaMagic == METAMAGIC_MAXIMIZE) nMetaMagic = 3; + else if(nMetaMagic == METAMAGIC_QUICKEN) nMetaMagic = 4; + nAdjLevel = nLevel + nMetaMagic; + if(nAdjLevel > 9) nAdjLevel = 9; + } + else nAdjLevel = nLevel; */ + ai_SaveTalent(oCreature, nClass, nLevel, nLevel, nSlot, nSpell, AI_TALENT_TYPE_SPELL, bMonster); + } + nSlot++; + } + nLevel--; + } + } + // Check non-memorized known lists for the spell. + else + { + // Check each level starting with the highest to lowest. + nLevel = (GetLevelByPosition(nClassPosition, oCreature) + 1) / 2; + if(nLevel > 9) nLevel = 9; + while(nLevel > -1) + { + // Check each slot within each level. + nMaxSlot = GetKnownSpellCount(oCreature, nClass, nLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "1462", "nClass: " + IntToString(nClass) + + " nLevel: " + IntToString(nLevel) + " nMaxSlot: " + + IntToString(nMaxSlot)); + nSlot = 0; + while(nSlot < nMaxSlot) + { + nSpell = GetKnownSpellId(oCreature, nClass, nLevel, nSlot); + if(AI_DEBUG) ai_Debug("0i_talents", "1469", "nSlot: " + IntToString(nSlot) + + " nSpell: " + IntToString(nSpell) + " nUsesLeft: " + + IntToString(GetSpellUsesLeft(oCreature, nClass, nSpell))); + if(GetSpellUsesLeft(oCreature, nClass, nSpell) > 0) + { + ai_SaveTalent(oCreature, nClass, nLevel, nLevel, nSlot, nSpell, AI_TALENT_TYPE_SPELL, bMonster); + } + nSlot++; + } + nLevel--; + } + } + } + nClassPosition++; + nClass = GetClassByPosition(nClassPosition, oCreature); + } +} +void ai_SetCreatureSpecialAbilityTalents(object oCreature, int bMonster) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1488", GetName(oCreature) + ": Setting Special Ability Talents for combat."); + // Cycle through all the creatures special abilities. + int nMaxSpecialAbilities = GetSpellAbilityCount(oCreature); + if(AI_DEBUG) ai_Debug("0i_talents", "1491", IntToString(GetSpellAbilityCount(oCreature)) + " Spell abilities."); + if(nMaxSpecialAbilities) + { + int nIndex, nSpell, nLevel; + while(nIndex < nMaxSpecialAbilities) + { + nSpell = GetSpellAbilitySpell(oCreature, nIndex); + if(GetSpellAbilityReady(oCreature, nSpell)) + { + nLevel = StringToInt(Get2DAString("spells", "Innate", nSpell)); + ai_SaveTalent(oCreature, 255, nLevel, nLevel, nIndex, nSpell, AI_TALENT_TYPE_SP_ABILITY, bMonster); + } + nIndex++; + } + } +} +void ai_CheckItemProperties(object oCreature, object oItem, int bMonster, int bEquiped = FALSE) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1509", "Checking Item properties on " + GetName(oItem)); + // We have established that we can use the item if it is equiped. + if(!bEquiped && !ai_CheckIfCanUseItem(oCreature, oItem)) return; + // Get or create an Immunity in json so we can check item immunities quickly. + int nSpellImmunity, bHasItemImmunity, nPerDay, nCharges, nUses, bSaveTalent; + json jImmunity = GetLocalJson(oCreature, AI_TALENT_IMMUNITY); + if(JsonGetType(jImmunity) == JSON_TYPE_NULL) jImmunity = JsonArray(); + int nIprpSubType, nSpell, nLevel, nIPType, nIndex; + itemproperty ipProp = GetFirstItemProperty(oItem); + // Lets skip this if there are no properties. + if(!GetIsItemPropertyValid(ipProp)) return; + // Check for cast spell property and add them to the talent list. + while(GetIsItemPropertyValid(ipProp)) + { + nIPType = GetItemPropertyType(ipProp); + if(AI_DEBUG) ai_Debug("0i_talents", "1895", "ItempropertyType(15/80/53): " + IntToString(nIPType)); + if(nIPType == ITEM_PROPERTY_CAST_SPELL) + { + bSaveTalent = TRUE; + // Get how they use the item (charges or uses per day). + nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses > 1 && nUses < 7) + { + nCharges = GetItemCharges(oItem); + if(AI_DEBUG) ai_Debug("0i_talents", "1530", "Charges per use: " + IntToString(nUses) + + " Item charges: " + IntToString(nCharges)); + if((nUses == IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE && nCharges < 1) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE && nCharges < 2) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_3_CHARGES_PER_USE && nCharges < 3) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_4_CHARGES_PER_USE && nCharges < 4) || + (nUses == IP_CONST_CASTSPELL_NUMUSES_5_CHARGES_PER_USE && nCharges < 5)) bSaveTalent = FALSE; + } + else if(nUses > 7 && nUses < 13) + { + nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(AI_DEBUG) ai_Debug("0i_talents", "1676", "Item uses: " + IntToString(nPerDay)); + if(nPerDay == 0) bSaveTalent = FALSE; + } + if(bSaveTalent) + { + // SubType is the ip spell index for iprp_spells.2da + nIprpSubType = GetItemPropertySubType(ipProp); + nSpell = StringToInt(Get2DAString("iprp_spells", "SpellIndex", nIprpSubType)); + nLevel = StringToInt(Get2DAString("iprp_spells", "InnateLvl", nIprpSubType)); + ai_SaveTalent(oCreature, 255, nLevel, nLevel, nIndex, nSpell, AI_TALENT_TYPE_ITEM, bMonster, oItem); + } + } + else if(nIPType == ITEM_PROPERTY_HEALERS_KIT) + { + // Lets set Healing kits as Cure Light Wounds since they heal 1d20 in combat. + nSpell = SPELL_CURE_MINOR_WOUNDS; + // Save the healer kit as level 9 so we can use them first. + // Must also have ranks in healing kits. + if(GetSkillRank(SKILL_HEAL, oCreature) > 0) + { + ai_SaveTalent(oCreature, 255, 7, 0, nIndex, nSpell, AI_TALENT_TYPE_ITEM, bMonster, oItem); + } + } + if(bEquiped) + { + if(nIPType == ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL) + { + bHasItemImmunity = TRUE; + nSpellImmunity = GetItemPropertyCostTableValue(ipProp); + nSpellImmunity = StringToInt(Get2DAString("iprp_spellcost", "SpellIndex", nSpellImmunity)); + //if(AI_DEBUG) ai_Debug("0i_talents", "1950", "SpellImmunity to " + Get2DAString("spells", "Label", nSpellImmunity)); + jImmunity = JsonArrayInsert(jImmunity, JsonInt(nSpellImmunity)); + } + else if(nIPType == ITEM_PROPERTY_HASTE) + { + SetLocalInt(oCreature, sIPHasHasteVarname, TRUE); + } + else if(nIPType == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE) + { + int nBit, nIpSubType = GetItemPropertySubType(ipProp); + if(AI_DEBUG) ai_Debug("0i_talents", "1957", "nIPSubType: " + IntToString(nIpSubType)); + if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING; + else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING; + else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING; + else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL; + else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID; + else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD; + else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE; + else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL; + else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE; + else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE; + else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE; + else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC; + if(nBit > 0) ai_SetItemProperty(oCreature, sIPImmuneVarname, nBit, TRUE); + } + else if(nIPType == ITEM_PROPERTY_DAMAGE_RESISTANCE) + { + int nBit, nIpSubType = GetItemPropertySubType(ipProp); + if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING; + else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING; + else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING; + else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL; + else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID; + else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD; + else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE; + else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL; + else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE; + else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE; + else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE; + else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC; + if(nBit > 0) ai_SetItemProperty(oCreature, sIPResistVarname, nBit, TRUE); + } + else if(nIPType == ITEM_PROPERTY_DAMAGE_REDUCTION) + { + int nIpSubType = GetItemPropertySubType(ipProp); + SetLocalInt(oCreature, sIPReducedVarname, nIpSubType); + } + } + nIndex++; + ipProp = GetNextItemProperty(oItem); + } + // If nSpellImmunity has been set then we need to save our Immunity json. + if(bHasItemImmunity) SetLocalJson(oCreature, AI_TALENT_IMMUNITY, jImmunity); +} +void ai_SetCreatureItemTalents(object oCreature, int bMonster) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1561", GetName(oCreature) + ": Setting Item Talents for combat."); + int bEquiped; + string sSlots; + // Cycle through all the creatures inventory items. + object oItem = GetFirstItemInInventory(oCreature); + while(oItem != OBJECT_INVALID) + { + if(GetIdentified(oItem)) + { + // Does the item need to be equiped to use its powers? + sSlots = Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)); + if(AI_DEBUG) ai_Debug("0i_talents", "1572", GetName(oItem) + " requires " + Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)) + " slots."); + if(sSlots == "0x00000") ai_CheckItemProperties(oCreature, oItem, bMonster); + } + oItem = GetNextItemInInventory(oCreature); + } + int nSlot; + // Cycle through all the creatures equiped items. + oItem = GetItemInSlot(nSlot, oCreature); + while(nSlot < 11) + { + if(oItem != OBJECT_INVALID) ai_CheckItemProperties(oCreature, oItem, bMonster, TRUE); + oItem = GetItemInSlot(++nSlot, oCreature); + } + oItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oCreature); + if(oItem != OBJECT_INVALID) ai_CheckItemProperties(oCreature, oItem, bMonster, TRUE); +} +void ai_SetCreatureTalents(object oCreature, int bMonster) +{ + json jCreature = ObjectToJson(oCreature); + //if(AI_DEBUG) ai_Debug("0i_talents", "2072", GetName(oCreature) + " jCreature: " + JsonDump(jCreature, 4)); + if(GetLocalInt(oCreature, AI_TALENTS_SET)) return; + SetLocalInt(oCreature, AI_TALENTS_SET, TRUE); + object oModule = GetModule(); + ai_Counter_Start(); + ai_SetCreatureSpellTalents(oCreature, bMonster); + ai_Counter_End(GetName(oCreature) + ": Spell Talents"); + ai_SetCreatureSpecialAbilityTalents(oCreature, bMonster); + ai_Counter_End(GetName(oCreature) + ": Special Ability Talents"); + DeleteLocalJson(oCreature, AI_TALENT_IMMUNITY); + ai_SetCreatureItemTalents(oCreature, bMonster); + ai_Counter_End(GetName(oCreature) + ": Item Talents"); + if(GetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS) && GetLocalInt(oModule, AI_RULE_PRESUMMON) && bMonster) + { + ai_TrySummonFamiliarTalent(oCreature); + ai_TrySummonAnimalCompanionTalent(oCreature); + } + // AI_CAT_CURE is setup differently we save the level as the highest. + //if(JsonGetType(GetLocalJson(oCreature, AI_TALENT_CURE)) != JSON_TYPE_NULL) SetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_CURE, 9); + // With spontaneous cure spells we need to clear this as the number of spells don't count. + //if(GetLevelByClass(CLASS_TYPE_CLERIC, oCreature)) SetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_HEALING, 0); +} +int ai_UseSpontaneousCureTalentFromCategory(object oCreature, string sCategory, int nInMelee, int nDamage, object oTarget = OBJECT_INVALID) +{ + // Get the saved category from oCreature. + json jCategory = GetLocalJson(oCreature, sCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "2095", "jCategory: " + sCategory + " " + JsonDump(jCategory, 2)); + if(JsonGetType(jCategory) == JSON_TYPE_NULL) return FALSE; + int nLevel = 4; + // If there are no talents at lower levels then start at the lower level. + int nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + sCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "2100", AI_MAX_TALENT + sCategory + ": " + + IntToString(nMaxTalentLevel) + + " nLevel: " + IntToString(nLevel)); + if(nMaxTalentLevel < nLevel) nLevel = nMaxTalentLevel; + if(nLevel < 0 || nLevel > 5) nLevel = 4; + json jLevel, jTalent, jLevelSave; + int nTalentType, nTalentClass, nTalentSlot, nSpell; + int nSlotIndex, nMaxSlotIndex, nMaxNoTalentLevel, nSpellSave, nLevelSave, nSlotSave; + string sSpellName; + // Loop through nLevels down to nMinNoTalentLevel looking for the first talent + // (i.e. the highest or best?). + while(nLevel > -1) + { + // Get the array of nLevel cycling down to 0. + jLevel = JsonArrayGet(jCategory, nLevel); + nMaxSlotIndex = JsonGetLength(jLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "2116", "nLevel: " + IntToString(nLevel) + + " nMaxSlotIndex: " + IntToString(nMaxSlotIndex)); + if(nMaxSlotIndex > 0) + { + // Get the talent within nLevel cycling from the first to the last. + nSlotIndex = 0; + while (nSlotIndex < nMaxSlotIndex) + { + jTalent= JsonArrayGet(jLevel, nSlotIndex); + if(AI_DEBUG) ai_Debug("0i_talents", "2125", "nSlotIndex: " + IntToString(nSlotIndex) + + " jTalent Type: " + IntToString(JsonGetInt(JsonArrayGet(jTalent, 0)))); + nTalentType = JsonGetInt(JsonArrayGet(jTalent, 0)); + nTalentClass = JsonGetInt(JsonArrayGet(jTalent, 2)); + // We can only convert spells from the cleric class. + if(nTalentType == AI_TALENT_TYPE_SPELL && nTalentClass == CLASS_TYPE_CLERIC) + { + if(nLevel == 4) nSpell = SPELL_CURE_CRITICAL_WOUNDS; + else if(nLevel == 3) nSpell = SPELL_CURE_SERIOUS_WOUNDS; + else if(nLevel == 2) nSpell = SPELL_CURE_MODERATE_WOUNDS; + else if(nLevel == 1) nSpell = SPELL_CURE_LIGHT_WOUNDS; + else nSpell = 0; + if(AI_DEBUG) ai_Debug("0i_talents", "2137", "nSpell: " + IntToString(nSpell)); + if(nSpell) + { + if(ai_ShouldWeCastThisCureSpell(nSpell, nDamage)) + { + + nTalentSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + SetMemorizedSpellReady(oCreature, nTalentClass, nLevel, nTalentSlot, FALSE); + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(ai_GetIsCharacter(oCreature)) ai_SendMessages(GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_MAGENTA, oCreature); + if(AI_DEBUG) ai_Debug("0i_talents", "2148", GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + "."); + ActionCastSpellAtObject(nSpell, oTarget, 255, TRUE); + return TRUE; + } + // Save the lowest level cure spell as we might need to cast it. + else if(nLevel < nLevelSave) + { + jLevelSave = jLevel; + nLevelSave = nLevel; + nSlotSave = nTalentSlot; + nSpellSave = nSpell; + } + } + } + nSlotIndex++; + } + } + else SetLocalInt(oCreature, AI_MAX_TALENT + sCategory, nLevel - 1); + nLevel--; + } + // Did we find a spell? If we did then use it. + if(nSpellSave) + { + if(AI_DEBUG) ai_Debug("0i_talents", "2171", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + "."); + SetMemorizedSpellReady(oCreature, CLASS_TYPE_CLERIC, nLevelSave, nSlotSave, FALSE); + ai_RemoveTalent(oCreature, jCategory, jLevelSave, sCategory, nLevelSave, nSlotSave); + sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpellSave))); + if(ai_GetIsCharacter(oCreature)) ai_SendMessages(GetName(oCreature) + " has spontaneously cast " + sSpellName + " on " + GetName(oTarget) + ".", AI_COLOR_MAGENTA, oCreature); + ActionCastSpellAtObject(nSpellSave, oTarget, 255, TRUE); + return TRUE; + } + return FALSE; +} +int ai_UseCreatureSpellTalent(object oCreature, json jLevel, json jTalent, string sCategory, int nInMelee, object oTarget = OBJECT_INVALID) +{ + // Check for polymorph, spells cannot be used while polymorphed. + if(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature)) return FALSE; + // Get the spells information so we can check if they still have it. + int nClass = JsonGetInt(JsonArrayGet(jTalent, 2)); + int nLevel = JsonGetInt(JsonArrayGet(jTalent, 3)); + int nSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + if(ai_IsSilenced(oCreature, JsonGetInt(JsonArrayGet(jTalent, 2)))) + { + if(GetMemorizedSpellMetaMagic(oCreature, nClass, nLevel, nSlot) != METAMAGIC_SILENT) + { + object oAOE = GetNearestObjectByTag("VFX_MOB_SILENCE", oCreature); + float fDistance = GetDistanceBetween(oAOE, oCreature); + if(fDistance != 0.0 && fDistance <= 4.0) + { + location lLocation = GetRandomLocation(GetArea(oCreature), oCreature, 5.0); + ai_ClearCreatureActions(); + if(AI_DEBUG) ai_Debug("0i_talents", "2225", GetName(oCreature) + " is moving out of a silence effect!"); + ActionMoveToLocation(lLocation, TRUE); + return TRUE; + } + else return FALSE; + } + } + if(ai_ArcaneSpellFailureTooHigh(oCreature, nClass, nLevel, nSlot)) return FALSE; + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + // Shouldn't need this anymore, we need to do a debug looking at this. + if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot) < 1) return FALSE; + if(ai_CheckSpecialTalentsandUse(oCreature, jTalent, sCategory, nInMelee, oTarget)) + { + if(ai_CompareLastAction(oCreature, AI_LAST_ACTION_CAST_SPELL)) return -1; + return TRUE; + } + return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "1629", "Known caster Level: " + IntToString(nLevel) + + " Uses : " + IntToString(GetSpellUsesLeft(oCreature, nClass, JsonGetInt(JsonArrayGet(jTalent, 1))))); + if(!GetSpellUsesLeft(oCreature, nClass, JsonGetInt(JsonArrayGet(jTalent, 1)))) return -2; + return ai_CheckSpecialTalentsandUse(oCreature, jTalent, sCategory, nInMelee, oTarget); +} +int ai_UseCreatureItemTalent(object oCreature, json jLevel, json jTalent, string sCategory, int nInMelee, object oTarget = OBJECT_INVALID) +{ + object oItem = StringToObject(JsonGetString(JsonArrayGet(jTalent, 2))); + int nItemType = GetBaseItemType(oItem); + // Check if the item is a potion since there are some special cases. + if(nItemType == BASE_ITEM_POTIONS || nItemType == BASE_ITEM_ENCHANTED_POTION) + { + // Potions cause attack of opportunities and this could be deadly! + // Removed for healing potions as that is one time you would use potions in melee. + if(sCategory != AI_TALENT_HEALING) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1925", "Using a non-healing potion nInMelee: " + IntToString(nInMelee)); + if(nInMelee > 1) return FALSE; + // Don't use potions on allies that are not within 3 meters. + if(GetDistanceBetween(oCreature, oTarget) > 3.1) return FALSE; + } + // For now we are allowing creatures to use "give" potions to others + // unless the player is using a healing potion and has party healing turned off. + else if(oCreature != oTarget && ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) return FALSE; + } + // Check for polymorph, only potions can be used while polymorphed. + else if(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature)) return FALSE; + else if(nItemType == BASE_ITEM_HEALERSKIT) + { + if(!GetLocalInt(GetModule(), AI_RULE_HEALERSKITS)) return FALSE; + if(oCreature != oTarget && ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) return FALSE; + if(AI_DEBUG) ai_Debug("0i_talents", "1724", "Using " + GetName(oItem) + " nInMelee: " + IntToString(nInMelee) + + " targeting: " + GetName(oTarget)); + ai_SetLastAction(oCreature, AI_LAST_ACTION_USED_ITEM); + ActionUseItemOnObject(oItem, GetFirstItemProperty(oItem), oTarget); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + // We also must check for stack size. + if(GetItemStackSize(oItem) == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + return TRUE; + } + if(ai_CheckSpecialTalentsandUse(oCreature, jTalent, sCategory, nInMelee, oTarget)) return TRUE; + return FALSE; +} +int ai_UseCreatureTalent(object oCreature, string sCategory, int nInMelee, int nLevel = 10, object oTarget = OBJECT_INVALID) +{ + // Get the saved category from oCreature. + json jCategory = GetLocalJson(oCreature, sCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "2292", "jCategory: " + sCategory + " " + JsonDump(jCategory, 2)); + if(JsonGetType(jCategory) == JSON_TYPE_NULL) return FALSE; + // If there are no talents at lower levels then start at the lower level. + int nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + sCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "2297", AI_MAX_TALENT + sCategory + ": " + + IntToString(nMaxTalentLevel) + + " nLevel: " + IntToString(nLevel)); + if(nMaxTalentLevel < nLevel) nLevel = nMaxTalentLevel; + if(nLevel < 0 || nLevel > 10) nLevel = 9; + json jLevel, jTalent; + int nClass, nSlot, nType, nSlotIndex, nMaxSlotIndex, nTalentUsed, nSpell; + int bUseMagic = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC); + int bUseMagicItems = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC_ITEMS); + if(AI_DEBUG) ai_Debug("0i_talents", "2305", "bUseMagic: " + IntToString(bUseMagic) + + " bUseMagicItems: " + IntToString(bUseMagicItems) + + " nLevel: " + IntToString(nLevel)); + // Loop through nLevels down to nMinNoTalentLevel looking for the first talent + // (i.e. the highest or best?). + while(nLevel > -1) + { + // Get the array of nLevel cycling down to 0. + jLevel = JsonArrayGet(jCategory, nLevel); + nMaxSlotIndex = JsonGetLength(jLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "2288", "nLevel: " + IntToString(nLevel) + + " nMaxSlotIndex: " + IntToString(nMaxSlotIndex)); + if(nMaxSlotIndex > 0) + { + // Get the talent within nLevel cycling from the first to the last. + nSlotIndex = 0; + while (nSlotIndex < nMaxSlotIndex) + { + jTalent= JsonArrayGet(jLevel, nSlotIndex); + if(AI_DEBUG) ai_Debug("0i_talents", "2300", "nSlotIndex: " + IntToString(nSlotIndex) + + " jTalent Type: " + IntToString(JsonGetInt(JsonArrayGet(jTalent, 0)))); + nType = JsonGetInt(JsonArrayGet(jTalent, 0)); + if(bUseMagic) + { + if(nType == AI_TALENT_TYPE_SPELL) + { + nTalentUsed = ai_UseCreatureSpellTalent(oCreature, jLevel, jTalent, sCategory, nInMelee, oTarget); + // -1 means it was a memorized spell and we need to remove it. + if(nTalentUsed == -1) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + return TRUE; + } + else if(nTalentUsed == -2) + { + ai_RemoveTalentLevel(oCreature, jCategory, jLevel, sCategory, nLevel); + } + else if(nTalentUsed) return TRUE; + } + else if(nType == AI_TALENT_TYPE_SP_ABILITY) + { + // Special ability spells do not need to concentrate?! + if(ai_CheckSpecialTalentsandUse(oCreature, jTalent, sCategory, nInMelee, oTarget)) + { + // When the ability is used that slot is now not readied. + // Multiple uses of the same spell are stored in different slots. + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + return TRUE; + } + } + } + if(bUseMagicItems && nType == AI_TALENT_TYPE_ITEM) + { + // Items do not need to concentrate. + if(ai_UseCreatureItemTalent(oCreature, jLevel, jTalent, sCategory, nInMelee, oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_talents", "2337", "Checking if Item is used up: " + + IntToString(JsonGetInt(JsonArrayGet(jTalent, 4)))); + if(JsonGetInt(JsonArrayGet(jTalent, 4)) == -1) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + } + return TRUE; + } + } + //else if(nType == AI_TALENT_TYPE_FEAT) {} + nSlotIndex++; + } + } + else SetLocalInt(oCreature, AI_MAX_TALENT + sCategory, nLevel - 1); + nLevel--; + } + return FALSE; +} +int ai_UseTalent(object oCreature, int nTalent, object oTarget) +{ + if(AI_DEBUG) ai_Debug("0i_talents", "1912", GetName(oCreature) + " is trying to use " + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nTalent))) + + " on " + GetName(oTarget)); + // Get the saved category from oCreature. + string sCategory = Get2DAString("ai_spells", "Category", nTalent); + json jCategory = GetLocalJson(oCreature, sCategory); + if(AI_DEBUG) ai_Debug("0i_talents", "1917", "jCategory: " + sCategory + " " + JsonDump(jCategory, 2)); + if(JsonGetType(jCategory) == JSON_TYPE_NULL) return FALSE; + json jLevel, jTalent; + int nLevel, nClass, nSlot, nType, nSlotIndex, nMaxSlotIndex, nTalentUsed, nSpell; + // Loop through nLevels down to nMinNoTalentLevel looking for the first talent + // (i.e. the highest or best?). + while(nLevel <= 9) + { + // Get the array of nLevel. + jLevel = JsonArrayGet(jCategory, nLevel); + nMaxSlotIndex = JsonGetLength(jLevel); + if(AI_DEBUG) ai_Debug("0i_talents", "1925", "nLevel: " + IntToString(nLevel) + + " nMaxSlotIndex: " + IntToString(nMaxSlotIndex)); + if(nMaxSlotIndex > 0) + { + // Get the talent within nLevel cycling from the first to the last. + nSlotIndex = 0; + while (nSlotIndex < nMaxSlotIndex) + { + jTalent= JsonArrayGet(jLevel, nSlotIndex); + if(AI_DEBUG) ai_Debug("0i_talents", "1936", "nSlotIndex: " + IntToString(nSlotIndex) + + " jTalent Type: " + IntToString(JsonGetInt(JsonArrayGet(jTalent, 0)))); + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + if(nSpell == nTalent) + { + nType = JsonGetInt(JsonArrayGet(jTalent, 0)); + if(nType == AI_TALENT_TYPE_SPELL || nType == AI_TALENT_TYPE_SP_ABILITY) + { + if(ai_UseTalentOnObject(oCreature, jTalent, oTarget, 0)) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + return TRUE; + } + } + else if(nType == AI_TALENT_TYPE_ITEM) + { + // Items do not need to concentrate. + if(ai_UseCreatureItemTalent(oCreature, jLevel, jTalent, sCategory, 0, oTarget)) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1955", "Checking if Item is used up: " + + IntToString(JsonGetInt(JsonArrayGet(jTalent, 4)))); + if(JsonGetInt(JsonArrayGet(jTalent, 4)) == -1) + { + ai_RemoveTalent(oCreature, jCategory, jLevel, sCategory, nLevel, nSlotIndex); + } + return TRUE; + } + } + } + nSlotIndex++; + } + } + nLevel++; + } + return FALSE; +} +int ai_UseTalentOnObject(object oCreature, json jTalent, object oTarget, int nInMelee) +{ + int nClass, nLevel, nSlot, nMetaMagic, nDomain; + int nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + int nType = JsonGetInt(JsonArrayGet(jTalent, 0)); + if(nType == AI_TALENT_TYPE_SPELL) + { + if(!ai_CastInMelee(oCreature, nSpell, nInMelee)) return FALSE; + nClass = JsonGetInt(JsonArrayGet(jTalent, 2)); + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + nLevel = JsonGetInt(JsonArrayGet(jTalent, 3)); + nSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + if(GetMemorizedSpellIsDomainSpell(oCreature, nClass, nLevel, nSlot) == 1) nDomain = nLevel; + else nDomain = 0; + nMetaMagic = GetMemorizedSpellMetaMagic(oCreature, nClass, nLevel, nSlot); + } + else + { + nMetaMagic = METAMAGIC_NONE; + nDomain = 0; + } + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell)) return TRUE; + } + else if(nType == AI_TALENT_TYPE_SP_ABILITY) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1790", GetName(oCreature) + " is using a special ability!"); + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + nClass = 255; + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell)) return TRUE; + } + else if(nType == AI_TALENT_TYPE_ITEM) + { + object oItem = StringToObject(JsonGetString(JsonArrayGet(jTalent, 2))); + int nBaseItemType = GetBaseItemType(oItem); + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell, nBaseItemType)) return TRUE; + int nIndex, nSubIndex = 0; + nSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + itemproperty ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + if(nIndex++ == nSlot) break; + ipProp = GetNextItemProperty(oItem); + } + // Cast items have the following: + // 1)Single_Use. + // 2-6) Charges/Use [Note: 7 is 0 charges per use]. + // 8-12) Uses/Day [Note: 13 is unlimited uses per day]. + // We set the slot to -1 to let the other function know we need this talent removed. + int nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses == 1) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1816", "Single Use item."); + if(AI_DEBUG) ai_Debug("0i_talents", "1817", "Stack size: " + IntToString(GetItemStackSize(oItem))); + // We also must check for stack size. + if(GetItemStackSize(oItem) == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + } + else if(nUses > 1 && nUses < 7) + { + int nCharges = GetItemCharges(oItem); + // If the item is equipable then do not use the last charge! + if(Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)) != "0x00000") + { + if(nCharges <= 7 - nUses) return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "1824", "Item charges: " + IntToString(nCharges)); + if(nCharges < (7 - nUses) * 2) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1829", "Stack size: " + IntToString(GetItemStackSize(oItem))); + // We also must check for stack size. + if(GetItemStackSize(oItem) == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + } + } + else if(nUses > 7 && nUses < 13) + { + int nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(AI_DEBUG) ai_Debug("0i_talents", "1837", "Item uses: " + IntToString(nPerDay)); + if(nPerDay == 1) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1842", "Stack size: " + IntToString(GetItemStackSize(oItem))); + // We also must check for stack size. + if(GetItemStackSize(oItem) == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + } + } + // Lets not always use unlimited items! + else if(nUses == 7 || nUses == 13) + { + if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + } + ai_SetLastAction(oCreature, nSpell); + ActionUseItemOnObject(oItem, ipProp, oTarget, nSubIndex); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + if(AI_DEBUG) ai_Debug("0i_talents", "1850", GetName(oCreature) + " is using " + GetName(oItem) + " on " + GetName(oTarget)); + return TRUE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "1853", "nMetaMagic: " + IntToString(nMetaMagic) + + " nDomain: " + IntToString(nDomain) + " nClass: " + IntToString(nClass)); + ai_SetLastAction(oCreature, nSpell); + ActionCastSpellAtObject(nSpell, oTarget, nMetaMagic, FALSE, nDomain, 0, FALSE, nClass, FALSE); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + if(AI_DEBUG) + { + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + ai_Debug("0i_talents", "1859", GetName(oCreature) + " is casting " + sSpellName + " on " + GetName(oTarget)); + } + return TRUE; +} +int ai_UseTalentAtLocation(object oCreature, json jTalent, object oTarget, int nInMelee) +{ + int nSpell, nClass, nLevel, nSlot, nMetaMagic, nDomain; + int nType = JsonGetInt(JsonArrayGet(jTalent, 0)); + if(nType == AI_TALENT_TYPE_SPELL) + { + if(!ai_CastInMelee(oCreature, nSpell, nInMelee)) return FALSE; + nClass = JsonGetInt(JsonArrayGet(jTalent, 2)); + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + nLevel = JsonGetInt(JsonArrayGet(jTalent, 3)); + nSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + if(GetMemorizedSpellIsDomainSpell(oCreature, nClass, nLevel, nSlot) == 1) nDomain = nLevel; + else nDomain = 0; + nMetaMagic = GetMemorizedSpellMetaMagic(oCreature, nClass, nLevel, nSlot); + } + else + { + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + nMetaMagic = METAMAGIC_NONE; + nDomain = 0; + } + } + else if(nType == AI_TALENT_TYPE_SP_ABILITY) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1888", GetName(oCreature) + " is using a special ability!"); + nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + nClass = 255; + } + else if(nType == AI_TALENT_TYPE_ITEM) + { + object oItem = StringToObject(JsonGetString(JsonArrayGet(jTalent, 2))); + int nBaseItemType = GetBaseItemType(oItem); + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell, nBaseItemType)) return TRUE; + int nIndex; + int nSubIndex = JsonGetInt(JsonArrayGet(jTalent, 3));; + nSlot = JsonGetInt(JsonArrayGet(jTalent, 4)); + itemproperty ipProp = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProp)) + { + if(nIndex++ == nSlot) break; + ipProp = GetNextItemProperty(oItem); + } + // Cast items have the following: + // 1)Single_Use. + // 2-6) Charges/Use [Note: 7 is 0 charges per use]. + // 8-12) Uses/Day [Note: 13 is unlimited uses per day]. + // We set the slot to -1 to let the other function know we need this talent removed. + int nUses = GetItemPropertyCostTableValue(ipProp); + if(nUses == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + else if(nUses > 1 && nUses < 7) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1915", "Item charges: " + IntToString(GetItemCharges(oItem))); + int nCharges = GetItemCharges(oItem); + // If the item is equipable then do not use the last charge! + if(Get2DAString("baseitems", "EquipableSlots", GetBaseItemType(oItem)) != "0x00000") + { + if(nCharges <= 7 - nUses) return FALSE; + } + if(AI_DEBUG) ai_Debug("0i_talents", "1824", "Item charges: " + IntToString(nCharges)); + if(nCharges < (7 - nUses) * 2) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1829", "Stack size: " + IntToString(GetItemStackSize(oItem))); + // We also must check for stack size. + if(GetItemStackSize(oItem) == 1) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + } + } + else if(nUses > 7 && nUses < 13) + { + if(AI_DEBUG) ai_Debug("0i_talents", "1923", "Item uses: " + IntToString(GetItemPropertyUsesPerDayRemaining(oItem, ipProp))); + int nPerDay = GetItemPropertyUsesPerDayRemaining(oItem, ipProp); + if(nUses == 8 && nPerDay == 1 || nUses == 9 && nPerDay < 4 || + nUses == 10 && nPerDay < 6 || nUses == 11 && nPerDay < 8 || + nUses == 12 && nPerDay < 10) JsonArrayInsertInplace(jTalent, JsonInt(-1), 4); + } + // Lets not always use unlimited items! + else if(nUses == 7 || nUses == 13) + { + if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + } + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell)) return TRUE; + ai_SetLastAction(oCreature, nSpell); + ActionUseItemAtLocation(oItem, ipProp, GetLocation(oTarget), nSubIndex); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + if(AI_DEBUG) ai_Debug("0i_talents", "1934", GetName(oCreature) + " is using " + GetName(oItem) + " at a location."); + return TRUE; + } + if(ai_CheckCombatPosition(oCreature, oTarget, nInMelee, nSpell)) return TRUE; + ai_SetLastAction(oCreature, nSpell); + ActionCastSpellAtLocation(nSpell, GetLocation(oTarget), nMetaMagic, FALSE, 0, FALSE, nClass, FALSE, nDomain); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(AI_DEBUG) ai_Debug("0i_talents", "1943", GetName(oCreature) + " is casting " + sSpellName + " at a location!"); + return TRUE; +} +int ai_CheckSpecialTalentsandUse(object oCreature, json jTalent, string sCategory, int nInMelee, object oTarget) +{ + int nSpell = JsonGetInt(JsonArrayGet(jTalent, 1)); + if(AI_DEBUG) ai_Debug("0i_talents", "1949", "nSpell: " + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))) + + " sCategory: " + sCategory); + if(sCategory == AI_TALENT_DISCRIMINANT_AOE) + { + //ai_Debug("0i_talents", "1953", "CompareLastAction: " + + // IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + //if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + // Check to see if Disjunction should *not* be cast. + if(nSpell == SPELL_MORDENKAINENS_DISJUNCTION) + { + // Our master does not want us using any type of dispel! + if(ai_GetMagicMode(oCreature, AI_MAGIC_STOP_DISPEL)) return FALSE; + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + // Get the biggest group we can. + string sIndex = IntToString(ai_GetHighestMeleeIndexNotInAOE(oCreature)); + oTarget = GetLocalObject(oCreature, AI_ENEMY + sIndex); + if(!ai_CreatureHasDispelableEffect(oCreature, oTarget)) return FALSE; + // Maybe we should do an area of effect instead? + int nEnemies = ai_GetNumOfEnemiesInRange(oTarget, 5.0); + if(nEnemies > 2) + { + if(ai_UseTalentAtLocation(oCreature, jTalent, oTarget, nInMelee)) return TRUE; + } + } + // These spells have a Range of Personal i.e. cast on themselves, and + // an Area of Effect of Colossal (10.0). + else if(nSpell == SPELL_FIRE_STORM || nSpell == SPELL_STORM_OF_VENGEANCE) + { + // Make sure we have enough enemies to use this on. + int nEnemies = ai_GetNumOfEnemiesInRange(oCreature, 10.0); + if(nEnemies < 2) return FALSE; + // Get the nearest target to check defenses on. + oTarget = ai_GetNearestTarget(oCreature, 10.0); + if(!ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + if(ai_UseTalentAtLocation(oCreature, jTalent, oTarget, nInMelee)) return TRUE; + } + else if(nSpell == SPELL_UNDEATH_TO_DEATH) + { + float fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + int nUndead = ai_GetRacialTypeCount(oCreature, RACIAL_TYPE_UNDEAD, fRange); + if(nUndead < 3) return FALSE; + oTarget = ai_GetLowestCRRacialTarget(oCreature, RACIAL_TYPE_UNDEAD, fRange); + } + // Get a target for discriminant spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_CheckForGroupedTargetNotInAOE(oCreature, fRange); + } + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget) || + !ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + } + else if(sCategory == AI_TALENT_INDISCRIMINANT_AOE) + { + //ai_Debug("0i_talents", "1991", "CompareLastAction: " + + // IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + //if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + // These spells have a Range of Personal i.e. cast on themselves, and + // an Area of Effect of Colossal (10.0). + if(nSpell == SPELL_METEOR_SWARM) + { + // Make sure we have enough enemies and few allies to hit. + int nAllies = ai_GetNumOfAlliesInGroup(oCreature, 10.0); + int nEnemies = ai_GetNumOfEnemiesInRange(oCreature, 10.0); + if(nAllies > 1 || nEnemies < 2) return FALSE; + // Get the nearest target to check defenses on. + oTarget = ai_GetNearestTarget(oCreature, 10.0); + if(!ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + if(ai_UseTalentAtLocation(oCreature, jTalent, oCreature, nInMelee)) return TRUE; + } + // Get a target for indiscriminant spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + float fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_CheckForGroupedTargetNotInAOE(oCreature, fRange); + // Check for the number of allies, if there are too many then skip. + if(oTarget == OBJECT_INVALID) return FALSE; + int nRoll = d6() + 1; + if(GetAssociateType(oCreature)) nRoll = d3(); + int nAllies = ai_GetNumOfAlliesInGroup(oTarget, AI_RANGE_CLOSE); + if(AI_DEBUG) ai_Debug("0i_talents", "2084", "Num of Allies in range: " + IntToString(nAllies)+ + " < nRoll: " + IntToString(nRoll)); + if(nAllies >= nRoll) return FALSE; + } + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget) || + !ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + //********************************************************************** + //********** These spells are checked after picking a target *********** + //********************************************************************** + // Check if the Sleep spells are being used appropriately. + if(nSpell == SPELL_SLEEP) + { + if(GetHitDice(oTarget) > 4) return FALSE; + } + // Lets only use silence on casters. + else if(nSpell == SPELL_SILENCE) + { + if(!ai_CheckClassType(oTarget, AI_CLASS_TYPE_CASTER)) + { + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER); + if(oTarget == OBJECT_INVALID) return FALSE; + } + } + } + else if(sCategory == AI_TALENT_RANGED) + { + //ai_Debug("0i_talents", "2045", "CompareLastAction: " + + // IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + //if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + // Check to see if Dispel Magic and similar spells should *not* be cast + if(nSpell == SPELL_DISPEL_MAGIC || nSpell == SPELL_LESSER_DISPEL || + nSpell == SPELL_GREATER_DISPELLING) + { + // Our master does not want us using any type of dispel! + if(ai_GetMagicMode(oCreature, AI_MAGIC_STOP_DISPEL)) return FALSE; + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + // Lets get a caster as they should have more buffs. + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, fRange); + // No caster then get the most powerful enemy! + if(oTarget == OBJECT_INVALID) oTarget = ai_GetHighestCRTarget(oCreature, fRange); + if(oTarget != OBJECT_INVALID) + { + if(!ai_CreatureHasDispelableEffect(oCreature, oTarget)) return FALSE; + // Maybe we should do an area of effect instead? + int nEnemies = ai_GetNumOfEnemiesInRange(oTarget, 5.0); + if(nEnemies > 2) + { + if(ai_UseTalentAtLocation(oCreature, jTalent, oTarget, nInMelee)) return TRUE; + } + } + if(oTarget == OBJECT_INVALID) return FALSE; + } + // Make sure the spell will work on the target. + else if(nSpell == SPELL_HOLD_PERSON || nSpell == SPELL_DOMINATE_PERSON || + nSpell == SPELL_CHARM_PERSON) + { + if(oTarget != OBJECT_INVALID) + { + int nRaceType = GetRacialType(oTarget); + if(AI_DEBUG) ai_Debug("0i_talents", "2075", " Person Spell race: " + IntToString(nRaceType)); + if((nRaceType > 6 && nRaceType < 12) || nRaceType > 15) oTarget = OBJECT_INVALID; + } + if(oTarget == OBJECT_INVALID) + { + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_GetNearestRacialTarget(oCreature, AI_RACIAL_TYPE_HUMANOID, fRange); + if(oTarget == OBJECT_INVALID) return FALSE; + } + } + else if(nSpell == SPELL_HOLD_ANIMAL || nSpell == SPELL_DOMINATE_ANIMAL) + { + if(oTarget != OBJECT_INVALID) + { + if(GetRacialType(oTarget) != RACIAL_TYPE_ANIMAL) oTarget = OBJECT_INVALID; + } + if(oTarget == OBJECT_INVALID) + { + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_GetNearestRacialTarget(oCreature, AI_RACIAL_TYPE_ANIMAL_BEAST, fRange); + if(oTarget == OBJECT_INVALID) return FALSE; + } + } + // Get a target for ranged spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_GetSpellTargetBasedOnSaves(oCreature, nSpell, fRange); + } + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget) || + !ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + //********************************************************************** + //********** These spells are checked after picking a target *********** + //********************************************************************** + // Don't use Domination spells on players! They don't work. + if((nSpell == SPELL_DOMINATE_MONSTER || nSpell == SPELL_DOMINATE_PERSON)) + { + if(ai_GetIsCharacter(oTarget)) return FALSE; + } + // Check to see if they have the shield spell up. + else if(nSpell == SPELL_MAGIC_MISSILE) + { + if(GetHasSpellEffect(SPELL_SHIELD, oTarget)) return FALSE; + } + // Scare only works on 5 hitdice or less. + else if(nSpell == SPELL_SCARE) + { + if(GetHitDice(oTarget) > 5) return FALSE; + } + // Don't use drown against nonliving opponents. + else if(nSpell == SPELL_DROWN) + { + if(ai_IsNonliving(GetRacialType(oTarget))) return FALSE; + } + // Don't use Power Word Kill on Targets with more than 100hp + else if(nSpell == SPELL_POWER_WORD_KILL) + { + if(GetCurrentHitPoints(oTarget) <= 100) return FALSE; + } + } + else if(sCategory == AI_TALENT_TOUCH) + { + //ai_Debug("0i_talents", "2139", "CompareLastAction: " + + // IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + //if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + // Get a target for touch spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + oTarget = ai_GetSpellTargetBasedOnSaves(oCreature, nSpell, AI_RANGE_MELEE); + } + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget) || + !ai_CastOffensiveSpellVsTarget(oCreature, oTarget, nSpell) || + ai_CreatureImmuneToEffect(oCreature, oTarget, nSpell)) return FALSE; + } + else if(sCategory == AI_TALENT_HEALING) + { + int nHpLost = ai_GetPercHPLoss(oTarget); + // If the target is bloody then just use the best we have! + if(nHpLost > AI_HEALTH_BLOODY) + { + // Make sure we should use a mass heal on us or an ally! + // Two allies need healing or one is almost dead to use mass heal! + if(nSpell == SPELL_MASS_HEAL) + { + int bWoundedAlly; + object oAlly = ai_GetNearestAlly(oTarget); + if(oAlly != OBJECT_INVALID) + { + // If we don't have a nearby ally that needs healed then skip. + if(ai_GetPercHPLoss(oAlly) > AI_HEALTH_WOUNDED || + GetDistanceBetween(oCreature, oAlly) > 9.0f) return FALSE; + } + } + // Make sure they have taken enough damage. + int nHpDmg = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + if(!ai_ShouldWeCastThisCureSpell(nSpell, nHpDmg)) return FALSE; + } + } + else if(sCategory == AI_TALENT_ENHANCEMENT) + { + if(AI_DEBUG) ai_Debug("0i_talents", "2713", "CompareLastAction: " + + IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + if(nSpell == SPELL_INVISIBILITY || nSpell == SPELL_SANCTUARY) + { + // Lets not run past an enemy to cast an enhancement unless we have + // the ability to move in combat, bad tactics! + float fRange; + if(ai_CanIMoveInCombat(oCreature)) fRange = AI_RANGE_PERCEPTION; + else + { + fRange = GetDistanceBetween(oCreature, GetLocalObject(oCreature, AI_ENEMY_NEAREST)) - 3.0f; + // Looks bad when your right next to an ally, but technically the enemy is closer. + if(fRange < AI_RANGE_MELEE) fRange = AI_RANGE_MELEE; + } + oTarget = ai_GetAllyToHealTarget(oCreature, fRange); + if(oTarget != OBJECT_INVALID) + { + int nHp = ai_GetPercHPLoss(oTarget); + int nHpLimit = ai_GetHealersHpLimit(oCreature); + if(nHp > nHpLimit) return FALSE; + } + } + if(nSpell == SPELL_PRAYER) + { + int nEnemies = ai_GetNumOfEnemiesInRange(oCreature, 10.0); + int nAllies = ai_GetNumOfAlliesInGroup(oCreature, 10.0); + if(nEnemies + nAllies < 5) return FALSE; + oTarget = oCreature; + } + // Since haste does not have an effect when it comes from items when we + // check for item properties we set this variable so we know they have it. + else if(nSpell == SPELL_HASTE && GetLocalInt(oCreature, sIPHasHasteVarname)) return FALSE; + // Only reason to cast Ultravision(Darkvision) in combat is if a Darkness + // spell is nearby. + else if(nSpell == SPELL_DARKVISION) + { + int nCnt = 1, bCastSpell; + string sAOEType; + object oAOE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCreature, nCnt); + while(oAOE != OBJECT_INVALID && GetDistanceBetween(oCreature, oAOE) <= AI_RANGE_PERCEPTION) + { + // AOE's have the tag set to the "LABEL" in vfx_persistent.2da + sAOEType = GetTag(oAOE); + if(AI_DEBUG) ai_Debug("0i_talents", "2759", "Ultravision check; AOE tag: " + sAOEType); + if(sAOEType == "VFX_PER_DARKNESS") + { + if(!GetHasFeat(FEAT_DARKVISION)) bCastSpell = TRUE; + break; + } + oAOE = GetNearestObject(OBJECT_TYPE_AREA_OF_EFFECT, oCreature, ++nCnt); + } + if(!bCastSpell) return FALSE; + } + // Get a target for enhancement spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + // Get talents range and target. + float fRange = ai_GetSpellRange(nSpell); + // Personal spell + if(fRange == 0.1f) oTarget = oCreature; + // Range/Touch spell + else oTarget = ai_GetAllyBuffTarget(oCreature, nSpell, fRange); + } + if(AI_DEBUG) ai_Debug("0i_talents", "2260", " oTarget: " + GetName(oTarget) + + " HasSpellEffect: " + IntToString(GetHasSpellEffect(nSpell, oTarget))); + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget)) return FALSE; + //********************************************************************** + //********** These spells are checked after picking a target *********** + //********************************************************************** + // Weapon enhancing spells only work on melee weapons! + if(nSpell == SPELL_MAGIC_WEAPON || nSpell == SPELL_GREATER_MAGIC_WEAPON || + nSpell == SPELL_BLESS_WEAPON || nSpell == SPELL_FLAME_WEAPON || + nSpell == SPELL_DARKFIRE) + { + object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + if(!ai_GetIsMeleeWeapon(oWeapon)) return FALSE; + } + // Should we ignore associates? + if(ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + } + else if(sCategory == AI_TALENT_PROTECTION) + { + if(AI_DEBUG) ai_Debug("0i_talents", "2281", "CompareLastAction: " + + IntToString(ai_CompareLastAction(oCreature, nSpell))); + // If we used this spell talent last round then don't use it this round. + if(ai_CompareLastAction(oCreature, nSpell)) return FALSE; + // Stone bones only effects the undead. + if(nSpell == SPELL_STONE_BONES) + { + if(oTarget != OBJECT_INVALID) + { + if(GetRacialType(oTarget) != RACIAL_TYPE_UNDEAD) oTarget = OBJECT_INVALID; + } + if(oTarget == OBJECT_INVALID) + { + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + oTarget = ai_GetNearestRacialTarget(oCreature, RACIAL_TYPE_UNDEAD, fRange); + if(oTarget == OBJECT_INVALID) return FALSE; + } + } + else if(nSpell == SPELL_MAGIC_FANG) + { + oTarget = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCreature); + if(oTarget == OBJECT_INVALID) return FALSE; + } + // Lets see if we should cast resistances in our current situation, + // lets check for enemy casters that may have energy damaging spells, or energy weapons. + else if(nSpell == SPELL_ENDURE_ELEMENTS || nSpell == SPELL_PROTECTION_FROM_ELEMENTS || + nSpell == SPELL_RESIST_ELEMENTS || nSpell == SPELL_ENERGY_BUFFER) + { + int bCastSpell; + object oEnemy = ai_GetEnemyAttackingMe(oCreature); + if(oEnemy != OBJECT_INVALID) + { + object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oEnemy); + if(oWeapon == OBJECT_INVALID) oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oEnemy); + if(oWeapon == OBJECT_INVALID) oWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oEnemy); + if(AI_DEBUG) ai_Debug("0i_talents", "2812", GetName(oEnemy) + " is using weapon: " + GetName(oWeapon)); + if(oWeapon != OBJECT_INVALID) + { + itemproperty nProperty = GetFirstItemProperty(oWeapon); + while(GetIsItemPropertyValid(nProperty)) + { + if(GetItemPropertyType(nProperty) == ITEM_PROPERTY_DAMAGE_BONUS) + { + int nSubType = GetItemPropertySubType(nProperty); + if(AI_DEBUG) ai_Debug("0i_talents", "2821", GetName(oWeapon) + " has PropertySubType: " + + IntToString(nSubType) + " If equals [6,7,9,10,13] don't cast!"); + if(nSubType == 6 || nSubType == 7 || nSubType == 9 || + nSubType == 10 || nSubType == 13) + { + bCastSpell = TRUE; + break; + } + } + nProperty = GetNextItemProperty(oWeapon); + } + } + } + if(ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER) != OBJECT_INVALID) bCastSpell = TRUE; + if(!bCastSpell) return FALSE; + } + // Get a target for protection spells if one is not already set. + if(oTarget == OBJECT_INVALID) + { + // Get talents range and target. + float fRange = ai_GetSpellRange(nSpell); + // Personal spell + if(fRange == 0.1f) oTarget = oCreature; + // Range/Touch spell + else oTarget = ai_GetAllyBuffTarget(oCreature, nSpell, fRange); + } + if(oTarget == OBJECT_INVALID || GetHasSpellEffect(nSpell, oTarget)) return FALSE; + //********************************************************************** + //********** These spells are checked after picking a target *********** + //********************************************************************** + // Don't double up Stoneskin, Ghostly visage, or Ethereal visage. + if(nSpell == SPELL_GHOSTLY_VISAGE || nSpell == SPELL_ETHEREAL_VISAGE || + nSpell == SPELL_STONESKIN) + { + if(GetHasSpellEffect(SPELL_ETHEREAL_VISAGE, oTarget) || + GetHasSpellEffect(SPELL_STONESKIN, oTarget) || + GetHasSpellEffect(SPELL_GHOSTLY_VISAGE, oTarget)) return FALSE; + } + // Don't use displacement if we are invisible! + else if(nSpell == SPELL_DISPLACEMENT) + { + if(GetHasSpellEffect(SPELL_INVISIBILITY, oTarget) || + GetHasSpellEffect(SPELL_IMPROVED_INVISIBILITY, oTarget) || + GetHasSpellEffect(SPELL_INVISIBILITY_SPHERE, oTarget) || + GetHasSpellEffect(SPELL_DISPLACEMENT, oTarget)) return FALSE; + } + // Should we ignore associates? + if(ai_GetAIMode(oCreature, AI_MODE_IGNORE_ASSOCIATES) && + GetAssociateType(oTarget) > 1) return FALSE; + } + else if(sCategory == AI_TALENT_SUMMON) + { + if(GetAssociate(ASSOCIATE_TYPE_SUMMONED, oCreature) != OBJECT_INVALID) return FALSE; + if(oTarget == OBJECT_INVALID) + { + /* Removed for now, summons creature in location that enemy was... looks bad. + float fRange; + if(nInMelee) fRange = AI_RANGE_MELEE; + else fRange = ai_GetOffensiveSpellSearchRange(oCreature, nSpell); + // Select lowest enemy combat target for summons. + oTarget = ai_GetLowestCRTarget(oCreature, fRange); + if(oTarget == OBJECT_INVALID) oTarget = oCreature; + */ + oTarget = oCreature; + if(ai_UseTalentAtLocation(oCreature, jTalent, oTarget, nInMelee)) + { + DelayCommand(4.0, ai_NameAssociate(oCreature, ASSOCIATE_TYPE_SUMMONED, "")); + return TRUE; + } + } + } + else if(sCategory == AI_TALENT_CURE) + { + } + if(ai_UseTalentOnObject(oCreature, jTalent, oTarget, nInMelee)) return TRUE; + return FALSE; +} diff --git a/src/module/nss/0i_time.nss b/src/module/nss/0i_time.nss new file mode 100644 index 0000000..3052ea6 --- /dev/null +++ b/src/module/nss/0i_time.nss @@ -0,0 +1,95 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_time +//////////////////////////////////////////////////////////////////////////////// + Include script for handling all time functions for the server. + + Lokey's functions: +int GetPosixTimestamp(); +string GetCurrentDateTime(); + +*/////////////////////////////////////////////////////////////////////////////// +// RETURNS a Timestamp in seconds since 1970-01-01. +int GetCurrentTimeInSeconds(); +// RETURNS a formated date, good for timestamping logs and text. +string GetCurrentDateTime(); +// Sends a server shutdown message 1800 seconds i.e 30 minutes before. +// nDuration is in seconds. i.e. one hours is 3600 defaults to 24 hours (86400). +// Should be put into the servers OnHeartBeat. +void CheckServerShutdownMessage(int nDuration = 86400); + +int GetCurrentTimeInSeconds() +{ + string stmt = "SELECT strftime('%s','now');"; + sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt); + SqlStep(sqlQuery); + return SqlGetInt(sqlQuery, 0); +} +string GetCurrentDateTime() +{ + string stmt = "SELECT datetime('now', 'localtime')"; + sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt); + SqlStep(sqlQuery); + return SqlGetString(sqlQuery, 0); +} +/// @addtogroup time Time +/// @brief Provides various time related functions. +/// @brief Returns the current time formatted according to the provided sqlite date time format string. +/// @param format Format string as used by sqlites STRFTIME(). +/// @return The current time in the requested format. Empty string on error. +string SQLite_GetFormattedSystemTime(string format); +/// @return Returns the number of seconds since midnight on January 1, 1970. +int SQLite_GetTimeStamp(); +/// @return Returns the number of milliseconds since midnight on January 1, 1970. +int SQLite_GetTimeMilliseconds(); +/// @brief A millisecond timestamp +struct SQLite_MillisecondTimeStamp +{ + int seconds; ///< Seconds since epoch + int milliseconds; ///< Milliseconds +}; +/// @remark For mircosecond timestamps use NWNX_Utility_GetHighResTimeStamp(). +/// @return Returns the number of milliseconds since midnight on January 1, 1970. +struct SQLite_MillisecondTimeStamp SQLite_GetMillisecondTimeStamp(); +/// @brief Returns the current date. +/// @return The date in the format (mm/dd/yyyy). +string SQLite_GetSystemDate(); +/// @brief Returns current time. +/// @return The current time in the format (24:mm:ss). +string SQLite_GetSystemTime(); +/// @} +string SQLite_GetFormattedSystemTime(string format) +{ + sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME(@format, 'now', 'localtime')"); + SqlBindString(query, "@format", format); + SqlStep(query); // sqlite returns NULL for invalid format in STRFTIME() + return SqlGetString(query, 0); +} +int SQLite_GetTimeStamp() +{ + sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME('%s', 'now')"); + SqlStep(query); + return SqlGetInt(query, 0); +} +int SQLite_GetTimeMillisecond() +{ + sqlquery query = SqlPrepareQueryObject(GetModule(), "select cast((julianday('now') - 2440587.5) * 86400 * 1000 as integer)"); + SqlStep(query); + return SqlGetInt(query, 0); +} +struct SQLite_MillisecondTimeStamp SQLite_GetMillisecondTimeStamp() +{ + sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME('%s', 'now'), SUBSTR(STRFTIME('%f', 'now'), 4)"); + SqlStep(query); + struct SQLite_MillisecondTimeStamp t; + t.seconds = SqlGetInt(query, 0); + t.milliseconds = SqlGetInt(query, 1); + return t; +} +string SQLite_GetSystemDate() +{ + return SQLite_GetFormattedSystemTime("%m/%d/%Y"); +} +string SQLite_GetSystemTime() +{ + return SQLite_GetFormattedSystemTime("%H:%M:%S"); +} diff --git a/src/module/nss/ai_a_ambusher.nss b/src/module/nss/ai_a_ambusher.nss new file mode 100644 index 0000000..f3f424b --- /dev/null +++ b/src/module/nss/ai_a_ambusher.nss @@ -0,0 +1,105 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_ambusher +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to ambush creatures by hiding or turning invisible. + OBJECT_SELF is the creature running the ai. + * This assumes we are not invisible since the ai_a_invisible script should fire if we are. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "19", GetName(oCreature) + " is using ambusher tactics: " + + " oNearestEnemy: " + GetName(oNearestEnemy) + " fDistance: " + + FloatToString(GetDistanceBetween(oNearestEnemy, oCreature), 0, 2)); + if(GetDistanceBetween(oNearestEnemy, oCreature) > AI_RANGE_CLOSE) + { + // Has our master told us to not use magic? + if(!ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) + { + // If can turn invisible then we should probably do that! + if(ai_UseTalent(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY_SPHERE, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_SANCTUARY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_ETHEREALNESS, oCreature)) return; // Greater Sanctuary + if(ai_UseTalent(oCreature, SPELLABILITY_AS_IMPROVED_INVISIBLITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELLABILITY_AS_INVISIBILITY, oCreature)) return; + } + } + // Check the battle field to see if anyone see us? + int nEnemyIndex = ai_GetNearestIndexThatSeesUs(oCreature); + // If seen, can we try to hide now? + if(nEnemyIndex) + { + // Check for an attacker and can they see through invisibility? + object oAttacker = ai_GetEnemyAttackingMe(oCreature); + int bCanSeeInvisible; + if(oAttacker != OBJECT_INVALID) + { + bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_SEEINVISIBLE); + if(!bCanSeeInvisible) bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_TRUESEEING); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_5_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_10_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_60_FEET, oCreature); + } + if(!bCanSeeInvisible) + { + if(GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature)) + { + if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "55", GetName(oCreature) + " is using hide in plain sight!"); + ClearAllActions(TRUE); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + return; + } + } + // Does not have hide in plain sight. + else + { + string sEnemyIndex = IntToString(nEnemyIndex); + float fEnemyDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sEnemyIndex); + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "66", "fDistance: " + FloatToString(fEnemyDistance, 0, 2)); + if(fEnemyDistance > 20.0) + { + int bTried = GetLocalInt(oCreature, AI_TRIED_TO_HIDE); + if(!bTried) + { + // Move away so we can hide. + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "73", GetName(oCreature) + " is trying to move away to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + object oEnemy = GetLocalObject(oCreature, AI_ENEMY + sEnemyIndex); + ActionMoveAwayFromObject(oEnemy, TRUE, AI_RANGE_BATTLEFIELD); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + else SetLocalInt(oCreature, AI_TRIED_TO_HIDE, GetLocalInt(oCreature, AI_TRIED_TO_HIDE) - 1); + } + // We have been seen by an enemy near us so drop stealth. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + } + // The enemy can see through stealth so lets drop it. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + // We are not in stealth mode so and no one sees us so lets hide. + else if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + // Use any hiding talents we have + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "97", GetName(oCreature) + " is trying to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + // If we have givin up on stealth do our normal actions. + string sScript = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + if(sScript == "ai_a_ambusher" || sScript == "") sScript = "ai_a_default"; + if(AI_DEBUG) ai_Debug("ai_a_ambusher", "101", "Executing Script: " + sScript); + ExecuteScript(sScript, oCreature); +} diff --git a/src/module/nss/ai_a_atk_casters.nss b/src/module/nss/ai_a_atk_casters.nss new file mode 100644 index 0000000..362ba4b --- /dev/null +++ b/src/module/nss/ai_a_atk_casters.nss @@ -0,0 +1,159 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_atk_casters +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to the nearest casting creatures. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy. + 2 - Check for healing and curing first. + 3 - Check moral if wounded and this is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff or summons if this is a difficult+ battle. + 6 - Check for a Class ability and an offensive spell if this is a simple+ battle. + 7 - Check for a physical attack. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + int bAlwaysAtk = !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK); + if(AI_DEBUG) ai_Debug("ai_a_atk_casters", "80", "Check for ranged attack on nearest casting enemy!"); + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the nearest targets first. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("ai_a_atk_casters", "119", "Check for melee attack on nearest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) + { + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget == OBJECT_INVALID) + { + // Are we in melee? If so try to get the nearest enemy in melee. + if(nInMelee > 0) + { + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk); + // If we didn't get a target then get any target within range. + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk); + } + // If not then lets go find someone to attack! + else + { + // Get the nearest enemy. + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk); + // If we didn't get a target then get any target within range. + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk); + } + } + } + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("ai_a_atk_casters", "149", GetName(oTarget) + " is the nearest target for melee combat!"); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + if(AI_DEBUG) ai_Debug("ai_a_atk_casters", "154", "Do melee attack against (caster/nearest): " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} + diff --git a/src/module/nss/ai_a_atk_nearest.nss b/src/module/nss/ai_a_atk_nearest.nss new file mode 100644 index 0000000..1261dc7 --- /dev/null +++ b/src/module/nss/ai_a_atk_nearest.nss @@ -0,0 +1,80 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_atk_nearest +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to the nearest target. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy. + 2 - Check for healing and curing first. + 3 - Check moral if wounded and this is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff or summons if this is a difficult+ battle. + 6 - Check for a Class ability and an offensive spell if this is a simple+ battle. + 7 - Check for a physical attack. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + ai_DoPhysicalAttackOnNearest(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); +} + diff --git a/src/module/nss/ai_a_atk_warrior.nss b/src/module/nss/ai_a_atk_warrior.nss new file mode 100644 index 0000000..4821e53 --- /dev/null +++ b/src/module/nss/ai_a_atk_warrior.nss @@ -0,0 +1,159 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_atk_warrior +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to the nearest casting creatures. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy. + 2 - Check for healing and curing first. + 3 - Check moral if wounded and this is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff or summons if this is a difficult+ battle. + 6 - Check for a Class ability and an offensive spell if this is a simple+ battle. + 7 - Check for a physical attack. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + int bAlwaysAtk = !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK); + if(AI_DEBUG) ai_Debug("0i_actions", "496", "Check for ranged attack on nearest casting enemy!"); + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the nearest targets first. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("ai_a_atk_warrior", "119", "Check for melee attack on nearest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) + { + object oPCTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + if(oPCTarget == OBJECT_INVALID) + { + // Are we in melee? If so try to get the nearest enemy in melee. + if(nInMelee > 0) + { + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk); + // If we didn't get a target then get any target within range. + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk); + } + // If not then lets go find someone to attack! + else + { + // Get the nearest enemy. + oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk); + // If we didn't get a target then get any target within range. + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk); + } + } + } + // We might not have a target this is fine as sometimes we don't want to attack! + if(AI_DEBUG) ai_Debug("ai_a_atk_warrior", "149", GetName(oTarget) + " is the nearest target for melee combat!"); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + if(AI_DEBUG) ai_Debug("ai_a_atk_warrior", "154", "Do melee attack against (caster/nearest): " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} + diff --git a/src/module/nss/ai_a_barbarian.nss b/src/module/nss/ai_a_barbarian.nss new file mode 100644 index 0000000..12521c9 --- /dev/null +++ b/src/module/nss/ai_a_barbarian.nss @@ -0,0 +1,87 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_barbarian +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Barbarian class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oTarget; + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature)) + { + //************************* HEALING & CURES ************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // ************************ CLASS FEATURES ************************* + if(ai_TryBarbarianRageFeat(oCreature)) return; + // ************************* SPELL TALENTS ************************* + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************* SPELL TALENTS ************************* + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ Ranged feat attacks ************************ + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + } + // *************************** Melee feat attacks ************************** + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_bard.nss b/src/module/nss/ai_a_bard.nss new file mode 100644 index 0000000..975bac2 --- /dev/null +++ b/src/module/nss/ai_a_bard.nss @@ -0,0 +1,83 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_bard +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Bard class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryBardSongFeat(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = OBJECT_INVALID; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_cleric.nss b/src/module/nss/ai_a_cleric.nss new file mode 100644 index 0000000..5de1cc2 --- /dev/null +++ b/src/module/nss/ai_a_cleric.nss @@ -0,0 +1,102 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_cleric +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Cleric class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ************************** CLASS FEATURES *************************** + // Turning is basically a powerful AOE so treat it like one. + if(ai_TryTurningTalent(oCreature)) return; + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + } + // SIMPLE+ - Offensive talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = OBJECT_INVALID; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_cntrspell.nss b/src/module/nss/ai_a_cntrspell.nss new file mode 100644 index 0000000..a1bc9ec --- /dev/null +++ b/src/module/nss/ai_a_cntrspell.nss @@ -0,0 +1,69 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_cntrspell +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the combat mode counter spell. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + // We are not in melee combat then we don't attack. + int bAttack = nInMelee; + if(!bAttack) + { + // If there are no casters, i.e. CLERIC or MAGES in the battle then attack. + struct stClasses stClasses = ai_GetFactionsClasses(oCreature); + if(!stClasses.CLERICS && !stClasses.MAGES) bAttack = TRUE; + } + // If we are not attacking and using magic then setup for counter spelling. + if(!bAttack && !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC)) + { + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + if(AI_DEBUG) ai_Debug("ai_a_cntrspell", "30", " Counterspell Mode? " + + IntToString(GetActionMode(OBJECT_SELF, ACTION_MODE_COUNTERSPELL))); + if(!GetActionMode(oCreature, ACTION_MODE_COUNTERSPELL)) + { + object oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER); + // We can only counter spells from a hasted caster if we are hasted as well. + if(ai_GetHasEffectType(oTarget, EFFECT_TYPE_HASTE) && + !ai_GetHasEffectType(oCreature, EFFECT_TYPE_HASTE)) + { + // If we have haste then we should cast it. + if(GetHasSpell(SPELL_HASTE, oCreature)) + { + if(AI_DEBUG) ai_Debug("ai_a_cntrspell", "42", "Opponent is hasted! Casting Haste."); + ActionCastSpellAtObject(SPELL_HASTE, oCreature); + ai_SetLastAction(oCreature, SPELL_HASTE); + return; + } + // If not then we need to go into normal combat. + else + { + if(AI_DEBUG) ai_Debug("ai_cntrspell", "50", "Opponent is hasted! Using ranged AI."); + ExecuteScript("ai_a_ranged"); + return; + } + } + if(oTarget != OBJECT_INVALID) + { + // First a good tactic for counter spelling is to be invisible. + if(ai_TryToBecomeInvisible(oCreature)) return; + // If we have attempted to become invisible or are invisible then + // it is time to counter spell. + if(AI_DEBUG) ai_Debug("ai_a_cntrspell", "61", "Setting Counterspell mode!"); + ActionCounterSpell(oTarget); + return; + } + } + } + if(AI_DEBUG) ai_Debug("ai_a_cntrspell", "67", "Situation is not good for counterspelling! Using ranged AI."); + ExecuteScript("ai_a_ranged"); +} diff --git a/src/module/nss/ai_a_default.nss b/src/module/nss/ai_a_default.nss new file mode 100644 index 0000000..7540340 --- /dev/null +++ b/src/module/nss/ai_a_default.nss @@ -0,0 +1,80 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_no_modes +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to not use any combat modes during combat ai. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy. + 2 - Check for healing and curing first. + 3 - Check moral if wounded and this is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff or summons if this is a difficult+ battle. + 6 - Check for a Class ability and an offensive spell if this is a simple+ battle. + 7 - Check for a physical attack. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + ai_DoPhysicalAttackOnBest(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); +} + diff --git a/src/module/nss/ai_a_defensive.nss b/src/module/nss/ai_a_defensive.nss new file mode 100644 index 0000000..f19523c --- /dev/null +++ b/src/module/nss/ai_a_defensive.nss @@ -0,0 +1,77 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_defensive +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates put in to a defensive mode to protect themselves. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy and the difficulty of the battle. + 2 - Check for healing potions if this is a simple+ battle. + 3 - Check moral if wounded and is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff if this is a difficult+ battle. + 6 - Check for defensive ability such as knockdown, expertise or parry. + 7 - If we can't fight defensive then flee. + 8 - If we are out of range with no ability then stand and watch. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(AI_DEBUG) ai_Debug("ai_a_defensive", "25", "oNearest Enemy: " + GetName(oNearestEnemy) + + " Distance to Nearest Enemy: " + FloatToString(GetDistanceToObject(oNearestEnemy), 0, 2)); + // ALWAYS - Check for healing and cure talents. + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // SIMPLE+ - Check for moral and get what spell power we should be using. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // DIFFICULT+ - Class talents, Offensive AOE's, Defensive talents, and Potion talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS **************** + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if (ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound, oTarget)) return; + } + } + object oTarget; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + if(nInMelee > 0) + { + if(ai_TryImprovedExpertiseFeat(oCreature)) return; + if(ai_TryExpertiseFeat(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy; + // Use knockdown when appropriate and the target is not immune. + if(ai_TryKnockdownFeat(oCreature, oTarget)) return; + if (ai_TryParry (oCreature)) return; + // We have tried everything to protect ourselves so the only thing left + // to do is man up and attack! + ai_DoPhysicalAttackOnLowestCR(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + return; + } + //********************** PHYSICAL ATTACKS ******************************** + // Even in defensive mode we want to be in battle so go find someone! + ai_DoPhysicalAttackOnBest(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); +} diff --git a/src/module/nss/ai_a_druid.nss b/src/module/nss/ai_a_druid.nss new file mode 100644 index 0000000..6b82c26 --- /dev/null +++ b/src/module/nss/ai_a_druid.nss @@ -0,0 +1,86 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_druid +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Druid class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // ************************** CLASS FEATURES *************************** + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TryPolymorphSelfFeat(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************** Ranged feat attacks ************************** + object oTarget; + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_fighter.nss b/src/module/nss/ai_a_fighter.nss new file mode 100644 index 0000000..a5f3720 --- /dev/null +++ b/src/module/nss/ai_a_fighter.nss @@ -0,0 +1,82 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: 0i_a_fighter +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Fighter class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = OBJECT_INVALID; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_flanker.nss b/src/module/nss/ai_a_flanker.nss new file mode 100644 index 0000000..fb6845a --- /dev/null +++ b/src/module/nss/ai_a_flanker.nss @@ -0,0 +1,117 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_flanker +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to flank the enemy and not charge into combat. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + oTarget = GetLocalObject(oCreature, AI_PC_LOCKED_TARGET); + // ************************** Melee feat attacks ************************* + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + // Lets get the nearest target that is attacking someone besides me. We want to flank! + if(oTarget == OBJECT_INVALID) + { + if(!nInMelee) oTarget = ai_GetFlankTarget(oCreature); + // If there are few enemies then we can safely move around. + else if(nInMelee < 3 || ai_CanIMoveInCombat(oCreature)) + { + oTarget = ai_GetFlankTarget(oCreature, AI_RANGE_MELEE); + } + // Ok we are in a serious fight so lets not give attack of opportunities. + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + } + // If there are no enemies being attacked then lets stay back. + if(oTarget == OBJECT_INVALID) + { + if(nInMelee) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + object oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + } + // ************************** Ranged feat attacks ************************** + else if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + oTarget = ai_GetLowestCRTarget(oCreature); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + else + { + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + } + if(oTarget != OBJECT_INVALID) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + // Are we too far from our master? + object oMaster = GetMaster(); + if(GetDistanceBetween(oMaster, oCreature) > AI_RANGE_LONG) + { + ActionMoveToObject(oMaster, TRUE, AI_RANGE_CLOSE); + return; + } + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); +} diff --git a/src/module/nss/ai_a_invisible.nss b/src/module/nss/ai_a_invisible.nss new file mode 100644 index 0000000..9772b32 --- /dev/null +++ b/src/module/nss/ai_a_invisible.nss @@ -0,0 +1,123 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_invisible +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to use when they are invisible. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + // Has our master told us to not use magic? + int bUseMagic = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_EASY) + { + // *************************** SPELL TALENTS *************************** + if(ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) return; + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound, oTarget)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Melee feat attacks ************************* + // If we won't loose invisibility then ranged attacks are ok! + // ************************ RANGED ATTACKS ******************************* + if(GetHasSpellEffect(SPELL_IMPROVED_INVISIBILITY) || GetHasSpellEffect(SPELLABILITY_AS_IMPROVED_INVISIBLITY)) + { + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + } + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + talent tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_MELEE, 20, oCreature); + if(GetIsTalentValid(tUse)) + { + int nId = GetIdFromTalent(tUse); + if(nId == FEAT_POWER_ATTACK) { if(ai_TryPowerAttackFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_KNOCKDOWN) { if(ai_TryKnockdownFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SMITE_EVIL) { if(ai_TrySmiteEvilFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SMITE_GOOD) { if(ai_TrySmiteGoodFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_IMPROVED_POWER_ATTACK) { if(ai_TryImprovedPowerAttackFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_FLURRY_OF_BLOWS) { if(ai_TryFlurryOfBlowsFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_STUNNING_FIST) { if(ai_TryStunningFistFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SAP) { if(ai_TrySapFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_DISARM) { if(ai_TryDisarmFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_KI_DAMAGE) { if(ai_TryKiDamageFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_CALLED_SHOT) { if(ai_TryCalledShotFeat(oCreature, oTarget)) return; } + } + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} + diff --git a/src/module/nss/ai_a_monk.nss b/src/module/nss/ai_a_monk.nss new file mode 100644 index 0000000..607ce4c --- /dev/null +++ b/src/module/nss/ai_a_monk.nss @@ -0,0 +1,82 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_monk +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Monk class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryWholenessOfBodyFeat(oCreature)) return; + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_no_cmb_mode.nss b/src/module/nss/ai_a_no_cmb_mode.nss new file mode 100644 index 0000000..1ffedb4 --- /dev/null +++ b/src/module/nss/ai_a_no_cmb_mode.nss @@ -0,0 +1,131 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_o_cmb_modes +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to not use any combat modes during combat ai. + OBJECT_SELF is the creature running the ai. + Our actions. + 1 - Get nearest enemy. + 2 - Check for healing and curing first. + 3 - Check moral if wounded and this is a simple+ battle. + 4 - Check for a magical ranged attack if not in melee and a difficult+ battle. + 5 - Check for a buff or summons if this is a difficult+ battle. + 6 - Check for a Class ability and an offensive spell if this is a simple+ battle. + 7 - Check for a physical attack. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + if(AI_DEBUG) ai_Debug("ai_a_no_modes", "78", "Check for ranged attack on weakest enemy!"); + object oTarget; + int bAlwaysAtk = !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK); + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + !ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && + ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the weaker targets. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + if(AI_DEBUG) ai_Debug("ai_a_no_modes", "105", GetName(OBJECT_SELF) + " does ranged attack on weakest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + if(AI_DEBUG) ai_Debug("ai_a_no_modes", "117", "Check for melee attack on weakest enemy!"); + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee, bAlwaysAtk)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, bAlwaysAtk); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee, bAlwaysAtk); + if(oTarget != OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("ai_a_no_modes", "126", GetName(OBJECT_SELF) + " does melee attack against weakest: " + GetName(oTarget) + "!"); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} + diff --git a/src/module/nss/ai_a_paladin.nss b/src/module/nss/ai_a_paladin.nss new file mode 100644 index 0000000..24520a7 --- /dev/null +++ b/src/module/nss/ai_a_paladin.nss @@ -0,0 +1,110 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_paladin +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Paladin class. + Paladins always protect their masters and face the strongest opponents first! + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + } + if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING)) + { + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + // Does our master want to be buffed first? + object oTarget = OBJECT_INVALID; + if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, 0, oTarget)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + } + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + if(ai_TryLayOnHands(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = OBJECT_INVALID; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Paladins ALWAYS protect their masters first! + oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Paladins face off against the strongest opponents first. + if(!nInMelee) oTarget = ai_GetHighestCRTarget(oCreature); + else oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + // Paladins ALWAYS protect their masters first! + oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + int bCheckCombat = ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK); + if(bCheckCombat) oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee, FALSE); + // If always attacking Paladins ALWAYS attack the strongest opponent. + else oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_peaceful.nss b/src/module/nss/ai_a_peaceful.nss new file mode 100644 index 0000000..b9bd310 --- /dev/null +++ b/src/module/nss/ai_a_peaceful.nss @@ -0,0 +1,81 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_a_peaceful +//////////////////////////////////////////////////////////////////////////////// + ai script mode for associates to use when they should remain out of combat. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + float fDistance = GetDistanceBetween(oCreature, oNearestEnemy); + // In Melee combat! + if(nInMelee > 0) + { + // If we are not being attacked then we should back out of combat. + if(ai_GetEnemyAttackingMe(oCreature) == OBJECT_INVALID) + { + if(AI_DEBUG) ai_Debug("ai_a_peaceful", "23", GetName(oCreature) + " is moving away from " + GetName(oNearestEnemy) + + "[" + FloatToString(AI_RANGE_MELEE - fDistance + 1.0, 0, 2) + "]" + " to use a ranged weapon."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + // Lets move just out of melee range! + int bRun = ai_CanIMoveInCombat(oCreature); + ActionMoveAwayFromObject(oNearestEnemy, bRun, AI_RANGE_CLOSE + 2.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return; + } + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryImprovedExpertiseFeat(oCreature)) return; + if(ai_TryExpertiseFeat(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + object oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy; + // Use knockdown when appropriate and the target is not immune. + if(ai_TryKnockdownFeat(oCreature, oTarget)) return; + if (ai_TryParry(oCreature)) return; + // We have tried everything to protect ourselves so the only thing left + // to do is man up and attack! + // Physical attacks are under TALENT_CATEGORY_HARMFUL_MELEE(22). + ai_DoPhysicalAttackOnNearest(oCreature, nInMelee); + return; + } + if(fDistance <= AI_RANGE_LONG) + { + if(AI_DEBUG) ai_Debug("ai_a_peaceful", "49", GetName(oCreature) + " is moving away from " + GetName(oNearestEnemy) + + "[" + FloatToString(AI_RANGE_LONG - fDistance, 0, 2) + "]" + "."); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MOVE); + // Lets move out of close range! + ActionMoveAwayFromObject(oNearestEnemy, TRUE, AI_RANGE_LONG + 2.0); + ActionDoCommand(ExecuteScript("0e_do_combat_rnd", oCreature)); + return; + } + //************************* OUT OF COMBAT ************************** + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, 0, oCreature)) return; + if(ai_TryCureConditionTalent(oCreature, 0)) return; + //************************** DEFENSIVE TALENTS *************************** + // Has our master told us to not use magic? + int bUseMagic = !ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC); + if(bUseMagic) + { + // If can turn invisible then we should probably do that! + if(ai_UseTalent(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY_SPHERE, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_SANCTUARY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_ETHEREALNESS, oCreature)) return; // Greater Sanctuary + if(ai_UseTalent(oCreature, SPELLABILITY_AS_IMPROVED_INVISIBLITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELLABILITY_AS_INVISIBILITY, oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + // Summons are powerfull and should be used as much as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_SUMMON, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_PROTECTION, nInMelee, nMaxLevel)) return; + } + // Stand and watch the battle we don't want to provoke anyone! + if(AI_DEBUG) ai_Debug("ai_a_peaceful", "80", GetName(oCreature) + " is holding here."); +} diff --git a/src/module/nss/ai_a_polymorphed.nss b/src/module/nss/ai_a_polymorphed.nss new file mode 100644 index 0000000..107e6e9 --- /dev/null +++ b/src/module/nss/ai_a_polymorphed.nss @@ -0,0 +1,70 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_polymorphed +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for polymorphed associates. + We check for abilities based on the form we are using and if we should polymorph back. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void ai_DoActions(object oCreature, int nForm) +{ + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(GetPercentageHPLoss(oCreature) <= AI_HEALTH_BLOODY) + { + //ai_Debug("ai_a_polymorphed", "24", "We are wounded and are transforming back!"); + ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH); + return; + } + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // When polymorphed we turn back then check moral. + //if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, FALSE); +} +void main() +{ + object oCreature = OBJECT_SELF; + // Need to know who we are so we can use thier abilities. + int nForm = GetAppearanceType(oCreature); + // Check to see if we are back to our normal form?(-1 to get the actual form #) + if(nForm == GetLocalInt(oCreature, AI_NORMAL_FORM) - 1) + { + // If we are transformed back then go back to our primary ai. + ai_SetCreatureAIScript(oCreature); + DeleteLocalInt(oCreature, AI_NORMAL_FORM); + string sAI = GetLocalString(oCreature, AI_COMBAT_SCRIPT); + if(sAI == "ai_a_polymorphed" || sAI == "") sAI = "ai_a_default"; + ExecuteScript(sAI, oCreature); + } + else ai_DoActions(oCreature, nForm); +} diff --git a/src/module/nss/ai_a_ranged.nss b/src/module/nss/ai_a_ranged.nss new file mode 100644 index 0000000..477937d --- /dev/null +++ b/src/module/nss/ai_a_ranged.nss @@ -0,0 +1,129 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_ranged +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates to use the ranged ai. + OBJECT_SELF is the creature running the ai. + Will attempt to use ranged weapons until surrounded. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + // Turning is basically a powerful AOE so treat it like one. + if(ai_TryTurningTalent(oCreature)) return; + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED)) + { + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + nInMelee < 3) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Lets defend master, nearest favored enemy, ranged, sneak, weakest targets. + if(!nInMelee) + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget == ai_GetRangedTarget(oCreature); + if(oTarget == OBJECT_INVALID && ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + } + // ************************** Melee feat attacks ************************* + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(nInMelee) + { + oTarget = ai_GetEnemyAttackingMe(oCreature); + if(oTarget != OBJECT_INVALID) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + } + } + if(oNearestEnemy != OBJECT_INVALID) + { + float fDistance = GetDistanceBetween(oCreature, oNearestEnemy); + float fRange = AI_RANGE_LONG; + if(GetIsAreaInterior(GetArea(oCreature))) fRange = AI_RANGE_CLOSE; + if(GetHasFeat(FEAT_SNEAK_ATTACK, oCreature)) fRange = AI_RANGE_CLOSE; + if(fDistance < fRange) + { + int bRun = ai_CanIMoveInCombat(oCreature); + ActionMoveAwayFromObject(oNearestEnemy, bRun, fRange - fDistance + 2.0); + } + } + else ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); +} + diff --git a/src/module/nss/ai_a_ranger.nss b/src/module/nss/ai_a_ranger.nss new file mode 100644 index 0000000..179298f --- /dev/null +++ b/src/module/nss/ai_a_ranger.nss @@ -0,0 +1,96 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_ranger +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Ranger class. + Rangers will take out favored enemies first! + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) + { + oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature); + } + else + { + oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + // Our master may have setup to check difficulty before we move into melee. + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_PERCEPTION, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_rogue.nss b/src/module/nss/ai_a_rogue.nss new file mode 100644 index 0000000..10e1ae0 --- /dev/null +++ b/src/module/nss/ai_a_rogue.nss @@ -0,0 +1,83 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_rogue +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Rogue class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_sorcerer.nss b/src/module/nss/ai_a_sorcerer.nss new file mode 100644 index 0000000..5e4a3b7 --- /dev/null +++ b/src/module/nss/ai_a_sorcerer.nss @@ -0,0 +1,75 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_sorcerer +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Sorcerer class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_a_taunter.nss b/src/module/nss/ai_a_taunter.nss new file mode 100644 index 0000000..b06fed8 --- /dev/null +++ b/src/module/nss/ai_a_taunter.nss @@ -0,0 +1,53 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_a_taunter +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using defined to use the taunt skill. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Class and Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + // ************************** CLASS FEATURES *************************** + if(ai_TryTurningTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // Taunt the nearest target! + if (ai_TryTaunt (oCreature, ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee))) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + ai_DoPhysicalAttackOnLowestCR(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); +} diff --git a/src/module/nss/ai_a_wizard.nss b/src/module/nss/ai_a_wizard.nss new file mode 100644 index 0000000..dfad8c3 --- /dev/null +++ b/src/module/nss/ai_a_wizard.nss @@ -0,0 +1,77 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_a_wizard +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for associates using the Wizard class. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + int nDifficulty = ai_GetDifficulty(oCreature); + int nMaxLevel; + // Check for moral and get the maximum spell level we should use. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(nInMelee && ai_MoralCheck(oCreature)) return; + nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty); + } + // Skill, Class, Offensive AOE's, and Defensive talents. + if(nDifficulty >= AI_COMBAT_MODERATE) + { + // ************************** CLASS FEATURES *************************** + if(ai_TrySummonFamiliarTalent(oCreature)) return; + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + } + // Offensive single target talents. + if(nDifficulty >= AI_COMBAT_EFFORTLESS) + { + if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING)) + { + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + } + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Are we suppose to protect our master first? + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) + { + // Lets pick off the weakest targets. + if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature); + else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetBestTargetForMeleeCombat(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK)); + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, FALSE); +} diff --git a/src/module/nss/ai_ambusher.nss b/src/module/nss/ai_ambusher.nss new file mode 100644 index 0000000..829a3da --- /dev/null +++ b/src/module/nss/ai_ambusher.nss @@ -0,0 +1,100 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_ambusher +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for ambushing creatures (Any). + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + // Rule used to disable ambush if the player wants to. + if(!GetLocalInt(GetModule(), AI_RULE_AMBUSH)) + { + ExecuteScript("ai_default", oCreature); + return; + } + // If can turn invisible then we should probably do that! + if(ai_UseTalent(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY_SPHERE, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_SANCTUARY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_ETHEREALNESS, oCreature)) return; // Greater Sanctuary + if(ai_UseTalent(oCreature, SPELLABILITY_AS_IMPROVED_INVISIBLITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELLABILITY_AS_INVISIBILITY, oCreature)) return; + // Check the battle field to see if anyone see us? + int nEnemyIndex = ai_GetNearestIndexThatSeesUs(oCreature); + // If seen, can we try to hide now? + if(nEnemyIndex) + { + // Check for an attacker and can they see through invisibility? + object oAttacker = ai_GetEnemyAttackingMe(oCreature); + int bCanSeeInvisible; + if(oAttacker != OBJECT_INVALID) + { + bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_SEEINVISIBLE); + if(!bCanSeeInvisible) bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_TRUESEEING); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_5_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_10_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_60_FEET, oCreature); + } + if(AI_DEBUG) ai_Debug("ai_ambusher", "43", "bCanSeeInvisible: " + IntToString(bCanSeeInvisible)); + if(!bCanSeeInvisible) + { + if(GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature)) + { + if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + if(AI_DEBUG) ai_Debug("ai_ambusher", "50", GetName(oCreature) + " is using hide in plain sight!"); + ClearAllActions(TRUE); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + return; + } + } + // Does not have hide in plain sight. + else + { + string sEnemyIndex = IntToString(nEnemyIndex); + float fEnemyDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sEnemyIndex); + if(AI_DEBUG) ai_Debug("ai_ambusher", "61", "fDistance: " + FloatToString(fEnemyDistance, 0, 2)); + if(fEnemyDistance >= AI_RANGE_LONG) + { + int bTried = GetLocalInt(oCreature, AI_TRIED_TO_HIDE); + if(!bTried) + { + // Move away so we can hide. + if(AI_DEBUG) ai_Debug("ai_ambusher", "68", GetName(oCreature) + " is trying to move away to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + object oEnemy = GetLocalObject(oCreature, AI_ENEMY + sEnemyIndex); + ActionMoveAwayFromObject(oEnemy, TRUE, AI_RANGE_BATTLEFIELD); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + else SetLocalInt(oCreature, AI_TRIED_TO_HIDE, GetLocalInt(oCreature, AI_TRIED_TO_HIDE) - 1); + } + // We have been seen by an enemy too close to us so drop stealth. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + } + // The enemy can see through stealth so lets drop it. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + // We are not in stealth mode so lets get there. + else if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + // Use any hiding talents we have + if(AI_DEBUG) ai_Debug("ai_ambusher", "88", GetName(oCreature) + " is trying to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + // If we have givin up on stealth do our normal actions. + string sScript = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + if(sScript == "ai_ambusher" || sScript == "") sScript = "ai_default"; + if(AI_DEBUG) ai_Debug("ai_ambusher", "96", "sScript: " + sScript + " AI_DEFAULT_SCRIPT: " + GetLocalString(oCreature, AI_DEFAULT_SCRIPT)); + ExecuteScript(sScript, oCreature); +} diff --git a/src/module/nss/ai_barbarian.nss b/src/module/nss/ai_barbarian.nss new file mode 100644 index 0000000..69efcb4 --- /dev/null +++ b/src/module/nss/ai_barbarian.nss @@ -0,0 +1,71 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_barbarian +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Barbarian. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oTarget; + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature)) + { + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // *************************** RANGED ATTACKS ***************************** + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + } + // ***************************** MELEE ATTACKS *************************** + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_bard.nss b/src/module/nss/ai_bard.nss new file mode 100644 index 0000000..9dde198 --- /dev/null +++ b/src/module/nss/ai_bard.nss @@ -0,0 +1,67 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_bard +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Bard. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBardSongFeat(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_cleric.nss b/src/module/nss/ai_cleric.nss new file mode 100644 index 0000000..34bd1e6 --- /dev/null +++ b/src/module/nss/ai_cleric.nss @@ -0,0 +1,68 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_cleric +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Cleric. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryTurningTalent(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_cntrspell.nss b/src/module/nss/ai_cntrspell.nss new file mode 100644 index 0000000..04939c9 --- /dev/null +++ b/src/module/nss/ai_cntrspell.nss @@ -0,0 +1,68 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_cntrspell +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the combat mode counter spell. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + // We are not in melee combat then we don't attack. + int bAttack = nInMelee; + if(!bAttack) + { + // If there are no casters, i.e. CLERIC or MAGES in the battle then attack. + struct stClasses stClasses = ai_GetFactionsClasses(oCreature); + if(!stClasses.CLERICS && !stClasses.MAGES) bAttack = TRUE; + } + // If we are not attacking then setup for counter spelling. + if(!bAttack) + { + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(AI_DEBUG) ai_Debug("ai_cntrspell", "29", " Counterspell Mode? " + + IntToString(GetActionMode(OBJECT_SELF, ACTION_MODE_COUNTERSPELL))); + if(!GetActionMode(oCreature, ACTION_MODE_COUNTERSPELL)) + { + object oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER); + // We can only counter spells from a hasted caster if we are hasted as well. + if(ai_GetHasEffectType(oTarget, EFFECT_TYPE_HASTE) && + !ai_GetHasEffectType(oCreature, EFFECT_TYPE_HASTE)) + { + // If we have haste then we should cast it. + if(GetHasSpell(SPELL_HASTE, oCreature)) + { + if(AI_DEBUG) ai_Debug("ai_cntrspell", "41", "Opponent is hasted! Casting Haste."); + ActionCastSpellAtObject(SPELL_HASTE, oCreature); + ai_SetLastAction(oCreature, SPELL_HASTE); + return; + } + // If not then we need to go into normal combat. + else + { + if(AI_DEBUG) ai_Debug("ai_cntrspell", "49", "Opponent is hasted! Using ranged AI."); + ExecuteScript("ai_ranged"); + return; + } + } + if(oTarget != OBJECT_INVALID) + { + // First a good tactic for counter spelling is to be invisible. + if(ai_TryToBecomeInvisible(oCreature)) return; + // If we have attempted to become invisible or are invisible then + // it is time to counter spell. + if(AI_DEBUG) ai_Debug("ai_cntrspell", "60", "Setting Counterspell mode!"); + ActionCounterSpell(oTarget); + return; + } + } + } + if(AI_DEBUG) ai_Debug("ai_cntrspell", "66", "Situation is not good for counterspelling! Using ranged AI."); + ExecuteScript("ai_ranged"); +} diff --git a/src/module/nss/ai_coward.nss b/src/module/nss/ai_coward.nss new file mode 100644 index 0000000..b88e424 --- /dev/null +++ b/src/module/nss/ai_coward.nss @@ -0,0 +1,133 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_coward +//////////////////////////////////////////////////////////////////////////////// + ai script for cowardly creatures (Any) used when they fail a moral check or + when associates are to remain out of combat. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with us. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + // If we have been healed up then get back in there! + if(ai_GetPercHPLoss(oCreature) > AI_HEALTH_WOUNDED) + { + string sDefaultCombatScript = GetLocalString(oCreature, AI_DEFAULT_SCRIPT); + SetLocalString(oCreature, AI_COMBAT_SCRIPT, sDefaultCombatScript); + ExecuteScript(sDefaultCombatScript, oCreature); + return; + } + // In Melee combat! + if(nInMelee) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryImprovedExpertiseFeat(oCreature)) return; + if(ai_TryExpertiseFeat(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + object oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy; + // Use knockdown when appropriate and the target is not immune. + if(ai_TryKnockdownFeat(oCreature, oTarget)) return; + if (ai_TryParry(oCreature)) return; + // We have tried everything to protect ourselves so the only thing left + // to do is man up and attack! + // Physical attacks are under TALENT_CATEGORY_HARMFUL_MELEE(22). + ai_DoPhysicalAttackOnNearest(oCreature, nInMelee); + return; + } + else + { + // If can turn invisible then we should probably do that! + if(ai_UseTalent(oCreature, SPELL_IMPROVED_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_INVISIBILITY_SPHERE, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_SANCTUARY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELL_ETHEREALNESS, oCreature)) return; // Greater Sanctuary + if(ai_UseTalent(oCreature, SPELLABILITY_AS_IMPROVED_INVISIBLITY, oCreature)) return; + if(ai_UseTalent(oCreature, SPELLABILITY_AS_INVISIBILITY, oCreature)) return; + // If we are seen by the enemy we need to move back so we can hide. + int nEnemyIndex = ai_GetNearestIndexThatSeesUs(oCreature); + if(nEnemyIndex) + { + // Check for an attacker and can they see through invisibility? + object oAttacker = ai_GetEnemyAttackingMe(oCreature); + int bCanSeeInvisible; + if(oAttacker != OBJECT_INVALID) + { + bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_SEEINVISIBLE); + if(!bCanSeeInvisible) bCanSeeInvisible = ai_GetHasEffectType(oAttacker, EFFECT_TYPE_TRUESEEING); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_5_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_10_FEET, oCreature); + if(!bCanSeeInvisible) bCanSeeInvisible = GetHasFeat(FEAT_BLINDSIGHT_60_FEET, oCreature); + } + if(!bCanSeeInvisible) + { + if(GetHasFeat(FEAT_HIDE_IN_PLAIN_SIGHT, oCreature)) + { + if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + if(AI_DEBUG) ai_Debug("ai_coward", "74", GetName(oCreature) + " is using hide in plain sight!"); + ClearAllActions(TRUE); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + return; + } + } + // Does not have hide in plain sight. + else + { + string sEnemyIndex = IntToString(nEnemyIndex); + float fEnemyDistance = GetLocalFloat(oCreature, AI_ENEMY_RANGE + sEnemyIndex); + if(AI_DEBUG) ai_Debug("ai_coward", "85", "fDistance: " + FloatToString(fEnemyDistance, 0, 2)); + if(fEnemyDistance >= AI_RANGE_CLOSE) + { + int bTried = GetLocalInt(oCreature, AI_TRIED_TO_HIDE); + if(!bTried) + { + // Move away so we can hide. + if(AI_DEBUG) ai_Debug("ai_coward", "93", GetName(oCreature) + " is trying to move away to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + object oEnemy = GetLocalObject(oCreature, AI_ENEMY + sEnemyIndex); + ActionMoveAwayFromObject(oEnemy, TRUE, AI_RANGE_BATTLEFIELD); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + else SetLocalInt(oCreature, AI_TRIED_TO_HIDE, GetLocalInt(oCreature, AI_TRIED_TO_HIDE) - 1); + } + // We have been seen by an enemy near us so drop stealth. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + } + // The enemy can see through stealth so lets drop it. + else SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + } + // We are not in stealth mode so lets get there. + else if(!GetActionMode(oCreature, ACTION_MODE_STEALTH)) + { + // Use any hiding talents we have + if(AI_DEBUG) ai_Debug("ai_coward", "113", GetName(oCreature) + " is trying to hide!"); + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + SetLocalInt(oCreature, AI_TRIED_TO_HIDE, 3); + return; + } + } + // Either we cannot go into stealth or we are in stealth so do something else. + //************************* OUT OF MELEE COMBAT ************************** + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, 0, oCreature)) return; + if(ai_TryCureConditionTalent(oCreature, 0)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //************************** DEFENSIVE TALENTS *************************** + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel)) return; + // Stand and watch the battle we don't want to provoke anyone! + if(AI_DEBUG) ai_Debug("ai_coward", "132", GetName(oCreature) + " is holding here."); +} diff --git a/src/module/nss/ai_default.nss b/src/module/nss/ai_default.nss new file mode 100644 index 0000000..cfe8e8f --- /dev/null +++ b/src/module/nss/ai_default.nss @@ -0,0 +1,49 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_default +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for default creatures(Any). + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + if(ai_TryPolymorphSelfFeat(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + ai_DoPhysicalAttackOnNearest(oCreature, nInMelee); +} diff --git a/src/module/nss/ai_defensive.nss b/src/module/nss/ai_defensive.nss new file mode 100644 index 0000000..15f5275 --- /dev/null +++ b/src/module/nss/ai_defensive.nss @@ -0,0 +1,48 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_defensive +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures put in to a defensive mode to protect themselves(Any). + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + //************************** DEFENSIVE TALENTS *************************** + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel)) return; + //******************** DEFENSIVE MELEE FEATS ***************************** + if(nInMelee > 0) + { + if(ai_TryImprovedExpertiseFeat(oCreature)) return; + if(ai_TryExpertiseFeat(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + object oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy; + // Use knockdown when appropriate and the target is not immune + if(ai_TryKnockdownFeat(oCreature, oTarget)) return; + if(ai_TryParry(oCreature)) return; + } + //********************** PHYSICAL ATTACKS ******************************** + // Even in defensive mode we want to be in battle so go find someone! + ai_DoPhysicalAttackOnNearest(oCreature, nInMelee); +} diff --git a/src/module/nss/ai_dragon.nss b/src/module/nss/ai_dragon.nss new file mode 100644 index 0000000..a82362c --- /dev/null +++ b/src/module/nss/ai_dragon.nss @@ -0,0 +1,51 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_dragon +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for dragons. + OBJECT_SELF is the dragons running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + // Dragons do not flee! if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // ************************ MELEE ATTACKS ******************************** + object oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(GetDistanceBetween(oCreature, oTarget) > AI_RANGE_CLOSE) + { + // Can we do a crush attack(HD 18+)? + if(ai_TryCrushAttack(oCreature, oTarget)) return; + ai_FlyToTarget(oCreature, oTarget); + return; + } + if(ai_TryDragonBreathAttack(oCreature, nRound)) return; + ai_TryWingAttacks(oCreature); + // If we don't do a Tail sweep attack(HD 30+) then see if we can do a Tail slap(HD 12+)! + if(!ai_TryTailSweepAttack(oCreature)) ai_TryTailSlap(oCreature); + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_druid.nss b/src/module/nss/ai_druid.nss new file mode 100644 index 0000000..95cb82b --- /dev/null +++ b/src/module/nss/ai_druid.nss @@ -0,0 +1,70 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_druid +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Druid. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS) && ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TryPolymorphSelfFeat(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // All else fails lets see if we have any good potions. + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Lets pick off the nearest targets. + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_fighter.nss b/src/module/nss/ai_fighter.nss new file mode 100644 index 0000000..04f4ce0 --- /dev/null +++ b/src/module/nss/ai_fighter.nss @@ -0,0 +1,65 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_fighter +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Fighter. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange (oCreature); + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //***************** OFFENSIVE AREA OF EFFECT TALENTS ********************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + // *********************** DEFENSIVE TALENTS ***************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //******************* OFFENSIVE TARGETED TALENTS ************************* + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // *************************** RANGED ATTACKS **************************** + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // **************************** MELEE ATTACKS **************************** + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryWhirlwindFeat (oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee); + if (oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents (oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_flanker.nss b/src/module/nss/ai_flanker.nss new file mode 100644 index 0000000..20a6538 --- /dev/null +++ b/src/module/nss/ai_flanker.nss @@ -0,0 +1,102 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_flanker +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for monsters to flank the enemy and not charge into combat. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //***************** OFFENSIVE AREA OF EFFECT TALENTS ********************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + // *********************** DEFENSIVE TALENTS ***************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //******************* OFFENSIVE TARGETED TALENTS ************************* + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Melee feat attacks ************************* + // Lets get the nearest target that is attacking someone besides me. We want to flank! + if(oTarget == OBJECT_INVALID) + { + if(!nInMelee) oTarget = ai_GetFlankTarget(oCreature); + // If there are few enemies then we can safely move around. + else if(nInMelee < 3 || ai_CanIMoveInCombat(oCreature)) + { + oTarget = ai_GetFlankTarget(oCreature, AI_RANGE_MELEE); + } + // Ok we are in a serious fight so lets not give attack of opportunities. + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + } + // If there are no enemies being attacked then lets stay back. + if(oTarget == OBJECT_INVALID) + { + if(nInMelee) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + // Lets get the strongest melee opponent in melee with us. + object oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + } + // ************************** Ranged feat attacks ************************** + if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + oTarget = ai_GetNearestTarget(oCreature); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + else + { + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + } + if(oTarget != OBJECT_INVALID) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); +} diff --git a/src/module/nss/ai_incorporeal.nss b/src/module/nss/ai_incorporeal.nss new file mode 100644 index 0000000..cdd20bd --- /dev/null +++ b/src/module/nss/ai_incorporeal.nss @@ -0,0 +1,83 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_incorporeal +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures that are incorporeal. + oCreature is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange (oCreature); + if (nInMelee && ai_MoralCheck (oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if (!GetHasFeatEffect (FEAT_BARBARIAN_RAGE, oCreature) && ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if (ai_TryRangedSneakAttack (oCreature, nInMelee)) return; + string sIndex; + if (!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat (oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee); + if (oTarget != OBJECT_INVALID) + { + // If we are using our hands then do a touch attack instead. + if (GetItemInSlot (INVENTORY_SLOT_RIGHTHAND) == OBJECT_INVALID) + { + if (GetItemInSlot (INVENTORY_SLOT_CWEAPON_L) != OBJECT_INVALID) + { + // Randomize so they don't appear synchronized. + float fDelay = IntToFloat(Random(2) + 1); + DelayCommand(fDelay, ActionCastSpellAtObject (769/*Shadow_Attack*/, oTarget, METAMAGIC_ANY, TRUE)); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MELEE_ATK); + SetLocalObject (oCreature, AI_ATTACKED_PHYSICAL, oTarget); + } + } + else ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_invisible.nss b/src/module/nss/ai_invisible.nss new file mode 100644 index 0000000..7d42b21 --- /dev/null +++ b/src/module/nss/ai_invisible.nss @@ -0,0 +1,93 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_invisible +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures(Any) that are invisible. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + // Skill, Class, Offensive AOE's, and Defensive talents. + // *************************** SPELL TALENTS *************************** + // ********** PROTECTION/ENHANCEMENT/SUMMON TALENTS ************ + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + // ************************** CLASS FEATURES *************************** + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + // ******************* OFFENSIVE AOE TALENTS *********************** + // Check the battlefield for a group of enemies to shoot a big spell at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // If we won't loose invisibility then ranged attacks are ok! + // ************************ RANGED ATTACKS ******************************* + if(GetHasSpellEffect(SPELL_IMPROVED_INVISIBILITY) || GetHasSpellEffect(SPELLABILITY_AS_IMPROVED_INVISIBLITY)) + { + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + talent tUse = GetCreatureTalentBest(TALENT_CATEGORY_HARMFUL_MELEE, 20, oCreature); + if(GetIsTalentValid(tUse)) + { + int nId = GetIdFromTalent(tUse); + if(nId == FEAT_POWER_ATTACK) { if(ai_TryPowerAttackFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_KNOCKDOWN) { if(ai_TryKnockdownFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SMITE_EVIL) { if(ai_TrySmiteEvilFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SMITE_GOOD) { if(ai_TrySmiteGoodFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_IMPROVED_POWER_ATTACK) { if(ai_TryImprovedPowerAttackFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_FLURRY_OF_BLOWS) { if(ai_TryFlurryOfBlowsFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_STUNNING_FIST) { if(ai_TryStunningFistFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_SAP) { if(ai_TrySapFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_DISARM) { if(ai_TryDisarmFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_KI_DAMAGE) { if(ai_TryKiDamageFeat(oCreature, oTarget)) return; } + else if(nId == FEAT_CALLED_SHOT) { if(ai_TryCalledShotFeat(oCreature, oTarget)) return; } + } + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_monk.nss b/src/module/nss/ai_monk.nss new file mode 100644 index 0000000..d6ff1b6 --- /dev/null +++ b/src/module/nss/ai_monk.nss @@ -0,0 +1,65 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_monk +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Monk. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange (oCreature); + //*************************** HEALING & CURES **************************** + if (ai_TryWholenessOfBodyFeat (oCreature)) return; + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck (oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if (!nInMelee) oTarget = ai_GetNearestTarget (oCreature); + else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee); + if (oTarget != OBJECT_INVALID) + { + if (ai_TryMeleeTalents (oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_paladin.nss b/src/module/nss/ai_paladin.nss new file mode 100644 index 0000000..d45d223 --- /dev/null +++ b/src/module/nss/ai_paladin.nss @@ -0,0 +1,71 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_paladin +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Paladin. + Paladins face the strongest opponents on the battlefield first! + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryTurningTalent(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return; + if(ai_TryDivineMightFeat(oCreature, nInMelee)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Paladins face the biggest challenges first! + if(!nInMelee) oTarget = ai_GetHighestCRTarget(oCreature); + else oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + // Paladins face the biggest challenges first! + oTarget = ai_GetHighestCRTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_polymorphed.nss b/src/module/nss/ai_polymorphed.nss new file mode 100644 index 0000000..9a7630a --- /dev/null +++ b/src/module/nss/ai_polymorphed.nss @@ -0,0 +1,55 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_polymorphed +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for polymorphed creatures. + We check for abilities based on the form we are using and if we should polymorph back. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void ai_DoActions(object oCreature, int nForm) +{ + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(GetPercentageHPLoss(oCreature) <= AI_HEALTH_BLOODY) + { + if(AI_DEBUG) ai_Debug("ai_polymorphed", "19", "We are wounded and are transforming back!"); + ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH); + return; + } + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + // When polymorphed we turn back then check moral. + // if(nInMelee && ai_MoralCheck(oCreature)) return; + // Skill, Class, Offensive AOE's, and Defensive talents. + // *************************** SPELL TALENTS *************************** + if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; + // Class and Offensive single target talents. + // *************************** SPELL TALENTS *************************** + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + // If we don't find a target then we don't want to fight anyone! + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, TRUE); +} +void main() +{ + object oCreature = OBJECT_SELF; + // Need to know who we are so we can use thier abilities. + int nForm = GetAppearanceType(oCreature); + // Check to see if we are back to our normal form?(-1 to get the actual form #) + if(nForm == GetLocalInt(oCreature, AI_NORMAL_FORM) - 1) + { + // If we are transformed back then go back to our primary ai. + ai_SetCreatureAIScript(oCreature); + DeleteLocalInt(oCreature, AI_NORMAL_FORM); + string sAI = GetLocalString(oCreature, AI_COMBAT_SCRIPT); + if(sAI == "ai_polymorphed" || sAI == "") sAI = "ai_default"; + ExecuteScript(sAI, oCreature); + } + else ai_DoActions(oCreature, nForm); +} diff --git a/src/module/nss/ai_ranged.nss b/src/module/nss/ai_ranged.nss new file mode 100644 index 0000000..3a46228 --- /dev/null +++ b/src/module/nss/ai_ranged.nss @@ -0,0 +1,116 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_ranged +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for monsters to use the ranged ai. + OBJECT_SELF is the creature running the ai. + Will attempt to use ranged weapons/spells until surrounded. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + // Check for moral and get the maximum spell level we should use. + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + // ************************** CLASS FEATURES ******************************* + if(ai_TryTurningTalent(oCreature)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + object oTarget; + // ************************** Ranged feat attacks ************************** + if(!GetHasFeatEffect(FEAT_BARBARIAN_RAGE, oCreature) && + (nInMelee < 3 || ai_GetEnemyAttackingMe(oCreature) == OBJECT_INVALID)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + // Lets pick off the ranged then nearest targets. + if(!nInMelee) + { + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget == ai_GetRangedTarget(oCreature); + if(oTarget == OBJECT_INVALID && ai_TryRangedSneakAttack(oCreature, nInMelee)) return; + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature); + } + else + { + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************** Melee feat attacks ************************* + object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST); + if(nInMelee) + { + oTarget = ai_GetEnemyAttackingMe(oCreature); + if(oTarget != OBJECT_INVALID) + { + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if(ai_TrySneakAttack(oCreature, nInMelee)) return; + if(ai_TryWhirlwindFeat(oCreature)) return; + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + return; + } + } + } + if(oNearestEnemy != OBJECT_INVALID) + { + float fDistance = GetDistanceBetween(oCreature, oNearestEnemy); + float fRange = AI_RANGE_LONG; + if(GetHasFeat(FEAT_SNEAK_ATTACK, oCreature)) fRange = AI_RANGE_CLOSE; + if(fDistance < fRange) + { + int bRun = ai_CanIMoveInCombat(oCreature); + ActionMoveAwayFromObject(oNearestEnemy, bRun, fRange - fDistance + 2.0); + } + } + else ai_SearchForHiddenCreature(oCreature, FALSE, OBJECT_INVALID, AI_RANGE_CLOSE); +} + diff --git a/src/module/nss/ai_ranger.nss b/src/module/nss/ai_ranger.nss new file mode 100644 index 0000000..5878cfb --- /dev/null +++ b/src/module/nss/ai_ranger.nss @@ -0,0 +1,79 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_ranger +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Ranger. + Need to add ---> Rangers will take out favored enemies first! + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS) && ai_TrySummonAnimalCompanionTalent(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) + { + oTarget = ai_GetNearestFavoredEnemyTarget(oCreature); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature); + } + else + { + oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + } + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE); + if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryMeleeTalents(oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_rogue.nss b/src/module/nss/ai_rogue.nss new file mode 100644 index 0000000..81c4500 --- /dev/null +++ b/src/module/nss/ai_rogue.nss @@ -0,0 +1,66 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_rogue +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Rogue. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange (oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck (oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if (ai_TryRangedSneakAttack (oCreature, nInMelee)) return; + oTarget = ai_GetNearestTarget (oCreature); + if(oTarget != OBJECT_INVALID) + { + if (ai_TryRapidShotFeat (oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + if (ai_TrySneakAttack (oCreature, nInMelee)) return; + oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee); + if (oTarget != OBJECT_INVALID) + { + if (ai_TryMeleeTalents (oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_shadow.nss b/src/module/nss/ai_shadow.nss new file mode 100644 index 0000000..3d6419f --- /dev/null +++ b/src/module/nss/ai_shadow.nss @@ -0,0 +1,77 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_shadow +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures that are incorporeal. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + // Shadows do not flee! if(nInMelee && ai_MoralCheck()) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************ RANGED ATTACKS ******************************* + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + string sIndex; + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee); + if(oTarget != OBJECT_INVALID) + { + // If we are using our hands then do a touch attack instead. + if(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND) == OBJECT_INVALID) + { + if(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L) != OBJECT_INVALID) + { + // Randomize so they don't appear synchronized. + float fDelay = IntToFloat(Random(2) + 1); + DelayCommand(fDelay, ActionCastSpellAtObject (769/*Shadow_Attack*/, oTarget, METAMAGIC_ANY, TRUE)); + ai_SetLastAction(oCreature, AI_LAST_ACTION_MELEE_ATK); + SetLocalObject (oCreature, AI_ATTACKED_PHYSICAL, oTarget); + } + } + else ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_sorcerer.nss b/src/module/nss/ai_sorcerer.nss new file mode 100644 index 0000000..f1fdcc3 --- /dev/null +++ b/src/module/nss/ai_sorcerer.nss @@ -0,0 +1,61 @@ +/*//////////////////////////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_sorcerer +////////////////////////////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Sorcerer. + OBJECT_SELF is the creature running the ai. +*///////////////////////////////////////////////////////////////////////////////////////////////////// +// Programmer: Philos +////////////////////////////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************* OFFENSIVE TARGETED TALENTS *********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************** RANGED ATTACKS ***************************** + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee, FALSE); + // I have a target now lets see if we want to move in! + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, TRUE, OBJECT_INVALID, AI_RANGE_CLOSE); +} diff --git a/src/module/nss/ai_taunter.nss b/src/module/nss/ai_taunter.nss new file mode 100644 index 0000000..825d025 --- /dev/null +++ b/src/module/nss/ai_taunter.nss @@ -0,0 +1,78 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: ai_taunter +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using defined to use the taunt skill. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange (oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck (oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + //**************************** SKILL FEATURES **************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + //**************************** CLASS FEATURES **************************** + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS)) + { + if(ai_TrySummonFamiliarTalent(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + } + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************** OFFENSIVE TARGETED TALENTS ********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // *************************** RANGED ATTACKS ***************************** + // We use a bow when we are not in melee, or only 1 enemy with PBS. + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if (!nInMelee) oTarget = ai_GetNearestTarget (oCreature); + else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ***************************** MELEE ATTACKS *************************** + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee); + if (oTarget != OBJECT_INVALID) + { + if (ai_TryTaunt (oCreature, oTarget)) return; + if (ai_TryMeleeTalents (oCreature, oTarget)) return; + ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + } + else ai_SearchForHiddenCreature(oCreature, TRUE); +} diff --git a/src/module/nss/ai_wizard.nss b/src/module/nss/ai_wizard.nss new file mode 100644 index 0000000..6baa4c8 --- /dev/null +++ b/src/module/nss/ai_wizard.nss @@ -0,0 +1,63 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: ai_wizard +//////////////////////////////////////////////////////////////////////////////// + ai script for creatures using the class Wizard. + OBJECT_SELF is the creature running the ai. +//////////////////////////////////////////////////////////////////////////////// + Programmer: Philos +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +void main() +{ + object oCreature = OBJECT_SELF; + // Get the number of enemies that we are in melee combat with. + int nInMelee = ai_GetNumOfEnemiesInRange(oCreature); + //*************************** HEALING & CURES **************************** + if(ai_TryHealingTalent(oCreature, nInMelee)) return; + if(ai_TryCureConditionTalent(oCreature, nInMelee)) return; + if(nInMelee && ai_MoralCheck(oCreature)) return; + int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature); + //******************* OFFENSIVE AREA OF EFFECT TALENTS ******************* + // Check the battlefield for a group of enemies to shoot a big talent at! + // We are checking here since these opportunities are rare and we need + // to take advantage of them as often as possible. + if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return; + // ************************** CLASS FEATURES **************************** + if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS) && ai_TrySummonFamiliarTalent(oCreature)) return; + //************************** DEFENSIVE TALENTS *************************** + int nRound = ai_GetCurrentRound(oCreature); + if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return; + //********************* OFFENSIVE TARGETED TALENTS *********************** + // Look for a touch attack since we are in melee. + if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return; + if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; + // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. + // ************************** RANGED ATTACKS ***************************** + object oTarget; + if(ai_CanIUseRangedWeapon(oCreature, nInMelee)) + { + if(ai_HasRangedWeaponWithAmmo(oCreature)) + { + if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature); + else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE); + if(oTarget != OBJECT_INVALID) + { + ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE); + return; + } + else + { + ai_SearchForHiddenCreature(oCreature, TRUE, OBJECT_INVALID, AI_RANGE_CLOSE); + return; + } + } + else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return; + } + // ************************* MELEE ATTACKS ******************************* + if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return; + oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee, TRUE); + // I have a target now lets see if we want to move in! + if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget); + else ai_SearchForHiddenCreature(oCreature, TRUE, OBJECT_INVALID, AI_RANGE_CLOSE); +} diff --git a/src/module/nss/mm_prc_spells.nss b/src/module/nss/mm_prc_spells.nss new file mode 100644 index 0000000..4aeb8e0 --- /dev/null +++ b/src/module/nss/mm_prc_spells.nss @@ -0,0 +1,161 @@ +#include "0i_menus" +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +json ai_CheckToReplaceSpell(json jSpellList, int nClass, int nLevel, int nSlot) +{ + //if(d100() > 49) return jSpellList; + string sSpellTableColumn = Get2DAString("classes", "SpellTableColumn", nClass); + int nRoll = d10() + 1 + nLevel * 10; + int nSpell = StringToInt(Get2DAString("prc_add_spells", sSpellTableColumn, nRoll)); + if(nSpell > 0) + { + //WriteTimestampedLogEntry("mm_prc_spells, 13 nSpell: " + IntToString(nSpell) + + // " nLevel: " + IntToString(nLevel) + " nSlot: " + IntToString(nSlot)); + json jSpellArray = JsonArrayGet(jSpellList, nSlot); + json jSpell = JsonObjectGet(jSpellArray, "Spell"); + jSpell = JsonObjectSet(jSpell, "value", JsonInt(nSpell)); + jSpellArray = JsonObjectSet(jSpellArray, "Spell", jSpell); + return JsonArraySet(jSpellList, nSlot, jSpellArray); + } + return jSpellList; +} +void main() +{ + object oPC = OBJECT_SELF; + if(StartingUp(oPC)) return; + int bChanged, bCreatureChanged, nPosition, nClass, nLevel, nSlot, nMaxSlots; + json jClass, jMemorizedList, jKnownList; + object oModule = GetModule(); + json jCreature = GetLocalJson(oModule, AI_MONSTER_JSON); + object oCreature = GetLocalObject(oModule, AI_MONSTER_OBJECT); + json jClassList = GffGetList(jCreature, "ClassList"); + while(nPosition <= AI_MAX_CLASSES_PER_CHARACTER) + { + nClass = GetClassByPosition(nPosition, oCreature); + if(Get2DAString("classes", "SpellCaster", nClass) == "1") + { + //WriteTimestampedLogEntry("mm_prc_spells, 39 " + GetName(oCreature) + JsonDump(jClassList, 4)); + jClass = JsonArrayGet(jClassList, nPosition - 1); + if(Get2DAString("classes", "MemorizesSpells", nClass) == "1") + { + nLevel = 1; + while(nLevel < 9) + { + jMemorizedList = GffGetList(jClass, "MemorizedList" + IntToString(nLevel)); + if(JsonGetType(jMemorizedList) != JSON_TYPE_NULL) + { + nSlot = 0; + nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel); + while(nSlot < nMaxSlots) + { + jMemorizedList = ai_CheckToReplaceSpell(jMemorizedList, nClass, nLevel, nSlot); + nSlot++; + } + //WriteTimestampedLogEntry("nClass: " + IntToString(nClass) + " nLevel: " + IntToString(nLevel) + + // " nSlot: " + IntToString(nSlot) + " jMemorizedList " + JsonDump(jMemorizedList, 4)); + jClass = GffReplaceList(jClass, "MemorizedList" + IntToString(nLevel), jMemorizedList); + bChanged = TRUE; + } + nLevel++; + } + } + else + { + nLevel = 1; + while(nLevel < 9) + { + jKnownList = GffGetList(jClass, "KnownList" + IntToString(nLevel)); + if(JsonGetType(jMemorizedList) != JSON_TYPE_NULL) + { + nSlot = 0; + nMaxSlots = GetKnownSpellCount(oCreature, nClass, nLevel); + while(nSlot < nMaxSlots) + { + jKnownList = ai_CheckToReplaceSpell(jKnownList, nClass, nLevel, nSlot); + nSlot++; + } + jClass = GffReplaceList(jClass, "KnownList" + IntToString(nLevel), jKnownList); + bChanged = TRUE; + } + nLevel++; + } + } + if(bChanged) + { + //WriteTimestampedLogEntry("0i_module, 87 " + GetName(oCreature) + " jClass: " + JsonDump(jClass, 4)); + jClassList = JsonArraySet(jClassList, nPosition - 1, jClass); + //if(AI_DEBUG) ai_Debug("0i_module, 89 " + GetName(oCreature) + " jClassList: " + JsonDump(jClassList, 4)); + jCreature = GffReplaceList(jCreature, "ClassList", jClassList); + bCreatureChanged = TRUE; + bChanged = FALSE; + } + } + nPosition++; + } + if(bCreatureChanged) + { + //WriteTimestampedLogEntry("mm_prc_spells, 99 " + GetName(oCreature) + " jClassList: " + JsonDump(jClassList, 4)); + SetLocalJson(oModule, AI_MONSTER_JSON, jCreature); + SetLocalInt(oModule, AI_MONSTER_CHANGED, TRUE); + } +} +int PRCSpellsSetup(object oPC) +{ + // Check to make sure prc_add_spells.2da is loaded. + if(ResManGetAliasFor("prc_add_spells", RESTYPE_2DA) == "") + { + SendMessageToPC(oPC, "prc_add_spells.2da is not loaded! Make sure it is in the override or development folder."); + return FALSE; + } + // Check to make sure PRC is loaded. + if(!GetLocalInt(GetModule(), AI_USING_PRC)) + { + SendMessageToPC(oPC, "PRC is not being used. PRC must be active for this mod to work."); + return FALSE; + } + return TRUE; +} +void SetMonsterModJson(object oPC) +{ + object oModule = GetModule(); + json jMonsterMods = GetLocalJson(oModule, AI_MONSTER_MOD_JSON); + if(JsonGetType(jMonsterMods) == JSON_TYPE_NULL) jMonsterMods = JsonArray(); + int nIndex; + string sMonsterMod = JsonGetString(JsonArrayGet(jMonsterMods, nIndex)); + while(sMonsterMod != "") + { + if(sMonsterMod == "mm_prc_spells") return; + sMonsterMod = JsonGetString(JsonArrayGet(jMonsterMods, ++nIndex)); + } + jMonsterMods = JsonArrayInsert(jMonsterMods, JsonString("mm_prc_spells")); + SetLocalJson(oModule, AI_MONSTER_MOD_JSON, jMonsterMods); + ai_SendMessages("mm_prc_spells loaded! Monsters will be using PRC spells.", AI_COLOR_YELLOW, oPC); +} +int StartingUp(object oPC) +{ + if(!PRCSpellsSetup(oPC)) + { + SendMessageToPC(oPC, "mm_prc_spells monster mod has failed to load due to an error."); + // Return -1 in AI_PLUGIN_SET to tell PEPS that we failed to load. + SetLocalInt(oPC, AI_PLUGIN_SET, -1); + return TRUE; + } + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("mm_prc_spells")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(3)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Monsters will use PRC spells!")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + SetMonsterModJson(oPC); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + SetMonsterModJson(oPC); + return TRUE; +} + diff --git a/src/module/nss/nw_c2_default1.nss b/src/module/nss/nw_c2_default1.nss index 62ac86b..4801a4d 100644 --- a/src/module/nss/nw_c2_default1.nss +++ b/src/module/nss/nw_c2_default1.nss @@ -1,108 +1,94 @@ -//::////////////////////////////////////////////////// -//:: NW_C2_DEFAULT1 -/* - Default OnHeartbeat script for NPCs. - - This script causes NPCs to perform default animations - while not otherwise engaged. - - This script duplicates the behavior of the default - script and just cleans up the code and removes - redundant conditional checks. - - */ -//::////////////////////////////////////////////////// -//:: Copyright (c) 2002 Floodgate Entertainment -//:: Created By: Naomi Novik -//:: Created On: 12/22/2002 -//::////////////////////////////////////////////////// - -#include "nw_i0_generic" -#include "prc_inc_spells" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default1 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnHeartbeat script; + This will usually fire every 6 seconds (1 game round). +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_module" void main() { - - // * if not runnning normal or better Ai then exit for performance reasons - if (GetAILevel() == AI_LEVEL_VERY_LOW) return; + // If not runnning normal or better AI then exit for performance reasons + if (GetAILevel(OBJECT_SELF) == AI_LEVEL_VERY_LOW) return; ExecuteScript("prc_npc_hb", OBJECT_SELF); - - // Buff ourselves up right away if we should - if(GetSpawnInCondition(NW_FLAG_FAST_BUFF_ENEMY)) - { - // This will return TRUE if an enemy was within 40.0 m - // and we buffed ourselves up instantly to respond -- - // simulates a spellcaster with protections enabled - // already. - if(TalentAdvancedBuff(40.0)) - { - // This is a one-shot deal - SetSpawnInCondition(NW_FLAG_FAST_BUFF_ENEMY, FALSE); - - // This return means we skip sending the user-defined - // heartbeat signal in this one case. - return; - } - } - - - if(PRCGetHasEffect(EFFECT_TYPE_SLEEP)) + + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("nw_c2_default1", "16", GetName(oCreature) + " Heartbeat." + + " OnSpawn: " + IntToString(GetLocalInt(oCreature, AI_ONSPAWN_EVENT))); + // We run our OnSpawn in the heartbeat so the creator can use the original + // OnSpawn for their own use. If we have to recreate the creature then we + // skip the rest of the heartbeat since this version is being destroyed! + if(ai_OnMonsterSpawn(oCreature)) return; + if(AI_DEBUG) ai_Debug("nw_c2_default1", "16", GetName(oCreature) + " Heartbeat." + + " Searching: " + IntToString(GetLocalInt(oCreature, AI_AM_I_SEARCHING))); + if(ai_GetHasEffectType(oCreature, EFFECT_TYPE_SLEEP)) { // If we're asleep and this is the result of sleeping // at night, apply the floating 'z's visual effect // every so often - if(GetSpawnInCondition(NW_FLAG_SLEEPING_AT_NIGHT)) { effect eVis = EffectVisualEffect(VFX_IMP_SLEEP); if(d10() > 6) { - ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCreature); } } } - - // If we have the 'constant' waypoints flag set, walk to the next - // waypoint. - else if ( GetWalkCondition(NW_WALK_FLAG_CONSTANT) ) - { - WalkWayPoints(); - } - - // Check to see if we should be playing default animations - // - make sure we don't have any current targets - else if ( !GetIsObjectValid(GetAttemptedAttackTarget()) - && !GetIsObjectValid(GetAttemptedSpellTarget()) - // && !GetIsPostOrWalking()) - && !GetIsObjectValid(GetNearestSeenEnemy())) - { - if (GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL) || GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE) || - GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE)) - { - // This handles special attacking/fleeing behavior - // for omnivores & herbivores. - DetermineSpecialBehavior(); - } - else if (!IsInConversation(OBJECT_SELF)) - { - if (GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS) - || GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN) - || GetIsEncounterCreature()) - { - PlayMobileAmbientAnimations(); - } - else if (GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS)) - { - PlayImmobileAmbientAnimations(); - } - } - } - - // Send the user-defined event signal if specified + // Send the user-defined event signal if specified here so it doesn't get skipped. if(GetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT)) { - SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_HEARTBEAT)); + SignalEvent(oCreature, EventUserDefined(EVENT_HEARTBEAT)); } + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature) || + GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return; + if(ai_GetIsInCombat(oCreature)) + { + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE)) + { + object oTarget = ai_GetNearestEnemy(oCreature, 1, 7, 7, -1, -1, TRUE); + if(GetDistanceBetween(oCreature, oTarget) <= 6.0) + { + if(GetLevelByClass(CLASS_TYPE_DRUID, oTarget) == 0 && GetLevelByClass(CLASS_TYPE_RANGER, oTarget) == 0) + { + SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_coward"); + ActionMoveAwayFromObject(oTarget, TRUE, AI_RANGE_LONG); + return; + } + } + } + ai_DoMonsterCombatRound(oCreature); + return; + } + if(ai_CheckForCombat(oCreature, TRUE)) return; + // If we have not set up our talents then we need to check to see if we should. + if(!GetLocalInt(oCreature, AI_TALENTS_SET)) + { + // We setup our talents when a PC gets withing Battlefield range 40.0 meters. + object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oCreature, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY); + if(oPC != OBJECT_INVALID && GetDistanceBetween(oCreature, oPC) <= AI_RANGE_BATTLEFIELD) + { + if(AI_DEBUG) ai_Debug("nw_c2_default1", "72", GetName(oCreature) + " is " + + FloatToString(GetDistanceBetween(oCreature, oPC), 0, 2) + " from " + GetName(oPC)); + if(AI_DEBUG) ai_Debug("nw_c2_default1", "74", GetName(oCreature) + " is Setting Creature Talents and buffing!"); + ai_SetupMonsterBuffTargets(oCreature); + // To save steps and time we set the talents while we buff! + ai_SetCreatureTalents(oCreature, TRUE); + ai_ClearBuffTargets(oCreature, "AI_ALLY_TARGET_"); + } + } + if(!IsInConversation (oCreature)) + { + if(GetWalkCondition(NW_WALK_FLAG_CONSTANT)) WalkWayPoints(); + if(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS)) PlayMobileAmbientAnimations_NonAvian(); + else if(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN)) PlayMobileAmbientAnimations_Avian(); + else if(GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS)) PlayImmobileAmbientAnimations(); + else if(GetLocalInt(GetModule(), AI_RULE_WANDER) && GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, oCreature) > 89) + { + ai_AmbientAnimations(); + } + } + if(ai_TryHealing(oCreature, oCreature)) return; } diff --git a/src/module/nss/nw_c2_default2.nss b/src/module/nss/nw_c2_default2.nss index 34499fd..b7d5e07 100644 --- a/src/module/nss/nw_c2_default2.nss +++ b/src/module/nss/nw_c2_default2.nss @@ -1,166 +1,138 @@ -//::////////////////////////////////////////////////// -//:: NW_C2_DEFAULT2 -/* - Default OnPerception event handler for NPCs. - - Handles behavior when perceiving a creature for the - first time. - */ -//::////////////////////////////////////////////////// - -#include "nw_i0_generic" -#include "prc_inc_spells" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default2 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnPerception script when not in combat; + There are 4 types of perception - Heard, Inaudible, Seen, Vanished. + Only one type will ever be true in an event trigger. + The order of trigger is Heard/Seen and Inaudible/Vanished. + There are two states of percepion Heard and Seen. + These states can be set at the same time thus a heard event can see the creature. + Fires when ever one of these states changes from TRUE to FALSE or FALSE to TRUE. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" void main() { - // * if not runnning normal or better Ai then exit for performance reasons - if (GetAILevel() == AI_LEVEL_VERY_LOW) return; - + // * if not runnning normal or better AI then exit for performance reasons + //if (GetAILevel() == AI_LEVEL_VERY_LOW) return; + object oCreature = OBJECT_SELF; ExecuteScript("prc_npc_percep", OBJECT_SELF); - - object oPercep = GetLastPerceived(); + if(AI_DEBUG) ai_Debug("nw_c2_default2", "19", "AI_ONSPAWN_EVENT: " + IntToString(GetLocalInt(oCreature, AI_ONSPAWN_EVENT))); + if(!GetLocalInt(oCreature, AI_ONSPAWN_EVENT)) return; + if(GetLastPerceptionSeen()) + { + if(AI_DEBUG) ai_Debug("nw_c2_default2", "22", GetName(oCreature) + " sees " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + "."); + } + if(GetLastPerceptionHeard()) + { + if(AI_DEBUG) ai_Debug("nw_c2_default2", "28", GetName(oCreature) + " heard " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + "."); + } + if(GetLastPerceptionVanished ()) + { + if(AI_DEBUG) ai_Debug("nw_c2_default2", "34", GetName(oCreature) + " lost sight of " + + GetName(GetLastPerceived ()) + "."); + } + // We do nothing on Inaudibles so drop out early! + if(GetLastPerceptionInaudible()) + { + if(AI_DEBUG) ai_Debug("nw_c2_default2", "41", GetName(oCreature) + " lost sound of " + + GetName(GetLastPerceived()) + "."); + return; + } + object oLastPerceived = GetLastPerceived(); + if(AI_DEBUG) ai_Debug("nw_c2_default2", "45", "Dead? " + IntToString(GetIsDead(oLastPerceived)) + + " Enemy? " + IntToString(GetIsEnemy(oLastPerceived, oCreature))); + if(ai_Disabled(oCreature)) return; + if(GetIsDead(oLastPerceived)) return; int bSeen = GetLastPerceptionSeen(); - int bHeard = GetLastPerceptionHeard(); - if (bHeard == FALSE) + // This will cause all NPC's to speak their one-liner conversation + // on perception even if they are already in combat. + if(GetIsPC(oLastPerceived) && bSeen) { - // Has someone vanished in front of me? - bHeard = GetLastPerceptionVanished(); - } - - // This will cause the NPC to speak their one-liner - // conversation on perception even if they are already - // in combat. - if(GetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION) - && GetIsPC(oPercep) - && bSeen) - { - SpeakOneLinerConversation(); - } - - // March 5 2003 Brent - // Had to add this section back in, since modifications were not taking this specific - // example into account -- it made invisibility basically useless. - //If the last perception event was hearing based or if someone vanished then go to search mode - if ((GetLastPerceptionVanished()) && GetIsEnemy(GetLastPerceived())) - { - object oGone = GetLastPerceived(); - if((GetAttemptedAttackTarget() == GetLastPerceived() || - GetAttemptedSpellTarget() == GetLastPerceived() || - GetAttackTarget() == GetLastPerceived()) && GetArea(GetLastPerceived()) != GetArea(OBJECT_SELF)) + if(GetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION)) { - ClearAllActions(); - DetermineCombatRound(); + SpeakOneLinerConversation(); } } - - // This section has been heavily revised while keeping the - // pre-existing behavior: - // - If we're in combat, keep fighting. - // - If not and we've perceived an enemy, start to fight. - // Even if the perception event was a 'vanish', that's - // still what we do anyway, since that will keep us - // fighting any visible targets. - // - If we're not in combat and haven't perceived an enemy, - // see if the perception target is a PC and if we should - // speak our attention-getting one-liner. - if (GetIsInCombat(OBJECT_SELF)) + if(GetIsEnemy(oLastPerceived, oCreature)) { - // don't do anything else, we're busy - //MyPrintString("GetIsFighting: TRUE"); - - } - // * BK FEB 2003 Only fight if you can see them. DO NOT RELY ON HEARING FOR ENEMY DETECTION - else if (GetIsEnemy(oPercep) && bSeen) - { // SpawnScriptDebugger(); - //MyPrintString("GetIsEnemy: TRUE"); - // We spotted an enemy and we're not already fighting - if(!PRCGetHasEffect(EFFECT_TYPE_SLEEP)) { - if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) + // ************************** ENEMY SEEN ******************************* + if(bSeen) + { + // If the creature we are perceiving was our invisible creature then + // remove that they are invisible. + if(oLastPerceived == GetLocalObject(oCreature, AI_IS_INVISIBLE)) { - //MyPrintString("DetermineSpecialBehavior"); - DetermineSpecialBehavior(); - } else - { - //MyPrintString("DetermineCombatRound"); - SetFacingPoint(GetPosition(oPercep)); - SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK); - DetermineCombatRound(); + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); } + ai_MonsterEvaluateNewThreat(oCreature, oLastPerceived, AI_I_SEE_AN_ENEMY); } + // ************************** ENEMY HEARD ****************************** + else if(GetLastPerceptionHeard()) + { + ai_MonsterEvaluateNewThreat(oCreature, oLastPerceived, AI_I_HEARD_AN_ENEMY); + } + // ************************** ENEMY VANISHED *************************** + else if(GetLastPerceptionVanished()) + { + // Lets keep a mental note of the invisible creature. + SetLocalObject(oCreature, AI_IS_INVISIBLE, oLastPerceived); + if(AI_DEBUG) ai_Debug("0e_c2_2_percept", "82", " We saw " + GetName(oLastPerceived) + " disappear!"); + if(ai_GetIsBusy(oCreature)) return; + // If in combat check to see if our target disappeared. + // If they have and we are not in melee with them then reevaluate combat + // since we lost our target. + if(ai_GetIsInCombat(oCreature)) + { + if(AI_DEBUG) ai_Debug("nw_c2_default2", "89", "Is this our target? " + + IntToString(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived)); + if(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived) + { + ai_DoMonsterCombatRound(oCreature); + } + } + // We are not in combat so lets move to that location and check it out. + else ActionMoveToLocation(GetLocation(oLastPerceived), TRUE); + // we use to move to the object but thats a bit creepy! + //else ActionMoveToObject(oLastPerceived, TRUE, AI_RANGE_CLOSE); + } + // ************************ ENEMY INAUDIBLE***************************** + // Not used. } else { - if (bSeen) + // ************************ NON_ENEMY SEEN ***************************** + if(bSeen) { - //MyPrintString("GetLastPerceptionSeen: TRUE"); - if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) { - DetermineSpecialBehavior(); - } else if (GetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION) - && GetIsPC(oPercep)) + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) ai_DetermineSpecialBehavior(oCreature); + else if(GetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION) && GetIsPC(oLastPerceived)) { - // The NPC will speak their one-liner conversation - // This should probably be: - // SpeakOneLinerConversation(oPercep); - // instead, but leaving it as is for now. - ActionStartConversation(OBJECT_SELF); + ActionStartConversation(oCreature); } } - else - // * July 14 2003: Some minor reactions based on invisible creatures being nearby - if (bHeard && GetIsEnemy(oPercep)) - { - // SpeakString("vanished"); - // * don't want creatures wandering too far after noises - if (GetDistanceToObject(oPercep) <= 7.0) - { -// if (GetHasSpell(SPELL_TRUE_SEEING) == TRUE) - if (GetHasSpell(SPELL_TRUE_SEEING)) - { - ActionCastSpellAtObject(SPELL_TRUE_SEEING, OBJECT_SELF); - } - else -// if (GetHasSpell(SPELL_SEE_INVISIBILITY) == TRUE) - if (GetHasSpell(SPELL_SEE_INVISIBILITY)) - { - ActionCastSpellAtObject(SPELL_SEE_INVISIBILITY, OBJECT_SELF); - } - else -// if (GetHasSpell(SPELL_INVISIBILITY_PURGE) == TRUE) - if (GetHasSpell(SPELL_INVISIBILITY_PURGE)) - { - ActionCastSpellAtObject(SPELL_INVISIBILITY_PURGE, OBJECT_SELF); - } - else - { - ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.5); - ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.5); - ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 0.5); - } - } - } - - // activate ambient animations or walk waypoints if appropriate - if (!IsInConversation(OBJECT_SELF)) { - if (GetIsPostOrWalking()) { - WalkWayPoints(); - } else if (GetIsPC(oPercep) && - (GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS) - || GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN) - || GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS) - || GetIsEncounterCreature())) - { - SetAnimationCondition(NW_ANIM_FLAG_IS_ACTIVE); - } - } } - + if(!IsInConversation(oCreature)) + { + if(GetIsPostOrWalking()) + { + WalkWayPoints(); + } + else if(GetIsPC(oLastPerceived) && + (GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS) || + GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN) || + GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS) || + GetIsEncounterCreature())) + { + SetAnimationCondition(NW_ANIM_FLAG_IS_ACTIVE); + } + } // Send the user-defined event if appropriate - if(GetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT) && GetLastPerceptionSeen()) + if(GetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT) && bSeen) { SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_PERCEIVE)); } } - - - - diff --git a/src/module/nss/nw_c2_default3.nss b/src/module/nss/nw_c2_default3.nss index 572e123..567b327 100644 --- a/src/module/nss/nw_c2_default3.nss +++ b/src/module/nss/nw_c2_default3.nss @@ -1,56 +1,68 @@ -//:://///////////////////////////////////////////// -//:: Default: End of Combat Round -//:: NW_C2_DEFAULT3 -//:: Copyright (c) 2008 Bioware Corp. -//::////////////////////////////////////////////// -/* - Calls the end of combat script every round -*/ -//::////////////////////////////////////////////// -//:: Created By: Preston Watamaniuk -//:: Created On: Oct 16, 2001 -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// -//:: Modified By: Deva Winblood -//:: Modified On: Feb 16th, 2008 -//:: Added Support for Mounted Combat Feat Support -//::////////////////////////////////////////////// - -#include "NW_I0_GENERIC" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default3 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnCombatRoundEnd event script; + Fires at the end of each combat round (6 seconds). + This will fire as long as oCreature is in combat (GetIsInCombat()). + This event starts counting once a combat action is started. + Every time a spell is cast it will queue another end combat round so haste with + two spells cast will fire this twice in one round. + It will also fire at the end of a hostile effect that stops actions i.e Stunned, Knockdown etc. + Action modes are also cleared prior to this event executing! + GetAttemptedAttackTarget() & GetAttemptedSpellTarget() also get cleared prior to this event. + This event can be canceled with ClearAllActions(TRUE) and SurrenderToEnemies. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" void main() { - ExecuteScript("prc_npc_combat", OBJECT_SELF); - - if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT")) - { // set variables on target for mounted combat - DeleteLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL"); - DeleteLocalInt(OBJECT_SELF,"nX3_HP_BEFORE"); - DeleteLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT"); - if (GetHasFeat(FEAT_MOUNTED_COMBAT,OBJECT_SELF)) - { // check for AC increase - int nRoll=d20()+GetSkillRank(SKILL_RIDE); - nRoll=nRoll-10; - if (nRoll>4) - { // ac increase - nRoll=nRoll/5; - ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectACIncrease(nRoll),OBJECT_SELF,8.5); - } // ac increase - } // check for AC increase - } // set variables on target for mounted combat - - if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) - { - DetermineSpecialBehavior(); - } - else if(!GetSpawnInCondition(NW_FLAG_SET_WARNINGS)) - { - DetermineCombatRound(); - } + object oCreature = OBJECT_SELF; + ExecuteScript("prc_npc_combat", OBJECT_SELF); + if(AI_DEBUG) ai_Debug("nw_c2_default3", "20", GetName(oCreature) + " ends combat round." + + " Current action: " + IntToString(GetCurrentAction(oCreature))); if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1003)); } + if(ai_Disabled(oCreature)) return; + // Action modes get cleared prior to each OnCombatRoundEnd! + // We do this to keep the action mode going. + int nActionMode = GetLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + if(nActionMode > 0) + { + SetActionMode(oCreature, nActionMode, TRUE); + // We don't want to use up all of the Dwarven Defenders uses! + if(nActionMode == 12) IncrementRemainingFeatUses(oCreature, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE); + } + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("nw_c2_default3", "37", "nAction: " + IntToString(nAction)); + switch(nAction) + { + // These actions are uninteruptable. + case ACTION_MOVETOPOINT : + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_COUNTERSPELL : return; + // Might be doing a special action that is not a defined action. + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("nw_c2_default3", "49", "nCombatWait: " + IntToString(nCombatWait)); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + } + // We always want to interupt an attack action at the end of a round. + //case ACTION_ATTACKOBJECT : + } + if(ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound (oCreature); + return; + } + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) ai_DetermineSpecialBehavior(oCreature); } diff --git a/src/module/nss/nw_c2_default4.nss b/src/module/nss/nw_c2_default4.nss index de90459..cd1f616 100644 --- a/src/module/nss/nw_c2_default4.nss +++ b/src/module/nss/nw_c2_default4.nss @@ -1,93 +1,70 @@ -//::////////////////////////////////////////////////// -//:: NW_C2_DEFAULT4 -/* - Default OnConversation event handler for NPCs. - - */ -//::////////////////////////////////////////////////// -//:: Copyright (c) 2002 Floodgate Entertainment -//:: Created By: Naomi Novik -//:: Created On: 12/22/2002 -//::////////////////////////////////////////////////// - -#include "nw_i0_generic" -#include "prc_inc_spells" - +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_c2_4_convers + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnConversation; + Fires when oCreature has been clicked on for conversation. + Fires when oCreature hears a shout from another creature. + If SetListening is FALSE then oCreature will not "hear" anything. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void ai_MonsterCommands(object oCreature, object oSpeaker, int nMatch); void main() { - // * if petrified, jump out - if (PRCGetHasEffect(EFFECT_TYPE_PETRIFY, OBJECT_SELF) == TRUE) - { - return; - } - - // * If dead, exit directly. - if (GetIsDead(OBJECT_SELF) == TRUE) - { - return; - } - + object oCreature = OBJECT_SELF; ExecuteScript("prc_npc_conv", OBJECT_SELF); - - // See if what we just 'heard' matches any of our - // predefined patterns + if(AI_DEBUG) ai_Debug("nw_c2_default4", "15", GetName(oCreature) + " listens " + + IntToString(GetListenPatternNumber()) + " to " + GetName(GetLastSpeaker()) + "." + + " AI_AM_I_SEARCHING: " + IntToString(GetLocalInt(oCreature, AI_AM_I_SEARCHING))); + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature) || GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return; + if(ai_GetIsInCombat(oCreature)) + { + ai_DoMonsterCombatRound(oCreature); + return; + } + object oLastSpeaker = GetLastSpeaker(); int nMatch = GetListenPatternNumber(); - object oShouter = GetLastSpeaker(); - - if (nMatch == -1) + if(nMatch != -1) { - // Not a match -- start an ordinary conversation - if (GetCommandable(OBJECT_SELF)) - { - ClearActions(CLEAR_NW_C2_DEFAULT4_29); - BeginConversation(); - } - else - // * July 31 2004 - // * If only charmed then allow conversation - // * so you can have a better chance of convincing - // * people of lowering prices - if (PRCGetHasEffect(EFFECT_TYPE_CHARMED) == TRUE) - { - ClearActions(CLEAR_NW_C2_DEFAULT4_29); - BeginConversation(); - } + if(GetFactionEqual(oLastSpeaker, oCreature)) ai_MonsterCommands(oCreature, oLastSpeaker, nMatch); } - // Respond to shouts from friendly non-PCs only - else if (GetIsObjectValid(oShouter) - && !GetIsPC(oShouter) - && GetIsFriend(oShouter)) + else { - object oIntruder = OBJECT_INVALID; - // Determine the intruder if any - if(nMatch == 4) - { - oIntruder = GetLocalObject(oShouter, "NW_BLOCKER_INTRUDER"); - } - else if (nMatch == 5) - { - oIntruder = GetLastHostileActor(oShouter); - if(!GetIsObjectValid(oIntruder)) - { - oIntruder = GetAttemptedAttackTarget(); - if(!GetIsObjectValid(oIntruder)) - { - oIntruder = GetAttemptedSpellTarget(); - if(!GetIsObjectValid(oIntruder)) - { - oIntruder = OBJECT_INVALID; - } - } - } - } - - // Actually respond to the shout - RespondToShout(oShouter, nMatch, oIntruder); + ai_ClearCreatureActions(); + BeginConversation(); } - // Send the user-defined event if appropriate if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DIALOGUE)); } } +void ai_MonsterCommands(object oCreature, object oSpeaker, int nMatch) +{ + object oTarget = GetLocalObject(oSpeaker, AI_MY_TARGET); + if(nMatch == AI_ALLY_SEES_AN_ENEMY || nMatch == AI_ALLY_HEARD_AN_ENEMY) + { + if(AI_DEBUG) ai_Debug("nw_c2_default4", "46", GetName(oCreature) + " heard " + + GetName(oSpeaker) + " has seen an enemy!"); + if(ai_CanIAttack(oCreature)) ai_FindTheEnemy(oCreature, oSpeaker, oTarget, TRUE); + } + else if(nMatch == AI_ALLY_ATKED_BY_WEAPON || + nMatch == AI_ALLY_ATKED_BY_SPELL) + { + if(AI_DEBUG) ai_Debug("nw_c2_default4", "53", GetName(oCreature) + " heard " + + GetName(oSpeaker) + " has been attacked by " + + GetName(GetLocalObject(oSpeaker, AI_MY_TARGET)) + "!"); + if(ai_CanIAttack(oCreature)) ai_FindTheEnemy(oCreature, oSpeaker, oTarget, TRUE); + } + else if(nMatch == AI_ALLY_IS_WOUNDED) + { + if(AI_DEBUG) ai_Debug("nw_c2_default4", "60", GetName(oCreature) + " heard " + + GetName(oSpeaker) + " is wounded!"); + if(ai_GetIsInCombat(oCreature)) ai_TryHealingTalent(oCreature, ai_GetNumOfEnemiesInRange(oCreature), oSpeaker); + else ai_TryHealing(oCreature, oSpeaker); + } + /*else if(nMatch == AI_ALLY_IS_DEAD) + { + } */ +} + diff --git a/src/module/nss/nw_c2_default5.nss b/src/module/nss/nw_c2_default5.nss index d6e2e63..acc3b3e 100644 --- a/src/module/nss/nw_c2_default5.nss +++ b/src/module/nss/nw_c2_default5.nss @@ -1,71 +1,37 @@ -//:://///////////////////////////////////////////// -//:: Default On Attacked -//:: NW_C2_DEFAULT5 -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - If already fighting then ignore, else determine - combat round -*/ -//::////////////////////////////////////////////// -//:: Created By: Preston Watamaniuk -//:: Created On: Oct 16, 2001 -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// -//:: Modified By: Deva Winblood -//:: Modified On: Jan 4th, 2008 -//:: Added Support for Mounted Combat Feat Support -//::////////////////////////////////////////////// - -#include "nw_i0_generic" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default5 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnPhysicalAttacked event script; + Fires for all physical attacks, claws, weapons, fists, bow, etc. + Fires for taunt skill, animal empathy skill. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" void main() { + object oCreature = OBJECT_SELF; ExecuteScript("prc_npc_physatt", OBJECT_SELF); - - if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT")) - { // set variables on target for mounted combat - SetLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL",TRUE); - SetLocalInt(OBJECT_SELF,"nX3_HP_BEFORE",GetCurrentHitPoints(OBJECT_SELF)); - } // set variables on target for mounted combat - - if(GetFleeToExit()) { - // Run away! - ActivateFleeToExit(); - } else if (GetSpawnInCondition(NW_FLAG_SET_WARNINGS)) { - // We give an attacker one warning before we attack - // This is not fully implemented yet - SetSpawnInCondition(NW_FLAG_SET_WARNINGS, FALSE); - - //Put a check in to see if this attacker was the last attacker - //Possibly change the GetNPCWarning function to make the check - } else { - object oAttacker = GetLastAttacker(); - if (!GetIsObjectValid(oAttacker)) { - // Don't do anything, invalid attacker - - } else if (!GetIsFighting(OBJECT_SELF)) { - // We're not fighting anyone else, so - // start fighting the attacker - if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) { - SetSummonHelpIfAttacked(); - DetermineSpecialBehavior(oAttacker); - } else if (GetArea(oAttacker) == GetArea(OBJECT_SELF)) { - SetSummonHelpIfAttacked(); - DetermineCombatRound(oAttacker); - } - - //Shout Attack my target, only works with the On Spawn In setup - SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK); - - //Shout that I was attacked - SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK); - } + object oAttacker = GetLastAttacker(oCreature); + if(AI_DEBUG) ai_Debug("nw_c2_default5", "14", GetName(oCreature) + " was attacked by " + + GetName(oAttacker) + "."); + SetLocalObject(oAttacker, AI_ATTACKED_PHYSICAL, oCreature); + // Run away! + if(ai_GetFleeToExit(oCreature)) + { + ai_ActivateFleeToExit(oCreature); + return; } - - if(GetSpawnInCondition(NW_FLAG_ATTACK_EVENT)) { - SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_ATTACKED)); + SignalEvent(oCreature, EventUserDefined(EVENT_ATTACKED)); } + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(ai_GetIsInCombat(oCreature)) return; + // We only inform others if attacked when not busy, not disabled & not in combat. + if(AI_DEBUG) ai_Debug("nw_c2_default5", "30", "Tell my allies I've been attacked!"); + SetLocalObject (oCreature, AI_MY_TARGET, oAttacker); + SpeakString(AI_ATKED_BY_WEAPON, TALKVOLUME_SILENT_TALK); + // Now move towards the attack in the hopes we can see them. + if(GetDistanceBetween(oCreature, oAttacker) < AI_RANGE_CLOSE) ai_DoMonsterCombatRound(oCreature); + else ActionMoveToObject(oAttacker, TRUE, AI_RANGE_CLOSE); } diff --git a/src/module/nss/nw_c2_default6.nss b/src/module/nss/nw_c2_default6.nss index d362ecf..5347842 100644 --- a/src/module/nss/nw_c2_default6.nss +++ b/src/module/nss/nw_c2_default6.nss @@ -1,109 +1,36 @@ -//::////////////////////////////////////////////////// -//:: NW_C2_DEFAULT6 -//:: Default OnDamaged handler -/* - If already fighting then ignore, else determine - combat round - */ -//::////////////////////////////////////////////////// -//:: Copyright (c) 2002 Floodgate Entertainment -//:: Created By: Naomi Novik -//:: Created On: 12/22/2002 -//::////////////////////////////////////////////////// -//::////////////////////////////////////////////////// -//:: Modified By: Deva Winblood -//:: Modified On: Jan 17th, 2008 -//:: Added Support for Mounted Combat Feat Support -//::////////////////////////////////////////////////// - -#include "nw_i0_generic" -#include "x3_inc_horse" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default6 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnDamaged event script; + Does not fire if the creature dies from the damage. + Does not fire for plot creatures as they take no damage. + May fire before or after OnPhysicalAttacked event. + Fires when EffectDamage is applied to oCreature even if 0 damage. + Fires when a weapon damages a oCreature, but not if resisted. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" void main() { - ExecuteScript("prc_npc_damaged", OBJECT_SELF); - - object oDamager = GetLastDamager(); - object oMe=OBJECT_SELF; - int nHPBefore; - if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT")) - if (GetHasFeat(FEAT_MOUNTED_COMBAT)&&HorseGetIsMounted(OBJECT_SELF)) - { // see if can negate some damage - if (GetLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL")) - { // last attack was physical - nHPBefore=GetLocalInt(OBJECT_SELF,"nX3_HP_BEFORE"); - if (!GetLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT")) - { // haven't already had a chance to use this for the round - SetLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT",TRUE); - int nAttackRoll=GetBaseAttackBonus(oDamager)+d20(); - int nRideCheck=GetSkillRank(SKILL_RIDE,OBJECT_SELF)+d20(); - if (nRideCheck>=nAttackRoll&&!GetIsDead(OBJECT_SELF)) - { // averted attack - if (GetIsPC(oDamager)) SendMessageToPC(oDamager,GetName(OBJECT_SELF)+GetStringByStrRef(111991)); - //if (GetIsPC(OBJECT_SELF)) SendMessageToPCByStrRef(OBJECT_SELF,111992"); - if (GetCurrentHitPoints(OBJECT_SELF) (GetMaxHitPoints(OBJECT_SELF) / 4) - || (GetHitDice(oDamager) - 2) > GetHitDice(oTarget) - ) - ) - ) - { - // Switch targets - DetermineCombatRound(oDamager); - } - } - } - + object oCreature = OBJECT_SELF; + + ExecuteScript("prc_npc_damaged", OBJECT_SELF); + // Send the user-defined event signal if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT)) { - SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DAMAGED)); + SignalEvent(oCreature, EventUserDefined(EVENT_DAMAGED)); + return; } + if(ai_Disabled(oCreature)) return; + // Make sure to clear wounded shout limit if we take damage. See ai_TryHealing. + DeleteLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT"); + object oDamager = GetLastDamager(oCreature); + if(AI_DEBUG) ai_Debug("nw_c2_default6", "23", GetName(oCreature) + " has been damaged by " + GetName(oDamager)); + if(ai_GetFleeToExit(oCreature)) return; + if(GetObjectType(oDamager) == OBJECT_TYPE_AREA_OF_EFFECT && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature) || ai_GetIsInCombat(oCreature)) return; + if(GetDistanceBetween(oCreature, oDamager) < AI_RANGE_CLOSE) ai_DoMonsterCombatRound(oCreature); + else ActionMoveToObject(oDamager, TRUE, AI_RANGE_CLOSE - 1.0); } diff --git a/src/module/nss/nw_c2_default8.nss b/src/module/nss/nw_c2_default8.nss index 3e49428..fa7ef11 100644 --- a/src/module/nss/nw_c2_default8.nss +++ b/src/module/nss/nw_c2_default8.nss @@ -1,30 +1,26 @@ -//::////////////////////////////////////////////////// -//:: NW_C2_DEFAULT8 -/* - Default OnDisturbed event handler for NPCs. - */ -//::////////////////////////////////////////////////// -//:: Copyright (c) 2002 Floodgate Entertainment -//:: Created By: Naomi Novik -//:: Created On: 12/22/2002 -//::////////////////////////////////////////////////// - -#include "nw_i0_generic" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_default8 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnDisturbed event script; + Fires when the inventory of oCreature is changed i.e. added or removed. + Creatures can't have items added or removed from its inventory (it's not a + container), then the only way this fires for creatures if something is stolen. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" void main() { ExecuteScript("prc_npc_disturb", OBJECT_SELF); - - object oTarget = GetLastDisturbed(); - - // If we've been disturbed and are not already fighting, - // attack our disturber. - if (GetIsObjectValid(oTarget) && !GetIsFighting(OBJECT_SELF)) { - DetermineCombatRound(oTarget); - } - + + if(AI_DEBUG) ai_Debug("nw_c2_default8", "13", GetName(OBJECT_SELF) + " is been disturbed!"); + // We do nothing at the moment... lets not mess up our factions ok? + // This should be defined by the server admins and is commented out. + //if(ai_GetIsBusy(OBJECT_SELF, FALSE) || ai_Disabled()) return; + //object oTarget = GetLastDisturbed(); + //if (oTarget != OBJECT_INVALID) ai_DoMonsterCombatRound (); // Send the disturbed flag if appropriate. - if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) { + if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) + { SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DISTURBED)); } -} \ No newline at end of file +} diff --git a/src/module/nss/nw_c2_defaultb.nss b/src/module/nss/nw_c2_defaultb.nss index 1338544..3150026 100644 --- a/src/module/nss/nw_c2_defaultb.nss +++ b/src/module/nss/nw_c2_defaultb.nss @@ -1,159 +1,42 @@ -//:://///////////////////////////////////////////// -//:: Default: On Spell Cast At -//:: NW_C2_DEFAULTB -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - This determines if the spell just cast at the - target is harmful or not. - - GZ 2003-Oct-02 : - New AoE Behavior AI. Will use - Dispel Magic against AOES - - Flying Creatures will ignore - Grease - -*/ -//::////////////////////////////////////////////// -//:: Created By: Preston Watamaniuk -//:: Created On: Dec 6, 2001 -//:: Last Modified On: 2003-Oct-13 -//::////////////////////////////////////////////// -//::////////////////////////////////////////////// -//:: Modified By: Deva Winblood -//:: Modified On: Jan 4th, 2008 -//:: Added Support for Mounted Combat Feat Support -//::////////////////////////////////////////////// - -#include "nw_i0_generic" -#include "x2_i0_spells" - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_defaultb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monster OnSpellCastAt event script; + Fires when oCreature becomes the target of a spell via SignalEvent. + Fires when a healing kit is used on a creature. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" void main() { - ExecuteScript("prc_npc_spellat", OBJECT_SELF); - + object oCreature = OBJECT_SELF; object oCaster = GetLastSpellCaster(); - - - if(GetLastSpellHarmful()) - { - SetCommandable(TRUE); - - if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT")) - { // set variables on target for mounted combat - DeleteLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL"); - } // set variables on target for mounted combat - - // ------------------------------------------------------------------ - // If I was hurt by someone in my own faction - // Then clear any hostile feelings I have against them - // After all, we're all just trying to do our job here - // if we singe some eyebrow hair, oh well. - // ------------------------------------------------------------------ - if (GetFactionEqual(oCaster, OBJECT_SELF) == TRUE) - { - ClearPersonalReputation(oCaster, OBJECT_SELF); - ClearAllActions(TRUE); - DelayCommand(1.2, ActionDoCommand(DetermineCombatRound(OBJECT_INVALID))); - // Send the user-defined event as appropriate - if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT)) - { - SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_SPELL_CAST_AT)); - } - return; - } - - int bAttack = TRUE; - // ------------------------------------------------------------------ - // GZ, 2003-Oct-02 - // Try to do something smart if we are subject to an AoE Spell. - // ------------------------------------------------------------------ - if (MatchAreaOfEffectSpell(GetLastSpell()) == TRUE) - { - int nAI = (GetBestAOEBehavior(GetLastSpell())); // from x2_i0_spells - switch (nAI) - { - case X2_SPELL_AOEBEHAVIOR_DISPEL_L: - case X2_SPELL_AOEBEHAVIOR_DISPEL_N: - case X2_SPELL_AOEBEHAVIOR_DISPEL_M: - case X2_SPELL_AOEBEHAVIOR_DISPEL_G: - case X2_SPELL_AOEBEHAVIOR_DISPEL_C: - bAttack = FALSE; - ActionCastSpellAtLocation(nAI, GetLocation(OBJECT_SELF)); - ActionDoCommand(SetCommandable(TRUE)); - SetCommandable(FALSE); - break; - - case X2_SPELL_AOEBEHAVIOR_FLEE: - ClearActions(CLEAR_NW_C2_DEFAULTB_GUSTWIND); - oCaster = GetLastSpellCaster(); - ActionForceMoveToObject(oCaster, TRUE, 2.0); - DelayCommand(1.2, ActionDoCommand(DetermineCombatRound(oCaster))); - bAttack = FALSE; - break; - - case X2_SPELL_AOEBEHAVIOR_IGNORE: - // well ... nothing - break; - - case X2_SPELL_AOEBEHAVIOR_GUST: - ActionCastSpellAtLocation(SPELL_GUST_OF_WIND, GetLocation(OBJECT_SELF)); - ActionDoCommand(SetCommandable(TRUE)); - SetCommandable(FALSE); - bAttack = FALSE; - break; - } - - } - // --------------------------------------------------------------------- - // Not an area of effect spell, but another hostile spell. - // If we're not already fighting someone else, - // attack the caster. - // --------------------------------------------------------------------- - if( !GetIsFighting(OBJECT_SELF) && bAttack) - { - if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) - { - DetermineSpecialBehavior(oCaster); - } - else - { - DetermineCombatRound(oCaster); - } - } - - // We were attacked, so yell for help - SetCommandable(TRUE); - //Shout Attack my target, only works with the On Spawn In setup - SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK); - - //Shout that I was attacked - SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK); - } - else - { - // --------------------------------------------------------------------- - // July 14, 2003 BK - // If there is a valid enemy nearby and a NON HARMFUL spell has been - // cast on me I should call DetermineCombatRound - // I may be invisible and casting spells on myself to buff myself up - // --------------------------------------------------------------------- - // Fix: JE - let's only do this if I'm currently in combat. If I'm not - // in combat, and something casts a spell on me, it'll make me search - // out the nearest enemy, no matter where they are on the level, which - // is kinda dumb. - object oEnemy =GetNearestEnemy(); - if ((GetIsObjectValid(oEnemy) == TRUE) && (GetIsInCombat() == TRUE)) - { - // SpeakString("keep me in combat"); - DetermineCombatRound(oEnemy); - } - } - + SetLocalObject(oCaster, AI_ATTACKED_SPELL, oCreature); + if(ai_Disabled(oCreature)) return; + ExecuteScript("prc_npc_spellat", OBJECT_SELF); + if(!GetLastSpellHarmful()) return; // Send the user-defined event as appropriate if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_SPELL_CAST_AT)); } - - + // If the spell came from an ally, we don't want to hold it against them. + if(GetFactionEqual(oCaster, oCreature)) ClearPersonalReputation(oCaster, oCreature); + // Lets see what kind of area of effect this is and select an appropriate action. + int nSpell = GetLastSpell(); + if(AI_DEBUG) ai_Debug("nw_c2_defaultb", "26", GetName(oCreature) + " has been hit by a harmful spell(" + + Get2DAString("spells", "Label", nSpell) + ")!"); + if(ai_GetInAOEReaction(oCreature, oCaster, nSpell) && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature)) return; + if(ai_CheckForCombat(oCreature, TRUE)) return; + // We have been attacked out of combat, so let our allies know. + SetLocalObject(oCreature, AI_MY_TARGET, oCaster); + SpeakString(AI_ATKED_BY_SPELL, TALKVOLUME_SILENT_TALK); + if(GetDistanceBetween(oCreature, oCaster) < AI_RANGE_CLOSE) + { + if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) ai_DetermineSpecialBehavior(oCreature); + else ai_DoMonsterCombatRound(oCreature); + } + else ActionMoveToObject(oCaster, TRUE, AI_RANGE_CLOSE); } diff --git a/src/module/nss/nw_c2_defaulte.nss b/src/module/nss/nw_c2_defaulte.nss index 3d8ab2c..76f62db 100644 --- a/src/module/nss/nw_c2_defaulte.nss +++ b/src/module/nss/nw_c2_defaulte.nss @@ -1,51 +1,53 @@ -//:://///////////////////////////////////////////// -//:: Default On Blocked -//:: NW_C2_DEFAULTE -//:: Copyright (c) 2001 Bioware Corp. -//::////////////////////////////////////////////// -/* - This will cause blocked creatures to open - or smash down doors depending on int and - str. -*/ -//::////////////////////////////////////////////// -//:: Created By: Preston Watamaniuk -//:: Created On: Nov 23, 2001 -//::////////////////////////////////////////////// - +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_c2_defaulte + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Monsters OnBlocked event script; + Can be blocked by a creature or door. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" void main() { - ExecuteScript("prc_npc_blocked", OBJECT_SELF); - - object oDoor = GetBlockingDoor(); - if (GetObjectType(oDoor) == OBJECT_TYPE_CREATURE) + object oCreature = OBJECT_SELF; + // This actually gets either a Creature or Door that is blocking OBJECT_SELF. + object oObject = GetBlockingDoor(); + if(AI_DEBUG) ai_Debug("nw_c2_defaulte", "14", GetName(oCreature) + " is being blocked by " + GetName(oObject)); + int nObjectType = GetObjectType(oObject); + if(nObjectType == OBJECT_TYPE_CREATURE) { - // * Increment number of times blocked - /*SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED", GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") + 1); - if (GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") > 3) + if(GetIsEnemy(oObject, oCreature)) { - SpeakString("Blocked by creature"); - SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED",0); - ClearAllActions(); - object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY); - if (GetIsObjectValid(oEnemy) == TRUE) + if(ai_CanIAttack(oCreature) && ai_GetIsInCombat(oCreature)) { - ActionEquipMostDamagingRanged(oEnemy); - ActionAttack(oEnemy); + ai_DoMonsterCombatRound(oCreature); + return; } - return; - } */ + if(ai_CheckForCombat(oCreature, TRUE)) return; + } + } + // Anything below blocking us is a door. + if(nObjectType != OBJECT_TYPE_DOOR) return; + // Only open the door if the player has turned door opening on. + if(!GetLocalInt(GetModule(), AI_RULE_OPEN_DOORS)) return; + //if(GetLockKeyTag(oObject) != "") return; + else if(GetIsDoorActionPossible(oObject, DOOR_ACTION_OPEN) && + GetAbilityScore(oCreature, ABILITY_INTELLIGENCE) >= 5) + { + if(AI_DEBUG) ai_Debug("nw_c2_defaulte", "33", GetName(oCreature) + " is opening " + GetName(oObject)); + DoDoorAction(oObject, DOOR_ACTION_OPEN); return; } - if(GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 5) + // If we are in combat we should ignore doors that do not easily open. + if(GetIsDoorActionPossible(oObject, DOOR_ACTION_BASH) && + ai_GetWeaponDamage(oCreature, 3, TRUE) > GetHardness(oObject) && + GetLockKeyTag(oObject) == "") { - if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN) && GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 7 ) - { - DoDoorAction(oDoor, DOOR_ACTION_OPEN); - } - else if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_BASH)) - { - DoDoorAction(oDoor, DOOR_ACTION_BASH); - } + ActionWait(1.0); + ActionAttack(oObject); + // Give them 3 rounds to break through a door. + DelayCommand(18.0, ai_ClearCreatureActions(TRUE)); + return; } } + + diff --git a/src/module/nss/nw_ch_ac1.nss b/src/module/nss/nw_ch_ac1.nss new file mode 100644 index 0000000..6ed2fea --- /dev/null +++ b/src/module/nss/nw_ch_ac1.nss @@ -0,0 +1,158 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac1 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate(Summons, Familiar, Companion) OnHeart beat script when out of combat; + This will usually fire every 6 seconds (1 game round). +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_module" +#include "0i_menus" +void ai_ActionFollow(object oCreature, object oTarget) +{ + if(GetLocalInt(OBJECT_SELF, AI_CURRENT_ACTION_MODE) == AI_LAST_ACTION_MOVE) + { + float fDistance = GetDistanceBetween(oCreature, oTarget); + float fFollowDistance = ai_GetFollowDistance(oCreature); + if(fDistance > fFollowDistance) + { + if(fDistance > fFollowDistance * 5.0 && + ai_GetIsInCombat(oCreature)) AssignCommand(oCreature, JumpToObject(oTarget)); + else + { + ClearAllActions(); + ActionMoveToObject(oTarget, TRUE, fFollowDistance); + } + } + DelayCommand(1.0, ai_ActionFollow(oCreature, oTarget)); + } +} +void main() +{ + if (GetAILevel(OBJECT_SELF) == AI_LEVEL_VERY_LOW) return; + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Counter_Start(); + // We run our OnSpawn in the heartbeat so the creator can use the original + // OnSpawn for their own use. + ai_OnAssociateSpawn(oCreature); + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat, ai_OnAssociateSpawn"); + if(AI_DEBUG) ai_Debug("nw_ch_ac1", "37", GetName(oCreature) + " Heartbeat." + + " MODE_FOLLOW: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_FOLLOW)) + + " Action: " + IntToString(GetCurrentAction(oCreature))); + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat, ai_GetIsBusy/ai_Disabled"); + // If we are an associate and don't have a master then exit. + object oMaster = GetMaster(oCreature); + if(AI_DEBUG) ai_Debug("nw_ch_ac1", "43", "oMaster: " + GetName(oMaster)); + if(oMaster == OBJECT_INVALID) + { + if(ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound(oCreature); + return; + } + ai_CheckForCombat(oCreature, FALSE); + return; + } + // ***** Code for Henchman data and menus ***** + if(ai_GetIsCharacter(oMaster)) + { + string sAssociateType = ai_GetAssociateType(oMaster, oCreature); + ai_CheckAssociateData(oMaster, oCreature, sAssociateType); + ai_CheckPCStart(oMaster); + if(AI_HENCHMAN_WIDGET) + { + // This keeps widgets from disappearing and reappearing. + int nUiToken = NuiFindWindow(oMaster, sAssociateType + AI_WIDGET_NUI); + if(nUiToken) + { + json jData = NuiGetUserData(oMaster, nUiToken); + object oAssociate = StringToObject(JsonGetString(JsonArrayGet(jData, 0))); + if(oAssociate != oCreature) NuiDestroy(oMaster, nUiToken); + } + else + { + if(!ai_GetWidgetButton(oMaster, BTN_WIDGET_OFF, oCreature, sAssociateType)) + { + ai_CreateWidgetNUI(oMaster, oCreature); + } + } + } + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat, Get Associate data/Build widget"); + } + // If follow mode we do not want the NPC doing anything but follow. + if(!ai_GetAIMode(oCreature, AI_MODE_FOLLOW)) + { + if(ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND)) + { + ai_TryHealing(oCreature, oCreature); + return; + } + if(ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound(oCreature); + return; + } + if(ai_CheckForCombat(oCreature, FALSE)) return; + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat, ai_CheckForCombat"); + if(IsInConversation(oCreature)) return; + // In command mode we let the player tell us what to do. + if(!ai_GetAIMode(oCreature, AI_MODE_COMMANDED)) + { + if(ai_TryHealing(oCreature, oCreature)) return; + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat: TryHealing"); + if(ai_CheckNearbyObjects(oCreature)) return; + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat: CheckNearbyObjects"); + if(ai_GetAIMode(oCreature, AI_MODE_SCOUT_AHEAD)) + { + ai_ScoutAhead(oCreature); + return; + } + } + } + // Finally we check to make sure we are following our master. + if(GetCurrentAction(oCreature) != ACTION_FOLLOW) + { + //ai_Debug("nw_ch_ac1", "66", "Follow master: " + + // " Stealth: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH)) + + // " Search: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH))); + if(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH)) + { + if(AI_DEBUG) ai_Debug("nw_ch_ac1", "120", "Going into stealth mode!"); + int nStealth = GetSkillRank(SKILL_HIDE, oCreature); + nStealth += GetSkillRank(SKILL_MOVE_SILENTLY, oCreature); + if(nStealth / 2 >= ai_GetCharacterLevels(oCreature)) + { + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + } + } + else + { + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + if(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH)) + { + if(AI_DEBUG) ai_Debug("nw_ch_ac1", "134", "Going into search mode!"); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + } + else SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + } + // Follow master. + if(GetDistanceBetween(oCreature, oMaster) > ai_GetFollowDistance(oCreature)) + { + if(!ai_GetAIMode(oCreature, AI_MODE_COMMANDED)) + { + object oTarget = GetLocalObject(oCreature, AI_FOLLOW_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oMaster; + //ActionForceFollowObject(oTarget, ai_GetFollowDistance(oCreature)); + //ActionMoveToObject(oTarget, TRUE, ai_GetFollowDistance(oCreature)); + SetLocalInt(oCreature, AI_CURRENT_ACTION_MODE, AI_LAST_ACTION_MOVE); + ai_ActionFollow(oCreature, oTarget); + } + } + } + if(AI_DEBUG) ai_Counter_End(GetName(oCreature) + ": Heartbeat, end"); + if(GetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1001)); + } +} diff --git a/src/module/nss/nw_ch_ac2.nss b/src/module/nss/nw_ch_ac2.nss new file mode 100644 index 0000000..04a56f9 --- /dev/null +++ b/src/module/nss/nw_ch_ac2.nss @@ -0,0 +1,107 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac2 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate(Summons, Familiars, Companions) OnPerception script when not in combat; + There are 4 types of perception - Heard, Inaudible, Seen, Vanished. + Only one type will ever be true in an event trigger. + The order of trigger is Heard/Seen and Inaudible/Vanished. + There are two states of percepion Heard and Seen. + These states can be set at the same time thus a heard event can see the creature. + Fires when ever one of these states changes from TRUE to FALSE or FALSE to TRUE. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oLastPerceived = GetLastPerceived(); + if(AI_DEBUG) + { + if(GetLastPerceptionHeard ()) + { + ai_Debug("nw_ch_ac2", "21", GetName(oCreature) + " heard " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + + " Seen: " + IntToString(GetObjectSeen(oLastPerceived, oCreature)) + "."); + } + if(GetLastPerceptionSeen ()) + { + ai_Debug("nw_ch_ac2", "29", GetName(oCreature) + " sees " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + "."); + } + if(GetLastPerceptionVanished ()) + { + ai_Debug("nw_ch_ac2", "35", GetName(oCreature) + " lost sight of " + + GetName(GetLastPerceived()) + "."); + } + } + // We do nothing on Inaudibles so drop out early! + if(GetLastPerceptionInaudible()) + { + ai_Debug("nw_ch_ac2", "42", GetName(oCreature) + " lost sound of " + + GetName(GetLastPerceived()) + "."); + return; + } + if(AI_DEBUG) ai_Debug("nw_ch_ac2", "46", "Dead? " + IntToString(GetIsDead(oLastPerceived)) + + " Enemy? " + IntToString(GetIsEnemy(oLastPerceived, oCreature))); + if(ai_Disabled(oCreature)) return; + if(GetIsDead(oLastPerceived) || !GetIsEnemy(oLastPerceived, oCreature)) return; + // All code below assumes the perceived creature is an enemy and is alive! + // **************************** ENEMY HEARD ******************************** + if(GetLastPerceptionHeard()) + { + // Since Heard is run before Seen, but the values are set at the same + // time we can skip heard checks on heard & seen creatures! + if(GetObjectSeen(oLastPerceived, oCreature)) + { + // If the creature we are perceiving was our invisible creature then + // remove that they are invisible. + if(oLastPerceived == GetLocalObject(oCreature, AI_IS_INVISIBLE)) + { + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); + } + ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_SEE_AN_ENEMY); + } + else ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_HEARD_AN_ENEMY); + return; + } + // **************************** ENEMY SEEN ********************************* + if(GetLastPerceptionSeen()) + { + // If the creature we are perceiving was our invisible creature then + // remove that they are invisible. + if(oLastPerceived == GetLocalObject(oCreature, AI_IS_INVISIBLE)) + { + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); + } + ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_SEE_AN_ENEMY); + return; + } + // **************************** ENEMY VANISHED ***************************** + if(GetLastPerceptionVanished()) + { + // Lets keep a mental note of the invisible creature. + SetLocalObject(oCreature, AI_IS_INVISIBLE, oLastPerceived); + if(AI_DEBUG) ai_Debug("nw_ch_ac2", "86", " We saw " + GetName(oLastPerceived) + " disappear!"); + if(ai_GetIsBusy(oCreature)) return; + // If in combat check to see if our target disappeared. + // If they have and we are not in melee with them then reevaluate combat + // since we lost our target. + if(ai_GetIsInCombat(oCreature)) + { + if(AI_DEBUG) ai_Debug("nw_ch_ac2", "93", "Is this our target? " + + IntToString(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived)); + if(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived) + { + ai_DoAssociateCombatRound(oCreature); + } + return; + } + // If they are not invisible then that means they left our perception + // range and we need follow them. + if(ai_CanIAttack(oCreature)) ActionMoveToObject(oLastPerceived, TRUE, AI_RANGE_CLOSE); + } + // **************************** ENEMY INAUDIBLE***************************** + // Not used. +} diff --git a/src/module/nss/nw_ch_ac3.nss b/src/module/nss/nw_ch_ac3.nss new file mode 100644 index 0000000..9eb3406 --- /dev/null +++ b/src/module/nss/nw_ch_ac3.nss @@ -0,0 +1,56 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac3 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate (Summons, Familiars, Companions) OnCombatRoundEnd event script; + Fires at the end of each combat round (6 seconds). + This will fire as long as oCreature is in combat (GetIsInCombat()). + This event starts counting once a combat action is started. + Every time a spell is cast it will queue another end combat round so haste with + two spells cast will fire this twice in one round. + It will also fire at the end of a hostile effect that stops actions i.e Stunned, Knockdown etc. + Action modes are also cleared prior to this event executing! + GetAttemptedAttackTarget() & GetAttemptedSpellTarget() also get cleared prior to this event. + This event can be canceled with ClearAllActions(TRUE) and SurrenderToEnemies. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("nw_ch_ac3", "20", GetName(oCreature) + " ends combat round."); + if(ai_Disabled(oCreature)) return; + // Action modes get cleared prior to each OnCombatRoundEnd! + // We do this to keep the action mode going. + int nActionMode = GetLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + if(nActionMode > 0) + { + SetActionMode(oCreature, nActionMode, TRUE); + // We don't want to use up all of the Dwarven Defenders uses! + if(nActionMode == 12) IncrementRemainingFeatUses(oCreature, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE); + } + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("nw_ch_ac3", "32", "nAction: " + IntToString(nAction)); + switch(nAction) + { + // These actions are uninteruptable. + case ACTION_MOVETOPOINT : + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_COUNTERSPELL : return; + // Might be doing a special action that is not a defined action. + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("nw_ch_ac3", "44", "nCombatWait: " + IntToString(nCombatWait)); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + } + // We always want to interupt an attack action at the end of a round. + //case ACTION_ATTACKOBJECT : + } + if(ai_GetIsInCombat(oCreature)) ai_DoAssociateCombatRound (oCreature); +} + diff --git a/src/module/nss/nw_ch_ac4.nss b/src/module/nss/nw_ch_ac4.nss new file mode 100644 index 0000000..f6c290d --- /dev/null +++ b/src/module/nss/nw_ch_ac4.nss @@ -0,0 +1,45 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac4 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate(Summons, Familiar, Companion) OnDialoge event script; + Fires when oCreature has been clicked on for conversation. + Fires when oCreature hears a shout from another creature. + If SetListening is FALSE then oCreature will not "hear" anything. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +#include "nw_inc_gff" +void main() +{ + object oCreature = OBJECT_SELF; + int nMatch = GetListenPatternNumber(); + if(AI_DEBUG) ai_Debug("nw_ch_ac4", "16", GetName(oCreature) + " listens " + + IntToString(nMatch) + " to " + GetName(GetLastSpeaker()) + "."); + // Skip ASSOCIATE_COMMAND_MASTERUNDERATTACK(11) since it fires for + // every physical attack made on our master. This fires alot! + if(nMatch == ASSOCIATE_COMMAND_MASTERUNDERATTACK) return; + // If we are disabled then we can't listen or talk, Busy is checked in ai_SelectAssociateCommand(). + if(ai_Disabled(oCreature)) return; + object oLastSpeaker = GetLastSpeaker(); + // Some commands override being busy so we check in ai_SelectAssociateCommand. + if(nMatch != -1) + { + if(GetFactionEqual(oLastSpeaker, oCreature)) ai_SelectAssociateCommand(oCreature, oLastSpeaker, nMatch); + } + else + { + if (!ai_GetIsBusy(oCreature)) + { + ai_ClearCreatureActions(); + if(GetAssociateType(oCreature) == ASSOCIATE_TYPE_HENCHMAN) BeginConversation("oc_ai_henchmen", oLastSpeaker); + else + { + json jHenchman = ObjectToJson(oCreature); + string sConversation = JsonGetString(GffGetResRef(jHenchman, "Conversation")); + if(sConversation == "") BeginConversation("oc_ai_henchmen", oLastSpeaker); + BeginConversation(); + } + } + } +} + diff --git a/src/module/nss/nw_ch_ac5.nss b/src/module/nss/nw_ch_ac5.nss new file mode 100644 index 0000000..78f9321 --- /dev/null +++ b/src/module/nss/nw_ch_ac5.nss @@ -0,0 +1,51 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac5 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associates (Summons, Familiars, Companions) OnPhysicalAttacked event script; + Fires for all physical attacks, claws, weapons, fists, bow, etc. + Fires for taunt skill, animal empathy skill. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oAttacker = GetLastAttacker(); + if(AI_DEBUG) ai_Debug("nw_ch_ac5", "14", GetName(oCreature) + " was attacked by " + + GetName(oAttacker) + "."); + SetLocalObject(oAttacker, AI_ATTACKED_PHYSICAL, oCreature); + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(GetSpawnInCondition(NW_FLAG_ATTACK_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1005)); + } + if(ai_GetIsInCombat(oCreature)) return; + // We only inform others if attacked when not busy, not disabled, & not in combat. + SetLocalObject(oCreature, AI_MY_TARGET, oAttacker); + SpeakString(AI_ATKED_BY_WEAPON, TALKVOLUME_SILENT_TALK); + // If they are using a melee weapon then make sure we are using our perception range. + // Don't go running towards them just yet, but if its a ranged weapon then react. + if(ai_GetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oAttacker))) + { + float fDistance = GetDistanceBetween(oCreature, oAttacker); + float fPerceptionDistance = GetLocalFloat(oCreature, AI_ASSOC_PERCEPTION_DISTANCE); + if(fDistance > fPerceptionDistance) return; + } + int nAction = GetCurrentAction(oCreature); + float fDistance = GetDistanceBetween(oCreature, oAttacker); + if(!ai_CanIAttack(oCreature)) + { + // We should defend ourselves if we are in Hold mode. + if(!ai_GetAIMode(oCreature, AI_MODE_STAND_GROUND)) return; + // Only defend against melee attacks. + if(fDistance > AI_RANGE_MELEE) return; + } + // The only way to get here is to not be in combat. + if(fDistance < AI_RANGE_CLOSE) + { + ai_StartAssociateCombat(oCreature); + } + else ActionMoveToObject(oAttacker, TRUE, AI_RANGE_CLOSE - 1.0); +} + + diff --git a/src/module/nss/nw_ch_ac6.nss b/src/module/nss/nw_ch_ac6.nss new file mode 100644 index 0000000..f51e937 --- /dev/null +++ b/src/module/nss/nw_ch_ac6.nss @@ -0,0 +1,32 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_ch_6_damaged + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnDamaged script for PC AI; + Does not fire if the creature dies from the damage. + Does not fire for plot creatures as they take no damage. + May fire before or after OnPhysicalAttacked event. + Fires when EffectDamage is applied to oCreature even if 0 damage. + Fires when a weapon damages a oCreature, but not if resisted. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + if(ai_Disabled(oCreature)) return; + // Make sure to clear wounded shout limit if we take damage. See ai_TryHealing. + DeleteLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT"); + object oDamager = GetLastDamager(oCreature); + if(AI_DEBUG) ai_Debug("nw_ch_ac6", "18", GetName(oCreature) + " has been damaged by " + GetName(oDamager)); + if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1006)); + } + if(GetObjectType(oDamager) == OBJECT_TYPE_AREA_OF_EFFECT && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature) || ai_GetIsInCombat(oCreature)) return; + if(!ai_CanIAttack(oCreature)) return; + if(GetDistanceBetween(oCreature, oDamager) < AI_RANGE_CLOSE) ai_DoAssociateCombatRound(oCreature); + else ActionMoveToObject(oDamager, TRUE, AI_RANGE_CLOSE - 1.0); +} + diff --git a/src/module/nss/nw_ch_ac8.nss b/src/module/nss/nw_ch_ac8.nss new file mode 100644 index 0000000..05b7f85 --- /dev/null +++ b/src/module/nss/nw_ch_ac8.nss @@ -0,0 +1,25 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_ac8 + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associates (Summons, Familiars, Companions) OnDisturbed event script. + Fires when the inventory of oCreature is changed i.e. added or removed. + Creatures can't have items added or removed from its inventory (it's not a + container), then the only way this fires for creatures if something is stolen. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + if(AI_DEBUG) ai_Debug("nw_ch_ac8", "13", GetName(OBJECT_SELF) + " is been disturbed!"); + if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1008)); + } + // We do nothing at the moment... lets not mess up our factions ok? + // This should be defined by the server admins and is commented out. + //if(ai_GetIsBusy(OBJECT_SELF, FALSE) || ai_Disabled()) return; + //object oTarget = GetLastDisturbed(); + //if (oTarget != OBJECT_INVALID) ai_DoMonsterCombatRound (); +} + + diff --git a/src/module/nss/nw_ch_aca.nss b/src/module/nss/nw_ch_aca.nss new file mode 100644 index 0000000..99b6d5f --- /dev/null +++ b/src/module/nss/nw_ch_aca.nss @@ -0,0 +1,46 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_aca + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate OnRested event script; + Fires when the creature attempts to rest via ActionRest or a PC rests. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_menus" +void ai_UpdateAssociateWidget(object oMaster, object oAssociate, int nUIToken) +{ + if(nUIToken) NuiDestroy(oMaster, nUIToken); + ai_CreateWidgetNUI(oMaster, oAssociate); + if(oMaster != oAssociate) + { + nUIToken = NuiFindWindow(oMaster, "pc" + AI_WIDGET_NUI); + if(nUIToken) + { + NuiDestroy(oMaster, nUIToken); + ai_CreateWidgetNUI(oMaster, oMaster); + } + } +} +void main() +{ + object oAssociate = OBJECT_SELF; + ai_ClearCreatureActions(); + ai_OnRested(oAssociate); + object oMaster = GetMaster(oAssociate); + if(ai_GetIsCharacter(oMaster) && AI_HENCHMAN_WIDGET) + { + int nLevel = ai_GetCharacterLevels(oAssociate); + float fDelay = StringToFloat(Get2DAString("restduration", "DURATION", nLevel)); + fDelay = (fDelay / 1000.0f) + 6.0f; + // Update widget for spell widget. + string sAssociateType = ai_GetAssociateType(oMaster, oAssociate); + int nUIToken = NuiFindWindow(oMaster, sAssociateType + AI_WIDGET_NUI); + if(nUIToken) DelayCommand(fDelay, ai_UpdateAssociateWidget(oMaster, oAssociate, nUIToken)); + else + { + if(!ai_GetWidgetButton(oMaster, BTN_WIDGET_OFF, oAssociate, sAssociateType)) + { + DelayCommand(fDelay, ai_UpdateAssociateWidget(oMaster, oAssociate, 0)); + } + } + } +} diff --git a/src/module/nss/nw_ch_acb.nss b/src/module/nss/nw_ch_acb.nss new file mode 100644 index 0000000..ec96e77 --- /dev/null +++ b/src/module/nss/nw_ch_acb.nss @@ -0,0 +1,42 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: nw_ch_acb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associates (Summons, Familiars, Companions) OnSpellCastAt event script; + Fires when oCreature becomes the target of a spell via SignalEvent. + Fires when a healing kit is used on a creature. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oCaster = GetLastSpellCaster(); + SetLocalObject(oCaster, AI_ATTACKED_SPELL, oCreature); + if(ai_Disabled(oCreature)) return; + if(!GetLastSpellHarmful()) return; + // If the spell came from an ally, we don't want to hold it against them. + if(GetFactionEqual(oCaster, oCreature)) + { + ClearPersonalReputation(oCaster, oCreature); + if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_SPELL_CAST_AT)); + } + } + // Lets see what kind of area of effect this is and select an appropriate action. + int nSpell = GetLastSpell(); + if(AI_DEBUG) ai_Debug("nw_ch_acb", "21", GetName(OBJECT_SELF) + " has been hit by a harmful spell(" + + Get2DAString("spells", "Label", nSpell) + ")!"); + if(ai_GetInAOEReaction(oCreature, oCaster, nSpell) && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature)) return; + if(ai_CheckForCombat(oCreature, FALSE)) return; + // We were attacked by an enemy out of combat, so let our allies know. + SetLocalObject(oCreature, AI_MY_TARGET, oCaster); + SpeakString(AI_ATKED_BY_SPELL, TALKVOLUME_SILENT_TALK); + if(!ai_CanIAttack(oCreature)) return; + if(GetDistanceBetween(oCreature, oCaster) < AI_RANGE_CLOSE) ai_DoAssociateCombatRound(oCreature); + else ActionMoveToObject(oCaster, TRUE, AI_RANGE_CLOSE - 1.0); +} + + diff --git a/src/module/nss/nw_ch_ace.nss b/src/module/nss/nw_ch_ace.nss new file mode 100644 index 0000000..688ab90 --- /dev/null +++ b/src/module/nss/nw_ch_ace.nss @@ -0,0 +1,60 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: 0e_ch_e_blocked + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associates OnBlocked event script; + Can be blocked by a creature or door. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + // This actually gets either a Creature or Door that is blocking OBJECT_SELF. + object oObject = GetBlockingDoor(); + if(AI_DEBUG) ai_Debug("nw_ch_ace", "14", GetName(oCreature) + " is being blocked by " + GetName(oObject)); + int nObjectType = GetObjectType(oObject); + if(nObjectType == OBJECT_TYPE_CREATURE) + { + if(GetIsEnemy(oObject, oCreature)) + { + if(ai_CanIAttack(oCreature) && ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound(oCreature); + return; + } + if(ai_CheckForCombat(oCreature, FALSE)) return; + } + } + // Anything below blocking us is a door. + if(nObjectType != OBJECT_TYPE_DOOR) return; + if(!ai_GetAIMode(oCreature, AI_MODE_OPEN_DOORS)) return; + //if(GetLockKeyTag(oObject) != "") return; + else if(GetIsDoorActionPossible(oObject, DOOR_ACTION_OPEN) && + GetAbilityScore(oCreature, ABILITY_INTELLIGENCE) >= 5) + { + DoDoorAction(oObject, DOOR_ACTION_OPEN); + return; + } + // Anything below is ignored in combat. + if(ai_GetIsInCombat(oCreature)) return; + if(GetIsDoorActionPossible(oObject, DOOR_ACTION_BASH) && + ai_GetWeaponDamage(oCreature, 3, TRUE) > GetHardness(oObject) && + GetLockKeyTag(oObject) == "") + { + ActionWait(1.0); + ActionAttack(oObject); + // Give them 3 rounds to break through a door. + DelayCommand(18.0, ai_ClearCreatureActions(TRUE)); + return; + } + else if(GetLocked(oObject)) + { + if(AI_DEBUG) ai_Debug("nw_ch_ace", "49", GetName(oObject) + " is locked!"); + ai_AttemptToByPassLock(oCreature, oObject); + } + // Clear our action so we can move on to something else unless the door is open. + else if(!GetIsOpen(oObject)) + { + ai_ClearCreatureActions(); + } +} diff --git a/src/module/nss/nw_ch_summon_9.nss b/src/module/nss/nw_ch_summon_9.nss new file mode 100644 index 0000000..ca5a87c --- /dev/null +++ b/src/module/nss/nw_ch_summon_9.nss @@ -0,0 +1,40 @@ +//:://///////////////////////////////////////////// +//:: Associate: On Spawn In +//:: nw_ch_summon_9 +//:: Copyright (c) 2001 Bioware Corp. +//::////////////////////////////////////////////// +/* + +This must support the OC henchmen and all summoned/companion +creatures. + +*/ +//::////////////////////////////////////////////// +//:: Created By: Preston Watamaniuk +//:: Created On: Nov 19, 2001 +//::////////////////////////////////////////////// +//:: Updated By: Georg Zoeller, 2003-08-20: Added variable check for spawn in animation +#include "X0_INC_HENAI" +#include "x2_inc_switches" +void main() +{ + //Sets up the special henchmen listening patterns + SetAssociateListenPatterns(); + + // Set additional henchman listening patterns + //bkSetListeningPatterns(); + // * If Incorporeal, apply changes + if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_IS_INCORPOREAL) == TRUE) + { + effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL); + eConceal = ExtraordinaryEffect(eConceal); + effect eGhost = EffectCutsceneGhost(); + eGhost = ExtraordinaryEffect(eGhost); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF); + } + // Set starting location + SetAssociateStartLocation(); +} + + diff --git a/src/module/nss/pc_savebuffs.nss b/src/module/nss/pc_savebuffs.nss new file mode 100644 index 0000000..96b42d0 --- /dev/null +++ b/src/module/nss/pc_savebuffs.nss @@ -0,0 +1,182 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pc_savebuffs +//////////////////////////////////////////////////////////////////////////////// + Used with pi_buffing to run the buffing plugin for + Philos Single Player Enhancements. + +Note: If a spell saves incorrectly check the spell script to see if the correct +spell is being passed through the SignalEvent correctly. +Known error in Shield of Faith spell as the below code in the shield of faith +script sends Camoflage instead! +"SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, 421, FALSE));" +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag = ""); +// sDataField should be one of the data fields for that table. +// sData is the string data to be saved. +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag = ""); +// sDataField should be one of the data fields for that table. +// jData is the json data to be saved. +void SetBuffDatabaseJson(object oPlayer, string sDataField, json jData, string sTag = ""); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +json GetBuffDatabaseJson(object oPlayer, string sDataField, string sTag = ""); +// Returns the level if this spell has a domain spell on nLevel, or 0. +int GetHasDomainSpell(object oCaster, int nClass, int nLevel, int nSpell); + +// We do some crazy hack to get all the correct information when casting spells. +// GetLastSpellCastClass() will only give the class if this script is running +// on the actual caster, i.e. our PC. +// GetLastSpellLevel() will only give the level if this script is running on +// the actual caster, i.e. our PC. +// So for this to work we run this scrip in the event OnSpellCastAt of our +// target, then we ExecuteScript this script again with the Caster (oPC) +// as OBJECT_SELF for this script on its second pass. This allows us to get the +// information from the above functions! Neat! +void main() +{ + object oTarget = OBJECT_SELF; + // The first pass we get oCaster via GetLastSpellCaster() fails in ExecuteScript! + // The second pass we get oCaster via the variable "AI_BUFF_CASTER". + object oCaster = GetLocalObject(oTarget, "AI_BUFF_CASTER"); + if(oCaster == OBJECT_INVALID) oCaster = GetLastSpellCaster(); + // We setting up the save spells button we saved the PC to itself. + // Here we get the PC to make sure the caster of this spell is our saving PC. + object oPC = GetLocalObject(oCaster, "AI_BUFF_PC"); + // The first pass we get nspell via GetLastSpell() fails in ExecuteScript! + // The second pass we get nSpell via the variable "AI_BUFF_SPELL". + int nSpell = GetLocalInt(oTarget, "AI_BUFF_SPELL"); + if(nSpell == 0) nSpell = GetLastSpell(); + // If this is a harful spell or The caster does not equal our saving PC then + // we need to fix the targets scripts back and run the correct OnSpellCastAt script. + if(GetLastSpellHarmful() || oPC != oCaster) + { + string sScript = GetLocalString(oTarget, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + ExecuteScript(sScript, oTarget); + return; + } + // If the oTarget != oCaster then we are casting a spell on one of our + // associates. We must make a second pass to get the correct information. + // We do this by saving the Target, Caster, and Spell so we can get them + // in the second pass as Execute Script makes them impossible to get on a + // second pass. + if(oTarget != oCaster) + { + SetLocalObject(oPC, "AI_BUFF_TARGET", oTarget); + SetLocalObject(oPC, "AI_BUFF_CASTER", oCaster); + SetLocalInt(oPC, "AI_BUFF_SPELL", nSpell); + ExecuteScript("pc_savebuffs", oPC); + return; + } + // If this is the first pass and we get here then oCaster is casting a spell + // on themselves. So oTarget will be invalid and we should use oPC. + // If this is the second pass and we get here then we have saved oTarget + // to oPC and this will get them so we can save the target to the spell! + oTarget = GetLocalObject(oPC, "AI_BUFF_TARGET"); + if(oTarget == OBJECT_INVALID) oTarget = oPC; + // We need to clean up this mess! + DeleteLocalObject(oPC, "AI_BUFF_TARGET"); + DeleteLocalObject(oPC, "AI_BUFF_CASTER"); + DeleteLocalInt(oPC, "AI_BUFF_SPELL"); + // This blocks one spell from saving multiple times due to being an AOE. + if(GetLocalInt(oPC, "AI_ONLY_ONE")) return; + SetLocalInt(oPC, "AI_ONLY_ONE", TRUE); + // We delay this for just less than half a round due to haste. + DelayCommand(2.5, DeleteLocalInt(oPC, "AI_ONLY_ONE")); + // Here is the whole problem and why we must do a second pass if the target + // is not the caster. These only work if this script is run by the caster. + int nClass = GetLastSpellCastClass(); + int nLevel = GetLastSpellLevel(); + // Everything below saves the spell to the database with all our now correct info. + int nDomain = GetHasDomainSpell(oPC, nClass, nLevel, nSpell); + int nMetaMagic = GetMetaMagicFeat(); + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(nDomain) sName += " [Domain]"; + if(nMetaMagic > 0 && StringToInt(Get2DAString("classes", "MemorizesSpells", nClass))) + { + // We must add the level of the metamagic to the spells level to get the spells correct level. + if(nMetaMagic == METAMAGIC_EMPOWER) { sName += " (Empowered)"; nLevel += 2; } + else if(nMetaMagic == METAMAGIC_EXTEND) { sName += " (Extended)"; nLevel += 1; } + else if(nMetaMagic == METAMAGIC_MAXIMIZE) { sName += " (Maximized)"; nLevel += 3; } + else if(nMetaMagic == METAMAGIC_QUICKEN) { sName += " (Quickened)"; nLevel += 4; } + else if(nMetaMagic == METAMAGIC_SILENT) { sName += " (Silent)"; nLevel += 1; } + else if(nMetaMagic == METAMAGIC_STILL) { sName += " (Still)"; nLevel += 1; } + } + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + string sList = JsonGetString(JsonArrayGet(jMenuData, 0)); + json jSpells = GetBuffDatabaseJson(oPC, "spells", sList); + json jSpell = JsonArray(); + jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nClass)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nMetaMagic)); + jSpell = JsonArrayInsert(jSpell, JsonInt(nDomain)); + string sTargetName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget, TRUE))); + jSpell = JsonArrayInsert(jSpell, JsonString(sTargetName)); + jSpell = JsonArrayInsert(jSpells, jSpell); + SetBuffDatabaseJson(oPC, "spells", jSpells, sList); + SendMessageToPC(oPC, sName + " has been saved for fast buffing on " + sTargetName + "."); + ExecuteScript("pi_buffing", oPC); +} +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if (SqlStep (sql)) return SqlGetString (sql, 0); + else return ""; +} +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@data", sData); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + SqlStep (sql); +} +void SetBuffDatabaseJson (object oPlayer, string sDataField, json jData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindJson (sql, "@data", jData); + SqlBindString (sql, "@name", sName); + SqlBindString (sql, "@tag", sTag); + SqlStep (sql); +} +json GetBuffDatabaseJson (object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString (sql, "@name", sName); + SqlBindString (sql, "@tag", sTag); + if (SqlStep (sql)) return SqlGetJson (sql, 0); + else return JsonArray (); +} +int GetHasDomainSpell(object oCaster, int nClass, int nLevel, int nSpell) +{ + int nIndex, nMaxIndex, nMSpell, nMmSpell, bDomain, nSubRadSpell, nSubSpell; + string sSubRadSpell; + if(StringToInt(Get2DAString("classes", "MemorizesSpells", nClass))) + { + nMaxIndex = GetMemorizedSpellCountByLevel(oCaster, nClass, nLevel); + while(nIndex < nMaxIndex) + { + nMSpell = GetMemorizedSpellId(oCaster, nClass, nLevel, nIndex); + if(nSpell == nMSpell) + { + if(GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex)) return nLevel; + } + nIndex ++; + } + } + return 0; +} diff --git a/src/module/nss/pe_buffing.nss b/src/module/nss/pe_buffing.nss new file mode 100644 index 0000000..a6c4050 --- /dev/null +++ b/src/module/nss/pe_buffing.nss @@ -0,0 +1,534 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pe_buffing +//////////////////////////////////////////////////////////////////////////////// + Used with pi_buffing to run the buffing plugin for + Philos Single Player Enhancements. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" + +const int BUFF_MAX_SPELLS = 50; +const string FB_NO_MONSTER_CHECK = "FB_NO_MONSTER_CHECK"; + +// sDataField should be one of the data fields for that table. +// sData is the string data to be saved. +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag); +// sDataField should be one of the data fields for that table. +// jData is the json data to be saved. +void SetBuffDatabaseJson(object oPlayer, string sDataField, json jData, string sTag); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +json GetBuffDatabaseJson(object oPlayer, string sDataField, string sTag); +// Casts all buff spells saved to the widget button. +void CastSavedBuffSpells(object oPC); +// Will check and make sure the spell is memorized and/or ready. +// Returns TRUE if memorized and ready, FALSE if memorized but not ready, +// and -1 if not memorized for classes that memorize. +// nSpell is the spell to find. +// nClass that cast the spell. +// nLevel the level of the spell. +// nMetamagic is if it has metamagic on it. +// nDomain is if it is a domain spell. +int GetSpellReady(object oCaster, int nSpell, int nClass, int nLevel, int nMetamagic, int nDomain); +// Creates the Buffing widget. +void PopupWidgetBuffGUIPanel(object oPC); +void main() +{ + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + string sWndId = NuiGetWindowId (oPC, nToken); + //************************************************************************** + // Watch to see if the window moves and save. + if(sElem == "window_geometry" && sEvent == "watch") + { + if(!GetLocalInt (oPC, AI_NO_NUI_SAVE)) + { + // Get the height, width, x, and y of the window. + json jGeom = NuiGetBind(oPC, nToken, "window_geometry"); + // Save on the player using the sWndId. + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + if(sWndId == "plbuffwin") + { + jMenuData = JsonArraySet(jMenuData, 1, JsonObjectGet(jGeom, "x")); + jMenuData = JsonArraySet(jMenuData, 2, JsonObjectGet(jGeom, "y")); + } + else if(sWndId == "widgetbuffwin") + { + jMenuData = JsonArraySet(jMenuData, 5, JsonObjectGet(jGeom, "x")); + jMenuData = JsonArraySet(jMenuData, 6, JsonObjectGet(jGeom, "y")); + } + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + } + return; + } + //************************************************************************** + // Spell Buffing. + if(sWndId == "plbuffwin") + { + if(sEvent == "click") + { + string sList; + if(GetStringLeft(sElem, 10) == "btn_spell_") + { + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + sList = JsonGetString(JsonArrayGet(jMenuData, 0)); + json jSpells = GetBuffDatabaseJson(oPC, "spells", sList); + int nIndex = StringToInt(GetStringRight(sElem, GetStringLength(sElem) - 10)); + int nSpell = JsonGetInt(JsonArrayGet(JsonArrayGet(jSpells, nIndex), 0)); + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + jSpells = JsonArrayDel(jSpells, nIndex); + SetBuffDatabaseJson(oPC, "spells", jSpells, sList); + ai_SendMessages(sName + " has been removed from the list.", AI_COLOR_YELLOW, oPC); + ExecuteScript("pi_buffing", oPC); + } + else if(sElem == "btn_save") + { + string sScript; + object oCreature; + if(JsonGetInt(NuiGetBind (oPC, nToken, "btn_save"))) + { + sScript = GetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + SetLocalObject(oPC, "AI_BUFF_PC", oPC); + SetLocalString(oPC, "AI_BUFF_CAST_AT_SCRIPT", sScript); + SetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "pc_savebuffs"); + // Setup your followers to allow spells to be saved on them as well. + int nAssociateType = 2; + object oAssociate = GetAssociate(nAssociateType, oPC); + while(nAssociateType < 5) + { + if(oAssociate != OBJECT_INVALID) + { + SetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT", sScript); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "pc_savebuffs"); + } + oAssociate = GetAssociate(++nAssociateType, oPC); + } + int nIndex = 1; + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(nIndex <= AI_MAX_HENCHMAN) + { + if(oAssociate != OBJECT_INVALID) + { + SetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT", sScript); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "pc_savebuffs"); + } + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + ai_SendMessages("Cast spells on yourself or an associate to save them to the widget.", AI_COLOR_YELLOW, oPC); + } + else + { + DeleteLocalObject(oPC, "AI_BUFF_PC"); + sScript = GetLocalString(oPC, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oPC, "AI_BUFF_CAST_AT_SCRIPT"); + // Cleanup your followers to allow spells to be reacted to as normal. + int nAssociateType = 2; + object oAssociate = GetAssociate(nAssociateType, oPC); + while(nAssociateType < 5) + { + if(oAssociate != OBJECT_INVALID) + { + sScript = GetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + } + oAssociate = GetAssociate(++nAssociateType, oPC); + } + int nIndex = 1; + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(nIndex <= AI_MAX_HENCHMAN) + { + if(oAssociate != OBJECT_INVALID) + { + sScript = GetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + } + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + NuiSetBind(oPC, nToken, "btn_save", JsonBool(FALSE)); + ai_SendMessages("Saving spells to the list has been turned off.", AI_COLOR_YELLOW, oPC); + } + } + else if(sElem == "btn_clear") + { + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + sList = JsonGetString(JsonArrayGet(jMenuData, 0)); + SetBuffDatabaseJson(oPC, "spells", JsonArray(), sList); + ExecuteScript("pi_buffing", oPC); + } + else if(sElem == "btn_buff") CastSavedBuffSpells(oPC); + // Runs all the List 1-4 buttons. + if(GetStringLeft(sElem, 8) == "btn_list") + { + sList = "list" + GetStringRight(sElem, 1); + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + jMenuData = JsonArraySet(jMenuData, 0, JsonString(sList)); + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + ExecuteScript("pi_buffing", oPC); + } + } + else if(sEvent == "watch") + { + if(sElem == "buff_widget_check") + { + int bBuffWidget = JsonGetInt(NuiGetBind(oPC, nToken, "buff_widget_check")); + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + jMenuData = JsonArraySet(jMenuData, 3, JsonBool(bBuffWidget)); + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + if(bBuffWidget) PopupWidgetBuffGUIPanel(oPC); + else NuiDestroy(oPC, NuiFindWindow(oPC, "widgetbuffwin")); + } + if(sElem == "lock_buff_widget_check") + { + int bBuffLockWidget = JsonGetInt(NuiGetBind(oPC, nToken, "lock_buff_widget_check")); + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + if(bBuffLockWidget) jMenuData = JsonArraySet(jMenuData, 3, JsonBool(TRUE)); + jMenuData = JsonArraySet(jMenuData, 4, JsonBool(bBuffLockWidget)); + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + NuiSetBind(oPC, nToken, "buff_widget_check", JsonBool(TRUE)); + PopupWidgetBuffGUIPanel(oPC); + } + if(sElem == "chbx_no_monster_check_check") + { + int bNoCheckMonsters = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetLocalInt(oPC, FB_NO_MONSTER_CHECK, bNoCheckMonsters); + } + } + } + //************************************************************************** + // Spell Buffing. + else if(sWndId == "widgetbuffwin") + { + if(sEvent == "click") + { + string sList; + if(sElem == "btn_one") sList = "list1"; + if(sElem == "btn_two") sList = "list2"; + if(sElem == "btn_three") sList = "list3"; + if(sElem == "btn_four") sList = "list4"; + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + jMenuData = JsonArraySet(jMenuData, 0, JsonString(sList)); + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + CastSavedBuffSpells(oPC); + } + } +} +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@data", sData); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + SqlStep (sql); +} +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if (SqlStep (sql)) return SqlGetString (sql, 0); + else return ""; +} +void SetBuffDatabaseJson (object oPlayer, string sDataField, json jData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindJson (sql, "@data", jData); + SqlBindString (sql, "@name", sName); + SqlBindString (sql, "@tag", sTag); + SqlStep (sql); +} +json GetBuffDatabaseJson (object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if(SqlStep(sql)) return SqlGetJson(sql, 0); + else return JsonArray(); +} +void CastBuffSpell (object oPC, object oTarget, int nSpell, int nClass, int nMetamagic, int nDomain, string sList, string sName) +{ + string sTargetName; + if(oPC == oTarget) sTargetName = "myself."; + else sTargetName = GetName(oTarget); + ai_SendMessages("Quick Buffing: " + sName + " on " + sTargetName, AI_COLOR_GREEN, oPC); + AssignCommand(oPC, ActionCastSpellAtObject(nSpell, oTarget, nMetamagic, FALSE, nDomain, 0, TRUE, nClass)); +} +void CastSavedBuffSpells(object oPC) +{ + // Lets make sure the save button is off! + if(GetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT) == "pc_savebuffs") + { + string sScript = GetLocalString(oPC, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oPC, "AI_BUFF_CAST_AT_SCRIPT"); + // Cleanup your followers to allow spells to be reacted to as normal. + int nAssociateType = 2; + object oAssociate = GetAssociate(nAssociateType, oPC); + while(nAssociateType < 5) + { + if(oAssociate != OBJECT_INVALID) + { + sScript = GetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + } + oAssociate = GetAssociate(++nAssociateType, oPC); + } + int nIndex = 1; + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(nIndex <= AI_MAX_HENCHMAN) + { + if(oAssociate != OBJECT_INVALID) + { + sScript = GetLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + DeleteLocalString(oAssociate, "AI_BUFF_CAST_AT_SCRIPT"); + } + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + int nMainWindow = NuiFindWindow(oPC, "plbuffwin"); + if(nMainWindow) NuiSetBind(oPC, nMainWindow, "btn_save", JsonBool(FALSE)); + ai_SendMessages("Saving spells to the list has been turned off.", AI_COLOR_YELLOW, oPC); + } + float fDistance; + if(!GetLocalInt(oPC, FB_NO_MONSTER_CHECK)) + { + // Check for monsters! We cannot let them buff if they are close to the enemy! + object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oPC); + fDistance = GetDistanceBetween(oPC, oEnemy); + } + if(fDistance > 30.0f || fDistance == 0.0) + { + string sName; + float fDelay = 0.1f; + int nSpell, nClass, nLevel, nMetamagic, nDomain, nSpellReady, nIndex = 0; + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + string sList = JsonGetString(JsonArrayGet(jMenuData, 0)); + json jSpell, jSpells = GetBuffDatabaseJson(oPC, "spells", sList); + while(nIndex <= BUFF_MAX_SPELLS) + { + jSpell = JsonArrayGet(jSpells, nIndex); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nLevel = JsonGetInt(JsonArrayGet(jSpell, 2)); + nMetamagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + // We save the target's name then look them up by it. + string sTargetName = JsonGetString(JsonArrayGet(jSpell, 5)); + object oTarget; + location lLocation = GetLocation(oPC); + if(sTargetName == "" || sTargetName == ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName (oPC)))) oTarget = oPC; + else + { + oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, lLocation, TRUE); + while(oTarget != OBJECT_INVALID) + { + if(sTargetName == ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget)))) break; + oTarget = GetNextObjectInShape(SHAPE_SPHERE, 10.0, lLocation, TRUE); + } + } + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + if(oTarget == OBJECT_INVALID) + { + DelayCommand(fDelay, ai_SendMessages("Cannot quick cast " + sName + " because the " + sTargetName + " is not here!", AI_COLOR_RED, oPC)); + } + else + { + if(nMetamagic > 0) + { + if(nMetamagic == METAMAGIC_EMPOWER) sName += " (Empowered)"; + else if(nMetamagic == METAMAGIC_EXTEND) sName += " (Extended)"; + else if(nMetamagic == METAMAGIC_MAXIMIZE) sName += " (Maximized)"; + else if(nMetamagic == METAMAGIC_QUICKEN) sName += " (Quickened)"; + else if(nMetamagic == METAMAGIC_SILENT) sName += " (Silent)"; + else if(nMetamagic == METAMAGIC_STILL) sName += " (Still)"; + } + nSpellReady = GetSpellReady(oPC, nSpell, nClass, nLevel, nMetamagic, nDomain); + if(nSpellReady == TRUE) + { + DelayCommand(fDelay, CastBuffSpell(oPC, oTarget, nSpell, nClass, nMetamagic, nDomain, sList, sName)); + } + else if(nSpellReady == -1) + { + DelayCommand(fDelay, ai_SendMessages("Cannot quick cast " + sName + " because it is not ready to cast!", AI_COLOR_RED, oPC)); + } + else if(nSpellReady == -2) + { + DelayCommand (fDelay, ai_SendMessages("Cannot quick cast " + sName + " because it is not memorized!", AI_COLOR_RED, oPC)); + } + else if(nSpellReady == -3) + { + DelayCommand (fDelay, ai_SendMessages("Cannot quick cast " + sName + " because there are no spell slots of that level left!", AI_COLOR_RED, oPC)); + } + else if(nSpellReady == -4) + { + DelayCommand (fDelay, ai_SendMessages("Cannot quick cast " + sName + " because that spell is not known.", AI_COLOR_RED, oPC)); + } + fDelay += 0.1f; + } + } + else break; + nIndex ++; + } + if(nIndex == 0 && !NuiFindWindow(oPC, "plbuffwin")) ExecuteScript("pi_buffing", oPC); + } + else ai_SendMessages("Enemies are too close for you to cast all your buff spells!", AI_COLOR_RED, oPC); +} +int GetSpellReady(object oCaster, int nSpell, int nClass, int nLevel, int nMetamagic, int nDomain) +{ + int nIndex, nMaxIndex, nMSpell, nMmSpell, nDSpell, nSubRadSpell, nSubSpell; + string sSubRadSpell; + if(StringToInt(Get2DAString("classes", "MemorizesSpells", nClass))) + { + int nSpellMemorized; + while(nIndex < nMaxIndex) + { + nMSpell = GetMemorizedSpellId(oCaster, nClass, nLevel, nIndex); + if(nSpell == nMSpell) + { + nMmSpell = GetMemorizedSpellMetaMagic(oCaster, nClass, nLevel, nIndex); + nDSpell = GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex); + //ai_Debug("pe_buffing", "308", "nMmSpell: " + IntToString(nMmSpell) + + // " nMetamagic: " + IntToString(nMetamagic) + + // " nDomain: " + IntToString(nDomain) + + // " nDSpell: " + IntToString(nDSpell)); + // Cannot save the domain status so we just use the first spell ID. + // Then return the domain statusl. + //if(nMmSpell == nMetamagic && + // ((nDomain > 0 && nDSpell == TRUE) || nDomain == 0 && nDSpell == FALSE)) + if(nMmSpell == nMetamagic) + { + nSpellMemorized = TRUE; + if(GetMemorizedSpellReady(oCaster, nClass, nLevel, nIndex)) + { + if(nDSpell == nDomain) return TRUE; + } + } + } + for(nSubRadSpell = 1; nSubRadSpell < 5; nSubRadSpell++) + { + sSubRadSpell = "SubRadSpell" + IntToString(nSubRadSpell); + if(nSpell == StringToInt(Get2DAString("spells", sSubRadSpell, nMSpell))) + nMmSpell = GetMemorizedSpellMetaMagic(oCaster, nClass, nLevel, nIndex); + nDSpell = GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex); + ai_Debug("pe_buffing", "421", "nMmSpell: " + IntToString(nMmSpell) + + " nMetamagic: " + IntToString(nMetamagic) + + " nDomain: " + IntToString(nDomain) + + " nDSpell: " + IntToString(nDSpell)); + if(nMmSpell == nMetamagic) + { + nSpellMemorized = TRUE; + if(GetMemorizedSpellReady(oCaster, nClass, nLevel, nIndex)) + { + if(nDSpell == nDomain) return TRUE; + } + } + } + nIndex ++; + } + if(nSpellMemorized) return -1; + return -2; + } + else + { + int nSpellKnown; + nMaxIndex = GetKnownSpellCount(oCaster, nClass, nLevel); + while(nIndex < nMaxIndex) + { + nMSpell = GetKnownSpellId(oCaster, nClass, nLevel, nIndex); + if(nSpell == nMSpell) + { + nSpellKnown = TRUE; + if(GetSpellUsesLeft(oCaster, nClass, nSpell)) return TRUE; + } + for(nSubRadSpell = 1; nSubRadSpell < 5; nSubRadSpell++) + { + sSubRadSpell = "SubRadSpell" + IntToString(nSubRadSpell); + if(nSpell == StringToInt(Get2DAString("spells", sSubRadSpell, nMSpell))) + { + nSpellKnown = TRUE; + if(GetSpellUsesLeft(oCaster, nClass, nSpell)) return TRUE; + } + } + nIndex ++; + } + if(nSpellKnown) return -3; + return -4; + } + return -2; +} +void PopupWidgetBuffGUIPanel(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // Row 1 (buttons)********************************************************** + + json jRow = CreateButtonImage(JsonArray(), "ir_level1", "btn_one", 35.0f, 35.0f, 0.0); + jRow = CreateButtonImage(jRow, "ir_level2", "btn_two", 35.0f, 35.0f, 0.0); + jRow = CreateButtonImage(jRow, "ir_level3", "btn_three", 35.0f, 35.0f, 0.0); + jRow = CreateButtonImage(jRow, "ir_level4", "btn_four", 35.0f, 35.0f, 0.0); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + int bAIBuffWidgetLock = JsonGetInt(JsonArrayGet(jMenuData, 4)); + // Get the window location to restore it from the database. + float fX = JsonGetFloat(JsonArrayGet(jMenuData, 5)); + float fY = JsonGetFloat(JsonArrayGet(jMenuData, 6)); + if(fX == 0.0f && fY == 0.0f) + { + fX = 10.0f; + fY = 10.0f; + } + float fGUI_Scale = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0; + if(bAIBuffWidgetLock) + { + fX += 4.0f; + // GUI scales are a mess, I just figured them out per scale to keep the widget from moving. + if(fGUI_Scale == 1.0) fY += 37.0; + else if(fGUI_Scale == 1.1) fY += 38.0; + else if(fGUI_Scale == 1.2) fY += 40.0; + else if(fGUI_Scale == 1.3) fY += 42.0; + else if(fGUI_Scale == 1.4) fY += 43.0; + else if(fGUI_Scale == 1.5) fY += 45.0; + else if(fGUI_Scale == 1.6) fY += 47.0; + else if(fGUI_Scale == 1.7) fY += 48.0; + else if(fGUI_Scale == 1.8) fY += 50.0; + else if(fGUI_Scale == 1.9) fY += 52.0; + else if(fGUI_Scale == 2.0) fY += 54.0; + } + // Set the layout of the window. + json jLayout = NuiCol(jCol); + int nToken; + if(bAIBuffWidgetLock) nToken = SetWindow (oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 62.0, FALSE, FALSE, FALSE, TRUE, FALSE, "pe_buffing"); + else nToken = SetWindow (oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 95.0, FALSE, FALSE, FALSE, TRUE, TRUE, "pe_buffing"); + // Set event watches for window inspector and save window location. + NuiSetBindWatch (oPC, nToken, "collapsed", TRUE); + NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE); + // Set the buttons to show events. + //NuiSetBind (oPC, nToken, "btn_one", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_one_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_two", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_two_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_three", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_three_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_four", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_four_event", JsonBool (TRUE)); +} + diff --git a/src/module/nss/pe_crafting.nss b/src/module/nss/pe_crafting.nss new file mode 100644 index 0000000..388c86a --- /dev/null +++ b/src/module/nss/pe_crafting.nss @@ -0,0 +1,2153 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pe_crafting +//////////////////////////////////////////////////////////////////////////////// + Used with pi_crafting to run the crafting plugin events for + Philos Single Player Enhancements. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "nw_inc_gff" +#include "0i_main" +#include "0i_items" +// Maximum model number for all items except weapons. +const int CRAFT_MAX_MODEL_NUMBER = 999; + +struct stWeaponAppearance +{ + object oItem; + int nModel; + int nColor; + string sPart; +}; +// Maximum model number for weapons. Note this will be the 100s and 10s places. +// The color number uses the ones place. Thus 25 is actually 250. +const int CRAFT_MAX_WEAPON_MODEL_NUMBER = 99; +const string CRAFT_JSON = "CRAFT_JSON"; +const string CRAFT_ORIGINAL_ITEM = "CRAFT_ORIGINAL_ITEM"; +const string CRAFT_COOL_DOWN = "CRAFT_COOL_DOWN"; +const string CRAFT_ITEM_SELECTION = "CRAFT_ITEM_SELECTION"; +const string CRAFT_MATERIAL_SELECTION = "CRAFT_MATERIAL_SELECTION"; +const string CRAFT_MODEL_SELECTION = "CRAFT_MODEL_SELECTION"; +const string CRAFT_MODEL_SPECIAL = "CRAFT_MODEL_SPECIAL"; +const string CRAFT_ITEM_TYPE = "CRAFT_ITEM_TYPE"; +const string CRAFT_WEAPON_MOD_TOP = "CRAFT_WEAPON_MOD_TOP"; +const string CRAFT_WEAPON_MOD_MID = "CRAFT_WEAPON_MOD_MID"; +const string CRAFT_WEAPON_MOD_BOT = "CRAFT_WEAPON_MOD_BOT"; +const string CRAFT_WEAPON_COL_TOP = "CRAFT_WEAPON_COL_TOP"; +const string CRAFT_WEAPON_COL_MID = "CRAFT_WEAPON_COL_MID"; +const string CRAFT_WEAPON_COL_BOT = "CRAFT_WEAPON_COL_BOT"; +const string CRAFT_COPY_ITEM = "CRAFT_COPY_ITEM"; +const string CRAFT_COPY_ITEM_TYPE = "CRAFT_COPY_ITEM_TYPE"; +const string CRAFT_COPY_MODEL = "CRAFT_COPY_MODEL"; +const string CRAFT_COPY_COLOR = "CRAFT_COPY_COLOR"; +const string CRAFT_COPY_PART_COLOR = "CRAFT_COPY_PART_COLOR"; +const string CRAFT_ARMOR_AC = "CRAFT_ARMOR_AC"; +const string CRAFT_COLOR_PALLET = "CRAFT_COLOR_PALLET"; +const string CRAFT_LEFT_PART_COLOR = "CRAFT_LEFT_PART_COLOR"; +const string CRAFT_ALL_COLOR = "CRAFT_ALL_COLOR"; +const string CRAFT_RIGHT_PART_COLOR = "CRAFT_RIGHT_PART_COLOR"; +const string CRAFT_TARGET = "CRAFT_TARGET"; +// Tag used in lighting effects. +const string CRAFT_HIGHLIGHT = "CRAFT_HIGHLIGHT"; +const string CRAFT_ULTRALIGHT = "CRAFT_ULTRALIGHT"; +// The tags for containers used to do some crafting. +const string CRAFT_TEMPLATE = "x3_plc_basket"; +const string CRAFT_CONTAINER = "CRAFT_CONTAINER"; +// Used in the crafting GUI to copy an item to be pasted to another item later. +void CopyCraftingItem(object oPC, object oItem); +// Used in the crafting GUI to paste a copy of an item to another item. +object PasteCraftingItem(object oPC, object oTarget, object oItem); +int GetItemSelectedEquipSlot(int nItemSelected); +int GetArmorModelSelected(object oPC); +object ChangeItemsAppearance(object oPC, object oTarget, int nToken, object oItem, int nDirection, string sPart); +// Checks to see if the item can be crafted. +// bPasteCheck is a special check when an item is being pasted. +int CanCraftItem(object oPC, object oItem, int nToken, int bPasteCheck = FALSE); +object RandomizeItemsCraftAppearance(object oPlayer, object oTarget, int nToken, object oItem); +// Returns the correct item based on the crafting menu selected item. +object GetSelectedItem(object oTarget, int nItemSelected); +// Cancels the crafted item for the player and restoring the original. +void CancelCraftedItem(object oPlayer, object oTarget); +// Gets the colorId from a image of the color pallet. +// Thanks Zunath for the base code. +int GetColorPalletId(object oPC, int nToken); +// Sets the pointer based on current Item, Part, and Material selected. +void SetColorPalletPointer(object oPC, int nToken, object oItem); +// Locks/Unlocks specific buttons when an item has been changed. +void LockItemInCraftingWindow(object oPC, object oItem, object oTarget, int nToken); +// Locks/Unlocks specific buttons when an item has been cleared. +void ClearItemInCraftingWindow(object oPC, object oItem, int nToken); +// Saves the crafted item for the player removing the original. +void SaveCraftedItem(object oPC, object oTarget, int nToken); +// Remove Effect of type specified from oCreature; +// sEffectTag is the tag of the effect to remove. +// Feat, Class, Racial. +void RemoveTagedEffects(object oCreature, string sEffectTag); +// Returns TRUE/FALSE if item has temporary item property. +int CheckForTemporaryItemProperty(object oItem); +// Updates the model number text in the NUI menu. +void SetModelNumberText(object oPC, object oTarget, int nToken); +// Sets the material buttons for use. +// nMaterial 0,1 Cloth 2,3 Leather 4,5 Metal -1 None. +void SetMaterialButtons(object oPC, int nToken, int nMaterial); +// Creates the item editing menu. +void CreateItemGUIPanel(object oPC, object oTarget); +// Events for ItemGUIPanel +void CraftItemInfoEvents(object oPC, int nToken); +// Creates the save/load menu for items. +//void CreateDresserGUIPanel(object oPC, object oTarget); + +int GetColorIDChange(object oItem, int nType, int nIndex, int nChange) +{ + int nColorId = GetItemAppearance(oItem, nType, nIndex) + nChange; + if(nColorId > 175) return 0; + if(nColorId < 0) return 175; + return nColorId; +} +void main() +{ + // Get the last player to use targeting mode + object oPC = GetLastPlayerToSelectTarget(); + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + if(oPC == OBJECT_SELF && sTargetMode != "") + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + //vector vTarget = GetTargetingModeSelectedPosition(); + //location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + //object oObject = GetLocalObject(oPC, "AI_TARGET_OBJECT"); + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget))// && vTarget == Vector()) + { + return; + } + // Targeting code here. + if(sTargetMode == "SELECT_TARGET") + { + if(GetAssociateType(oTarget) == ASSOCIATE_TYPE_HENCHMAN || + ai_GetIsCharacter(oTarget)) + { + SetLocalObject(oPC, CRAFT_TARGET, oTarget); + AttachCamera(oPC, oTarget); + ExecuteScript("pi_crafting", oPC); + } + else ai_SendMessages(GetName(oTarget) + " is not the player or a henchmen! Other associates cannot use item crafting.", AI_COLOR_RED, oPC); + } + DeleteLocalString(oPC, AI_TARGET_MODE); + } + else + { + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sWndId = NuiGetWindowId (oPC, nToken); + if(sWndId == "craft_item_nui") + { + CraftItemInfoEvents(oPC, nToken); + return; + } + string sEvent = NuiGetEventType(); + // We don't use and it causes error windows to go off! Return early! + if(sEvent == "mouseup") return; + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + //SendMessageToPC(oPC, "0e_crafting, 144, sElem: " + sElem + " sEvent: " + sEvent); + //************************************************************************** + // Watch to see if the window moves and save. + if(sElem == "window_geometry" && sEvent == "watch") + { + if(!GetLocalInt (oPC, AI_NO_NUI_SAVE)) + { + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + if(JsonGetType(jCraft) == JSON_TYPE_NULL) jCraft = JsonObject(); + // Get the height, width, x, and y of the window. + json jGeometry = NuiGetBind(oPC, nToken, "window_geometry"); + jCraft = JsonObjectSet(jCraft, "CRAFT_MENU", jGeometry); + SetLocalJson(oPC, CRAFT_JSON, jCraft); + } + return; + } + //************************************************************************** + object oTarget = GetLocalObject(oPC, CRAFT_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oPC; + // Get the item we are crafting. + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetSelectedItem(oTarget, nItemSelected); + object oOriginalItem = GetLocalObject(oPC, CRAFT_ORIGINAL_ITEM); + if(oItem == OBJECT_INVALID) + { + if(sElem != "btn_cancel") + { + ai_SendMessages("The item we are adjusting is not equiped!", AI_COLOR_RED, oPC); + return; + } + } + else if(oOriginalItem != OBJECT_INVALID && GetTag(oItem) != GetTag(oOriginalItem)) + { + ai_SendMessages(GetName(oItem) + " is not the item you have been adjusting!", AI_COLOR_RED, oPC); + return; + } + // Changing the name needs to be before the cooldown. + if(sElem == "txt_item_name" && sEvent == "watch") + { + string sName = JsonGetString(NuiGetBind(oPC, nToken, "txt_item_name")); + SetName(oItem, sName); + int nToken2 = NuiFindWindow(oPC, "craft_item_nui"); + if(nToken2) NuiSetBind(oPC, nToken2, "txt_item_name", JsonString(sName)); + return; + } + // Delay crafting so it has time to equip and unequip as well as remove. + //if(GetLocalInt(oPC, CRAFT_COOL_DOWN)) return; + //SetLocalInt(oPC, CRAFT_COOL_DOWN, TRUE); + //DelayCommand(0.25f, DeleteLocalInt(oPC, CRAFT_COOL_DOWN)); + // They have selected a color. + if(sElem == "color_pallet") + { + int nColorId, nChange; + object oNewItem; + if(sEvent == "mousedown") + { + // Get the color they selected from the color pallet cell. + nColorId = GetColorPalletId(oPC, nToken); + } + else if(sEvent == "mousescroll") + { + float nMouseScroll = JsonGetFloat(JsonObjectGet(JsonObjectGet(NuiGetEventPayload(), "mouse_scroll"), "y")); + nChange = FloatToInt(nMouseScroll); + } + else return; + if(!CanCraftItem(oPC, oItem, nToken)) return; + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + int nBaseItemType = GetBaseItemType(oItem); + int nAllColor = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ALL_COLOR)); + if(!nAllColor && nBaseItemType == BASE_ITEM_ARMOR) + { + int nIndex; + int nModelSelected = GetArmorModelSelected(oPC); + int nLeftColor = JsonGetInt(JsonObjectGet(jCraft, CRAFT_LEFT_PART_COLOR)); + int nRightColor = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)); + if(nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + if(nChange) nColorId = GetColorIDChange(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nChange); + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nColorId, TRUE); + DestroyObject(oItem); + } + else + { + if(nRightColor) + { + // Color Right side. + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + if(nChange) nColorId = GetColorIDChange(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nChange); + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nColorId, TRUE); + DestroyObject(oItem); + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(TRUE)); + if(nLeftColor) + { + // If we are doing the left side then add one to get the left side. + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected = nModelSelected - 1; + else nModelSelected = nModelSelected + 1; + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + if(nChange) nColorId = GetColorIDChange(oNewItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nChange); + oItem = CopyItemAndModify(oNewItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nColorId, TRUE); + DestroyObject(oNewItem); + oNewItem = oItem; + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(TRUE)); + } + } + else if(nLeftColor) + { + // If we are doing the left side then add one to get the left side. + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected = nModelSelected - 1; + else nModelSelected = nModelSelected + 1; + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + if(nChange) nColorId = GetColorIDChange(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nChange); + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, nColorId, TRUE); + DestroyObject(oItem); + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(TRUE)); + } + } + } + else + { + if(nChange) nColorId = GetColorIDChange(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected, nChange); + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected, nColorId, TRUE); + DestroyObject(oItem); + } + // Lock the new item so they can't change it on the character. + LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken); + // Equip new item. + if(nBaseItemType == BASE_ITEM_CLOAK) AssignCommand (oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CLOAK)); + else if(nBaseItemType == BASE_ITEM_HELMET) AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_HEAD)); + else if(nBaseItemType == BASE_ITEM_ARMOR) AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + } + else if(sEvent == "watch") + { + // The player is changing the item they are crafting. + if(sElem == "item_combo_selected") + { + int nSelected = JsonGetInt(NuiGetBind (oPC, nToken, sElem)); + oItem = GetSelectedItem(oTarget, nSelected); + if(oItem == OBJECT_INVALID) + { + ai_SendMessages("There is not an item to modify!", AI_COLOR_RED, oPC); + int nItem = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + NuiSetBind(oPC, nToken, "item_combo_selected", JsonInt(nItem)); + return; + } + jCraft = JsonObjectSet(jCraft, CRAFT_ITEM_SELECTION, JsonInt(nSelected)); + // Set button for cloak and helms. + if(nSelected == 1 || nSelected == 2) + { + int nHidden = GetHiddenWhenEquipped(oItem); + if(nHidden) jCraft = JsonObjectSet(jCraft, CRAFT_MODEL_SELECTION, JsonInt(1)); + else jCraft = JsonObjectSet(jCraft, CRAFT_MODEL_SELECTION, JsonInt(0)); + } + else jCraft = JsonObjectSet(jCraft, CRAFT_MODEL_SELECTION, JsonInt(0)); + SetLocalJson(oPC, CRAFT_JSON, jCraft); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_crafting", oPC); + } + // They have selected a part to change. + else if(sElem == "model_combo_selected") + { + int nSelected = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + jCraft = JsonObjectSet(jCraft, CRAFT_MODEL_SELECTION, JsonInt(nSelected)); + SetLocalJson(oPC, CRAFT_JSON, jCraft); + SetModelNumberText(oPC, oTarget, nToken); + int nItem = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + if(nItem == 1) // Cloak + { + if(!CanCraftItem(oPC, oItem, nToken)) return; + object oItem = GetItemInSlot(INVENTORY_SLOT_CLOAK, oTarget); + if(nSelected == 1) SetHiddenWhenEquipped(oItem, TRUE); + else SetHiddenWhenEquipped(oItem, FALSE); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + else if(nItem == 2) // Headgear + { + if(!CanCraftItem(oPC, oItem, nToken)) return; + object oItem = GetItemInSlot(INVENTORY_SLOT_HEAD, oTarget); + if(nSelected == 1) SetHiddenWhenEquipped(oItem, TRUE); + else SetHiddenWhenEquipped(oItem, FALSE); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + else if(nItem == 4 && ai_GetIsShield(oItem)) + { + if(!CanCraftItem(oPC, oItem, nToken)) return; + object oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); + if(nSelected == 1) SetHiddenWhenEquipped(oItem, TRUE); + else SetHiddenWhenEquipped(oItem, FALSE); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + if(ai_GetIsWeapon(oItem)) + { + // Clearing sets the module to 0 triggering an extra call. + if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + if(!CanCraftItem(oPC, oItem, nToken)) return; + int nVisual; + itemproperty ipProperty = GetFirstItemProperty(oItem); + while(GetIsItemPropertyValid(ipProperty)) + { + if(GetItemPropertyType(ipProperty) == ITEM_PROPERTY_VISUALEFFECT) + { + RemoveItemProperty(oItem, ipProperty); + } + ipProperty = GetNextItemProperty(oItem); + } + if(nSelected == 1) nVisual = ITEM_VISUAL_ACID; + else if(nSelected == 2) nVisual = ITEM_VISUAL_COLD; + else if(nSelected == 3) nVisual = ITEM_VISUAL_ELECTRICAL; + else if(nSelected == 4) nVisual = ITEM_VISUAL_EVIL; + else if(nSelected == 5) nVisual = ITEM_VISUAL_FIRE; + else if(nSelected == 6) nVisual = ITEM_VISUAL_HOLY; + else if(nSelected == 7) nVisual = ITEM_VISUAL_SONIC; + if(nVisual) + { + ipProperty = ItemPropertyVisualEffect(nVisual); + AddItemProperty(DURATION_TYPE_PERMANENT, ipProperty, oItem); + } + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + } + } + else if(sEvent == "click") + { + if(sElem == "btn_info") + { + SetLocalObject(oPC, "CRAFT_INFO_ITEM", oItem); + CreateItemGUIPanel(oPC, oItem); + } + //else if(sElem == "btn_wardrobe") CreateDresserGUIPanel(oPC, oTarget); + // Random button to change items looks randomly. + else if(sElem == "btn_randomize") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + oItem = RandomizeItemsCraftAppearance(oPC, oTarget, nToken, oItem); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + } + // Save any changes made to the selected item. + else if(sElem == "btn_save") + { + SaveCraftedItem(oPC, oTarget, nToken); + } + // Selecte target to change clothing on. + else if(sElem == "btn_select_target") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_crafting"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "SELECT_TARGET"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select either your charcter or a henchman to craft their equipment.", AI_COLOR_YELLOW, oPC); + DeleteLocalObject(oPC, CRAFT_ORIGINAL_ITEM); + DeleteLocalObject(oPC, CRAFT_TARGET); + DeleteLocalObject(oPC, "CRAFT_INFO_ITEM"); + if(GetLocalInt(oPC, CRAFT_ULTRALIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_ULTRALIGHT); + DeleteLocalInt(oPC, CRAFT_ULTRALIGHT); + } + if(GetLocalInt(oPC, CRAFT_HIGHLIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_HIGHLIGHT); + DeleteLocalInt(oPC, CRAFT_HIGHLIGHT); + } + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + // Cancel any changes made to the selected item. + else if(sElem == "btn_cancel") + { + // If the button is on cancel then clear the item. + if(JsonGetString(NuiGetBind(oPC, nToken, "btn_cancel_label")) == "Cancel") + { + CancelCraftedItem(oPC, oTarget); + ClearItemInCraftingWindow(oPC, oItem, nToken); + DelayCommand(0.5, NuiDestroy(oPC, nToken)); + DelayCommand(0.5, ExecuteScript("pi_crafting", oPC)); + } + // If the button is on Exit not Cancel then exit. + else + { + AssignCommand(oPC, RestoreCameraFacing()); + AttachCamera(oPC, oPC); + DeleteLocalObject(oPC, CRAFT_ORIGINAL_ITEM); + DeleteLocalObject(oPC, CRAFT_TARGET); + DeleteLocalObject(oPC, "CRAFT_INFO_ITEM"); + NuiDestroy(oPC, nToken); + nToken = NuiFindWindow(oPC, "craft_item_nui"); + if(nToken) NuiDestroy(oPC, nToken); + if(GetLocalInt(oPC, CRAFT_ULTRALIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_ULTRALIGHT); + DeleteLocalInt(oPC, CRAFT_ULTRALIGHT); + } + if(GetLocalInt(oPC, CRAFT_HIGHLIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_HIGHLIGHT); + DeleteLocalInt(oPC, CRAFT_HIGHLIGHT); + } + } + } + // Get the previous model of the selected item. + else if(GetStringLeft(sElem, 9) == "btn_prev_") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + oItem = ChangeItemsAppearance(oPC, oTarget, nToken, oItem, -1, GetStringRight(sElem, 1)); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + } + // Get the next model of the selected item. + else if(GetStringLeft(sElem, 9) == "btn_next_") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + oItem = ChangeItemsAppearance(oPC, oTarget, nToken, oItem, 1, GetStringRight(sElem, 1)); + LockItemInCraftingWindow(oPC, oItem, oTarget, nToken); + } + } + else if(sElem == "btn_highlight") + { + if(GetLocalInt(oPC, CRAFT_HIGHLIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_HIGHLIGHT); + DeleteLocalInt(oPC, CRAFT_HIGHLIGHT); + NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(FALSE)); + } + else + { + if(GetLocalInt(oPC, CRAFT_ULTRALIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_ULTRALIGHT); + DeleteLocalInt(oPC, CRAFT_ULTRALIGHT); + } + SetLocalInt(oPC, CRAFT_HIGHLIGHT, TRUE); + effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20); + eLight = TagEffect(eLight, CRAFT_HIGHLIGHT); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oTarget); + NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(TRUE)); + } + } + else if(sElem == "btn_left_part_color") + { + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(TRUE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(FALSE)); + SetColorPalletPointer(oPC, nToken, oItem); + } + else if(sElem == "btn_all_color") + { + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(TRUE)); + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(FALSE)); + SetColorPalletPointer(oPC, nToken, oItem); + } + else if(sElem == "btn_right_part_color") + { + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(TRUE)); + SetColorPalletPointer(oPC, nToken, oItem); + } + else if(sElem == "btn_right_part_reset") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + int nIndex; + int nModelSelected = GetArmorModelSelected(oPC); + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + object oNewItem; + if(nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, 255, TRUE); + DestroyObject(oItem); + } + else + { + nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, 255, TRUE); + DestroyObject(oItem); + } + // Lock the new item so they can't change it on the character. + LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken); + // Equip new item. + AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(FALSE)); + int nLeft = JsonGetInt(NuiGetBind(oPC, nToken, "btn_left_part_color")); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(!nLeft)); + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(!nLeft)); + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + nLeft = JsonGetInt(NuiGetBind(oPC, nToken, "btn_left_part_reset_event")); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nLeft)); + SetColorPalletPointer(oPC, nToken, oNewItem); + } + } + else if(sElem == "btn_all_reset") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + int nIndex, nColor; + json jItem = ObjectToJson(oItem, TRUE); + string sColor, sPartName; + for(nIndex = 0;nIndex < 19;nIndex++) + { + sPartName = "APart_" + IntToString(nIndex) + "_Col_"; + for(nColor = 0;nColor < 6;nColor++) + { + sColor = IntToString(nColor); + if(JsonGetType(GffGetByte(jItem, sPartName + sColor)) != JSON_TYPE_NULL) + { + jItem = GffRemoveByte(jItem, sPartName + sColor); + } + } + } + object oNewItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + DestroyObject(oItem); + // Lock the new item so they can't change it on the character. + LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken); + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(TRUE)); + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonInt(FALSE)); + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + SetColorPalletPointer(oPC, nToken, oNewItem); + } + } + else if(sElem == "btn_left_part_reset") + { + if(CanCraftItem(oPC, oItem, nToken)) + { + int nModelSelected = GetArmorModelSelected(oPC); + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected = nModelSelected - 1; + else nModelSelected = nModelSelected + 1; + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + int nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + object oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex, 255, TRUE); + DestroyObject(oItem); + // Lock the new item so they can't change it on the character. + LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken); + // Equip new item. + AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + // Fix buttons. + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonInt(FALSE)); + int nRight = JsonGetInt(NuiGetBind(oPC, nToken, "btn_right_part_color")); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(!nRight)); + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonInt(!nRight)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + nRight = JsonGetInt(NuiGetBind(oPC, nToken, "btn_right_part_reset_event")); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nRight)); + SetColorPalletPointer(oPC, nToken, oNewItem); + } + } + // They have changed the material (color item) for the item. + else if(GetStringLeft(sElem, 13) == "btn_material_") + { + int nSelected = StringToInt(GetStringRight(sElem, 1)); + SetMaterialButtons(oPC, nToken, nSelected); + jCraft = JsonObjectSet(jCraft, CRAFT_MATERIAL_SELECTION, JsonInt(nSelected)); + // Change the pallet for the correct material. + string sColorPallet; + if(nSelected < 4) + { + sColorPallet = "gui_pal_tattoo"; + NuiSetBind(oPC, nToken, "armor_block_1", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "armor_block_2", JsonBool(FALSE)); + } + else + { + sColorPallet = "armor_pallet"; + if(ResManGetAliasFor(sColorPallet, RESTYPE_TGA) == "") + { + sColorPallet = "gui_pal_tattoo"; + NuiSetBind(oPC, nToken, "armor_block_1", JsonBool(TRUE)); + } + } + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString (sColorPallet)); + SetLocalString(oPC, CRAFT_COLOR_PALLET, sColorPallet); + SetColorPalletPointer(oPC, nToken, oItem); + } + SetLocalJson(oPC, CRAFT_JSON, jCraft); + } + else if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + AssignCommand(oPC, PlaySound("gui_button")); + if(sElem == "btn_highlight") + { + if(GetLocalInt(oPC, CRAFT_ULTRALIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_ULTRALIGHT); + DeleteLocalInt(oPC, CRAFT_ULTRALIGHT); + NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(FALSE)); + } + else + { + if(GetLocalInt(oPC, CRAFT_HIGHLIGHT)) + { + RemoveTagedEffects(oTarget, CRAFT_HIGHLIGHT); + DeleteLocalInt(oPC, CRAFT_HIGHLIGHT); + } + SetLocalInt(oPC, CRAFT_ULTRALIGHT, TRUE); + effect eLight = EffectVisualEffect(VFX_DUR_ULTRAVISION); + eLight = TagEffect(eLight, CRAFT_ULTRALIGHT); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oTarget); + NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(TRUE)); + } + } + } + } + } +} +/*void CopyCraftingItem(object oPC, object oItem) +{ + //ai_Debug("pe_crafting", "295", JsonDump(ObjectToJson(oItem), 2)); + json jItem = ObjectToJson(oItem); + + SetLocalInt(oPC, CRAFT_COPY_ITEM, TRUE); + int nSelected = GetLocalInt(oPC, CRAFT_ITEM_SELECTION); + if (ai_GetIsWeapon(oItem)) + { + // Copy the base item type; + SetLocalInt(oPC, CRAFT_COPY_ITEM_TYPE, GetBaseItemType(oItem)); + // Copy each model/color & save to variables. + int nIndex = 1; + string sIndex; + while(nIndex <= 3) + { + sIndex = IntToString(nIndex); + SetLocalInt(oPC, CRAFT_COPY_MODEL + sIndex, JsonGetInt(GffGetByte(jItem, "ModelPart" + sIndex))); + nIndex++; + } + } + else if (nSelected == 0) + { + // Copy the armors AC so we can check it. + SetLocalInt(oPC, CRAFT_ARMOR_AC, ai_GetArmorBonus(oItem)); + // Copy an per part colors if they exist. + int nPart, nColor, nPartColor; + string sPart, sColor; + while(nPart <= 18) + { + sPart = IntToString(nPart); + nColor = 0; + while(nColor <= 5) + { + sColor = IntToString(nColor); + if(GffGetFieldExists(jItem, "APart_" + sPart + "_Col_" + sColor, GFF_FIELD_TYPE_BYTE)) + { + // Shift the number up by 1 so we can save as a variable and not use 0! + nPartColor = JsonGetInt(GffGetByte(jItem, "APart_" + sPart + "_Col_" + sColor)) + 1; + SetLocalInt(oPC, CRAFT_COPY_PART_COLOR + sPart + sColor, nPartColor); + } + nColor++; + } + nPart++; + } + // Copy each model & save to variables. + SetLocalInt(oPC, "CRAFT_COPY_MODEL0", JsonGetInt(GffGetByte(jItem, "ArmorPart_Belt"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL1", JsonGetInt(GffGetByte(jItem, "ArmorPart_LBicep"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL2", JsonGetInt(GffGetByte(jItem, "ArmorPart_LFArm"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL3", JsonGetInt(GffGetByte(jItem, "ArmorPart_LFoot"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL4", JsonGetInt(GffGetByte(jItem, "ArmorPart_LHand"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL5", JsonGetInt(GffGetByte(jItem, "ArmorPart_LShin"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL6", JsonGetInt(GffGetByte(jItem, "ArmorPart_LShoul"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL7", JsonGetInt(GffGetByte(jItem, "ArmorPart_LThigh"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL8", JsonGetInt(GffGetByte(jItem, "ArmorPart_Neck"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL9", JsonGetInt(GffGetByte(jItem, "ArmorPart_Pelvis"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL10", JsonGetInt(GffGetByte(jItem, "ArmorPart_RBicep"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL11", JsonGetInt(GffGetByte(jItem, "ArmorPart_RFArm"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL12", JsonGetInt(GffGetByte(jItem, "ArmorPart_RFoot"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL13", JsonGetInt(GffGetByte(jItem, "ArmorPart_RHand"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL14", JsonGetInt(GffGetByte(jItem, "ArmorPart_RShin"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL15", JsonGetInt(GffGetByte(jItem, "ArmorPart_RShoul"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL16", JsonGetInt(GffGetByte(jItem, "ArmorPart_RThigh"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL17", JsonGetInt(GffGetByte(jItem, "ArmorPart_Robe"))); + SetLocalInt(oPC, "CRAFT_COPY_MODEL18", JsonGetInt(GffGetByte(jItem, "ArmorPart_Torso"))); + // Copy each color and save to variables. + SetLocalInt(oPC, "CRAFT_COPY_COLOR0", JsonGetInt(GffGetByte(jItem, "Cloth1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR1", JsonGetInt(GffGetByte(jItem, "Cloth2Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR2", JsonGetInt(GffGetByte(jItem, "Leather1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR3", JsonGetInt(GffGetByte(jItem, "Leather2Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR4", JsonGetInt(GffGetByte(jItem, "Metal1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR5", JsonGetInt(GffGetByte(jItem, "Metal2Color"))); + } +else + { + // Copy the base item type; + SetLocalInt(oPC, CRAFT_COPY_ITEM_TYPE, GetBaseItemType(oItem)); + // Copy the base item type; + SetLocalInt(oPC, "CRAFT_COPY_MODEL0", JsonGetInt(GffGetByte(jItem, "ModelPart1"))); + // Copy each color and save to variables. + SetLocalInt(oPC, "CRAFT_COPY_COLOR0", JsonGetInt(GffGetByte(jItem, "Cloth1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR1", JsonGetInt(GffGetByte(jItem, "Cloth2Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR2", JsonGetInt(GffGetByte(jItem, "Leather1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR3", JsonGetInt(GffGetByte(jItem, "Leather2Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR4", JsonGetInt(GffGetByte(jItem, "Metal1Color"))); + SetLocalInt(oPC, "CRAFT_COPY_COLOR5", JsonGetInt(GffGetByte(jItem, "Metal2Color"))); + } + // Send message that it has been copied. + ai_SendMessages(GetName (oItem) + " appearance has been copied!", AI_COLOR_GREEN, oPC); +} + +// Used in the crafting GUI to paste a copy of an item to another item. +object PasteCraftingItem (object oPC, object oTarget, object oItem) +{ + int nModelPartNum; + object oChestItem; + int nSelected = GetLocalInt(oPC, CRAFT_ITEM_SELECTION); + object oBuildContainer = GetObjectByTag(CRAFT_CONTAINER); + // Move the item to the building container. + oChestItem = CopyItem(oItem, oBuildContainer, TRUE); + DestroyObject(oItem); + json jItem = ObjectToJson(oChestItem, TRUE); + if (ai_GetIsWeapon(oChestItem)) + { + // Copy each model & save to variables. + int nIndex = 1; + string sIndex; + while(nIndex <= 3) + { + sIndex = IntToString(nIndex); + jItem = GffReplaceByte(jItem,"ModelPart" + sIndex, GetLocalInt(oPC, CRAFT_COPY_MODEL + sIndex)); + jItem = GffReplaceWord(jItem,"xModelPart" + sIndex, GetLocalInt(oPC, CRAFT_COPY_MODEL + sIndex)); + DeleteLocalInt(oPC, CRAFT_COPY_MODEL + sIndex); + nIndex++; + } + oItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + // Equip new item. + AssignCommand(oTarget, ActionEquipItem (oItem, INVENTORY_SLOT_RIGHTHAND)); + } + // Armor. + else if (nSelected == 0) + { + // Paste per part colors if they exist. + int nPart, nColor, nPartColor; + string sPart, sColor; + while(nPart <= 18) + { + sPart = IntToString(nPart); + nColor = 0; + while(nColor <= 5) + { + sColor = IntToString(nColor); + nPartColor = GetLocalInt(oPC, CRAFT_COPY_PART_COLOR + sPart + sColor); + if(nPartColor > 0) + { + // Shift the number down by 1 since we can not use 0 in the variable! + nPartColor = nPartColor - 1; + if(GffGetFieldExists(jItem, "APart_" + sPart + "_Col_" + sColor, GFF_FIELD_TYPE_BYTE)) + { + jItem = GffReplaceByte(jItem, "APart_" + sPart + "_Col_" + sColor, nPartColor); + } + else jItem = GffAddByte(jItem, "APart_" + sPart + "_Col_" + sColor, nPartColor); + DeleteLocalInt(oPC, "CRAFT_COPY_PART_COLOR" + sPart + sColor); + } + nColor++; + } + nPart++; + } + jItem = GffReplaceByte(jItem,"ArmorPart_Belt", GetLocalInt(oPC, "CRAFT_COPY_MODEL0")); + jItem = GffReplaceByte(jItem,"ArmorPart_LBicep", GetLocalInt(oPC, "CRAFT_COPY_MODEL1")); + jItem = GffReplaceByte(jItem,"ArmorPart_LFArm", GetLocalInt(oPC, "CRAFT_COPY_MODEL2")); + jItem = GffReplaceByte(jItem,"ArmorPart_LFoot", GetLocalInt(oPC, "CRAFT_COPY_MODEL3")); + jItem = GffReplaceByte(jItem,"ArmorPart_LHand", GetLocalInt(oPC, "CRAFT_COPY_MODEL4")); + jItem = GffReplaceByte(jItem,"ArmorPart_LShin", GetLocalInt(oPC, "CRAFT_COPY_MODEL5")); + jItem = GffReplaceByte(jItem,"ArmorPart_LShoul", GetLocalInt(oPC, "CRAFT_COPY_MODEL6")); + jItem = GffReplaceByte(jItem,"ArmorPart_LThigh", GetLocalInt(oPC, "CRAFT_COPY_MODEL7")); + jItem = GffReplaceByte(jItem,"ArmorPart_Neck", GetLocalInt(oPC, "CRAFT_COPY_MODEL8")); + jItem = GffReplaceByte(jItem,"ArmorPart_Pelvis", GetLocalInt(oPC, "CRAFT_COPY_MODEL9")); + jItem = GffReplaceByte(jItem,"ArmorPart_RBicep", GetLocalInt(oPC, "CRAFT_COPY_MODEL10")); + jItem = GffReplaceByte(jItem,"ArmorPart_RFArm", GetLocalInt(oPC, "CRAFT_COPY_MODEL11")); + jItem = GffReplaceByte(jItem,"ArmorPart_RFoot", GetLocalInt(oPC, "CRAFT_COPY_MODEL12")); + jItem = GffReplaceByte(jItem,"ArmorPart_RHand", GetLocalInt(oPC, "CRAFT_COPY_MODEL13")); + jItem = GffReplaceByte(jItem,"ArmorPart_RShin", GetLocalInt(oPC, "CRAFT_COPY_MODEL14")); + jItem = GffReplaceByte(jItem,"ArmorPart_RShoul", GetLocalInt(oPC, "CRAFT_COPY_MODEL15")); + jItem = GffReplaceByte(jItem,"ArmorPart_RThigh", GetLocalInt(oPC, "CRAFT_COPY_MODEL16")); + jItem = GffReplaceByte(jItem,"ArmorPart_Robe", GetLocalInt(oPC, "CRAFT_COPY_MODEL17")); + jItem = GffReplaceByte(jItem,"ArmorPart_Torso", GetLocalInt(oPC, "CRAFT_COPY_MODEL18")); + jItem = GffReplaceWord(jItem,"xArmorPart_Belt", GetLocalInt(oPC, "CRAFT_COPY_MODEL0")); + jItem = GffReplaceWord(jItem,"xArmorPart_LBice", GetLocalInt(oPC, "CRAFT_COPY_MODEL1")); + jItem = GffReplaceWord(jItem,"xArmorPart_LFArm", GetLocalInt(oPC, "CRAFT_COPY_MODEL2")); + jItem = GffReplaceWord(jItem,"xArmorPart_LFoot", GetLocalInt(oPC, "CRAFT_COPY_MODEL3")); + jItem = GffReplaceWord(jItem,"xArmorPart_LHand", GetLocalInt(oPC, "CRAFT_COPY_MODEL4")); + jItem = GffReplaceWord(jItem,"xArmorPart_LShin", GetLocalInt(oPC, "CRAFT_COPY_MODEL5")); + jItem = GffReplaceWord(jItem,"xArmorPart_LShou", GetLocalInt(oPC, "CRAFT_COPY_MODEL6")); + jItem = GffReplaceWord(jItem,"xArmorPart_LThig", GetLocalInt(oPC, "CRAFT_COPY_MODEL7")); + jItem = GffReplaceWord(jItem,"xArmorPart_Neck", GetLocalInt(oPC, "CRAFT_COPY_MODEL8")); + jItem = GffReplaceWord(jItem,"xArmorPart_Pelvi", GetLocalInt(oPC, "CRAFT_COPY_MODEL9")); + jItem = GffReplaceWord(jItem,"xArmorPart_RBice", GetLocalInt(oPC, "CRAFT_COPY_MODEL10")); + jItem = GffReplaceWord(jItem,"xArmorPart_RFArm", GetLocalInt(oPC, "CRAFT_COPY_MODEL11")); + jItem = GffReplaceWord(jItem,"xArmorPart_RFoot", GetLocalInt(oPC, "CRAFT_COPY_MODEL12")); + jItem = GffReplaceWord(jItem,"xArmorPart_RHand", GetLocalInt(oPC, "CRAFT_COPY_MODEL13")); + jItem = GffReplaceWord(jItem,"xArmorPart_RShin", GetLocalInt(oPC, "CRAFT_COPY_MODEL14")); + jItem = GffReplaceWord(jItem,"xArmorPart_RShou", GetLocalInt(oPC, "CRAFT_COPY_MODEL15")); + jItem = GffReplaceWord(jItem,"xArmorPart_RThig", GetLocalInt(oPC, "CRAFT_COPY_MODEL16")); + jItem = GffReplaceWord(jItem,"xArmorPart_Robe", GetLocalInt(oPC, "CRAFT_COPY_MODEL17")); + jItem = GffReplaceWord(jItem,"xArmorPart_Torso", GetLocalInt(oPC, "CRAFT_COPY_MODEL18")); + jItem = GffReplaceByte(jItem,"Cloth1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR0")); + jItem = GffReplaceByte(jItem,"Cloth2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR1")); + jItem = GffReplaceByte(jItem,"Leather1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR2")); + jItem = GffReplaceByte(jItem,"Leather2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR3")); + jItem = GffReplaceByte(jItem,"Metal1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR4")); + jItem = GffReplaceByte(jItem,"Metal2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR5")); + oItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + int nIndex; + for(nIndex = 0; nIndex <= 18; nIndex++) + { + DeleteLocalInt(oPC, CRAFT_COPY_MODEL + IntToString(nIndex)); + } + for(nIndex = 0; nIndex <= 5; nIndex++) + { + DeleteLocalInt(oPC, CRAFT_COPY_COLOR + IntToString(nIndex)); + } + // Equip new item. + AssignCommand (oTarget, ActionEquipItem (oItem, INVENTORY_SLOT_CHEST)); + } + else if(ai_GetIsShield(oChestItem)) + { + jItem = GffReplaceByte(jItem,"ModelPart1", GetLocalInt(oPC, "CRAFT_COPY_MODEL1")); + jItem = GffReplaceWord(jItem,"xModelPart1", GetLocalInt(oPC, "CRAFT_COPY_MODEL1")); + oItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + // Equip new item. + AssignCommand(oTarget, ActionEquipItem (oItem, INVENTORY_SLOT_LEFTHAND)); + } + else + { + //ai_Debug("pe_crafting", "389", JsonDump(ObjectToJson(oChestItem), 2)); + jItem = GffReplaceByte(jItem,"ModelPart1", GetLocalInt(oPC, "CRAFT_COPY_MODEL0")); + jItem = GffReplaceWord(jItem,"xModelPart1", GetLocalInt(oPC, "CRAFT_COPY_MODEL0")); + jItem = GffReplaceByte(jItem,"Cloth1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR0")); + jItem = GffReplaceByte(jItem,"Cloth2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR1")); + jItem = GffReplaceByte(jItem,"Leather1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR2")); + jItem = GffReplaceByte(jItem,"Leather2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR3")); + jItem = GffReplaceByte(jItem,"Metal1Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR4")); + jItem = GffReplaceByte(jItem,"Metal2Color", GetLocalInt(oPC, "CRAFT_COPY_COLOR5")); + oItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + DeleteLocalInt(oPC, "CRAFT_COPY_MODEL0"); + int nIndex; + for(nIndex = 0; nIndex <= 5; nIndex++) + { + DeleteLocalInt(oPC, CRAFT_COPY_COLOR + IntToString(nIndex)); + } + // Equip new item. + int nItemType = GetBaseItemType(oChestItem); + if(nItemType == BASE_ITEM_CLOAK) AssignCommand(oTarget, ActionEquipItem (oItem, INVENTORY_SLOT_CLOAK)); + else if(nItemType == BASE_ITEM_HELMET) AssignCommand(oTarget, ActionEquipItem (oItem, INVENTORY_SLOT_HEAD)); + } + // Send message that it has been copied. + AssignCommand(oPC, ai_SendMessages (GetName (oItem) + " appearance has been changed!", AI_COLOR_GREEN, oPC)); + DestroyObject(oChestItem); + return oItem; +} */ +int GetItemSelectedEquipSlot (int nItemSelected) +{ + if (nItemSelected == 0) return INVENTORY_SLOT_CHEST; + if (nItemSelected == 1) return INVENTORY_SLOT_CLOAK; + if (nItemSelected == 2) return INVENTORY_SLOT_HEAD; + if (nItemSelected == 3) return INVENTORY_SLOT_RIGHTHAND; + if (nItemSelected == 4) return INVENTORY_SLOT_LEFTHAND; + return INVENTORY_SLOT_CHEST; +} +int GetArmorModelSelected (object oPC) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nModelSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION)); + if(nModelSelected == 0) return ITEM_APPR_ARMOR_MODEL_NECK; + if(nModelSelected == 1) return ITEM_APPR_ARMOR_MODEL_RSHOULDER; + if(nModelSelected == 2) return ITEM_APPR_ARMOR_MODEL_RBICEP; + if(nModelSelected == 3) return ITEM_APPR_ARMOR_MODEL_RFOREARM; + if(nModelSelected == 4) return ITEM_APPR_ARMOR_MODEL_RHAND; + if(nModelSelected == 5) return ITEM_APPR_ARMOR_MODEL_TORSO; + if(nModelSelected == 6) return ITEM_APPR_ARMOR_MODEL_BELT; + if(nModelSelected == 7) return ITEM_APPR_ARMOR_MODEL_PELVIS; + if(nModelSelected == 8) return ITEM_APPR_ARMOR_MODEL_RTHIGH; + if(nModelSelected == 9) return ITEM_APPR_ARMOR_MODEL_RSHIN; + if(nModelSelected == 10) return ITEM_APPR_ARMOR_MODEL_RFOOT; + return ITEM_APPR_ARMOR_MODEL_ROBE; +} +int GetMaxSimpleItemNumber(object oItem, int nBaseItemType) +{ + int nResType, nMaxNumber, nModelNumber; + string sModelNumber, sModelName = Get2DAString("baseitems", "ItemClass", nBaseItemType) + "_"; + //ai_Debug("pe_crafting", "804", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + while(nModelNumber < 999) + { + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + if(nBaseItemType == BASE_ITEM_CLOAK) nResType = RESTYPE_PLT; + else nResType = RESTYPE_MDL; + if(ResManGetAliasFor(sModelName + sModelNumber, nResType) != "") nMaxNumber++; + nModelNumber++; + //ai_Debug("pe_crafting", "841", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + } + return nMaxNumber; +} +int GetSimpleItemNumber(object oItem, int nModelNumber, int nBaseItemType) +{ + int nResType, nIndex, nCounter; + string sModelNumber, sModelName = Get2DAString("baseitems", "ItemClass", nBaseItemType) + "_"; + //ai_Debug("pe_crafting", "804", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + while(nIndex <= 999) + { + if(nIndex < 10) sModelNumber = "00" + IntToString(nIndex); + else if(nIndex < 100) sModelNumber = "0" + IntToString(nIndex); + else sModelNumber = IntToString(nIndex); + if(nBaseItemType == BASE_ITEM_CLOAK) nResType = RESTYPE_PLT; + else nResType = RESTYPE_MDL; + if(ResManGetAliasFor(sModelName + sModelNumber, nResType) != "") nCounter++; + if(nCounter == nModelNumber) return nIndex; + nIndex++; + //ai_Debug("pe_crafting", "841", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + } + return nIndex; +} +int GetMaxWeaponModuleNumber(struct stWeaponAppearance stWA) +{ + int nBaseItemType = GetBaseItemType(stWA.oItem); + stWA.nColor = 1; + stWA.nModel = 99; + stWA.sPart = "t"; + string sModelNumber; + string sModelName = Get2DAString("baseitems", "ItemClass", nBaseItemType) + "_" + stWA.sPart + "_"; + int nModelNumber = (stWA.nModel * 10) + stWA.nColor; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //SendMessageToPC(GetFirstPC(), "pe_crafting, 780, sModel: " + sModelName + sModelNumber + + // " nModel: " + IntToString(stWA.nModel) + " nColor: " + IntToString(stWA.nColor)); + while(ResManGetAliasFor(sModelName + sModelNumber, RESTYPE_MDL) == "") + { + stWA.nModel += -1; + // Create the model name. + nModelNumber = (stWA.nModel * 10) + stWA.nColor; + if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //SendMessageToPC(GetFirstPC(), "pe_crafting, 789, sModel: " + sModelName + sModelNumber + + // " nModel: " + IntToString(stWA.nModel) + " nColor: " + IntToString(stWA.nColor)); + } + return stWA.nModel; +} +struct stWeaponAppearance GetNextWeaponAppearance(struct stWeaponAppearance stWA, int nDirection) +{ + int nBaseItemType = GetBaseItemType(stWA.oItem); + string sModelNumber; + string sModelName = Get2DAString("baseitems", "ItemClass", nBaseItemType) + "_" + stWA.sPart + "_"; + // Get next/previous color/model. + stWA.nColor += nDirection; + if(stWA.nColor > 9) + { + stWA.nColor = 1; + stWA.nModel += nDirection; + if(stWA.nModel > CRAFT_MAX_WEAPON_MODEL_NUMBER) stWA.nModel = 1; + } + else if(stWA.nColor < 1) + { + stWA.nColor = 9; + stWA.nModel += nDirection; + if(stWA.nModel < 1) stWA.nModel = CRAFT_MAX_WEAPON_MODEL_NUMBER; + } + int nModelNumber = (stWA.nModel * 10) + stWA.nColor; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //SendMessageToPC(GetFirstPC(), "pe_crafting, 778, sModel: " + sModelName + sModelNumber + + // " nModel: " + IntToString(stWA.nModel) + " nColor: " + IntToString(stWA.nColor)); + while(ResManGetAliasFor(sModelName + sModelNumber, RESTYPE_MDL) == "") + { + // Get next/previous color/model. + stWA.nColor += nDirection; + if(stWA.nColor > 9) + { + stWA.nColor = 1; + stWA.nModel += nDirection; + if(stWA.nModel > CRAFT_MAX_WEAPON_MODEL_NUMBER) stWA.nModel = 1; + } + else if(stWA.nColor < 1) + { + stWA.nColor = 9; + stWA.nModel += nDirection; + if(stWA.nModel < 1) stWA.nModel = CRAFT_MAX_WEAPON_MODEL_NUMBER; + } + // Create the model name. + nModelNumber = (stWA.nModel * 10) + stWA.nColor; + if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //SendMessageToPC(GetFirstPC(), "pe_crafting, 800, sModel: " + sModelName + sModelNumber + + // " nModel: " + IntToString(stWA.nModel) + " nColor: " + IntToString(stWA.nColor)); + } + return stWA; +} +object ChangeItemsAppearance(object oPC, object oTarget, int nToken, object oItem, int nDirection, string sPart) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + // Get the item we are changing. + int nModelSelected; + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + string sModelName, sModelNumber; + object oNewItem; + // Weapons. + if(ai_GetIsWeapon(oItem)) + { + // Freeze animations - vfx 352? + if(sPart == "t") nModelSelected = 2; + else if(sPart == "m") nModelSelected = 1; + else if(sPart == "b") nModelSelected = 0; + sModelName = Get2DAString("baseitems", "ItemClass", GetBaseItemType(oItem)) + "_" + sPart + "_"; + struct stWeaponAppearance stWA; + stWA.oItem = oItem; + stWA.sPart = sPart; + stWA.nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, nModelSelected); + stWA.nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, nModelSelected); + stWA = GetNextWeaponAppearance(stWA, nDirection); + json jItem = ObjectToJson(oItem, TRUE); + int nModelNumber = stWA.nModel * 10 + stWA.nColor; + jItem = GffReplaceByte(jItem, "ModelPart" + IntToString(nModelSelected + 1), nModelNumber); + jItem = GffReplaceWord(jItem, "xModelPart" + IntToString(nModelSelected + 1), nModelNumber); + oNewItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + AssignCommand(oTarget, ClearAllActions(TRUE)); + DestroyObject(oItem); + // Item selected 3 is the right hand, 4 is the left hand. + //SendMessageToPC(oPC, "nItemSelected: " + IntToString(nItemSelected)); + if(nItemSelected == 3) + { + AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_RIGHTHAND)); + } + else AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_LEFTHAND)); + NuiSetBind(oPC, nToken, "txt_model_number_" + sPart, JsonString(IntToString(nModelNumber))); + } + // Armor. + else if(nItemSelected == 0) + { + // Create the model name. + // Get the ModelType. + int nAppearance = GetAppearanceType(oTarget); + string sModelName = Get2DAString("appearance", "MODELTYPE", nAppearance); + // Get gender. + if(GetGender(oTarget) == GENDER_MALE) sModelName += "m"; + else sModelName += "f"; + // Get race. + sModelName += Get2DAString("appearance", "RACE", nAppearance); + // Get Phenotype. + sModelName += IntToString(GetPhenoType(oTarget)) + "_"; + // Get the selected model. + nModelSelected = GetArmorModelSelected(oPC); + //ai_Debug("pe_crafting", "646", "nModelSide: " + IntToString(nModelSide)); + // If we are doing the left side (bottom menu options) then add one to + // get the left side. + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if(sPart == "b") + { + if(nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected--; + else nModelSelected++; + } + int nModelNumber = StringToInt(JsonGetString(NuiGetBind(oPC, nToken, "txt_model_number_" + sPart))); + //int nModelNumber = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nModelSelected); + //SendMessageToPC(oPC, "pe_crafting, 826, nModelNumber: " + IntToString(nModelNumber) + + // " sPart: " + sPart + " nModelSelected: " + IntToString(nModelSelected)); + int nBaseModelNumber = nModelNumber; + nModelNumber += nDirection; + if(nModelNumber > CRAFT_MAX_MODEL_NUMBER) nModelNumber = 0; + else if(nModelNumber < 0) nModelNumber = CRAFT_MAX_MODEL_NUMBER; + string sModelNumber; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + // Check for changes to the torso (base part of the armor linked to AC). + if(nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO) + { + string sCurrentACBonus = Get2DAString("parts_chest", "ACBONUS", nBaseModelNumber); + string sACBonus = Get2DAString ("parts_chest", "ACBONUS", nModelNumber); + sModelName += Get2DAString ("capart", "MDLNAME", nModelSelected); + //SendMessageToPC(oPC, "pe_crafting, 842, sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber) + " sCurrentACBonus: " + sCurrentACBonus + + // " sACBonus: " + sACBonus + " nModelSelected: " + IntToString(nModelSelected)); + while(ResManGetAliasFor(sModelName + sModelNumber, RESTYPE_MDL) == "" || + sACBonus != sCurrentACBonus) + { + nModelNumber += nDirection; + if (nModelNumber > CRAFT_MAX_MODEL_NUMBER) nModelNumber = 0; + else if (nModelNumber < 0) nModelNumber = CRAFT_MAX_MODEL_NUMBER; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + sACBonus = Get2DAString ("parts_chest", "ACBONUS", nModelNumber); + //SendMessageToPC(oPC, "pe_crafting, 854, sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber) + " sACBonus: " + sACBonus + + // " nModelSelected: " + IntToString(nModelSelected)); + } + // Change the model. + oNewItem = CopyItemAndModify (oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nModelSelected, nModelNumber, TRUE); + DestroyObject (oItem); + AssignCommand (oTarget, ActionEquipItem (oNewItem, INVENTORY_SLOT_CHEST)); + } + // Change all other parts of armor. + else + { + sModelName += Get2DAString("capart", "MDLNAME", nModelSelected); + //SendMessageToPC(oPC, "pe_crafting, 866, sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber) + " nModelSelected: " + IntToString(nModelSelected)); + while(ResManGetAliasFor(sModelName + sModelNumber, RESTYPE_MDL) == "") + { + nModelNumber += nDirection; + if (nModelNumber > CRAFT_MAX_MODEL_NUMBER) nModelNumber = 0; + else if (nModelNumber < 0) nModelNumber = CRAFT_MAX_MODEL_NUMBER; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //SendMessageToPC(oPC, "pe_crafting, 705, sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber) + " nModelSelected: " + IntToString(nModelSelected)); + } + oNewItem = CopyItemAndModify (oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nModelSelected, nModelNumber, TRUE); + DestroyObject (oItem); + // If using the linked menu option then change the left side too. + if(sPart == "m" && (nModelSelected != ITEM_APPR_ARMOR_MODEL_NECK && + nModelSelected != ITEM_APPR_ARMOR_MODEL_BELT && + nModelSelected != ITEM_APPR_ARMOR_MODEL_PELVIS && + nModelSelected != ITEM_APPR_ARMOR_MODEL_ROBE)) + { + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected--; + else nModelSelected++; + oItem = CopyItemAndModify(oNewItem, ITEM_APPR_TYPE_ARMOR_MODEL, nModelSelected, nModelNumber, TRUE); + DestroyObject(oNewItem); + AssignCommand(oTarget, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST)); + } + else AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + } + string sModelSelected; + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + NuiSetBind(oPC, nToken, "txt_model_number_" + sPart, JsonString(IntToString(nModelNumber))); + } + else + { + if(sPart == "m") + { + // Using labels for Mobile. + //NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(IntToString(nModelNumber))); + //NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(IntToString(nModelNumber))); + //NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(IntToString(nModelNumber))); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(IntToString(nModelNumber))); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(IntToString(nModelNumber))); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(IntToString(nModelNumber))); + } + else + { + NuiSetBind(oPC, nToken, "txt_model_number_" + sPart, JsonString(IntToString(nModelNumber))); + } + } + } + // All other items. + else + { + int nSlot, nResType, nBaseItemType = GetBaseItemType(oItem); + string sModelName = Get2DAString("baseitems", "ItemClass", nBaseItemType) + "_"; + if(nBaseItemType == BASE_ITEM_CLOAK) + { + nSlot = INVENTORY_SLOT_CLOAK; + nResType = RESTYPE_PLT; + } + else if(nBaseItemType == BASE_ITEM_HELMET) + { + nSlot = INVENTORY_SLOT_HEAD; + nResType = RESTYPE_MDL; + } + else if(nBaseItemType == BASE_ITEM_LARGESHIELD || + nBaseItemType == BASE_ITEM_SMALLSHIELD || + nBaseItemType == BASE_ITEM_TOWERSHIELD) + { + nSlot = INVENTORY_SLOT_LEFTHAND; + nResType = RESTYPE_MDL; + } + int nModelNumber = GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0); + nModelNumber += nDirection; + if (nModelNumber > CRAFT_MAX_MODEL_NUMBER) nModelNumber = 0; + else if (nModelNumber < 0) nModelNumber = CRAFT_MAX_MODEL_NUMBER; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //ai_Debug("pe_crafting", "804", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + while(ResManGetAliasFor(sModelName + sModelNumber, nResType) == "") + { + nModelNumber += nDirection; + if (nModelNumber > CRAFT_MAX_MODEL_NUMBER) nModelNumber = 0; + else if (nModelNumber < 0) nModelNumber = CRAFT_MAX_MODEL_NUMBER; + if(nModelNumber < 10) sModelNumber = "00" + IntToString(nModelNumber); + else if(nModelNumber < 100) sModelNumber = "0" + IntToString(nModelNumber); + else sModelNumber = IntToString(nModelNumber); + //ai_Debug("pe_crafting", "841", "sModelName: " + sModelName + sModelNumber + + // " nModelNumber: " + IntToString(nModelNumber)); + } + oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, nModelNumber, TRUE); + DestroyObject(oItem); + AssignCommand(oTarget, ActionEquipItem (oNewItem, nSlot)); + NuiSetBind(oPC, nToken, "txt_model_number_" + sPart, JsonString(IntToString(nModelNumber))); + } + return oNewItem; +} +object RandomizeItemsCraftAppearance(object oPC, object oTarget, int nToken, object oItem) +{ + // Get the item we are changing. + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + int nBaseItemType = GetBaseItemType(oItem); + object oNewItem; + if(ai_GetIsWeapon(oItem)) + { + int nRollTop, nRollMid, nRollBottom; + int nColorTop, nColorMid, nColorBottom; + struct stWeaponAppearance stWA; + stWA.oItem = oItem; + int nMaxModuleNumber = GetMaxWeaponModuleNumber(stWA); + nRollTop = Random(nMaxModuleNumber) + 1; + // Check bows as they must randomize to the same top, middle, and bottom otherwise they look bad. + if(nBaseItemType == BASE_ITEM_LONGBOW || nBaseItemType == BASE_ITEM_SHORTBOW) + { + nRollMid = nRollTop; + nRollBottom = nRollTop; + } + // Randomize each item individualy for other weapons. + else + { + nRollMid = Random(nMaxModuleNumber) + 1; + nRollBottom = Random(nMaxModuleNumber) + 1; + } + nColorTop = Random(9) + 1; + nColorMid = Random(9) + 1; + nColorBottom = Random(9) + 1; + // Change weapons model. + stWA.sPart = "t"; + stWA.nModel = nRollTop; + stWA.nColor = nColorTop; + stWA = GetNextWeaponAppearance(stWA, -1); + json jItem = ObjectToJson(oItem, TRUE); + //ai_Debug("pe_crafting", "614", "ModelPart" + IntToString(nModelSelected + 1) + + // " nModelNumber: " + IntToString(nModelNumber)); + jItem = GffReplaceByte(jItem, "ModelPart" + IntToString(3), stWA.nModel * 10 + stWA.nColor); + jItem = GffReplaceWord(jItem, "xModelPart" + IntToString(3), stWA.nModel * 10 + stWA.nColor); + NuiSetBind(oPC, nToken, "txt_model_number_" + stWA.sPart, JsonString(IntToString(stWA.nModel * 10 + stWA.nColor))); + stWA.sPart = "m"; + stWA.nModel = nRollMid; + stWA.nColor = nColorMid; + stWA = GetNextWeaponAppearance(stWA, -1); + jItem = GffReplaceByte(jItem, "ModelPart" + IntToString(2), stWA.nModel * 10 + stWA.nColor); + jItem = GffReplaceWord(jItem, "xModelPart" + IntToString(2), stWA.nModel * 10 + stWA.nColor); + NuiSetBind(oPC, nToken, "txt_model_number_" + stWA.sPart, JsonString(IntToString(stWA.nModel * 10 + stWA.nColor))); + stWA.sPart = "b"; + stWA.nModel = nRollBottom; + stWA.nColor = nColorBottom; + stWA = GetNextWeaponAppearance(stWA, -1); + jItem = GffReplaceByte(jItem, "ModelPart" + IntToString(1), stWA.nModel * 10 + stWA.nColor); + jItem = GffReplaceWord(jItem, "xModelPart" + IntToString(1), stWA.nModel * 10 + stWA.nColor); + NuiSetBind(oPC, nToken, "txt_model_number_" + stWA.sPart, JsonString(IntToString(stWA.nModel * 10 + stWA.nColor))); + oNewItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + AssignCommand(oTarget, ClearAllActions(TRUE)); + DestroyObject(oItem); + // Item selected 3 is the right hand, 4 is the left hand. + if (nItemSelected == 3) AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_RIGHTHAND)); + else AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_LEFTHAND)); + } + // Armor. + else if(nItemSelected == 0) + { + int nRoll, nRoll2; + json jItem = ObjectToJson(oItem, TRUE); + // Randomize the models. + // Randomize Torso + //jItem = GffReplaceByte(jItem, "ArmorPart_Torso", ); + //jItem = GffReplaceWord(jItem, "xArmorPart_Torso", ); + // Randomize the colors. + nRoll = Random(175) + 1; + if(d100() < 50) nRoll2 = nRoll + Random(5) - 3; + else nRoll2 = Random(175) + 1; + jItem = GffReplaceByte(jItem, "Cloth1Color", nRoll); + jItem = GffReplaceByte(jItem, "Cloth2Color", nRoll2); + if(d100() < 50) nRoll = nRoll + Random(5) - 3; + else nRoll = Random(175) + 1; + if(d100() < 50) nRoll2 = nRoll + Random(5) - 3; + else nRoll2 = Random(175) + 1; + jItem = GffReplaceByte(jItem, "Leather1Color", nRoll); + jItem = GffReplaceByte(jItem, "Leather2Color", nRoll2); + if(d100() < 50) nRoll = nRoll + Random(5) - 3; + else nRoll = Random(175) + 1; + if(d100() < 50) nRoll2 = nRoll + Random(5) - 3; + else nRoll2 = Random(175) + 1; + jItem = GffReplaceByte(jItem, "Metal1Color", nRoll); + jItem = GffReplaceByte(jItem, "Metal2Color", nRoll2); + DestroyObject(oItem); + oNewItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + AssignCommand(oTarget, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST)); + } + // All other items. + else + { + int nSlot; + // Get max models and inventory slot. + int nMaxModel = GetMaxSimpleItemNumber(oItem, nBaseItemType); + if(nBaseItemType == BASE_ITEM_CLOAK) nSlot = INVENTORY_SLOT_CLOAK; + else if(nBaseItemType == BASE_ITEM_HELMET) nSlot = INVENTORY_SLOT_HEAD; + else if(nBaseItemType == BASE_ITEM_LARGESHIELD || nBaseItemType == BASE_ITEM_SMALLSHIELD || + nBaseItemType == BASE_ITEM_TOWERSHIELD) nSlot = INVENTORY_SLOT_LEFTHAND; + int nRoll = Random(nMaxModel) + 1; + int nModel = GetSimpleItemNumber(oItem, nRoll, nBaseItemType); + json jItem = ObjectToJson(oItem, TRUE); + jItem = GffReplaceByte(jItem, "ModelPart1", nModel); + jItem = GffReplaceWord(jItem, "xModelPart1", nModel); + if (nBaseItemType == BASE_ITEM_CLOAK || nBaseItemType == BASE_ITEM_HELMET) + { + jItem = GffReplaceByte(jItem, "Cloth1Color", Random(175) + 1); + jItem = GffReplaceByte(jItem, "Cloth2Color", Random(175) + 1); + jItem = GffReplaceByte(jItem, "Leather1Color", Random(175) + 1); + jItem = GffReplaceByte(jItem, "Leather2Color", Random(175) + 1); + jItem = GffReplaceByte(jItem, "Metal1Color", Random(175) + 1); + jItem = GffReplaceByte(jItem, "Metal2Color", Random(175) + 1); + } + DestroyObject(oItem); + oNewItem = JsonToObject(jItem, GetLocation(oTarget), oTarget, TRUE); + AssignCommand(oTarget, ActionEquipItem(oNewItem, nSlot)); + } + return oNewItem; +} +object GetSelectedItem(object oTarget, int nItemSelected) +{ + if(nItemSelected == 0) return GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); + else if(nItemSelected == 1) return GetItemInSlot(INVENTORY_SLOT_CLOAK, oTarget); + else if(nItemSelected == 2) return GetItemInSlot(INVENTORY_SLOT_HEAD, oTarget); + else if(nItemSelected == 3) return GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + else if(nItemSelected == 4) return GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); + return OBJECT_INVALID; +} +void CancelCraftedItem(object oPC, object oTarget) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetSelectedItem(oTarget, nItemSelected); + object oOriginalItem = GetLocalObject(oPC, CRAFT_ORIGINAL_ITEM); + if(oOriginalItem != OBJECT_INVALID) + { + DestroyObject(oItem); + int nSlot = GetItemSelectedEquipSlot(nItemSelected); + // Give item Backup to Player + oOriginalItem = CopyItem(oOriginalItem, oTarget, TRUE); + DelayCommand(0.2f, AssignCommand (oTarget, ActionEquipItem(oOriginalItem, nSlot))); + DeleteLocalObject(oPC, CRAFT_ORIGINAL_ITEM); + } +} +// Gets the colorId from a image of the color pallet. +// Thanks Zunath for the base code. +int GetColorPalletId(object oPC, int nToken) +{ + float fScale = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0f; + json jPayload = NuiGetEventPayload(); + json jMousePosition = JsonObjectGet(jPayload, "mouse_pos"); + json jX = JsonObjectGet(jMousePosition, "x"); + json jY = JsonObjectGet(jMousePosition, "y"); + float fX = StringToFloat(JsonDump (jX)); + float fY = StringToFloat(JsonDump (jY)); + float fCellSize = 20.0f * fScale; + int nCellX = FloatToInt(fX / fCellSize); + int nCellY = FloatToInt(fY / fCellSize); + if(nCellX < 0) nCellX = 0; + else if (nCellX > 16) nCellX = 16; + if(nCellY < 0) nCellY = 0; + else if(nCellY > 11) nCellY = 11; + NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(IntToFloat(nCellX * 20), IntToFloat(nCellY * 20), 20.0, 20.0)); + return nCellX + nCellY * 16; +} +void SetColorPalletPointer(object oPC, int nToken, object oItem) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + int nColor; + if(!JsonGetInt(NuiGetBind(oPC, nToken, "btn_all_color"))) + { + int nModelSelected = GetArmorModelSelected(oPC); + if(!JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR))) + { + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected--; + else nModelSelected++; + } + int nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex); + } + else nColor = 255; + if(nColor == 255) nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected); + float fPointX = IntToFloat((nColor - ((nColor / 16) * 16)) * 20); + float fPointY = IntToFloat((nColor / 16) * 20); + NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(fPointX, fPointY, 20.0, 20.0)); +} +void LockItemInCraftingWindow(object oPC, object oItem, object oTarget, int nToken) +{ + NuiSetBind(oPC, nToken, "item_combo_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_cancel_label", JsonString("Cancel")); + NuiSetBind(oPC, nToken, "btn_cancel_tooltip", JsonString(" Revert back to the original items appearance")); + NuiSetBind(oPC, nToken, "btn_save_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_select_target_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_info_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_wardrobe_event", JsonBool(FALSE)); + // Make sure the item information window is closed. + nToken = NuiFindWindow(oPC, "craft_item_nui"); + if(nToken) NuiDestroy(oPC, nToken); +} +void ClearItemInCraftingWindow(object oPC, object oItem, int nToken) +{ + NuiSetBind(oPC, nToken, "btn_save_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "item_combo_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_select_target_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_info_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_wardrobe_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cancel_label", JsonString("Exit")); + NuiSetBind(oPC, nToken, "btn_cancel_tooltip", JsonString(" Exit the crafting menu")); + if(ai_GetIsWeapon(oItem)) + { + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + NuiSetBind(oPC, nToken, "model_combo_selected", JsonInt(0)); + DelayCommand(1.0, DeleteLocalInt(oPC, AI_NO_NUI_SAVE)); + } +} +void SaveCraftedItem(object oPC, object oTarget, int nToken) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetSelectedItem(oTarget, nItemSelected); + ClearItemInCraftingWindow(oPC, oItem, nToken); + DestroyObject(GetLocalObject(oPC, CRAFT_ORIGINAL_ITEM)); + DeleteLocalObject(oPC, CRAFT_ORIGINAL_ITEM); +} +int CanCraftItem(object oPC, object oItem, int nToken, int bPasteCheck = FALSE) +{ + // Plot items cannot be changed. + if(GetPlotFlag(oItem)) + { + ai_SendMessages(GetName(oItem) + "is a plot item and its appearance cannot be changed!", AI_COLOR_RED, oPC); + return FALSE; + } + // Cannot change temorary enchanted items. + if(CheckForTemporaryItemProperty(oItem)) + { + ai_SendMessages(GetName(oItem) + " cannot be altered while it has a temporary enchantment.", AI_COLOR_RED, oPC); + return FALSE; + } + // Do special paste checks. + if (bPasteCheck) + { + int nOldItemType = GetLocalInt (oPC, CRAFT_COPY_ITEM_TYPE); + int nNewItemType = GetBaseItemType(oItem); + if(nNewItemType == BASE_ITEM_ARMOR) + { + if(GetLocalInt (oPC, CRAFT_ARMOR_AC) != ai_GetArmorBonus(oItem)) + { + ai_SendMessages("The armor you are trying to paste to is not the same type as the copy!", AI_COLOR_RED, oPC); + return FALSE; + } + } + else if(nOldItemType != nNewItemType) + { + string sOldBaseItem = GetStringByStrRef(StringToInt(Get2DAString ("baseitems", "Name", nOldItemType))); + string sNewBaseItem = GetStringByStrRef(StringToInt(Get2DAString ("baseitems", "Name", nNewItemType))); + ai_SendMessages("You copied a " + sOldBaseItem + " and are trying to paste to a " + sNewBaseItem + "!", AI_COLOR_RED, oPC); + return FALSE; + } + } + if(GetLocalObject(oPC, CRAFT_ORIGINAL_ITEM) == OBJECT_INVALID) + { + object oBuildContainer = GetObjectByTag(CRAFT_CONTAINER); + if(!GetIsObjectValid(oBuildContainer)) + { + vector vPosition = GetPositionFromLocation(GetLocation(oPC)); + vPosition.z = vPosition.z -2.0; + location lLocation = Location(GetArea(oPC), vPosition, 0.0); + oBuildContainer = CreateObject(OBJECT_TYPE_PLACEABLE, CRAFT_TEMPLATE, lLocation, FALSE, CRAFT_CONTAINER); + //SetObjectVisualTransform(oBuildContainer, OBJECT_VISUAL_TRANSFORM_TRANSLATE_Z, -5.0); + } + object oBackup = CopyItem(oItem, oBuildContainer, TRUE); + // Save the original item to the PC. + SetLocalObject(oPC, CRAFT_ORIGINAL_ITEM, oBackup); + } + return TRUE; +} +void RemoveTagedEffects(object oCreature, string sEffectTag) +{ + //Search for the effect. + //Debug ("0i_effects", "578", "RemoveTagedEffects: " + sEffectTag); + effect eEffect = GetFirstEffect(oCreature); + while (GetIsEffectValid(eEffect)) + { + //Debug ("0i_effects", "582", "Effect Tag: " + GetEffectTag (eEffect)); + if (GetEffectTag(eEffect) == sEffectTag) RemoveEffect(oCreature, eEffect); + eEffect = GetNextEffect(oCreature); + } +} +int CheckForTemporaryItemProperty (object oItem) +{ + itemproperty ipProperty; + ipProperty = GetFirstItemProperty (oItem); + while (GetIsItemPropertyValid (ipProperty)) + { + // Check to see if the item is temporary enchanted. + if (GetItemPropertyDurationType (ipProperty) == DURATION_TYPE_TEMPORARY) return TRUE; + ipProperty = GetNextItemProperty (oItem); + } + return FALSE; +} +int GetHasPartColor(object oItem, int nPart, string sSide) +{ + json jItem = ObjectToJson(oItem); + string sPartName = "APart_"; + if(sSide == "Left") + { + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nPart == ITEM_APPR_ARMOR_MODEL_RTHIGH) nPart--; + else nPart++; + } + sPartName += IntToString(nPart) + "_Col_"; + int nPartColor = JsonGetInt(GffGetByte(jItem, sPartName + "0")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "1")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "2")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "3")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "4")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "5")); + //SendMessageToPC(GetFirstPC(), "sPartName: " + sPartName + " nPartColor: " + IntToString(nPartColor)); + return nPartColor; +} +void SetModelNumberText(object oPC, object oTarget, int nToken) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nItem = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetSelectedItem(oTarget, nItem); + int nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION)); + string sModelTop, sModelMiddle, sModelBottom; + // Model Group + if (ai_GetIsWeapon (oItem)) + { + int nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 0); + int nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 0); + int nModelNumber = (nModel * 10) + nColor; + sModelTop = IntToString(nModelNumber); + nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 1); + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 1); + nModelNumber = (nModel * 10) + nColor; + sModelMiddle = IntToString(nModelNumber); + nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 2); + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 2); + nModelNumber = (nModel * 10) + nColor; + sModelBottom = IntToString(nModelNumber); + NuiSetBind(oPC, nToken, "top_title_label", JsonString("Top")); + //NuiSetBind(oPC, nToken, "txt_model_number_t_enable", JsonBool(TRUE)); + //NuiSetBindWatch(oPC, nToken, "txt_model_number_t", TRUE); + NuiSetBind(oPC, nToken, "txt_model_name_t", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Middle")); + //NuiSetBind(oPC, nToken, "txt_model_number_m_enable", JsonBool(TRUE)); + //NuiSetBindWatch(oPC, nToken, "txt_model_number_m", TRUE); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Bottom")); + //NuiSetBind(oPC, nToken, "txt_model_number_b_enable", JsonBool(TRUE)); + //NuiSetBindWatch(oPC, nToken, "txt_model_number_b", TRUE); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom)); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE)); + } + // Armor and clothing + if(nItem == 0) + { + nSelected = GetArmorModelSelected(oPC); + // These models only have one side so make sure we are not linked. + if (nSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + NuiSetBind(oPC, nToken, "top_title_label", JsonString("")); + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_name_t", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model")); + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("")); + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE)); + } + else + { + sModelTop = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + if(nSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nSelected--; + else nSelected++; + sModelBottom = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + NuiSetBind(oPC, nToken, "top_title_label", JsonString("Right")); + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Right & Left")); + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Left")); + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom)); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE)); + } + } + // Cloaks and Helmets. + else + { + sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0)); + NuiSetBind(oPC, nToken, "top_title_label", JsonString("")); + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE)); + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model")); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString("")); + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE)); + } + // Color Group + if(ai_GetIsWeapon(oItem) || ai_GetIsShield(oItem)) + { + // Need to disable the color widgets. + // Row 511 + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString("gui_pal_tattoo")); + NuiSetBind(oPC, nToken, "color_pallet_image_event", JsonBool(FALSE)); + // Row 512 - Label Part to Color + // Row 5l3 + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 515 + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + // Row 516 - Label Material to Color + // Row 517 + NuiSetBind(oPC, nToken, "btn_material_0", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_2", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_4", JsonBool(FALSE)); + // Row 518 + NuiSetBind(oPC, nToken, "btn_material_1", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_3", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_5", JsonBool(FALSE)); + SetMaterialButtons(oPC, nToken, -1); + } + // Armor and clothing + else if(nItem == 0) + { + // Row 511 + string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET); + if(sColorPallet == "") sColorPallet = "gui_pal_tattoo"; + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet)); + NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel")); + NuiSetBindWatch(oPC, nToken, "txt_color_l", TRUE); + int nSelectedRight, nSelectedAll, nSelectedLeft; + int nModelSelected = GetArmorModelSelected(oPC); + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + string sColorAll = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected)); + // These models only have one side so make sure we are not linked. + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + // Row 512 - Label Part to Color + // Row 5l3 + nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)); + nSelectedAll = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ALL_COLOR)); + if(!nSelectedRight && !nSelectedAll) + { + nSelectedAll = TRUE; + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(TRUE)); + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonBool(FALSE)); + } + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedAll = nSelectedRight; + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + } + else + { + // Row 511 + string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET); + if(sColorPallet == "") sColorPallet = "gui_pal_tattoo"; + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet)); + NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel")); + // Row 512 - Label Part to Color + // Row 5l3 + nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)); + nSelectedAll = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ALL_COLOR)); + nSelectedLeft = JsonGetInt(JsonObjectGet(jCraft, CRAFT_LEFT_PART_COLOR)); + if(!nSelectedRight && !nSelectedAll && !nSelectedLeft) + { + nSelectedAll = TRUE; + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(TRUE)); + } + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(nSelectedLeft)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(TRUE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedLeft = GetHasPartColor(oItem, nModelSelected, "Left"); + nSelectedAll = nSelectedRight || nSelectedLeft; + //SendMessageToPC(oPC, "nSelectedRight: " + IntToString(nSelectedRight) + + // " nSelectedLeft: " + IntToString(nSelectedLeft)); + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(nSelectedLeft)); + // Row 516 - Label Material to Color + // Row 517 & 518 + nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + SetMaterialButtons(oPC, nToken, nSelected); + } + SetLocalJson(oPC, CRAFT_JSON, jCraft); + } + // Cloaks and Helmets. + else + { + // Row 512 - Label Part to Color + // Row 5l3 + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + //NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE)); + // Row 516 - Label Material to Color + // Row 517 & 518 + nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + SetMaterialButtons(oPC, nToken, nSelected); + } +} +void SetMaterialButtons(object oPC, int nToken, int nMaterial) +{ + int nIndex, bBool, bUseable; + string sIndex; + if(nMaterial > -1) bUseable = TRUE; + for(nIndex = 0;nIndex < 6;nIndex++) + { + if(nIndex == nMaterial) bBool = TRUE; + else bBool = FALSE; + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_material_" + sIndex + "_event", JsonBool(bUseable)); + NuiSetBind(oPC, nToken, "btn_material_" + sIndex, JsonBool(bBool)); + } +} +void CreateItemGUIPanel(object oPC, object oItem) +{ + // Row 1 (Name)************************************************************* 73 + json jRow = CreateLabel(JsonArray(), "Name:", "lbl_name_title", 50.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateTextEditBox (jRow, "name_placeholder", "txt_item_name", 60, FALSE, 325.0f, 20.0f); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Tag)************************************************************** 101 + jRow = CreateLabel(JsonArray(), "Tag:", "lbl_tag_title", 50.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateTextEditBox(jRow, "name_placeholder", "txt_item_tag", 60, FALSE, 325.0f, 20.0f); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 2 (ResRef)*********************************************************** 129 + jRow = CreateLabel(JsonArray(), "ResRef:", "lbl_resref_title", 50.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateTextEditBox(jRow, "name_placeholder", "txt_item_resref", 60, FALSE, 325.0f, 20.0f); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Base Item/Weight)************************************************* 157 + jRow = CreateLabel(JsonArray(), "Base Item: ", "lbl_baseitem_title", 75.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "", "lbl_baseitem", 145.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "Weight: ", "lbl_weight_title", 55.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "", "lbl_weight", 65.0f, 20.0f, NUI_HALIGN_LEFT); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (Gold Value)******************************************************* 185 + jRow = CreateLabel(JsonArray(), "Gold Value: ", "lbl_gold_title", 85.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "", "lbl_gold_value", 135.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "Minimum Level: ", "lbl_min_lvl_title", 110.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateLabel(jRow, "", "lbl_min_lvl", 20.0f, 20.0f, NUI_HALIGN_LEFT); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 (Plot/Stolen)****************************************************** 213 + jRow = CreateCheckBox(JsonArray(), " Plot", "chbx_plot", 110.0, 20.0f, "chbx_plot_tooltip"); + jRow = CreateCheckBox(jRow, " Stolen", "chbx_stolen", 110.0, 20.0f, "chbx_stolen_tooltip"); + jRow = CreateCheckBox(jRow, " Cursed", "chbx_cursed", 110.0, 20.0f, "chbx_cursed_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 6 (Identified/Droppable)********************************************* 269 + jRow = CreateCheckBox(JsonArray(), " Identified", "chbx_identified", 110.0, 25.0f, "chbx_identified_tooltip"); + jRow = CreateCheckBox(jRow, " Droppable", "chbx_droppable", 110.0, 25.0f, "chbx_droppable_tooltip"); + jRow = CreateButton(jRow, "Save as UTI", "btn_save_uti", 110.0, 25.0, -1.0, "btn_save_uti_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 9 (Stack/Variables/Destroy/Charges)********************************** 307 + jRow = CreateTextEditBox(JsonArray(), "name_placeholder", "txt_stack", 4, FALSE, 35.0f, 25.0f); + jRow = CreateLabel(jRow, " Stack", "lbl_stack_title", 72.0f, 20.0f, NUI_HALIGN_LEFT); + jRow = CreateTextEditBox(jRow, "name_placeholder", "txt_charges", 4, FALSE, 40.0f, 25.0f); + jRow = CreateLabel(jRow, " Charges", "lbl_charges_title", 68.0f, 25.0f, NUI_HALIGN_LEFT); + jRow = CreateButtonSelect(jRow, "Destroy", "btn_destroy", 110.0, 25.0, "btn_destroy_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 11 (Description)***************************************************** 558 + jRow = CreateTextEditBox(JsonArray(), "desc_placeholder", "txt_desc", 1000, TRUE, 375.0, 243.0, "txt_desc_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 566.0; + // Row 12 (Item Base Description)* ***************************************** 158 + int nBaseItemType = GetBaseItemType(oItem); + float fWeight; + string sBaseItemDesc; + if(nBaseItemType == BASE_ITEM_ARMOR) + { + int nArmorAC = ai_GetArmorBonus(oItem); + sBaseItemDesc = GetStringByStrRef(StringToInt(Get2DAString("armor", "BASEITEMSTATREF", nArmorAC))); + fWeight = StringToFloat(Get2DAString("armor", "WEIGHT", nArmorAC)); + } + else + { + sBaseItemDesc = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "BaseItemStatRef", nBaseItemType))); + fWeight = StringToFloat(Get2DAString("baseitems", "TenthLBS", nBaseItemType)); + } + if(sBaseItemDesc == "Bad Strref") sBaseItemDesc = ""; + if(sBaseItemDesc != "") + { + jRow = CreateTextBox(JsonArray(), "txt_base_desc", 375.0, 150.0, FALSE, NUI_SCROLLBARS_NONE, "txt_base_desc_tooltip"); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 158.0; + } + // Set the layout of the window. + json jLayout = NuiCol (jCol); + object oOwner = GetItemPossessor(oItem); + string sName = ai_StripColorCodes (GetName(oOwner)); + int nToken = SetWindow (oPC, jLayout, "craft_item_nui", sName + "'s item menu", + -1.0, -1.0, 400.0, fHeight, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_crafting"); + // Set the buttons to show events to 0e_window. + NuiSetBind(oPC, nToken, "txt_item_name_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_item_name", JsonString(GetName(oItem))); + NuiSetBindWatch(oPC, nToken, "txt_item_name", TRUE); + NuiSetBind(oPC, nToken, "txt_item_tag_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_item_tag", JsonString(GetTag(oItem))); + NuiSetBindWatch(oPC, nToken, "txt_item_tag", TRUE); + NuiSetBind(oPC, nToken, "txt_item_resref_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_item_resref", JsonString(GetResRef(oItem))); + NuiSetBindWatch(oPC, nToken, "txt_item_resref", TRUE); + string sValue = GetStringByStrRef(StringToInt(Get2DAString("baseitems", "Name", nBaseItemType))); + NuiSetBind(oPC, nToken, "lbl_baseitem_label", JsonString(sValue)); + sValue = FloatToString(fWeight * 0.1f, 0, 1); + NuiSetBind(oPC, nToken, "lbl_weight_label", JsonString(sValue)); + int nValue = GetGoldPieceValue(oItem); + NuiSetBind (oPC, nToken, "lbl_gold_value_label", JsonString(IntToString(nValue))); + sValue = IntToString (ai_GetMinimumEquipLevel(oItem)); + NuiSetBind(oPC, nToken, "lbl_min_lvl_label", JsonString (sValue)); + nValue = GetPlotFlag (oItem); + NuiSetBind(oPC, nToken, "chbx_plot_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_plot_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "chbx_plot_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_plot_tooltip", JsonString (" Plot items cannot be sold or destroyed.")); + nValue = GetStolenFlag(oItem); + NuiSetBind(oPC, nToken, "chbx_stolen_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_stolen_check", JsonBool(nValue)); + NuiSetBindWatch (oPC, nToken, "chbx_stolen_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_stolen_tooltip", JsonString (" Stolen items cannot be sold to some stores.")); + nValue = GetItemCursedFlag(oItem); + NuiSetBind(oPC, nToken, "chbx_cursed_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_cursed_check", JsonBool(nValue)); + NuiSetBindWatch (oPC, nToken, "chbx_cursed_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_cursed_tooltip", JsonString (" Cursed items cannot be dropped or sold.")); + nValue = GetIdentified (oItem); + NuiSetBind(oPC, nToken, "chbx_identified_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_identified_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "chbx_identified_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_identified_tooltip", JsonString (" Close inventory and open again to refresh identified state.")); + nValue = GetDroppableFlag(oItem); + NuiSetBind(oPC, nToken, "chbx_droppable_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "chbx_droppable_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "chbx_droppable_check", TRUE); + NuiSetBind(oPC, nToken, "chbx_droppable_tooltip", JsonString (" Droppable items only work on death of an NPC.")); + NuiSetBind(oPC, nToken, "btn_save_uti_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_save_uti_tooltip", JsonString (" Saves item to a UTI file. Update will be used in the game.")); + nValue = GetItemStackSize (oItem); + NuiSetBind(oPC, nToken, "txt_stack_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "txt_stack", JsonString(IntToString (nValue))); + NuiSetBindWatch (oPC, nToken, "txt_stack", TRUE); + nValue = GetItemCharges (oItem); + NuiSetBind(oPC, nToken, "txt_charges_event", JsonBool(TRUE)); + NuiSetBind (oPC, nToken, "txt_charges", JsonString(IntToString (nValue))); + NuiSetBindWatch (oPC, nToken, "txt_charges", TRUE); + NuiSetBind(oPC, nToken, "btn_destroy_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_destroy_tooltip", JsonString(" Destroys the item permanently! Must click twice to destroy the item.")); + // Description + NuiSetBind(oPC, nToken, "txt_desc_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "txt_desc", TRUE); + NuiSetBind(oPC, nToken, "txt_desc_tooltip", JsonString (" Color codes can be used!")); + NuiSetBind(oPC, nToken, "txt_desc", JsonString(GetDescription(oItem))); + // Base Item Description + NuiSetBind(oPC, nToken, "txt_base_desc_event", JsonBool(TRUE)); + //NuiSetBind(oPC, nToken, "txt_desc_tooltip", JsonString ("Color codes can be used!")); + if(sBaseItemDesc != "") NuiSetBind(oPC, nToken, "txt_base_desc", JsonString(sBaseItemDesc)); +} +void CraftItemInfoEvents(object oPC, int nToken) +{ + string sEvent = NuiGetEventType(); + // We don't use and it causes error windows to go off! Return early! + if(sEvent == "mouseup") return; + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + //SendMessageToPC(oPC, "0e_crafting, 1961, sElem: " + sElem + " sEvent: " + sEvent); + object oTarget = GetLocalObject(oPC, CRAFT_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oPC; + // Get the item we are crafting. + int nItemSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetLocalObject(oPC, "CRAFT_INFO_ITEM"); + if(sEvent == "click") + { + if(sElem == "btn_destroy") + { + if(!JsonGetInt(NuiGetBind(oPC, nToken, "btn_destroy"))) + { + if(!GetPlotFlag(oItem)) + { + DestroyObject(oItem); + ai_SendMessages(GetName(oItem) + " has been permanently destroyed!", AI_COLOR_RED, oPC); + NuiDestroy(oPC, nToken); + } + else + { + ai_SendMessages("The plot flag must be removed before you can destroy " + GetName(oItem) + "!", AI_COLOR_YELLOW, oPC); + } + } + else + { + ai_SendMessages("Click Destroy button again to destroy " + GetName(oItem) + "!", AI_COLOR_RED, oPC); + } + } + // Allows saving the item as a UTI! + else if(sElem == "btn_save_uti") + { + json jItem = ObjectToJson(oItem); + string sResRef = JsonGetString(NuiGetBind(oPC, nToken, "txt_item_resref")); + sResRef = ai_RemoveIllegalCharacters(sResRef); + if(sResRef == "") ai_SendMessages(GetName(oItem) + " has not been saved! ResRef does not have a value.", AI_COLOR_RED, oPC); + else + { + JsonToTemplate(jItem, sResRef, RESTYPE_UTI); + ai_SendMessages(GetName(oItem) + " has been saved as " + sResRef + ".uti in your Neverwinter Nights Temp directory.", AI_COLOR_GREEN, oPC); + ai_SendMessages("This temp directory will be removed when the game is left.", AI_COLOR_GREEN, oPC); + } + } + } + if(sEvent == "watch") + { + // Changing the name needs to be before the cooldown. + if(sElem == "txt_item_name") + { + string sName = JsonGetString(NuiGetBind(oPC, nToken, "txt_item_name")); + SetName(oItem, sName); + int nToken2 = NuiFindWindow(oPC, "crafting_nui"); + if(nToken2) NuiSetBind(oPC, nToken2, "txt_item_name", JsonString(sName)); + } + else if(sElem == "txt_item_tag") + { + string sTag = JsonGetString(NuiGetBind(oPC, nToken, "txt_item_tag")); + SetTag(oItem, sTag); + } + else if(sElem == "txt_stack") + { + int nSize = StringToInt(JsonGetString(NuiGetBind(oPC, nToken, "txt_stack"))); + int nBaseItemType = GetBaseItemType(oItem); + string sMaxSize = Get2DAString("baseitems", "Stacking", nBaseItemType); + if(nSize > StringToInt(sMaxSize)) + { + ai_SendMessages("The maximum stack for this item type is " + sMaxSize + ".", AI_COLOR_RED, oPC); + NuiSetBind(oPC, nToken, "txt_stack", JsonString(sMaxSize)); + } + if(nSize != 0) SetItemStackSize(oItem, nSize); + } + else if(sElem == "txt_charges") + { + int nCharges = StringToInt(JsonGetString(NuiGetBind(oPC, nToken, "txt_charges"))); + if(nCharges > 250) + { + ai_SendMessages("The maximum charges for this item type is 250.", AI_COLOR_RED, oPC); + NuiSetBind(oPC, nToken, "txt_charges", JsonString("250")); + } + if(nCharges != 0) SetItemCharges(oItem, nCharges); + } + else if(sElem == "chbx_plot_check") + { + int nValue = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetPlotFlag(oItem, nValue); + } + else if(sElem == "chbx_stolen_check") + { + int nValue = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetStolenFlag(oItem, nValue); + } + else if(sElem == "chbx_cursed_check") + { + int nValue = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetItemCursedFlag(oItem, nValue); + } + else if(sElem == "chbx_identified_check") + { + int nValue = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetIdentified(oItem, nValue); + } + else if(sElem == "chbx_droppable_check") + { + int nValue = JsonGetInt(NuiGetBind(oPC, nToken, sElem)); + SetDroppableFlag(oItem, nValue); + } + } +} +/*void CreateDresserGUIPanel(object oPC, object oTarget) +{ +} + diff --git a/src/module/nss/pe_debug.nss b/src/module/nss/pe_debug.nss new file mode 100644 index 0000000..5b6ad1a --- /dev/null +++ b/src/module/nss/pe_debug.nss @@ -0,0 +1,900 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: pe_debug + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + PEPS Plugin to allow use of special Debug scripts +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +#include "0i_module" +#include "0i_menus" +//#include "prc_inc_eventhk" +// Gets a variable from oTarget, if oTarget is OBJECT_INVALID then +// it will get the variable from the Module and Area. +void debug_GetObjectVariable(object oPC, object oTarget, string sDesc = ""); +// Lists the variables from oTarget to the screen. +void debug_ListObjectVariables(object oPC, object oTarget); +// Force event script change to default for oCreature. +void ai_ForceAssociateEventScriptsToDefault(object oPC, object oCreature); +// Reverts event script change from default for oCreature. +void ai_RevertAssociateEventScriptsToDefault(object oPC, object oCreature); +void main() +{ + // Get the last player to use targeting mode + object oPC = GetLastPlayerToSelectTarget(); + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + if(oPC == OBJECT_SELF && sTargetMode != "") + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + vector vTarget = GetTargetingModeSelectedPosition(); + location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + object oObject = GetLocalObject(oPC, "AI_TARGET_OBJECT"); + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget) && vTarget == Vector()) + { + return; + } + // Targeting code here. + if(sTargetMode == "DEBUG_CREATURE") + { + object oModule = GetModule(); + string sDebugName = GetName(oTarget); + SetLocalString(oModule, AI_RULE_DEBUG_CREATURE, sDebugName); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_DEBUG_CREATURE, JsonString(sDebugName)); + ai_SetCampaignDbJson("rules", jRules); + SetLocalObject(oPC, "AI_RULE_DEBUG_CREATURE_OBJECT", oTarget); + ExecuteScript("pi_debug", oPC); + } + else if(sTargetMode == "CLEAR_REPUTATION") + { + int nReputation = GetFactionAverageReputation(oTarget, oPC); + object oPCMember = GetFirstFactionMember(oPC, FALSE); + while(GetIsObjectValid(oPCMember)) + { + ClearPersonalReputation(oPCMember, oTarget); + oPCMember = GetNextFactionMember(oPC, FALSE); + } + ai_SendMessages("Your reputation with " + GetName(oTarget) + " has been set to neutral.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "SET_REPUTATION") + { + SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 50, oTarget); + SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 50, oTarget); + SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 50, oTarget); + SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 50, oTarget); + ai_SendMessages(GetName(oTarget) + " has been set to a neutral reputation.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DEBUG_INFO") + { + ai_SendMessages("Information for " + GetName(oTarget), AI_COLOR_WHITE, oPC); + ai_SendMessages("ResRef: " + GetResRef(oTarget), AI_COLOR_GREEN, oPC); + ai_SendMessages("Tag: " + GetTag(oTarget), AI_COLOR_ORANGE, oPC); + ai_SendMessages("UUID: " + GetObjectUUID(oTarget), AI_COLOR_LIGHT_MAGENTA, oPC); + ai_SendMessages("Faction Commoner: " + IntToString(GetStandardFactionReputation(STANDARD_FACTION_COMMONER, oTarget)), AI_COLOR_GREEN, oPC); + ai_SendMessages("Faction Defender: " + IntToString(GetStandardFactionReputation(STANDARD_FACTION_DEFENDER, oTarget)), AI_COLOR_GREEN, oPC); + ai_SendMessages("Faction Merchant: " + IntToString(GetStandardFactionReputation(STANDARD_FACTION_MERCHANT, oTarget)), AI_COLOR_GREEN, oPC); + ai_SendMessages("Faction Hostile: " + IntToString(GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, oTarget)), AI_COLOR_RED, oPC); + int nObjectType = GetObjectType(oTarget); + if(nObjectType == OBJECT_TYPE_CREATURE) + { + json jObject = ObjectToJson(oTarget); + string sConversation = JsonGetString(GffGetResRef(jObject, "Conversation")); + ai_SendMessages("Conversation: " + sConversation, AI_COLOR_CYAN, oPC); + SendMessageToPC(oPC, "Creature Event Scripts:"); + string sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_NOTICE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_NOTICE SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_END_COMBATROUND SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DIALOGUE SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_MELEE_ATTACKED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DAMAGED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DEATH); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DEATH SCRIPT: " + sScript); + sScript = GetLocalString(oTarget, "AI_ON_DEATH"); + if(sScript != "") + { + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DEATH SECOND SCRIPT: " + sScript); + } + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DISTURBED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_SPAWN_IN SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_RESTED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_RESTED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_SPELLCASTAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_BLOCKED_BY_DOOR SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USER_DEFINED_EVENT SCRIPT: " + sScript); + } + else if(nObjectType == OBJECT_TYPE_DOOR) + { + SendMessageToPC(oPC, "Door Event Scripts:"); + string sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_CLICKED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLICKED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_CLOSE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLOSED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_DAMAGE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DAMAGE SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_DEATH); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DEATH SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_DIALOGUE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DIALOGUE SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_DISARM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DISARM SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_FAIL_TO_OPEN); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_FAIL_TO_OPEN SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_LOCK); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_LOCK SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_MELEE_ATTACKED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_MELEE_ATTACKED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_OPEN); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_OPEN SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_SPELLCASTAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_SPELLCASTAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_TRAPTRIGGERED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_TRAPTRIGGERED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_UNLOCK); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_UNLOCK SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_DOOR_ON_USERDEFINED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USERDEFINED SCRIPT: " + sScript); + } + else if(nObjectType == OBJECT_TYPE_PLACEABLE) + { + SendMessageToPC(oPC, "Placeable Event Scripts:"); + string sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_CLOSED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLOSED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_DAMAGED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DAMAGED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_DEATH); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DEATH SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_DIALOGUE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DIALOGUE SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_DISARM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DISARM SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_INVENTORYDISTURBED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_INVENTORYDISTURBED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_LEFT_CLICK); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_LEFT_CLICK SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_LOCK); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_LOCK SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_MELEEATTACKED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_MELEEATTACKED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_OPEN); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_OPEN SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_SPELLCASTAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_SPELLCASTAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_TRAPTRIGGERED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_TRAPTRIGGERED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_UNLOCK); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_UNLOCK SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_USED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USER_DEFINED_EVENT SCRIPT: " + sScript); + } + else if(nObjectType == OBJECT_TYPE_TRIGGER) + { + SendMessageToPC(oPC, "Trigger Event Scripts:"); + string sScript = GetEventScript(oTarget, EVENT_SCRIPT_TRIGGER_ON_CLICKED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLICKED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_DISARM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_DISARM SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_OBJECT_ENTER SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_TRIGGER_ON_OBJECT_EXIT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_OBJECT_EXIT SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_PLACEABLE_ON_TRAPTRIGGERED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_TRAPTRIGGERED SCRIPT: " + sScript); + sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USER_DEFINED_EVENT SCRIPT: " + sScript); + } + else + { + // Area event scripts. + object oArea = GetArea(oPC); + SendMessageToPC(oPC, "Area Event Scripts:"); + string sScript = GetEventScript(oArea, EVENT_SCRIPT_AREA_ON_ENTER); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_ENTER SCRIPT: " + sScript); + sScript = GetEventScript(oArea, EVENT_SCRIPT_AREA_ON_EXIT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_EXIT SCRIPT: " + sScript); + sScript = GetEventScript(oArea, EVENT_SCRIPT_PLACEABLE_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oArea, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USER_DEFINED_EVENT SCRIPT: " + sScript); + // Module event scripts. + object oModule = GetModule(); + SendMessageToPC(oPC, GetModuleName() + " Module Event Scripts."); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_ACQUIRE_ITEM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_ACQUIRE_ITEM SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_ACTIVATE_ITEM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_ACTIVATE_ITEM SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_CLIENT_ENTER); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLIENT_ENTER SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_CLIENT_EXIT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_CLIENT_EXIT SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_EQUIP_ITEM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_EQUIP_ITEM SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_HEARTBEAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_HEARTBEAT SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_LOSE_ITEM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_LOSE_ITEM SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_MODULE_LOAD); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_MODULE_LOAD SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_MODULE_START); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_MODULE_START SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_NUI_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_NUI_EVENT SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_CANCEL_CUTSCENE); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_CANCEL_CUTSCENE SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_CHAT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_CHAT SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_DEATH); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_DEATH SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_DYING); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_DYING SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_GUIEVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_GUIEVENT SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_LEVEL_UP); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_LEVEL_UP SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_REST); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_REST SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_TARGET SCRIPT: " + sScript); + sScript = GetLocalString(oModule, AI_MODULE_TARGET_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + if(sScript != "") + { + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_TARGET SECOND SCRIPT: " + sScript); + } + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_TILE_ACTION); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_PLAYER_TILE_ACTION SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_RESPAWN_BUTTON_PRESSED); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_RESPAWN_BUTTON_PRESSED SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_UNEQUIP_ITEM); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_UNEQUIP_ITEM SCRIPT: " + sScript); + sScript = GetEventScript(oModule, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT); + sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]"; + SendMessageToPC(oPC, "ON_USER_DEFINED_EVENT SCRIPT: " + sScript); + } + /* Checks PRC virtual events. See prc_inc_eventhk + int nIndex = 1; + string sEvent = GetFirstEventScript(oTarget, EVENT_VIRTUAL_ONHEARTBEAT, FALSE); + if(sEvent != "") + { + SendMessageToPC(oPC, "HB event script " + IntToString(nIndex) + ": " + sEvent); + for(nIndex = 2; nIndex < 20; nIndex++) + { + sEvent = GetNextEventScript(oTarget, EVENT_VIRTUAL_ONHEARTBEAT, FALSE); + if(sEvent == "") break; + SendMessageToPC(oPC, "HB event script " + IntToString(nIndex) + ": " + sEvent); + } + }*/ + } + else if(sTargetMode == "SET_NPC_SCRIPTS") + { + if(GetLocalString(oTarget, "AI_ON_HEARTBEAT") == "") + { + ai_ForceAssociateEventScriptsToDefault(oPC, oTarget); + } + else ai_RevertAssociateEventScriptsToDefault(oPC, oTarget); + } + else if(sTargetMode == "CLEAR_CREATURE_EVENTS") + { + ai_SendMessages("Set event scripts for " + GetName(oTarget) + " to default.", AI_COLOR_YELLOW, oPC); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_NOTICE, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DEATH, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_RESTED, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "default"); + SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "default"); + DeleteLocalInt(oTarget, "AI_I_AM_BEING_HEALED"); + DeleteLocalString(oTarget, "AIScript"); + ai_ClearCreatureActions(); + } + else if(sTargetMode == "DEBUG_JSON_DUMP") + { + json jObject = ObjectToJson(oTarget, TRUE); + WriteTimestampedLogEntry(GetName(oTarget) + " JsonDump: " + JsonDump(jObject, 1)); + ai_SendMessages(GetName(oTarget) + " has been dumped to the log file!", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DEBUG_LIST_VAR") + { + debug_ListObjectVariables(oPC, oTarget); + } + else if(sTargetMode == "DEBUG_SET_VARIABLE") + { + string sVarName = GetLocalString(oPC, "Debug_Var_Name"); + int nVarType = GetLocalInt(oPC, "Debug_Var_Type"); + if(nVarType == 0) // Int + { + string sVarValue = GetLocalString(oPC, "Debug_Var_Value"); + int nVarValue = StringToInt(sVarValue); + SetLocalInt(oTarget, sVarName, nVarValue); + ai_SendMessages(sVarName + " [Int] has been set to " + IntToString(nVarValue) + " for " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 1) // Float + { + string sVarValue = GetLocalString(oPC, "Debug_Var_Value"); + DeleteLocalString(oPC, "Debug_Var_Name"); + float fVarValue = StringToFloat(sVarValue); + SetLocalFloat(oTarget, sVarName, fVarValue); + ai_SendMessages(sVarName + " [Float] has been set to " + FloatToString(fVarValue, 0, 2) + " for " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 2) // String + { + string sVarValue = GetLocalString(oPC, "Debug_Var_Value"); + SetLocalString(oTarget, sVarName, sVarValue); + ai_SendMessages(sVarName + " [String] has been set to " + sVarValue + " for " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 3) // Object + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalObject(oPC, "AI_TARGET_OBJECT", oTarget); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_OBJECT_VARIABLE"); + ai_SendMessages("Select an object to save to " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | + OBJECT_TYPE_ITEM | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_TRIGGER, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(nVarType == 4) // Location + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalObject(oPC, "AI_TARGET_OBJECT", oTarget); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_LOCATION_VARIABLE"); + ai_SendMessages("Select a location to save to " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + DeleteLocalString(oPC, "Debug_Var_Name"); + DeleteLocalInt(oPC, "Debug_Var_Type"); + DeleteLocalString(oPC, "Debug_Var_Value"); + } + else if(sTargetMode == "DEBUG_SET_OBJECT_VARIABLE") + { + string sVarName = GetLocalString(oPC, "Debug_Var_Name"); + SetLocalObject(oObject, sVarName, oTarget); + DeleteLocalObject(oPC, "AI_TARGET_OBJECT"); + DeleteLocalString(oPC, "Debug_Var_Name"); + ai_SendMessages(sVarName + " [Object] has been set to " + GetName(oObject) + " for " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DEBUG_SET_LOCATION_VARIABLE") + { + string sVarName = GetLocalString(oPC, "Debug_Var_Name"); + SetLocalLocation(oObject, sVarName, lLocation); + DeleteLocalObject(oPC, "AI_TARGET_OBJECT"); + DeleteLocalString(oPC, "Debug_Var_Name"); + ai_SendMessages(sVarName + " [Location] has been set to " + LocationToString(lLocation) + " for " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "DEBUG_DELETE_VARIABLE") + { + string sVarName = GetLocalString(oPC, "Debug_Var_Name"); + int nVarType = GetLocalInt(oPC, "Debug_Var_Type"); + if(nVarType == 0) DeleteLocalInt(oTarget, sVarName); + else if(nVarType == 1) DeleteLocalFloat(oTarget, sVarName); + else if(nVarType == 2) DeleteLocalString(oTarget, sVarName); + else if(nVarType == 4) DeleteLocalObject(oTarget, sVarName); + else if(nVarType == 5) DeleteLocalLocation(oTarget, sVarName); + ai_SendMessages(sVarName + " has been deleted from " + GetName(oTarget), AI_COLOR_YELLOW, oPC); + DeleteLocalString(oPC, "Debug_Var_Name"); + DeleteLocalInt(oPC, "Debug_Var_Type"); + } + else if(sTargetMode == "DEBUG_GET_VARIABLE") + { + debug_GetObjectVariable(oPC, oTarget); + } + } + // Run all non-targeting code here, usually NUI events. + else + { + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + //string sWndId = NuiGetWindowId(oPC, nToken); + //********************************************************************** + //if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + if(sEvent == "click") + { + if(sElem == "btn_npc_scripts") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "SET_NPC_SCRIPTS"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select an npc to change scripts for.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_CREATE, MOUSECURSOR_NOCREATE); + } + else if(sElem == "btn_set_reputation") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "SET_REPUTATION"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select a creature to set all standard reputations to neutral.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_clear_reputation") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "CLEAR_REPUTATION"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select a creature to clear your PC's reputation with that creature's faction.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_info") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_INFO"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select an object to send it's information to the players screen.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_obj_json") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_JSON_DUMP"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select an object to dump it's json values to the log.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | + OBJECT_TYPE_ITEM | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_TRIGGER, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_obj_var") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_LIST_VAR"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select an object to list it's variables to the player screen.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_debug_creature") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_CREATURE"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select a creature to start sending debug information to the log for.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_clear_events") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "CLEAR_CREATURE_EVENTS"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select a creature to set event scripts to default.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_clear_debug") + { + object oModule = GetModule(); + SetLocalString(oModule, AI_RULE_DEBUG_CREATURE, ""); + json jRules = ai_GetCampaignDbJson("rules"); + jRules = JsonObjectSet(jRules, AI_RULE_DEBUG_CREATURE, JsonString("")); + ai_SetCampaignDbJson("rules", jRules); + DeleteLocalObject(oPC, "AI_RULE_DEBUG_CREATURE_OBJECT"); + ai_SendMessages("Creature Debug mode has been cleared.", AI_COLOR_YELLOW, oPC); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_debug", oPC); + } + else if(sElem == "btn_delete_var") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + string sVarName = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")); + SetLocalString(oPC, "Debug_Var_Name", sVarName); + SetLocalString(oPC, "Debug_Var_Value", JsonGetString(NuiGetBind(oPC, nToken, "txt_var_value"))); + SetLocalInt(oPC, "Debug_Var_Type", JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected"))); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_DELETE_VARIABLE"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select Object to delete (" + sVarName + ") variable from.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_get_var") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + string sVarName = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")); + SetLocalString(oPC, "Debug_Var_Name", sVarName); + SetLocalString(oPC, "Debug_Var_Value", JsonGetString(NuiGetBind(oPC, nToken, "txt_var_value"))); + SetLocalInt(oPC, "Debug_Var_Type", JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected"))); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_GET_VARIABLE"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select Object to get (" + sVarName + ") variable from.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_set_var") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + string sVarName = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")); + SetLocalString(oPC, "Debug_Var_Name", sVarName); + SetLocalString(oPC, "Debug_Var_Value", JsonGetString(NuiGetBind(oPC, nToken, "txt_var_value"))); + SetLocalInt(oPC, "Debug_Var_Type", JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected"))); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_VARIABLE"); + NuiDestroy(oPC, nToken); + ai_SendMessages("Select Object to set (" + sVarName + ") variable to.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + } + if(sEvent == "watch") + { + if(sElem == "txt_var_name" || sElem == "txt_var_value" || + sElem == "cmb_var_type_selected") + { + if(JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")) != "") + { + NuiSetBind(oPC, nToken, "btn_get_var_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_delete_var_event", JsonBool(TRUE)); + if(JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected")) == 3 || // Objects + JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected")) == 4 || // Locations + JsonGetString(NuiGetBind(oPC, nToken, "txt_var_value")) != "") + { + NuiSetBind(oPC, nToken, "btn_set_var_event", JsonBool(TRUE)); + return; + } + } + else + { + NuiSetBind(oPC, nToken, "btn_get_var_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_delete_var_event", JsonBool(FALSE)); + } + NuiSetBind(oPC, nToken, "btn_set_var_event", JsonBool(FALSE)); + } + } + if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + if(sElem == "btn_delete_var") + { + object oModule = GetModule(); + // Set Targeting variables. + string sVarName = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")); + int nVarType = JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected")); + if(nVarType == 0) DeleteLocalInt(oModule, sVarName); + else if(nVarType == 1) DeleteLocalFloat(oModule, sVarName); + else if(nVarType == 2) DeleteLocalString(oModule, sVarName); + else if(nVarType == 4) DeleteLocalObject(oModule, sVarName); + else if(nVarType == 5) DeleteLocalLocation(oModule, sVarName); + ai_SendMessages(sVarName + " has been deleted from the Module", AI_COLOR_YELLOW, oPC); + } + else if(sElem == "btn_get_var") + { + // Set Targeting variables. + SetLocalString(oPC, "Debug_Var_Name", JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name"))); + SetLocalInt(oPC, "Debug_Var_Type", JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected"))); + debug_GetObjectVariable(oPC, GetModule(), "(Module)"); + } + else if(sElem == "btn_set_var") + { + // Set Targeting variables. + string sVarName = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_name")); + string sVarValue = JsonGetString(NuiGetBind(oPC, nToken, "txt_var_value")); + int nVarType = JsonGetInt(NuiGetBind (oPC, nToken, "cmb_var_type_selected")); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_VARIABLE"); + if(nVarType == 0) // Int + { + int nVarValue = StringToInt(sVarValue); + SetLocalInt(GetModule(), sVarName, nVarValue); + ai_SendMessages(sVarName + " [Int] has been set to " + IntToString(nVarValue) + " on the Module.", AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 1) // Float + { + float fVarValue = StringToFloat(sVarValue); + SetLocalFloat(GetModule(), sVarName, fVarValue); + ai_SendMessages(sVarName + " [Float] has been set to " + FloatToString(fVarValue, 0, 2) + " on the Module.", AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 2) // String + { + SetLocalString(GetModule(), sVarName, sVarValue); + ai_SendMessages(sVarName + " [String] has been set to " + sVarValue + " on the Module.", AI_COLOR_YELLOW, oPC); + } + else if(nVarType == 3) // Object + { + object oModule = GetModule(); + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, "Debug_Var_Name", sVarName); + SetLocalObject(oPC, "AI_TARGET_OBJECT", oModule); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_OBJECT_VARIABLE"); + ai_SendMessages("Select an object to save to " + GetName(oModule), AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | + OBJECT_TYPE_ITEM | OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_TRIGGER, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(nVarType == 4) // Location + { + object oModule = GetModule(); + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_debug"); + // Set Targeting variables. + SetLocalString(oPC, "Debug_Var_Name", sVarName); + SetLocalObject(oPC, "AI_TARGET_OBJECT", oModule); + SetLocalString(oPC, AI_TARGET_MODE, "DEBUG_SET_LOCATION_VARIABLE"); + ai_SendMessages("Select a location to save to " + GetName(oModule), AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + } + } + } + } +} +void debug_GetObjectVariable(object oPC, object oTarget, string sDesc = "") +{ + string sVar, sVarName = GetLocalString(oPC, "Debug_Var_Name"); + int nVarType = GetLocalInt(oPC, "Debug_Var_Type"); + if(nVarType == 0) sVar = IntToString(GetLocalInt(oTarget, sVarName)); + else if(nVarType == 1) sVar = FloatToString(GetLocalFloat(oTarget, sVarName), 0, 2); + else if(nVarType == 2) sVar = GetLocalString(oTarget, sVarName); + else if(nVarType == 4) sVar = GetName(GetLocalObject(oTarget, sVarName)); + else if(nVarType == 5) sVar = LocationToString(GetLocalLocation(oTarget, sVarName)); + ai_SendMessages(sVarName + " on " + GetName(oTarget) + sDesc + " is set to " + sVar, AI_COLOR_YELLOW, oPC); +} +void debug_ListObjectVariables(object oPC, object oTarget) +{ + string sName = GetName(oTarget); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + ai_SendMessages(sName + " variables:", AI_COLOR_GREEN, oPC); + json jObject = ObjectToJson(oTarget, TRUE); + json jVarTable = GffGetList(jObject, "VarTable"); + string sVariable; + int nIndex, nVarType; + json jVar = JsonArrayGet(jVarTable, nIndex); + while(JsonGetType(jVar) != JSON_TYPE_NULL) + { + sVariable = JsonGetString(GffGetString(jVar, "Name")); + nVarType = JsonGetInt(GffGetDword(jVar, "Type")); + if(nVarType == 1) + { + sVariable += " [int] "; + sVariable += IntToString(JsonGetInt(GffGetInt(jVar, "Value"))); + } + else if(nVarType == 2) + { + sVariable += " [float] "; + sVariable += FloatToString(JsonGetFloat(GffGetFloat(jVar, "Value")), 0, 2); + } + else if(nVarType == 3) + { + sVariable += " [string] "; + sVariable += JsonGetString(GffGetString(jVar, "Value")); + } + else if(nVarType == 4) + { + sName = GetName(GetLocalObject(oTarget, sVariable)); + sVariable += " [object] " + sName; + } + else if(nVarType == 5) + { + sName = LocationToString(GetLocalLocation(oTarget, sVariable)); + sVariable += " [location] " + sName; + } + else if(nVarType == 7) + { + sVariable += " [struct] "; + sVariable += JsonDump(GffGetStruct(jVar, "Value")); + } + sVariable += JsonGetString(JsonObjectGet(jVar, "Value")); + ai_SendMessages(sVariable, AI_COLOR_YELLOW, oPC); + jVar = JsonArrayGet(jVarTable, ++nIndex); + } + if(!nIndex) ai_SendMessages("No variables to list!", AI_COLOR_YELLOW, oPC); +} +void ai_ForceAssociateEventScriptsToDefault(object oPC, object oCreature) +{ + ai_SendMessages("Changing " + GetName(oCreature) + "'s event scripts to default event scripts!", AI_COLOR_YELLOW, oPC); + ai_SendMessages("Use this tool on them again to revert this creatures event scripts back!", AI_COLOR_YELLOW, oPC); + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + if(sScript == "0e_id_events" || sScript == "0e_prc_id_events") + { + ai_SendMessages("You cannot use this on creatures in Infinite Dungeons!"); + return; + } + SetLocalString(oCreature, "AI_ON_HEARTBEAT", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_ch_ac1"); + //********** On Perception ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE); + SetLocalString(oCreature, "AI_ON_NOTICE", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "nw_ch_ac2"); + //********** On End Combat Round ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND); + SetLocalString(oCreature, "AI_ON_END_COMBATROUND", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "nw_ch_ac3"); + //********** On Dialogue ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE); + SetLocalString(oCreature, "AI_ON_DIALOGUE", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "nw_ch_ac4"); + //********** On Melee Attacked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED); + SetLocalString(oCreature, "AI_ON_MELEE_ATTACKED", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "nw_ch_ac5"); + //********** On Damaged ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED); + SetLocalString(oCreature, "AI_ON_DAMAGED", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "nw_ch_ac6"); + //********** On Disturbed ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED); + SetLocalString(oCreature, "AI_ON_DISTURBED", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "nw_ch_ac8"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //********** On Rested ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED); + SetLocalString(oCreature, "AI_ON_RESTED", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, "nw_ch_aca"); + //********** On Spell Cast At ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT); + SetLocalString(oCreature, "AI_ON_SPELLCASTAT", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "nw_ch_acb"); + //********** On Blocked ********** + sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR); + SetLocalString(oCreature, "AI_ON_BLOCKED_BY_DOOR", sScript); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "nw_ch_acb"); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); + if(!GetCommandable(oCreature)) SetCommandable(TRUE, oCreature); +} +void ai_RevertAssociateEventScriptsToDefault(object oPC, object oCreature) +{ + ai_SendMessages("Changing " + GetName(oCreature) + "'s event scripts back to original!", AI_COLOR_YELLOW, oPC); + //********** On Heartbeat ********** + string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + if(sScript == "0e_id_events" || sScript == "0e_prc_id_events") + { + ai_SendMessages("You cannot use this on creatures in Infinite Dungeons!", AI_COLOR_RED, oPC); + return; + } + sScript = GetLocalString(oCreature, "AI_ON_HEARTBEAT"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, sScript); + //********** On Perception ********** + sScript = GetLocalString(oCreature, "AI_ON_NOTICE"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, sScript); + //********** On End Combat Round ********** + sScript = GetLocalString(oCreature, "AI_ON_END_COMBATROUND"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, sScript); + //********** On Dialogue ********** + sScript = GetLocalString(oCreature, "AI_ON_DIALOGUE"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, sScript); + //********** On Melee Attacked ********** + sScript = GetLocalString(oCreature, "AI_ON_MELEE_ATTACKED"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, sScript); + //********** On Damaged ********** + sScript = GetLocalString(oCreature, "AI_ON_DAMAGED"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DAMAGED, sScript); + //********** On Disturbed ********** + sScript = GetLocalString(oCreature, "AI_ON_DISTURBED"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DISTURBED, sScript); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, ""); + //********** On Rested ********** + sScript = GetLocalString(oCreature, "AI_ON_RESTED"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_RESTED, sScript); + //********** On Spell Cast At ********** + sScript = GetLocalString(oCreature, "AI_ON_SPELLCASTAT"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, sScript); + //********** On Blocked ********** + sScript = GetLocalString(oCreature, "AI_ON_BLOCKED_BY_DOOR"); + SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, sScript); + //SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, ""); + if(!GetCommandable(oCreature)) SetCommandable(TRUE, oCreature); +} + diff --git a/src/module/nss/pe_henchmen.nss b/src/module/nss/pe_henchmen.nss new file mode 100644 index 0000000..4f6bf42 --- /dev/null +++ b/src/module/nss/pe_henchmen.nss @@ -0,0 +1,589 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pe_henchmen +//////////////////////////////////////////////////////////////////////////////// + Used with pe_henchmen to run the npc plugin for + Philos Single Player Enhancements. +*/////////////////////////////////////////////////////////////////////////////// +#include "pinc_henchmen" +#include "x0_i0_henchman" +#include "0i_module" +// Creates the Henchman widget. +void PopupWidgetHenchmanGUIPanel(object oPC); +void ResetHenchmanWindows(object oPC, int nToken, object oHenchman) +{ + DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "henchman_nui"))); + DelayCommand(0.1, ExecuteScript("pi_henchmen", oPC)); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.2, CreateCharacterEditGUIPanel(oPC, oHenchman)); +} +void main() +{ + //************************************************************************** + //********************** Henchmen Targeting Execution ********************** + //************************************************************************** + // Get the last player to use targeting mode + object oPC = GetLastPlayerToSelectTarget(); + if(GetLocalInt (oPC, "0_No_Win_Save")) return; + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + if(oPC == OBJECT_SELF && sTargetMode != "") + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + vector vTarget = GetTargetingModeSelectedPosition(); + location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + object oObject = GetLocalObject(oPC, "AI_TARGET_OBJECT"); + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget) && vTarget == Vector()) + { + return; + } + // Targeting code here. + if(sTargetMode == "MAKE_NPC_HENCHMAN") + { + if(GetAssociateType(oTarget) == ASSOCIATE_TYPE_HENCHMAN) + { + ai_SendMessages(GetName(oTarget) + " is already a henchman!", AI_COLOR_RED, oPC); + return; + } + oTarget = CopyObject(oTarget, GetLocation(oPC), OBJECT_INVALID, "", TRUE); + ai_ClearCombatState(oTarget); + ChangeToStandardFaction(oTarget, STANDARD_FACTION_DEFENDER); + DeleteLocalInt(oTarget, AI_ONSPAWN_EVENT); + ai_ChangeEventScriptsForAssociate(oTarget); + AddHenchman(oPC, oTarget); + // Special check for Infinite Dungeon plot givers to be changed into henchman. + if(GetStringLeft(GetLocalString(oTarget, "sConversation"), 8) == "id1_plot") + { + DeleteLocalString(oTarget, "sConversation"); + } + // Remove this variable so they may get a unique tag associate widget. + DeleteLocalString(oTarget, AI_TAG); + ai_SendMessages(GetName(oTarget) + " has been copied and is now in your party as a henchman.", AI_COLOR_GREEN, oPC); + //ExecuteScript("pi_henchmen", oPC); + } + } + //************************************************************************** + //*********************** Henchmen Elements Execution ********************** + //************************************************************************** + else + { + // Let the inspector handle what it wants. + //HandleWindowInspectorEvent (); + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + string sWndId = NuiGetWindowId (oPC, nToken); + //SendMessageToPC(oPC, "pe_henchmen , 26 sWndId: " + sWndId + " sEvent: " + sEvent + " sElem: " + sElem + + // " nToken: " + IntToString(nToken) + " nIndex: " + IntToString(nIndex) + + // " oPC: " + GetName(oPC)); + //********************************************************************** + // Watch to see if the window moves and save. + if(sElem == "window_geometry" && sEvent == "watch") + { + if(GetLocalInt(oPC, "AI_NO_NUI_SAVE")) return; + json jGeometry = NuiGetBind(oPC, nToken, "window_geometry"); + json jData = GetHenchmanDbJson(oPC, "henchman", "0"); + if(JsonGetType(jData) == JSON_TYPE_NULL) jData = JsonObject(); + jData = JsonObjectSet(jData, sWndId, jGeometry); + SetHenchmanDbJson(oPC, "henchman", jData, "0"); + } + else if(sWndId == "henchman_nui") + { + //********************************************************************** + // Henchman menu. + if(sEvent == "click") + { + string sParty = GetHenchmanDbString(oPC, "henchname", "0"); + // Change to a different saved party #. + if(GetStringLeft(sElem, 9) == "btn_party") + { + sParty = GetStringRight(sElem, 1); + SetHenchmanDbString(oPC, "henchname", sParty, "0"); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ExecuteScript("pi_henchmen", oPC)); + } + // Add an NPC in the game as a henchman. + else if(sElem == "btn_npc_henchman") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_henchmen"); + // Set Targeting variables. + SetLocalString(oPC, AI_TARGET_MODE, "MAKE_NPC_HENCHMAN"); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + ai_SendMessages("Select an NPC to copy and make your henchman.", AI_COLOR_YELLOW, oPC); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL , MOUSECURSOR_CREATE, MOUSECURSOR_NOCREATE); + } + // ******************* Saved Character buttons ********************* + // Show saved party member. + else if(sElem == "btn_saved_char") + { + string sIndex = IntToString(nIndex); + SetHenchmanDbString(oPC, "henchname", sIndex, sParty); + AddSavedCharacterInfo(oPC, nToken, sParty); + } + // Have any saved henchman not in the party join. + else if(sElem == "btn_join_party") + { + SavedPartyJoin(oPC, nToken, sParty); + } + else if(sElem == "btn_saved_join") + { + SavedCharacterJoin(oPC, nToken, sParty); + } + else if(sElem == "btn_saved_remove") + { + string sIndex = GetHenchmanDbString(oPC, "henchname", sParty); + RemoveHenchmanDb(oPC, sParty + sIndex); + if(GetHenchmanDbString(oPC, "henchname", sParty + "0") == "") + { + SetHenchmanDbString(oPC, "henchname", "", sParty); + } + else SetHenchmanDbString(oPC, "henchname", "0", sParty); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ExecuteScript("pi_henchmen", oPC)); + } + else if(sElem == "btn_clear_party") + { + SavedPartyCleared(oPC, nToken, sParty); + } + // ******************* Current Character buttons ********************* + // Show current party member. + else if(sElem == "btn_cur_char") + { + string sIndex = IntToString(nIndex); + SetHenchmanDbString(oPC, "image", sIndex, sParty); + AddCurrentCharacterInfo(oPC, nToken, sParty); + } + // The edit button, for now we are using it to level up! + else if(sElem == "btn_cur_edit") + { + object oHenchman = GetSelectedHenchman(oPC, sParty); + SetLocalObject(oPC, HENCHMAN_TO_EDIT, oHenchman); + CreateCharacterEditGUIPanel(oPC, oHenchman); + } + else if(sElem == "btn_cur_remove") + { + RemoveYourHenchman(oPC, nToken, sParty); + } + else if(sElem == "btn_remove_party") + { + RemoveWholeParty(oPC, nToken, sParty); + } + else if(sElem == "btn_cur_save") + { + SaveYourHenchman(oPC, nToken, sParty); + SetHenchmanDbString(oPC, "henchname", "0", sParty); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, ExecuteScript("pi_henchmen", oPC)); + } + else if(sElem == "btn_save_party") + { + SaveWholeParty(oPC, nToken, sParty); + } + } + /*else if(sEvent == "watch") + { + if(sElem == "henchman_widget_check") + { + int bWidget = JsonGetInt(NuiGetBind(oPC, nToken, "henchman_widget_check")); + SetLocalInt(oPC, "AI_WIDGET_HENCHMAN", bWidget); + if(bWidget) PopupWidgetHenchmanGUIPanel(oPC); + else DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "widgethenchmanwin"))); + } + if(sElem == "lock_henchman_widget_check") + { + int bBuffLockWidget = JsonGetInt(NuiGetBind(oPC, nToken, "lock_henchman_widget_check")); + SetLocalInt(oPC, "AI_WIDGET_HENCHMAN_LOCK", bBuffLockWidget); + SetLocalInt(oPC, "AI_WIDGET_HENCHMAN", TRUE); + NuiSetBind(oPC, nToken, "henchman_widget_check", JsonBool(TRUE)); + PopupWidgetHenchmanGUIPanel(oPC); + } + } + //************************************************************************** + // Spell Buffing. + else if (sWndId == "widget_henchman") + { + if (sEvent == "click") + { + string sParty; + if (sElem == "btn_one") sParty = "1"; + if (sElem == "btn_two") sParty = "2"; + if (sElem == "btn_three") sParty = "3"; + if (sElem == "btn_four") sParty = "4"; + SetHenchmanDbString (oPC, "henchname", sParty, "0"); + PopupWidgetHenchmanGUIPanel(oPC); + } + } */ + } + else if(sWndId == "henchman_edit_nui") + { + int nChange = 0; + int nID; + string sResRef, sID, sPlot; + object oHenchman = GetLocalObject(oPC, HENCHMAN_TO_EDIT); + if(sEvent == "watch") + { + if(sElem == "char_name") + { + string sName = JsonGetString(NuiGetBind(oPC, nToken, "char_name")); + SetName(oHenchman, sName); + } + if(sElem == "port_name") + { + if(GetLocalInt(oPC, "AI_PORTRAIT_ID_SET")) + { + DeleteLocalInt(oPC, "AI_PORTRAIT_ID_SET"); + //nID = JsonGetInt(NuiGetUserData(oPC, nToken)); + //SetPortraitId(oHenchman, nID); + } + else NuiSetUserData(oPC, nToken, JsonInt(-1)); + sResRef = JsonGetString (NuiGetBind(oPC, nToken, "port_name")); + if(ResManGetAliasFor(sResRef + "l", RESTYPE_TGA) == "" && + ResManGetAliasFor(sResRef + "l", RESTYPE_DDS) == "") + { + if(GetGender(oHenchman)) sResRef = "po_hu_f_99_"; + else sResRef = "po_hu_m_99_"; + } + NuiSetBind (oPC, nToken, "port_resref_image", JsonString (sResRef + "l")); + } + else if(sElem == "cmb_class_selected") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + int nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_class_selected")); + int nClass = GetClassBySelection2DA(nSelection); + SetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nPosition), nClass); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, CreateCharacterEditGUIPanel(oPC, oHenchman)); + } + else if(sElem == "cmb_package_selected") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + string sClass = IntToString(GetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nPosition))); + int nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_package_selected")); + int nPackage = GetPackageBySelection2DA(sClass, nSelection); + SetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nPosition), nPackage); + } + else if(sElem == "cmb_soundset_selected") + { + int nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_soundset_selected")); + int nSoundSet = GetSoundSetBySelection2DA(oHenchman, nSelection); + SetSoundset(oHenchman, nSoundSet); + string sResRef = GetStringLowerCase(Get2DAString("soundset", "RESREF", nSoundSet)); + if(GetStringLeft(sResRef, 4) == "vs_f") + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 11, ":1:2:3:22:34:35:41:42:44:45:46:")); + } + else if(GetStringLeft(sResRef, 4) == "vs_n") + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 10, ":1:2:3:34:35:36:40:42:44:45:")); + } + else + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 7, ":1:2:3:11:12:13:33:")); + } + } + } + if(sEvent == "click") + { + if (sElem == "btn_desc_save") + { + string sDescription = JsonGetString(NuiGetBind(oPC, nToken, "desc_value")); + SetDescription(oHenchman, sDescription); + return; + } + else if(sElem == "btn_level_up") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + int nClass = GetClassByPosition(nPosition, oHenchman); + if(nClass == CLASS_TYPE_INVALID) + { + nClass = GetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nPosition)); + int nIndex = 1; + while(nIndex < 5) + { + if(nClass == GetClassByPosition(nIndex, oHenchman)) + { + ai_SendMessages(GetName(oHenchman) + " already has this class in a different slot! You can only level up this class in its original slot.", AI_COLOR_RED, oPC); + return; + } + nIndex++; + } + } + int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nPosition)); + if(nPackage == 0) nPackage = GetPackageBySelection2DA(IntToString(nClass), 0); + else if(nPackage == -1) + { + ai_SendMessages("There is not a valid package for this class!", AI_COLOR_RED, oPC); + return; + } + string sLevel = IntToString(GetLevelByClass(nClass, oHenchman) + 1); + json jHenchman = ObjectToJson(oHenchman, TRUE); + //WriteTimestampedLogEntry("pe_henchmen, 318, jHenchman: " + JsonDump(jHenchman, 4)); + // Check to see if this character has a LvlStatList that is required to level. + json jLvlStatList = JsonObjectGet(jHenchman, "LvlStatList"); + //WriteTimestampedLogEntry("pe_henchmen, 321, jLvlStatList: " + JsonDump(jLvlStatList, 4)); + if(JsonGetType(jLvlStatList) == JSON_TYPE_NULL) + { + RemoveHenchman(oPC, oHenchman); + // Make sure to get a clean faction version of the henchman here. + jHenchman = ObjectToJson(oHenchman, TRUE); + jHenchman = CreateLevelStatList(jHenchman, oHenchman, oPC); + location lLocation = GetLocation(oHenchman); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oHenchman); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oHenchman); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE)); + DestroyObject(oHenchman); + oHenchman = ai_AddHenchman(oPC, jHenchman, lLocation, nFamiliar, nCompanion); + SetLocalObject(oPC, HENCHMAN_TO_EDIT, oHenchman); + // We need to move party button list index to the last one since + // the henchman will move to the last henchman slot. + int nIndex = 1; + object oHench = GetHenchman(oPC, nIndex); + while(oHench != OBJECT_INVALID) + { + oHench = GetHenchman(oPC, ++nIndex); + //SendMessageToPC(oPC, "oHench: " + GetName(oHench) + " nIndex: " + IntToString(nIndex)); + } + string sParty = GetHenchmanDbString(oPC, "henchname", "0"); + SetHenchmanDbString(oPC, "image", IntToString(nIndex - 1), sParty); + } + int nLeveled = LevelUpHenchman(oHenchman, nClass, TRUE, nPackage); + //SendMessageToPC(oPC, "pe_henchmen, 282, nClass: " + IntToString(nClass) + + // " nPackage: " + IntToString(nPackage) + " nPosition: " + IntToString(nPosition) + + // " nLeveled: " + IntToString(nLeveled)); + string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + if(!nLeveled) + { + //WriteTimestampedLogEntry("pe_henchmen, 306, jLvlStatList: " + JsonDump(jLvlStatList, 1)); + ai_SendMessages(GetName(oHenchman) + " could not level " + sClass + " to level " + sLevel + "!", AI_COLOR_RED, oPC); + } + else + { + ai_SendMessages(GetName(oHenchman) + " has leveled " + sClass + " to " + sLevel + " level!", AI_COLOR_GREEN, oPC); + ResetHenchmanWindows(oPC, nToken, oHenchman); + } + return; + } + else if(sElem == "btn_reset") + { + oHenchman = ResetCharacter(oPC, oHenchman); + SetLocalObject(oPC, HENCHMAN_TO_EDIT, oHenchman); + ai_SendMessages(GetName(oHenchman) + " has been reset to level 1!", AI_COLOR_GREEN, oPC); + // We need to move party button list index to the last one since + // the henchman will move to the last henchman slot. + int nIndex = 1; + object oHench = GetHenchman(oPC, nIndex); + while(oHench != OBJECT_INVALID) + { + oHench = GetHenchman(oPC, ++nIndex); + } + string sParty = GetHenchmanDbString(oPC, "henchname", "0"); + SetHenchmanDbString(oPC, "image", IntToString(nIndex - 1), sParty); + ResetHenchmanWindows(oPC, nToken, oHenchman); + } + else if(sElem == "btn_portrait_next") + { + nID = JsonGetInt(NuiGetUserData(oPC, nToken)) + 1; + nChange = 1; + } + else if(sElem == "btn_portrait_prev") + { + nID = JsonGetInt(NuiGetUserData(oPC, nToken)) - 1; + nChange = -1; + } + else if(sElem == "btn_portrait_ok") + { + nID = JsonGetInt(NuiGetUserData(oPC, nToken)); + if(nID != -1) SetPortraitId(oHenchman, nID); + else + { + sResRef = JsonGetString (NuiGetBind (oPC, nToken, "port_name")); + if(ResManGetAliasFor(sResRef + "l", RESTYPE_TGA) == "" && + ResManGetAliasFor(sResRef + "l", RESTYPE_DDS) == "") + { + if(GetGender(oHenchman)) sResRef = "po_hu_f_99_"; + else sResRef = "po_hu_m_99_"; + SetPortraitResRef(oHenchman, sResRef); + } + } + int nHenchToken = NuiFindWindow(oPC, "henchman_nui"); + if(nHenchToken) + { + string sImage = GetPortraitResRef(oHenchman); + NuiSetBind(oPC, nHenchToken, "img_cur_portrait_image", JsonString(sImage + "l")); + } + } + if (nChange != 0) + { + int nPRace, nPGender; + int nMax2DARow = Get2DARowCount("portraits") - 1; + if(nID > 5000) nID = 1; + if(nID < 0) nID = 5000; + int nGender = GetGender(oHenchman); + int nRace = GetRacialType(oHenchman); + string sPRace = Get2DAString("portraits", "Race", nID); + if(sPRace != "") nPRace = StringToInt(sPRace); + else nPRace = -1; + string sResRef, sPGender = Get2DAString("portraits", "Sex", nID); + if(sPGender != "") nPGender = StringToInt(sPGender); + else nPGender = -1; + //WriteTimestampedLogEntry("pe_henchmen, 367, nGender: " + IntToString(nGender) + + // " nPGender: " + IntToString(nPGender) + + // " nRace: " + IntToString(nRace) + " nPRace: " + IntToString(nPRace) + + // " nID: " + IntToString(nID)); + while((nRace != nPRace && + (nRace != RACIAL_TYPE_HALFELF || + (nPRace != RACIAL_TYPE_ELF || nPRace != RACIAL_TYPE_HUMAN))) || + nGender != nPGender && nPGender != 4) + { + nID += nChange; + //WriteTimestampedLogEntry("pe_henchmen, 382, nCounter: " + IntToString(nCounter) + + // " nMax2DARow: " + IntToString(nMax2DARow)); + if (nID > 5000) nID = 1; + if (nID < 1) nID = 5000; + sPRace = Get2DAString("portraits", "Race", nID); + if(sPRace != "") nPRace = StringToInt(sPRace); + else nPRace = -1; + sPGender = Get2DAString("portraits", "Sex", nID); + if(sPGender != "") nPGender = StringToInt(sPGender); + else nPGender = -1; + //WriteTimestampedLogEntry("pe_henchmen, 385, nGender: " + IntToString(nGender) + + // " nPGender: " + IntToString(nPGender) + " sPGender: " + sPGender + + // " nRace: " + IntToString(nRace) + " nPRace: " + IntToString(nPRace) + + // " sPRace: " + sPRace + " nID: " + IntToString(nID)); + sResRef = "po_" + Get2DAString("portraits", "BaseResRef", nID) + "l"; + if(ResManGetAliasFor(sResRef, RESTYPE_TGA) == "" && + ResManGetAliasFor(sResRef, RESTYPE_DDS) == "") nPRace = 99; + } + sResRef = "po_" + Get2DAString("portraits", "BaseResRef", nID); + NuiSetUserData(oPC, nToken, JsonInt (nID)); + // This is passed to the portrait name txt that actually sets + // the portrait information and tells it we picked an ID. + SetLocalInt(oPC, "AI_PORTRAIT_ID_SET", TRUE); + NuiSetBind(oPC, nToken, "port_name", JsonString (sResRef)); + } + } + if(sEvent == "mousedown") + { + int nMouseButton = JsonGetInt(JsonObjectGet(NuiGetEventPayload(), "mouse_btn")); + if (sElem == "opt_classes" && nMouseButton == NUI_MOUSE_BUTTON_LEFT) + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")); + SetLocalInt(oHenchman, "CLASS_OPTION_POSITION", nPosition); + DelayCommand(0.0, NuiDestroy(oPC, nToken)); + DelayCommand(0.1, CreateCharacterEditGUIPanel(oPC, oHenchman)); + return; + } + if(nMouseButton == NUI_MOUSE_BUTTON_RIGHT) + { + if(sElem == "cmb_class") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + int nClass = GetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nPosition)); + string sName = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + string sDescription = GetStringByStrRef(StringToInt(Get2DAString("classes", "Description", nClass))); + string sIcon = Get2DAString("classes", "Icon", nClass); + CreateCharacterDescriptionNUI(oPC, sName, sIcon, sDescription); + } + else if(sElem == "cmb_package") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + int nClass = GetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nPosition)); + int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nPosition)); + string sName = GetStringByStrRef(StringToInt(Get2DAString("packages", "Name", nPackage))); + string sDescription = GetStringByStrRef(StringToInt(Get2DAString("packages", "Description", nPackage))); + string sIcon = Get2DAString("classes", "Icon", nClass); + CreateCharacterDescriptionNUI(oPC, sName, sIcon, sDescription); + } + else if(sElem == "cmb_soundset") + { + int nSelection = JsonGetInt(NuiGetBind(oPC, nToken, "cmb_soundset_selected")); + int nSoundSet = GetSoundSetBySelection2DA(oHenchman, nSelection); + string sResRef = GetStringLowerCase(Get2DAString("soundset", "RESREF", nSoundSet)); + if(GetStringLeft(sResRef, 4) == "vs_f") + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 11, ":1:2:3:22:34:35:41:42:44:45:46:")); + } + else if(GetStringLeft(sResRef, 4) == "vs_n") + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 10, ":1:2:3:34:35:36:40:42:44:45:")); + } + else + { + DelayCommand(0.1, ai_HaveCreatureSpeak(oHenchman, 7, ":1:2:3:11:12:13:33:")); + } + } + else if(sElem == "opt_classes") + { + int nPosition = JsonGetInt(NuiGetBind(oPC, nToken, "opt_classes_value")) + 1; + int nClass = GetClassByPosition(nPosition, oHenchman); + if(nClass != CLASS_TYPE_INVALID) + { + string sName = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + string sDescription = GetStringByStrRef(StringToInt(Get2DAString("classes", "Description", nClass))); + int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nPosition)); + string sPackageName = GetStringByStrRef(StringToInt(Get2DAString("packages", "Name", nPackage))); + sDescription += "\n\nPACKAGE: \n" + sPackageName + "\n"; + sDescription += GetStringByStrRef(StringToInt(Get2DAString("packages", "Description", nPackage))); + string sIcon = Get2DAString("classes", "Icon", nClass); + CreateCharacterDescriptionNUI(oPC, sName, sIcon, sDescription); + } + } + } + } + } + else if(sWndId == "char_description_nui") + { + if(sEvent == "click" && sElem == "btn_ok") DelayCommand(0.0, NuiDestroy(oPC, nToken)); + } + } +} +void PopupWidgetHenchmanGUIPanel(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt (oPC, "AI_NO_NUI_SAVE", TRUE); + DelayCommand (0.5f, DeleteLocalInt (oPC, "AI_NO_NUI_SAVE")); + // Row 1 (buttons)********************************************************** + json jRow = CreateButtonImage(JsonArray(), "ir_level1", "btn_one", 30.0f, 30.0f); + jRow = CreateButtonImage(jRow, "ir_level2", "btn_two", 30.0f, 30.0f); + jRow = CreateButtonImage(jRow, "ir_level3", "btn_three", 30.0f, 30.0f); + jRow = CreateButtonImage(jRow, "ir_level4", "btn_four", 30.0f, 30.0f); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + int bAINPCWidgetLock = GetLocalInt(oPC, "AI_WIDGET_HENCHMAN_LOCK"); + // Get the window location to restore it from the database. + float fX = GetLocalFloat(oPC, "widget_henchman_X"); + float fY = GetLocalFloat(oPC, "widget_henchman_Y"); + if(fX == 0.0f && fY == 0.0f) + { + fX = 10.0f; + fY = 10.0f; + } + if(bAINPCWidgetLock) + { + fX = fX + 4.0f; + fY = fY + 45.0f; + } + // Set the layout of the window. + json jLayout = NuiCol (jCol); + int nToken; + if(bAINPCWidgetLock) nToken = SetWindow (oPC, jLayout, "widget_henchman", "Henchman Widget", fX, fY, 160.0, 62.0, FALSE, FALSE, FALSE, TRUE, FALSE, "pe_npc"); + else nToken = SetWindow (oPC, jLayout, "widget_henchman", "Henchman Widget", fX, fY, 160.0, 95.0, FALSE, FALSE, FALSE, TRUE, TRUE, "pe_npc"); + // Set event watches for window inspector and save window location. + NuiSetBindWatch (oPC, nToken, "collapsed", TRUE); + NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE); + // Set the buttons to show events. + //NuiSetBind (oPC, nToken, "btn_one", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_one_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_two", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_two_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_three", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_three_event", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_four", JsonBool (TRUE)); + NuiSetBind (oPC, nToken, "btn_four_event", JsonBool (TRUE)); +} diff --git a/src/module/nss/pe_mod_set.nss b/src/module/nss/pe_mod_set.nss new file mode 100644 index 0000000..9c251b9 --- /dev/null +++ b/src/module/nss/pe_mod_set.nss @@ -0,0 +1,119 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: pe_mod_settings + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + PEPS Plugin to set module and area settings. +/*////////////////////////////////////////////////////////////////////////////// +const string AI_MODULE_HEARTBEAT_SCRIPT = "AI_MODULE_HEARTBEAT_SCRIPT"; + +#include "0i_main" +void main() +{ + // Get the last player to use targeting mode + object oPC = GetLastPlayerToSelectTarget(); + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + if(oPC == OBJECT_SELF && sTargetMode != "") + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + vector vTarget = GetTargetingModeSelectedPosition(); + location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + object oAssociate = GetLocalObject(oPC, AI_TARGET_ASSOCIATE); + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget) && vTarget == Vector()) + { + return; + } + // Targeting code here. + if(sTargetMode == "TEST_LEVEL_TARGET") + { + int nLevel = ai_GetCharacterLevels(oTarget); + int nXPNeeded = StringToInt(Get2DAString("exptable", "XP", nLevel)); + int nXPToGive = nXPNeeded - GetXP(oTarget); + GiveXPToCreature(oTarget, nXPToGive); + ai_SendMessages(GetName(oTarget) + " has gained " + IntToString(nXPToGive) + " experience to gain 1 level.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "TEST_GOLD_TARGET") + { + GiveGoldToCreature(oTarget, 10000); + ai_SendMessages(GetName(oTarget) + " has gained 10,000 gold.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "TEST_REST_TARGET") + { + ForceRest(oTarget); + ai_SendMessages(GetName(oTarget) + " has rested.", AI_COLOR_GREEN, oPC); + } + else if(sTargetMode == "TEST_HEAL_TARGET") + { + int nHeal = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + if(nHeal > 0) + { + effect eHeal = EffectHeal(nHeal); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget); + ai_SendMessages(GetName(oTarget) + " has been healed.", AI_COLOR_GREEN, oPC); + } + } + else if(sTargetMode == "TEST_ID_TARGET") SetIdentified(oTarget, !GetIdentified(oTarget)); + else if(sTargetMode == "TEST_CLEAR_TARGET") + { + ClearAllActions(TRUE, oTarget); + } + else if(sTargetMode == "TEST_KILL_TARGET") + { + effect eDmg = EffectDamage(10000); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); + ai_SendMessages(GetName(oTarget) + " has been killed.", AI_COLOR_RED, oPC); + } + else if(sTargetMode == "TEST_REMOVE_TARGET") + { + SetIsDestroyable(TRUE, FALSE, FALSE, oTarget); + DestroyObject(oTarget); + ai_SendMessages(GetName(oTarget) + " has been removed!", AI_COLOR_RED, oPC); + } + } + // Run all non-targeting code here, usually NUI events. + else + { + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + //string sWndId = NuiGetWindowId(oPC, nToken); + //********************************************************************** + //if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + if(sEvent == "click") + { + if(sElem == "btn_combat_music_off") + { + object oArea = GetFirstArea(); + while(GetIsObjectValid(oArea)) + { + MusicBattleChange(oArea, 0); + oArea = GetNextArea(); + } + ai_SendMessages(GetModuleName() + " has had the combat music removed. Save your game or you may loose this change!", AI_COLOR_GREEN, oPC); + } + if(sElem == "btn_night_to_day") + { + object oModule = GetModule(); + string sScript = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_HEARTBEAT); + if(sScript == "pc_mod_set") + { + sScript = GetLocalString(oPC, AI_MODULE_HEARTBEAT_SCRIPT); + SetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_HEARTBEAT, sScript); + DeleteLocalString(oPC, AI_MODULE_HEARTBEAT_SCRIPT); + SendMessageToPC(oPC, "Module has been set to use normal time passage!"); + } + else + { + SetLocalString(oPC, AI_MODULE_HEARTBEAT_SCRIPT, sScript); + SetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_HEARTBEAT, "pc_mod_set"); + SendMessageToPC(oPC, "Module has been set to pass through nighttime to make it morning!"); + } + } + } + } +} + + diff --git a/src/module/nss/pe_test.nss b/src/module/nss/pe_test.nss new file mode 100644 index 0000000..7fd799c --- /dev/null +++ b/src/module/nss/pe_test.nss @@ -0,0 +1,227 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script Name: pe_test + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + PEPS Plugin to help test errors. + Gives gold, Heals, etc. +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_main" +void main() +{ + // Get the last player to use targeting mode + object oPC = GetLastPlayerToSelectTarget(); + string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE); + if(oPC == OBJECT_SELF && sTargetMode != "") + { + // Get the targeting mode data + object oTarget = GetTargetingModeSelectedObject(); + vector vTarget = GetTargetingModeSelectedPosition(); + location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC)); + object oAssociate = GetLocalObject(oPC, AI_TARGET_ASSOCIATE); + // If the user manually exited targeting mode without selecting a target, return + if(!GetIsObjectValid(oTarget) && vTarget == Vector()) + { + return; + } + // Targeting code here. + if(sTargetMode == "TEST_LEVEL_TARGET") + { + int nLevel = ai_GetCharacterLevels(oTarget); + int nXPNeeded = StringToInt(Get2DAString("exptable", "XP", nLevel)); + int nXPToGive = nXPNeeded - GetXP(oTarget); + GiveXPToCreature(oTarget, nXPToGive); + ai_SendMessages(GetName(oTarget) + " has gained " + IntToString(nXPToGive) + " experience to gain 1 level.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "TEST_GOLD_TARGET") + { + GiveGoldToCreature(oTarget, 10000); + ai_SendMessages(GetName(oTarget) + " has gained 10,000 gold.", AI_COLOR_YELLOW, oPC); + } + else if(sTargetMode == "TEST_REST_TARGET") + { + ForceRest(oTarget); + ai_SendMessages(GetName(oTarget) + " has rested.", AI_COLOR_GREEN, oPC); + } + else if(sTargetMode == "TEST_HEAL_TARGET") + { + int nHeal = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget); + if(nHeal > 0) + { + effect eHeal = EffectHeal(nHeal); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget); + ai_SendMessages(GetName(oTarget) + " has been healed.", AI_COLOR_GREEN, oPC); + } + } + else if(sTargetMode == "TEST_ID_TARGET") SetIdentified(oTarget, !GetIdentified(oTarget)); + else if(sTargetMode == "TEST_CLEAR_TARGET") + { + ClearAllActions(TRUE, oTarget); + } + else if(sTargetMode == "TEST_KILL_TARGET") + { + effect eDmg = EffectDamage(10000); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget); + ai_SendMessages(GetName(oTarget) + " has been killed.", AI_COLOR_RED, oPC); + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL); + } + else if(sTargetMode == "TEST_REMOVE_TARGET") + { + SetIsDestroyable(TRUE, FALSE, FALSE, oTarget); + DestroyObject(oTarget); + ai_SendMessages(GetName(oTarget) + " has been removed!", AI_COLOR_RED, oPC); + } + else if(sTargetMode == "TEST_JUMP") + { + JumpToLocation(lLocation); + int nIndex; + object oAssociate; + for(nIndex = 2; nIndex < 6; nIndex++) + { + oAssociate = GetAssociate(nIndex, oPC); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, JumpToLocation(lLocation)); + } + for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, JumpToLocation(lLocation)); + } + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_JUMP"); + EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_TRANSITION, MOUSECURSOR_NOWALK); + } + else if(sTargetMode == "TEST_KILL_AREA") + { + effect eDmg = EffectDamage(10000); + object oKill = GetFirstObjectInShape(SHAPE_SPHERE, 6.67, lLocation, FALSE); + while(oKill != OBJECT_INVALID) + { + ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oKill); + oKill = GetNextObjectInShape(SHAPE_SPHERE, 6.67, lLocation, FALSE); + } + } + } + // Run all non-targeting code here, usually NUI events. + else + { + object oPC = NuiGetEventPlayer(); + int nToken = NuiGetEventWindow(); + string sEvent = NuiGetEventType(); + string sElem = NuiGetEventElement(); + int nIndex = NuiGetEventArrayIndex(); + //string sWndId = NuiGetWindowId(oPC, nToken); + //********************************************************************** + //if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return; + if(sEvent == "click") + { + if(sElem == "btn_level") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_LEVEL_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_gold") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_GOLD_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_CREATE, MOUSECURSOR_NOCREATE); + } + else if(sElem == "btn_rest") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_REST_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE); + } + else if(sElem == "btn_heal") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_HEAL_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_HEAL, MOUSECURSOR_NOHEAL); + } + else if(sElem == "btn_id_item") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_ID_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_ITEM, MOUSECURSOR_HEAL, MOUSECURSOR_NOHEAL); + } + else if(sElem == "btn_clear") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_CLEAR_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_MAGIC, MOUSECURSOR_NOMAGIC); + } + else if(sElem == "btn_kill") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL); + } + else if(sElem == "btn_remove") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_REMOVE_TARGET"); + EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE | + OBJECT_TYPE_DOOR | OBJECT_TYPE_ITEM | + OBJECT_TYPE_PLACEABLE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL); + } + else if(sElem == "btn_jump") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_JUMP"); + EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_TRANSITION, MOUSECURSOR_NOWALK); + } + else if(sElem == "btn_kill_area") + { + // Set this variable on the player so PEPS can run the targeting script for this plugin. + SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test"); + // Set Targeting variables. + SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF); + SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_AREA"); + SetEnterTargetingModeData(oPC, SPELL_TARGETING_SHAPE_SPHERE, 6.67, 0.0, 3); + EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL); + } + } + else if(sEvent == "watch") + { + if(sElem == "txt_debug_creature") + { + } + } + } +} + + diff --git a/src/module/nss/pi_buffing.nss b/src/module/nss/pi_buffing.nss new file mode 100644 index 0000000..6ce454e --- /dev/null +++ b/src/module/nss/pi_buffing.nss @@ -0,0 +1,338 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pi_buffing +//////////////////////////////////////////////////////////////////////////////// + Executable plug in script for Philos Module Extentions. + + Database structure: + Name(string) Tag(String) Spells(Json) + Tag: Widget - 0 = x position, 1 = y position, 2 = On/Off, 3 = Locked + Tag: List (string) set to the list number selected 1,2,3, or 4. + Tag: List# is the list of spells for List number 1,2,3, or 4. + + UI to save a players buff spells to be cast after resting. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +const int BUFF_MAX_SPELLS = 50; +const string FB_NO_MONSTER_CHECK = "FB_NO_MONSTER_CHECK"; + +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +// Creates the table and initializes if it needs to. +void CheckBuffDataAndInitialize(object oPlayer, string sTag); +// sDataField should be one of the data fields for that table. +// sData is the string data to be saved. +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag); +// sDataField should be one of the data fields for that table. +// jData is the json data to be saved. +void SetBuffDatabaseJson(object oPlayer, string sDataField, json jData, string sTag); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +json GetBuffDatabaseJson(object oPlayer, string sDataField, string sTag); +// Creates the widget for buffing. +void PopupWidgetBuffGUIPanel(object oPC); + +void main() +{ + object oPC = OBJECT_SELF; + // Check to make sure the database is setup before we do anything. + CheckBuffDataAndInitialize(oPC, "menudata"); + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + if(JsonGetType(JsonArrayGet(jMenuData, 0)) == JSON_TYPE_NULL) + { + jMenuData = JsonArrayInsert(JsonArray(), JsonString("list1")); // 0 Spell List # + jMenuData = JsonArrayInsert(jMenuData, JsonFloat(0.0)); // 1 Main menu X pos. + jMenuData = JsonArrayInsert(jMenuData, JsonFloat(GetGUIHeightMiddle(oPC, 257.0))); // 2 Main menu Y pos. + jMenuData = JsonArrayInsert(jMenuData, JsonBool(FALSE)); // 3 Widget on/off + jMenuData = JsonArrayInsert(jMenuData, JsonBool(FALSE)); // 4 Widget Locked + jMenuData = JsonArrayInsert(jMenuData, JsonFloat(10.0)); // 5 Widget X pos. + jMenuData = JsonArrayInsert(jMenuData, JsonFloat(10.0)); // 6 Widget Y pos. + SetBuffDatabaseJson(oPC, "spells", jMenuData, "menudata"); + } + if(StartingUp(oPC)) return; + // Row 1 (Buttons) ********************************************************* 83 + json jRow = CreateButtonSelect(JsonArray(), "Save", "btn_save", 60.0f, 30.0f, "btn_save_tooltip"); + CreateButton(jRow, "Clear", "btn_clear", 60.0f, 30.0f, -1.0, "btn_clear_tooltip"); + CreateButton(jRow, "Buff", "btn_buff", 60.0f, 30.0f, -1.0, "btn_buff_tooltip"); + CreateButtonSelect(jRow, "List 1", "btn_list1", 60.0f, 30.0f); + CreateButtonSelect(jRow, "List 2", "btn_list2", 60.0f, 30.0f); + CreateButtonSelect(jRow, "List 3", "btn_list3", 60.0f, 30.0f); + CreateButtonSelect(jRow, "List 4", "btn_list4", 60.0f, 30.0f); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Buttons) ********************************************************* 121 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateCheckBox(jRow, "Buff Widget", "buff_widget", 110.0, 30.0f, "buff_widget_tooltip"); + jRow = CreateCheckBox(jRow, "Lock Widget", "lock_buff_widget", 110.0, 30.0f, "lock_buff_widget_tooltip"); + if(!AI_SERVER) + { + jRow = CreateCheckBox(jRow, "Don't Check for Monsters", "chbx_no_monster_check", 200.0, 30.0f, "chbx_no_monster_check_tooltip"); + } + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (List of Spells) ************************************************** 164 + // Create the button template for the List. + jRow = JsonArray(); + string sList = JsonGetString(JsonArrayGet(jMenuData, 0)); + int nCntr, nIndex; + string sCntr, sIndex; + json jSpell; + CheckBuffDataAndInitialize(oPC, sList); + json jSpells = GetBuffDatabaseJson(oPC, "spells", sList); + while(nCntr <= BUFF_MAX_SPELLS) + { + jSpell = JsonArrayGet(jSpells, nCntr); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + sIndex = IntToString(nIndex++); + jRow = CreateButtonImage(jRow, "", "btn_spell_" + sIndex, 35.0, 35.0, 0.0, "btn_spell_" + sIndex + "_tooltip"); + } + nCntr++; + } + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Get the window location to restore it from the database. + float fWidth = IntToFloat(nIndex) * 39; + if(fWidth < 470.0) fWidth = 470.0; + float fX = JsonGetFloat(JsonArrayGet(jMenuData, 1)); + float fY = JsonGetFloat(JsonArrayGet(jMenuData, 2)); + if(fX == 0.0f && fY == 0.0f) + { + fX = 0.0f; + fY = GetGUIHeightMiddle(oPC, 257.0); + } + // Set the layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPC, jLayout, "plbuffwin", "Fast Buffing Spells", + fX, fY, fWidth, 164.0, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_buffing"); + // Set the elements to show events. + int nSelected = GetEventScript(oPC, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT) == "pc_savebuffs"; + NuiSetBind(oPC, nToken, "btn_save", JsonBool(nSelected)); + NuiSetBind(oPC, nToken, "btn_save_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_save_tooltip", JsonString(" Saves any spells cast on you or your associates.")); + NuiSetBind(oPC, nToken, "btn_clear", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_tooltip", JsonString(" Clears the current list of all saved spells.")); + NuiSetBind(oPC, nToken, "btn_buff", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_buff_tooltip", JsonString(" Casts the current list of saved spells.")); + if(sList == "list1") NuiSetBind (oPC, nToken, "btn_list1", JsonBool (TRUE)); + else NuiSetBind(oPC, nToken, "btn_list1", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_list1_event", JsonBool(TRUE)); + if(sList == "list2") NuiSetBind (oPC, nToken, "btn_list2", JsonBool (TRUE)); + else NuiSetBind(oPC, nToken, "btn_list2", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_list2_event", JsonBool(TRUE)); + if(sList == "list3") NuiSetBind (oPC, nToken, "btn_list3", JsonBool (TRUE)); + else NuiSetBind(oPC, nToken, "btn_list3", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_list3_event", JsonBool(TRUE)); + if(sList == "list4") NuiSetBind (oPC, nToken, "btn_list4", JsonBool (TRUE)); + else NuiSetBind (oPC, nToken, "btn_list4", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_list4_event", JsonBool(TRUE)); + int nValue = JsonGetInt(JsonArrayGet(jMenuData, 3)); + NuiSetBind(oPC, nToken, "buff_widget_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "buff_widget_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "buff_widget_check", TRUE); + string sText = " Creates a set of 4 buttons on the screen for quick buffing."; + NuiSetBind(oPC, nToken, "buff_widget_tooltip", JsonString(sText)); + nValue = JsonGetInt(JsonArrayGet(jMenuData, 4)); + NuiSetBind(oPC, nToken, "lock_buff_widget_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "lock_buff_widget_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "lock_buff_widget_check", TRUE); + sText = " Locks the buffing widget in place reducing its size."; + NuiSetBind(oPC, nToken, "lock_buff_widget_tooltip", JsonString(sText)); + if(!AI_SERVER) + { + NuiSetBind(oPC, nToken, "chbx_no_monster_check_event", JsonBool(TRUE)); + nValue = GetLocalInt(oPC, FB_NO_MONSTER_CHECK); + NuiSetBind(oPC, nToken, "chbx_no_monster_check_check", JsonBool(nValue)); + NuiSetBindWatch(oPC, nToken, "chbx_no_monster_check_check", TRUE); + sText = " Turns on/off checks for nearby monsters."; + NuiSetBind(oPC, nToken, "chbx_no_monster_check_tooltip", JsonString(sText)); + } + // Create buttons with spells listed. + int nSpell, nClass, nLevel, nMetamagic, nDomain; + string sName, sTargetName, sResRef; + nCntr = 0; + nIndex = 0; + while(nCntr <= BUFF_MAX_SPELLS) + { + jSpell = JsonArrayGet(jSpells, nCntr); + if(JsonGetType(jSpell) != JSON_TYPE_NULL) + { + nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); + nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); + nLevel = JsonGetInt(JsonArrayGet(jSpell, 2)); + nMetamagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); + sTargetName = JsonGetString(JsonArrayGet(jSpell, 5)); + sResRef = Get2DAString("spells", "IconResRef", nSpell); + sName = " " + GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sName += " (" + GetStringByStrRef(StringToInt(Get2DAString("classes", "Short", nClass))); + sName += " / " + IntToString (nLevel); + if(nMetamagic > 0) + { + if(nMetamagic == METAMAGIC_EMPOWER) sName += " / Empowered"; + else if(nMetamagic == METAMAGIC_EXTEND) sName += " / Extended"; + else if(nMetamagic == METAMAGIC_MAXIMIZE) sName += " / Maximized"; + else if(nMetamagic == METAMAGIC_QUICKEN) sName += " / Quickened"; + else if(nMetamagic == METAMAGIC_SILENT) sName += " / Silent"; + else if(nMetamagic == METAMAGIC_STILL) sName += " / Still"; + } + if(nDomain > 0) sName += " / Domain"; + sName += ") " + sTargetName; + sIndex = IntToString(nIndex++); + NuiSetBind(oPC, nToken, "btn_spell_" + sIndex + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_spell_" + sIndex + "_image", JsonString(sResRef)); + NuiSetBind(oPC, nToken, "btn_spell_" + sIndex + "_tooltip", JsonString(sName)); + } + nCntr++; + } + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_buffing")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Quick Buff")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("dm_appear")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata"); + int bWidgetOn = JsonGetInt(JsonArrayGet(jMenuData, 3)); + if(bWidgetOn) + { + PopupWidgetBuffGUIPanel(oPC); + ai_SendMessages("Buffing widget has been created.", AI_COLOR_YELLOW, oPC); + } + return TRUE; +} +void CreateBuffDataTable(object oPlayer) +{ + sqlquery sql = SqlPrepareQueryObject(oPlayer, + "CREATE TABLE IF NOT EXISTS BUFF_TABLE (" + + "name TEXT, " + + "tag TEXT, " + + "spells TEXT, " + + "PRIMARY KEY(name, tag));"); + SqlStep(sql); +} +void CheckBuffDataAndInitialize(object oPlayer, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT name FROM sqlite_master WHERE type ='table' AND name=@tableName;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString (sql, "@tableName", "BUFF_TABLE"); + if(!SqlStep (sql)) CreateBuffDataTable(oPlayer); + sQuery = "SELECT name FROM BUFF_TABLE Where name = @name AND tag = @tag;"; + sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if(!SqlStep(sql)) + { + sQuery = "INSERT INTO BUFF_TABLE(name, tag, spells) " + + "VALUES (@name, @tag, @spells);"; + sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + SqlBindJson(sql, "@spells", JsonArray()); + SqlStep(sql); + } +} +void SetBuffDatabaseString(object oPlayer, string sDataField, string sData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@data", sData); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + SqlStep(sql); +} +string GetBuffDatabaseString(object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if(SqlStep(sql)) return SqlGetString(sql, 0); + else return ""; +} +void SetBuffDatabaseJson (object oPlayer, string sDataField, json jData, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "UPDATE BUFF_TABLE SET " + sDataField + " = @data WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindJson(sql, "@data", jData); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + SqlStep(sql); +} +json GetBuffDatabaseJson(object oPlayer, string sDataField, string sTag) +{ + string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer, TRUE))); + string sQuery = "SELECT " + sDataField + " FROM BUFF_TABLE WHERE name = @name AND tag = @tag;"; + sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); + SqlBindString(sql, "@name", sName); + SqlBindString(sql, "@tag", sTag); + if(SqlStep(sql)) return SqlGetJson(sql, 0); + else return JsonArray(); +} +void PopupWidgetBuffGUIPanel(object oPC) +{ + // Set window to not save until it has been created. + SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // Row 1 (buttons)********************************************************** + json jRow = JsonArray(); + CreateButtonImage(jRow, "ir_level1", "btn_one", 35.0f, 35.0f, 0.0); + CreateButtonImage(jRow, "ir_level2", "btn_two", 35.0f, 35.0f, 0.0); + CreateButtonImage(jRow, "ir_level3", "btn_three", 35.0f, 35.0f, 0.0); + CreateButtonImage(jRow, "ir_level4", "btn_four", 35.0f, 35.0f, 0.0); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + json jWidget = GetBuffDatabaseJson(oPC, "spells", "menudata"); + int bAIBuffWidgetLock = JsonGetInt(JsonArrayGet(jWidget, 4)); + // Get the window location to restore it from the database. + float fX = JsonGetFloat(JsonArrayGet(jWidget, 5)); + float fY = JsonGetFloat(JsonArrayGet(jWidget, 6)); + if(fX == 0.0f && fY == 0.0f) + { + fX = 10.0f; + fY = 10.0f; + } + if(bAIBuffWidgetLock) + { + fX = fX + 4.0f; + fY = fY + 45.0f; + } + // Set the layout of the window. + json jLayout = NuiCol (jCol); + int nToken; + if(bAIBuffWidgetLock) nToken = SetWindow(oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 62.0, FALSE, FALSE, FALSE, TRUE, FALSE, "pe_buffing"); + else nToken = SetWindow(oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 95.0, FALSE, FALSE, FALSE, TRUE, TRUE, "pe_buffing"); + // Set event watches for window inspector and save window location. + //NuiSetBindWatch(oPC, nToken, "collapsed", TRUE); + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + // Set the buttons to show events. + //NuiSetBind (oPC, nToken, "btn_one", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_one_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_two", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_two_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_three", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_three_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_four", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_four_event", JsonBool(TRUE)); +} + diff --git a/src/module/nss/pi_crafting.nss b/src/module/nss/pi_crafting.nss new file mode 100644 index 0000000..3fa9775 --- /dev/null +++ b/src/module/nss/pi_crafting.nss @@ -0,0 +1,717 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pi_crafting +//////////////////////////////////////////////////////////////////////////////// + Executable plug in script for Philos Module Extentions + + Crafting UI for players items. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "0i_items" +#include "nw_inc_gff" +const string CRAFT_JSON = "CRAFT_JSON"; +const string CRAFT_COOL_DOWN = "CRAFT_COOL_DOWN"; +const string CRAFT_ITEM_SELECTION = "CRAFT_ITEM_SELECTION"; +const string CRAFT_MATERIAL_SELECTION = "CRAFT_MATERIAL_SELECTION"; +const string CRAFT_MODEL_SELECTION = "CRAFT_MODEL_SELECTION"; +const string CRAFT_COLOR_PALLET = "CRAFT_COLOR_PALLET"; +const string CRAFT_LEFT_PART_COLOR = "CRAFT_LEFT_PART_COLOR"; +const string CRAFT_ALL_COLOR = "CRAFT_ALL_COLOR"; +const string CRAFT_RIGHT_PART_COLOR = "CRAFT_RIGHT_PART_COLOR"; +const string CRAFT_TARGET = "CRAFT_TARGET"; +// Tag used in lighting effects. +const string CRAFT_HIGHLIGHT = "CRAFT_HIGHLIGHT"; +const string CRAFT_ULTRALIGHT = "CRAFT_ULTRALIGHT"; + +json CreateItemCombo(object oPC, json jRow, string sComboBind); +json CreateModelCombo(object oPC, object oTarget, json jRow, string sComboBind); +json CreateMaterialCombo(object oPC, json jRow, string sComboBind); +// Sets the material buttons for use. +// nMaterial 0,1 Cloth 2,3 Leather 4,5 Metal -1 None. +void SetMaterialButtons(object oPC, int nToken, int nMaterial); +// Returns the correct item based on the crafting menu selected item. +object GetSelectedItem(object oTarget, int nItemSelected); +int GetArmorModelSelected(object oPC); +// Returns True if oItem, nPart has a per part color for sSide. +int GetHasPartColor(object oItem, int nPart, string sSide); +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +void main() +{ + object oPC = OBJECT_SELF; + object oTarget = GetLocalObject(oPC, CRAFT_TARGET); + if(oTarget == OBJECT_INVALID) oTarget = oPC; + if(StartingUp(oPC)) return; + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + // Row 1 (Object Name)****************************************************** 508 / 83 + json jRow = CreateTextEditBox(JsonArray(), "plc_hold_bind", "txt_item_name", 50, FALSE, 486.0f, 30.0f); // 419 + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Object Name)****************************************************** 508 / 121 + jRow = JsonArray(); + if(!AI_SERVER) jRow = CreateButton(jRow, "Information", "btn_info", 160.0f, 30.0f, -1.0, "btn_info_tooltip"); + else + { + if(GetIsDM(oTarget)) + { + jRow = CreateButton(jRow, "Information", "btn_info", 160.0f, 30.0f, -1.0, "btn_info_tooltip"); + } + else jRow = JsonArrayInsert(jRow, NuiSpacer()); + } + jRow = CreateButton(jRow, "Wardrobe", "btn_wardrobe", 158.0f, 30.0f, -1.0, "btn_wardrobe_tooltip"); + jRow = CreateButtonSelect(jRow, "Add Light", "btn_highlight", 160.0f, 30.0f, "btn_highlight_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Object Name)****************************************************** 508 / 159 + jRow = CreateButton(JsonArray(), "Save", "btn_save", 160.0f, 30.0f, -1.0, "btn_save_tooltip"); + jRow = CreateButton(jRow, "Select Target", "btn_select_target", 158.0f, 30.0f); + jRow = CreateButton(jRow, "", "btn_cancel", 160.0f, 30.0f, -1.0, "btn_cancel_tooltip"); + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (labels)*********************************************************** 508 / 177 + jRow = CreateLabel(JsonArray(), "Model", "module_title", 143.0f, 10.0f); + jRow = CreateLabel(jRow, "Color", "color_title", 339.0f, 10.0f); + jRow = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 (groups) + // Row 51 (title)*********************************************************** 508 / 195 / 18 + json jGroupRow = CreateLabel(JsonArray(), "Item", "item__cmb_title", 128.0f, 10.0f); + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + // Row 52 (combo)*********************************************************** 508 / 233 / 56 + jGroupRow = CreateItemCombo(oPC, JsonArray(), "item_combo"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 53 (title)*********************************************************** 508 / 251 / 74 + jGroupRow = CreateLabel(JsonArray(), "Model", "model_cmb_title",128.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 54 (combo)*********************************************************** 508 / 289 / 112 + jGroupRow = CreateModelCombo(oPC, oTarget, JsonArray(), "model_combo"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 55 (title)*********************************************************** 508 / 307 / 120 + jGroupRow = CreateLabel(JsonArray(), "", "top_title",128.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 56 (top)************************************************************* 508 / 355 / 168 + jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_t", 40.0f, 40.0f); + // Removed TextEditBox for mobile + jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_t", 3, FALSE, 40.0, 40.0); + //CreateLabel(jGroupRow, "", "txt_model_number_t", 40.0, 40.0); + jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_t", 40.0f, 40.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 57 (title)*********************************************************** 508 / 373 / 186 + jGroupRow = CreateLabel(JsonArray(), "", "middle_title",128.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 58 (middle)********************************************************** 508 / 421 /234 + jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_m", 40.0f, 40.0f); + // Removed TextEditBox for mobile + jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_m", 3, FALSE, 40.0, 40.0); + //CreateLabel(jGroupRow, "", "txt_model_number_m", 40.0, 40.0); + jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_m", 40.0f, 40.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 59 (title)*********************************************************** 508 / 439 / 252 + jGroupRow = CreateLabel(JsonArray(), "", "bottom_title",128.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 510 (bottom)********************************************************* 508 / 487 /300 + jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_b", 40.0f, 40.0f); + // Removed TextEditBox for mobile + jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_b", 3, FALSE, 40.0, 40.0); + //CreateLabel(jGroupRow, "", "txt_model_number_b", 40.0, 40.0); + jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_b", 40.0f, 40.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 511 (blank spacer) + jGroupRow = CreateLabel(JsonArray(), "", "blank_space",128.0f, 20.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 512 (light)********************************************************** 508 / 487 /300 + jGroupRow = CreateButtonSelect(JsonArray(), "Randomize", "btn_randomize", 128.0f, 30.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupCol = JsonArrayInsert(jGroupCol, NuiSpacer()); + jRow = JsonArrayInsert(JsonArray(), NuiHeight(NuiWidth(NuiGroup(NuiCol(jGroupCol)), 143.0), 442.0)); + // Make the Color Group. + // Row 550 (groups)********************************************************* 508 / 361 / 184 + json jImage = NuiEnabled(NuiId(NuiImage(NuiBind("color_pallet_image"), JsonInt(0), JsonInt(0), JsonInt(1)), "color_pallet"), NuiBind("color_pallet_event")); + jImage = NuiWidth(jImage, 320.0); // 256 + 64 + jImage = NuiHeight(jImage, 220.0); // 176 + 44 + jImage = NuiTooltip(jImage, NuiBind("color_pallet_tooltip")); + json jIndicator = JsonArrayInsert(JsonArray(), NuiDrawListRect(JsonBool(TRUE), NuiColor(255,255,255), JsonBool(FALSE), JsonFloat(2.0), NuiBind("color_pallet_pointer"))); + jImage = NuiDrawList(jImage, JsonBool(FALSE), jIndicator); + jGroupRow = JsonArrayInsert(JsonArray(), jImage); + jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + // Row 551 (groups)********************************************************* 508 / 379 /202 + jGroupRow = CreateLabel(JsonArray(), "Part To Color", "lbl_color_parts", 320.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 552 (groups)********************************************************* 508 / 417 /240 + jGroupRow = CreateButtonSelect(JsonArray(), "Right", "btn_right_part_color", 98.0, 30.0, "btn_right_part_color_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "All", "btn_all_color", 98.0, 30.0, "btn_all_color_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "Left", "btn_left_part_color", 98.0, 30.0, "btn_left_part_color_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 553 (groups)********************************************************* 508 / 435 / 258 + jGroupRow = CreateLabel(JsonArray(), "Part Color To Reset", "lbl_reset_parts", 320.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 554 (groups)********************************************************* 508 / 473 /296 + jGroupRow = CreateButton(JsonArray(), "Right", "btn_right_part_reset", 98.0, 30.0, -1.0, "btn_right_part_reset_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButton(jGroupRow, "All", "btn_all_reset", 50.0, 30.0, -1.0, "btn_all_reset_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButton(jGroupRow, "Left", "btn_left_part_reset", 98.0, 30.0, -1.0, "btn_left_part_reset_tooltip"); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 555 (groups)********************************************************* 508 / 491 / 314 + jGroupRow = CreateLabel(JsonArray(), "Material to Color", "lbl_material_color", 320.0f, 10.0f); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 556 (groups)********************************************************* 508 / 529 /352 + jGroupRow = CreateButtonSelect(JsonArray(), "Cloth 1", "btn_material_0", 98.0, 30.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "Leather 1", "btn_material_2", 98.0, 30.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "Metal 1", "btn_material_4", 98.0, 30.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Row 557 (groups)********************************************************* 508 / 567 / 390 + jGroupRow = CreateButtonSelect(JsonArray(), "Cloth 2", "btn_material_1", 98.0, 30.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "Leather 2", "btn_material_3", 98.0, 30.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButtonSelect(jGroupRow, "Metal 2", "btn_material_5", 98.0, 30.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupCol = JsonArrayInsert(jGroupCol, NuiSpacer()); + jRow = JsonArrayInsert(jRow, NuiHeight(NuiWidth(NuiGroup(NuiCol(jGroupCol)), 339.0), 442.0)); // 275 398 + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + json jLayout = NuiCol(jCol); + // Get the window location to restore it from the database. + json jGeometry = JsonObjectGet(jCraft, "CRAFT_MENU"); + float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x")); + float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y")); + string sPCWindow; + int nToken = SetWindow(oPC, jLayout, "crafting_nui", "Crafting", + fX, fY, 508.0, 700.0, FALSE, FALSE, FALSE, FALSE, TRUE, "pe_crafting"); // 444 645 + // Set all binds, events, and watches. + NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE); + int nItem = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + object oItem = GetSelectedItem(oTarget, nItem); + // Row 1 + NuiSetBind(oPC, nToken, "txt_item_name", JsonString(GetName(oItem))); + NuiSetBind(oPC, nToken, "txt_item_name_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "txt_item_name", TRUE); + // Row 2 + NuiSetBind(oPC, nToken, "btn_info_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_info_tooltip", JsonString(" Look at and change item information")); + NuiSetBind(oPC, nToken, "btn_wardrobe_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_wardrobe_tooltip", JsonString(" Use your wardrobe to save/load item appearances")); + int nLight = GetLocalInt(oPC, CRAFT_HIGHLIGHT) + GetLocalInt(oPC, CRAFT_ULTRALIGHT); + NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(nLight)); + NuiSetBind(oPC, nToken, "btn_highlight_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_highlight_tooltip", JsonString(" Left click for White light, Right click for Ultravision")); + // Row 3 + NuiSetBind(oPC, nToken, "btn_save_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_save_tooltip", JsonString(" Save current changes")); + NuiSetBind(oPC, nToken, "btn_select_target_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cancel_label", JsonString("Exit")); + NuiSetBind(oPC, nToken, "btn_cancel_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cancel_tooltip", JsonString(" Exit the crafting menu")); + // Row 4 Labels. + // Row 5 Groups. + // Row 51 title. + // Row 52 + NuiSetBind(oPC, nToken, "item_combo_selected", JsonInt(nItem)); + NuiSetBind(oPC, nToken, "item_combo_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "item_combo_selected", TRUE); + // Row 53 title. + // Row 54 + int nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION)); + if(nItem == 1 || nItem == 2 || nItem == 4) + { + if(GetHiddenWhenEquipped(oItem)) nSelected = 1; + else nSelected = 0; + } + NuiSetBind(oPC, nToken, "model_combo_selected", JsonInt (nSelected)); + NuiSetBind(oPC, nToken, "model_combo_event", JsonBool (TRUE)); + NuiSetBindWatch(oPC, nToken, "model_combo_selected", TRUE); + // Row 55, 56, 57 titles + // Row 58 top, 59 middle, 510 bottom + string sModelTop, sModelMiddle, sModelBottom; + // Model Group + if(ai_GetIsWeapon(oItem)) + { + int nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 0); + int nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 0); + int nModelNumber = (nModel * 10) + nColor; + sModelTop = IntToString(nModelNumber); + nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 1); + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 1); + nModelNumber = (nModel * 10) + nColor; + sModelMiddle = IntToString(nModelNumber); + nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 2); + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 2); + nModelNumber = (nModel * 10) + nColor; + sModelBottom = IntToString(nModelNumber); + // Row 55 + NuiSetBind(oPC, nToken, "top_title_label", JsonString("Top")); + // Row 56 + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE)); + // Row 57 + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Middle")); + // Row 58 + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + // Row 59 + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Bottom")); + // Row 510 + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom)); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE)); + // Row 511 + NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected weapon")); + } + // Armor and clothing + else if(nItem == 0) + { + nSelected = GetArmorModelSelected(oPC); + // These models only have one side so make sure we are not linked. + if (nSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + // Row 55 + NuiSetBind(oPC, nToken, "top_title_label", JsonString("")); + // Row 56 + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_name_t", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE)); + // Row 57 + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model")); + // Row 58 + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + // Row 59 + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("")); + // Row 510 + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE)); + } + else + { + sModelTop = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + if(nSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nSelected--; + else nSelected++; + sModelBottom = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected)); + // Row 55 + NuiSetBind(oPC, nToken, "top_title_label", JsonString("Right")); + // Row 56 + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE)); + // Row 57 + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Right & Left")); + // Row 58 + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelTop)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + // Row 59 + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Left")); + // Row 510 + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom)); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE)); + } + // Row 511 + NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected armor")); + } + // Shields, Cloaks, and Helmets. + else + { + sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0)); + // Row 55 + NuiSetBind(oPC, nToken, "top_title_label", JsonString("")); + // Row 56 + //NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE)); + // Row 57 + NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model")); + // Row 58 + //NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle)); + NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE)); + // Row 59 + NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("")); + // Row 510 + //NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString("")); + NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE)); + // Row 511 + NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected item")); + } + // Color Group + if(ai_GetIsWeapon(oItem) || ai_GetIsShield(oItem)) + { + // Need to disable the color widgets. + // Row 511 + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString("gui_pal_tattoo")); + NuiSetBind(oPC, nToken, "color_pallet_image_event", JsonBool(FALSE)); + // Row 512 - Label Part to Color + // Row 5l3 + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 515 + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + // Row 516 - Label Material to Color + // Row 517 + NuiSetBind(oPC, nToken, "btn_material_0", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_2", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_4", JsonBool(FALSE)); + // Row 518 + NuiSetBind(oPC, nToken, "btn_material_1", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_3", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_material_5", JsonBool(FALSE)); + SetMaterialButtons(oPC, nToken, -1); + } + // Armor and clothing + else if(nItem == 0) + { + // Row 511 + string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET); + if(sColorPallet == "") sColorPallet = "gui_pal_tattoo"; + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + int nModelSelected = GetArmorModelSelected(oPC); + // Row 511 + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet)); + NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel")); + int nSelectedRight, nSelectedAll, nSelectedLeft; + string sColorAll = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected)); + // These models only have one side so make sure we are not linked. + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK || + nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO || + nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT || + nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS || + nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE) + { + // Row 512 - Label Part to Color + // Row 5l3 + int nPartColor = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)); + if(!nSelectedRight && nPartColor) + { + nSelectedRight = TRUE; + nSelectedLeft = FALSE; + } + nSelectedAll = !nSelectedRight; + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(nSelectedAll)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedAll = nSelectedRight; + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + } + else + { + // Row 512 - Label Part to Color + // Row 5l3 + int nPartColor = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)); + if(!nSelectedRight && nPartColor) + { + nSelectedRight = TRUE; + nSelectedLeft = FALSE; + } + else + { + nPartColor = GetHasPartColor(oItem, nModelSelected, "Left"); + nSelectedLeft = JsonGetInt(JsonObjectGet(jCraft, CRAFT_LEFT_PART_COLOR)); + if(!nSelectedLeft && nPartColor) + { + nSelectedLeft = TRUE; + nSelectedRight = FALSE; + } + } + nSelectedAll = !nSelectedRight && !nSelectedLeft; + jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonBool(nSelectedLeft)); + jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(nSelectedAll)); + jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(nSelectedLeft)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(TRUE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right"); + nSelectedLeft = GetHasPartColor(oItem, nModelSelected, "Left"); + nSelectedAll = nSelectedRight || nSelectedLeft; + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight)); + NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(nSelectedLeft)); + } + int nColor; + if(!JsonGetInt(NuiGetBind(oPC, nToken, "btn_all_color"))) + { + int nModelSelected = GetArmorModelSelected(oPC); + if(!JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR))) + { + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected--; + else nModelSelected++; + } + int nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected; + nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex); + } + else nColor = 255; + if(nColor == 255) nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected); + float fPointX = IntToFloat((nColor - ((nColor / 16) * 16)) * 20); + float fPointY = IntToFloat((nColor / 16) * 20); + NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(fPointX, fPointY, 20.0, 20.0)); + // Row 516 - Label Material to Color + // Row 517 & 518 + NuiSetBind(oPC, nToken, "btn_right_part_color_tooltip", JsonString(" Select the right part to be uniquely colored")); + NuiSetBind(oPC, nToken, "btn_all_color_tooltip", JsonString(" Select all parts to be colored")); + NuiSetBind(oPC, nToken, "btn_left_part_color_tooltip", JsonString(" Select the left part to be uniquely colored")); + NuiSetBind(oPC, nToken, "btn_right_part_reset_tooltip", JsonString(" Clears the right part's unique color")); + NuiSetBind(oPC, nToken, "btn_all_reset_tooltip", JsonString(" Clears all parts unique colors")); + NuiSetBind(oPC, nToken, "btn_left_part_reset_tooltip", JsonString(" Clears the left part's unique color")); + nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + SetMaterialButtons(oPC, nToken, nSelected); + SetLocalJson(oPC, CRAFT_JSON, jCraft); + } + // Cloaks and Helmets. + else + { + // Row 511 + string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET); + if(sColorPallet == "") sColorPallet = "gui_pal_tattoo"; + int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + int nModelSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION)); + int nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected); + float fPointX = IntToFloat((nColor - ((nColor / 16) * 16)) * 20); + float fPointY = IntToFloat((nColor / 16) * 20); + NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(fPointX, fPointY, 20.0, 20.0)); + NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet)); + NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel")); + // Row 512 - Label Part to Color + // Row 5l3 + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE)); + // Row 514 - Label Part Color to Reset + // Row 5l5 + NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE)); + //NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE)); + // Row 516 - Label Material to Color + // Row 517 & 518 + nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION)); + SetMaterialButtons(oPC, nToken, nSelected); + } + // Lets make sure we clean up any cool down variables. + //DeleteLocalInt(oPC, CRAFT_COOL_DOWN); +} +json CreateItemCombo(object oPC, json jRow, string sComboBind) +{ + int nCnt; + // Create the list. + json jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Armor", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Cloak", 1)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Headgear", 2)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Right hand", 3)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Left hand", 4)); + return CreateCombo(jRow, jCombo, sComboBind, 128.0, 40.0); +} +json CreateModelCombo(object oPC, object oTarget, json jRow, string sComboBind) +{ + float fFacing = GetFacing(oTarget); + json jCombo, jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION)); + // Create the list. + // Armor. + if(nSelected == 0) + { + fFacing += 180.0f; + if (fFacing > 359.0) fFacing -=359.0; + AssignCommand(oPC, SetCameraFacing(fFacing, 4.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST)); + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Neck", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Shoulder", 1)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Bicep", 2)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Forearm", 3)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Hand", 4)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Torso", 5)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Belt", 6)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Pelvis", 7)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Thigh", 8)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Shin", 9)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Foot", 10)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Robe", 11)); + } + // Cloak. + else if(nSelected == 1) + { + if(fFacing > 359.0) fFacing -=359.0; + AssignCommand (oPC, SetCameraFacing(fFacing, 4.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST)); + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Cloak", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1)); + } + // Headgear. + else if (nSelected == 2) + { + fFacing += 180.0f; + if(fFacing > 359.0) fFacing -=359.0; + AssignCommand(oPC, SetCameraFacing(fFacing, 2.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST)); + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Headgear", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1)); + } + // Weapon. + else if (nSelected == 3) + { + // If they are changing a bow then face the opposite side. + object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); + int nBaseItemType = GetBaseItemType(oItem); + if(nBaseItemType == BASE_ITEM_LONGBOW || nBaseItemType == BASE_ITEM_SHORTBOW) fFacing -= 90.00; + // This will make the camera face a melee weapon. + else fFacing += 90.0; + if(fFacing > 359.0) fFacing -=359.0; + AssignCommand(oPC, SetCameraFacing(fFacing, 3.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST)); + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Weapon", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Acidic", 1)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Frost", 2)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Electric", 3)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Unholy", 4)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Flaming", 5)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Holy", 6)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Sonic", 7)); +} + // Weapon/Shield. + else if(nSelected == 4) + { + fFacing += 270.0f; + if(fFacing > 359.0) fFacing -=359.0; + AssignCommand(oPC, SetCameraFacing(fFacing, 3.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST)); + object oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); + if(ai_GetIsShield(oItem)) + { + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Shield", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1)); + } + else + { + jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Weapon", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Acidic", 1)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Frost", 2)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Electric", 3)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Unholy", 4)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Flaming", 5)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Holy", 6)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Sonic", 7)); + } + } + return CreateCombo(jRow, jCombo, sComboBind, 128.0, 40.0); +} +void SetMaterialButtons(object oPC, int nToken, int nMaterial) +{ + int nIndex, bBool, bUseable; + string sIndex; + if(nMaterial > -1) bUseable = TRUE; + for(nIndex = 0;nIndex < 6;nIndex++) + { + if(nIndex == nMaterial) bBool = TRUE; + else bBool = FALSE; + sIndex = IntToString(nIndex); + NuiSetBind(oPC, nToken, "btn_material_" + sIndex + "_event", JsonBool(bUseable)); + NuiSetBind(oPC, nToken, "btn_material_" + sIndex, JsonBool(bBool)); + } +} +object GetSelectedItem(object oTarget, int nItemSelected) +{ + if(nItemSelected == 0) return GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); + else if(nItemSelected == 1) return GetItemInSlot(INVENTORY_SLOT_CLOAK, oTarget); + else if(nItemSelected == 2) return GetItemInSlot(INVENTORY_SLOT_HEAD, oTarget); + else if(nItemSelected == 3) return GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget); + else if(nItemSelected == 4) return GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget); + return OBJECT_INVALID; +} +int GetArmorModelSelected(object oPC) +{ + json jCraft = GetLocalJson(oPC, CRAFT_JSON); + int nModelSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION)); + if(nModelSelected == 0) return ITEM_APPR_ARMOR_MODEL_NECK; + if(nModelSelected == 1) return ITEM_APPR_ARMOR_MODEL_RSHOULDER; + if(nModelSelected == 2) return ITEM_APPR_ARMOR_MODEL_RBICEP; + if(nModelSelected == 3) return ITEM_APPR_ARMOR_MODEL_RFOREARM; + if(nModelSelected == 4) return ITEM_APPR_ARMOR_MODEL_RHAND; + if(nModelSelected == 5) return ITEM_APPR_ARMOR_MODEL_TORSO; + if(nModelSelected == 6) return ITEM_APPR_ARMOR_MODEL_BELT; + if(nModelSelected == 7) return ITEM_APPR_ARMOR_MODEL_PELVIS; + if(nModelSelected == 8) return ITEM_APPR_ARMOR_MODEL_RTHIGH; + if(nModelSelected == 9) return ITEM_APPR_ARMOR_MODEL_RSHIN; + if(nModelSelected == 10) return ITEM_APPR_ARMOR_MODEL_RFOOT; + return ITEM_APPR_ARMOR_MODEL_ROBE; +} +int GetHasPartColor(object oItem, int nPart, string sSide) +{ + json jItem = ObjectToJson(oItem); + string sPartName = "APart_"; + if(sSide == "Left") + { + // Note: Right Thigh and Left Thigh are backwards so this fixes that! + if (nPart == ITEM_APPR_ARMOR_MODEL_RTHIGH) nPart--; + else nPart++; + } + sPartName += IntToString(nPart) + "_Col_"; + int nPartColor = JsonGetInt(GffGetByte(jItem, sPartName + "0")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "1")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "2")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "3")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "4")); + nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "5")); + return nPartColor; +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_crafting")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Item Crafting")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("isk_x2cweap")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + return TRUE; +} + diff --git a/src/module/nss/pi_debug.nss b/src/module/nss/pi_debug.nss new file mode 100644 index 0000000..6555882 --- /dev/null +++ b/src/module/nss/pi_debug.nss @@ -0,0 +1,200 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: pi_debug + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Plugin for debugging. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "0i_player_target" +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +void main() +{ + object oPC = OBJECT_SELF; + if(StartingUp(oPC)) return; + // Set window to not save until it has been created. + //SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + //DelayCommand (0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + string sText = " [Single player]"; + if(AI_SERVER) sText = " [Server]"; + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 500 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, PHILOS_VERSION + sText, "lbl_version", 470.0f, 20.0f, NUI_HALIGN_CENTER); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 129 + sText = "Module: " + GetModuleName() + " [" + GetTag(GetModule()) + "]"; + jRow = CreateLabel(JsonArray(), sText, "lbl_module_name", 470.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 500 / 101 + sText = "Monster AI (nw_c2_default1): " + ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS); + jRow = CreateLabel(JsonArray(), sText, "monster_1_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 ******************************************************************* 500 / 157 + sText = "Monster AI (j_ai_onheartbeat): " + ResManGetAliasFor("j_ai_onheartbeat", RESTYPE_NCS); + jRow = CreateLabel(JsonArray(), sText, "monster_2_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 5 ******************************************************************* 500 / 213 + sText = "Associate AI (nw_ch_ac1): " + ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS); + jRow = CreateLabel(JsonArray(), sText, "henchman_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 6 ******************************************************************* 500 / 241 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Set NPC's scripts", "btn_npc_scripts", 150.0f, 20.0f, -1.0, "btn_npc_scripts_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Set Reputations", "btn_set_reputation", 150.0f, 20.0f, -1.0, "btn_set_reputation_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear Party Rep.", "btn_clear_reputation", 150.0f, 20.0f, -1.0, "btn_clear_reputation_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 7 ******************************************************************* 500 / 269 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Display Target Info", "btn_info", 150.0f, 20.0f, -1.0, "btn_info_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Dump Object to Json", "btn_obj_json", 150.0f, 20.0f, -1.0, "btn_obj_json_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "List Object Variables", "btn_obj_var", 150.0f, 20.0f, -1.0, "btn_obj_var_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 8 ******************************************************************* 500 / 297 jRow = JsonArray(); + jRow = CreateButton(JsonArray(), "Delete Variable", "btn_delete_var", 115.0f, 25.0f, -1.0, "btn_delete_var_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Set Variable", "btn_set_var", 115.0f, 25.0f, -1.0, "btn_set_var_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Get Variable", "btn_get_var", 115.0f, 25.0f, -1.0, "btn_get_var_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + json jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("int", 0)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("float", 1)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("string", 2)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("object", 3)); + jCombo = JsonArrayInsert(jCombo, NuiComboEntry("location", 4)); + jRow = CreateCombo(jRow, jCombo, "cmb_var_type", 115.0, 25.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 9 ******************************************************************* 500 / 329 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "Name:", "lbl_name", 40.0f, 20.0f); + jRow = CreateTextEditBox(jRow, "sPlaceHolder", "txt_var_name", 40, FALSE, 425.0f, 20.0f, "txt_var_name_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 10 ******************************************************************* 500 / 357 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateLabel(jRow, "Value:", "lbl_value", 40.0f, 20.0f); + jRow = CreateTextEditBox(jRow, "sPlaceHolder", "txt_var_value", 40, FALSE, 425.0f, 20.0f, "txt_var_value_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 11 ******************************************************************* 500 / 385 + // Make the debug creature group. + // Group Row 1 ******************************************************************* 500 / 385 + json jGroupRow = CreateButton(JsonArray(), "Debug Creature", "btn_debug_creature", 120.0f, 20.0f, -1.0, "btn_debug_creature_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButton(jGroupRow, "Clear Event Scripts", "btn_clear_events", 150.0f, 20.0f, -1.0, "btn_clear_events_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupRow = CreateButton(jGroupRow, "Clear Debug", "btn_clear_debug", 120.0f, 20.0f, -1.0, "btn_clear_debug_tooltip"); + // Add group row to the group column. + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + float fHeight = 431.0; + // Group Row 2 ******************************************************************* 500 / --- + object oDebugCreature = GetLocalObject(oPC, "AI_RULE_DEBUG_CREATURE_OBJECT"); + if(GetIsObjectValid(oDebugCreature)) + { + string sScript = GetEventScript(oDebugCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT); + if(sScript == "nw_c2_default1") sText = GetName(oDebugCreature) + " is using monster AI scripts (" + sScript + ")."; + else if(sScript == "nw_ch_ac1") sText = GetName(oDebugCreature) + " is using associate AI scripts (" + sScript + ")."; + else if(sScript == "xx_pc_1_hb") sText = GetName(oDebugCreature) + " is using player AI scripts (" + sScript + ")."; + else if(sScript == "0e_id_events") sText = GetName(oDebugCreature) + " is using Infinite Dungeons AI scripts (" + sScript + ")."; + else if(sScript == "0e_prc_id_events") sText = GetName(oDebugCreature) + " is using PRC Infinite Dungeons AI scripts (" + sScript + ")."; + else sText = GetName(oDebugCreature) + " is using unknown AI scripts (" + sScript + ")."; + jGroupRow = CreateLabel(JsonArray(), sText, "debug_info", 455.0f, 20.0f, NUI_HALIGN_CENTER); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight = fHeight + 28; + } + // Group Row 3 ******************************************************************* 500 / --- + sText = GetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE); + if(sText != "") sText = sText + " is sending AI debug to the log file."; + else sText = "Nothing is sending AI debug to the log file."; + jGroupRow = CreateLabel(JsonArray(), sText, "debug_log", 455.0f, 20.0f, NUI_HALIGN_CENTER); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + fHeight = fHeight + 28; + // Add group to the row. + jRow = JsonArrayInsert(JsonArray(), NuiGroup(NuiCol(jGroupCol))); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, "pi_debug_nui", sName + " PEPS Debug Menu", + -1.0, -1.0, 500.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_debug"); + // Set all binds, events, and watches. + // Row 1 - Version label. + // Row 2 Module Name. + // Row 3 - 5 Script locations. + // Row 6 + NuiSetBind(oPC, nToken, "btn_npc_scripts_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_npc_scripts_tooltip", JsonString(" Forces NPC to use Philos AI scripts!")); + NuiSetBind(oPC, nToken, "btn_set_reputation_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_set_reputation_tooltip", JsonString(" Sets a creatures faction to neutral for all standard factions.")); + NuiSetBind(oPC, nToken, "btn_clear_reputation_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_reputation_tooltip", JsonString(" Clears the party's reputation with creature's faction.")); + // Row 7 + NuiSetBind(oPC, nToken, "btn_info_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_info_tooltip", JsonString(" Displays a target object's information to the log screen.")); + NuiSetBind(oPC, nToken, "btn_obj_json_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_obj_json_tooltip", JsonString(" Sends a Json Dump to the log file for the targeted object.")); + NuiSetBind(oPC, nToken, "btn_obj_var_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_obj_var_tooltip", JsonString(" Sends a list of variables for the targeted object.")); + // Row 8 + NuiSetBind(oPC, nToken, "btn_delete_var_tooltip", JsonString(" Delete the variable for the targeted object or Right click for the Module.")); + NuiSetBind(oPC, nToken, "btn_set_var_tooltip", JsonString(" Set the variable for the targeted object or Right click for the Module.")); + NuiSetBind(oPC, nToken, "btn_get_var_tooltip", JsonString(" Get the variable for the targeted object or Right click for the Module.")); + NuiSetBind(oPC, nToken, "cmb_var_type_event", JsonBool(TRUE)); + NuiSetBindWatch(oPC, nToken, "cmb_var_type_selected", TRUE); + // Row 9 + NuiSetBind(oPC, nToken, "txt_var_name_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "txt_var_name", TRUE); + NuiSetBind(oPC, nToken, "txt_var_name_tooltip", JsonString(" Name of the variable we are setting.")); + // Row 10 + NuiSetBind(oPC, nToken, "txt_var_value_event", JsonBool(TRUE)); + NuiSetBindWatch (oPC, nToken, "txt_var_value", TRUE); + NuiSetBind(oPC, nToken, "txt_var_value_tooltip", JsonString(" The value to set on the variable, Objects/Locations will need to be selected.")); + // Row 11 + NuiSetBind(oPC, nToken, "btn_debug_creature_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_debug_creature_tooltip", JsonString(" Sets target creature to send AI debug to the log file.")); + NuiSetBind(oPC, nToken, "btn_clear_events_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_events_tooltip", JsonString(" Sets a creature's event scripts to default.")); + NuiSetBind(oPC, nToken, "btn_clear_debug_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_debug_tooltip", JsonString(" Clears a creature from sending AI debug to the log file.")); +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_debug")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Debug Menu")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("dm_tagsearch")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + return TRUE; +} + diff --git a/src/module/nss/pi_forcerest.nss b/src/module/nss/pi_forcerest.nss new file mode 100644 index 0000000..dfabb34 --- /dev/null +++ b/src/module/nss/pi_forcerest.nss @@ -0,0 +1,70 @@ +#include "0i_menus" +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +void ai_UpdateAssociateWidget(object oMaster, object oAssociate, int nUIToken) +{ + if(nUIToken) NuiDestroy(oMaster, nUIToken); + ai_CreateWidgetNUI(oMaster, oAssociate); + if(oMaster != oAssociate) + { + nUIToken = NuiFindWindow(oMaster, "pc" + AI_WIDGET_NUI); + if(nUIToken) + { + NuiDestroy(oMaster, nUIToken); + ai_CreateWidgetNUI(oMaster, oMaster); + } + } +} +void main() +{ + object oPC = OBJECT_SELF; + if(StartingUp(oPC)) return; + ForceRest(oPC); + DeleteLocalInt(oPC, "HF_REST_LAST_TIME"); + int nIndex; + int nMaxHenchman = GetMaxHenchmen(); + object oAssociate; + for(nIndex = 1;nIndex <= nMaxHenchman; nIndex++) + { + oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + ForceRest(oAssociate); + DeleteLocalInt(oAssociate, "HF_REST_LAST_TIME"); + if(ai_GetMagicMode(oAssociate, AI_MAGIC_BUFF_AFTER_REST)) + { + DelayCommand(1.0, ai_HenchmanCastDefensiveSpells(oAssociate, oPC)); + } + if(AI_HENCHMAN_WIDGET) + { + // Update widget for spell widget. + string sAssociateType = ai_GetAssociateType(oPC, oAssociate); + int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI); + if(nUIToken) DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate, nUIToken)); + else + { + if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType)) + { + DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate, 0)); + } + } + } + } +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_forcerest")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Force Rest")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("ir_rest")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + return TRUE; +} + diff --git a/src/module/nss/pi_henchmen.nss b/src/module/nss/pi_henchmen.nss new file mode 100644 index 0000000..5119039 --- /dev/null +++ b/src/module/nss/pi_henchmen.nss @@ -0,0 +1,209 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pi_henchmen +//////////////////////////////////////////////////////////////////////////////// + Executable plug in script for Philos Module Extentions. + + UI to save a players as Henchmen. +*/////////////////////////////////////////////////////////////////////////////// +#include "pinc_henchmen" +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +// Inserts base classes to an array for a combo box. +json JArrayInsertBaseClasses(); +void main() +{ + object oPC = OBJECT_SELF; + if(StartingUp(oPC)) return; + // Set window to not save until it has been created. + SetLocalInt (oPC, "AI_NO_NUI_SAVE", TRUE); + DelayCommand (0.5f, DeleteLocalInt (oPC, "AI_NO_NUI_SAVE")); + // Row 1 (Buttons) ********************************************************* 775 / 73 + json jRow = CreateButtonSelect(JsonArray(), "Party 1", "btn_party1", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 2", "btn_party2", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 3", "btn_party3", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 4", "btn_party4", 90.0f, 20.0f); + jRow = CreateButtonSelect(jRow, "Party 5", "btn_party5", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 6", "btn_party6", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 7", "btn_party7", 90.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Party 8", "btn_party8", 90.0f, 20.0f); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 (Options)********************************************************** 775 / 101 + jRow = CreateButton(JsonArray(), "Clear Party", "btn_clear_party", 120.0f, 20.0f, -1.0, "btn_clear_party_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Party Join", "btn_join_party", 120.0f, 20.0f, -1.0, "btn_join_party_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButtonSelect(jRow, "Create NPC Henchman", "btn_npc_henchman", 200.0f, 20.0f, "btn_npc_henchman_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Save Party", "btn_save_party", 120.0f, 20.0f, -1.0, "btn_save_party_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Remove Party", "btn_remove_party", 120.0f, 20.0f, -1.0, "btn_remove_party_tooltip"); + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 (Names and List titles) ******************************************* 775 / 124 + jRow = CreateLabel(JsonArray(), "", "lbl_save_char", 150.0, 15.0, 0, 0); + jRow = CreateLabel(jRow, "", "lbl_save_list", 200.0, 15.0, 0, 0); + jRow = CreateLabel(jRow, "In game party", "lbl_game_list", 200.0, 15.0, 0, 0); + jRow = CreateLabel(jRow, "", "lbl_game_char", 150.0, 15.0, 0, 0); + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 4 (List Characters) ************************************************* 775 / 488 (364) + // Saved Characters for Party # + // ***** Adding character saved group next to the button list ************** + json jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateImage(jGroupRow, "", "img_saved_portrait", NUI_ASPECT_EXACTSCALED, NUI_HALIGN_CENTER, NUI_VALIGN_TOP, 128.0, 200.0, 0.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_saved_stats", 150.0, 15.0, 0, 0, 0.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_saved_classes", 150.0, 15.0, 0, 0, 0.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateButton(JsonArray(), "", "btn_saved_join", 75.0, 20.0); + jGroupRow = CreateButton(jGroupRow, "Remove", "btn_saved_remove", 75.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + //jGroupRow = JsonArray(); + //CreateButton(jGroupRow, "Edit", "btn_saved_edit", 150.0, 20.0); + //jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jRow = JsonArrayInsert(JsonArray(), NuiGroup(NuiCol(jGroupCol))); + // Create the button template for the List. + json jButton = NuiId(NuiButton(NuiBind ("btns_saved_char")), "btn_saved_char"); + json jList = JsonArrayInsert(JsonArray (), NuiListTemplateCell(jButton, 170.0, TRUE)); + // Create the list with the template. + jRow = CreateList(jRow, jList, "btns_saved_char", 25.0, 200.0, 325.0); + // Current Characters. + // Create the button template for the List. + jButton = NuiId(NuiButton(NuiBind ("btns_cur_char")), "btn_cur_char"); + jList = JsonArrayInsert(JsonArray (), NuiListTemplateCell(jButton, 170.0, TRUE)); + // Create the list with the template. + jRow = CreateList(jRow, jList, "btns_cur_char", 25.0, 200.0, 325.0); + // ***** Adding character current group next to the button list ************ + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateImage(jGroupRow, "", "img_cur_portrait", NUI_ASPECT_EXACTSCALED, NUI_HALIGN_CENTER, NUI_VALIGN_TOP, 128.0, 200.0, 0.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_cur_stats", 150.0, 15.0, 0, 0, 0.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateLabel(JsonArray(), "", "lbl_cur_classes", 150.0, 15.0, 0, 0, 0.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateButton(JsonArray(), "", "btn_cur_save", 75.0, 20.0); + jGroupRow = CreateButton(jGroupRow, "Remove", "btn_cur_remove", 75.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jGroupRow = CreateButton(JsonArray(), "Edit", "btn_cur_edit", 150.0, 20.0); + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jRow = JsonArrayInsert(jRow, NuiGroup(NuiCol(jGroupCol))); + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Set the layout of the window. + json jLayout = NuiCol(jCol); + // Get the window location to restore it from the database. + CheckHenchmanDataAndInitialize(oPC, "0"); + json jData = GetHenchmanDbJson(oPC, "henchman", "0"); + json jGeometry = JsonObjectGet(jData, "henchman_nui"); + float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x")); + float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y")); + if(fX == 0.0 && fY == 0.0) + { + fX = -1.0; + fY = -1.0; + } + string sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow (oPC, jLayout, "henchman_nui", sName + " party", + fX, fY, 775.0, 488.0, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_henchmen"); + // Lets set MaxHenchman here. + if(GetMaxHenchmen() < 6) SetMaxHenchmen(6); + // Setup watch for saving location. + NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE); + // Set the elements to show events. + NuiSetBind(oPC, nToken, "btn_save_pc_event", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_current_party_event", JsonBool (TRUE)); + string sParty = GetHenchmanDbString(oPC, "henchname", "0"); + if(sParty == "") + { + SetHenchmanDbString(oPC, "henchname", "1", "0"); + sParty = "1"; + } + // Set the party # buttons. + int nIndex; + string sIndex; + for(nIndex = 1; nIndex < 9; nIndex++) + { + sIndex = IntToString(nIndex); + if(sParty == sIndex) NuiSetBind(oPC, nToken, "btn_party" + sIndex, JsonBool(TRUE)); + else NuiSetBind(oPC, nToken, "btn_party" + sIndex, JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_party" + sIndex + "_event", JsonBool (TRUE)); + } + NuiSetBind(oPC, nToken, "btn_npc_henchman_event", JsonBool(TRUE)); + string sText = " Select a creature to copy and have them join you."; + NuiSetBind(oPC, nToken, "btn_npc_henchman_tooltip", JsonString(sText)); + // ********** Saved Henchman in party # ********* + nIndex = 0; + int nSlot, nMaxHenchman = AI_MAX_HENCHMAN + 1; + json jButtons = JsonArray(); + string sFirstHenchman, sButtonText; + json jNPCs, jNPC; + // Add saved party members from sParty to the button list. + while(nIndex < nMaxHenchman) + { + sIndex = IntToString(nIndex); + sButtonText = GetHenchmanDbString(oPC, "henchname", sParty + sIndex); + if(sButtonText != "") + { + jButtons = JsonArrayInsert(jButtons, JsonString(sButtonText)); + SetHenchmanDbString(oPC, "slot", sParty + IntToString(nSlot++), sParty + sIndex); + } + nIndex++; + } + // Add the buttons to the list. + NuiSetBind(oPC, nToken, "btns_saved_char", jButtons); + // Set up button lables for henchman. + NuiSetBind(oPC, nToken, "lbl_save_list_label", JsonString("Party Save " + sParty)); + AddSavedCharacterInfo(oPC, nToken, sParty); + // ********** Current Party ********* + NuiSetBind(oPC, nToken, "btn_current_party", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_party", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "lbl_save_char", JsonBool(TRUE)); + // Set up button labels for henchman. + NuiSetBind(oPC, nToken, "btn_join_save_label", JsonString("Save")); + nIndex = 0; + jButtons = JsonArray(); + object oPartyMember, oCharacter = OBJECT_INVALID; + // Add current party members to the button list. + while(nIndex < AI_MAX_HENCHMAN) + { + if(nIndex == 0) oPartyMember = oPC; + else oPartyMember = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oPartyMember != OBJECT_INVALID) jButtons = JsonArrayInsert(jButtons, JsonString(GetName(oPartyMember))); + else break; + nIndex++; + } + // Add the buttons to the list. + NuiSetBind(oPC, nToken, "btns_cur_char", jButtons); + AddCurrentCharacterInfo(oPC, nToken, sParty); +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_henchmen")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Henchmen Menu")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("dm_creator")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + return TRUE; +} + diff --git a/src/module/nss/pi_test.nss b/src/module/nss/pi_test.nss new file mode 100644 index 0000000..818da8c --- /dev/null +++ b/src/module/nss/pi_test.nss @@ -0,0 +1,103 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: pi_test + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Plugin for debugging. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "0i_player_target" +// Does startup check if the game has just been loaded. +int StartingUp(object oPC); +void main() +{ + object oPC = OBJECT_SELF; + if(StartingUp(oPC)) return; + string sText; + // Set window to not save until it has been created. + //SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); + //DelayCommand (0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); + // ************************************************************************* Width / Height + // Row 1 ******************************************************************* 636 / 73 + json jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Level Up Creature", "btn_level", 150.0f, 20.0f, -1.0, "btn_level_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Gold for Creature", "btn_gold", 150.0f, 20.0f, -1.0, "btn_gold_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Force Rest Creature", "btn_rest", 150.0f, 20.0f, -1.0, "btn_rest_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "ID/UnID Item", "btn_id_item", 150.0f, 20.0f, -1.0, "btn_id_item_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 636 / 101 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Heal Creature", "btn_heal", 150.0f, 20.0f, -1.0, "btn_heal_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Clear Creature Actions", "btn_clear", 150.0f, 20.0f, -1.0, "btn_clear_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Kill Creature", "btn_kill", 150.0f, 20.0f, -1.0, "btn_kill_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Remove Object", "btn_remove", 150.0f, 20.0f, -1.0, "btn_remove_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Row 3 ******************************************************************* 636 / 101 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "Jump To", "btn_jump", 150.0f, 20.0f, -1.0, "btn_jump_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + jRow = CreateButton(jRow, "Kill In Area", "btn_kill_area", 150.0f, 20.0f, -1.0, "btn_kill_area_tooltip"); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + float fHeight = 129.0; + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + string sName = GetName(oPC); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow(oPC, jLayout, "pi_test_nui", sName + " PEPS Testing Menu", + -1.0, -1.0, 636.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_test"); + // Set all binds, events, and watches. + // Row 1 + NuiSetBind(oPC, nToken, "btn_level_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_tooltip", JsonString(" Give level to target creature.")); + NuiSetBind(oPC, nToken, "btn_gold_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_gold_tooltip", JsonString(" Give Gold to target creature.")); + NuiSetBind(oPC, nToken, "btn_rest_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_rest_tooltip", JsonString(" Force rest target creature.")); + NuiSetBind(oPC, nToken, "btn_id_item_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_id_item_tooltip", JsonString(" Identify or UnIdentify the target item.")); + // Row 2 + NuiSetBind(oPC, nToken, "btn_heal_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_heal_tooltip", JsonString(" Heal target creature to max hitpoints.")); + NuiSetBind(oPC, nToken, "btn_clear_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_clear_tooltip", JsonString(" Clears a creature's actions including combat.")); + NuiSetBind(oPC, nToken, "btn_kill_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_kill_tooltip", JsonString(" Kill target creature doing 10,000 magic damage.")); + NuiSetBind(oPC, nToken, "btn_remove_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_remove_tooltip", JsonString(" Remove selected object or the nearest object to ground selection.")); + // Row 3 + NuiSetBind(oPC, nToken, "btn_jump_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_jump_tooltip", JsonString(" Jump to target location.")); + NuiSetBind(oPC, nToken, "btn_kill_area_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_kill_area_tooltip", JsonString(" Kills all creatures in target area.")); +} +int StartingUp(object oPC) +{ + if(GetLocalInt(oPC, AI_ADD_PLUGIN)) + { + json jPlugin = JsonArray(); + jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_test")); + jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE)); + jPlugin = JsonArrayInsert(jPlugin, JsonString("Testing Menu")); + jPlugin = JsonArrayInsert(jPlugin, JsonString("ir_charsheet")); + json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS); + jPlugins = JsonArrayInsert(jPlugins, jPlugin); + SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin); + SetLocalInt(oPC, AI_PLUGIN_SET, TRUE); + return TRUE; + } + if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE; + return TRUE; +} + diff --git a/src/module/nss/pinc_henchmen.nss b/src/module/nss/pinc_henchmen.nss new file mode 100644 index 0000000..a67141a --- /dev/null +++ b/src/module/nss/pinc_henchmen.nss @@ -0,0 +1,1531 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: pinc_henchmen +//////////////////////////////////////////////////////////////////////////////// + Include file for Henchmen plug in scripts for Philos Module Extentions. + +Database Info: +Slot 0 - henchname = the save slot 1 - 8. +Slots 1 - 8 define the selections: + henchname = Saved character selected. + image = Current character selected. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_nui" +#include "nw_inc_gff" + +const string HENCHMAN_DATABASE = "philos_henchman_db"; +const string HENCHMAN_TABLE = "HENCHMAN_TABLE"; +const string HENCHMAN_TO_EDIT = "HENCHMAN_TO_EDIT"; + +// Creates the table and initializes if it needs to. +void CheckHenchmanDataAndInitialize(object oPC, string sSlot); +// Removes a henchan from the current slot. +void RemoveHenchmanDb(object oPC, string sSlot); +// sDataField should be one of the data fields for that table. +// sData is the string data to be saved. +void SetHenchmanDbString(object oPC, string sDataField, string sData, string sSlot); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +string GetHenchmanDbString(object oPC, string sDataField, string sSlot); +// sDataField should be one of the data fields for that table. +// jData is the json data to be saved. +void SetHenchmanDbJson(object oPC, string sDataField, json jData, string sSlot); +// sDataField should be one of the data fields for the table. +// Returns a string of the data stored. +json GetHenchmanDbJson(object oPC, string sDataField, string sSlot); +// sSlot is the slot to define this object in the database for this Slot## (# Party button and #1-6). +// oHenchman is the PC/Henchman to be saved. +void SetHenchmanDbObject(object oPC, object oHenchman, string sSlot); +// sSlot is the slot to define this object in the database for this Slot## (# Party button and #1-6). +// lLocationToSpawn will spawn the object at that location. +object GetHenchmanDbObject(object oPC, location lLocationToSpawn, string sSlot); +// Returns TRUE if the henchman with sName can join. +int GetJoinButtonActive(object oPC, string sName); +// Returns a two letter alignment string. +string GetAlignText(object oHenchman); +// Populates the Saved character group. +void AddSavedCharacterInfo(object oPC, int nToken, string sParty); +// Populates the Current character group. +void AddCurrentCharacterInfo(object oPC, int nToken, string sParty); +// Removes a henchman from your party. +void RemoveYourHenchman(object oPC, int nToken, string sParty); +// Removes all henchman from the party. +void RemoveWholeParty(object oPC, int nToken, string sParty); +// Saves a henchman in your party to the saved party #. +void SaveYourHenchman(object oPC, int nToken, string sParty); +// Saves the whole party to the saved party #. +void SaveWholeParty(object oPC, int nToken, string sParty); +// Saves the players current party to party #. +void SavedPartyJoin(object oPC, int nToken, string sParty); +// Saves a character in the players party to party #. +void SavedCharacterJoin(object oPC, int nToken, string sParty); +// Clears the players saved party #. +void SavedPartyCleared(object oPC, int nToken, string sParty); +// Sets oHenchmans scripts to the current AI. +void SetHenchmanScripts(object oHenchman); +// If a henchman does not have a LvlStatList this will create one for them. +// nLevels allows the creation of x levels for LvlStatList using the 1st class. +// 0 on nLevels makes the function build it based on current levels. +json CreateLevelStatList(json jHenchman, object oHenchman, object oPC, int nLevels = 0); +// Resets the character to level one in the first class. +object ResetCharacter(object oPC, object oHenchman); +// Creates a menu to edit a characters information. +void CreateCharacterEditGUIPanel(object oPC, object oAssociate); +// Creates a character description menu. +void CreateCharacterDescriptionNUI(object oPC, string sName, string sIcon, string sDescription); + +void CreateHenchmanDataTable () +{ + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, + "CREATE TABLE IF NOT EXISTS " + HENCHMAN_TABLE + " (" + + "name TEXT, " + + "slot TEXT, " + + "henchname TEXT, " + + "image TEXT, " + + "stats TEXT, " + + "classes TEXT, " + + "henchman TEXT, " + + "PRIMARY KEY(slot));"); + SqlStep (sql); +} +void CheckHenchmanDataAndInitialize(object oPC, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "SELECT name FROM sqlite_master WHERE type ='table' AND name=@tableName;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@tableName", HENCHMAN_TABLE); + if(!SqlStep (sql)) CreateHenchmanDataTable(); + sQuery = "SELECT slot FROM " + HENCHMAN_TABLE + " Where name = @name AND slot = @slot;"; + sql = SqlPrepareQueryCampaign("philos_henchman_db", sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + if(!SqlStep(sql)) + { + sQuery = "INSERT INTO " + HENCHMAN_TABLE + "(name, slot, henchname, image, stats, classes " + + ", henchman) VALUES (@name, @slot, @henchname, @image, @stats, @classes, @henchman);"; + sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + SqlBindString(sql, "@henchname", ""); + SqlBindString(sql, "@image", ""); + SqlBindString(sql, "@stats", ""); + SqlBindString(sql, "@classes", ""); + SqlBindJson(sql, "@henchman", JsonObject()); + SqlStep(sql); + } +} +void RemoveHenchmanDb(object oPC, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "DELETE FROM " + HENCHMAN_TABLE + " WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + SqlStep(sql); +} +void SetHenchmanDbString(object oPC, string sDataField, string sData, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "UPDATE " + HENCHMAN_TABLE + " SET " + sDataField + " = @data WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@data", sData); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + SqlStep(sql); +} +string GetHenchmanDbString(object oPC, string sDataField, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "SELECT " + sDataField + " FROM " + HENCHMAN_TABLE + " WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + if(SqlStep (sql)) return SqlGetString(sql, 0); + else return ""; +} +void SetHenchmanDbJson(object oPC, string sDataField, json jData, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "UPDATE " + HENCHMAN_TABLE + " SET " + sDataField + + " = @data WHERE name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindJson (sql, "@data", jData); + SqlBindString(sql, "@name", sPCName); + SqlBindString (sql, "@slot", sSlot); + SqlStep (sql); +} +json GetHenchmanDbJson(object oPC, string sDataField, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "SELECT " + sDataField + " FROM " + HENCHMAN_TABLE + " WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString (sql, "@slot", sSlot); + if (SqlStep (sql)) return SqlGetJson (sql, 0); + else return JsonArray (); +} +void SetHenchmanDbObject(object oPC, object oHenchman, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "UPDATE " + HENCHMAN_TABLE + " SET henchman = @henchman WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindObject(sql, "@henchman", oHenchman); + SqlBindString(sql, "@name", sPCName); + SqlBindString(sql, "@slot", sSlot); + SqlStep(sql); +} +object GetHenchmanDbObject(object oPC, location lLocationToSpawn, string sSlot) +{ + string sPCName = ai_RemoveIllegalCharacters(GetPCPlayerName(oPC)); + string sQuery = "SELECT henchman FROM " + HENCHMAN_TABLE + " WHERE " + + "name = @name AND slot = @slot;"; + sqlquery sql = SqlPrepareQueryCampaign(HENCHMAN_DATABASE, sQuery); + SqlBindString(sql, "@name", sPCName); + SqlBindString (sql, "@slot", sSlot); + if (SqlStep (sql)) + { + json jHenchman = SqlGetJson(sql, 0); + string sTag = JsonGetString(GffGetString(jHenchman, "Tag")); + if(sTag == "") jHenchman = GffReplaceString(jHenchman, "Tag", "Hench_" + IntToString(Random(100))); + return JsonToObject(jHenchman, lLocationToSpawn, OBJECT_INVALID, TRUE); + } + return OBJECT_INVALID; +} +int GetJoinButtonActive(object oPC, string sName) +{ + if(sName == GetName(oPC)) return FALSE; + // Look for a free henchman slot, and if this henchman is already joined! + int nIndex = 1; + object oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(oHenchman != OBJECT_INVALID) + { + if(GetName(oHenchman) == sName) return FALSE; + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + return TRUE; +} +string GetAlignText(object oHenchman) +{ + string sAlign1, sAlign2; + switch (GetAlignmentLawChaos(oHenchman)) + { + case ALIGNMENT_LAWFUL : sAlign1 = "L"; break; + case ALIGNMENT_NEUTRAL : sAlign1 = "N"; break; + case ALIGNMENT_CHAOTIC : sAlign1 = "C"; break; + } + switch (GetAlignmentGoodEvil(oHenchman)) + { + case ALIGNMENT_GOOD : sAlign2 = "G"; break; + case ALIGNMENT_NEUTRAL : sAlign2 = "N"; break; + case ALIGNMENT_EVIL : sAlign2 = "E"; break; + } + string sAlign = sAlign1 + sAlign2; + if (sAlign == "NN") sAlign = "TN"; + return sAlign; +} +void AddSavedCharacterInfo(object oPC, int nToken, string sParty) +{ + string sHenchman = GetHenchmanDbString(oPC, "henchname", sParty); + // Add Henchman information. + if(sHenchman != "") + { + NuiSetBind (oPC, nToken, "btn_clear_party_event", JsonBool (TRUE)); + string sText = " Clears all characters from party " + sParty + "'s list!"; + NuiSetBind(oPC, nToken, "btn_clear_party_tooltip", JsonString(sText)); + NuiSetBind(oPC, nToken, "btn_join_party", JsonBool (TRUE)); + NuiSetBind(oPC, nToken, "btn_join_party_event", JsonBool (TRUE)); + sText = " Saved characters from party " + sParty + " enter the game and join you."; + NuiSetBind(oPC, nToken, "btn_join_party_tooltip", JsonString(sText)); + // Setup the henchman window. + string sName = GetHenchmanDbString(oPC, "henchname", sParty + sHenchman); + string sImage = GetHenchmanDbString(oPC, "image", sParty + sHenchman); + string sStats = GetHenchmanDbString(oPC, "stats", sParty + sHenchman); + string sClasses = GetHenchmanDbString(oPC, "classes", sParty + sHenchman); + NuiSetBind(oPC, nToken, "lbl_save_char_label", JsonString(sName)); + NuiSetBind(oPC, nToken, "img_saved_portrait_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "img_saved_portrait_image", JsonString(sImage + "l")); + NuiSetBind(oPC, nToken, "lbl_saved_stats_label", JsonString(sStats)); + NuiSetBind(oPC, nToken, "lbl_saved_classes_label", JsonString(sClasses)); + NuiSetBind(oPC, nToken, "btn_saved_join_label", JsonString("Join")); + NuiSetBind(oPC, nToken, "btn_saved_join_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_saved_remove_event", JsonBool(TRUE)); + //NuiSetBind(oPC, nToken, "btn_saved_edit_event", JsonBool(TRUE)); + } + else + { + NuiSetBind(oPC, nToken, "lbl_save_char_label", JsonString("Empty Party")); + NuiSetBind (oPC, nToken, "btn_clear_party_event", JsonBool (FALSE)); + NuiSetBind (oPC, nToken, "btn_join_party", JsonBool (FALSE)); + NuiSetBind (oPC, nToken, "btn_join_party_event", JsonBool (FALSE)); + // Setup the henchman window. + NuiSetBind(oPC, nToken, "img_saved_portrait_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "img_saved_portrait_image", JsonString("po_hu_m_99_l")); + NuiSetBind(oPC, nToken, "lbl_saved_stats_label", JsonString("")); + NuiSetBind(oPC, nToken, "lbl_saved_classes_label", JsonString("")); + NuiSetBind(oPC, nToken, "btn_saved_join_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_saved_join_label", JsonString("Join")); + NuiSetBind(oPC, nToken, "btn_saved_remove_event", JsonBool(FALSE)); + NuiSetBind(oPC, nToken, "btn_saved_edit_event", JsonBool(FALSE)); + } +} +void AddCurrentCharacterInfo(object oPC, int nToken, string sParty) +{ + string sHenchman = GetHenchmanDbString(oPC, "image", sParty); + if(sHenchman == "") + { + CheckHenchmanDataAndInitialize(oPC, sParty); + SetHenchmanDbString(oPC, "image", "0", sParty); + } + int nHenchman = StringToInt(sHenchman); + int nIndex = 0; + object oCharacter; + while(nIndex < AI_MAX_HENCHMAN) + { + if(nIndex == 0) oCharacter = oPC; + else oCharacter = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oCharacter == OBJECT_INVALID) + { + nIndex = 0; + oCharacter = oPC; + break; + } + else if(nHenchman == nIndex) break; + nIndex++; + } + // Adjust the party buttons. + int bParty = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, 1) != OBJECT_INVALID; + //NuiSetBind(oPC, nToken, "btn_save_party", JsonBool (bParty)); + NuiSetBind(oPC, nToken, "btn_save_party_event", JsonBool (bParty)); + //NuiSetBind(oPC, nToken, "btn_remove_party", JsonBool (bParty)); + NuiSetBind(oPC, nToken, "btn_remove_party_event", JsonBool (bParty)); + if(bParty) + { + string sText = " Saves all henchman from your current party to party " + sParty + "."; + NuiSetBind(oPC, nToken, "btn_save_party_tooltip", JsonString(sText)); + sText = " Removes all henchman from your current party!"; + NuiSetBind(oPC, nToken, "btn_remove_party_tooltip", JsonString(sText)); + } + // Setup the henchman window. + string sName = GetName(oCharacter); + string sImage = GetPortraitResRef(oCharacter); + string sStats = GetAlignText(oCharacter) + " "; + if(GetGender(oCharacter) == GENDER_MALE) sStats += "Male "; + else sStats += "Female "; + int nPosition = 1; + sStats += GetStringByStrRef (StringToInt (Get2DAString ("racialtypes", "Name", GetRacialType (oCharacter)))); + string sClasses = GetStringByStrRef (StringToInt (Get2DAString ("classes", "Short", GetClassByPosition (nPosition, oCharacter)))); + sClasses += " " + IntToString (GetLevelByPosition (nPosition, oCharacter)); + int nClass = GetClassByPosition(++nPosition, oCharacter); + while(nClass != CLASS_TYPE_INVALID) + { + sClasses += ", " + GetStringByStrRef (StringToInt (Get2DAString ("classes", "Short", nClass))); + sClasses += " " + IntToString (GetLevelByPosition (nPosition, oCharacter)); + nClass = GetClassByPosition(++nPosition, oCharacter); + } + NuiSetBind(oPC, nToken, "lbl_game_char_label", JsonString(sName)); + NuiSetBind(oPC, nToken, "img_cur_portrait_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "img_cur_portrait_image", JsonString(sImage + "l")); + NuiSetBind(oPC, nToken, "lbl_cur_stats_label", JsonString(sStats)); + NuiSetBind(oPC, nToken, "lbl_cur_classes_label", JsonString(sClasses)); + NuiSetBind(oPC, nToken, "btn_cur_save_label", JsonString("Save")); + NuiSetBind(oPC, nToken, "btn_cur_save_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cur_edit_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_cur_remove_event", JsonBool(TRUE)); +} +object GetSelectedHenchman(object oPC, string sParty) +{ + string sHenchman = GetHenchmanDbString(oPC, "image", sParty); + if(sHenchman == "") + { + CheckHenchmanDataAndInitialize(oPC, sParty); + SetHenchmanDbString(oPC, "image", "0", sParty); + } + int nHenchman = StringToInt(sHenchman); + int nIndex = 0; + object oCharacter; + while(nIndex < AI_MAX_HENCHMAN) + { + if(nIndex == 0) oCharacter = oPC; + else oCharacter = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oCharacter == OBJECT_INVALID) + { + nIndex = 0; + oCharacter = oPC; + break; + } + else if(nHenchman == nIndex) break; + nIndex++; + } + return oCharacter; +} +void RemoveYourHenchman(object oPC, int nToken, string sParty) +{ + object oHenchman = GetSelectedHenchman(oPC, sParty); + if(oHenchman == oPC) ai_SendMessages("You cannot remove the player from the party!", AI_COLOR_RED, oPC); + else + { + RemoveHenchman(oPC, oHenchman); + AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE)); + NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oHenchman) + AI_WIDGET_NUI)); + DestroyObject(oHenchman); + } + ai_SendMessages(GetName(oHenchman) + " has been removed from the party!", AI_COLOR_GREEN, oPC); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +void RemoveWholeParty(object oPC, int nToken, string sParty) +{ + int nIndex = AI_MAX_HENCHMAN; + object oHenchman; + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(nIndex > 0) + { + if(oHenchman != OBJECT_INVALID) + { + ai_SendMessages(GetName(oHenchman) + " has been remove from your Party.", AI_COLOR_YELLOW, oPC); + RemoveHenchman(oPC, oHenchman); + AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE)); + NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oHenchman) + AI_WIDGET_NUI)); + DestroyObject(oHenchman); + } + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, --nIndex); + } + ai_SendMessages("All of your henchman have been remove from the Party.", AI_COLOR_YELLOW, oPC); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +void SaveYourHenchman(object oPC, int nToken, string sParty) +{ + int bPC, nIndex, nClass, nPosition, nMaxHenchman = AI_MAX_HENCHMAN + 1; + string sName, sIndex, sSlot, sStats, sClasses; + object oHenchman = GetSelectedHenchman(oPC, sParty); + if(oHenchman == oPC) + { + bPC = TRUE; + oHenchman = CopyObject(oPC, GetLocation(oPC), OBJECT_INVALID, "hench_" + IntToString(Random(100)), TRUE); + SetHenchmanScripts(oHenchman); + } + string sHenchmanName = GetName(oHenchman); + while(nIndex < nMaxHenchman) + { + sIndex = IntToString(nIndex); + sName = GetHenchmanDbString(oPC, "henchname", sParty + sIndex); + if(sName == sHenchmanName || sName == "") + { + sSlot = sParty + sIndex; + if(!bPC) RemoveHenchman(oPC, oHenchman); + // Special check for Infinite Dungeon plot givers to be changed into henchman. + if(GetStringLeft(GetLocalString(oHenchman, "sConversation"), 8) == "id1_plot") + { + DeleteLocalString(oHenchman, "sConversation"); + } + ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER); + json jHenchman = ObjectToJson(oHenchman, TRUE); + if(!bPC) AddHenchman(oPC, oHenchman); + else DestroyObject(oHenchman); + //string sPatch = "[{\"op\":\"replace\",\"path\":\"/FactionID/value\",\"value\":1}]"; + //json jPatch = JsonParse(sPatch); + //jHenchman = JsonPatch(jHenchman, jPatch); + CheckHenchmanDataAndInitialize(oPC, sSlot); + SetHenchmanDbString(oPC, "image", GetPortraitResRef(oHenchman), sSlot); + SetHenchmanDbString(oPC, "henchname", sHenchmanName, sSlot); + sStats = GetAlignText(oHenchman) + " "; + if(GetGender(oHenchman) == GENDER_MALE) sStats += "Male "; + else sStats += "Female "; + nPosition = 1; + sStats += GetStringByStrRef (StringToInt (Get2DAString ("racialtypes", "Name", GetRacialType (oHenchman)))); + sClasses = GetStringByStrRef (StringToInt (Get2DAString ("classes", "Short", GetClassByPosition (nPosition, oHenchman)))); + sClasses += " " + IntToString (GetLevelByPosition (nPosition, oHenchman)); + nClass = GetClassByPosition(++nPosition, oHenchman); + while(nClass != CLASS_TYPE_INVALID) + { + sClasses += ", " + GetStringByStrRef (StringToInt (Get2DAString ("classes", "Short", GetClassByPosition (nPosition, oHenchman)))); + sClasses += " " + IntToString (GetLevelByPosition (nPosition, oHenchman)); + nClass = GetClassByPosition(++nPosition, oHenchman); + } + SetHenchmanDbString(oPC, "stats", sStats, sSlot); + SetHenchmanDbString(oPC, "classes", sClasses, sSlot); + SetHenchmanDbJson(oPC, "henchman", jHenchman, sSlot); + if(sName == "") ai_SendMessages(sHenchmanName + " has been saved to the party.", AI_COLOR_GREEN, oPC); + else ai_SendMessages(sHenchmanName + " has replaced a copy of themselves in the party.", AI_COLOR_GREEN, oPC); + break; + } + nIndex++; + } +if(nIndex == nMaxHenchman) ai_SendMessages("This party is full!", AI_COLOR_RED, oPC); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +void SaveWholeParty(object oPC, int nToken, string sParty) +{ + int nIndex = AI_MAX_HENCHMAN; + object oHenchman; + while(nIndex > 0) + { + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + if(oHenchman != OBJECT_INVALID) + { + SetHenchmanDbString(oPC, "image", IntToString(nIndex), sParty); + SaveYourHenchman(oPC, nToken, sParty); + } + nIndex--; + } + ai_SendMessages("All of your henchman have been saved to Party " + sParty + ".", AI_COLOR_YELLOW, oPC); + SetHenchmanDbString(oPC, "henchname", "0", sParty); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +void SavedPartyJoin(object oPC, int nToken, string sParty) +{ + int bFound, nIndex, nDBHenchman = 0; + json jHenchman; + object oHenchman, oLoadedHenchman; + string sDBHenchman = IntToString(nDBHenchman); + string sName = GetHenchmanDbString(oPC, "henchname", sParty + sDBHenchman); + while(sName != "") + { + bFound = FALSE; + nIndex = 1; + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(oHenchman != OBJECT_INVALID) + { + if(sName == GetName(oPC) || GetName(oHenchman) == sName) + { + bFound = TRUE; + break; + } + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + if(!bFound) + { + ai_SendMessages(sName + " has joined your party.", AI_COLOR_GREEN, oPC); + jHenchman = GetHenchmanDbJson(oPC, "henchman", sParty + sDBHenchman); + oLoadedHenchman = JsonToObject(jHenchman, GetLocation(oPC), OBJECT_INVALID, TRUE); + AddHenchman(oPC, oLoadedHenchman); + } + else ai_SendMessages(sName + " is already in your party!", AI_COLOR_RED, oPC); + sDBHenchman = IntToString(++nDBHenchman); + sName = GetHenchmanDbString(oPC, "henchname", sParty + sDBHenchman); + } + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +void SavedCharacterJoin(object oPC, int nToken, string sParty) +{ + int nIndex, bFound; + object oHenchman, oLoadedHenchman; + string sHenchman = GetHenchmanDbString(oPC, "henchname", sParty); + string sName = GetHenchmanDbString(oPC, "henchname", sParty + sHenchman); + nIndex = 1; + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); + while(oHenchman != OBJECT_INVALID) + { + if(sName == GetName(oPC) || GetName(oHenchman) == sName) + { + bFound = TRUE; + break; + } + oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, ++nIndex); + } + if(!bFound) + { + ai_SendMessages(sName + " has joined your party!", AI_COLOR_GREEN, oPC); + oLoadedHenchman = GetHenchmanDbObject(oPC, GetLocation(oPC), sParty + sHenchman); + AddHenchman(oPC, oLoadedHenchman); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); + } + else ai_SendMessages(sName + " is already in your party!", AI_COLOR_RED, oPC); +} +void SavedPartyCleared(object oPC, int nToken, string sParty) +{ + int nIndex, nMaxHenchman = AI_MAX_HENCHMAN + 1; + object oHenchman, oLoadedHenchman; + string sIndex = IntToString(nIndex); + string sName = GetHenchmanDbString(oPC, "henchname", sParty + sIndex); + while(nIndex < nMaxHenchman) + { + if(sName != "") + { + RemoveHenchmanDb(oPC, sParty + sIndex); + ai_SendMessages(sName + " has been cleared from the saved party " + sParty + ".", AI_COLOR_YELLOW, oPC); + } + sIndex = IntToString(++nIndex); + sName = GetHenchmanDbString(oPC, "henchname", sParty + sIndex); + } + SetHenchmanDbString(oPC, "henchname", "", sParty); + NuiDestroy(oPC, nToken); + ExecuteScript("pi_henchmen", oPC); +} +json CreateOptionsAlignment(object oHenchman, int nAlignType) +{ + json jAlignNameList = JsonArray(); + if(nAlignType == 0) + { + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Lawful")); + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Neutral")); + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Chaotic")); + } + else + { + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Good")); + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Neutral")); + jAlignNameList = JsonArrayInsert(jAlignNameList, JsonString("Evil")); + } + return jAlignNameList; +} +json CreateOptionsClasses(object oHenchman) +{ + int nIndex = 1, nClass; + string sClassName; + json jClassNameList = JsonArray(); + while(nIndex < 5) + { + nClass = GetClassByPosition(nIndex, oHenchman); + if(nClass == CLASS_TYPE_INVALID) sClassName = "Empty"; + else + { + sClassName = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + sClassName += " " + IntToString(GetLevelByClass(nClass, oHenchman)); + } + jClassNameList = JsonArrayInsert(jClassNameList, JsonString(sClassName)); + nIndex++; + } + return jClassNameList; +} +json jArrayInsertClasses() +{ + int nIndex, nClass, nMaxClass = Get2DARowCount("classes"); + string sClassName; + json jClassNameCombo = JsonArray(); + while(nIndex < nMaxClass) + { + if(Get2DAString("classes", "PlayerClass", nIndex) == "1") + { + sClassName = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nIndex))); + jClassNameCombo = JsonArrayInsert(jClassNameCombo, NuiComboEntry(sClassName, nClass)); + nClass++; + } + nIndex++; + } + return jClassNameCombo; +} +int GetSelectionByClass2DA(int nClass) +{ + int nIndex, nSelection, nMaxClass = Get2DARowCount("classes"); + while(nIndex < nMaxClass) + { + if(Get2DAString("classes", "PlayerClass", nIndex) == "1") + { + if(nClass == nIndex) return nSelection; + nSelection++; + } + nIndex++; + } + return -1; +} +int GetClassBySelection2DA(int nSelection) +{ + int nIndex, nClass, nMaxClass = Get2DARowCount("classes"); + while(nClass < nMaxClass) + { + if(Get2DAString("classes", "PlayerClass", nClass) == "1") + { + if(nSelection == nIndex) return nClass; + nIndex++; + } + nClass++; + } + return -1; +} +json ArrayInsertPackages(string sClass) +{ + int nIndex, nPackage, nMaxPackage = Get2DARowCount("packages"); + string sPackageName; + json jPackageNameCombo = JsonArray(); + while(nIndex < nMaxPackage) + { + if(Get2DAString("packages", "ClassID", nIndex) == sClass) + { + sPackageName = Get2DAString("packages", "Label", nIndex); + //GetStringByStrRef(StringToInt(Get2DAString("packages", "Name", nIndex))); + if(sPackageName != "Bad Strref" && sPackageName != "") + { + jPackageNameCombo = JsonArrayInsert(jPackageNameCombo, NuiComboEntry(sPackageName, nPackage)); + nPackage++; + } + } + nIndex++; + } + return jPackageNameCombo; +} +int GetSelectionByPackage2DA(string sClass, int nPackage) +{ + int nIndex, nSelection, nMaxPackage = Get2DARowCount("packages"); + string sPackageName; + while(nIndex < nMaxPackage) + { + if(Get2DAString("packages", "ClassID", nIndex) == sClass) + { + sPackageName = GetStringByStrRef(StringToInt(Get2DAString("packages", "Name", nIndex))); + if(sPackageName != "Bad Strref" && sPackageName != "") + { + if(nPackage == nIndex) return nSelection; + nSelection++; + } + } + nIndex++; + } + return -1; +} +int GetPackageBySelection2DA(string sClass, int nSelection) +{ + int nIndex, nPackage, nMaxPackage = Get2DARowCount("packages"); + while(nPackage < nMaxPackage) + { + if(Get2DAString("packages", "ClassID", nPackage) == sClass) + { + if(nSelection == nIndex) return nPackage; + nIndex++; + } + nPackage++; + } + return -1; +} +json ArrayInsertSoundSets(object oHenchman) +{ + int nIndex, nSoundSet, nSoundSetType, nMaxSets = Get2DARowCount("soundset"); + string sGender = IntToString(GetGender(oHenchman)); + string sSoundSetName, sResRef; + json jSoundSetNameCombo = JsonArray(); + while(nIndex < nMaxSets) + { + if(Get2DAString("soundset", "GENDER", nIndex) == sGender) + { + nSoundSetType = StringToInt(Get2DAString("soundset", "TYPE", nIndex)); + if(nSoundSetType < 5) + { + sSoundSetName = GetStringByStrRef(StringToInt(Get2DAString("soundset", "STRREF", nIndex))); + sResRef = GetStringLowerCase(Get2DAString("soundset", "RESREF", nIndex)); + if(GetStringLeft(sResRef, 4) == "vs_f") sSoundSetName += " (Full)"; + else if(GetStringLeft(sResRef, 4) == "vs_n") sSoundSetName += " (Part)"; + jSoundSetNameCombo = JsonArrayInsert(jSoundSetNameCombo, NuiComboEntry(sSoundSetName, nSoundSet)); + nSoundSet++; + } + } + nIndex++; + } + return jSoundSetNameCombo; +} +int GetSelectionBySoundSet2DA(object oHenchman, int nSoundSet) +{ + int nIndex, nSelection, nSoundSetType, nMaxSoundSet = Get2DARowCount("soundset"); + string sGender = IntToString(GetGender(oHenchman)); + while(nIndex < nMaxSoundSet) + { + if(Get2DAString("soundset", "GENDER", nIndex) == sGender) + { + nSoundSetType = StringToInt(Get2DAString("soundset", "TYPE", nIndex)); + if(nSoundSetType < 5) + { + if(nSoundSet == nIndex) return nSelection; + nSelection++; + } + } + nIndex++; + } + return -1; +} +int GetSoundSetBySelection2DA(object oHenchman, int nSelection) +{ + int nIndex, nSoundSet, nSoundSetType, nMaxSoundSet = Get2DARowCount("soundset"); + string sGender = IntToString(GetGender(oHenchman)); + while(nSoundSet < nMaxSoundSet) + { + if(Get2DAString("soundset", "GENDER", nSoundSet) == sGender) + { + nSoundSetType = StringToInt(Get2DAString("soundset", "TYPE", nSoundSet)); + if(nSoundSetType < 5) + { + if(nSelection == nIndex) return nSoundSet; + nIndex++; + } + } + nSoundSet++; + } + return -1; +} +void SetHenchmanScripts(object oHenchman) +{ + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_ch_ac1"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_NOTICE, "nw_ch_ac2"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "nw_ch_ac3"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "nw_ch_ac4"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "nw_ch_ac5"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "nw_ch_ac6"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_DEATH, "nw_ch_ac7"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "nw_ch_ac8"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "nw_ch_ac9"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_RESTED, "nw_ch_aca"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "nw_ch_acb"); + SetEventScript(oHenchman, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "nw_ch_ace"); +} +object ai_AddHenchman(object oPC, json jHenchman, location lLocation, int nFamiliar, int nCompanion) +{ + jHenchman = GffReplaceResRef(jHenchman, "ScriptSpawn", ""); + object oHenchman = JsonToObject(jHenchman, lLocation, OBJECT_INVALID, TRUE); + AddHenchman(oPC, oHenchman); + DeleteLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE"); + string sAssociateType = ai_GetAssociateType(oPC, oHenchman); + NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)); + if(nFamiliar) SummonFamiliar(oHenchman); + if(nCompanion) SummonAnimalCompanion(oHenchman); + return oHenchman; +} +json CreateLevelStatList(json jHenchman, object oHenchman, object oPC, int nLevels = 0) +{ + int nClass = GetClassByPosition(1, oHenchman); + int nHitDie = StringToInt(Get2DAString("classes", "HitDie", nClass)); + SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE); + json jSkill = JsonObject(); + jSkill = GffAddByte(jSkill, "Rank", 0); + jSkill = JsonObjectSet(jSkill, "__struct_id", JsonInt(0)); + json jSkillArray = JsonArray(); + int nNumOfSkills; + for(nNumOfSkills = Get2DARowCount("skills"); nNumOfSkills > 0; nNumOfSkills--) + { + jSkillArray = JsonArrayInsert(jSkillArray, jSkill); + } + json jLevel = JsonObject(); + jLevel = GffAddByte(jLevel, "EpicLevel", 0); + jLevel = GffAddList(jLevel, "FeatList", JsonArray()); + jLevel = GffAddByte(jLevel, "LvlStatClass", nClass); + jLevel = GffAddByte(jLevel, "LvlStatHitDie", nHitDie); + jLevel = GffAddList(jLevel, "SkillList", jSkillArray); + jLevel = GffAddWord(jLevel, "SkillPoints", 0); + jLevel = JsonObjectSet(jLevel, "__struct_id", JsonInt(0)); + json jLevelArray = JsonArray(); + if(nLevels == 0) nLevels = GetLevelByPosition(1, oHenchman); + for(nLevels; nLevels > 0; nLevels--) + { + jLevelArray = JsonArrayInsert(jLevelArray, jLevel); + } + WriteTimestampedLogEntry("pinc_henchmen, 813, Adding LvlStatList to " + GetName(oHenchman)); + return GffAddList(jHenchman, "LvlStatList", jLevelArray); +} +int CanSelectFeat(json jCreature, object oCreature, int nFeat, int nPosition = 1) +{ + // Check if all classes can use. + int n2DAStat = StringToInt(Get2DAString("feat", "ALLCLASSESCANUSE", nFeat)); + if(n2DAStat == 0) + { + int bPass, nClassFeat, nRow, nClass = GetClassByPosition(nPosition, oCreature); + string sClsFeat2DAName = Get2DAString("classes", "FeatsTable", nClass); + int nMaxRow = Get2DARowCount(sClsFeat2DAName); + while(nRow < nMaxRow) + { + nClassFeat = StringToInt(Get2DAString(sClsFeat2DAName, "FeatIndex", nRow)); + if(nClassFeat == nFeat) + { + bPass = TRUE; + break; + } + nRow++; + } + if(!bPass) return FALSE; + } + n2DAStat = StringToInt(Get2DAString("feat", "MINATTACKBONUS", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "BaseAttackBonus")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINSTR", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Str")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINDEX", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Dex")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINCON", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Con")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MININT", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Int")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINWIS", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Wis")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINCHA", nFeat)); + if(JsonGetInt(GffGetByte(jCreature, "Cha")) < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "MINSPELLLVL", nFeat)); + int nSpellLevel = 0, nClass = GetClassByPosition(nPosition, oCreature); + string s2DAName = Get2DAString("classes", "SpellGainTable", nClass); + int nLevel = GetLevelByPosition(nPosition, oCreature); + if(s2DAName != "") + { + nSpellLevel = StringToInt(Get2DAString(s2DAName, "NumSpellLevels", nLevel - 1)) - 1; + } + if(nSpellLevel < n2DAStat) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "PREREQFEAT1", nFeat)); + if(n2DAStat > 0) + { + // ************************************** Add code to search jCreature's feats! + if(!GetHasFeat(n2DAStat, oCreature)) return FALSE; + n2DAStat = StringToInt(Get2DAString("feat", "PREREQFEAT2", nFeat)); + if(!GetHasFeat(n2DAStat, oCreature)) return FALSE; + } + int nIndex; + while(nIndex < 5) + { + n2DAStat = StringToInt(Get2DAString("feat", "OrReqFeat" + IntToString(nIndex), nFeat)); + if(nIndex == 0 && n2DAStat == 0) break; + if(GetHasFeat(n2DAStat, oCreature)) break; + nIndex++; + if(nIndex == 5) return FALSE; + } + string s2DAStat = Get2DAString("feat", "REQSKILL", nFeat); + if(s2DAStat != "") + { + n2DAStat = StringToInt(s2DAStat); + int bCanUse; + if(Get2DAString("skills", "AllClassesCanUse", n2DAStat) == "1") bCanUse = TRUE; + else + { + string sClsSkill2DA = Get2DAString("classes", "SkillsTable", nClass); + int bPass, nClassSkill, nRow, nMaxRow = Get2DARowCount(sClsSkill2DA); + while(nRow < nMaxRow) + { + nClassSkill = StringToInt(Get2DAString(sClsSkill2DA, "SkillIndex", nRow)); + if(nClassSkill == n2DAStat) + { + bCanUse = TRUE; + break; + } + nRow++; + } + } + if(bCanUse) + { + int nSkillReq = StringToInt(Get2DAString("feat", "ReqSkillMinRanks", n2DAStat)); + // ************************** Add code to check jCreatures skills. + if(GetSkillRank(n2DAStat, oCreature, TRUE) < nSkillReq) return FALSE; + } + else return FALSE; + } + s2DAStat = Get2DAString("feat", "REQSKILL2", nFeat); + if(s2DAStat != "") + { + n2DAStat = StringToInt(s2DAStat); + int bCanUse; + if(Get2DAString("skills", "AllClassesCanUse", n2DAStat) == "1") bCanUse = TRUE; + else + { + string sClsSkill2DA = Get2DAString("classes", "SkillsTable", nClass); + int bPass, nClassSkill, nRow, nMaxRow = Get2DARowCount(sClsSkill2DA); + while(nRow < nMaxRow) + { + nClassSkill = StringToInt(Get2DAString(sClsSkill2DA, "SkillIndex", nRow)); + if(nClassSkill == n2DAStat) + { + bCanUse = TRUE; + break; + } + nRow++; + } + } + if(bCanUse) + { + int nSkillReq = StringToInt(Get2DAString("feat", "ReqSkillMinRanks2", n2DAStat)); + if(GetSkillRank(n2DAStat, oCreature, TRUE) < nSkillReq) return FALSE; + } + else return FALSE; + } + n2DAStat = StringToInt(Get2DAString("feat", "MinLevel", nFeat)); + if(n2DAStat > 0) + { + int bPass, nClassPosition, nPositionClass, nPositionLevel; + int nClassRequired = StringToInt(Get2DAString("feat", "MinLevelClass", nFeat)); + while(nClassPosition < AI_MAX_CLASSES_PER_CHARACTER) + { + // ***************************** Rework to check jCreature class list instead. + nPositionClass = GetClassByPosition(nClassPosition, oCreature); + if(nPositionClass == nClassRequired) + { + nPositionLevel = GetLevelByPosition(nClassPosition, oCreature); + if(nPositionLevel < n2DAStat) return FALSE; + else bPass = TRUE; + } + nClassPosition++; + } + if(!bPass) return FALSE; + } + n2DAStat = StringToInt(Get2DAString("feat", "MinFortSave", nFeat)); + if(JsonGetInt(GffGetChar(jCreature, "FortSaveThrow")) < n2DAStat) return FALSE; + s2DAStat = Get2DAString("feat", "PreReqEpic", nFeat); + if(s2DAStat == "1") return FALSE; + return TRUE; +} +json ResetFeats(json jHenchman, object oHenchman) +{ + int nLevel = 0; + // We remake the Feat list if the character doesn't have a level list! + json jFeatList = JsonArray(); + json jFeat; + int nRace = GetRacialType(oHenchman); + string sRace2DAName = Get2DAString("racialtypes", "FeatsTable", nRace); + // Give racial feats. + int nRaceRow, nRaceFeat; + int nRaceMaxRow = Get2DARowCount(sRace2DAName); + while(nRaceRow < nRaceMaxRow) + { + nRaceFeat = StringToInt(Get2DAString(sRace2DAName, "FeatIndex", nRaceRow)); + jFeat = JsonObject(); + jFeat = GffAddWord(jFeat, "Feat", nRaceFeat); + jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); + jFeatList = JsonArrayInsert(jFeatList, jFeat); + WriteTimestampedLogEntry("pinc_henchmen, 973, Adding racial feat: " + + Get2DAString("feat", "LABEL", nRaceFeat)); + nRaceRow++; + } + // Give class feats. + int nClass = GetClassByPosition(1, oHenchman); + string sGranted, sList; + string sClsFeat2DAName = Get2DAString("classes", "FeatsTable", nClass); + int nClassRow, nClassFeat, nClassMaxRow = Get2DARowCount(sClsFeat2DAName); + while(nClassRow < nClassMaxRow) + { + sGranted = Get2DAString(sClsFeat2DAName, "GrantedOnLevel", nClassRow); + if(sGranted == "1") + { + sList = Get2DAString(sClsFeat2DAName, "List", nClassRow); + if(sList == "3") + { + nClassFeat = StringToInt(Get2DAString(sClsFeat2DAName, "FeatIndex", nClassRow)); + jFeat = JsonObject(); + jFeat = GffAddWord(jFeat, "Feat", nClassFeat); + jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); + jFeatList = JsonArrayInsert(jFeatList, jFeat); + WriteTimestampedLogEntry("pinc_henchmen, 995, Adding class feat: " + + Get2DAString("feat", "LABEL", nClassFeat)); + } + } + nClassRow++; + } + // Give any bonus feats from package. + int nPackageFeat, nPackageRow; + string sBonusFeat2DAName = Get2DAString("classes", "BonusFeatsTable", nClass); + int nNumOfFeats = StringToInt(Get2DAString(sBonusFeat2DAName, "Bonus", nLevel)); + string sPackage2DAName = Get2DAString("packages", "FeatPref2DA", nClass); + int nPackageMaxRow = Get2DARowCount(sPackage2DAName); + // Give bonus feats based on the package. + nPackageRow = 0; + if(nNumOfFeats > 0) + { + while(nPackageRow < nPackageMaxRow) + { + nPackageFeat = StringToInt(Get2DAString(sPackage2DAName, "FeatIndex", nPackageRow)); + nClassRow = 0; + while(nClassRow < nClassMaxRow) + { + nClassFeat = StringToInt(Get2DAString(sClsFeat2DAName, "FeatIndex", nClassRow)); + if(nClassFeat == nPackageFeat) + { + sList = Get2DAString(sClsFeat2DAName, "List", nClassRow); + if((sList == "1" || sList == "2") && CanSelectFeat(jHenchman, oHenchman, nClassFeat)) + { + jFeat = JsonObject(); + jFeat = GffAddWord(jFeat, "Feat", nClassFeat); + jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); + jFeatList = JsonArrayInsert(jFeatList, jFeat); + WriteTimestampedLogEntry("pinc_henchmen, 1028, Adding class bonus feat: " + + Get2DAString("feat", "LABEL", nPackageFeat)); + nNumOfFeats--; + } + } + nClassRow++; + } + if(nNumOfFeats < 1) break; + nPackageRow++; + } + } + // Give picked feats from package. + nNumOfFeats = 1; + if(GetHasFeat(FEAT_QUICK_TO_MASTER, oHenchman)) nNumOfFeats++; + nPackageRow = 0; + while(nPackageRow < nPackageMaxRow) + { + nClassRow = 0; + nPackageFeat = StringToInt(Get2DAString(sPackage2DAName, "FeatIndex", nPackageRow)); + if(CanSelectFeat(jHenchman, oHenchman, nPackageFeat)) + { + jFeat = JsonObject(); + jFeat = GffAddWord(jFeat, "Feat", nPackageFeat); + jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); + jFeatList = JsonArrayInsert(jFeatList, jFeat); + WriteTimestampedLogEntry("pinc_henchmen, 1053, Adding character bonus feat: " + + Get2DAString("feat", "LABEL", nPackageFeat)); + nNumOfFeats--; + } + if(nNumOfFeats < 1) break; + nPackageRow++; + } + jHenchman = GffReplaceList(jHenchman, "FeatList", jFeatList); + return jHenchman; +} +json ResetSkills(json jHenchman, object oHenchman) +{ + // We remake the Skill List if the character doesn't have a level list! + int nClass = GetClassByPosition(1, oHenchman); + int nSkillPoints, nIntMod = GetAbilityModifier(ABILITY_INTELLIGENCE, oHenchman); + if(nIntMod > 0) nSkillPoints = nIntMod * 4; + if(GetRacialType(oHenchman) == RACIAL_TYPE_HUMAN) nSkillPoints += 4; + nSkillPoints += StringToInt(Get2DAString("classes", "SkillPointBase", nClass)) * 4; + int nMaxRanks = 5; + json jSkillList = JsonArray(); + json jSkill; + // Setup the Skill List. + int nIndex, nSkillMaxRow = Get2DARowCount("skills"); + for(nIndex = 0; nIndex < nSkillMaxRow; nIndex++) + { + jSkill = JsonObject(); + jSkill = GffAddByte(jSkill, "Rank", 0); + jSkill = JsonObjectSet(jSkill, "__struct_id", JsonInt(0)); + jSkillList = JsonArrayInsert(jSkillList, jSkill); + } + // Give skill points based on the package. + int nPackageSkill, nPackageRow, nCurrentRanks, bCrossClass, nClassRow, nNewRanks; + string sPackage2DAName = Get2DAString("packages", "SkillPref2DA", nClass); + int nPackageMaxRow = Get2DARowCount(sPackage2DAName); + string sClass2DAName = Get2DAString("classes", "SkillsTable", nClass); + int nClassMaxRow = Get2DARowCount(sClass2DAName); + nPackageRow = 0; + while(nPackageRow < nPackageMaxRow && nSkillPoints > 0) + { + nPackageSkill = StringToInt(Get2DAString(sPackage2DAName, "SkillIndex", nPackageRow)); + jSkill = JsonArrayGet(jSkillList, nPackageSkill); + nCurrentRanks = JsonGetInt(GffGetByte(jSkill, "Rank")); + nClassRow = 0; + while(nClassRow < nClassMaxRow) + { + if(nPackageSkill == StringToInt(Get2DAString(sClass2DAName, "SkillIndex", nClassRow))) + { + bCrossClass = Get2DAString(sClass2DAName, "ClassSkill", nClassRow) == "0"; + break; + } + nClassRow++; + } + if(bCrossClass) nNewRanks = (nMaxRanks / 2) - nCurrentRanks; + else nNewRanks = nMaxRanks - nCurrentRanks; + if(nNewRanks > nSkillPoints) nNewRanks = nSkillPoints; + if(nNewRanks > 0) + { + jSkill = GffReplaceByte(jSkill, "Rank", nCurrentRanks + nNewRanks); + jSkillList = JsonArraySet(jSkillList, nPackageSkill, jSkill); + WriteTimestampedLogEntry("pinc_henchmen, 1110, Adding " + IntToString(nNewRanks) + + " ranks to " + Get2DAString("skills", "Label", nPackageSkill)); + nSkillPoints -= nNewRanks; + } + nPackageRow++; + } + jHenchman = GffReplaceList(jHenchman, "SkillList", jSkillList); + return jHenchman; +} +json ResetSpellsKnown(json jClass, object oHenchman) +{ + int nClass = GetClassByPosition(1, oHenchman); + if(Get2DAString("classes", "SpellCaster", nClass) == "0") return jClass; + int nLevel = 0; + // We remake the Known spell list if the character doesn't have a level list! + json jKnownList, jMemorizedList; + json jSpell, jSpellsPerDayList; + int bMemorizesSpells = StringToInt(Get2DAString("classes", "MemorizesSpells", nClass)); + int bSpellBookRestricted = StringToInt(Get2DAString("classes", "SpellBookRestricted", nClass)); + string sSpellKnown2DAName = Get2DAString("classes", "SpellKnownTable", nClass); + string sSpellGained2DAName = Get2DAString("classes", "SpellGainTable", nClass); + string sSpellTableColumn = Get2DAString("classes", "SpellTableColumn", nClass); + string sSpellPackage2DAName = Get2DAString("packages", "SpellPref2DA", nClass); + int nPackageSpell, nPackageRow; + int nPackageMaxRow = Get2DARowCount(sSpellPackage2DAName); + int nKnownSpellIndex, nSpellsKnown, nAbility, nSpellLevel = 0; + string sKnownListName, sSpellLevel, sPackageSpellLevel, sAbility; + // Cycle through all spell levels and reset. + while(nSpellLevel < 10) + { + sSpellLevel = IntToString(nSpellLevel); + WriteTimestampedLogEntry("pinc_henchmen, 1143, Checking Spell Level: " + sSpellLevel); + // Recreate the 0th and 1st level based on the package. + if(nSpellLevel < 2 && bSpellBookRestricted) + { + // Spellbook restricted that don't have a SpellsKnown2DAName + // get to keep all 0th level spells so we skip them. Example:Wizard + if(nSpellLevel != 0 || sSpellKnown2DAName != "") + { + // Classes that are spell book restricted but don't have a SpellKnownTable + // get 3 spells + Ability Modifier worth of spells like a wizard. + if(sSpellKnown2DAName == "") + { + sAbility = Get2DAString("classes", "SpellCastingAbil", nClass); + if(sAbility == "INT") nAbility = ABILITY_INTELLIGENCE; + else if(sAbility == "WIS") nAbility = ABILITY_WISDOM; + else if(sAbility == "CHA") nAbility = ABILITY_CHARISMA; + nSpellsKnown = 3 + GetAbilityModifier(nAbility, oHenchman); + } + else + { + nSpellsKnown = StringToInt(Get2DAString(sSpellKnown2DAName, "SpellLevel" + sSpellLevel, nLevel)); + } + WriteTimestampedLogEntry("pinc_henchmen, 1165, nSpellsKnown: " + IntToString(nSpellsKnown)); + jKnownList = JsonArray(); + nPackageRow = 0; + while(nPackageRow < nPackageMaxRow && nSpellsKnown > 0) + { + nPackageSpell = StringToInt(Get2DAString(sSpellPackage2DAName, "SpellIndex", nPackageRow)); + sPackageSpellLevel = Get2DAString("spells", sSpellTableColumn, nPackageSpell); + if(sPackageSpellLevel == sSpellLevel) + { + jSpell = JsonObject(); + jSpell = GffAddWord(jSpell, "Spell", nPackageSpell); + jSpell = JsonObjectSet(jSpell, "__struct_id", JsonInt(3)); + jKnownList = JsonArrayInsert(jKnownList, jSpell); + WriteTimestampedLogEntry("pinc_henchmen, 1178, Adding known spell: " + + Get2DAString("spells", "LABEL", nPackageSpell)); + nSpellsKnown--; + } + nPackageRow++; + } + if(JsonGetLength(jKnownList) == 0) + { + jClass = GffRemoveList(jClass, "KnownList" + sSpellLevel); + WriteTimestampedLogEntry("pinc_henchmen, 1187, Removing KnownList" + sSpellLevel); + } + else if(JsonGetType(GffGetList(jClass, "KnownList" + sSpellLevel)) != JSON_TYPE_NULL) + { + jClass = GffReplaceList(jClass, "KnownList" + sSpellLevel, jKnownList); + } + else jClass = GffAddList(jClass, "KnownList" + sSpellLevel, jKnownList); + } + } + // Remove all other known spell levels and memorized levels. + else + { + jKnownList = GffGetList(jClass, "KnownList" + sSpellLevel); + if(JsonGetType(jKnownList) != JSON_TYPE_NULL) + { + jClass = GffRemoveList(jClass, "KnownList" + sSpellLevel); + WriteTimestampedLogEntry("pinc_henchmen, 1203, Removing KnownList" + sSpellLevel); + } + } + if(bMemorizesSpells) + { + jMemorizedList = GffGetList(jClass, "MemorizedList" + sSpellLevel); + if(JsonGetType(jMemorizedList) != JSON_TYPE_NULL) + { + jClass = GffRemoveList(jClass, "MemorizedList" + sSpellLevel); + WriteTimestampedLogEntry("pinc_henchmen, 1210, Removing MemorizedList" + sSpellLevel); + } + } + else + { + jSpellsPerDayList = GffGetList(jClass, "SpellsPerDayList"); + nSpellsKnown = StringToInt(Get2DAString(sSpellGained2DAName, "SpellLevel"+ sSpellLevel, nLevel)); + jSpell = JsonArrayGet(jSpellsPerDayList, nSpellLevel); + jSpell = GffReplaceByte(jSpell, "NumSpellsLeft", nSpellsKnown); + jSpellsPerDayList = JsonArraySet(jSpellsPerDayList, nSpellLevel, jSpell); + jClass = GffReplaceList(jClass, "SpellsPerDayList", jSpellsPerDayList); + WriteTimestampedLogEntry("pinc_henchmen, 1223, Setting SpellsPerDay to " + + IntToString(nSpellsKnown)); + } + nSpellLevel++; + } + return jClass; +} +object ResetCharacter(object oPC, object oHenchman) +{ + SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE); + RemoveHenchman(oPC, oHenchman); + json jHenchman = ObjectToJson(oHenchman, TRUE); + json jClassList = GffGetList(jHenchman, "ClassList"); + json jClass = JsonArrayGet(jClassList, 0); + // Set the Class list to the first class only and put at level 1. + int nClass = JsonGetInt(JsonObjectGet(jClass, "Class")); + jClass = GffReplaceShort(jClass, "ClassLevel", 1); + // Delete extra classes. + int nClassIndex = JsonGetLength(jClassList) - 1; + while(nClassIndex > 0) + { + jClassList = JsonArrayDel(jClassList, nClassIndex--); + } + int nHitPoints = StringToInt(Get2DAString("classes", "HitDie", nClass)); + int nMod = JsonGetInt(GffGetByte(jHenchman, "Con")); + if(nMod > 9) nHitPoints += (nMod - 10) / 2; + else nHitPoints += (nMod - 11) / 2; + jHenchman = GffReplaceShort(jHenchman, "CurrentHitPoints", nHitPoints); + jHenchman = GffReplaceShort(jHenchman, "HitPoints", nHitPoints); + jHenchman = GffReplaceShort(jHenchman, "MaxHitPoints", nHitPoints); + jHenchman = GffReplaceDword(jHenchman, "Experience", 0); + jHenchman = GffReplaceFloat(jHenchman, "ChallengeRating", 1.0); + string s2DA = Get2DAString("classes", "AttackBonusTable", nClass); + int nAtk = StringToInt(Get2DAString(s2DA, "BAB", 0)); + jHenchman = GffReplaceByte(jHenchman, "BaseAttackBonus", nAtk); + s2DA = Get2DAString("classes", "SavingThrowTable", nClass); + int nSave = StringToInt(Get2DAString(s2DA, "FortSave", 0)); + jHenchman = GffReplaceChar(jHenchman, "FortSaveThrow", nSave); + nSave = StringToInt(Get2DAString(s2DA, "RefSave", 0)); + jHenchman = GffReplaceChar(jHenchman, "RefSaveThrow", nSave); + nSave = StringToInt(Get2DAString(s2DA, "WillSave", 0)); + jHenchman = GffReplaceChar(jHenchman, "WillSaveThrow", nSave); + json jLvlStatList = GffGetList(jHenchman, "LvlStatList"); + if(JsonGetType(jLvlStatList) != JSON_TYPE_NULL) + { + WriteTimestampedLogEntry("pinc_henchmen 1275, jLvlStatList: " + JsonDump(jLvlStatList, 4)); + int nLevel = 1, nLevelTrack = 1; + int nAbilityStatIncrease, nAbility; + string sAbility; + json jAbility; + json jLevel = JsonArrayGet(jLvlStatList, nLevel); + while(JsonGetType(jLevel) != JSON_TYPE_NULL) + { + WriteTimestampedLogEntry("inc_henchmen, 1297, Checking level " + IntToString(nLevelTrack)); + // Remove all Ability score increases for each level from ability scores. + jAbility = GffGetByte(jLevel, "LvlStatAbility"); + if(JsonGetType(jAbility) != JSON_TYPE_NULL) + { + nAbilityStatIncrease = JsonGetInt(jAbility); + if(nAbilityStatIncrease == ABILITY_STRENGTH) sAbility = "Str"; + if(nAbilityStatIncrease == ABILITY_DEXTERITY) sAbility = "Dex"; + if(nAbilityStatIncrease == ABILITY_CONSTITUTION) sAbility = "Con"; + if(nAbilityStatIncrease == ABILITY_INTELLIGENCE) sAbility = "Int"; + if(nAbilityStatIncrease == ABILITY_WISDOM) sAbility = "Wis"; + if(nAbilityStatIncrease == ABILITY_CHARISMA) sAbility = "Cha"; + nAbility = JsonGetInt(GffGetByte(jHenchman, sAbility)) - 1; + jHenchman = GffReplaceByte(jHenchman, sAbility, nAbility); + WriteTimestampedLogEntry("pinc_henchmen, 1314, Removing " + sAbility + " level bonus ability score point."); + } + jLvlStatList = JsonArrayDel(jLvlStatList, nLevel); + // Note: nLevel is not incremented since we are removing the previous level. + // there for when we get the same level again its the next level! + jLevel = JsonArrayGet(jLvlStatList, nLevel); + //SendMessageToPC(oPC, "jLvlStatList: " + JsonDump(jLvlStatList, 4)); + nLevelTrack++; + } + jHenchman = GffRemoveList(jHenchman, "LvlStatList"); + } + jHenchman = CreateLevelStatList(jHenchman, oHenchman, oPC, 1); + jHenchman = ResetSkills(jHenchman, oHenchman); + jHenchman = ResetFeats(jHenchman, oHenchman); + jClass = ResetSpellsKnown(jClass, oHenchman); + jClassList = JsonArraySet(jClassList, 0, jClass); + jHenchman = GffReplaceList(jHenchman, "ClassList", jClassList); + //WriteTimestampedLogEntry("pinc_henchmen 1397, jHenchman: " + JsonDump(jHenchman, 4)); + location lLocation = GetLocation(oHenchman); + int nFamiliar, nCompanion; + object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oHenchman); + if(oCompanion != OBJECT_INVALID) nFamiliar = TRUE; + oCompanion = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oHenchman); + if(oCompanion != OBJECT_INVALID) nCompanion = TRUE; + AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE)); + DestroyObject(oHenchman); + oHenchman = ai_AddHenchman(oPC, jHenchman, lLocation, nFamiliar, nCompanion); + return oHenchman; +} +// ********* New Henchman windows ********** +void CreateCharacterEditGUIPanel(object oPC, object oHenchman) +{ + // Set window to not save until it has been created. + SetLocalInt(oPC, "0_No_Win_Save", TRUE); + DelayCommand(0.5f, DeleteLocalInt (oPC, "0_No_Win_Save")); + // Group 1 (Portrait)******************************************************* 151 / 73 + // Group 1 Row 1 *********************************************************** 350 / 91 + json jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateTextEditBox (jGroupRow, "name_placeholder", "char_name", 15, FALSE, 140.0, 20.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add the group row to the group column. + json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + // Group 1 Row 1 *********************************************************** 350 / 91 + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateTextEditBox (jGroupRow, "port_placeholder", "port_name", 15, FALSE, 140.0, 20.0, "port_tooltip"); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add the group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 1 Row 2 *********************************************************** 350 / 259 + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateImage(jGroupRow, "", "port_resref", NUI_ASPECT_EXACTSCALED, NUI_HALIGN_CENTER, NUI_VALIGN_TOP, 140.0f, 160.0f); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add the group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 1 Row 3 *********************************************************** 350 / 292 + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateButton (jGroupRow, "<", "btn_portrait_prev", 42.0f, 25.0f); + jGroupRow = CreateButton (jGroupRow, "Set", "btn_portrait_ok", 44.0f, 25.0f); + jGroupRow = CreateButton (jGroupRow, ">", "btn_portrait_next", 42.0f, 25.0f); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 1 Row 4 *********************************************************** 350 / 91 + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateLabel(jGroupRow, "Sound Set", "lbl_sound_set", 140.0, 10.0f, NUI_HALIGN_CENTER, NUI_VALIGN_BOTTOM); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add the group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 1 Row 5 *********************************************************** 350 / 325 + jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jGroupRow = CreateCombo(jGroupRow, ArrayInsertSoundSets(oHenchman), "cmb_soundset", 140.0, 25.0); + jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + json jRow = JsonArrayInsert(JsonArray(), NuiGroup(NuiCol(jGroupCol))); + // Group 2 (Stats)********************************************************** 151 / 73 + // Group 2 Row 1 *********************************************************** 350 / 91 + jGroupRow = CreateLabel(JsonArray(), "", "lbl_stats", 150.0, 15.0, 0, NUI_VALIGN_BOTTOM, 0.0); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); + + // Group 2 Row 2 *********************************************************** 350 / 243 + //json jAlign = CreateOptionsAlignment(oHenchman, 0); + //jGroupRow = CreateOptions(JsonArray(), "opt_lawchaos", NUI_DIRECTION_HORIZONTAL, jAlign, 60.0, 35.0); + // Add group row to the group column. + //jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 3 *********************************************************** 350 / 243 + //jAlign = CreateOptionsAlignment(oHenchman, 1); + //jGroupRow = CreateOptions(JsonArray(), "opt_goodevil", NUI_DIRECTION_HORIZONTAL, jAlign, 60.0, 35.0); + //jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer()); + // Add group row to the group column. + //jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 2 *********************************************************** 350 / 243 + json jClasses = CreateOptionsClasses(oHenchman); + jGroupRow = CreateOptions(JsonArray(), "opt_classes", NUI_DIRECTION_VERTICAL, jClasses, 150.0, 144.0); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 3 *********************************************************** 350 / 276 + jGroupRow = CreateButton(JsonArray(), "Level Up", "btn_level_up", 150.0f, 25.0f, -1.0, "btn_level_up_tooltip"); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 4 *********************************************************** 350 / 309 + jGroupRow = CreateButton (JsonArray(), "Reset Character", "btn_reset", 150.0f, 25.0f, -1.0, "btn_reset_tooltip"); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 5 *********************************************************** 350 / 342 + jGroupRow = CreateCombo(JsonArray(), jArrayInsertClasses(), "cmb_class", 150.0, 25.0); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + // Group 2 Row 6 *********************************************************** 350 / 375 + int nClassOption = GetLocalInt(oHenchman, "CLASS_OPTION_POSITION"); + int nClass = GetClassByPosition(nClassOption + 1, oHenchman); + int bNoClass = FALSE; + if(nClass == CLASS_TYPE_INVALID) + { + nClass = GetLocalInt(oHenchman, "CLASS_SELECTED_" + IntToString(nClassOption + 1)); + bNoClass = TRUE; + } + string sClass = IntToString(nClass); + jGroupRow = CreateCombo(JsonArray(), ArrayInsertPackages(sClass), "cmb_package", 150.0, 25.0); + // Add group row to the group column. + jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow)); + jRow = JsonArrayInsert(jRow, NuiGroup(NuiCol(jGroupCol))); + // Add the row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 5 (text edit box)**************************************************** 350 / 518 + jRow = CreateTextEditBox(JsonArray(), "desc_placeholder", "desc_value", 1000, TRUE, 350.0, 150.0, "desc_tooltip"); + // Add the row to the column. + jCol = JsonArrayInsert(jCol, NuiRow (jRow)); + // Row 6 (button)*********************************************************** 350/ 546 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton (jRow, "Save Description", "btn_desc_save", 150.0f, 20.0f); + jRow = JsonArrayInsert(jRow, NuiSpacer()); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow (jRow)); + // Set the Layout of the window. + json jLayout = NuiCol (jCol); + // Get the window location to restore it from the database. + CheckHenchmanDataAndInitialize(oPC, "0"); + json jData = GetHenchmanDbJson(oPC, "henchman", "0"); + json jGeometry = JsonObjectGet(jData, "henchman_edit_nui"); + float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x")); + float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y")); + if(fX == 0.0 && fY == 0.0) + { + fX = -1.0; + fY = -1.0; + } + string sName = GetName(oHenchman); + if(GetStringRight(sName, 1) == "s") sName = sName + "'"; + else sName = sName + "'s"; + int nToken = SetWindow (oPC, jLayout, "henchman_edit_nui", sName + " Character editor", + fX, fY, 380.0, 588.0, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_henchmen"); + // Set all binds, events, and watches. + int nID = GetPortraitId (oPC); + NuiSetUserData(oPC, nToken, JsonInt(nID)); + string sResRef = GetPortraitResRef(oHenchman); + NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE); + NuiSetBind(oPC, nToken, "char_name", JsonString(GetName(oHenchman))); + NuiSetBindWatch(oPC, nToken, "char_name", TRUE); + NuiSetBind(oPC, nToken, "char_name_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "port_name", JsonString(sResRef)); + NuiSetBindWatch(oPC, nToken, "port_name", TRUE); + NuiSetBind(oPC, nToken, "port_name_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "port_resref_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "port_resref_image", JsonString(sResRef + "l")); + NuiSetBind(oPC, nToken, "port_tooltip", JsonString (" You may also type the portrait file name.")); + // Set buttons active. + NuiSetBind(oPC, nToken, "btn_portrait_prev_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_portrait_next_event", JsonBool(TRUE)); + int nSelection = GetSelectionBySoundSet2DA(oHenchman, GetSoundset(oHenchman)); + NuiSetBind(oPC, nToken, "cmb_soundset_selected", JsonInt(nSelection)); + NuiSetBindWatch(oPC, nToken, "cmb_soundset_selected", TRUE); + NuiSetBind(oPC, nToken, "cmb_soundset_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_desc_save_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_portrait_ok_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "desc_tooltip", JsonString(" You can use color codes!")); + string sDescription = GetDescription(oHenchman); + NuiSetBind(oPC, nToken, "desc_value_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "desc_value", JsonString (sDescription)); + // Setup the henchman window. + string sStats = GetAlignText(oHenchman) + " "; + if(GetGender(oHenchman) == GENDER_MALE) sStats += "Male "; + else sStats += "Female "; + sStats += GetStringByStrRef (StringToInt (Get2DAString ("racialtypes", "Name", GetRacialType (oHenchman)))); + NuiSetBind(oPC, nToken, "lbl_stats_label", JsonString(sStats)); + json jHenchman = ObjectToJson(oHenchman); + NuiSetBind(oPC, nToken, "opt_classes_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "opt_classes_value", JsonInt(nClassOption)); + NuiSetBind(oPC, nToken, "btn_level_up_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_level_up_tooltip", JsonString(" Levels the character up by one level in selected class.")); + if(ai_GetIsCharacter(oHenchman)) NuiSetBind(oPC, nToken, "btn_reset_event", JsonBool(FALSE)); + else NuiSetBind(oPC, nToken, "btn_reset_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_reset_tooltip", JsonString(" Resets the character to level 1.")); + nSelection = GetSelectionByClass2DA(nClass); + NuiSetBind(oPC, nToken, "cmb_class_selected", JsonInt(nSelection)); + NuiSetBindWatch(oPC, nToken, "cmb_class_selected", bNoClass); + NuiSetBind(oPC, nToken, "cmb_class_event", JsonBool(bNoClass)); + int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nClassOption + 1)); + if(nPackage == 0) + { + nPackage = GetPackageBySelection2DA(sClass, 0); + SetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nClassOption + 1), nPackage); + } + NuiSetBind(oPC, nToken, "cmb_package_selected", JsonInt(GetSelectionByPackage2DA(sClass, nPackage))); + NuiSetBindWatch(oPC, nToken, "cmb_package_selected", bNoClass); + NuiSetBind(oPC, nToken, "cmb_package_event", JsonBool(bNoClass)); +} +void CreateCharacterDescriptionNUI(object oPC, string sName, string sIcon, string sDescription) +{ + // Row 1 ******************************************************************* 500 / 469 + json jRow = CreateImage(JsonArray(), "", "char_icon", NUI_ASPECT_FIT, NUI_HALIGN_CENTER, NUI_VALIGN_MIDDLE, 40.0, 40.0); + jRow = CreateTextBox(jRow, "char_text", 380.0, 400.0); + // Add row to the column. + json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow)); + // Row 2 ******************************************************************* 500 / 522 + jRow = JsonArrayInsert(JsonArray(), NuiSpacer()); + jRow = CreateButton(jRow, "OK", "btn_ok", 150.0f, 45.0f); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + // Set the Layout of the window. + json jLayout = NuiCol(jCol); + int nToken = SetWindow(oPC, jLayout, "char_description_nui", sName, + -1.0, -1.0, 460.0f, 537.0 + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_henchmen"); + json jData = JsonArrayInsert(JsonArray(), JsonString(ObjectToString(oPC))); + NuiSetUserData(oPC, nToken, jData); + // Row 1 + NuiSetBind(oPC, nToken, "char_icon_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "char_icon_image", JsonString(sIcon)); + NuiSetBind(oPC, nToken, "char_text_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "char_text", JsonString(sDescription)); + // Row 2 + NuiSetBind(oPC, nToken, "btn_ok_event", JsonBool(TRUE)); +} + diff --git a/src/module/nss/xx_pc_1_hb.nss b/src/module/nss/xx_pc_1_hb.nss new file mode 100644 index 0000000..7dac876 --- /dev/null +++ b/src/module/nss/xx_pc_1_hb.nss @@ -0,0 +1,79 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_1_hb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnHeart beat script for PC AI; + This will usually fire every 6 seconds (1 game round). +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_menus" +void ai_ActionFollow(object oCreature, object oTarget) +{ + if(GetLocalInt(OBJECT_SELF, AI_CURRENT_ACTION_MODE) == AI_LAST_ACTION_MOVE) + { + float fDistance = GetDistanceBetween(oCreature, oTarget); + float fFollowDistance = ai_GetFollowDistance(oCreature); + if(fDistance > fFollowDistance && !ai_GetIsInCombat(oCreature)) + { + if(fDistance > fFollowDistance * 5.0) AssignCommand(oCreature, JumpToObject(oTarget)); + else + { + ClearAllActions(); + ActionMoveToObject(oTarget, TRUE, fFollowDistance); + } + } + DelayCommand(1.0, ai_ActionFollow(oCreature, oTarget)); + } +} +void main() +{ + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("xx_pc_1_hb", "12", GetName(oCreature) + " heartbeat."); + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound(oCreature); + return; + } + if(ai_CheckForCombat(oCreature, FALSE)) return; + if(IsInConversation(oCreature)) return; + if(ai_TryHealing(oCreature, oCreature)) return; + if(ai_CheckNearbyObjects(oCreature)) return; + if(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH)) + { + if(AI_DEBUG) ai_Debug("xx_ch_1_hb", "47", "Going into stealth mode!"); + int nStealth = GetSkillRank(SKILL_HIDE, oCreature); + nStealth += GetSkillRank(SKILL_MOVE_SILENTLY, oCreature); + if(nStealth / 2 >= ai_GetCharacterLevels(oCreature)) + { + SetActionMode(oCreature, ACTION_MODE_STEALTH, TRUE); + SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + } + } + else + { + SetActionMode(oCreature, ACTION_MODE_STEALTH, FALSE); + if(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH)) + { + if(AI_DEBUG) ai_Debug("xx_ch_1_hb", "61", "Going into search mode!"); + SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE); + } + else SetActionMode(oCreature, ACTION_MODE_DETECT, FALSE); + } + // Finally we check to make sure we are following. + if(GetCurrentAction(oCreature) != ACTION_FOLLOW) + { + // Follow associate. + object oAssociate = GetLocalObject(oCreature, AI_FOLLOW_TARGET); + if(oAssociate == OBJECT_INVALID || GetMaster(oAssociate) != oCreature) return; + if(GetDistanceBetween(oCreature, oAssociate) > ai_GetFollowDistance(oCreature)) + { + ai_ClearCreatureActions(); + if(AI_DEBUG) ai_Debug("XX_pc_1_hb", "75", "Follow master: " + + " Stealth: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_STEALTH)) + + " Search: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_AGGRESSIVE_SEARCH))); + SetLocalInt(oCreature, AI_CURRENT_ACTION_MODE, AI_LAST_ACTION_MOVE); + ai_ActionFollow(oCreature, oAssociate); + //ActionMoveToObject(oAssociate, TRUE, ai_GetFollowDistance(oCreature)); + } + } +} diff --git a/src/module/nss/xx_pc_2_percept.nss b/src/module/nss/xx_pc_2_percept.nss new file mode 100644 index 0000000..9731f70 --- /dev/null +++ b/src/module/nss/xx_pc_2_percept.nss @@ -0,0 +1,107 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_2_percept + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnPerception script for PC AI; + There are 4 types of perception - Heard, Inaudible, Seen, Vanished. + Only one type will ever be true in an event trigger. + The order of trigger is Heard/Seen and Inaudible/Vanished. + There are two states of percepion Heard and Seen. + These states can be set at the same time thus a heard event can see the creature. + Fires when ever one of these states changes from TRUE to FALSE or FALSE to TRUE. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oLastPerceived = GetLastPerceived(); + if(AI_DEBUG) + { + if(GetLastPerceptionHeard ()) + { + ai_Debug("xx_pc_2_percept", "22", GetName(oCreature) + " heard " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + + " Seen: " + IntToString(GetObjectSeen(oLastPerceived, oCreature)) + "."); + } + if(GetLastPerceptionSeen ()) + { + ai_Debug("xx_pc_2_percept", "29", GetName(oCreature) + " sees " + + GetName(GetLastPerceived()) + " Distance: " + + FloatToString(GetDistanceBetween(GetLastPerceived(), oCreature), 0, 2) + "."); + } + if(GetLastPerceptionVanished ()) + { + ai_Debug("xx_pc_2_percept", "35", GetName(oCreature) + " lost sight of " + + GetName(GetLastPerceived()) + "."); + } + } + // We do nothing on Inaudibles so drop out early! + if(GetLastPerceptionInaudible()) + { + ai_Debug("xx_pc_2_percept", "42", GetName(oCreature) + " lost sound of " + + GetName(GetLastPerceived()) + "."); + return; + } + if(AI_DEBUG) ai_Debug("xx_pc_2_percept", "46", "Dead? " + IntToString(GetIsDead(oLastPerceived)) + + " Enemy? " + IntToString(GetIsEnemy(oLastPerceived, oCreature))); + if(ai_Disabled(oCreature)) return; + if(GetIsDead(oLastPerceived) || !GetIsEnemy(oLastPerceived, oCreature)) return; + // All code below assumes the perceived creature is an enemy and is alive! + // **************************** ENEMY HEARD ******************************** + if(GetLastPerceptionHeard()) + { + // Since Heard is run before Seen, but the values are set at the same + // time we can skip heard checks on heard & seen creatures! + if(GetObjectSeen(oLastPerceived, oCreature)) + { + // If the creature we are perceiving was our invisible creature then + // remove that they are invisible. + if(oLastPerceived == GetLocalObject(oCreature, AI_IS_INVISIBLE)) + { + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); + } + ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_SEE_AN_ENEMY); + } + else ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_HEARD_AN_ENEMY); + return; + } + // **************************** ENEMY SEEN ********************************* + if(GetLastPerceptionSeen()) + { + // If the creature we are perceiving was our invisible creature then + // remove that they are invisible. + if(oLastPerceived == GetLocalObject(oCreature, AI_IS_INVISIBLE)) + { + DeleteLocalObject(oCreature, AI_IS_INVISIBLE); + } + ai_AssociateEvaluateNewThreat(oCreature, oLastPerceived, AI_I_SEE_AN_ENEMY); + return; + } + // **************************** ENEMY VANISHED ***************************** + if(GetLastPerceptionVanished()) + { + // Lets keep a mental note of the invisible creature. + SetLocalObject(oCreature, AI_IS_INVISIBLE, oLastPerceived); + if(AI_DEBUG) ai_Debug("xx_pc_2_percept", "86", " We saw " + GetName(oLastPerceived) + " disappear!"); + if(ai_GetIsBusy(oCreature)) return; + // If in combat check to see if our target disappeared. + // If they have and we are not in melee with them then reevaluate combat + // since we lost our target. + if(ai_GetIsInCombat(oCreature)) + { + if(AI_DEBUG) ai_Debug("xx_pc_2_percept", "93", "Is this our target? " + + IntToString(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived)); + if(ai_GetAttackedTarget(oCreature, TRUE, TRUE) == oLastPerceived) + { + ai_DoAssociateCombatRound(oCreature); + } + return; + } + // If they are not invisible then that means they left our perception + // range and we need follow them. + ActionMoveToObject(oLastPerceived, TRUE, AI_RANGE_CLOSE); + } + // **************************** ENEMY INAUDIBLE***************************** + // Not used. +} diff --git a/src/module/nss/xx_pc_3_endround.nss b/src/module/nss/xx_pc_3_endround.nss new file mode 100644 index 0000000..51126e6 --- /dev/null +++ b/src/module/nss/xx_pc_3_endround.nss @@ -0,0 +1,60 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_3_endround + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnCombatRoundEnd event script for PC AI; + Fires at the end of each combat round (6 seconds). + This will fire as long as oCreature is in combat (GetIsInCombat()). + This event starts counting once a combat action is started. + Every time a spell is cast it will queue another end combat round so haste with + two spells cast will fire this twice in one round. + It will also fire at the end of a hostile effect that stops actions i.e Stunned, Knockdown etc. + Action modes are also cleared prior to this event executing! + GetAttemptedAttackTarget() & GetAttemptedSpellTarget() also get cleared prior to this event. + This event can be canceled with ClearAllActions(TRUE) and SurrenderToEnemies. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + if(AI_DEBUG) ai_Debug("xx_pc_3_endround", "20", GetName(oCreature) + " ends combat round."); + if(ai_Disabled(oCreature)) return; + // Action modes get cleared prior to each OnCombatRoundEnd! + // We do this to keep the action mode going. + int nActionMode = GetLocalInt(oCreature, AI_CURRENT_ACTION_MODE); + if(nActionMode > 0) + { + SetActionMode(oCreature, nActionMode, TRUE); + // We don't want to use up all of the Dwarven Defenders uses! + if(nActionMode == 12) IncrementRemainingFeatUses(oCreature, FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE); + } + int nAction = GetCurrentAction(oCreature); + if(AI_DEBUG) ai_Debug("xx_pc_3_endround", "32", "nAction: " + IntToString(nAction)); + switch(nAction) + { + // These actions are uninteruptable. + case ACTION_MOVETOPOINT : + case ACTION_CASTSPELL : + case ACTION_ITEMCASTSPELL : + case ACTION_COUNTERSPELL : return; + // Might be doing a special action that is not a defined action. + case ACTION_INVALID : + { + int nCombatWait = GetLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + if(AI_DEBUG) ai_Debug("xx_pc_3_endround", "47", "nCombatWait: " + IntToString(nCombatWait)); + if(nCombatWait) + { + if(ai_IsInCombatRound(oCreature, nCombatWait)) return; + DeleteLocalInt(oCreature, AI_COMBAT_WAIT_IN_SECONDS); + } + break; + } + // We always want to interupt an attack action at the end of a round (6 seconds). + case ACTION_ATTACKOBJECT : + { + if(ai_IsInCombatRound(oCreature, AI_COMBAT_ROUND_IN_SECONDS)) return; + } + } + if(ai_GetIsInCombat(oCreature)) ai_DoAssociateCombatRound (oCreature); +} + diff --git a/src/module/nss/xx_pc_4_convers.nss b/src/module/nss/xx_pc_4_convers.nss new file mode 100644 index 0000000..413aef1 --- /dev/null +++ b/src/module/nss/xx_pc_4_convers.nss @@ -0,0 +1,30 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_4_convers + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnDialoge event script for PC AI; + Fires when oCreature has been clicked on for conversation. + Fires when oCreature hears a shout from another creature. + If SetListening is FALSE then oCreature will not "hear" anything. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + int nMatch = GetListenPatternNumber(); + object oLastSpeaker = GetLastSpeaker(); + if(AI_DEBUG) ai_Debug("xx_pc_4_convers", "17", GetName(oCreature) + " listens " + + IntToString(nMatch) + " to " + GetName(oLastSpeaker) + "." + + " Searching: " + IntToString(GetLocalInt(oCreature, AI_AM_I_SEARCHING))); + // If we are disabled then we can't listen or talk, Busy is checked in ai_SelectAssociateCommand(). + // Some modules disable the player then talk to them! So it should be ok + // to keep this remarked out. + // Some commands override being busy so we check in ai_SelectAssociateCommand. + if(nMatch != -1) + { + if(!GetFactionEqual(oLastSpeaker, oCreature)) return; + if(!ai_Disabled(oCreature)) ai_SelectAssociateCommand(oCreature, oLastSpeaker, nMatch); + } + else BeginConversation("", oLastSpeaker); +} + diff --git a/src/module/nss/xx_pc_5_phyatked.nss b/src/module/nss/xx_pc_5_phyatked.nss new file mode 100644 index 0000000..1c6ba79 --- /dev/null +++ b/src/module/nss/xx_pc_5_phyatked.nss @@ -0,0 +1,29 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_5_phyatked + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnPhysicalAttacked event script for PC AI; + Fires for all physical attacks, claws, weapons, fists, bow, etc. + Fires for taunt skill, animal empathy skill. +/*////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oAttacker = GetLastAttacker(); + if(AI_DEBUG) ai_Debug("xx_pc_5_phyatked", "14", GetName(oCreature) + " was attacked by " + + GetName(oAttacker) + "."); + SetLocalObject(oAttacker, AI_ATTACKED_PHYSICAL, oCreature); + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature)) return; + if(ai_GetIsInCombat(oCreature)) return; + // We only inform others if attacked when not busy, not disabled, & not in combat. + SetLocalObject(oCreature, AI_MY_TARGET, oAttacker); + SpeakString(AI_ATKED_BY_WEAPON, TALKVOLUME_SILENT_TALK); + // The only way to get here is to not be in combat thus we have not + // perceived them so lets look for them. + if(!ai_CanIAttack(oCreature)) return; + if(GetDistanceBetween(oCreature, oAttacker) < AI_RANGE_CLOSE) ai_DoAssociateCombatRound(oCreature); + else ActionMoveToObject(oAttacker, TRUE, AI_RANGE_CLOSE - 1.0); +} + + diff --git a/src/module/nss/xx_pc_6_damaged.nss b/src/module/nss/xx_pc_6_damaged.nss new file mode 100644 index 0000000..c3d6aaa --- /dev/null +++ b/src/module/nss/xx_pc_6_damaged.nss @@ -0,0 +1,27 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_6_damaged + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Associate (Summons, Familiars, Companions) OnDamaged script; + Does not fire if the creature dies from the damage. + Does not fire for plot creatures as they take no damage. + May fire before or after OnPhysicalAttacked event. + Fires when EffectDamage is applied to oCreature even if 0 damage. + Fires when a weapon damages a oCreature, but not if resisted. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + if(ai_Disabled(oCreature)) return; + // Make sure to clear wounded shout limit if we take damage. See ai_TryHealing. + DeleteLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT"); + object oDamager = GetLastDamager(oCreature); + if(AI_DEBUG) ai_Debug("xx_pc_6_damaged", "18", GetName(oCreature) + " has been damaged by " + GetName(oDamager)); + if(GetObjectType(oDamager) == OBJECT_TYPE_AREA_OF_EFFECT && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature) || ai_GetIsInCombat(oCreature)) return; + if(GetDistanceBetween(oCreature, oDamager) < AI_RANGE_CLOSE) ai_DoAssociateCombatRound(oCreature); + else ActionMoveToObject(oDamager, TRUE, AI_RANGE_CLOSE - 1.0); +} + diff --git a/src/module/nss/xx_pc_8_disturb.nss b/src/module/nss/xx_pc_8_disturb.nss new file mode 100644 index 0000000..6440c03 --- /dev/null +++ b/src/module/nss/xx_pc_8_disturb.nss @@ -0,0 +1,21 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_8_disturb + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnDisturbed event script for PC AI. + Fires when the inventory of oCreature is changed i.e. added or removed. + Creatures can't have items added or removed from its inventory (it's not a + container), then the only way this fires for creatures if something is stolen. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + if(AI_DEBUG) ai_Debug("xx_pc_8_disturb", "14", GetName(OBJECT_SELF) + " is been disturbed!"); + // We do nothing at the moment... lets not mess up our factions ok? + // This should be defined by the server admins and is commented out. + //if(ai_GetIsBusy(OBJECT_SELF, FALSE) || ai_Disabled()) return; + //object oTarget = GetLastDisturbed(); + //if (oTarget != OBJECT_INVALID) ai_DoMonsterCombatRound (); +} + + diff --git a/src/module/nss/xx_pc_b_castat.nss b/src/module/nss/xx_pc_b_castat.nss new file mode 100644 index 0000000..5d4b85f --- /dev/null +++ b/src/module/nss/xx_pc_b_castat.nss @@ -0,0 +1,35 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_b_castat + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnSpellCastAt event script for PC AI; + Fires when oCreature becomes the target of a spell via SignalEvent. + Fires when a healing kit is used on a creature. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + object oCaster = GetLastSpellCaster(); + SetLocalObject(oCaster, AI_ATTACKED_SPELL, oCreature); + if(ai_Disabled(oCreature)) return; + if(!GetLastSpellHarmful()) return; + // If the spell came from an ally, we don't want to hold it against them. + if(GetFactionEqual(oCaster, oCreature)) ClearPersonalReputation(oCaster, oCreature); + // Lets see what kind of area of effect this is and select an appropriate action. + int nSpell = GetLastSpell(); + if(AI_DEBUG) ai_Debug("xx_pc_b_castat", "21", GetName(OBJECT_SELF) + " has been hit by a harmful spell(" + + Get2DAString("spells", "Label", nSpell) + ")!"); + if(ai_GetInAOEReaction(oCreature, oCaster, nSpell) && + ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return; + if(ai_GetIsBusy(oCreature)) return; + if(ai_CheckForCombat(oCreature, FALSE)) return; + // We were attacked by an enemy out of combat, so let our allies know. + SetLocalObject(oCreature, AI_MY_TARGET, oCaster); + SpeakString(AI_ATKED_BY_SPELL, TALKVOLUME_SILENT_TALK); + if(!ai_CanIAttack(oCreature)) return; + if(GetDistanceBetween(oCreature, oCaster) < AI_RANGE_CLOSE) ai_DoAssociateCombatRound(oCreature); + else ActionMoveToObject(oCaster, TRUE, AI_RANGE_CLOSE - 1.0); +} + + diff --git a/src/module/nss/xx_pc_e_blocked.nss b/src/module/nss/xx_pc_e_blocked.nss new file mode 100644 index 0000000..604513e --- /dev/null +++ b/src/module/nss/xx_pc_e_blocked.nss @@ -0,0 +1,68 @@ +/*////////////////////////////////////////////////////////////////////////////// + Script: xx_pc_e_blocked + Programmer: Philos +//////////////////////////////////////////////////////////////////////////////// + Player OnBlocked event script for PC AI; + Can be blocked by a creature or door. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_associates" +void main() +{ + object oCreature = OBJECT_SELF; + // This actually gets either a Creature or Door that is blocking OBJECT_SELF. + object oObject = GetBlockingDoor(); + if(AI_DEBUG) ai_Debug("xx_pc_e_blocked", "14", GetName(oCreature) + " is being blocked by " + GetName(oObject)); + int nObjectType = GetObjectType(oObject); + if(nObjectType == OBJECT_TYPE_CREATURE) + { + if(GetIsEnemy(oObject, oCreature)) + { + if(ai_CanIAttack(oCreature) && ai_GetIsInCombat(oCreature)) + { + ai_DoAssociateCombatRound(oCreature); + return; + } + if(ai_CheckForCombat(oCreature, FALSE)) return; + } + } + // Anything below blocking us is a door. + if(nObjectType != OBJECT_TYPE_DOOR) return; + //if(GetLockKeyTag(oObject) != "") return; + else if(GetIsDoorActionPossible(oObject, DOOR_ACTION_OPEN) && + GetAbilityScore(oCreature, ABILITY_INTELLIGENCE) >= 5) + { + DoDoorAction(oObject, DOOR_ACTION_OPEN); + return; + } + // Anything below is ignored in combat. + if(ai_GetIsInCombat(oCreature)) return; + // If we are in combat we should ignore doors that do not easily open. + if(GetIsDoorActionPossible(oObject, DOOR_ACTION_BASH) && + ai_GetWeaponDamage(oCreature, 3, TRUE) > GetHardness(oObject) && + GetLockKeyTag(oObject) == "") + { + ActionWait(1.0); + ActionAttack(oObject); + // Give them 3 rounds to break through a door. + DelayCommand(18.0, ai_ClearCreatureActions(TRUE)); + return; + } + else if(GetLocked(oObject)) + { + if(AI_DEBUG) ai_Debug("0e_ch_e_blocked", "49", GetName(oObject) + " is locked!"); + string sID = ObjectToString(oCreature); + if(!GetLocalInt(oObject, "AI_STATED_LOCKED_" + sID) && + !ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK)) SpeakString("That " + GetName(oObject) + " is locked!"); + SetLocalInt(oObject, "AI_STATED_LOCKED_" + sID, TRUE); + if(ai_GetAIMode(oCreature, AI_MODE_PICK_LOCKS) || + ai_GetAIMode(oCreature, AI_MODE_BASH_LOCKS)) + { + ai_AttemptToByPassLock(oCreature, oObject); + } + } + // Clear our action so we can move on to something else unless the door is open. + else if(!GetIsOpen(oObject)) + { + ai_ClearCreatureActions(); + } +} diff --git a/unpack_haks.cmd b/unpack_haks.cmd new file mode 100644 index 0000000..6ecd98e --- /dev/null +++ b/unpack_haks.cmd @@ -0,0 +1 @@ +nasher unpack pepshak --verbose --removeDeleted:false \ No newline at end of file diff --git a/update_src_from_haks.cmd b/update_src_from_haks.cmd new file mode 100644 index 0000000..443bf64 --- /dev/null +++ b/update_src_from_haks.cmd @@ -0,0 +1,2 @@ +nasher unpack tophak --verbose -y +nasher unpack mediahak --verbose -y \ No newline at end of file