diff --git a/_module/ifo/module.ifo.json b/_module/ifo/module.ifo.json index b76a57a..bf21722 100644 --- a/_module/ifo/module.ifo.json +++ b/_module/ifo/module.ifo.json @@ -186,7 +186,7 @@ "Mod_Description": { "type": "cexolocstring", "value": { - "0": "The Horde: Orcs v2.0\n8/17/02\n\n(Requires PRC8 v4.1.11+)\n\n\nA Neverwinter Nights Module created by Mithral Hammer\nhttp://wind.prohosting.com/mithral\n\nAuthor: Dalantriel\nSylvan_Blades@yahoo.com\n\nIntro Movie available from:\nhttp://wind.prohosting.com/mithral/prefabs.shtml\n\n\nDescription:\n\nNestled on the west shore of the Goblintide river the tiny hamlet of Helmsfield has always been plagued by orc raids from the neighbouring Lurkwood Forest. Disorganised and poorly executed, the attacks to date have been easily repelled by the local militia... but the tide is turning. With each day the orcs have become more brazen in their raids and it is now evident that someone (or something) is rallying their numbers. Out of desperation Henrick, Cleric of Helm and founder of Helmsfield, puts out a call for help to the neighbouring regions requesting the assistance of those of able body and stout heart: a call not easily dismissed by those of adventurous spirit.\n\nDesigned for co-operative play, The Horde is an action-based module, which pits players against an invading army of orcs. The primary goal of the scenario is to capture and hold key parts of the map in a strategic battle for territorial control. Victory is achieved through the defeat of the orc horde while defending the hamlet of Helmsfield.\n \n\nRecommended Starting Levels:\n\nParty: 5-10 players level 1-2\n 2-4 players levels 2-3\n\nSolo play: 1 player, levels 4-5\n\n\nReplayability:\n\nThe combination of random treasure and random elements to the Horde AI means that no two scenarios will play the same. \n\n \n\nDungeon Master:\n\nNo DM is required to play, in fact it is recommended you don't play with one. However if you do wish to DM a Horde scenario, I strongly recommend you study and understand the AI that motivates the different units. Read the DM's readme and f eel free to contact the author for more information.\n\n\nGetting Started:\n\nFor those of you wanting to dive straight into the action, fire up the module and speak to the NPCs within the Temple of Helm, they'll tell you everything you need to know. Otherwise browse over this readme file for more detailed information.\n \n\n\nThe Main Area (Helmsfield):\n\nThe main area contains two staging areas for the opposing sides.\n\n- these are placed at opposite sides of the map.\n- each staging area houses the primary NPC of that faction.\n- the Horde will not initiate its attack until you leave the town (ie pass through one of the two main gates). Thus players have plenty of time to equip and prepare their characters.\n\n\nWinning the Scenario:\n\nTo win the scenario, Fangrot the orc warlord must be defeated whilst keeping Henrick the Cleric of Helm alive.\n\n- killing the orc warlord does not automatically win the scenario, though it will dramatically reduces the battle hardiness of the Horde.\n- players are required to return to Henrick after defeating the warlord to successfully complete the adventure.\n- players cannot win the scenario if Henrick, Cleric of Helm is killed at any time.\n\n\nNPCs:\n\nSome NPCs provide key functions. \n\nNPC: Function:\n\nHenrick Cleric of Helm Primary NPC (success depends upon his survival)\nBelonor Sten Magic Shop Owner/Inn Guard\nLomilas Swift Scout reports on progress of the battle\nMeroppi Instructions on playing Horde scenarios\nTown Guards Defend Gates/Temple\n\nNote that NPCs are mortal and it is in your best interest to keep them alive. If they die they cannot be replaced and the function associated with them will no longer be available.\n\n\nTreasure & Items:\n\n- gold and loot can be collected from defeated enemies and used to purchase equipment.\n- optional encounters with tougher opponents who guard better loot are also available for those who want to get rich quick, but be warned these guys are tough (these encounters and their loot respawn but are no longer available after the scenario has been won).\n- items can be purchased from outposts (see below).\n- more powerful magic items can be purchased from Belonor's Emporium a magic shop located just south of the Temple of Helm. His prices are more competitive than you'll find at outposts.\n \n\nOutposts:\n\n- at the beginning of a scenario outposts are distributed between the two factions.\n- items can be purchased from outposts that are under control of the players. Simply click the banner to open a trading window.\n- outposts are captured by destroying their associated banner, this is done by casting spells at or bashing the banner.\n- the strength of the Horde is determined by how many outposts are in its possession, thus it is important for players to capture and defend outposts.\n- note that intentionally destroying a player controlled banner (Helm Banner) will return control of that outpost to the Horde (so be cautious when using area of effect damage spells, or in other words watch where you're slinging those fireballs).\n- Upon capture, houses will be torched by the orcs. When recaptured by players the fires will not be extinguished to simulate that the farm was indeed damaged by the orcs during the attack.\n\n\nBanner Descriptions:\n\nBanner Name Faction Description\n---------------------------------------------------------------------------------------------------------\nHelm Banner Player White, Light Blue and Purple Y \nBlood Moon Banner Orcs Red Circle on Black \n \n\nPlayer Death/Healing:\n\nUpon death, players may simply respawn at the resurrection shrine located to the North of the Temple. Respawning will incur a small experience and monetary loss. In addition players can receive healing for free from a healing shrine also located to the North of the Temple. Since these shrines are located away from the main action, players will be indisposed for a period of time as they travel back and forth.\n\n \n\nPlayers Guide: Strategy and Tips:\n\n- use henchmen/pets to guard outposts, bridges and ramps (especially if you are solo).\n- use town guards to help defeat tougher creatures.\n- heal NPCs wherever possible.\n- watch for scout reports indicating attacks on town gates and respond to them.\n- recapture lost outposts as soon as possible. The enemy grows stronger with each outpost they capture.\n- capture and hold outposts to weaken the Horde. Once you control the area, begin your assualt on the orc temple.\n- only purchase ammunition and healing potions from outposts.\n- call in heavy melee characters to help capture outposts.\n- set traps at outposts, bridges, gates and ramps.\n- money is hard to come by. Take items from fallen NPCs and use the respawning guardian encounters to gain wealth.\n- control and hold the ramps to the river before attempting the guardian encounters.\n- in a party of mixed levels, lower level players make very effective scouts.\n- work together. A coordinated party is very effective and alot of fun as well.\n- direct assualts are very risky. If you fail you will lose alot of ground by the time you recover.\n\n \n\nKnown Issues/Bugs:\n\nI'm pleased to say that on release there are no known bugs. However if you encounter any they can be posted on the Mithral Hammer Bug Reporting Forum:\n\nhttp://wind.prohosting.com/mithral/cgi-bin/yabb/YaBB.pl?board=bugs\n\n \n\nFuture Releases:\n\nWe are currently working on the addition of more and improved features as well as new maps and scenarios. If you have suggestions or features that you'd like to see, post them on the Mithral Hammer Forums and we'll see what we can do.\n\n \n\nScripting:\n\nIn the process of creating this module we have probably broken most programming conventions and not done things in the most effective manner, but we're learning as we go. We welcome your suggestions to improve our scripts. You are free to use the resources contained in this module as you wish, but please reference the work of the original authors.\n\n \n\nAcknowledgements:\n\nAvarice - Concept/AI design\n \n\nScripts/Resources:\nWhiskeyFur - General Scripting and Server Hosting (via www.wyrmfyre.com)\nJeff Mann - General scripting and AI advice\nCrashed - Static Monster Respawn script\nLeo Lipelis - Trashcan script\nWydraz - Henchman Tutorial (http://nwvault.ign.com/modules/wydraz/tutorial/henchman.shtml)\nRichard Conner - Item resref listing\nMark Temple - Custom Random Loot Drops script\n\n\nBeta Testers:\n\nAvarice\nX-Bones\nKristal\nVarious\n\nGeneral:\n\nThe NWN community: for making the boards such an friendly and informative place to hang out.\nBioware: for bringing to life their vision of Neverwinter Nights. \n" + "0": "The Horde: Orcs v2.0\n8/17/02\n\n(Requires PRC8 v4.1.11+)\n\nNOW WITH PEPS AI!\n\n\nA Neverwinter Nights Module created by Mithral Hammer\nhttp://wind.prohosting.com/mithral\n\nAuthor: Dalantriel\nSylvan_Blades@yahoo.com\n\nIntro Movie available from:\nhttp://wind.prohosting.com/mithral/prefabs.shtml\n\n\nDescription:\n\nNestled on the west shore of the Goblintide river the tiny hamlet of Helmsfield has always been plagued by orc raids from the neighbouring Lurkwood Forest. Disorganised and poorly executed, the attacks to date have been easily repelled by the local militia... but the tide is turning. With each day the orcs have become more brazen in their raids and it is now evident that someone (or something) is rallying their numbers. Out of desperation Henrick, Cleric of Helm and founder of Helmsfield, puts out a call for help to the neighbouring regions requesting the assistance of those of able body and stout heart: a call not easily dismissed by those of adventurous spirit.\n\nDesigned for co-operative play, The Horde is an action-based module, which pits players against an invading army of orcs. The primary goal of the scenario is to capture and hold key parts of the map in a strategic battle for territorial control. Victory is achieved through the defeat of the orc horde while defending the hamlet of Helmsfield.\n \n\nRecommended Starting Levels:\n\nParty: 5-10 players level 1-2\n 2-4 players levels 2-3\n\nSolo play: 1 player, levels 4-5\n\n\nReplayability:\n\nThe combination of random treasure and random elements to the Horde AI means that no two scenarios will play the same. \n\n \n\nDungeon Master:\n\nNo DM is required to play, in fact it is recommended you don't play with one. However if you do wish to DM a Horde scenario, I strongly recommend you study and understand the AI that motivates the different units. Read the DM's readme and f eel free to contact the author for more information.\n\n\nGetting Started:\n\nFor those of you wanting to dive straight into the action, fire up the module and speak to the NPCs within the Temple of Helm, they'll tell you everything you need to know. Otherwise browse over this readme file for more detailed information.\n \n\n\nThe Main Area (Helmsfield):\n\nThe main area contains two staging areas for the opposing sides.\n\n- these are placed at opposite sides of the map.\n- each staging area houses the primary NPC of that faction.\n- the Horde will not initiate its attack until you leave the town (ie pass through one of the two main gates). Thus players have plenty of time to equip and prepare their characters.\n\n\nWinning the Scenario:\n\nTo win the scenario, Fangrot the orc warlord must be defeated whilst keeping Henrick the Cleric of Helm alive.\n\n- killing the orc warlord does not automatically win the scenario, though it will dramatically reduces the battle hardiness of the Horde.\n- players are required to return to Henrick after defeating the warlord to successfully complete the adventure.\n- players cannot win the scenario if Henrick, Cleric of Helm is killed at any time.\n\n\nNPCs:\n\nSome NPCs provide key functions. \n\nNPC: Function:\n\nHenrick Cleric of Helm Primary NPC (success depends upon his survival)\nBelonor Sten Magic Shop Owner/Inn Guard\nLomilas Swift Scout reports on progress of the battle\nMeroppi Instructions on playing Horde scenarios\nTown Guards Defend Gates/Temple\n\nNote that NPCs are mortal and it is in your best interest to keep them alive. If they die they cannot be replaced and the function associated with them will no longer be available.\n\n\nTreasure & Items:\n\n- gold and loot can be collected from defeated enemies and used to purchase equipment.\n- optional encounters with tougher opponents who guard better loot are also available for those who want to get rich quick, but be warned these guys are tough (these encounters and their loot respawn but are no longer available after the scenario has been won).\n- items can be purchased from outposts (see below).\n- more powerful magic items can be purchased from Belonor's Emporium a magic shop located just south of the Temple of Helm. His prices are more competitive than you'll find at outposts.\n \n\nOutposts:\n\n- at the beginning of a scenario outposts are distributed between the two factions.\n- items can be purchased from outposts that are under control of the players. Simply click the banner to open a trading window.\n- outposts are captured by destroying their associated banner, this is done by casting spells at or bashing the banner.\n- the strength of the Horde is determined by how many outposts are in its possession, thus it is important for players to capture and defend outposts.\n- note that intentionally destroying a player controlled banner (Helm Banner) will return control of that outpost to the Horde (so be cautious when using area of effect damage spells, or in other words watch where you're slinging those fireballs).\n- Upon capture, houses will be torched by the orcs. When recaptured by players the fires will not be extinguished to simulate that the farm was indeed damaged by the orcs during the attack.\n\n\nBanner Descriptions:\n\nBanner Name Faction Description\n---------------------------------------------------------------------------------------------------------\nHelm Banner Player White, Light Blue and Purple Y \nBlood Moon Banner Orcs Red Circle on Black \n \n\nPlayer Death/Healing:\n\nUpon death, players may simply respawn at the resurrection shrine located to the North of the Temple. Respawning will incur a small experience and monetary loss. In addition players can receive healing for free from a healing shrine also located to the North of the Temple. Since these shrines are located away from the main action, players will be indisposed for a period of time as they travel back and forth.\n\n \n\nPlayers Guide: Strategy and Tips:\n\n- use henchmen/pets to guard outposts, bridges and ramps (especially if you are solo).\n- use town guards to help defeat tougher creatures.\n- heal NPCs wherever possible.\n- watch for scout reports indicating attacks on town gates and respond to them.\n- recapture lost outposts as soon as possible. The enemy grows stronger with each outpost they capture.\n- capture and hold outposts to weaken the Horde. Once you control the area, begin your assualt on the orc temple.\n- only purchase ammunition and healing potions from outposts.\n- call in heavy melee characters to help capture outposts.\n- set traps at outposts, bridges, gates and ramps.\n- money is hard to come by. Take items from fallen NPCs and use the respawning guardian encounters to gain wealth.\n- control and hold the ramps to the river before attempting the guardian encounters.\n- in a party of mixed levels, lower level players make very effective scouts.\n- work together. A coordinated party is very effective and alot of fun as well.\n- direct assualts are very risky. If you fail you will lose alot of ground by the time you recover.\n\n \n\nKnown Issues/Bugs:\n\nI'm pleased to say that on release there are no known bugs. However if you encounter any they can be posted on the Mithral Hammer Bug Reporting Forum:\n\nhttp://wind.prohosting.com/mithral/cgi-bin/yabb/YaBB.pl?board=bugs\n\n \n\nFuture Releases:\n\nWe are currently working on the addition of more and improved features as well as new maps and scenarios. If you have suggestions or features that you'd like to see, post them on the Mithral Hammer Forums and we'll see what we can do.\n\n \n\nScripting:\n\nIn the process of creating this module we have probably broken most programming conventions and not done things in the most effective manner, but we're learning as we go. We welcome your suggestions to improve our scripts. You are free to use the resources contained in this module as you wish, but please reference the work of the original authors.\n\n \n\nAcknowledgements:\n\nAvarice - Concept/AI design\n \n\nScripts/Resources:\nWhiskeyFur - General Scripting and Server Hosting (via www.wyrmfyre.com)\nJeff Mann - General scripting and AI advice\nCrashed - Static Monster Respawn script\nLeo Lipelis - Trashcan script\nWydraz - Henchman Tutorial (http://nwvault.ign.com/modules/wydraz/tutorial/henchman.shtml)\nRichard Conner - Item resref listing\nMark Temple - Custom Random Loot Drops script\n\n\nBeta Testers:\n\nAvarice\nX-Bones\nKristal\nVarious\n\nGeneral:\n\nThe NWN community: for making the boards such an friendly and informative place to hang out.\nBioware: for bringing to life their vision of Neverwinter Nights. \n" } }, "Mod_DuskHour": { diff --git a/_module/ncs/0c_assoc_actions.ncs b/_module/ncs/0c_assoc_actions.ncs index 38d5507..cdbaad0 100644 Binary files a/_module/ncs/0c_assoc_actions.ncs and b/_module/ncs/0c_assoc_actions.ncs differ diff --git a/_module/ncs/0c_henchmenspell.ncs b/_module/ncs/0c_henchmenspell.ncs index 3e0cb16..cd33d49 100644 Binary files a/_module/ncs/0c_henchmenspell.ncs and b/_module/ncs/0c_henchmenspell.ncs differ diff --git a/_module/ncs/0c_if_has_class.ncs b/_module/ncs/0c_if_has_class.ncs index ccacecf..1461b03 100644 Binary files a/_module/ncs/0c_if_has_class.ncs and b/_module/ncs/0c_if_has_class.ncs differ diff --git a/_module/ncs/0c_if_has_spell.ncs b/_module/ncs/0c_if_has_spell.ncs index d98b201..aa89e0e 100644 Binary files a/_module/ncs/0c_if_has_spell.ncs and b/_module/ncs/0c_if_has_spell.ncs differ diff --git a/_module/ncs/0c_if_taunt.ncs b/_module/ncs/0c_if_taunt.ncs index c715cd9..9222ff7 100644 Binary files a/_module/ncs/0c_if_taunt.ncs and b/_module/ncs/0c_if_taunt.ncs differ diff --git a/_module/ncs/0e_c2_7_ondeath.ncs b/_module/ncs/0e_c2_7_ondeath.ncs index 1fc2a89..c5ae737 100644 Binary files a/_module/ncs/0e_c2_7_ondeath.ncs and b/_module/ncs/0e_c2_7_ondeath.ncs differ diff --git a/_module/ncs/0e_ch_7_ondeath.ncs b/_module/ncs/0e_ch_7_ondeath.ncs index 911eb7a..47f35bc 100644 Binary files a/_module/ncs/0e_ch_7_ondeath.ncs and b/_module/ncs/0e_ch_7_ondeath.ncs differ diff --git a/_module/ncs/0e_do_combat_rnd.ncs b/_module/ncs/0e_do_combat_rnd.ncs index aea68d3..0f93676 100644 Binary files a/_module/ncs/0e_do_combat_rnd.ncs and b/_module/ncs/0e_do_combat_rnd.ncs differ diff --git a/_module/ncs/0e_gui_events.ncs b/_module/ncs/0e_gui_events.ncs index 2064ddc..91bda4d 100644 Binary files a/_module/ncs/0e_gui_events.ncs and b/_module/ncs/0e_gui_events.ncs differ diff --git a/_module/ncs/0e_id_events.ncs b/_module/ncs/0e_id_events.ncs new file mode 100644 index 0000000..259080c Binary files /dev/null and b/_module/ncs/0e_id_events.ncs differ diff --git a/_module/ncs/0e_m1_3_endround.ncs b/_module/ncs/0e_m1_3_endround.ncs index 13dfe43..5154fd0 100644 Binary files a/_module/ncs/0e_m1_3_endround.ncs and b/_module/ncs/0e_m1_3_endround.ncs differ diff --git a/_module/ncs/0e_nui.ncs b/_module/ncs/0e_nui.ncs index 69733f0..e70f753 100644 Binary files a/_module/ncs/0e_nui.ncs and b/_module/ncs/0e_nui.ncs differ diff --git a/_module/ncs/0e_nui_dm.ncs b/_module/ncs/0e_nui_dm.ncs index af7cbfb..479c155 100644 Binary files a/_module/ncs/0e_nui_dm.ncs and b/_module/ncs/0e_nui_dm.ncs differ diff --git a/_module/ncs/0e_onclientload.ncs b/_module/ncs/0e_onclientload.ncs index 2244bcd..fc0ff67 100644 Binary files a/_module/ncs/0e_onclientload.ncs and b/_module/ncs/0e_onclientload.ncs differ diff --git a/_module/ncs/0e_player_target.ncs b/_module/ncs/0e_player_target.ncs index 55d2976..2864f9a 100644 Binary files a/_module/ncs/0e_player_target.ncs and b/_module/ncs/0e_player_target.ncs differ diff --git a/_module/ncs/2xmtreasure.ncs b/_module/ncs/2xmtreasure.ncs index 1d9575b..3311c94 100644 Binary files a/_module/ncs/2xmtreasure.ncs and b/_module/ncs/2xmtreasure.ncs differ diff --git a/_module/ncs/2xtreasure.ncs b/_module/ncs/2xtreasure.ncs index d27d426..92d06d5 100644 Binary files a/_module/ncs/2xtreasure.ncs and b/_module/ncs/2xtreasure.ncs differ diff --git a/_module/ncs/3xtreasure.ncs b/_module/ncs/3xtreasure.ncs index 6025176..56f58a2 100644 Binary files a/_module/ncs/3xtreasure.ncs and b/_module/ncs/3xtreasure.ncs differ diff --git a/_module/ncs/ai_a_ambusher.ncs b/_module/ncs/ai_a_ambusher.ncs index a3807bd..25d510a 100644 Binary files a/_module/ncs/ai_a_ambusher.ncs and b/_module/ncs/ai_a_ambusher.ncs differ diff --git a/_module/ncs/ai_a_atk_casters.ncs b/_module/ncs/ai_a_atk_casters.ncs index 5aafe7f..c2a3954 100644 Binary files a/_module/ncs/ai_a_atk_casters.ncs and b/_module/ncs/ai_a_atk_casters.ncs differ diff --git a/_module/ncs/ai_a_atk_nearest.ncs b/_module/ncs/ai_a_atk_nearest.ncs index 51b5bab..4ab9cf5 100644 Binary files a/_module/ncs/ai_a_atk_nearest.ncs and b/_module/ncs/ai_a_atk_nearest.ncs differ diff --git a/_module/ncs/ai_a_atk_warrior.ncs b/_module/ncs/ai_a_atk_warrior.ncs index cdd1fcc..28aeda3 100644 Binary files a/_module/ncs/ai_a_atk_warrior.ncs and b/_module/ncs/ai_a_atk_warrior.ncs differ diff --git a/_module/ncs/ai_a_barbarian.ncs b/_module/ncs/ai_a_barbarian.ncs index bafeedb..fcad436 100644 Binary files a/_module/ncs/ai_a_barbarian.ncs and b/_module/ncs/ai_a_barbarian.ncs differ diff --git a/_module/ncs/ai_a_bard.ncs b/_module/ncs/ai_a_bard.ncs index d0e85e3..1e0f286 100644 Binary files a/_module/ncs/ai_a_bard.ncs and b/_module/ncs/ai_a_bard.ncs differ diff --git a/_module/ncs/ai_a_cleric.ncs b/_module/ncs/ai_a_cleric.ncs index 00cd7bb..db0648c 100644 Binary files a/_module/ncs/ai_a_cleric.ncs and b/_module/ncs/ai_a_cleric.ncs differ diff --git a/_module/ncs/ai_a_cntrspell.ncs b/_module/ncs/ai_a_cntrspell.ncs index 0502ceb..b240c5b 100644 Binary files a/_module/ncs/ai_a_cntrspell.ncs and b/_module/ncs/ai_a_cntrspell.ncs differ diff --git a/_module/ncs/ai_a_default.ncs b/_module/ncs/ai_a_default.ncs index 62dd563..7122b9b 100644 Binary files a/_module/ncs/ai_a_default.ncs and b/_module/ncs/ai_a_default.ncs differ diff --git a/_module/ncs/ai_a_defensive.ncs b/_module/ncs/ai_a_defensive.ncs index 0703aed..830a87e 100644 Binary files a/_module/ncs/ai_a_defensive.ncs and b/_module/ncs/ai_a_defensive.ncs differ diff --git a/_module/ncs/ai_a_druid.ncs b/_module/ncs/ai_a_druid.ncs index 8b0099a..6177c61 100644 Binary files a/_module/ncs/ai_a_druid.ncs and b/_module/ncs/ai_a_druid.ncs differ diff --git a/_module/ncs/ai_a_fighter.ncs b/_module/ncs/ai_a_fighter.ncs index 65ba6d8..69bdc0e 100644 Binary files a/_module/ncs/ai_a_fighter.ncs and b/_module/ncs/ai_a_fighter.ncs differ diff --git a/_module/ncs/ai_a_flanker.ncs b/_module/ncs/ai_a_flanker.ncs index c021687..f9b72bc 100644 Binary files a/_module/ncs/ai_a_flanker.ncs and b/_module/ncs/ai_a_flanker.ncs differ diff --git a/_module/ncs/ai_a_invisible.ncs b/_module/ncs/ai_a_invisible.ncs index 67a9a81..e5dc6b1 100644 Binary files a/_module/ncs/ai_a_invisible.ncs and b/_module/ncs/ai_a_invisible.ncs differ diff --git a/_module/ncs/ai_a_monk.ncs b/_module/ncs/ai_a_monk.ncs index 7eb5970..1da2e48 100644 Binary files a/_module/ncs/ai_a_monk.ncs and b/_module/ncs/ai_a_monk.ncs differ diff --git a/_module/ncs/ai_a_no_cmb_mode.ncs b/_module/ncs/ai_a_no_cmb_mode.ncs index 2aef820..24c7a11 100644 Binary files a/_module/ncs/ai_a_no_cmb_mode.ncs and b/_module/ncs/ai_a_no_cmb_mode.ncs differ diff --git a/_module/ncs/ai_a_paladin.ncs b/_module/ncs/ai_a_paladin.ncs index d854d63..43ac202 100644 Binary files a/_module/ncs/ai_a_paladin.ncs and b/_module/ncs/ai_a_paladin.ncs differ diff --git a/_module/ncs/ai_a_peaceful.ncs b/_module/ncs/ai_a_peaceful.ncs index 02a0054..4785a6f 100644 Binary files a/_module/ncs/ai_a_peaceful.ncs and b/_module/ncs/ai_a_peaceful.ncs differ diff --git a/_module/ncs/ai_a_polymorphed.ncs b/_module/ncs/ai_a_polymorphed.ncs index c513c3f..8d21990 100644 Binary files a/_module/ncs/ai_a_polymorphed.ncs and b/_module/ncs/ai_a_polymorphed.ncs differ diff --git a/_module/ncs/ai_a_ranged.ncs b/_module/ncs/ai_a_ranged.ncs index 19c592d..c741b2f 100644 Binary files a/_module/ncs/ai_a_ranged.ncs and b/_module/ncs/ai_a_ranged.ncs differ diff --git a/_module/ncs/ai_a_ranger.ncs b/_module/ncs/ai_a_ranger.ncs index be76ad1..3f7efde 100644 Binary files a/_module/ncs/ai_a_ranger.ncs and b/_module/ncs/ai_a_ranger.ncs differ diff --git a/_module/ncs/ai_a_rogue.ncs b/_module/ncs/ai_a_rogue.ncs index a652083..7e26195 100644 Binary files a/_module/ncs/ai_a_rogue.ncs and b/_module/ncs/ai_a_rogue.ncs differ diff --git a/_module/ncs/ai_a_sorcerer.ncs b/_module/ncs/ai_a_sorcerer.ncs index 9d3fd6e..91e107c 100644 Binary files a/_module/ncs/ai_a_sorcerer.ncs and b/_module/ncs/ai_a_sorcerer.ncs differ diff --git a/_module/ncs/ai_a_taunter.ncs b/_module/ncs/ai_a_taunter.ncs index 6686a00..bb03e53 100644 Binary files a/_module/ncs/ai_a_taunter.ncs and b/_module/ncs/ai_a_taunter.ncs differ diff --git a/_module/ncs/ai_a_wizard.ncs b/_module/ncs/ai_a_wizard.ncs index af215ee..cbd5264 100644 Binary files a/_module/ncs/ai_a_wizard.ncs and b/_module/ncs/ai_a_wizard.ncs differ diff --git a/_module/ncs/ai_ambusher.ncs b/_module/ncs/ai_ambusher.ncs index d6387dc..d1f1f8d 100644 Binary files a/_module/ncs/ai_ambusher.ncs and b/_module/ncs/ai_ambusher.ncs differ diff --git a/_module/ncs/ai_barbarian.ncs b/_module/ncs/ai_barbarian.ncs index 29eb43d..982e8d6 100644 Binary files a/_module/ncs/ai_barbarian.ncs and b/_module/ncs/ai_barbarian.ncs differ diff --git a/_module/ncs/ai_bard.ncs b/_module/ncs/ai_bard.ncs index f1d6c70..384fe44 100644 Binary files a/_module/ncs/ai_bard.ncs and b/_module/ncs/ai_bard.ncs differ diff --git a/_module/ncs/ai_cleric.ncs b/_module/ncs/ai_cleric.ncs index 1c0d242..c8f039a 100644 Binary files a/_module/ncs/ai_cleric.ncs and b/_module/ncs/ai_cleric.ncs differ diff --git a/_module/ncs/ai_cntrspell.ncs b/_module/ncs/ai_cntrspell.ncs index e8150cb..b675c9e 100644 Binary files a/_module/ncs/ai_cntrspell.ncs and b/_module/ncs/ai_cntrspell.ncs differ diff --git a/_module/ncs/ai_coward.ncs b/_module/ncs/ai_coward.ncs index 56d9278..10e571e 100644 Binary files a/_module/ncs/ai_coward.ncs and b/_module/ncs/ai_coward.ncs differ diff --git a/_module/ncs/ai_default.ncs b/_module/ncs/ai_default.ncs index c95d2d3..8897334 100644 Binary files a/_module/ncs/ai_default.ncs and b/_module/ncs/ai_default.ncs differ diff --git a/_module/ncs/ai_defensive.ncs b/_module/ncs/ai_defensive.ncs index 777e2f9..c61ef29 100644 Binary files a/_module/ncs/ai_defensive.ncs and b/_module/ncs/ai_defensive.ncs differ diff --git a/_module/ncs/ai_dragon.ncs b/_module/ncs/ai_dragon.ncs index 5de5e34..5d75ac1 100644 Binary files a/_module/ncs/ai_dragon.ncs and b/_module/ncs/ai_dragon.ncs differ diff --git a/_module/ncs/ai_druid.ncs b/_module/ncs/ai_druid.ncs index de40f51..fdc1778 100644 Binary files a/_module/ncs/ai_druid.ncs and b/_module/ncs/ai_druid.ncs differ diff --git a/_module/ncs/ai_fighter.ncs b/_module/ncs/ai_fighter.ncs index 8d39b57..36fb56c 100644 Binary files a/_module/ncs/ai_fighter.ncs and b/_module/ncs/ai_fighter.ncs differ diff --git a/_module/ncs/ai_flanker.ncs b/_module/ncs/ai_flanker.ncs index d03ab5f..cc43329 100644 Binary files a/_module/ncs/ai_flanker.ncs and b/_module/ncs/ai_flanker.ncs differ diff --git a/_module/ncs/ai_incorporeal.ncs b/_module/ncs/ai_incorporeal.ncs index 7950518..ea7ce3b 100644 Binary files a/_module/ncs/ai_incorporeal.ncs and b/_module/ncs/ai_incorporeal.ncs differ diff --git a/_module/ncs/ai_invisible.ncs b/_module/ncs/ai_invisible.ncs index c1c4a31..a0d4488 100644 Binary files a/_module/ncs/ai_invisible.ncs and b/_module/ncs/ai_invisible.ncs differ diff --git a/_module/ncs/ai_monk.ncs b/_module/ncs/ai_monk.ncs index 69db5d8..f3b5142 100644 Binary files a/_module/ncs/ai_monk.ncs and b/_module/ncs/ai_monk.ncs differ diff --git a/_module/ncs/ai_paladin.ncs b/_module/ncs/ai_paladin.ncs index 593113a..1f982f5 100644 Binary files a/_module/ncs/ai_paladin.ncs and b/_module/ncs/ai_paladin.ncs differ diff --git a/_module/ncs/ai_polymorphed.ncs b/_module/ncs/ai_polymorphed.ncs index 9d25929..2dcbf86 100644 Binary files a/_module/ncs/ai_polymorphed.ncs and b/_module/ncs/ai_polymorphed.ncs differ diff --git a/_module/ncs/ai_ranged.ncs b/_module/ncs/ai_ranged.ncs index 9a9524e..9a62f27 100644 Binary files a/_module/ncs/ai_ranged.ncs and b/_module/ncs/ai_ranged.ncs differ diff --git a/_module/ncs/ai_ranger.ncs b/_module/ncs/ai_ranger.ncs index d35ffce..6ee586a 100644 Binary files a/_module/ncs/ai_ranger.ncs and b/_module/ncs/ai_ranger.ncs differ diff --git a/_module/ncs/ai_rogue.ncs b/_module/ncs/ai_rogue.ncs index a7da6ff..c48ed23 100644 Binary files a/_module/ncs/ai_rogue.ncs and b/_module/ncs/ai_rogue.ncs differ diff --git a/_module/ncs/ai_shadow.ncs b/_module/ncs/ai_shadow.ncs index 5bbe01a..66646c4 100644 Binary files a/_module/ncs/ai_shadow.ncs and b/_module/ncs/ai_shadow.ncs differ diff --git a/_module/ncs/ai_sorcerer.ncs b/_module/ncs/ai_sorcerer.ncs index 1346087..b709618 100644 Binary files a/_module/ncs/ai_sorcerer.ncs and b/_module/ncs/ai_sorcerer.ncs differ diff --git a/_module/ncs/ai_taunter.ncs b/_module/ncs/ai_taunter.ncs index c8f5b71..5fd20c4 100644 Binary files a/_module/ncs/ai_taunter.ncs and b/_module/ncs/ai_taunter.ncs differ diff --git a/_module/ncs/ai_wizard.ncs b/_module/ncs/ai_wizard.ncs index 404c2f8..22b7cf9 100644 Binary files a/_module/ncs/ai_wizard.ncs and b/_module/ncs/ai_wizard.ncs differ diff --git a/_module/ncs/at_004.ncs b/_module/ncs/at_004.ncs index c46634c..d00611e 100644 Binary files a/_module/ncs/at_004.ncs and b/_module/ncs/at_004.ncs differ diff --git a/_module/ncs/attackhouse1.ncs b/_module/ncs/attackhouse1.ncs index b065238..61a5fd5 100644 Binary files a/_module/ncs/attackhouse1.ncs and b/_module/ncs/attackhouse1.ncs differ diff --git a/_module/ncs/attackhouse2.ncs b/_module/ncs/attackhouse2.ncs index 01f99df..c7d2216 100644 Binary files a/_module/ncs/attackhouse2.ncs and b/_module/ncs/attackhouse2.ncs differ diff --git a/_module/ncs/attackhouse3.ncs b/_module/ncs/attackhouse3.ncs index b130ea4..cd7dc49 100644 Binary files a/_module/ncs/attackhouse3.ncs and b/_module/ncs/attackhouse3.ncs differ diff --git a/_module/ncs/attackhouse4.ncs b/_module/ncs/attackhouse4.ncs index 6bb78e8..b1c7b12 100644 Binary files a/_module/ncs/attackhouse4.ncs and b/_module/ncs/attackhouse4.ncs differ diff --git a/_module/ncs/attackhouse5.ncs b/_module/ncs/attackhouse5.ncs index db69cbc..e94668f 100644 Binary files a/_module/ncs/attackhouse5.ncs and b/_module/ncs/attackhouse5.ncs differ diff --git a/_module/ncs/calc_hs_var.ncs b/_module/ncs/calc_hs_var.ncs index 1335639..df43bc0 100644 Binary files a/_module/ncs/calc_hs_var.ncs and b/_module/ncs/calc_hs_var.ncs differ diff --git a/_module/ncs/combatroundend.ncs b/_module/ncs/combatroundend.ncs index c3fe82e..4c4b109 100644 Binary files a/_module/ncs/combatroundend.ncs and b/_module/ncs/combatroundend.ncs differ diff --git a/_module/ncs/finalloot.ncs b/_module/ncs/finalloot.ncs index c4ab675..70db061 100644 Binary files a/_module/ncs/finalloot.ncs and b/_module/ncs/finalloot.ncs differ diff --git a/_module/ncs/gateannounce.ncs b/_module/ncs/gateannounce.ncs index 0400b53..11296d4 100644 Binary files a/_module/ncs/gateannounce.ncs and b/_module/ncs/gateannounce.ncs differ diff --git a/_module/ncs/goblinattack.ncs b/_module/ncs/goblinattack.ncs index c46634c..d00611e 100644 Binary files a/_module/ncs/goblinattack.ncs and b/_module/ncs/goblinattack.ncs differ diff --git a/_module/ncs/goblinfarm.ncs b/_module/ncs/goblinfarm.ncs index b2da35f..7dc2133 100644 Binary files a/_module/ncs/goblinfarm.ncs and b/_module/ncs/goblinfarm.ncs differ diff --git a/_module/ncs/hbrove1.ncs b/_module/ncs/hbrove1.ncs index d3521e2..fec27c4 100644 Binary files a/_module/ncs/hbrove1.ncs and b/_module/ncs/hbrove1.ncs differ diff --git a/_module/ncs/hbrove1attack.ncs b/_module/ncs/hbrove1attack.ncs index 2aa26b9..bb5e9dc 100644 Binary files a/_module/ncs/hbrove1attack.ncs and b/_module/ncs/hbrove1attack.ncs differ diff --git a/_module/ncs/hbrove2.ncs b/_module/ncs/hbrove2.ncs index 44475b8..529961e 100644 Binary files a/_module/ncs/hbrove2.ncs and b/_module/ncs/hbrove2.ncs differ diff --git a/_module/ncs/hbrove2attack.ncs b/_module/ncs/hbrove2attack.ncs index d36f7a8..fcc5515 100644 Binary files a/_module/ncs/hbrove2attack.ncs and b/_module/ncs/hbrove2attack.ncs differ diff --git a/_module/ncs/hiddenchest.ncs b/_module/ncs/hiddenchest.ncs index e73cece..e7f22c2 100644 Binary files a/_module/ncs/hiddenchest.ncs and b/_module/ncs/hiddenchest.ncs differ diff --git a/_module/ncs/hiddenloot.ncs b/_module/ncs/hiddenloot.ncs index a4c094d..6d6e1bb 100644 Binary files a/_module/ncs/hiddenloot.ncs and b/_module/ncs/hiddenloot.ncs differ diff --git a/_module/ncs/ho_lvlup_pc.ncs b/_module/ncs/ho_lvlup_pc.ncs index 6129a2b..3da8ad6 100644 Binary files a/_module/ncs/ho_lvlup_pc.ncs and b/_module/ncs/ho_lvlup_pc.ncs differ diff --git a/_module/ncs/horde_onmodload.ncs b/_module/ncs/horde_onmodload.ncs index eeaeda8..91daf8f 100644 Binary files a/_module/ncs/horde_onmodload.ncs and b/_module/ncs/horde_onmodload.ncs differ diff --git a/_module/ncs/intro.ncs b/_module/ncs/intro.ncs index 860258b..1676d93 100644 Binary files a/_module/ncs/intro.ncs and b/_module/ncs/intro.ncs differ diff --git a/_module/ncs/intro2.ncs b/_module/ncs/intro2.ncs index 7244739..26e5805 100644 Binary files a/_module/ncs/intro2.ncs and b/_module/ncs/intro2.ncs differ diff --git a/_module/ncs/introstart.ncs b/_module/ncs/introstart.ncs index a4cba59..b6988ca 100644 Binary files a/_module/ncs/introstart.ncs and b/_module/ncs/introstart.ncs differ diff --git a/_module/ncs/mm_prc_spells.ncs b/_module/ncs/mm_prc_spells.ncs index eff6029..a2a65a5 100644 Binary files a/_module/ncs/mm_prc_spells.ncs and b/_module/ncs/mm_prc_spells.ncs differ diff --git a/_module/ncs/movetoop10.ncs b/_module/ncs/movetoop10.ncs index 99aeae1..c88853c 100644 Binary files a/_module/ncs/movetoop10.ncs and b/_module/ncs/movetoop10.ncs differ diff --git a/_module/ncs/movetoop6.ncs b/_module/ncs/movetoop6.ncs index fa6bb73..a8252d8 100644 Binary files a/_module/ncs/movetoop6.ncs and b/_module/ncs/movetoop6.ncs differ diff --git a/_module/ncs/movetoop7.ncs b/_module/ncs/movetoop7.ncs index 60d2e20..b24384c 100644 Binary files a/_module/ncs/movetoop7.ncs and b/_module/ncs/movetoop7.ncs differ diff --git a/_module/ncs/movetoop8.ncs b/_module/ncs/movetoop8.ncs index 2cbc8b7..8334ac6 100644 Binary files a/_module/ncs/movetoop8.ncs and b/_module/ncs/movetoop8.ncs differ diff --git a/_module/ncs/movetoop9.ncs b/_module/ncs/movetoop9.ncs index ca0bc89..f414e92 100644 Binary files a/_module/ncs/movetoop9.ncs and b/_module/ncs/movetoop9.ncs differ diff --git a/_module/ncs/nw_c2_bossdie.ncs b/_module/ncs/nw_c2_bossdie.ncs index cf6cbf6..a1996a4 100644 Binary files a/_module/ncs/nw_c2_bossdie.ncs and b/_module/ncs/nw_c2_bossdie.ncs differ diff --git a/_module/ncs/nw_c2_bossspawn.ncs b/_module/ncs/nw_c2_bossspawn.ncs index 715be82..7001e45 100644 Binary files a/_module/ncs/nw_c2_bossspawn.ncs and b/_module/ncs/nw_c2_bossspawn.ncs differ diff --git a/_module/ncs/nw_c2_default1.ncs b/_module/ncs/nw_c2_default1.ncs index 8a75e8f..3cd4c74 100644 Binary files a/_module/ncs/nw_c2_default1.ncs and b/_module/ncs/nw_c2_default1.ncs differ diff --git a/_module/ncs/nw_c2_default2.ncs b/_module/ncs/nw_c2_default2.ncs index 603f806..5ad704e 100644 Binary files a/_module/ncs/nw_c2_default2.ncs and b/_module/ncs/nw_c2_default2.ncs differ diff --git a/_module/ncs/nw_c2_default3.ncs b/_module/ncs/nw_c2_default3.ncs index 3c27f36..e559975 100644 Binary files a/_module/ncs/nw_c2_default3.ncs and b/_module/ncs/nw_c2_default3.ncs differ diff --git a/_module/ncs/nw_c2_default4.ncs b/_module/ncs/nw_c2_default4.ncs index ddb3945..14626cc 100644 Binary files a/_module/ncs/nw_c2_default4.ncs and b/_module/ncs/nw_c2_default4.ncs differ diff --git a/_module/ncs/nw_c2_default5.ncs b/_module/ncs/nw_c2_default5.ncs index 3c848e6..9d52b2d 100644 Binary files a/_module/ncs/nw_c2_default5.ncs and b/_module/ncs/nw_c2_default5.ncs differ diff --git a/_module/ncs/nw_c2_default6.ncs b/_module/ncs/nw_c2_default6.ncs index b71e606..6ec1b10 100644 Binary files a/_module/ncs/nw_c2_default6.ncs and b/_module/ncs/nw_c2_default6.ncs differ diff --git a/_module/ncs/nw_c2_default8.ncs b/_module/ncs/nw_c2_default8.ncs index 631a522..8036133 100644 Binary files a/_module/ncs/nw_c2_default8.ncs and b/_module/ncs/nw_c2_default8.ncs differ diff --git a/_module/ncs/nw_c2_defaultb.ncs b/_module/ncs/nw_c2_defaultb.ncs index 1afa53b..4ac42af 100644 Binary files a/_module/ncs/nw_c2_defaultb.ncs and b/_module/ncs/nw_c2_defaultb.ncs differ diff --git a/_module/ncs/nw_c2_defaulte.ncs b/_module/ncs/nw_c2_defaulte.ncs index db0e0b5..953e07b 100644 Binary files a/_module/ncs/nw_c2_defaulte.ncs and b/_module/ncs/nw_c2_defaulte.ncs differ diff --git a/_module/ncs/nw_ch_ac1.ncs b/_module/ncs/nw_ch_ac1.ncs index aab4dae..3534133 100644 Binary files a/_module/ncs/nw_ch_ac1.ncs and b/_module/ncs/nw_ch_ac1.ncs differ diff --git a/_module/ncs/nw_ch_ac2.ncs b/_module/ncs/nw_ch_ac2.ncs index b5e70e2..2929d1c 100644 Binary files a/_module/ncs/nw_ch_ac2.ncs and b/_module/ncs/nw_ch_ac2.ncs differ diff --git a/_module/ncs/nw_ch_ac3.ncs b/_module/ncs/nw_ch_ac3.ncs index 9125c61..4392b31 100644 Binary files a/_module/ncs/nw_ch_ac3.ncs and b/_module/ncs/nw_ch_ac3.ncs differ diff --git a/_module/ncs/nw_ch_ac4.ncs b/_module/ncs/nw_ch_ac4.ncs index 8630808..e6248b0 100644 Binary files a/_module/ncs/nw_ch_ac4.ncs and b/_module/ncs/nw_ch_ac4.ncs differ diff --git a/_module/ncs/nw_ch_ac5.ncs b/_module/ncs/nw_ch_ac5.ncs index 4e6b5a8..35de089 100644 Binary files a/_module/ncs/nw_ch_ac5.ncs and b/_module/ncs/nw_ch_ac5.ncs differ diff --git a/_module/ncs/nw_ch_ac6.ncs b/_module/ncs/nw_ch_ac6.ncs index 10f3f1f..aedf00e 100644 Binary files a/_module/ncs/nw_ch_ac6.ncs and b/_module/ncs/nw_ch_ac6.ncs differ diff --git a/_module/ncs/nw_ch_aca.ncs b/_module/ncs/nw_ch_aca.ncs index d5ad0b4..7dc0caf 100644 Binary files a/_module/ncs/nw_ch_aca.ncs and b/_module/ncs/nw_ch_aca.ncs differ diff --git a/_module/ncs/nw_ch_acb.ncs b/_module/ncs/nw_ch_acb.ncs index d2a2d61..3d57e9b 100644 Binary files a/_module/ncs/nw_ch_acb.ncs and b/_module/ncs/nw_ch_acb.ncs differ diff --git a/_module/ncs/nw_ch_ace.ncs b/_module/ncs/nw_ch_ace.ncs index 7ed9d64..29d75f3 100644 Binary files a/_module/ncs/nw_ch_ace.ncs and b/_module/ncs/nw_ch_ace.ncs differ diff --git a/_module/ncs/nw_o2_boss.ncs b/_module/ncs/nw_o2_boss.ncs index 371c149..586fa99 100644 Binary files a/_module/ncs/nw_o2_boss.ncs and b/_module/ncs/nw_o2_boss.ncs differ diff --git a/_module/ncs/nw_o2_generalhig.ncs b/_module/ncs/nw_o2_generalhig.ncs index 4088ba7..5bbe734 100644 Binary files a/_module/ncs/nw_o2_generalhig.ncs and b/_module/ncs/nw_o2_generalhig.ncs differ diff --git a/_module/ncs/nw_o2_generallow.ncs b/_module/ncs/nw_o2_generallow.ncs index db90211..72b50dc 100644 Binary files a/_module/ncs/nw_o2_generallow.ncs and b/_module/ncs/nw_o2_generallow.ncs differ diff --git a/_module/ncs/nw_o2_generalmed.ncs b/_module/ncs/nw_o2_generalmed.ncs index ed7ed2d..2fec0ac 100644 Binary files a/_module/ncs/nw_o2_generalmed.ncs and b/_module/ncs/nw_o2_generalmed.ncs differ diff --git a/_module/ncs/nw_s1_aurablnda.ncs b/_module/ncs/nw_s1_aurablnda.ncs index a19678c..8eb2136 100644 Binary files a/_module/ncs/nw_s1_aurablnda.ncs and b/_module/ncs/nw_s1_aurablnda.ncs differ diff --git a/_module/ncs/nw_s1_auracoldc.ncs b/_module/ncs/nw_s1_auracoldc.ncs index 152a045..f3d57e6 100644 Binary files a/_module/ncs/nw_s1_auracoldc.ncs and b/_module/ncs/nw_s1_auracoldc.ncs differ diff --git a/_module/ncs/nw_s1_auraelecc.ncs b/_module/ncs/nw_s1_auraelecc.ncs index 2d2a639..1a7eb25 100644 Binary files a/_module/ncs/nw_s1_auraelecc.ncs and b/_module/ncs/nw_s1_auraelecc.ncs differ diff --git a/_module/ncs/nw_s1_aurafirec.ncs b/_module/ncs/nw_s1_aurafirec.ncs index 5c7d001..56ab9ea 100644 Binary files a/_module/ncs/nw_s1_aurafirec.ncs and b/_module/ncs/nw_s1_aurafirec.ncs differ diff --git a/_module/ncs/nw_s1_auramenca.ncs b/_module/ncs/nw_s1_auramenca.ncs index 44d0509..9d92eb9 100644 Binary files a/_module/ncs/nw_s1_auramenca.ncs and b/_module/ncs/nw_s1_auramenca.ncs differ diff --git a/_module/ncs/nw_s1_aurastuna.ncs b/_module/ncs/nw_s1_aurastuna.ncs index 2fb195e..c47d1c0 100644 Binary files a/_module/ncs/nw_s1_aurastuna.ncs and b/_module/ncs/nw_s1_aurastuna.ncs differ diff --git a/_module/ncs/nw_s1_aurauneaa.ncs b/_module/ncs/nw_s1_aurauneaa.ncs index d6b248d..3141e0d 100644 Binary files a/_module/ncs/nw_s1_aurauneaa.ncs and b/_module/ncs/nw_s1_aurauneaa.ncs differ diff --git a/_module/ncs/nw_s1_bltacid.ncs b/_module/ncs/nw_s1_bltacid.ncs index 6240303..71cf5b0 100644 Binary files a/_module/ncs/nw_s1_bltacid.ncs and b/_module/ncs/nw_s1_bltacid.ncs differ diff --git a/_module/ncs/nw_s1_bltcharm.ncs b/_module/ncs/nw_s1_bltcharm.ncs index 9c21fa0..07be62b 100644 Binary files a/_module/ncs/nw_s1_bltcharm.ncs and b/_module/ncs/nw_s1_bltcharm.ncs differ diff --git a/_module/ncs/nw_s1_bltchrdr.ncs b/_module/ncs/nw_s1_bltchrdr.ncs index acd59bf..75cc5f6 100644 Binary files a/_module/ncs/nw_s1_bltchrdr.ncs and b/_module/ncs/nw_s1_bltchrdr.ncs differ diff --git a/_module/ncs/nw_s1_bltcold.ncs b/_module/ncs/nw_s1_bltcold.ncs index 4f8c653..e353005 100644 Binary files a/_module/ncs/nw_s1_bltcold.ncs and b/_module/ncs/nw_s1_bltcold.ncs differ diff --git a/_module/ncs/nw_s1_bltcondr.ncs b/_module/ncs/nw_s1_bltcondr.ncs index f2ab27b..c02d0a2 100644 Binary files a/_module/ncs/nw_s1_bltcondr.ncs and b/_module/ncs/nw_s1_bltcondr.ncs differ diff --git a/_module/ncs/nw_s1_bltconf.ncs b/_module/ncs/nw_s1_bltconf.ncs index a467544..e92ba81 100644 Binary files a/_module/ncs/nw_s1_bltconf.ncs and b/_module/ncs/nw_s1_bltconf.ncs differ diff --git a/_module/ncs/nw_s1_bltdaze.ncs b/_module/ncs/nw_s1_bltdaze.ncs index 7d5576b..601a16f 100644 Binary files a/_module/ncs/nw_s1_bltdaze.ncs and b/_module/ncs/nw_s1_bltdaze.ncs differ diff --git a/_module/ncs/nw_s1_bltdeath.ncs b/_module/ncs/nw_s1_bltdeath.ncs index 30c0903..29c535b 100644 Binary files a/_module/ncs/nw_s1_bltdeath.ncs and b/_module/ncs/nw_s1_bltdeath.ncs differ diff --git a/_module/ncs/nw_s1_bltdexdr.ncs b/_module/ncs/nw_s1_bltdexdr.ncs index d24f3b1..8022633 100644 Binary files a/_module/ncs/nw_s1_bltdexdr.ncs and b/_module/ncs/nw_s1_bltdexdr.ncs differ diff --git a/_module/ncs/nw_s1_bltdisese.ncs b/_module/ncs/nw_s1_bltdisese.ncs index 235ff8c..c4305e6 100644 Binary files a/_module/ncs/nw_s1_bltdisese.ncs and b/_module/ncs/nw_s1_bltdisese.ncs differ diff --git a/_module/ncs/nw_s1_bltdomn.ncs b/_module/ncs/nw_s1_bltdomn.ncs index 2fe5dca..d3fe494 100644 Binary files a/_module/ncs/nw_s1_bltdomn.ncs and b/_module/ncs/nw_s1_bltdomn.ncs differ diff --git a/_module/ncs/nw_s1_bltfire.ncs b/_module/ncs/nw_s1_bltfire.ncs index 082e286..112ce2f 100644 Binary files a/_module/ncs/nw_s1_bltfire.ncs and b/_module/ncs/nw_s1_bltfire.ncs differ diff --git a/_module/ncs/nw_s1_bltintdr.ncs b/_module/ncs/nw_s1_bltintdr.ncs index 7cd3302..e67d642 100644 Binary files a/_module/ncs/nw_s1_bltintdr.ncs and b/_module/ncs/nw_s1_bltintdr.ncs differ diff --git a/_module/ncs/nw_s1_bltknckd.ncs b/_module/ncs/nw_s1_bltknckd.ncs index b2e85ed..2d42de1 100644 Binary files a/_module/ncs/nw_s1_bltknckd.ncs and b/_module/ncs/nw_s1_bltknckd.ncs differ diff --git a/_module/ncs/nw_s1_bltlightn.ncs b/_module/ncs/nw_s1_bltlightn.ncs index 91d2c19..7eb3865 100644 Binary files a/_module/ncs/nw_s1_bltlightn.ncs and b/_module/ncs/nw_s1_bltlightn.ncs differ diff --git a/_module/ncs/nw_s1_bltlvldr.ncs b/_module/ncs/nw_s1_bltlvldr.ncs index 1efa5d4..f264014 100644 Binary files a/_module/ncs/nw_s1_bltlvldr.ncs and b/_module/ncs/nw_s1_bltlvldr.ncs differ diff --git a/_module/ncs/nw_s1_bltparal.ncs b/_module/ncs/nw_s1_bltparal.ncs index 5a38337..91d35ec 100644 Binary files a/_module/ncs/nw_s1_bltparal.ncs and b/_module/ncs/nw_s1_bltparal.ncs differ diff --git a/_module/ncs/nw_s1_bltpoison.ncs b/_module/ncs/nw_s1_bltpoison.ncs index 7772100..e61fba1 100644 Binary files a/_module/ncs/nw_s1_bltpoison.ncs and b/_module/ncs/nw_s1_bltpoison.ncs differ diff --git a/_module/ncs/nw_s1_bltshards.ncs b/_module/ncs/nw_s1_bltshards.ncs index 3ec4054..66e1106 100644 Binary files a/_module/ncs/nw_s1_bltshards.ncs and b/_module/ncs/nw_s1_bltshards.ncs differ diff --git a/_module/ncs/nw_s1_bltslow.ncs b/_module/ncs/nw_s1_bltslow.ncs index 251f8ab..07aae6b 100644 Binary files a/_module/ncs/nw_s1_bltslow.ncs and b/_module/ncs/nw_s1_bltslow.ncs differ diff --git a/_module/ncs/nw_s1_bltstrdr.ncs b/_module/ncs/nw_s1_bltstrdr.ncs index c707a7d..3c45945 100644 Binary files a/_module/ncs/nw_s1_bltstrdr.ncs and b/_module/ncs/nw_s1_bltstrdr.ncs differ diff --git a/_module/ncs/nw_s1_bltstun.ncs b/_module/ncs/nw_s1_bltstun.ncs index d6e66a4..f56a4d4 100644 Binary files a/_module/ncs/nw_s1_bltstun.ncs and b/_module/ncs/nw_s1_bltstun.ncs differ diff --git a/_module/ncs/nw_s1_bltweb.ncs b/_module/ncs/nw_s1_bltweb.ncs index d2017d8..af9ae1d 100644 Binary files a/_module/ncs/nw_s1_bltweb.ncs and b/_module/ncs/nw_s1_bltweb.ncs differ diff --git a/_module/ncs/nw_s1_bltwisdr.ncs b/_module/ncs/nw_s1_bltwisdr.ncs index b47dbab..6343d42 100644 Binary files a/_module/ncs/nw_s1_bltwisdr.ncs and b/_module/ncs/nw_s1_bltwisdr.ncs differ diff --git a/_module/ncs/nw_s1_coneacid.ncs b/_module/ncs/nw_s1_coneacid.ncs index 07a285f..dbac089 100644 Binary files a/_module/ncs/nw_s1_coneacid.ncs and b/_module/ncs/nw_s1_coneacid.ncs differ diff --git a/_module/ncs/nw_s1_conecold.ncs b/_module/ncs/nw_s1_conecold.ncs index 5bfea21..7bc6839 100644 Binary files a/_module/ncs/nw_s1_conecold.ncs and b/_module/ncs/nw_s1_conecold.ncs differ diff --git a/_module/ncs/nw_s1_coneelec.ncs b/_module/ncs/nw_s1_coneelec.ncs index a4e18ef..e6f88d6 100644 Binary files a/_module/ncs/nw_s1_coneelec.ncs and b/_module/ncs/nw_s1_coneelec.ncs differ diff --git a/_module/ncs/nw_s1_conesonic.ncs b/_module/ncs/nw_s1_conesonic.ncs index 9342f95..37fdb27 100644 Binary files a/_module/ncs/nw_s1_conesonic.ncs and b/_module/ncs/nw_s1_conesonic.ncs differ diff --git a/_module/ncs/nw_s1_dragfear.ncs b/_module/ncs/nw_s1_dragfear.ncs index aa31ccb..737c812 100644 Binary files a/_module/ncs/nw_s1_dragfear.ncs and b/_module/ncs/nw_s1_dragfear.ncs differ diff --git a/_module/ncs/nw_s1_dragfeara.ncs b/_module/ncs/nw_s1_dragfeara.ncs index fc31f1a..02f1182 100644 Binary files a/_module/ncs/nw_s1_dragfeara.ncs and b/_module/ncs/nw_s1_dragfeara.ncs differ diff --git a/_module/ncs/nw_s1_gazechaos.ncs b/_module/ncs/nw_s1_gazechaos.ncs index 136c2c1..ac8153a 100644 Binary files a/_module/ncs/nw_s1_gazechaos.ncs and b/_module/ncs/nw_s1_gazechaos.ncs differ diff --git a/_module/ncs/nw_s1_gazecharm.ncs b/_module/ncs/nw_s1_gazecharm.ncs index a5e428f..f4c1f8b 100644 Binary files a/_module/ncs/nw_s1_gazecharm.ncs and b/_module/ncs/nw_s1_gazecharm.ncs differ diff --git a/_module/ncs/nw_s1_gazeconfu.ncs b/_module/ncs/nw_s1_gazeconfu.ncs index 7098a7b..0079267 100644 Binary files a/_module/ncs/nw_s1_gazeconfu.ncs and b/_module/ncs/nw_s1_gazeconfu.ncs differ diff --git a/_module/ncs/nw_s1_gazedaze.ncs b/_module/ncs/nw_s1_gazedaze.ncs index cec80ee..12e9f71 100644 Binary files a/_module/ncs/nw_s1_gazedaze.ncs and b/_module/ncs/nw_s1_gazedaze.ncs differ diff --git a/_module/ncs/nw_s1_gazedeath.ncs b/_module/ncs/nw_s1_gazedeath.ncs index dc871c4..07fd108 100644 Binary files a/_module/ncs/nw_s1_gazedeath.ncs and b/_module/ncs/nw_s1_gazedeath.ncs differ diff --git a/_module/ncs/nw_s1_gazedomn.ncs b/_module/ncs/nw_s1_gazedomn.ncs index 89377d4..006e39e 100644 Binary files a/_module/ncs/nw_s1_gazedomn.ncs and b/_module/ncs/nw_s1_gazedomn.ncs differ diff --git a/_module/ncs/nw_s1_gazedoom.ncs b/_module/ncs/nw_s1_gazedoom.ncs index 3299989..0c44c0e 100644 Binary files a/_module/ncs/nw_s1_gazedoom.ncs and b/_module/ncs/nw_s1_gazedoom.ncs differ diff --git a/_module/ncs/nw_s1_gazeevil.ncs b/_module/ncs/nw_s1_gazeevil.ncs index 09b4c76..1ca1826 100644 Binary files a/_module/ncs/nw_s1_gazeevil.ncs and b/_module/ncs/nw_s1_gazeevil.ncs differ diff --git a/_module/ncs/nw_s1_gazefear.ncs b/_module/ncs/nw_s1_gazefear.ncs index 730c9d4..626a403 100644 Binary files a/_module/ncs/nw_s1_gazefear.ncs and b/_module/ncs/nw_s1_gazefear.ncs differ diff --git a/_module/ncs/nw_s1_gazegood.ncs b/_module/ncs/nw_s1_gazegood.ncs index 364717b..a2b6985 100644 Binary files a/_module/ncs/nw_s1_gazegood.ncs and b/_module/ncs/nw_s1_gazegood.ncs differ diff --git a/_module/ncs/nw_s1_gazelaw.ncs b/_module/ncs/nw_s1_gazelaw.ncs index 6dd6d43..9a9ae20 100644 Binary files a/_module/ncs/nw_s1_gazelaw.ncs and b/_module/ncs/nw_s1_gazelaw.ncs differ diff --git a/_module/ncs/nw_s1_gazestun.ncs b/_module/ncs/nw_s1_gazestun.ncs index ffa7ed2..c7f6c10 100644 Binary files a/_module/ncs/nw_s1_gazestun.ncs and b/_module/ncs/nw_s1_gazestun.ncs differ diff --git a/_module/ncs/nw_s1_hndbreath.ncs b/_module/ncs/nw_s1_hndbreath.ncs index b1b180c..4d18c31 100644 Binary files a/_module/ncs/nw_s1_hndbreath.ncs and b/_module/ncs/nw_s1_hndbreath.ncs differ diff --git a/_module/ncs/nw_s1_howlconf.ncs b/_module/ncs/nw_s1_howlconf.ncs index 2fcc2d0..cf35567 100644 Binary files a/_module/ncs/nw_s1_howlconf.ncs and b/_module/ncs/nw_s1_howlconf.ncs differ diff --git a/_module/ncs/nw_s1_howldaze.ncs b/_module/ncs/nw_s1_howldaze.ncs index 24b6054..6d49192 100644 Binary files a/_module/ncs/nw_s1_howldaze.ncs and b/_module/ncs/nw_s1_howldaze.ncs differ diff --git a/_module/ncs/nw_s1_howldeath.ncs b/_module/ncs/nw_s1_howldeath.ncs index 1cb223d..477997d 100644 Binary files a/_module/ncs/nw_s1_howldeath.ncs and b/_module/ncs/nw_s1_howldeath.ncs differ diff --git a/_module/ncs/nw_s1_howlfear.ncs b/_module/ncs/nw_s1_howlfear.ncs index 4625b40..36d1159 100644 Binary files a/_module/ncs/nw_s1_howlfear.ncs and b/_module/ncs/nw_s1_howlfear.ncs differ diff --git a/_module/ncs/nw_s1_howlparal.ncs b/_module/ncs/nw_s1_howlparal.ncs index cd7da61..bdb56c5 100644 Binary files a/_module/ncs/nw_s1_howlparal.ncs and b/_module/ncs/nw_s1_howlparal.ncs differ diff --git a/_module/ncs/nw_s1_howlsonic.ncs b/_module/ncs/nw_s1_howlsonic.ncs index 8d0b33a..121bc04 100644 Binary files a/_module/ncs/nw_s1_howlsonic.ncs and b/_module/ncs/nw_s1_howlsonic.ncs differ diff --git a/_module/ncs/nw_s1_howlstun.ncs b/_module/ncs/nw_s1_howlstun.ncs index a12f4bd..665b6cd 100644 Binary files a/_module/ncs/nw_s1_howlstun.ncs and b/_module/ncs/nw_s1_howlstun.ncs differ diff --git a/_module/ncs/nw_s1_krenscare.ncs b/_module/ncs/nw_s1_krenscare.ncs index 072906d..2f4fcee 100644 Binary files a/_module/ncs/nw_s1_krenscare.ncs and b/_module/ncs/nw_s1_krenscare.ncs differ diff --git a/_module/ncs/nw_s1_mephsalt.ncs b/_module/ncs/nw_s1_mephsalt.ncs index aac314b..22d2258 100644 Binary files a/_module/ncs/nw_s1_mephsalt.ncs and b/_module/ncs/nw_s1_mephsalt.ncs differ diff --git a/_module/ncs/nw_s1_mephsteam.ncs b/_module/ncs/nw_s1_mephsteam.ncs index e494e7d..0f3078c 100644 Binary files a/_module/ncs/nw_s1_mephsteam.ncs and b/_module/ncs/nw_s1_mephsteam.ncs differ diff --git a/_module/ncs/nw_s1_pulschrdr.ncs b/_module/ncs/nw_s1_pulschrdr.ncs index 64cff89..3d8770a 100644 Binary files a/_module/ncs/nw_s1_pulschrdr.ncs and b/_module/ncs/nw_s1_pulschrdr.ncs differ diff --git a/_module/ncs/nw_s1_pulscold.ncs b/_module/ncs/nw_s1_pulscold.ncs index 4643e6c..c89ae1c 100644 Binary files a/_module/ncs/nw_s1_pulscold.ncs and b/_module/ncs/nw_s1_pulscold.ncs differ diff --git a/_module/ncs/nw_s1_pulscondr.ncs b/_module/ncs/nw_s1_pulscondr.ncs index dabf3fb..e34bd8e 100644 Binary files a/_module/ncs/nw_s1_pulscondr.ncs and b/_module/ncs/nw_s1_pulscondr.ncs differ diff --git a/_module/ncs/nw_s1_pulsdeath.ncs b/_module/ncs/nw_s1_pulsdeath.ncs index ba1d358..a68fbc0 100644 Binary files a/_module/ncs/nw_s1_pulsdeath.ncs and b/_module/ncs/nw_s1_pulsdeath.ncs differ diff --git a/_module/ncs/nw_s1_pulsdexdr.ncs b/_module/ncs/nw_s1_pulsdexdr.ncs index cc7aa77..4017889 100644 Binary files a/_module/ncs/nw_s1_pulsdexdr.ncs and b/_module/ncs/nw_s1_pulsdexdr.ncs differ diff --git a/_module/ncs/nw_s1_pulselec.ncs b/_module/ncs/nw_s1_pulselec.ncs index f157eea..a6da792 100644 Binary files a/_module/ncs/nw_s1_pulselec.ncs and b/_module/ncs/nw_s1_pulselec.ncs differ diff --git a/_module/ncs/nw_s1_pulsfire.ncs b/_module/ncs/nw_s1_pulsfire.ncs index 92ad1a3..8010551 100644 Binary files a/_module/ncs/nw_s1_pulsfire.ncs and b/_module/ncs/nw_s1_pulsfire.ncs differ diff --git a/_module/ncs/nw_s1_pulsholy.ncs b/_module/ncs/nw_s1_pulsholy.ncs index 65123e1..6847904 100644 Binary files a/_module/ncs/nw_s1_pulsholy.ncs and b/_module/ncs/nw_s1_pulsholy.ncs differ diff --git a/_module/ncs/nw_s1_pulsintdr.ncs b/_module/ncs/nw_s1_pulsintdr.ncs index 5de23e1..adb4194 100644 Binary files a/_module/ncs/nw_s1_pulsintdr.ncs and b/_module/ncs/nw_s1_pulsintdr.ncs differ diff --git a/_module/ncs/nw_s1_pulslvldr.ncs b/_module/ncs/nw_s1_pulslvldr.ncs index 0599841..14f5db6 100644 Binary files a/_module/ncs/nw_s1_pulslvldr.ncs and b/_module/ncs/nw_s1_pulslvldr.ncs differ diff --git a/_module/ncs/nw_s1_pulsneg.ncs b/_module/ncs/nw_s1_pulsneg.ncs index 30beae8..299e67b 100644 Binary files a/_module/ncs/nw_s1_pulsneg.ncs and b/_module/ncs/nw_s1_pulsneg.ncs differ diff --git a/_module/ncs/nw_s1_pulsstrdr.ncs b/_module/ncs/nw_s1_pulsstrdr.ncs index adef4b8..e462589 100644 Binary files a/_module/ncs/nw_s1_pulsstrdr.ncs and b/_module/ncs/nw_s1_pulsstrdr.ncs differ diff --git a/_module/ncs/nw_s1_pulswind.ncs b/_module/ncs/nw_s1_pulswind.ncs index 5d7e5a8..d465597 100644 Binary files a/_module/ncs/nw_s1_pulswind.ncs and b/_module/ncs/nw_s1_pulswind.ncs differ diff --git a/_module/ncs/nw_s1_pulswisdr.ncs b/_module/ncs/nw_s1_pulswisdr.ncs index 0f4d8c8..07f3328 100644 Binary files a/_module/ncs/nw_s1_pulswisdr.ncs and b/_module/ncs/nw_s1_pulswisdr.ncs differ diff --git a/_module/ncs/nw_s1_smokeclaw.ncs b/_module/ncs/nw_s1_smokeclaw.ncs index 84e49f9..7a3090b 100644 Binary files a/_module/ncs/nw_s1_smokeclaw.ncs and b/_module/ncs/nw_s1_smokeclaw.ncs differ diff --git a/_module/ncs/nw_s1_stink_a.ncs b/_module/ncs/nw_s1_stink_a.ncs index 62cbc7f..51c84ef 100644 Binary files a/_module/ncs/nw_s1_stink_a.ncs and b/_module/ncs/nw_s1_stink_a.ncs differ diff --git a/_module/ncs/nw_s1_tyrantfga.ncs b/_module/ncs/nw_s1_tyrantfga.ncs index 6fbf604..75a0fcd 100644 Binary files a/_module/ncs/nw_s1_tyrantfga.ncs and b/_module/ncs/nw_s1_tyrantfga.ncs differ diff --git a/_module/ncs/nw_s2_divprot.ncs b/_module/ncs/nw_s2_divprot.ncs index 68e7d06..0418cac 100644 Binary files a/_module/ncs/nw_s2_divprot.ncs and b/_module/ncs/nw_s2_divprot.ncs differ diff --git a/_module/ncs/nw_s3_balordeth.ncs b/_module/ncs/nw_s3_balordeth.ncs index fed3ab0..3fb8fcf 100644 Binary files a/_module/ncs/nw_s3_balordeth.ncs and b/_module/ncs/nw_s3_balordeth.ncs differ diff --git a/_module/ncs/oldmanhb.ncs b/_module/ncs/oldmanhb.ncs index 7cdcc12..d27d482 100644 Binary files a/_module/ncs/oldmanhb.ncs and b/_module/ncs/oldmanhb.ncs differ diff --git a/_module/ncs/onenter.ncs b/_module/ncs/onenter.ncs index db45d72..fa06858 100644 Binary files a/_module/ncs/onenter.ncs and b/_module/ncs/onenter.ncs differ diff --git a/_module/ncs/op10shaman.ncs b/_module/ncs/op10shaman.ncs index 2714942..b73c5e4 100644 Binary files a/_module/ncs/op10shaman.ncs and b/_module/ncs/op10shaman.ncs differ diff --git a/_module/ncs/op9shaman.ncs b/_module/ncs/op9shaman.ncs index 7b43749..c56c820 100644 Binary files a/_module/ncs/op9shaman.ncs and b/_module/ncs/op9shaman.ncs differ diff --git a/_module/ncs/pathfinding.ncs b/_module/ncs/pathfinding.ncs index 06a69e3..32a2f37 100644 Binary files a/_module/ncs/pathfinding.ncs and b/_module/ncs/pathfinding.ncs differ diff --git a/_module/ncs/pathfindingrun.ncs b/_module/ncs/pathfindingrun.ncs index edc1ebb..6cd08b1 100644 Binary files a/_module/ncs/pathfindingrun.ncs and b/_module/ncs/pathfindingrun.ncs differ diff --git a/_module/ncs/pathfindingscale.ncs b/_module/ncs/pathfindingscale.ncs index 1afb4ea..b5a93ca 100644 Binary files a/_module/ncs/pathfindingscale.ncs and b/_module/ncs/pathfindingscale.ncs differ diff --git a/_module/ncs/pc_savebuffs.ncs b/_module/ncs/pc_savebuffs.ncs index cb415d4..9441325 100644 Binary files a/_module/ncs/pc_savebuffs.ncs and b/_module/ncs/pc_savebuffs.ncs differ diff --git a/_module/ncs/pe_buffing.ncs b/_module/ncs/pe_buffing.ncs index f1564d4..3eaeaea 100644 Binary files a/_module/ncs/pe_buffing.ncs and b/_module/ncs/pe_buffing.ncs differ diff --git a/_module/ncs/pe_crafting.ncs b/_module/ncs/pe_crafting.ncs index 5d741a0..6f7cb01 100644 Binary files a/_module/ncs/pe_crafting.ncs and b/_module/ncs/pe_crafting.ncs differ diff --git a/_module/ncs/pe_henchmen.ncs b/_module/ncs/pe_henchmen.ncs index 7275c69..7f0271e 100644 Binary files a/_module/ncs/pe_henchmen.ncs and b/_module/ncs/pe_henchmen.ncs differ diff --git a/_module/ncs/pe_mod_set.ncs b/_module/ncs/pe_mod_set.ncs index ccab4da..5a09e7d 100644 Binary files a/_module/ncs/pe_mod_set.ncs and b/_module/ncs/pe_mod_set.ncs differ diff --git a/_module/ncs/pe_test.ncs b/_module/ncs/pe_test.ncs deleted file mode 100644 index 3fb5d40..0000000 Binary files a/_module/ncs/pe_test.ncs and /dev/null differ diff --git a/_module/ncs/pi_buffing.ncs b/_module/ncs/pi_buffing.ncs index c1a93e9..e654f65 100644 Binary files a/_module/ncs/pi_buffing.ncs and b/_module/ncs/pi_buffing.ncs differ diff --git a/_module/ncs/pi_crafting.ncs b/_module/ncs/pi_crafting.ncs index dc5627f..7ba191b 100644 Binary files a/_module/ncs/pi_crafting.ncs and b/_module/ncs/pi_crafting.ncs differ diff --git a/_module/ncs/pi_debug.ncs b/_module/ncs/pi_debug.ncs index 1d9a0ea..25f33de 100644 Binary files a/_module/ncs/pi_debug.ncs and b/_module/ncs/pi_debug.ncs differ diff --git a/_module/ncs/pi_forcerest.ncs b/_module/ncs/pi_forcerest.ncs index 3beda05..0466eb6 100644 Binary files a/_module/ncs/pi_forcerest.ncs and b/_module/ncs/pi_forcerest.ncs differ diff --git a/_module/ncs/pi_henchmen.ncs b/_module/ncs/pi_henchmen.ncs index ccaa01b..f9c4726 100644 Binary files a/_module/ncs/pi_henchmen.ncs and b/_module/ncs/pi_henchmen.ncs differ diff --git a/_module/ncs/pi_test.ncs b/_module/ncs/pi_test.ncs deleted file mode 100644 index 7d3ae06..0000000 Binary files a/_module/ncs/pi_test.ncs and /dev/null differ diff --git a/_module/ncs/releaseorc.ncs b/_module/ncs/releaseorc.ncs index 8ea5702..d63f90c 100644 Binary files a/_module/ncs/releaseorc.ncs and b/_module/ncs/releaseorc.ncs differ diff --git a/_module/ncs/returnop1.ncs b/_module/ncs/returnop1.ncs index b5d7995..ddf1bfc 100644 Binary files a/_module/ncs/returnop1.ncs and b/_module/ncs/returnop1.ncs differ diff --git a/_module/ncs/returnop10.ncs b/_module/ncs/returnop10.ncs index d6d92ad..955193f 100644 Binary files a/_module/ncs/returnop10.ncs and b/_module/ncs/returnop10.ncs differ diff --git a/_module/ncs/returnop10sham.ncs b/_module/ncs/returnop10sham.ncs index d995121..ff32ff9 100644 Binary files a/_module/ncs/returnop10sham.ncs and b/_module/ncs/returnop10sham.ncs differ diff --git a/_module/ncs/returnop2.ncs b/_module/ncs/returnop2.ncs index 7d27798..2ec453b 100644 Binary files a/_module/ncs/returnop2.ncs and b/_module/ncs/returnop2.ncs differ diff --git a/_module/ncs/returnop3.ncs b/_module/ncs/returnop3.ncs index badbbb1..9b8b5cc 100644 Binary files a/_module/ncs/returnop3.ncs and b/_module/ncs/returnop3.ncs differ diff --git a/_module/ncs/returnop4.ncs b/_module/ncs/returnop4.ncs index 4da7d17..39efbac 100644 Binary files a/_module/ncs/returnop4.ncs and b/_module/ncs/returnop4.ncs differ diff --git a/_module/ncs/returnop5.ncs b/_module/ncs/returnop5.ncs index 98a89b1..9de0b92 100644 Binary files a/_module/ncs/returnop5.ncs and b/_module/ncs/returnop5.ncs differ diff --git a/_module/ncs/returnop6.ncs b/_module/ncs/returnop6.ncs index 03039c3..2f3a1b9 100644 Binary files a/_module/ncs/returnop6.ncs and b/_module/ncs/returnop6.ncs differ diff --git a/_module/ncs/returnop7.ncs b/_module/ncs/returnop7.ncs index 89e3fd0..bec873d 100644 Binary files a/_module/ncs/returnop7.ncs and b/_module/ncs/returnop7.ncs differ diff --git a/_module/ncs/returnop8.ncs b/_module/ncs/returnop8.ncs index e9b5f71..7cf0ab3 100644 Binary files a/_module/ncs/returnop8.ncs and b/_module/ncs/returnop8.ncs differ diff --git a/_module/ncs/returnop9.ncs b/_module/ncs/returnop9.ncs index 3e35910..926f14d 100644 Binary files a/_module/ncs/returnop9.ncs and b/_module/ncs/returnop9.ncs differ diff --git a/_module/ncs/returnop9sham.ncs b/_module/ncs/returnop9sham.ncs index e597f4a..b5f4da6 100644 Binary files a/_module/ncs/returnop9sham.ncs and b/_module/ncs/returnop9sham.ncs differ diff --git a/_module/ncs/rove1.ncs b/_module/ncs/rove1.ncs index f6bf84c..d90a20d 100644 Binary files a/_module/ncs/rove1.ncs and b/_module/ncs/rove1.ncs differ diff --git a/_module/ncs/rove1attack.ncs b/_module/ncs/rove1attack.ncs index 7dcd676..d706075 100644 Binary files a/_module/ncs/rove1attack.ncs and b/_module/ncs/rove1attack.ncs differ diff --git a/_module/ncs/rove2.ncs b/_module/ncs/rove2.ncs index 9465358..3e93d30 100644 Binary files a/_module/ncs/rove2.ncs and b/_module/ncs/rove2.ncs differ diff --git a/_module/ncs/rove2attack.ncs b/_module/ncs/rove2attack.ncs index 3a164b9..c732a2e 100644 Binary files a/_module/ncs/rove2attack.ncs and b/_module/ncs/rove2attack.ncs differ diff --git a/_module/ncs/spawntreasure.ncs b/_module/ncs/spawntreasure.ncs index 82c6d1c..2bc8e6e 100644 Binary files a/_module/ncs/spawntreasure.ncs and b/_module/ncs/spawntreasure.ncs differ diff --git a/_module/ncs/trashcan.ncs b/_module/ncs/trashcan.ncs index 6efe44c..cb3a8c4 100644 Binary files a/_module/ncs/trashcan.ncs and b/_module/ncs/trashcan.ncs differ diff --git a/_module/ncs/x0_ch_hen_block.ncs b/_module/ncs/x0_ch_hen_block.ncs new file mode 100644 index 0000000..77b29b8 Binary files /dev/null and b/_module/ncs/x0_ch_hen_block.ncs differ diff --git a/_module/ncs/x0_ch_hen_combat.ncs b/_module/ncs/x0_ch_hen_combat.ncs new file mode 100644 index 0000000..12959ea Binary files /dev/null and b/_module/ncs/x0_ch_hen_combat.ncs differ diff --git a/_module/ncs/x0_ch_hen_conv.ncs b/_module/ncs/x0_ch_hen_conv.ncs new file mode 100644 index 0000000..2fda87c Binary files /dev/null and b/_module/ncs/x0_ch_hen_conv.ncs differ diff --git a/_module/ncs/x0_ch_hen_rest.ncs b/_module/ncs/x0_ch_hen_rest.ncs new file mode 100644 index 0000000..19d68e3 Binary files /dev/null and b/_module/ncs/x0_ch_hen_rest.ncs differ diff --git a/_module/ncs/xx_pc_1_hb.ncs b/_module/ncs/xx_pc_1_hb.ncs index 21caec3..f1feac4 100644 Binary files a/_module/ncs/xx_pc_1_hb.ncs and b/_module/ncs/xx_pc_1_hb.ncs differ diff --git a/_module/ncs/xx_pc_2_percept.ncs b/_module/ncs/xx_pc_2_percept.ncs index 908ca7e..cf5b2e8 100644 Binary files a/_module/ncs/xx_pc_2_percept.ncs and b/_module/ncs/xx_pc_2_percept.ncs differ diff --git a/_module/ncs/xx_pc_3_endround.ncs b/_module/ncs/xx_pc_3_endround.ncs index 2acc6c0..6002996 100644 Binary files a/_module/ncs/xx_pc_3_endround.ncs and b/_module/ncs/xx_pc_3_endround.ncs differ diff --git a/_module/ncs/xx_pc_4_convers.ncs b/_module/ncs/xx_pc_4_convers.ncs index c63ea38..6b3e206 100644 Binary files a/_module/ncs/xx_pc_4_convers.ncs and b/_module/ncs/xx_pc_4_convers.ncs differ diff --git a/_module/ncs/xx_pc_5_phyatked.ncs b/_module/ncs/xx_pc_5_phyatked.ncs index 9136c2b..59fc6ee 100644 Binary files a/_module/ncs/xx_pc_5_phyatked.ncs and b/_module/ncs/xx_pc_5_phyatked.ncs differ diff --git a/_module/ncs/xx_pc_6_damaged.ncs b/_module/ncs/xx_pc_6_damaged.ncs index 0ee0511..619825e 100644 Binary files a/_module/ncs/xx_pc_6_damaged.ncs and b/_module/ncs/xx_pc_6_damaged.ncs differ diff --git a/_module/ncs/xx_pc_b_castat.ncs b/_module/ncs/xx_pc_b_castat.ncs index b9b5108..136f51f 100644 Binary files a/_module/ncs/xx_pc_b_castat.ncs and b/_module/ncs/xx_pc_b_castat.ncs differ diff --git a/_module/ncs/xx_pc_e_blocked.ncs b/_module/ncs/xx_pc_e_blocked.ncs index 009f816..35b29c3 100644 Binary files a/_module/ncs/xx_pc_e_blocked.ncs and b/_module/ncs/xx_pc_e_blocked.ncs differ diff --git a/_module/nss/0e_c2_7_ondeath.nss b/_module/nss/0e_c2_7_ondeath.nss index 129e81e..7d9570e 100644 --- a/_module/nss/0e_c2_7_ondeath.nss +++ b/_module/nss/0e_c2_7_ondeath.nss @@ -11,17 +11,19 @@ void main() object oCreature = OBJECT_SELF; // Added code to allow for permanent associates in the battle! object oModule = GetModule(); + if(AI_DEBUG) ai_Debug("0e_c2_7_ondeath", "14", "AI_RULE_PERM_ASSOC: " + IntToString(GetLocalInt(oModule, AI_RULE_PERM_ASSOC))); if(GetLocalInt(oModule, AI_RULE_PERM_ASSOC)) { object oAssociate; int nIndex; - for(nIndex = 1; nIndex < 5; nIndex++) + for(nIndex = 2; nIndex < 6; nIndex++) { oAssociate = GetAssociate(nIndex, oCreature); if(oAssociate != OBJECT_INVALID) { - SetIsDestroyable(FALSE, FALSE, FALSE); + SetIsDestroyable(FALSE, FALSE, FALSE, oAssociate); DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE)); + DelayCommand(3.0, SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate)); } } } diff --git a/_module/nss/0e_ch_7_ondeath.nss b/_module/nss/0e_ch_7_ondeath.nss index 76d955d..bb36552 100644 --- a/_module/nss/0e_ch_7_ondeath.nss +++ b/_module/nss/0e_ch_7_ondeath.nss @@ -17,13 +17,14 @@ void main() { object oAssociate; int nIndex; - for(nIndex = 2; nIndex < 5; nIndex++) + for(nIndex = 2; nIndex < 6; nIndex++) { oAssociate = GetAssociate(nIndex, oCreature); if(oAssociate != OBJECT_INVALID) { - SetIsDestroyable(FALSE, FALSE, FALSE); - ChangeFaction(oAssociate, oCreature); + SetIsDestroyable(FALSE, FALSE, FALSE, oAssociate); + DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE)); + DelayCommand(3.0, SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate)); } } } diff --git a/_module/nss/0e_id_events.nss b/_module/nss/0e_id_events.nss new file mode 100644 index 0000000..c68e74c --- /dev/null +++ b/_module/nss/0e_id_events.nss @@ -0,0 +1,277 @@ +/*////////////////////////////////////////////////////////////////////////////// +// Script Name: 0e_id_events +//////////////////////////////////////////////////////////////////////////////// + Infinite Dungeons monster event handler. +*/////////////////////////////////////////////////////////////////////////////// +#include "0i_actions" +#include "x0_i0_assoc" +// Followers special heartbeat script. +void ai_hen_id1_heart(object oCreature); +// Followers special conversation script. +void ai_hen_id1_convo(object oCreature, int nMatch); +// Followers special perception script. +void ai_hen_id1_percept(object oCreature); +// Followers special end of round script. +void ai_hen_id1_endcombat(object oCreature, int bFollower); +// Followers special castat script. +void ai_hen_id1_castat(object oCreature); + +void main() +{ + object oCreature = OBJECT_SELF; + int nEvent = GetCurrentlyRunningEvent(); + int bFollower = GetLocalInt(oCreature, "bFollower"); + //WriteTimestampedLogEntry("0e_id_events [24] " + GetName(oCreature) + " nEvent: " + IntToString(nEvent) + + // " bFollower: " + IntToString(bFollower)); + switch (nEvent) + { + case EVENT_SCRIPT_CREATURE_ON_HEARTBEAT: + { + if(bFollower) ai_hen_id1_heart(oCreature); + else ExecuteScript("nw_c2_default1", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_NOTICE: + { + if(bFollower) ai_hen_id1_percept(oCreature); + else ExecuteScript("nw_c2_default2", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DIALOGUE: + { + int nMatch = GetListenPatternNumber(); + if(nMatch == -1) + { + if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature) || + GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return; + ai_ClearCreatureActions(); + string sConversation = GetLocalString(oCreature, "sConversation"); + if(sConversation != "") BeginConversation(sConversation); + else BeginConversation(); + } + if(bFollower) ai_hen_id1_convo(oCreature, nMatch); + else ExecuteScript("nw_c2_default4", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED: + { + if(bFollower) ExecuteScript("nw_ch_ac5", oCreature); + else ExecuteScript("nw_c2_default5", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DAMAGED: + { + if(bFollower) ExecuteScript("nw_ch_ac6", oCreature); + else ExecuteScript("nw_c2_default6", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT: + { + if(bFollower) ai_hen_id1_castat(oCreature); + else ExecuteScript("nw_c2_defaultb", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND: + { + ai_hen_id1_endcombat(oCreature, bFollower); + break; + } + case EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR: + { + if(bFollower) ExecuteScript("nw_ch_ace", oCreature); + else ExecuteScript("nw_c2_defaulte", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_RESTED: + { + if(bFollower) ExecuteScript("nw_ch_aca", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DISTURBED: + { + if(bFollower) ExecuteScript("nw_ch_ac8", oCreature); + else ExecuteScript("nw_c2_default8", oCreature); + break; + } + case EVENT_SCRIPT_CREATURE_ON_DEATH: + { + if(bFollower) ExecuteScript("nw_ch_ac7", oCreature); + else + { + ExecuteScript("nw_c2_default7", oCreature); + } + break; + } + } +} + +void ai_hen_id1_heart(object oCreature) +{ + // Sometimes they slip out of this mode! + if(GetAssociateState(NW_ASC_MODE_DYING, oCreature) && + GetCommandable()) + { + ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 65.0); + SetCommandable(FALSE); + } + ExecuteScript("nw_ch_ac1", oCreature); +} +void ai_hen_id1_convo(object oCreature, int nMatch) +{ + if(nMatch == ASSOCIATE_COMMAND_INVENTORY) + { + // * cannot modify disabled equipment + if(!GetLocalInt(OBJECT_SELF, "X2_JUST_A_DISABLEEQUIP")) + { + OpenInventory(oCreature, GetLastSpeaker()); + } + // * feedback as to why + else SendMessageToPCByStrRef(GetMaster(), 100895); + return; + } + else if(nMatch == ASSOCIATE_COMMAND_LEAVEPARTY) + { + object oMaster = GetMaster(); + string sTag = GetTag(GetArea(oMaster)); + // * henchman cannot be kicked out in the reaper realm + // * Followers can never be kicked out + if (sTag == "GatesofCania" || GetIsFollower(oCreature)) return; + if(GetIsObjectValid(oMaster)) + { + ai_ClearCreatureActions(); + if(GetAssociateType(oCreature) == ASSOCIATE_TYPE_HENCHMAN) + { + string sConversation = GetLocalString(oCreature, "sConversation"); + if (sConversation == "id1_plotgiver") + { + string sVariable = GetLocalString(oCreature, "sVariable"); + object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon"); + SetLocalInt(oDungeon, "b" + sVariable + "Gone", FALSE); + } + RemoveHenchman(oMaster); + DestroyObject(oCreature); + } + } + return; + } + ExecuteScript("nw_ch_ac4", oCreature); +} +void ai_hen_id1_percept(object oCreature) +{ + // If henchman is dying and Player disappears then force a respawn of the henchman + if (GetIsHenchmanDying(oCreature)) + { + // The henchman must be removed otherwise their corpse will follow the player + object oOldMaster = GetMaster(); + object oPC = GetLastPerceived(); + int bVanish = GetLastPerceptionVanished(); + if(GetIsObjectValid(oPC) && bVanish) + { + if (oPC == oOldMaster) + { + RemoveHenchman(oPC, oCreature); + // Only in chapter 1 + if(GetTag(GetModule()) == "x0_module1") + { + SetCommandable(TRUE); + DoRespawn(oPC, oCreature); // Should teleport henchman back + } + } + } + } + ExecuteScript("nw_ch_ac2", oCreature); +} +void ai_hen_id1_endcombat(object oCreature, int bFollower) +{ + if (ai_GetIsInCombat(oCreature)) + { + int nNum; + int nLine; + string sString; + int nCreature; + int bIntelligent; + int nRandom = d100(); + // chance of a oneliner + int nOnelinerPercentage = GetLocalInt(GetModule(), "nFlagCombatOneLinerFrequencyValue"); + if(nRandom <= nOnelinerPercentage) + { + string sCreature = GetLocalString(oCreature, "sVariable"); + // if the current creature is hostile towards PCs + if(sCreature != "") + { + object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon"); + if(GetIsReactionTypeHostile(GetFirstPC())) + { + nCreature = GetLocalInt(oDungeon, "n" + sCreature); + bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent"); + if(bIntelligent) + { + nNum = GetLocalInt(GetModule(), "nLinesHostileNum"); + nLine = Random(nNum) + 1; + if(nLine > 0) + { + sString = GetLocalString(GetModule(), "sLinesHostile" + IntToString(nLine)); + SpeakString(sString, TALKVOLUME_SHOUT); + } + } + } + else + { + nCreature = GetLocalInt(oDungeon, "n" + sCreature); + bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent"); + if(bIntelligent) + { + nNum = GetLocalInt(GetModule(), "nLinesAlliesNum"); + nLine = Random(nNum) + 1; + if (nLine > 0) + { + sString = GetLocalString(GetModule(), "sLinesAllies" + IntToString(nLine)); + SpeakString(sString, TALKVOLUME_SHOUT); + } + } + } + } + } + } + if(bFollower) ExecuteScript("nw_ch_ac3", oCreature); + else ExecuteScript("nw_c2_default3", oCreature); +} +void ai_hen_id1_castat(object oCreature) +{ + if(!GetLastSpellHarmful()) + { + int nSpell = GetLastSpell(); + if(nSpell == SPELL_RAISE_DEAD || nSpell == SPELL_RESURRECTION) + { + object oCaster = GetLastSpellCaster(); + // Restore faction to neutral + SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 100, oCaster); + SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 100, oCaster); + SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 100, oCaster); + ClearPersonalReputation(oCaster, oCreature); + AssignCommand(oCreature, SurrenderToEnemies()); + AssignCommand(oCreature, ai_ClearCreatureActions(TRUE)); + // Reset henchmen attack state - Oct 28 (BK) + ai_SetAIMode(oCreature, AI_MODE_DEFEND_MASTER, FALSE); + ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE); + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE); + ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE); + // Oct 30 - If player previously hired this hench + // then just have them rejoin automatically + if(GetPlayerHasHired(oCaster, oCreature)) + { + // Feb 11, 2004 - Jon: Don't fire the HireHenchman function if the + // henchman is already oCaster's associate. Fixes a silly little problem + // that occured when you try to raise a henchman who wasn't actually dead. + if(GetMaster(oCreature)!= oCaster) HireHenchman(oCaster, oCreature, TRUE); + } + else + { + string sFile = GetDialogFileToUse(oCaster); + AssignCommand(oCaster, ActionStartConversation(oCreature, sFile)); + } + } + } + ExecuteScript("nw_ch_acb", oCreature); +} diff --git a/_module/nss/0e_nui.nss b/_module/nss/0e_nui.nss index 7d18c65..aa5dd96 100644 --- a/_module/nss/0e_nui.nss +++ b/_module/nss/0e_nui.nss @@ -1311,7 +1311,8 @@ void main() jWidget = JsonArray(); if(JsonGetLength(jSpells) == 2) jSpells = JsonArrayInsert(jSpells, JsonArray()); } - if(JsonGetLength(jWidget) < 20) + int nWidgetLength = JsonGetLength(jWidget); + if(nWidgetLength < 20) { json jData = NuiGetUserData(oPC, nToken); json jQuickListArray = JsonArrayGet(jData, 1); @@ -1320,8 +1321,7 @@ void main() 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)); + ai_PopulateWidgetList(oPC, oAssociate, nToken, jWidget); } else ai_SendMessages("The quick widget can only have 20 abilities or spells!", AI_COLOR_RED, oPC); } @@ -1331,7 +1331,7 @@ void main() json jSpell = JsonArrayGet(jQuickListArray, nIndex); ai_CreateDescriptionNUI(oPC, jSpell); } - else if(GetStringLeft(sElem, 11) == "btn_widget_") + else if(GetStringLeft(sElem, 11) == "btn_widget_") // Removes ability from quick use widget { string sIndex; if(GetStringLength(sElem) == 13) sIndex = GetStringRight(sElem, 2); @@ -1343,8 +1343,7 @@ void main() 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)); + ai_PopulateWidgetList(oPC, oAssociate, nToken, jWidget); } } else if(sEvent == "close") @@ -1393,23 +1392,22 @@ void main() 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)); + string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + int nSlot; int nMaxMemorizationSlot = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevel); - int nSlot, nSpell; + string sSlot; 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) + ")")); + sSlot = IntToString(nSlot); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")")); return; } nSlot++; @@ -1422,19 +1420,17 @@ void main() int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex)); ai_CreateDescriptionNUI(oPC, JsonArray(), nSpell); } - else if(GetStringLeft(sElem, 14) == "btn_memorized_") + else if(GetStringLeft(sElem, 14) == "btn_memorized_") // Remove memorized 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); - 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); + string sSlot = GetStringRight(sElem, 1); + ClearMemorizedSpell(oAssociate, nClass, nLevel, StringToInt(sSlot)); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_image", JsonString("ctl_cg_btn_splvl")); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_tooltip", JsonString("")); + NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_event", JsonBool(FALSE)); } } else if(sEvent == "close") @@ -1500,6 +1496,7 @@ void main() jKnownList = JsonArray(); } int nMaxKnownSlots, nSlot; + string sClass, sName, sSpellIcon, sSlot; string sSpellKnownTable = Get2DAString("classes", "SpellKnownTable", nClass); if(sSpellKnownTable != "") nMaxKnownSlots = StringToInt(Get2DAString(sSpellKnownTable, "SpellLevel" + sLevel, GetLevelByClass(nClass, oAssociate) - 1)); else nMaxKnownSlots = 20; @@ -1511,13 +1508,13 @@ void main() 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 + ")")); + sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); + sSlot = IntToString(nSlot); + NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_event", JsonBool(TRUE)); + NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_image", JsonString(sSpellIcon)); + NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + sLevel + ")")); SetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE", TRUE); break; } diff --git a/_module/nss/0i_constants.nss b/_module/nss/0i_constants.nss index 5413ac4..bb7dbe8 100644 --- a/_module/nss/0i_constants.nss +++ b/_module/nss/0i_constants.nss @@ -7,7 +7,7 @@ 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"; +const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:07.20.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 diff --git a/_module/nss/0i_main.nss b/_module/nss/0i_main.nss index a0a4674..e32aa71 100644 --- a/_module/nss/0i_main.nss +++ b/_module/nss/0i_main.nss @@ -121,9 +121,8 @@ void ai_SetAIRules() 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("")); + jRules = JsonObjectSet(JsonObject(), 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)); @@ -702,28 +701,48 @@ void ai_CheckAssociateDataAndInitialize(object oPlayer, string sAssociateType) string ai_GetAssociateType(object oPlayer, object oAssociate) { if(GetIsPC(oAssociate)) return "pc"; + int nIndex = 1; string sAITag = GetLocalString(oAssociate, AI_TAG); + object oCreature; 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++) + if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) { + sAITag = GetTag(oAssociate); oCreature = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPlayer, nIndex); - if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000)); + // Check for duplicate tags and change. + while(nIndex <= AI_MAX_HENCHMAN && oCreature != OBJECT_INVALID) + { + if(oAssociate != oCreature && sAITag == GetTag(oCreature)) + { + sAITag += IntToString(Random(1000)); + break; + } + oCreature = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPlayer, ++nIndex); + } } - for(nIndex = 2; nIndex < 6; nIndex++) + else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED) { - oCreature = GetAssociate(nIndex, oPlayer, 1); - if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000)); + int nCounter; + sAITag = GetTag(oAssociate); + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPlayer, nIndex); + while(nIndex <= 10 && oCreature != OBJECT_INVALID) + { + if(oAssociate != oCreature && sAITag == GetTag(oCreature)) + { + nCounter++; + sAITag += IntToString(nCounter); + nIndex = 0; + } + oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPlayer, ++nIndex); + } + } + else + { + if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) sAITag = "companion"; + else if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) sAITag = "familiar"; + else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) sAITag = "dominated"; } SetLocalString(oAssociate, AI_TAG, sAITag); } @@ -773,7 +792,7 @@ float ai_GetAssociateDbFloat(object oPlayer, string sAssociatetype, string sData } 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)); + //SendMessageToPC(oPlayer, "0i_main, 777, Set DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField + " jData: " + JsonDump(jData)); string sQuery = "UPDATE " + sTable + " SET " + sDataField + " = @data WHERE name = @name;"; sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); @@ -783,7 +802,7 @@ void ai_SetAssociateDbJson(object oPlayer, string sAssociateType, string sDataFi } json ai_GetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE) { - //SendMessageToPC(oPlayer, "0i_main, 638, Get DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField); + //SendMessageToPC(oPlayer, "0i_main, 787, Get DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField); string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;"; sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery); SqlBindString (sql, "@name", sAssociateType); @@ -1082,7 +1101,7 @@ void ai_CheckAssociateData(object oPlayer, object oAssociate, string sAssociateT // 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) + if(JsonGetType(JsonObjectGet(jLocations, sAssociateType + AI_WIDGET_NUI)) == JSON_TYPE_NULL) { ai_SetupLocations(oPlayer, oAssociate, sAssociateType); } diff --git a/_module/nss/0i_menus.nss b/_module/nss/0i_menus.nss index 8d6834c..756797c 100644 --- a/_module/nss/0i_menus.nss +++ b/_module/nss/0i_menus.nss @@ -26,6 +26,8 @@ int ai_GetAIButton2(object oPlayer, int nButton, object oAssociate, string sAsso 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); +// Populates the Quick widget list menu. +void ai_PopulateWidgetList(object oPC, object oAssociate, int nToken, json jWidget); // Creates the AI options menu. void ai_CreateAIMainNUI(object oPC); // Creates the AI options menu. @@ -129,6 +131,211 @@ string ai_GetSpellIconAttributes(object oCaster, int nMetaMagic, int nDomain) if(nDomain > 0) sAttributeText += "D"; return sAttributeText; } +void ai_PopulateWidgetList(object oPC, object oAssociate, int nToken, json jWidget) +{ + int nSAIndex, nSpell, nClass, nFeat, nBaseItemType, nIprpSubType, nUses; + int nLevel, nMetaMagic, nDomain, nIndex; + string sIndex, sBaseName, sName, sSpellIcon, sText, sClass, sMetaMagicText; + object oItem; + json jSpell; + 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. + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3)); + 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))); + 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)); + if(nClass == 255) + { + nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6)); + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")")); + } + else + { + 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)); + if(nClass == 255) + { + nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6)); + if(GetSpellAbilityReady(oAssociate, nSAIndex)) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")")); + } + } + else + { + 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_CreateAIMainNUI(object oPC) { // Set window to not save until it has been created. @@ -1174,6 +1381,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate) SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE); DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE)); int bRight, bLeft; + int nAssociateType = GetAssociateType(oAssociate); float fHeight = 45.0; // ************************************************************************* Width / Height int bIsPC = ai_GetIsCharacter(oAssociate); @@ -1436,7 +1644,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate) jRow = JsonArrayInsert(jRow, NuiSpacer()); if(bLeft) { - if(sAssociateType != "summons" && sAssociateType != "dominated") + if(nAssociateType != ASSOCIATE_TYPE_SUMMONED && nAssociateType != ASSOCIATE_TYPE_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); @@ -1751,7 +1959,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate) 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") + if(nAssociateType != ASSOCIATE_TYPE_SUMMONED && nAssociateType != ASSOCIATE_TYPE_DOMINATED) { sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE), 0, 0); if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sText = " Looting On [" + sRange + " meters]"; @@ -2238,7 +2446,7 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int object oItem; if(JsonGetType(jWidget) != JSON_TYPE_NULL) { - int nLevel, nSpell, nIndex, nClass, nMetaMagic, nDomain, nSubSpell, nFeat; + int nLevel, nSpell, nIndex, nClass, nMetaMagic, nDomain, nSubSpell, nFeat, nSAIndex; string sSpellIcon, sMetaMagicText, sSubSpell, sClass, sIndex; while(nIndex < 10) { @@ -2319,14 +2527,20 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int 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)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); 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)) + nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6)); + if(nClass == 255 && GetSpellAbilityReady(oAssociate, nSAIndex)) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")")); + } + else if(GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain)) { sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass))); @@ -2419,8 +2633,8 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int { nSpell = JsonGetInt(JsonArrayGet(jSpell, 0)); nClass = JsonGetInt(JsonArrayGet(jSpell, 1)); - nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3)); + nDomain = JsonGetInt(JsonArrayGet(jSpell, 4)); sSpellIcon = Get2DAString("spells", "IconResRef", nSpell); //SendMessageToPC(oPC, GetName(oAssociate) + " nSpell: " + IntToString(nSpell) + // " nClass: " + IntToString(nClass) + " nMetaMagic: " + IntToString(nMetaMagic) + @@ -2431,15 +2645,20 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int 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)) + if(nClass == 255) + { + nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6)); + if(GetSpellAbilityReady(oAssociate, nSAIndex)) + { + sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell))); + NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")")); + } + } + else if(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) + ")")); - } + 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)); } @@ -2876,7 +3095,6 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate) } // 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); @@ -2885,14 +3103,16 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate) jLocations = JsonObjectGet(jLocations, sAssociateType + AI_WIDGET_NUI); float fX = JsonGetFloat(JsonObjectGet(jLocations, "x")); float fY = JsonGetFloat(JsonObjectGet(jLocations, "y")); + //SendMessageToPC(oPC, "0i_menu, 2901, sAssociateType: " + sAssociateType + AI_WIDGET_NUI + " jLocations: " + JsonDump(jLocations, 1)); // Keeps the widgets from bunching up in the top corner. if(fY == 0.0 && fX == 0.0) { + int nAssociateType = GetAssociateType(oAssociate); 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 if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) fY = 96.0 * fScale; + else if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) fY = 192.0 * fScale; + else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED) fY = 288.0 * fScale; + else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) fY = 384.0 * fScale; else { int nIndex = 1; @@ -3178,24 +3398,34 @@ void ai_CreateCopySettingsNUI(object oPC, object oAssociate) 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 + // Row 4 ******************************************************************* 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; + // Row 5+ ******************************************************************* 244 / 185 + float fHeight = 213.0; int nIndex; string sAssocName; object oAssoc; for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++) + { + oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, 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_summons" + IntToString(nIndex), 220.0, 20.0); + // Add row to the column. + jCol = JsonArrayInsert(jCol, NuiRow(jRow)); + fHeight += 28.0; + } + else break; + } + // Row 5+ ****************************************************************** 244 / 241 + for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++) { oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex); if(oAssoc != OBJECT_INVALID) @@ -3661,7 +3891,7 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) { if(StringToInt(Get2DAString("classes", "SpellCaster", nClass))) { - int nClassLevel = GetLevelByClass(nClass, oAssociate); + int nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass); string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); for(nLevelIndex = 0; nLevelIndex <= 9; nLevelIndex++) @@ -3741,8 +3971,8 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) 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)); + //WriteTimestampedLogEntry("0i_menus, 3643, oAssociate: " + GetName(oAssociate) + + // " jSpell_Text: " + JsonDump(jSpell_Text, 4)); } } oItem = GetNextItemInInventory(oAssociate); @@ -3811,9 +4041,9 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) 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(-1)); // Level + jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // MetaMagic + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat)); jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); } @@ -3828,9 +4058,9 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) 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(0)); // Level + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // MetaMagic + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat)); jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); } @@ -3840,6 +4070,66 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) } } } + // Checks for monsters special abilities. + int nCounter = 0, nPreviousSpell = -1, nMaxSpellAbility = GetSpellAbilityCount(oAssociate); + while(nCounter < nMaxSpellAbility) + { + nSpell = GetSpellAbilitySpell(oAssociate, nCounter); + if(nPreviousSpell != nSpell) + { + nPreviousSpell = nSpell; + // Check for subfeats. + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell)); + if(nSubSpell) + { + for(nSubSpellIndex = 1; nSubSpellIndex <= 5; nSubSpellIndex++) + { + sSubSpellIndex = IntToString(nSubSpellIndex); + nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell)); + 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)); // Level + jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // MetaMagic + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Feat + 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(255)); // Class - Special abilities is always 255. + jSpell = JsonArrayInsert(jSpell, JsonInt(GetSpellAbilityCasterLevel(oAssociate, nCounter))); + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // metamagic + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // domain + jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // feat + // Index of Special ability on monster. + jSpell = JsonArrayInsert(jSpell, JsonInt(nCounter)); + jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell); + //SendMessageToPC(oPC, "nSpell: " + IntToString(nSpell) + + // " sSpellIcon: " + sSpellIcon + + // " sSpellName: " + sSpellName+ + // " nMaxSlot: " + IntToString(nMaxSpellAbility) + + // " nSpellAbilityIndex: " + IntToString(nCounter)); + } + } + nCounter++; + } // Used in the execution script to get the special abilities. //jData = JsonArrayInsert(jData, jQuickListArray); } @@ -3944,185 +4234,7 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate) 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; - } + ai_PopulateWidgetList(oPC, oAssociate, nToken, JsonArrayGet(jSpells, 2)); } void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate) { @@ -4289,7 +4401,7 @@ void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate) NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass)); if(nClassSelected == nIndex) { - int nClassLevel = GetLevelByClass(nClass, oAssociate); + int nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass); string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++) @@ -4605,7 +4717,7 @@ void ai_CreateSpellKnownNUI(object oPC, object oAssociate) NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass)); if(nClassSelected == nIndex) { - nClassLevel = GetLevelByClass(nClass, oAssociate); + nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass); sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass); nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1)); for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++) diff --git a/_module/nss/0i_spells.nss b/_module/nss/0i_spells.nss index b7b75e2..3c064c9 100644 --- a/_module/nss/0i_spells.nss +++ b/_module/nss/0i_spells.nss @@ -69,6 +69,8 @@ struct stSpell int nMaxSlots; int nSlot; }; +// Gets the total caster levels for nClass for oCreature. +int ai_GetCasterTotalLevel(object oCreature, int nClass); // 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. @@ -184,6 +186,23 @@ void ai_CastWidgetSpell(object oPC, object oAssociate, object oTarget, location 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_GetCasterTotalLevel(object oCreature, int nClass) +{ + int nIndex, nCheckClass; + int nLevel = GetLevelByClass(nClass, oCreature); + if(nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_WIZARD) + { + for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex ++) + { + nCheckClass = GetClassByPosition(nIndex, oCreature); + if(nCheckClass == CLASS_TYPE_PALE_MASTER) + { + nLevel += (GetLevelByClass(CLASS_TYPE_PALE_MASTER, oCreature) + 1) / 2; + } + } + } + return nLevel; +} 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; @@ -2111,13 +2130,17 @@ void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lL json jWidget = JsonArrayGet(jSpells, 2); json jFeat = JsonArrayGet(jWidget, nIndex); int nFeat = JsonGetInt(JsonArrayGet(jFeat, 5)); + int nLevel = JsonGetInt(JsonArrayGet(jFeat, 2)); + // We use nLevel at -1 to denote this is a feat with a subradial spell. + int nSubSpell; + if(nLevel == -1) nSubSpell = JsonGetInt(JsonArrayGet(jFeat, 0)); 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)); + AssignCommand(oAssociate, ActionUseFeat(nFeat, OBJECT_INVALID, nSubSpell, lLocation)); } - else AssignCommand(oAssociate, ActionUseFeat(nFeat, oTarget)); + else AssignCommand(oAssociate, ActionUseFeat(nFeat, oTarget, nSubSpell)); } void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lLocation) { diff --git a/_module/nss/0i_talents.nss b/_module/nss/0i_talents.nss index fa773b9..6728abb 100644 --- a/_module/nss/0i_talents.nss +++ b/_module/nss/0i_talents.nss @@ -854,6 +854,8 @@ int ai_TryKnockdownFeat(object oCreature, object oTarget) } int ai_TryPolymorphSelfFeat(object oCreature) { + // Lets check to see if we should actually Polymorph? + if(GetHasFeat(FEAT_EPIC_OUTSIDER_SHAPE)) { int nSubFeat = Random(3) + 733; // 733 azer, 734 rakshasa, 735 Slaad. diff --git a/_module/nss/ai_a_default.nss b/_module/nss/ai_a_default.nss index 7540340..6491fdf 100644 --- a/_module/nss/ai_a_default.nss +++ b/_module/nss/ai_a_default.nss @@ -54,13 +54,6 @@ void main() 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) @@ -74,6 +67,17 @@ void main() if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; } } + if(nDifficulty >= AI_COMBAT_MODERATE) + { + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; + // ************************** CLASS FEATURES *************************** + if(ai_TryPolymorphSelfFeat(oCreature)) return; + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; + if(ai_TrySummonFamiliarTalent(oCreature)) 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/_module/nss/ai_a_druid.nss b/_module/nss/ai_a_druid.nss index 6b82c26..53b9303 100644 --- a/_module/nss/ai_a_druid.nss +++ b/_module/nss/ai_a_druid.nss @@ -17,8 +17,6 @@ void main() 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) { @@ -30,7 +28,6 @@ void main() { // ************************** CLASS FEATURES *************************** if(ai_TrySummonAnimalCompanionTalent(oCreature)) return; - if(ai_TryPolymorphSelfFeat(oCreature)) return; // *************************** SPELL TALENTS *************************** if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return; } @@ -44,6 +41,9 @@ void main() if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return; } } + if(nDifficulty >= AI_COMBAT_MODERATE && ai_TryPolymorphSelfFeat(oCreature)) return; + //************************** SKILL FEATURES ************************** + if(ai_TryAnimalEmpathy(oCreature)) return; // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. // ************************** Ranged feat attacks ************************** object oTarget; diff --git a/_module/nss/ai_default.nss b/_module/nss/ai_default.nss index cfe8e8f..f84f6f7 100644 --- a/_module/nss/ai_default.nss +++ b/_module/nss/ai_default.nss @@ -26,15 +26,11 @@ void main() //**************************** 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; @@ -44,6 +40,11 @@ void main() // 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; + //**************************** CLASS FEATURES **************************** + if(ai_TryPolymorphSelfFeat(oCreature)) return; + if(ai_TryBarbarianRageFeat(oCreature)) return; + if(ai_TryBardSongFeat(oCreature)) return; + if(ai_TryTurningTalent(oCreature)) return; // PHYSICAL ATTACKS - Either we don't have talents or we are saving them. ai_DoPhysicalAttackOnNearest(oCreature, nInMelee); } diff --git a/_module/nss/ai_druid.nss b/_module/nss/ai_druid.nss index 95cb82b..7ec19fa 100644 --- a/_module/nss/ai_druid.nss +++ b/_module/nss/ai_druid.nss @@ -22,8 +22,6 @@ void main() // 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; @@ -34,6 +32,8 @@ void main() // 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; // 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 ******************************* diff --git a/_module/nss/nw_c2_default1.nss b/_module/nss/nw_c2_default1.nss index 4801a4d..6d717da 100644 --- a/_module/nss/nw_c2_default1.nss +++ b/_module/nss/nw_c2_default1.nss @@ -10,10 +10,8 @@ void main() { // 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); - object oCreature = OBJECT_SELF; + ExecuteScript("prc_npc_hb", oCreature); 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 diff --git a/_module/nss/nw_c2_default2.nss b/_module/nss/nw_c2_default2.nss index b7d5e07..fa6f5f8 100644 --- a/_module/nss/nw_c2_default2.nss +++ b/_module/nss/nw_c2_default2.nss @@ -16,7 +16,7 @@ void main() // * 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); + ExecuteScript("prc_npc_percep", oCreature); 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()) diff --git a/_module/nss/nw_c2_default3.nss b/_module/nss/nw_c2_default3.nss index 567b327..6e36412 100644 --- a/_module/nss/nw_c2_default3.nss +++ b/_module/nss/nw_c2_default3.nss @@ -17,7 +17,7 @@ void main() { object oCreature = OBJECT_SELF; - ExecuteScript("prc_npc_combat", OBJECT_SELF); + ExecuteScript("prc_npc_combat", oCreature); 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)) diff --git a/_module/nss/nw_c2_default4.nss b/_module/nss/nw_c2_default4.nss index cd1f616..38603f1 100644 --- a/_module/nss/nw_c2_default4.nss +++ b/_module/nss/nw_c2_default4.nss @@ -12,7 +12,7 @@ void ai_MonsterCommands(object oCreature, object oSpeaker, int nMatch); void main() { object oCreature = OBJECT_SELF; - ExecuteScript("prc_npc_conv", OBJECT_SELF); + ExecuteScript("prc_npc_conv", oCreature); 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))); diff --git a/_module/nss/nw_c2_default5.nss b/_module/nss/nw_c2_default5.nss index acc3b3e..c2e663d 100644 --- a/_module/nss/nw_c2_default5.nss +++ b/_module/nss/nw_c2_default5.nss @@ -10,7 +10,7 @@ void main() { object oCreature = OBJECT_SELF; - ExecuteScript("prc_npc_physatt", OBJECT_SELF); + ExecuteScript("prc_npc_physatt", oCreature); object oAttacker = GetLastAttacker(oCreature); if(AI_DEBUG) ai_Debug("nw_c2_default5", "14", GetName(oCreature) + " was attacked by " + GetName(oAttacker) + "."); diff --git a/_module/nss/nw_c2_default6.nss b/_module/nss/nw_c2_default6.nss index 5347842..60aef49 100644 --- a/_module/nss/nw_c2_default6.nss +++ b/_module/nss/nw_c2_default6.nss @@ -13,9 +13,7 @@ void main() { object oCreature = OBJECT_SELF; - - ExecuteScript("prc_npc_damaged", OBJECT_SELF); - + ExecuteScript("prc_npc_damaged", oCreature); // Send the user-defined event signal if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT)) { diff --git a/_module/nss/nw_c2_default8.nss b/_module/nss/nw_c2_default8.nss index fa7ef11..ef07c73 100644 --- a/_module/nss/nw_c2_default8.nss +++ b/_module/nss/nw_c2_default8.nss @@ -10,9 +10,9 @@ #include "0i_actions" void main() { - ExecuteScript("prc_npc_disturb", OBJECT_SELF); - - if(AI_DEBUG) ai_Debug("nw_c2_default8", "13", GetName(OBJECT_SELF) + " is been disturbed!"); + object oCreature = OBJECT_SELF; + ExecuteScript("prc_npc_disturb", oCreature); + if(AI_DEBUG) ai_Debug("nw_c2_default8", "13", GetName(oCreature) + " 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; @@ -21,6 +21,6 @@ void main() // Send the disturbed flag if appropriate. if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) { - SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DISTURBED)); + SignalEvent(oCreature, EventUserDefined(EVENT_DISTURBED)); } } diff --git a/_module/nss/nw_c2_defaultb.nss b/_module/nss/nw_c2_defaultb.nss index 3150026..050a3ea 100644 --- a/_module/nss/nw_c2_defaultb.nss +++ b/_module/nss/nw_c2_defaultb.nss @@ -10,10 +10,10 @@ void main() { object oCreature = OBJECT_SELF; + ExecuteScript("prc_npc_spellat", oCreature); object oCaster = GetLastSpellCaster(); 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)) diff --git a/_module/nss/nw_c2_defaulte.nss b/_module/nss/nw_c2_defaulte.nss index 76f62db..98e4364 100644 --- a/_module/nss/nw_c2_defaulte.nss +++ b/_module/nss/nw_c2_defaulte.nss @@ -9,6 +9,7 @@ void main() { object oCreature = OBJECT_SELF; + ExecuteScript("prc_npc_blocked", oCreature); // 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)); diff --git a/_module/nss/nw_o2_classweap.nss b/_module/nss/nw_o2_classweap.nss index 65c85cf..f2954e2 100644 --- a/_module/nss/nw_o2_classweap.nss +++ b/_module/nss/nw_o2_classweap.nss @@ -15,7 +15,7 @@ //::////////////////////////////////////////////// #include "NW_O2_CONINCLUDE" - +#include "prc_class_const" void CreateBastardSword(object oTarget, object oAdventurer) diff --git a/_module/nss/pe_crafting.nss b/_module/nss/pe_crafting.nss index 388c86a..a1a8fac 100644 --- a/_module/nss/pe_crafting.nss +++ b/_module/nss/pe_crafting.nss @@ -285,6 +285,7 @@ void main() 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); + SetColorPalletPointer(oPC, nToken, oNewItem); } // Lock the new item so they can't change it on the character. LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken); @@ -643,6 +644,7 @@ void main() int nSelected = StringToInt(GetStringRight(sElem, 1)); SetMaterialButtons(oPC, nToken, nSelected); jCraft = JsonObjectSet(jCraft, CRAFT_MATERIAL_SELECTION, JsonInt(nSelected)); + SetLocalJson(oPC, CRAFT_JSON, jCraft); // Change the pallet for the correct material. string sColorPallet; if(nSelected < 4) diff --git a/_module/nss/pe_test.nss b/_module/nss/pe_test.nss deleted file mode 100644 index 7fd799c..0000000 --- a/_module/nss/pe_test.nss +++ /dev/null @@ -1,227 +0,0 @@ -/*////////////////////////////////////////////////////////////////////////////// - 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/_module/nss/pi_crafting.nss b/_module/nss/pi_crafting.nss index 3fa9775..b7d6309 100644 --- a/_module/nss/pi_crafting.nss +++ b/_module/nss/pi_crafting.nss @@ -42,6 +42,7 @@ void main() if(oTarget == OBJECT_INVALID) oTarget = oPC; if(StartingUp(oPC)) return; json jCraft = GetLocalJson(oPC, CRAFT_JSON); + if(JsonGetType(jCraft) == JSON_TYPE_NULL) jCraft = JsonObject(); // 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)); @@ -125,7 +126,7 @@ void main() 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"))); + json jIndicator = JsonArrayInsert(JsonArray(), NuiDrawListRect(JsonBool(TRUE), NuiColor(255,0,0), JsonBool(FALSE), JsonFloat(2.0), NuiBind("color_pallet_pointer"))); jImage = NuiDrawList(jImage, JsonBool(FALSE), jIndicator); jGroupRow = JsonArrayInsert(JsonArray(), jImage); jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow)); diff --git a/_module/nss/pi_test.nss b/_module/nss/pi_test.nss deleted file mode 100644 index 818da8c..0000000 --- a/_module/nss/pi_test.nss +++ /dev/null @@ -1,103 +0,0 @@ -/*////////////////////////////////////////////////////////////////////////////// - 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/_module/nss/pinc_henchmen.nss b/_module/nss/pinc_henchmen.nss index a67141a..a65adf4 100644 --- a/_module/nss/pinc_henchmen.nss +++ b/_module/nss/pinc_henchmen.nss @@ -814,7 +814,7 @@ json CreateLevelStatList(json jHenchman, object oHenchman, object oPC, int nLeve { jLevelArray = JsonArrayInsert(jLevelArray, jLevel); } - WriteTimestampedLogEntry("pinc_henchmen, 813, Adding LvlStatList to " + GetName(oHenchman)); + WriteTimestampedLogEntry("pinc_henchmen, 813, Creating LvlStatList for " + GetName(oHenchman)); return GffAddList(jHenchman, "LvlStatList", jLevelArray); } int CanSelectFeat(json jCreature, object oCreature, int nFeat, int nPosition = 1) @@ -969,6 +969,7 @@ json ResetFeats(json jHenchman, object oHenchman) int nRace = GetRacialType(oHenchman); string sRace2DAName = Get2DAString("racialtypes", "FeatsTable", nRace); // Give racial feats. + WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for racial feats."); int nRaceRow, nRaceFeat; int nRaceMaxRow = Get2DARowCount(sRace2DAName); while(nRaceRow < nRaceMaxRow) @@ -978,11 +979,12 @@ json ResetFeats(json jHenchman, object oHenchman) jFeat = GffAddWord(jFeat, "Feat", nRaceFeat); jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); jFeatList = JsonArrayInsert(jFeatList, jFeat); - WriteTimestampedLogEntry("pinc_henchmen, 973, Adding racial feat: " + + WriteTimestampedLogEntry("pinc_henchmen, 982, Adding racial feat: " + Get2DAString("feat", "LABEL", nRaceFeat)); nRaceRow++; } // Give class feats. + WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for class feats."); int nClass = GetClassByPosition(1, oHenchman); string sGranted, sList; string sClsFeat2DAName = Get2DAString("classes", "FeatsTable", nClass); @@ -1000,13 +1002,14 @@ json ResetFeats(json jHenchman, object oHenchman) jFeat = GffAddWord(jFeat, "Feat", nClassFeat); jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1)); jFeatList = JsonArrayInsert(jFeatList, jFeat); - WriteTimestampedLogEntry("pinc_henchmen, 995, Adding class feat: " + + WriteTimestampedLogEntry("pinc_henchmen, 1005, Adding class feat: " + Get2DAString("feat", "LABEL", nClassFeat)); } } nClassRow++; } // Give any bonus feats from package. + WriteTimestampedLogEntry("pinc_henchmen, 1012, Checking for selectable feats."); int nPackageFeat, nPackageRow; string sBonusFeat2DAName = Get2DAString("classes", "BonusFeatsTable", nClass); int nNumOfFeats = StringToInt(Get2DAString(sBonusFeat2DAName, "Bonus", nLevel)); @@ -1044,10 +1047,11 @@ json ResetFeats(json jHenchman, object oHenchman) } } // Give picked feats from package. + WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for select feats."); nNumOfFeats = 1; if(GetHasFeat(FEAT_QUICK_TO_MASTER, oHenchman)) nNumOfFeats++; nPackageRow = 0; - while(nPackageRow < nPackageMaxRow) + while(nPackageRow < nPackageMaxRow || nNumOfFeats > 0) { nClassRow = 0; nPackageFeat = StringToInt(Get2DAString(sPackage2DAName, "FeatIndex", nPackageRow)); @@ -1064,6 +1068,7 @@ json ResetFeats(json jHenchman, object oHenchman) if(nNumOfFeats < 1) break; nPackageRow++; } + WriteTimestampedLogEntry("pinc_henchmen, 1071, Adding feat list."); jHenchman = GffReplaceList(jHenchman, "FeatList", jFeatList); return jHenchman; } @@ -1079,6 +1084,7 @@ json ResetSkills(json jHenchman, object oHenchman) json jSkillList = JsonArray(); json jSkill; // Setup the Skill List. + WriteTimestampedLogEntry("pinc_henchmen, 1087, Generating skill list."); int nIndex, nSkillMaxRow = Get2DARowCount("skills"); for(nIndex = 0; nIndex < nSkillMaxRow; nIndex++) { @@ -1088,6 +1094,7 @@ json ResetSkills(json jHenchman, object oHenchman) jSkillList = JsonArrayInsert(jSkillList, jSkill); } // Give skill points based on the package. + WriteTimestampedLogEntry("pinc_henchmen, 1097, Gets " + IntToString(nSkillPoints) + " skill points."); int nPackageSkill, nPackageRow, nCurrentRanks, bCrossClass, nClassRow, nNewRanks; string sPackage2DAName = Get2DAString("packages", "SkillPref2DA", nClass); int nPackageMaxRow = Get2DARowCount(sPackage2DAName); @@ -1116,8 +1123,9 @@ json ResetSkills(json jHenchman, object oHenchman) { jSkill = GffReplaceByte(jSkill, "Rank", nCurrentRanks + nNewRanks); jSkillList = JsonArraySet(jSkillList, nPackageSkill, jSkill); - WriteTimestampedLogEntry("pinc_henchmen, 1110, Adding " + IntToString(nNewRanks) + - " ranks to " + Get2DAString("skills", "Label", nPackageSkill)); + WriteTimestampedLogEntry("pinc_henchmen, 1126, Adding " + IntToString(nNewRanks) + + " ranks to " + Get2DAString("skills", "Label", nPackageSkill) + + " CrossClass: " + IntToString(bCrossClass)); nSkillPoints -= nNewRanks; } nPackageRow++; @@ -1127,7 +1135,9 @@ json ResetSkills(json jHenchman, object oHenchman) } json ResetSpellsKnown(json jClass, object oHenchman) { + WriteTimestampedLogEntry("pinc_henchmen, 1138, Checking for spells known."); int nClass = GetClassByPosition(1, oHenchman); + WriteTimestampedLogEntry("pinc_henchmen, 1140, SpellCaster: " + Get2DAString("classes", "SpellCaster", nClass)); 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! diff --git a/_module/nss/x0_ch_hen_block.nss b/_module/nss/x0_ch_hen_block.nss new file mode 100644 index 0000000..d7d86a3 --- /dev/null +++ b/_module/nss/x0_ch_hen_block.nss @@ -0,0 +1,14 @@ +//::////////////////////////////////////////////////// +//:: X0_CH_HEN_BLOCK +/* + OnBlocked handler for henchmen/associates. + */ +//::////////////////////////////////////////////////// +//:: Copyright (c) 2002 Floodgate Entertainment +//:: Created By: Naomi Novik +//:: Created On: 01/06/2003 +//::////////////////////////////////////////////////// +void main() +{ + ExecuteScript("nw_ch_ace"); +} diff --git a/_module/nss/x0_ch_hen_combat.nss b/_module/nss/x0_ch_hen_combat.nss new file mode 100644 index 0000000..d3e359b --- /dev/null +++ b/_module/nss/x0_ch_hen_combat.nss @@ -0,0 +1,36 @@ +//:://///////////////////////////////////////////// +//:: Associate: End of Combat End +//:: NW_CH_AC3 +//:: Copyright (c) 2001 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: Jan 16th, 2008 +//:: Added Support for Mounted Combat Feat Support +//::////////////////////////////////////////////// +#include "x0_inc_henai" + +void main() +{ + 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"); + } // set variables on target for mounted combat + if(!GetSpawnInCondition(NW_FLAG_SET_WARNINGS)) + { + ExecuteScript("nw_ch_ac3"); + } + if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT)) + { + SignalEvent(OBJECT_SELF, EventUserDefined(1003)); + } +} diff --git a/_module/nss/x0_ch_hen_conv.nss b/_module/nss/x0_ch_hen_conv.nss new file mode 100644 index 0000000..6943250 --- /dev/null +++ b/_module/nss/x0_ch_hen_conv.nss @@ -0,0 +1,91 @@ +//::////////////////////////////////////////////////// +//:: X0_CH_HEN_CONV +// OnDialogue event handler for henchmen/associates. +//::////////////////////////////////////////////////// +//:: Copyright (c) 2002 Floodgate Entertainment +//:: Created By: Naomi Novik +//:: Created On: 01/05/2003 +//::////////////////////////////////////////////////// +#include "x0_inc_henai" +#include "x0_i0_henchman" +#include "0i_associates" +//* GeorgZ - Put in a fix for henchmen talking even if they are petrified +int AbleToTalk(object oSelf) +{ + if (GetHasEffect(EFFECT_TYPE_CONFUSED, oSelf) || GetHasEffect(EFFECT_TYPE_DOMINATED, oSelf) || + GetHasEffect(EFFECT_TYPE_PETRIFY, oSelf) || GetHasEffect(EFFECT_TYPE_PARALYZE, oSelf) || + GetHasEffect(EFFECT_TYPE_STUNNED, oSelf) || GetHasEffect(EFFECT_TYPE_FRIGHTENED, oSelf) + ) + { + return FALSE; + } + + return TRUE; +} +void main() +{ + object oCreature = OBJECT_SELF; + // * XP2, special handling code for interjections + // * This script only fires if someone inits with me. + // * with that in mind, I am now clearing any interjections + // * that the character might have on themselves. + if (GetLocalInt(GetModule(), "X2_L_XP2") == TRUE) + { + SetLocalInt(oCreature, "X2_BANTER_TRY", 0); + SetHasInterjection(GetMaster(oCreature), FALSE); + SetLocalInt(oCreature, "X0_L_BUSY_SPEAKING_ONE_LINER", 0); + SetOneLiner(FALSE, 0); + } + object oLastSpeaker = GetLastSpeaker(); + if (GetTag(oCreature) == "x0_hen_dee") + { + string sCall = GetCampaignString("Deekin", "q6_Deekin_Call"+ GetName(oLastSpeaker), oLastSpeaker); + if (sCall == "") SetCustomToken(1001, GetStringByStrRef(40570)); + else SetCustomToken(1001, sCall); + } + // If we are disabled then we can't listen or talk, Busy is checked in ai_SelectAssociateCommand(). + if (GetIsHenchmanDying(oCreature) || ai_Disabled(oCreature)) return; + object oMaster = GetMaster(); + int nMatch = GetListenPatternNumber(); + object oIntruder; + if (nMatch == -1) + { + if (!ai_GetIsBusy(oCreature)) + { + ai_ClearCreatureActions(); + string sDialogFileToUse = GetDialogFileToUse(GetLastSpeaker()); + BeginConversation(sDialogFileToUse); + } + } + else + { + // listening pattern matched + if (GetIsObjectValid(oMaster)) ai_SelectAssociateCommand(oCreature, oLastSpeaker, nMatch); + // we don't have a master, behave in default way + else if (GetIsObjectValid(oLastSpeaker) && + !GetIsPC(oLastSpeaker) && + GetIsFriend(oLastSpeaker)) + { + object oIntruder = OBJECT_INVALID; + // Determine the intruder if any + if(nMatch == 4) oIntruder = GetLocalObject(oLastSpeaker, "NW_BLOCKER_INTRUDER"); + else if (nMatch == 5) + { + oIntruder = GetLastHostileActor(oLastSpeaker); + if(!GetIsObjectValid(oIntruder)) + { + oIntruder = GetAttemptedAttackTarget(); + if(!GetIsObjectValid(oIntruder)) oIntruder = GetAttemptedSpellTarget(); + } + } + // Actually respond to the shout + RespondToShout(oLastSpeaker, nMatch, oIntruder); + } + } + // Signal user-defined event + if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT)) + { + SignalEvent(oCreature, EventUserDefined(EVENT_DIALOGUE)); + } +} + diff --git a/_module/nss/x0_ch_hen_rest.nss b/_module/nss/x0_ch_hen_rest.nss new file mode 100644 index 0000000..8d2fc78 --- /dev/null +++ b/_module/nss/x0_ch_hen_rest.nss @@ -0,0 +1,15 @@ +//::////////////////////////////////////////////////// +//:: X0_CH_HEN_REST +/* + OnRest event handler for henchmen/associates. + */ +//::////////////////////////////////////////////////// +//:: Copyright (c) 2002 Floodgate Entertainment +//:: Created By: Naomi Novik +//:: Created On: 01/06/2003 +//::////////////////////////////////////////////////// + +void main() +{ + ExecuteScript("nw_ch_aca"); +}