generated from Jaysyn/ModuleTemplate
2025/12/24 Update
Hooked up new GUI module event. Updated 2DAs. Updated TLK. Updated PRC8 includes. Updated nasher.cfg.
This commit is contained in:
23
nasher.cfg
23
nasher.cfg
@@ -242,8 +242,17 @@ description = "PRC8 version of Pharaoh SE."
|
||||
filter = "prc_nui_sc_inc.nss"
|
||||
filter = "prc_nui_scd_inc.nss"
|
||||
filter = "prc_nui_consts.nss"
|
||||
filter = "nw_inc_nui"
|
||||
filter = "nw_inc_nui.nss"
|
||||
filter = "xchst_inc.nss"
|
||||
filter = "prc_nui_sbd_inc.nss"
|
||||
filter = "prc_nui_sb_inc.nss"
|
||||
filter = "prc_nui_lv_inc.nss"
|
||||
filter = "prc_nui_com_inc.nss"
|
||||
filter = "prc_inc_size.nss"
|
||||
filter = "prc_inc_json.nss"
|
||||
filter = "prc_inc_gff.nss"
|
||||
filter = "inc_infusion.nss"
|
||||
|
||||
|
||||
[target.rules]
|
||||
"*" = "src/module/$ext"
|
||||
@@ -466,8 +475,16 @@ description = "Merge hakpak for PRC8 version of Pharaoh SE.."
|
||||
filter = "prc_nui_sc_inc.nss"
|
||||
filter = "prc_nui_scd_inc.nss"
|
||||
filter = "prc_nui_consts.nss"
|
||||
filter = "nw_inc_nui"
|
||||
filter = "xchst_inc.nss"
|
||||
filter = "nw_inc_nui.nss"
|
||||
filter = "xchst_inc.nss"
|
||||
filter = "prc_nui_sbd_inc.nss"
|
||||
filter = "prc_nui_sb_inc.nss"
|
||||
filter = "prc_nui_lv_inc.nss"
|
||||
filter = "prc_nui_com_inc.nss"
|
||||
filter = "prc_inc_size.nss"
|
||||
filter = "prc_inc_json.nss"
|
||||
filter = "prc_inc_gff.nss"
|
||||
filter = "inc_infusion.nss"
|
||||
|
||||
[target.rules]
|
||||
"*" = "src/hakpak/pharaoh_prc8_top/$ext"
|
||||
@@ -16,7 +16,7 @@
|
||||
12 172 twobladedsword 2 5 0x1C010 1 2 WDbSw 0 1 1 1 it_bag iwdbsw 0 8 3 4 **** 1.5 10 255 1 8 2 2 1 100 1 2 1702 10 8 0 0 1 **** **** **** **** **** 4 0 0 5431 0 1 150 11 **** **** **** 50 50 50 99 1 127 655 165 693 89 745 531 943 **** ****
|
||||
13 167 greatsword 2 5 0x1C030 1 2 WSwGs 0 1 1 1 it_bag iwswgs 0 **** 3 3 **** 1.8 10 255 2 6 2 2 1 50 1 2 1693 9 8 0 0 1 **** **** **** **** **** 4 0 0 5427 0 1 150 11 **** **** **** 65 65 35 99 1 107 637 145 675 69 727 513 929 **** ****
|
||||
14 179 smallshield 2 2 0x00020 0 0 AShSw 0 1 1 1 it_bag iashsw 0 7 0 **** **** **** 10 255 **** **** **** **** 3 9 1 1 2287 16 8 0 6 0 32 4565 **** **** **** 3 1 -1 5443 0 1 60 **** **** **** 5 **** **** **** 7 1 **** **** **** **** **** **** **** **** **** ****
|
||||
15 180 torch 1 3 0x00020 1 0 it_torch 0 **** **** **** it_bag iit_torch_000 0 1 0 2 **** **** 0 255 **** **** **** **** 20 1 1 0.02 1725 17 8 0 20 4 **** **** **** **** **** **** 0 0 5444 0 1 1 **** **** **** **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
15 180 torch 1 3 0x00020 1 0 it_torch 0 **** **** **** it_bag iit_torch_000 0 1 0 2 **** **** 0 255 **** **** **** **** 20 1 1 0.02 1725 17 8 0 20 4 **** **** **** **** **** **** 0 0 5444 0 1 1 **** **** **** **** **** **** **** 0 1 **** **** **** **** **** **** **** **** 1 ****
|
||||
16 335 armor 2 3 0x00002 0 3 AArCl 1 1 **** **** gifp iit_chest 0 **** 0 **** **** **** 0 255 **** **** **** **** 4 **** 1 1 **** 30 8 0 6 0 **** **** **** **** **** 2 0 0 **** 0 0 100 **** **** **** **** **** **** **** 10 1 **** **** **** **** **** **** **** **** **** ****
|
||||
17 182 helmet 2 2 0x00001 0 1 helm 0 1 **** **** it_bag ihelm 0 **** 0 **** **** **** 0 255 **** **** **** **** 5 3 1 1 1710 0 8 0 7 0 **** **** **** **** **** 4 0 0 5445 0 0 20 **** **** **** **** **** **** **** 5 1 **** **** **** **** **** **** **** **** **** ****
|
||||
18 515 greataxe 2 4 0x1C030 1 2 WAxGr 0 1 1 1 it_bag iwaxgr 0 **** 3 3 **** 1.4 10 255 1 12 1 3 1 20 1 2 1692 9 8 0 0 1 **** **** **** **** **** 4 0 0 5426 0 1 200 17 **** **** **** 100 100 0 73 1 111 641 149 679 73 731 517 932 **** ****
|
||||
@@ -104,7 +104,7 @@
|
||||
100 **** RESERVED_poisons **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
101 76389 empty_potion 1 2 0x00000 0 2 it_potion 0 **** **** **** it_potion_000 iit_potion 0 1 0 **** **** **** 10 255 **** **** **** **** 9 1 1 0.2 86786 24 1 0 8 2 **** **** **** **** **** **** 0 0 5455 0 2 1 **** **** 2 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
102 76390 blank_scroll 1 1 0x00000 0 0 IT_SCROLL 0 **** **** **** gi_scrl iit_scroll_002 0 1 0 **** **** **** 0 255 **** **** **** **** 10 1 1 0.36 86787 27 1 0 9 2 **** **** **** **** **** **** 0 0 5470 0 0 1 **** **** 2 **** **** **** **** 1 1 **** **** **** **** **** **** **** **** **** ****
|
||||
103 76391 blank_magicwand 1 2 0x00000 1 2 WMGWn 0 1 1 1 it_bag iwmgwn 0 **** **** **** **** **** 10 255 **** **** **** **** 8 1 1 1 86788 16 1 0 1 3 **** **** **** **** **** **** 0 0 66196 50 1 10 **** **** 1 **** **** **** **** 10 1 **** **** **** **** **** **** **** **** **** ****
|
||||
103 76391 blank_magicwand 1 2 0x1C030 1 2 WMGWn 0 1 1 1 it_bag iwmgwn 0 1 2 1 **** **** 10 255 1 1 1 1 8 1 1 1 86788 16 1 0 1 3 **** **** **** **** **** **** 0 0 66196 50 1 10 4 **** 1 **** **** **** **** 10 1 **** **** **** **** **** **** **** **** **** ****
|
||||
104 83365 crafted_potion 1 2 0x00000 0 2 it_potion 0 **** **** **** it_potion_000 iit_potion 0 1 0 **** **** **** 10 255 **** **** **** **** 9 1 10 0.2 1719 24 1 0 8 2 **** **** **** **** **** **** 0 0 5455 0 2 1 **** **** 2 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
105 83364 crafted_scroll 1 1 0x00000 0 0 IT_SCROLL 0 **** **** **** gi_scrl iit_scroll_002 0 1 0 **** **** **** 0 255 **** **** **** **** 10 1 10 0.36 1718 27 1 0 9 2 **** **** **** **** **** **** 0 0 5470 0 0 1 **** **** 2 **** **** **** **** 1 1 **** **** **** **** **** **** **** **** **** ****
|
||||
106 83363 crafted_magicwand 1 2 0x1C030 1 2 WMGWn 0 1 1 1 it_bag iwmgwn 0 1 2 1 **** **** 0 255 1 1 1 1 8 1 1 1 1707 16 1 1 10 3 **** **** **** **** **** **** 0 0 66196 50 1 10 4 **** 1 **** **** **** **** 10 1 **** **** **** **** **** **** **** **** **** ****
|
||||
@@ -126,7 +126,7 @@
|
||||
122 16807269 heavy_mace 1 3 0x1C030 1 2 wxblmh 0 1 1 1 it_bag iwxblmh 0 **** 2 3 **** 1.2 10 255 1 8 1 2 1 6 1 2 16807270 14 8 0 0 1 **** **** **** **** **** 4 0 0 16807271 0 1 80 2 **** **** **** 100 100 0 99 1 24609 24621 24633 24645 24657 24669 24681 24693 **** ****
|
||||
123 16807272 maul 2 4 0x1C030 1 2 wxblma 0 1 1 1 it_bag iwxblma 0 **** 2 3 **** 1.2 10 255 1 10 1 3 1 8 1 2 16807273 14 8 0 0 1 **** **** **** **** **** 4 0 0 16807274 0 1 200 12 **** **** **** 100 100 0 99 1 24610 24622 24634 24646 24658 24670 24682 24694 **** ****
|
||||
124 16807275 scimitar_double 2 5 0x1c010 1 2 wxdbsc 0 1 1 1 it_bag iwxdbsc 0 8 3 4 **** 1.5 10 255 1 6 3 2 1 63 1 2 16807276 10 8 0 0 1 **** **** **** **** **** 4 0 0 16807277 0 1 150 11 **** **** **** 50 50 50 99 1 24611 24623 24635 24647 24659 24671 24683 24695 **** ****
|
||||
125 16807284 goad 1 2 0x1C030 0 2 wspgd 0 1 1 1 it_bag iwspgd 0 **** 1 2 **** 1.1 10 255 1 6 1 2 1 6 1 2 16807285 8 8 0 0 1 **** **** **** **** **** 4 0 0 16807286 0 1 30 18 **** **** **** 35 35 65 22 1 24612 24624 24636 24348 24660 24672 24684 24596 **** 2
|
||||
125 16807284 goad 2 2 0x1C030 0 2 wspgd 0 1 1 1 it_bag iwspgd 0 **** 1 2 **** 1.1 10 255 1 6 1 2 1 6 1 2 16807285 8 8 0 0 1 **** **** **** **** **** 4 0 0 16807286 0 1 30 18 **** **** **** 35 35 65 22 1 24612 24624 24636 24348 24660 24672 24684 24596 **** 2
|
||||
126 16793718 eagleclaw 1 2 0x1C030 1 2 wswec 0 1 1 1 it_bag iwswec 0 **** 4 2 **** 1.2 10 255 1 6 3 2 1 20 1 2 16793719 8 8 0 0 1 **** **** **** **** **** 4 0 0 16793720 0 1 20 1 **** **** **** 35 35 65 19 1 24721 24722 24723 24724 24725 24726 24727 24728 **** 2
|
||||
127 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
128 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
@@ -152,9 +152,9 @@
|
||||
148 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
149 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
150 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
151 16777221 skullgarath 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_garath iit_midmisc_129 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** ****
|
||||
152 16777222 falconidol 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_falcon iit_midmisc_128 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** ****
|
||||
153 16777223 silverstatue 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_sstat iit_midmisc_130 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** ****
|
||||
151 16777221 skullgarath 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_garath iit_midmisc_129 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
152 16777222 falconidol 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_falcon iit_midmisc_128 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
153 16777223 silverstatue 2 2 0x00000 0 0 it_midmisc 0 **** **** **** plc_sstat iit_midmisc_130 0 1 0 **** **** **** 0 200 **** **** **** **** 16 0 1 1 1726 29 8 0 15 4 **** **** **** **** **** **** 0 0 5449 0 0 50 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
154 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
155 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
156 **** padding **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
@@ -250,9 +250,9 @@
|
||||
246 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
247 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
248 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
249 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
250 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
249 16989399 crafted_scepter 1 3 0x1C030 1 2 WMgRd 0 1 1 1 it_bag iwmgrd 0 **** 2 3 **** 1.2 10 255 1 6 1 2 8 10 1 1 16989400 16 8 0 4 3 **** **** **** **** **** **** 4 0 16989401 50 1 30 2 **** 1 **** 100 100 0 10 1 43 619 47 657 15 709 495 919 **** ****
|
||||
250 16989402 crafted_vial 1 2 0x00000 0 0 it_thnmisc 0 1 1 1 it_potion_000 iit_thnmisc_019 0 1 0 **** **** **** 0 255 **** **** **** **** 16 0 1 1 16989403 24 8 0 15 3 **** **** **** **** **** **** 0 0 5470 0 0 3 **** **** 1 **** **** **** **** 0 1 **** **** **** **** **** **** **** **** **** ****
|
||||
251 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
252 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
253 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
252 16989220 mundane_herb 1 1 0x00000 0 0 it_herb 0 **** **** **** it_bag iit_herb_000 0 1 0 **** **** **** 0 255 **** **** **** **** 16 1 1 0.36 16989221 2 1 0 9 2 **** **** **** **** **** **** 0 0 5470 0 0 0 **** **** 2 **** **** **** **** 1 1 **** **** **** **** **** **** **** **** **** ****
|
||||
253 16989222 infused_herb 1 1 0x00000 0 0 it_herb 0 **** **** **** it_bag iit_herb_254 0 1 0 **** **** **** 0 255 **** **** **** **** 16 1 10 0.36 16989223 2 1 0 9 2 **** **** **** **** **** **** 0 0 5470 0 0 0 **** **** 2 **** **** **** **** 1 1 **** **** **** **** **** **** **** **** **** ****
|
||||
254 **** ***WIKI_LAST_ROW*** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
//PRC8 Token pre-fix = 161838
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Constant definitions */
|
||||
@@ -21,23 +22,23 @@ const int DYNCONV_EXITED = -2;
|
||||
const int DYNCONV_ABORTED = -3;
|
||||
const int DYNCONV_SETUP_STAGE = -1;
|
||||
|
||||
const int DYNCONV_TOKEN_HEADER = 99;
|
||||
const int DYNCONV_TOKEN_REPLY_0 = 100;
|
||||
const int DYNCONV_TOKEN_REPLY_1 = 101;
|
||||
const int DYNCONV_TOKEN_REPLY_2 = 102;
|
||||
const int DYNCONV_TOKEN_REPLY_3 = 103;
|
||||
const int DYNCONV_TOKEN_REPLY_4 = 104;
|
||||
const int DYNCONV_TOKEN_REPLY_5 = 105;
|
||||
const int DYNCONV_TOKEN_REPLY_6 = 106;
|
||||
const int DYNCONV_TOKEN_REPLY_7 = 107;
|
||||
const int DYNCONV_TOKEN_REPLY_8 = 108;
|
||||
const int DYNCONV_TOKEN_REPLY_9 = 109;
|
||||
const int DYNCONV_TOKEN_EXIT = 110;
|
||||
const int DYNCONV_TOKEN_WAIT = 111;
|
||||
const int DYNCONV_TOKEN_NEXT = 112;
|
||||
const int DYNCONV_TOKEN_PREV = 113;
|
||||
const int DYNCONV_MIN_TOKEN = 99;
|
||||
const int DYNCONV_MAX_TOKEN = 113;
|
||||
const int DYNCONV_TOKEN_HEADER = 16183899;
|
||||
const int DYNCONV_TOKEN_REPLY_0 = 161838100;
|
||||
const int DYNCONV_TOKEN_REPLY_1 = 161838101;
|
||||
const int DYNCONV_TOKEN_REPLY_2 = 161838102;
|
||||
const int DYNCONV_TOKEN_REPLY_3 = 161838103;
|
||||
const int DYNCONV_TOKEN_REPLY_4 = 161838104;
|
||||
const int DYNCONV_TOKEN_REPLY_5 = 161838105;
|
||||
const int DYNCONV_TOKEN_REPLY_6 = 161838106;
|
||||
const int DYNCONV_TOKEN_REPLY_7 = 161838107;
|
||||
const int DYNCONV_TOKEN_REPLY_8 = 161838108;
|
||||
const int DYNCONV_TOKEN_REPLY_9 = 161838109;
|
||||
const int DYNCONV_TOKEN_EXIT = 161838110;
|
||||
const int DYNCONV_TOKEN_WAIT = 161838111;
|
||||
const int DYNCONV_TOKEN_NEXT = 161838112;
|
||||
const int DYNCONV_TOKEN_PREV = 161838113;
|
||||
const int DYNCONV_MIN_TOKEN = 16183899;
|
||||
const int DYNCONV_MAX_TOKEN = 161838113;
|
||||
|
||||
const int DYNCONV_STRREF_PLEASE_WAIT = 16824202; // "Please wait"
|
||||
const int DYNCONV_STRREF_PREVIOUS = 16824203; // "Previous"
|
||||
@@ -477,9 +478,28 @@ void _DynConvInternal_ExitedConvo(object oPC, int bAbort)
|
||||
DeleteLocalInt(oPC, DYNCONV_STAGE);
|
||||
DeleteLocalString(oPC, DYNCONV_SCRIPT);
|
||||
DeleteLocalString(oPC, "DynConv_HeaderText");
|
||||
int i;
|
||||
for(i = DYNCONV_MIN_TOKEN; i <= DYNCONV_MAX_TOKEN; i++)
|
||||
DeleteLocalString(oPC, GetTokenIDString(i));
|
||||
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_HEADER));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_0));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_1));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_2));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_3));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_4));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_5));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_6));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_7));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_8));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_9));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_EXIT));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_WAIT));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_NEXT));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_PREV));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_MIN_TOKEN));
|
||||
DeleteLocalString(oPC, GetTokenIDString(DYNCONV_MAX_TOKEN));
|
||||
|
||||
//int i;
|
||||
//for(i = DYNCONV_MIN_TOKEN; i <= DYNCONV_MAX_TOKEN; i++)
|
||||
//DeleteLocalString(oPC, GetTokenIDString(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,77 +47,78 @@ const string MES_CONTINGENCIES_YES2 = "The contingencies must expire to allo
|
||||
*/
|
||||
|
||||
//Primogenitors SpellID constants
|
||||
const int SPELL_EPIC_A_STONE = 0;//4007;
|
||||
const int SPELL_EPIC_ACHHEEL = 1;//4000;
|
||||
const int SPELL_EPIC_AL_MART = 2;//4002;
|
||||
const int SPELL_EPIC_ALLHOPE = 3;//4001;
|
||||
const int SPELL_EPIC_ANARCHY = 4;//4003;
|
||||
const int SPELL_EPIC_ANBLAST = 5;//4004;
|
||||
const int SPELL_EPIC_ANBLIZZ = 6;//4005;
|
||||
const int SPELL_EPIC_ARMY_UN = 7;//4006;
|
||||
const int SPELL_EPIC_BATTLEB = 999;//4008;
|
||||
const int SPELL_EPIC_CELCOUN = 8;//4009;
|
||||
const int SPELL_EPIC_CHAMP_V = 9;//4010;
|
||||
const int SPELL_EPIC_CON_RES =10;//4011;
|
||||
const int SPELL_EPIC_CON_REU =11;//4012;
|
||||
const int SPELL_EPIC_DEADEYE =12;//4013;
|
||||
const int SPELL_EPIC_DIREWIN =13;//4015;
|
||||
const int SPELL_EPIC_DREAMSC =14;//4017;
|
||||
const int SPELL_EPIC_DRG_KNI =15;//4016;
|
||||
const int SPELL_EPIC_DTHMARK =1000;//4014;
|
||||
const int SPELL_EPIC_DULBLAD =16;//4018;
|
||||
const int SPELL_EPIC_DWEO_TH =17;//4019;
|
||||
const int SPELL_EPIC_ENSLAVE =18;//4020;
|
||||
const int SPELL_EPIC_EP_M_AR =19;//4021;
|
||||
const int SPELL_EPIC_EP_RPLS =20;//4022;
|
||||
const int SPELL_EPIC_EP_SP_R =21;//4023;
|
||||
const int SPELL_EPIC_EP_WARD =22;//4024;
|
||||
const int SPELL_EPIC_ET_FREE =23;//4025;
|
||||
const int SPELL_EPIC_FIEND_W =24;//4026;
|
||||
const int SPELL_EPIC_FLEETNS =25;//4027;
|
||||
const int SPELL_EPIC_GEMCAGE =26;//4028;
|
||||
const int SPELL_EPIC_GODSMIT =27;//4029;
|
||||
const int SPELL_EPIC_GR_RUIN =28;//4030;
|
||||
const int SPELL_EPIC_GR_SP_RE=29;//4031;
|
||||
const int SPELL_EPIC_GR_TIME =30;//4032;
|
||||
const int SPELL_EPIC_HELBALL =31;//4034;
|
||||
const int SPELL_EPIC_HELSEND =1001;//4033;
|
||||
const int SPELL_EPIC_HERCALL =32;//4035;
|
||||
const int SPELL_EPIC_HERCEMP =33;//4036;
|
||||
const int SPELL_EPIC_IMPENET =34;//4037;
|
||||
const int SPELL_EPIC_LEECH_F =35;//4038;
|
||||
const int SPELL_EPIC_LEG_ART =1002;//4039;
|
||||
const int SPELL_EPIC_LIFE_FT =1003;//4040;
|
||||
const int SPELL_EPIC_MAGMA_B =36;//4041;
|
||||
const int SPELL_EPIC_MASSPEN =37;//4042;
|
||||
const int SPELL_EPIC_MORI = 38;//4043;
|
||||
const int SPELL_EPIC_MUMDUST =39;//4044;
|
||||
const int SPELL_EPIC_NAILSKY =40;//4045;
|
||||
const int SPELL_EPIC_NIGHTSU =1004;//4046;
|
||||
const int SPELL_EPIC_ORDER_R =41;//4047;
|
||||
const int SPELL_EPIC_PATHS_B =42;//4048;
|
||||
const int SPELL_EPIC_PEERPEN =43;//4049;
|
||||
const int SPELL_EPIC_PESTIL = 44;//4050;
|
||||
const int SPELL_EPIC_PIOUS_P =45;//4051;
|
||||
const int SPELL_EPIC_PLANCEL =46;//4052;
|
||||
const int SPELL_EPIC_PSION_S =47;//4053;
|
||||
const int SPELL_EPIC_RAINFIR =48;//4054;
|
||||
const int SPELL_EPIC_RISEN_R =1005;//4055;
|
||||
const int SPELL_EPIC_RUINN = 49;//4056; //NON_STANDARD
|
||||
const int SPELL_EPIC_SINGSUN =50;//4057;
|
||||
const int SPELL_EPIC_SP_WORM =51;//4058;
|
||||
const int SPELL_EPIC_STORM_M =52;//4059;
|
||||
const int SPELL_EPIC_SUMABER =53;//4060;
|
||||
const int SPELL_EPIC_SUP_DIS =54;//4061;
|
||||
const int SPELL_EPIC_SYMRUST =1006;//4062;
|
||||
const int SPELL_EPIC_THEWITH =55;//4063;
|
||||
const int SPELL_EPIC_TOLO_KW =56;//4064;
|
||||
const int SPELL_EPIC_TRANVIT =57;//4065;
|
||||
const int SPELL_EPIC_TWINF = 58;//4066;
|
||||
const int SPELL_EPIC_UNHOLYD =59;//4067;
|
||||
const int SPELL_EPIC_UNIMPIN =60;//4068;
|
||||
const int SPELL_EPIC_UNSEENW =61;//4069;
|
||||
const int SPELL_EPIC_WHIP_SH =62;//4070;
|
||||
const int SPELL_EPIC_A_STONE = 0;//4007;
|
||||
const int SPELL_EPIC_ACHHEEL = 1;//4000;
|
||||
const int SPELL_EPIC_AL_MART = 2;//4002;
|
||||
const int SPELL_EPIC_ALLHOPE = 3;//4001;
|
||||
const int SPELL_EPIC_ANARCHY = 4;//4003;
|
||||
const int SPELL_EPIC_ANBLAST = 5;//4004;
|
||||
const int SPELL_EPIC_ANBLIZZ = 6;//4005;
|
||||
const int SPELL_EPIC_ARMY_UN = 7;//4006;
|
||||
const int SPELL_EPIC_BATTLEB = 999;//4008;
|
||||
const int SPELL_EPIC_CELCOUN = 8;//4009;
|
||||
const int SPELL_EPIC_CHAMP_V = 9;//4010;
|
||||
const int SPELL_EPIC_CON_RES = 10;//4011;
|
||||
const int SPELL_EPIC_CON_REU = 11;//4012;
|
||||
const int SPELL_EPIC_DEADEYE = 12;//4013;
|
||||
const int SPELL_EPIC_DIREWIN = 13;//4015;
|
||||
const int SPELL_EPIC_DREAMSC = 14;//4017;
|
||||
const int SPELL_EPIC_DRG_KNI = 15;//4016;
|
||||
const int SPELL_EPIC_DTHMARK = 1000;//4014;
|
||||
const int SPELL_EPIC_DULBLAD = 16;//4018;
|
||||
const int SPELL_EPIC_DWEO_TH = 17;//4019;
|
||||
const int SPELL_EPIC_ENSLAVE = 18;//4020;
|
||||
const int SPELL_EPIC_EP_M_AR = 19;//4021;
|
||||
const int SPELL_EPIC_EP_RPLS = 20;//4022;
|
||||
const int SPELL_EPIC_EP_SP_R = 21;//4023;
|
||||
const int SPELL_EPIC_EP_WARD = 22;//4024;
|
||||
const int SPELL_EPIC_ET_FREE = 23;//4025;
|
||||
const int SPELL_EPIC_FIEND_W = 24;//4026;
|
||||
const int SPELL_EPIC_FLEETNS = 25;//4027;
|
||||
const int SPELL_EPIC_GEMCAGE = 26;//4028;
|
||||
const int SPELL_EPIC_GODSMIT = 27;//4029;
|
||||
const int SPELL_EPIC_GR_RUIN = 28;//4030;
|
||||
const int SPELL_EPIC_GR_SP_RE = 29;//4031;
|
||||
const int SPELL_EPIC_GR_TIME = 30;//4032;
|
||||
const int SPELL_EPIC_HELBALL = 31;//4034;
|
||||
const int SPELL_EPIC_HELSEND = 1001;//4033;
|
||||
const int SPELL_EPIC_HERCALL = 32;//4035;
|
||||
const int SPELL_EPIC_HERCEMP = 33;//4036;
|
||||
const int SPELL_EPIC_IMPENET = 34;//4037;
|
||||
const int SPELL_EPIC_LEECH_F = 35;//4038;
|
||||
const int SPELL_EPIC_LEG_ART = 1002;//4039;
|
||||
const int SPELL_EPIC_LIFE_FT = 1003;//4040;
|
||||
const int SPELL_EPIC_MAGMA_B = 36;//4041;
|
||||
const int SPELL_EPIC_MASSPEN = 37;//4042;
|
||||
const int SPELL_EPIC_MORI = 38;//4043;
|
||||
const int SPELL_EPIC_MUMDUST = 39;//4044;
|
||||
const int SPELL_EPIC_NAILSKY = 40;//4045;
|
||||
const int SPELL_EPIC_NIGHTSU = 1004;//4046;
|
||||
const int SPELL_EPIC_ORDER_R = 41;//4047;
|
||||
const int SPELL_EPIC_PATHS_B = 42;//4048;
|
||||
const int SPELL_EPIC_PEERPEN = 43;//4049;
|
||||
const int SPELL_EPIC_PESTIL = 44;//4050;
|
||||
const int SPELL_EPIC_PIOUS_P = 45;//4051;
|
||||
const int SPELL_EPIC_PLANCEL = 46;//4052;
|
||||
const int SPELL_EPIC_PSION_S = 47;//4053;
|
||||
const int SPELL_EPIC_RAINFIR = 48;//4054;
|
||||
//const int SPELL_EPIC_RISEN_R =1005;//4055;
|
||||
const int SPELL_EPIC_RISEN_R = 49;//4055;
|
||||
const int SPELL_EPIC_RUINN = 50;//4056; //NON_STANDARD
|
||||
const int SPELL_EPIC_SINGSUN = 51;//4057;
|
||||
const int SPELL_EPIC_SP_WORM = 52;//4058;
|
||||
const int SPELL_EPIC_STORM_M = 53;//4059;
|
||||
const int SPELL_EPIC_SUMABER = 54;//4060;
|
||||
const int SPELL_EPIC_SUP_DIS = 55;//4061;
|
||||
const int SPELL_EPIC_SYMRUST = 1006;//4062;
|
||||
const int SPELL_EPIC_THEWITH = 56;//4063;
|
||||
const int SPELL_EPIC_TOLO_KW = 57;//4064;
|
||||
const int SPELL_EPIC_TRANVIT = 58;//4065;
|
||||
const int SPELL_EPIC_TWINF = 59;//4066;
|
||||
const int SPELL_EPIC_UNHOLYD = 60;//4067;
|
||||
const int SPELL_EPIC_UNIMPIN = 61;//4068;
|
||||
const int SPELL_EPIC_UNSEENW = 62;//4069;
|
||||
const int SPELL_EPIC_WHIP_SH = 63;//4070;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,7 +26,7 @@ int GetSpellFromAbrev(string sAbrev);
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "inc_utility"
|
||||
//#include "inc_epicspelldef"
|
||||
#include "inc_epicspells"
|
||||
|
||||
// SEED FUNCTIONS
|
||||
|
||||
@@ -246,7 +246,7 @@ int GetSpellFromAbrev(string sAbrev)
|
||||
sAbrev = GetStringLowerCase(sAbrev);
|
||||
if(GetStringLeft(sAbrev, 8) == "epic_sp_")
|
||||
sAbrev = GetStringRight(sAbrev, GetStringLength(sAbrev)-8);
|
||||
if(DEBUG) DoDebug("sAbrew to check vs: " + sAbrev);
|
||||
if(DEBUG) DoDebug("sAbrev to check vs: " + sAbrev);
|
||||
int i = 0;
|
||||
string sLabel = GetStringLowerCase(Get2DACache("epicspells", "LABEL", i));
|
||||
while(sLabel != "")
|
||||
|
||||
@@ -303,11 +303,18 @@ int GetIsEpicShaman(object oPC)
|
||||
&& GetAbilityScore(oPC, ABILITY_WISDOM) > 18;
|
||||
}
|
||||
|
||||
int GetIsEpicSorcerer(object oPC)
|
||||
int GetIsEpicSorcerer(object oPC)
|
||||
{
|
||||
return GetHitDice(oPC) >= 21
|
||||
&& GetCasterLvl(CLASS_TYPE_SORCERER, oPC) > 17
|
||||
&& GetAbilityScore(oPC, ABILITY_CHARISMA) > 18;
|
||||
}
|
||||
|
||||
/* int GetIsEpicSorcerer(object oPC)
|
||||
{
|
||||
return GetPrCAdjustedCasterLevel(CLASS_TYPE_SORCERER, oPC, FALSE) > 17
|
||||
&& GetAbilityScore(oPC, ABILITY_CHARISMA) > 18;
|
||||
}
|
||||
} */
|
||||
|
||||
int GetIsEpicSublimeChord(object oPC)
|
||||
{
|
||||
|
||||
481
src/include/inc_infusion.nss
Normal file
481
src/include/inc_infusion.nss
Normal file
@@ -0,0 +1,481 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:: ;-. ,-. ,-. ,-.
|
||||
//:: | ) | ) / ( )
|
||||
//:: |-' |-< | ;-:
|
||||
//:: | | \ \ ( )
|
||||
//:: ' ' ' `-' `-'
|
||||
//::///////////////////////////////////////////////
|
||||
//::
|
||||
/*
|
||||
Script: inc_infusion
|
||||
Author: Jaysyn
|
||||
Created: 2025-08-11 17:01:26
|
||||
|
||||
Description:
|
||||
Contains most functions related to the Create
|
||||
Infusion feat.
|
||||
|
||||
*/
|
||||
//::
|
||||
//:://////////////////////////////////////////////
|
||||
#include "prc_inc_spells"
|
||||
|
||||
int GetMaxDivineSpellLevel(object oCaster, int nClass);
|
||||
int GetCastSpellCasterLevelFromItem(object oItem, int nSpellID);
|
||||
int GetIsClassSpell(object oCaster, int nSpellID, int nClass);
|
||||
int GetHasSpellOnClassList(object oCaster, int nSpellID);
|
||||
void InfusionSecondSave(object oUser, int nDC);
|
||||
|
||||
/**
|
||||
* @brief Finds the class index for which the given spell is available to the specified caster.
|
||||
*
|
||||
* This function iterates through all possible classes and returns the first class
|
||||
* index for which the specified spell is on the caster's spell list.
|
||||
*
|
||||
* @param oCaster The creature object to check.
|
||||
* @param nSpellID The spell ID to find the class for.
|
||||
*
|
||||
* @return The class index that has the spell on its class spell list for the caster,
|
||||
* or -1 if no matching class is found.
|
||||
*/
|
||||
int FindSpellCastingClass(object oCaster, int nSpellID)
|
||||
{
|
||||
int i = 0;
|
||||
int nClassFound = -1;
|
||||
int nClass;
|
||||
|
||||
// Only loop through caster's classes
|
||||
for (i = 0; i <= 8; i++)
|
||||
{
|
||||
nClass = GetClassByPosition(i, oCaster);
|
||||
if (nClass == CLASS_TYPE_INVALID) continue;
|
||||
|
||||
if (GetIsClassSpell(oCaster, nSpellID, nClass))
|
||||
{
|
||||
nClassFound = nClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nClassFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Performs validation checks to determine if the caster can use a spell infusion from the specified item.
|
||||
*
|
||||
* This function verifies that the item is a valid infused herb, checks the caster's relevant class and ability scores,
|
||||
* confirms the caster is a divine spellcaster with the necessary caster level, and ensures the spell is on the caster's class spell list.
|
||||
*
|
||||
* @param oCaster The creature attempting to use the infusion.
|
||||
* @param oItem The infused herb item containing the spell.
|
||||
* @param nSpellID The spell ID of the infusion spell being cast.
|
||||
*
|
||||
* @return TRUE if all infusion use checks pass and the caster can use the infusion; FALSE otherwise.
|
||||
*/
|
||||
int DoInfusionUseChecks(object oCaster, object oItem, int nSpellID)
|
||||
{
|
||||
int bPnPHerbs = GetPRCSwitch(PRC_CREATE_INFUSION_OPTIONAL_HERBS);
|
||||
|
||||
if(GetBaseItemType(oItem) != BASE_ITEM_INFUSED_HERB)
|
||||
{
|
||||
FloatingTextStringOnCreature("Not casting from an Infused Herb", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int nItemSpellLvl = GetCastSpellCasterLevelFromItem(oItem, nSpellID);
|
||||
if (bPnPHerbs && nItemSpellLvl == -1)
|
||||
{
|
||||
FloatingTextStringOnCreature("Item has no spellcaster level.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// **CRITICAL: Find the correct class that actually has the spell on its list**
|
||||
int nClassCaster = FindSpellCastingClass(oCaster, nSpellID);
|
||||
|
||||
if(DEBUG) DoDebug("nClassCaster is: " + IntToString(nClassCaster) + ".");
|
||||
|
||||
// Check for valid class
|
||||
if (nClassCaster == -1)
|
||||
{
|
||||
FloatingTextStringOnCreature("No valid class found for this spell.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(GetMaxDivineSpellLevel(oCaster, nClassCaster) < 1 )
|
||||
{
|
||||
FloatingTextStringOnCreature("You must be a divine spellcaster to activate an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must have spell on class list - (This will also double-check via the class)
|
||||
if (!GetHasSpellOnClassList(oCaster, nSpellID))
|
||||
{
|
||||
FloatingTextStringOnCreature("You must have a spell on one of your class spell lists to cast it from an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must meet ability requirement: Ability score >= 10 + spell level
|
||||
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nClassCaster);
|
||||
int nClassAbility = GetAbilityScoreForClass(nClassCaster, oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nClassCaster is "+IntToString(nClassCaster)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: Class nSpellLevel is "+IntToString(nSpellLevel)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nClassAbility is "+IntToString(nClassAbility)+".");
|
||||
|
||||
if (nClassAbility < 10 + nSpellLevel)
|
||||
{
|
||||
FloatingTextStringOnCreature("You must meet ability score requirement to cast spell from infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must have a divine caster level at least equal to infusion's caster level
|
||||
int nDivineLvl = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nDivineLvl is "+IntToString(nDivineLvl)+".");
|
||||
|
||||
if (nDivineLvl < nItemSpellLvl)
|
||||
{
|
||||
FloatingTextStringOnCreature("Your divine caster level is too low to cast this spell from an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* int DoInfusionUseChecks(object oCaster, object oItem, int nSpellID)
|
||||
{
|
||||
int bPnPHerbs = GetPRCSwitch(PRC_CREATE_INFUSION_OPTIONAL_HERBS);
|
||||
|
||||
if(GetBaseItemType(oItem) != BASE_ITEM_INFUSED_HERB)
|
||||
{
|
||||
FloatingTextStringOnCreature("Not casting from an Infused Herb", oCaster);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
int nItemSpellLvl = GetCastSpellCasterLevelFromItem(oItem, nSpellID);
|
||||
if (bPnPHerbs && nItemSpellLvl == -1)
|
||||
{
|
||||
FloatingTextStringOnCreature("Item has no spellcaster level.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Find relevant class for the spell
|
||||
int nClassCaster = FindSpellCastingClass(oCaster, nSpellID);
|
||||
|
||||
if(DEBUG) DoDebug("nClassCaster is: "+IntToString(nClassCaster)+".");
|
||||
|
||||
if(GetMaxDivineSpellLevel(oCaster, nClassCaster) < 1 )
|
||||
{
|
||||
FloatingTextStringOnCreature("You must be a divine spellcaster to activate an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must have spell on class list
|
||||
if (!GetHasSpellOnClassList(oCaster, nSpellID))
|
||||
{
|
||||
FloatingTextStringOnCreature("You must have a spell on one of your class spell lists to cast it from an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must meet ability requirement: Ability score >= 10 + spell level
|
||||
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nClassCaster);
|
||||
int nClassAbility = GetAbilityScoreForClass(nClassCaster, oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nClassCaster is "+IntToString(nClassCaster)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: Class nSpellLevel is "+IntToString(nSpellLevel)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nClassAbility is "+IntToString(nClassAbility)+".");
|
||||
|
||||
if (nClassAbility < 10 + nSpellLevel)
|
||||
{
|
||||
FloatingTextStringOnCreature("You must meet ability score requirement to cast spell from infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Must have a divine caster level at least equal to infusion's caster level
|
||||
int nDivineLvl = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster);
|
||||
|
||||
if(DEBUG) DoDebug("inc_infusion >> DoInfusionUseChecks: nDivineLvl is "+IntToString(nDivineLvl)+".");
|
||||
|
||||
if (nDivineLvl < nItemSpellLvl)
|
||||
{
|
||||
FloatingTextStringOnCreature("Your divine caster level is too low to cast this spell from an infusion.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* @brief Retrieves the maximum divine spell level known by the caster for a given class.
|
||||
*
|
||||
* This function checks the caster's local integers named "PRC_DivSpell1" through "PRC_DivSpell9"
|
||||
* in descending order to determine the highest divine spell level available.
|
||||
* It returns the highest spell level for which the corresponding local int is false (zero).
|
||||
*
|
||||
* @param oCaster The creature whose divine spell levels are being checked.
|
||||
* @param nClass The class index for which to check the divine spell level (currently unused).
|
||||
*
|
||||
* @return The highest divine spell level known by the caster (1 to 9).
|
||||
*/
|
||||
int GetMaxDivineSpellLevel(object oCaster, int nClass)
|
||||
{
|
||||
int i = 9;
|
||||
for (i; i > 0; i--)
|
||||
{
|
||||
if(!GetLocalInt(oCaster, "PRC_DivSpell"+IntToString(i)))
|
||||
return i;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the spell school of an herb based on its resref by looking it up in the craft_infusion.2da file.
|
||||
*
|
||||
* This function searches the "craft_infusion" 2DA for a row matching the herb's resref.
|
||||
* If found, it returns the corresponding spell school as an integer constant.
|
||||
* If not found or the SpellSchool column is missing/invalid, it returns -1.
|
||||
*
|
||||
* @param oHerb The herb object to check.
|
||||
*
|
||||
* @return The spell school constant corresponding to the herb's infusion spell school,
|
||||
* or -1 if the herb is invalid, not found, or the data is missing.
|
||||
*/
|
||||
int GetHerbsSpellSchool(object oHerb)
|
||||
{
|
||||
if (!GetIsObjectValid(oHerb)) return -1;
|
||||
|
||||
string sResref = GetResRef(oHerb);
|
||||
int nRow = 0;
|
||||
string sRowResref;
|
||||
|
||||
while (nRow < 200)
|
||||
{
|
||||
sRowResref = Get2DACache("craft_infusion", "Resref", nRow);
|
||||
if (sRowResref == "") break;
|
||||
if (sRowResref == sResref)
|
||||
{
|
||||
string sHerbSpellSchool = Get2DAString("craft_infusion", "SpellSchool", nRow);
|
||||
|
||||
if (sHerbSpellSchool == "A") return SPELL_SCHOOL_ABJURATION;
|
||||
else if (sHerbSpellSchool == "C") return SPELL_SCHOOL_CONJURATION;
|
||||
else if (sHerbSpellSchool == "D") return SPELL_SCHOOL_DIVINATION;
|
||||
else if (sHerbSpellSchool == "E") return SPELL_SCHOOL_ENCHANTMENT;
|
||||
else if (sHerbSpellSchool == "V") return SPELL_SCHOOL_EVOCATION;
|
||||
else if (sHerbSpellSchool == "I") return SPELL_SCHOOL_ILLUSION;
|
||||
else if (sHerbSpellSchool == "N") return SPELL_SCHOOL_NECROMANCY;
|
||||
else if (sHerbSpellSchool == "T") return SPELL_SCHOOL_TRANSMUTATION;
|
||||
else return SPELL_SCHOOL_GENERAL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
nRow++;
|
||||
}
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the infusion spell level of an herb by matching its resref in the craft_infusion.2da file.
|
||||
*
|
||||
* This function searches the "craft_infusion" 2DA for a row matching the herb's resref.
|
||||
* If found, it returns the spell level from the SpellLevel column as an integer.
|
||||
* If not found or the column is missing, it returns -1.
|
||||
*
|
||||
* @param oHerb The herb object whose infusion spell level is to be retrieved.
|
||||
*
|
||||
* @return The spell level as an integer if found, or -1 if the herb is invalid, not found, or the column is missing.
|
||||
*/
|
||||
int GetHerbsInfusionSpellLevel(object oHerb)
|
||||
{
|
||||
if (!GetIsObjectValid(oHerb)) return -1;
|
||||
|
||||
string sResref = GetResRef(oHerb);
|
||||
int nRow = 0;
|
||||
string sRowResref;
|
||||
|
||||
// Brute-force loop <20> adjust limit if your 2DA has more than 500 rows
|
||||
while (nRow < 200)
|
||||
{
|
||||
sRowResref = Get2DACache("craft_infusion", "Resref", nRow);
|
||||
if (sRowResref == "") break; // End of valid rows
|
||||
if (sRowResref == sResref)
|
||||
{
|
||||
string sSpellLevelStr = Get2DAString("craft_infusion", "SpellLevel", nRow);
|
||||
return StringToInt(sSpellLevelStr);
|
||||
}
|
||||
nRow++;
|
||||
}
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the caster level of a specific cast-spell item property from an item.
|
||||
*
|
||||
* This function iterates through the item properties of the given item, searching for an
|
||||
* ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL property that matches the specified spell ID.
|
||||
* If found, it returns the caster level value stored in the item property.
|
||||
*
|
||||
* @param oItem The item object to check.
|
||||
* @param nSpellID The spell ID to match against the item property.
|
||||
*
|
||||
* @return The caster level associated with the matching cast-spell item property,
|
||||
* or -1 if no matching property is found.
|
||||
*/
|
||||
int GetCastSpellCasterLevelFromItem(object oItem, int nSpellID)
|
||||
{
|
||||
int nFoundCL = -1;
|
||||
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
while (GetIsItemPropertyValid(ip))
|
||||
{
|
||||
int nType = GetItemPropertyType(ip);
|
||||
|
||||
// First preference: PRC's CASTER_LEVEL itemprop
|
||||
if (nType == ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL)
|
||||
{
|
||||
int nSubType = GetItemPropertySubType(ip);
|
||||
string sSpellIDStr = Get2DAString("iprp_spells", "SpellIndex", nSubType);
|
||||
int nSubSpellID = StringToInt(sSpellIDStr);
|
||||
|
||||
if (nSubSpellID == nSpellID)
|
||||
{
|
||||
return GetItemPropertyCostTableValue(ip); // Found exact CL
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: vanilla CAST_SPELL property
|
||||
if (nType == ITEM_PROPERTY_CAST_SPELL && nFoundCL == -1)
|
||||
{
|
||||
int nSubType = GetItemPropertySubType(ip);
|
||||
string sSpellIDStr = Get2DAString("iprp_spells", "SpellIndex", nSubType);
|
||||
int nSubSpellID = StringToInt(sSpellIDStr);
|
||||
|
||||
if (nSubSpellID == nSpellID)
|
||||
{
|
||||
// Vanilla uses CostTableValue for *number of uses*, not CL,
|
||||
// so we<77>ll assume default caster level = spell level * 2 - 1
|
||||
int nSpellLevel = StringToInt(Get2DAString("spells", "Innate", nSubSpellID));
|
||||
nFoundCL = nSpellLevel * 2 - 1; // default NWN caster level rule
|
||||
}
|
||||
}
|
||||
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
|
||||
return nFoundCL; // -1 if not found
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if a given spell ID is present on the specified class's spell list for the caster.
|
||||
*
|
||||
* This function determines the spell level of the spell for the given class using PRCGetSpellLevelForClass.
|
||||
* If the spell level is -1, the spell is not on the class's spell list.
|
||||
* Otherwise, the spell is considered to be on the class spell list.
|
||||
*
|
||||
* @param oCaster The creature object casting or querying the spell.
|
||||
* @param nSpellID The spell ID to check.
|
||||
* @param nClass The class index to check the spell list against.
|
||||
*
|
||||
* @return TRUE if the spell is on the class's spell list; FALSE otherwise.
|
||||
*/
|
||||
int GetIsClassSpell(object oCaster, int nSpellID, int nClass)
|
||||
{
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetIsClassSpell: nSpellID is: "+IntToString(nSpellID)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetIsClassSpell: nClass is: "+IntToString(nClass)+".");
|
||||
|
||||
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nClass);
|
||||
if (nSpellLevel == -1)
|
||||
{
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetIsClassSpell: SpellLevel is "+IntToString(nSpellLevel)+".");
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetIsClassSpell: Spell "+IntToString(nSpellID)+" is not in spelllist of "+IntToString(nClass)+".");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the caster has the specified spell on any of their class spell lists.
|
||||
*
|
||||
* This function iterates through all classes the caster has (up to position 8),
|
||||
* and returns TRUE if the spell is found on any class's spell list.
|
||||
*
|
||||
* @param oCaster The creature object to check.
|
||||
* @param nSpellID The spell ID to search for.
|
||||
*
|
||||
* @return TRUE if the spell is present on at least one of the caster's class spell lists;
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
int GetHasSpellOnClassList(object oCaster, int nSpellID)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i <= 8; i++)
|
||||
{
|
||||
int nClass = GetClassByPosition(i, oCaster);
|
||||
if (nClass == CLASS_TYPE_INVALID) continue;
|
||||
|
||||
if (GetIsClassSpell(oCaster, nSpellID, nClass))
|
||||
{
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetHasSpellOnClassList: Class spell found.");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if(DEBUG) DoDebug("inc_infusion >> GetHasSpellOnClassList: Class spell not found.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies a poison nausea effect to the user when infusion use fails.
|
||||
*
|
||||
* This function performs an immediate Fortitude saving throw against poison DC based on infusion caster level.
|
||||
* If the user fails and is not immune to poison, an infusion nausea effect is applied, replacing any existing one.
|
||||
* A second saving throw is scheduled after 1 minute to attempt to remove the effect.
|
||||
*
|
||||
* @param oUser The creature who used the infusion and may be poisoned.
|
||||
* @param nInfusionCL The caster level of the infusion used, affecting the DC of the saving throw.
|
||||
*/
|
||||
void ApplyInfusionPoison(object oUser, int nInfusionCL)
|
||||
{
|
||||
int nDC = 10 + (nInfusionCL / 2);
|
||||
int bImmune = GetIsImmune(oUser, IMMUNITY_TYPE_POISON);
|
||||
|
||||
// First save immediately
|
||||
if (!bImmune && !PRCMySavingThrow(SAVING_THROW_FORT, oUser, nDC, SAVING_THROW_TYPE_POISON))
|
||||
{
|
||||
// Remove existing infusion poison nausea effect before applying new
|
||||
effect eOld = GetFirstEffect(oUser);
|
||||
while (GetIsEffectValid(eOld))
|
||||
{
|
||||
if (GetEffectTag(eOld) == "INFUSION_POISON_TAG")
|
||||
{
|
||||
RemoveEffect(oUser, eOld);
|
||||
break; // Assuming only one effect with this tag
|
||||
}
|
||||
eOld = GetNextEffect(oUser);
|
||||
}
|
||||
|
||||
effect eNausea = EffectNausea(oUser, 60.0f);
|
||||
|
||||
TagEffect(eNausea, "INFUSION_POISON_TAG");
|
||||
FloatingTextStringOnCreature("The infusion has made you nauseous.", oUser);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eNausea, oUser, RoundsToSeconds(10));
|
||||
}
|
||||
|
||||
// Second save 1 minute later
|
||||
if (!bImmune)
|
||||
{
|
||||
DelayCommand(60.0, InfusionSecondSave(oUser, nDC));
|
||||
}
|
||||
}
|
||||
|
||||
void InfusionSecondSave(object oUser, int nDC)
|
||||
{
|
||||
if (!PRCMySavingThrow(SAVING_THROW_FORT, oUser, nDC, SAVING_THROW_TYPE_POISON))
|
||||
{
|
||||
FloatingTextStringOnCreature("The infusion has made you nauseous.", oUser);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectNausea(oUser, 60.0f), oUser, RoundsToSeconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
//:: void main (){}
|
||||
@@ -1643,7 +1643,60 @@ int GetIsMagicItem(object oItem)
|
||||
int FeatToIprop(int nFeat)
|
||||
{
|
||||
switch(nFeat)
|
||||
{//: Weapon Focus
|
||||
{
|
||||
//:: Weapon Proficiencies
|
||||
case FEAT_WEAPON_PROFICIENCY_SHORTSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
|
||||
case FEAT_WEAPON_PROFICIENCY_LONGSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LONGSWORD;
|
||||
case FEAT_WEAPON_PROFICIENCY_BATTLEAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
|
||||
case FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
|
||||
case FEAT_WEAPON_PROFICIENCY_WARHAMMER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_WARHAMMER;
|
||||
case FEAT_WEAPON_PROFICIENCY_LONGBOW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LONGBOW;
|
||||
case FEAT_WEAPON_PROFICIENCY_LIGHT_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
|
||||
case FEAT_WEAPON_PROFICIENCY_HALBERD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HALBERD;
|
||||
case FEAT_WEAPON_PROFICIENCY_SHORTBOW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTBOW;
|
||||
case FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD;
|
||||
case FEAT_WEAPON_PROFICIENCY_GREATSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GREATSWORD;
|
||||
case FEAT_WEAPON_PROFICIENCY_GREATAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GREATAXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_DART: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DART;
|
||||
case FEAT_WEAPON_PROFICIENCY_DIRE_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DIRE_MACE;
|
||||
case FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL;
|
||||
case FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER;
|
||||
case FEAT_WEAPON_PROFICIENCY_HANDAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HANDAXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_KAMA: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KAMA;
|
||||
case FEAT_WEAPON_PROFICIENCY_KATANA: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KATANA;
|
||||
case FEAT_WEAPON_PROFICIENCY_KUKRI: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KUKRI;
|
||||
case FEAT_WEAPON_PROFICIENCY_MORNINGSTAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_MORNINGSTAR;
|
||||
case FEAT_WEAPON_PROFICIENCY_RAPIER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_RAPIER;
|
||||
case FEAT_WEAPON_PROFICIENCY_SCIMITAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SCIMITAR;
|
||||
case FEAT_WEAPON_PROFICIENCY_SCYTHE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SCYTHE;
|
||||
case FEAT_WEAPON_PROFICIENCY_SHORTSPEAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTSPEAR;
|
||||
case FEAT_WEAPON_PROFICIENCY_SHURIKEN: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHURIKEN;
|
||||
case FEAT_WEAPON_PROFICIENCY_SICKLE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SICKLE;
|
||||
case FEAT_WEAPON_PROFICIENCY_SLING: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SLING;
|
||||
case FEAT_WEAPON_PROFICIENCY_THROWING_AXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_THROWING_AXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_TRIDENT: return IP_CONST_FEAT_WEAPON_PROFICIENCY_TRIDENT;
|
||||
case FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE;
|
||||
case FEAT_WEAPON_PROFICIENCY_WHIP: return IP_CONST_FEAT_WEAPON_PROFICIENCY_WHIP;
|
||||
case FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE;
|
||||
case FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE;
|
||||
case FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE;
|
||||
case FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE;
|
||||
case FEAT_WEAPON_PROFICIENCY_HEAVY_PICK: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_PICK;
|
||||
case FEAT_WEAPON_PROFICIENCY_LIGHT_PICK: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_PICK;
|
||||
case FEAT_WEAPON_PROFICIENCY_SAI: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SAI;
|
||||
case FEAT_WEAPON_PROFICIENCY_NUNCHAKU: return IP_CONST_FEAT_WEAPON_PROFICIENCY_NUNCHAKU;
|
||||
case FEAT_WEAPON_PROFICIENCY_FALCHION: return IP_CONST_FEAT_WEAPON_PROFICIENCY_FALCHION;
|
||||
case FEAT_WEAPON_PROFICIENCY_SAP: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SAP;
|
||||
case FEAT_WEAPON_PROFICIENCY_KATAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KATAR;
|
||||
case FEAT_WEAPON_PROFICIENCY_HEAVY_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_MACE;
|
||||
case FEAT_WEAPON_PROFICIENCY_MAUL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_MAUL;
|
||||
case FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR;
|
||||
case FEAT_WEAPON_PROFICIENCY_GOAD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GOAD;
|
||||
case FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW;
|
||||
|
||||
//: Weapon Focus
|
||||
case FEAT_WEAPON_FOCUS_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_BASTARD_SWORD;
|
||||
case FEAT_WEAPON_FOCUS_BATTLE_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_BATTLE_AXE;
|
||||
case FEAT_WEAPON_FOCUS_CLUB: return IP_CONST_FEAT_WEAPON_FOCUS_CLUB;
|
||||
|
||||
@@ -242,25 +242,27 @@ void SetupLookupStage(object oMod, int n)
|
||||
case 11: SetLkupStage(n, oMod, CLASS_TYPE_DRAGON_SHAMAN, "cls_inv_drgshm"); break;
|
||||
case 12: SetLkupStage(n, oMod, CLASS_TYPE_WARLOCK, "cls_inv_warlok"); break;
|
||||
case 13: SetLkupStage(n, oMod, CLASS_TYPE_ARCHIVIST, "cls_spell_archv"); break;
|
||||
case 14: SetLkupStage(n, oMod, CLASS_TYPE_ASSASSIN, "cls_spell_asasin"); break;
|
||||
case 15: SetLkupStage(n, oMod, CLASS_TYPE_BARD, "cls_spell_bard"); break;
|
||||
case 16: SetLkupStage(n, oMod, CLASS_TYPE_BEGUILER, "cls_spell_beguil"); break;
|
||||
case 17: SetLkupStage(n, oMod, CLASS_TYPE_DREAD_NECROMANCER, "cls_spell_dnecro"); break;
|
||||
case 18: SetLkupStage(n, oMod, CLASS_TYPE_DUSKBLADE, "cls_spell_duskbl"); break;
|
||||
case 19: SetLkupStage(n, oMod, CLASS_TYPE_FAVOURED_SOUL, "cls_spell_favsol"); break;
|
||||
case 20: SetLkupStage(n, oMod, CLASS_TYPE_HARPER, "cls_spell_harper"); break;
|
||||
case 21: SetLkupStage(n, oMod, CLASS_TYPE_HEXBLADE, "cls_spell_hexbl"); break;
|
||||
case 22: SetLkupStage(n, oMod, CLASS_TYPE_JUSTICEWW, "cls_spell_justww"); break;
|
||||
case 23: SetLkupStage(n, oMod, CLASS_TYPE_SORCERER, "cls_spell_sorc"); break;
|
||||
case 24: SetLkupStage(n, oMod, CLASS_TYPE_SUBLIME_CHORD, "cls_spell_schord"); break;
|
||||
case 25: SetLkupStage(n, oMod, CLASS_TYPE_SUEL_ARCHANAMACH, "cls_spell_suel"); break;
|
||||
case 26: SetLkupStage(n, oMod, CLASS_TYPE_VIGILANT, "cls_spell_vigil"); break;
|
||||
case 27: SetLkupStage(n, oMod, CLASS_TYPE_WARMAGE, "cls_spell_wrmage"); break;
|
||||
case 28: SetLkupStage(n, oMod, CLASS_TYPE_KNIGHT_WEAVE, "cls_spell_kngtwv"); break;
|
||||
case 29: SetLkupStage(n, oMod, CLASS_TYPE_PSYCHIC_ROGUE, "cls_psipw_psyrog"); break;
|
||||
case 30: SetLkupStage(n, oMod, CLASS_TYPE_SHADOWCASTER, "cls_myst_shdcst"); break;
|
||||
case 31: SetLkupStage(n, oMod, CLASS_TYPE_SHADOWSMITH, "cls_myst_shdsmt"); break;
|
||||
case 32: SetLkupStage(n, oMod, CLASS_TYPE_CELEBRANT_SHARESS, "cls_spell_sharss"); break;
|
||||
case 14: SetLkupStage(n, oMod, CLASS_TYPE_BARD, "cls_spell_bard"); break;
|
||||
case 15: SetLkupStage(n, oMod, CLASS_TYPE_BEGUILER, "cls_spell_beguil"); break;
|
||||
case 16: SetLkupStage(n, oMod, CLASS_TYPE_DREAD_NECROMANCER, "cls_spell_dnecro"); break;
|
||||
case 17: SetLkupStage(n, oMod, CLASS_TYPE_DUSKBLADE, "cls_spell_duskbl"); break;
|
||||
case 18: SetLkupStage(n, oMod, CLASS_TYPE_FAVOURED_SOUL, "cls_spell_favsol"); break;
|
||||
case 19: SetLkupStage(n, oMod, CLASS_TYPE_HARPER, "cls_spell_harper"); break;
|
||||
case 20: SetLkupStage(n, oMod, CLASS_TYPE_HEXBLADE, "cls_spell_hexbl"); break;
|
||||
case 21: SetLkupStage(n, oMod, CLASS_TYPE_JUSTICEWW, "cls_spell_justww"); break;
|
||||
case 22: SetLkupStage(n, oMod, CLASS_TYPE_SORCERER, "cls_spell_sorc"); break;
|
||||
case 23: SetLkupStage(n, oMod, CLASS_TYPE_SUBLIME_CHORD, "cls_spell_schord"); break;
|
||||
case 24: SetLkupStage(n, oMod, CLASS_TYPE_SUEL_ARCHANAMACH, "cls_spell_suel"); break;
|
||||
case 25: SetLkupStage(n, oMod, CLASS_TYPE_VIGILANT, "cls_spell_vigil"); break;
|
||||
case 26: SetLkupStage(n, oMod, CLASS_TYPE_WARMAGE, "cls_spell_wrmage"); break;
|
||||
case 27: SetLkupStage(n, oMod, CLASS_TYPE_KNIGHT_WEAVE, "cls_spell_kngtwv"); break;
|
||||
case 28: SetLkupStage(n, oMod, CLASS_TYPE_PSYCHIC_ROGUE, "cls_psipw_psyrog"); break;
|
||||
case 29: SetLkupStage(n, oMod, CLASS_TYPE_SHADOWCASTER, "cls_myst_shdcst"); break;
|
||||
case 30: SetLkupStage(n, oMod, CLASS_TYPE_SHADOWSMITH, "cls_myst_shdsmt"); break;
|
||||
case 31: SetLkupStage(n, oMod, CLASS_TYPE_CELEBRANT_SHARESS, "cls_spell_sharss"); break;
|
||||
|
||||
//:: These were all moved to the Bioware spellbooks -Jaysyn
|
||||
//case 14: SetLkupStage(n, oMod, CLASS_TYPE_ASSASSIN, "cls_spell_asasin"); break;
|
||||
//case 46: SetLkupStage(n, oMod, CLASS_TYPE_CULTIST_SHATTERED_PEAK, "cls_spell_cultst"); break;
|
||||
//case 40: SetLkupStage(n, oMod, CLASS_TYPE_NENTYAR_HUNTER, "cls_spell_hunter"); break;
|
||||
//case 28: SetLkupStage(n, oMod, CLASS_TYPE_SHADOWLORD, "cls_spell_tfshad"); break;
|
||||
@@ -528,7 +530,7 @@ int SpellToSpellbookID(int nSpell)
|
||||
int nOutSpellID = GetLocalInt(oWP, /*"PRC_GetRowFromSpellID_" + */IntToString(nSpell));
|
||||
if(nOutSpellID == 0)
|
||||
nOutSpellID = -1;
|
||||
//if(DEBUG) DoDebug("SpellToSpellbookID(" + IntToString(nSpell) + ", " + sFile + ") = " + IntToString(nOutSpellID));
|
||||
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: (nSpell: " + IntToString(nSpell) + ") = nOutSpellID: " + IntToString(nOutSpellID));
|
||||
return nOutSpellID;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Make cls_spcr_*.2da
|
||||
Make blank cls_spell_*.2da
|
||||
Add cls_spgn_*.2da to classes.2da
|
||||
Add class entry in prc_classes.2da
|
||||
Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level
|
||||
Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level (not needed for NWN:EE)
|
||||
Add class to PRCGetSpellSaveDC() in prc_add_spell_dc
|
||||
Add class to GetSpellbookTypeForClass() below
|
||||
Add class to GetAbilityScoreForClass() below
|
||||
@@ -20,6 +20,8 @@ Add class to GetCasterLvl() in prc_inc_spells
|
||||
Add Practiced Spellcaster feat to feat.2da and to PracticedSpellcasting() in prc_inc_castlvl
|
||||
Run the assemble_spellbooks.bat file
|
||||
Make the prc_* scripts in newspellbook. The filenames can be found under the spell entries for the class in spells.2da.
|
||||
Update the fileends for all relevant files in inc_switch_setup
|
||||
Delete prc_data in the \database\ folder before testing new spells.
|
||||
|
||||
Spont:
|
||||
Make cls_spgn_*.2da
|
||||
@@ -41,6 +43,8 @@ Add class to prc_amagsys_gain if(CheckMissingSpells(oPC, CLASS_TYPE_SORCERER, Mi
|
||||
Add class to ExecuteScript("prc_amagsys_gain", oPC) list in EvalPRCFeats in prc_inc_function
|
||||
Run the assemble_spellbooks.bat file
|
||||
Make the prc_* scripts in newspellbook
|
||||
Update the fileends for all relevant files in inc_switch_setup
|
||||
Delete prc_data in the \database\ folder before testing new spells.
|
||||
|
||||
prc_classes.2da entry:
|
||||
Label - name for the class
|
||||
@@ -104,11 +108,10 @@ void ProcessPreparedSpellLevel(object oPC, int nClass, int nSpellLevel, int nLev
|
||||
//#include "prc_effect_inc" //access via prc_inc_core
|
||||
//#include "inc_lookups" //access via prc_inc_core
|
||||
#include "prc_inc_core"
|
||||
#include "inc_sp_gain_mem" //providing child access to prc_inc_core
|
||||
//Must load in this order.
|
||||
#include "inc_sp_gain_mem"
|
||||
//#include "prc_inc_castlvl" //access via prc_inc_core
|
||||
//#include "prc_inc_descrptr" //access via prc_inc_core
|
||||
|
||||
#include "inc_item_props"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
@@ -119,6 +122,7 @@ int GetSpellbookTypeForClass(int nClass)
|
||||
switch(nClass)
|
||||
{
|
||||
case CLASS_TYPE_ARCHIVIST:
|
||||
case CLASS_TYPE_ASSASSIN:
|
||||
case CLASS_TYPE_BLACKGUARD:
|
||||
case CLASS_TYPE_BLIGHTER:
|
||||
case CLASS_TYPE_CLERIC:
|
||||
@@ -141,7 +145,6 @@ int GetSpellbookTypeForClass(int nClass)
|
||||
case CLASS_TYPE_VIGILANT:
|
||||
case CLASS_TYPE_WIZARD:
|
||||
return SPELLBOOK_TYPE_PREPARED;
|
||||
case CLASS_TYPE_ASSASSIN:
|
||||
case CLASS_TYPE_BARD:
|
||||
case CLASS_TYPE_BEGUILER:
|
||||
case CLASS_TYPE_CELEBRANT_SHARESS:
|
||||
@@ -559,7 +562,7 @@ int bKnowsAllClassSpells(int nClass)
|
||||
{
|
||||
//case CLASS_TYPE_WIZARD:
|
||||
case CLASS_TYPE_ARCHIVIST:
|
||||
case CLASS_TYPE_ASSASSIN:
|
||||
//case CLASS_TYPE_ASSASSIN:
|
||||
case CLASS_TYPE_BARD:
|
||||
case CLASS_TYPE_CELEBRANT_SHARESS:
|
||||
case CLASS_TYPE_CULTIST_SHATTERED_PEAK:
|
||||
@@ -580,7 +583,79 @@ int bKnowsAllClassSpells(int nClass)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
|
||||
{
|
||||
// If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either
|
||||
if(!GetSlotCount(nLevel, nSpellLevel, GetAbilityScoreForClass(nClass, oPC), nClass))
|
||||
{
|
||||
if(DEBUG) DoDebug("GetSpellKnownMaxCount: No slots available for " + IntToString(nClass) + " level " + IntToString(nLevel) + " circle " + IntToString(nSpellLevel));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nKnown;
|
||||
string sFile = Get2DACache("classes", "SpellKnownTable", nClass);
|
||||
string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1);
|
||||
|
||||
if(DEBUG)
|
||||
{
|
||||
DoDebug("GetSpellKnownMaxCount Details:");
|
||||
DoDebug("- Class: " + IntToString(nClass));
|
||||
DoDebug("- Passed Level: " + IntToString(nLevel));
|
||||
DoDebug("- Base Class Level: " + IntToString(GetLevelByClass(nClass, oPC)));
|
||||
DoDebug("- Effective Level: " + IntToString(GetSpellslotLevel(nClass, oPC)));
|
||||
DoDebug("- Spell Level: " + IntToString(nSpellLevel));
|
||||
DoDebug("- SpellKnownTable: " + sFile);
|
||||
DoDebug("- MaxKnown from 2DA: " + sKnown);
|
||||
}
|
||||
|
||||
if(sKnown == "")
|
||||
{
|
||||
nKnown = -1;
|
||||
if(DEBUG) DoDebug("GetSpellKnownMaxCount: Problem getting known numbers");
|
||||
}
|
||||
else
|
||||
nKnown = StringToInt(sKnown);
|
||||
|
||||
if(nKnown == -1)
|
||||
return 0;
|
||||
|
||||
// COMPLETELY REWROTE THIS SECTION
|
||||
// Bard and Sorcerer logic for prestige class advancement
|
||||
if(nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD)
|
||||
{
|
||||
int baseClassLevel = GetLevelByClass(nClass, oPC);
|
||||
int effectiveLevel = GetSpellslotLevel(nClass, oPC);
|
||||
|
||||
// Debug the values we're checking
|
||||
if(DEBUG)
|
||||
{
|
||||
DoDebug("Spont caster check - Base level: " + IntToString(baseClassLevel) +
|
||||
", Effective level: " + IntToString(effectiveLevel));
|
||||
}
|
||||
|
||||
// If they have prestige class advancement OR special feats, they should get spells
|
||||
if(effectiveLevel > baseClassLevel ||
|
||||
GetHasFeat(FEAT_DRACONIC_GRACE, oPC) ||
|
||||
GetHasFeat(FEAT_DRACONIC_BREATH, oPC))
|
||||
{
|
||||
// Allow them to get spells - do nothing here, return nKnown at the end
|
||||
if(DEBUG) DoDebug("Spontaneous caster eligible for new spells");
|
||||
}
|
||||
else
|
||||
{
|
||||
// No advancement, no special feats - no new spells
|
||||
if(DEBUG) DoDebug("Spontaneous caster NOT eligible for new spells");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(DEBUG) DoDebug("Final spell known count: " + IntToString(nKnown));
|
||||
return nKnown;
|
||||
}
|
||||
|
||||
|
||||
/* int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
|
||||
{
|
||||
// If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either
|
||||
// @todo Check rules. There might be cases where this doesn't hold
|
||||
@@ -588,22 +663,9 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
|
||||
return 0;
|
||||
int nKnown;
|
||||
string sFile;
|
||||
// Bioware casters use their classes.2da-specified tables
|
||||
/*if( nClass == CLASS_TYPE_WIZARD
|
||||
|| nClass == CLASS_TYPE_SORCERER
|
||||
|| nClass == CLASS_TYPE_BARD
|
||||
|| nClass == CLASS_TYPE_CLERIC
|
||||
|| nClass == CLASS_TYPE_DRUID
|
||||
|| nClass == CLASS_TYPE_PALADIN
|
||||
|| nClass == CLASS_TYPE_RANGER)
|
||||
{*/
|
||||
sFile = Get2DACache("classes", "SpellKnownTable", nClass);
|
||||
/*}
|
||||
else
|
||||
{
|
||||
sFile = Get2DACache("classes", "FeatsTable", nClass);
|
||||
sFile = "cls_spkn" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231
|
||||
}*/
|
||||
|
||||
sFile = Get2DACache("classes", "SpellKnownTable", nClass);
|
||||
|
||||
|
||||
string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1);
|
||||
if(DEBUG) DoDebug("GetSpellKnownMaxCount(" + IntToString(nLevel) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ", " + GetName(oPC) + ") = " + sKnown);
|
||||
@@ -626,6 +688,7 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
|
||||
}
|
||||
return nKnown;
|
||||
}
|
||||
*/
|
||||
|
||||
int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass)
|
||||
{
|
||||
@@ -693,6 +756,44 @@ int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass)
|
||||
}
|
||||
|
||||
int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
|
||||
{
|
||||
// Get the lookup token created by MakeSpellbookLevelLoop()
|
||||
string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel);
|
||||
object oCache = GetObjectByTag(sTag);
|
||||
if(!GetIsObjectValid(oCache))
|
||||
{
|
||||
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount: " + sTag + " is not valid");
|
||||
|
||||
// Add code to create the missing lookup object
|
||||
if(DEBUG) DoDebug("Attempting to create missing spell lookup token");
|
||||
ExecuteScript("prc_create_spellb", oPC);
|
||||
|
||||
// Try again after creating it
|
||||
oCache = GetObjectByTag(sTag);
|
||||
if(!GetIsObjectValid(oCache))
|
||||
{
|
||||
if(DEBUG) DoDebug("Still couldn't create spell lookup token");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("Successfully created spell lookup token");
|
||||
}
|
||||
}
|
||||
|
||||
// Read the total number of spells on the given level and determine how many are already known
|
||||
int nTotal = array_get_size(oCache, "Lkup");
|
||||
int nKnown = GetSpellKnownCurrentCount(oPC, nSpellLevel, nClass);
|
||||
int nUnknown = nTotal - nKnown;
|
||||
|
||||
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown));
|
||||
if(DEBUG) DoDebug(" Total spells in lookup: " + IntToString(nTotal) + ", Known spells: " + IntToString(nKnown));
|
||||
|
||||
return nUnknown;
|
||||
}
|
||||
|
||||
|
||||
/* int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
|
||||
{
|
||||
// Get the lookup token created by MakeSpellbookLevelLoop()
|
||||
string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel);
|
||||
@@ -709,7 +810,7 @@ int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
|
||||
|
||||
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown));
|
||||
return nUnknown;
|
||||
}
|
||||
} */
|
||||
|
||||
void AddSpellUse(object oPC, int nSpellbookID, int nClass, string sFile, string sArrayName, int nSpellbookType, object oSkin, int nFeatID, int nIPFeatID, string sIDX = "")
|
||||
{
|
||||
@@ -850,7 +951,7 @@ void SetupSpells(object oPC, int nClass)
|
||||
int nAbility = GetAbilityScoreForClass(nClass, oPC);
|
||||
int nSpellbookType = GetSpellbookTypeForClass(nClass);
|
||||
|
||||
if(DEBUG) DoDebug("SetupSpells\n"
|
||||
if(DEBUG) DoDebug("SetupSpells()\n"
|
||||
+ "nClass = " + IntToString(nClass) + "\n"
|
||||
+ "nSpellslotLevel = " + IntToString(nLevel) + "\n"
|
||||
+ "nAbility = " + IntToString(nAbility) + "\n"
|
||||
@@ -1178,7 +1279,7 @@ void CastSpontaneousSpell(int nClass, int bInstantSpell = FALSE)
|
||||
else if(GetLocalInt(OBJECT_SELF, "PRC_metamagic_state") == 1)
|
||||
SetLocalInt(OBJECT_SELF, "MetamagicFeatAdjust", 0);
|
||||
}
|
||||
|
||||
if (DEBUG) DoDebug("CastSpontaneousSpell(): nSpellLevel is: "+IntToString(nSpellLevel)+".");
|
||||
CheckSpontSlots(nClass, nSpellID, nSpellLevel);
|
||||
if(GetLocalInt(OBJECT_SELF, "NSB_Cast"))
|
||||
ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE));
|
||||
@@ -1330,6 +1431,8 @@ void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGI
|
||||
|
||||
string sFile = GetFileForClass(nClass);
|
||||
int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID));
|
||||
|
||||
if (DEBUG) DoDebug("inc_newspellbook >> NewSpellbookSpell(): nSpellbookType is: "+IntToString(nSpellbookType)+".");
|
||||
|
||||
// Make sure the caster has uses of this spell remaining
|
||||
// 2009-9-20: Add metamagic feat abilities. -N-S
|
||||
@@ -1371,13 +1474,14 @@ void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGI
|
||||
else if(nSpellLevel > 9)//now test the spell level
|
||||
{
|
||||
nMetamagic = METAMAGIC_NONE;
|
||||
ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is to high! Casting spell without metamagic"));
|
||||
ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is too high! Casting spell without metamagic"));
|
||||
nSpellLevel = nSpellSlotLevel;
|
||||
}
|
||||
else if(GetLocalInt(oPC, "PRC_metamagic_state") == 1)
|
||||
SetLocalInt(oPC, "MetamagicFeatAdjust", 0);
|
||||
}
|
||||
|
||||
|
||||
if (DEBUG) DoDebug("inc_newspellbook >> NewSpellbookSpell(): nSpellLevel is: "+IntToString(nSpellLevel)+".");
|
||||
CheckSpontSlots(nClass, nSpellID, nSpellLevel);
|
||||
if(GetLocalInt(oPC, "NSB_Cast"))
|
||||
ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE));
|
||||
@@ -1460,7 +1564,7 @@ void CheckPrepSlots(int nClass, int nSpellID, int nSpellbookID, int bIsAction =
|
||||
{
|
||||
DeleteLocalInt(OBJECT_SELF, "NSB_Cast");
|
||||
int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellbookID);
|
||||
if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellbookID) + "] = " + IntToString(nCount));
|
||||
if(DEBUG) DoDebug("NewSpellbookSpell >> CheckPrepSlots: NewSpellbookMem_" + IntToString(nClass) + "[SpellbookID: " + IntToString(nSpellbookID) + "] = " + IntToString(nCount));
|
||||
if(nCount < 1)
|
||||
{
|
||||
string sSpellName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
|
||||
@@ -1486,7 +1590,7 @@ void CheckSpontSlots(int nClass, int nSpellID, int nSpellSlotLevel, int bIsActio
|
||||
{
|
||||
DeleteLocalInt(OBJECT_SELF, "NSB_Cast");
|
||||
int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellSlotLevel);
|
||||
if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellSlotLevel) + "] = " + IntToString(nCount));
|
||||
if(DEBUG) DoDebug("NewSpellbookSpell >> CheckSpontSlots: NewSpellbookMem_" + IntToString(nClass) + "[SpellSlotLevel: " + IntToString(nSpellSlotLevel) + "] = " + IntToString(nCount));
|
||||
if(nCount < 1)
|
||||
{
|
||||
// "You have no castings of spells of level " + IntToString(nSpellLevel) + " remaining"
|
||||
@@ -1517,6 +1621,3 @@ void DoCleanUp(int nMetamagic)
|
||||
DeleteLocalInt(OBJECT_SELF, "NSB_SpellLevel");
|
||||
DeleteLocalInt(OBJECT_SELF, "NSB_SpellbookID");
|
||||
}
|
||||
|
||||
//:: Test Void
|
||||
//:: void main (){}
|
||||
@@ -7,8 +7,11 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
//:: Levels up an NPC according to variables set on NPC.
|
||||
void LevelUpSummon(object oSummon, int iTargetLvl);
|
||||
|
||||
// Get the master of oAssociate.
|
||||
object GetMasterNPC(object oAssociate=OBJECT_SELF);
|
||||
object GetMasterNPC(object oAssociate0 = OBJECT_SELF);
|
||||
|
||||
// Returns the associate type of the specified creature.
|
||||
// - Returns ASSOCIATE_TYPE_NONE if the creature is not the associate of anyone.
|
||||
@@ -75,7 +78,6 @@ void DestroySummon(object oSummon)
|
||||
DestroyObject(oSummon);
|
||||
}
|
||||
|
||||
|
||||
object CreateLocalNPC(object oMaster,int nAssociateType,string sTemplate,location loc,int Nth=1,string sTag="")
|
||||
{
|
||||
object oSummon=CreateObject(OBJECT_TYPE_CREATURE,sTemplate,loc,FALSE,sTag);
|
||||
@@ -111,7 +113,7 @@ object CreateLocalNextNPC(object oMaster,int nAssociateType,string sTemplate,loc
|
||||
SetLocalObject(oMaster, IntToString(nAssociateType)+"oHench"+IntToString(nCount), oSummon);
|
||||
SetLocalInt(oSummon, "iAssocNth", nCount);
|
||||
|
||||
SetAssociateState(NW_ASC_HAVE_MASTER,TRUE,oSummon);
|
||||
SetAssociateState(NW_ASC_HAVE_MASTER, TRUE, oSummon);
|
||||
SetAssociateState(NW_ASC_DISTANCE_2_METERS);
|
||||
SetAssociateState(NW_ASC_DISTANCE_4_METERS, FALSE);
|
||||
SetAssociateState(NW_ASC_DISTANCE_6_METERS, FALSE);
|
||||
@@ -122,6 +124,7 @@ object CreateLocalNextNPC(object oMaster,int nAssociateType,string sTemplate,loc
|
||||
return oSummon;
|
||||
|
||||
}
|
||||
|
||||
object GetMasterNPC(object oAssociate=OBJECT_SELF)
|
||||
{
|
||||
object oMaster = GetLocalObject(oAssociate, "oMaster");
|
||||
@@ -220,4 +223,173 @@ int GetAssociateHealMasterNPC()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Levels up a summoned creature based on its master's total casting level,
|
||||
* while respecting configured HD limits and multiclass transition rules.
|
||||
* Should only be called on the NPC onSpawn event.
|
||||
*
|
||||
* This function:
|
||||
* - Retrieves the master<65>s total casting level and clamps it to the creature<72>s
|
||||
* minimum and maximum HD (iMinHD, iMaxHD).
|
||||
* - Repeatedly calls LevelUpHenchman() until the creature reaches that level,
|
||||
* switching classes when the creature's stored "ClassXStart" thresholds are met.
|
||||
*
|
||||
* Local variables recognized on the summoned creature:
|
||||
*
|
||||
* | Variable Name | Purpose |
|
||||
* |-----------------|-------------------------------------------------------------|
|
||||
* | iMinHD | Minimum HD allowed |
|
||||
* | iMaxHD | Maximum HD allowed |
|
||||
* | Class2Start | Level to begin second class progression |
|
||||
* | Class2 | Class type for second progression |
|
||||
* | Class2Package | Package for second progression |
|
||||
* | Class3Start | Level to begin third class progression |
|
||||
* | Class3 | Class type for third progression |
|
||||
* | Class3Package | Package for third progression |
|
||||
* | Class4Start | Level to begin fourth class progression |
|
||||
* | Class4 | Class type for fourth progression |
|
||||
* | Class4Package | Package for fourth progression |
|
||||
*
|
||||
* Behavior notes:
|
||||
* - Leveling continues until the creature reaches the master<65>s effective
|
||||
* casting level (bounded by iMinHD/iMaxHD).
|
||||
* - If LevelUpHenchman() returns 0, the creature shouts a failure message.
|
||||
* - CLASS_TYPE_INVALID causes the creature to level in its current class.
|
||||
*
|
||||
* @param oCreature The summoned creature being leveled. Defaults to OBJECT_SELF.
|
||||
*
|
||||
* @see LevelUpHenchman
|
||||
* @see GetLocalInt
|
||||
* @see GetHitDice
|
||||
*/
|
||||
void LevelUpSummon(object oSummon, int iTargetLvl)
|
||||
{
|
||||
int nCurrentHD = GetHitDice(oSummon);
|
||||
int iNewHD = nCurrentHD;
|
||||
|
||||
// Read multiclassing info from locals
|
||||
int iClass2Start = GetLocalInt(oSummon, "Class2Start");
|
||||
int iClass2 = GetLocalInt(oSummon, "Class2");
|
||||
int iClass2Package = GetLocalInt(oSummon, "Class2Package");
|
||||
|
||||
int iClass3Start = GetLocalInt(oSummon, "Class3Start");
|
||||
int iClass3 = GetLocalInt(oSummon, "Class3");
|
||||
int iClass3Package = GetLocalInt(oSummon, "Class3Package");
|
||||
|
||||
int iClass4Start = GetLocalInt(oSummon, "Class4Start");
|
||||
int iClass4 = GetLocalInt(oSummon, "Class4");
|
||||
int iClass4Package = GetLocalInt(oSummon, "Class4Package");
|
||||
|
||||
int iClass; // current class to level
|
||||
int iPackage; // package to use
|
||||
|
||||
// Main leveling loop
|
||||
while (nCurrentHD < iTargetLvl && nCurrentHD > 0)
|
||||
{
|
||||
// Determine which class and package to use
|
||||
if (iClass4Start != 0 && nCurrentHD >= iClass4Start)
|
||||
{
|
||||
iClass = iClass4;
|
||||
iPackage = iClass4Package;
|
||||
}
|
||||
else if (iClass3Start != 0 && nCurrentHD >= iClass3Start)
|
||||
{
|
||||
iClass = iClass3;
|
||||
iPackage = iClass3Package;
|
||||
}
|
||||
else if (iClass2Start != 0 && nCurrentHD >= iClass2Start)
|
||||
{
|
||||
iClass = iClass2;
|
||||
iPackage = iClass2Package;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Base class (first class in the sheet)
|
||||
iClass = CLASS_TYPE_INVALID; // keeps current
|
||||
iPackage = PACKAGE_INVALID;
|
||||
}
|
||||
|
||||
// Level up one HD
|
||||
iNewHD = LevelUpHenchman(oSummon, iClass, TRUE, iPackage);
|
||||
|
||||
if (iNewHD == 0)
|
||||
{
|
||||
SpeakString(GetName(oSummon) + " failed to level properly!", TALKVOLUME_SHOUT);
|
||||
break;
|
||||
}
|
||||
|
||||
nCurrentHD = iNewHD;
|
||||
}
|
||||
|
||||
// Force the creature to rest to memorize spells
|
||||
// PRCForceRest(oSummon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* void LevelUpSummon(object oSummon, int iTargetLvl)
|
||||
{
|
||||
//get the default hit dice of the summon
|
||||
int nDefaultHD = GetHitDice(oSummon);
|
||||
|
||||
if (DEBUG) DoDebug("inc_npc >> LevelUpSummon: nDefaultHD = " +IntToString(nDefaultHD)+".");
|
||||
|
||||
if (DEBUG) DoDebug("inc_npc >> LevelUpSummon: iTargetLvl = " +IntToString(iTargetLvl)+".");
|
||||
|
||||
//get the multiclassing variables to see if we need to change classes from its base class
|
||||
int iClass2Start = GetLocalInt(oSummon, "Class2Start");
|
||||
int iClass2 = GetLocalInt(oSummon, "Class2");
|
||||
int iClass2Package = GetLocalInt(oSummon, "Class2Package");
|
||||
|
||||
int iClass3Start = GetLocalInt(oSummon, "Class3Start");
|
||||
int iClass3 = GetLocalInt(oSummon, "Class3");
|
||||
int iClass3Package = GetLocalInt(oSummon, "Class3Package");
|
||||
|
||||
int iClass4Start = GetLocalInt(oSummon, "Class4Start");
|
||||
int iClass4 = GetLocalInt(oSummon, "Class4");
|
||||
int iClass4Package = GetLocalInt(oSummon, "Class4Package");
|
||||
|
||||
//check for zero cause thats an error
|
||||
//if creatures are not leveling then best bet is they are not legal creatures
|
||||
while( (nDefaultHD < iTargetLvl) && (nDefaultHD > 0) )
|
||||
{
|
||||
//check the multiclassing numbers to change classes
|
||||
if( (iClass4Start != 0) && (nDefaultHD >= iClass4Start) )
|
||||
{
|
||||
//level up using the new class and Packageage
|
||||
nDefaultHD = LevelUpHenchman(oSummon, iClass4 ,TRUE, iClass4Package);
|
||||
|
||||
if(nDefaultHD == 0)
|
||||
SpeakString(GetName(oSummon) + " Failed on fourth class", TALKVOLUME_SHOUT);
|
||||
}
|
||||
else if( (iClass3Start != 0) && (nDefaultHD >= iClass3Start) )
|
||||
{
|
||||
//level up using the new class and Packageage
|
||||
nDefaultHD = LevelUpHenchman(oSummon, iClass3 ,TRUE, iClass3Package);
|
||||
|
||||
if(nDefaultHD == 0)
|
||||
SpeakString(GetName(oSummon) + " Failed on third class", TALKVOLUME_SHOUT);
|
||||
}
|
||||
else if( (iClass2Start != 0) && (nDefaultHD >= iClass2Start) )
|
||||
{
|
||||
//level up using the new class and Packageage
|
||||
nDefaultHD = LevelUpHenchman(oSummon, iClass2 ,TRUE, iClass2Package);
|
||||
|
||||
if(nDefaultHD == 0)
|
||||
SpeakString(GetName(oSummon) + " Failed on second class", TALKVOLUME_SHOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
//just level up using the class it already has
|
||||
nDefaultHD = LevelUpHenchman(oSummon, CLASS_TYPE_INVALID ,TRUE);
|
||||
|
||||
if(nDefaultHD == 0)
|
||||
SpeakString(GetName(oSummon) + " Failed to level properly", TALKVOLUME_SHOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//:: void main() {}
|
||||
@@ -3433,6 +3433,7 @@ int PrimoGetWeaponSize(object oItem)
|
||||
case BASE_ITEM_LIGHTFLAIL:
|
||||
case BASE_ITEM_KATANA:
|
||||
case BASE_ITEM_MAGICSTAFF:
|
||||
case BASE_ITEM_CRAFTED_SCEPTER:
|
||||
case BASE_ITEM_LONGSWORD:
|
||||
case BASE_ITEM_TRIDENT:
|
||||
case BASE_ITEM_MORNINGSTAR:
|
||||
|
||||
@@ -30,6 +30,7 @@ int GetDamageFromConstant(int nIPConst);
|
||||
void DoFrostRend(object oTarget, object oAttacker, object oWeapon);
|
||||
|
||||
#include "moi_inc_moifunc"
|
||||
#include "prc_inc_combat"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function defintions */
|
||||
|
||||
@@ -17,9 +17,6 @@ Created: May 1, 2008
|
||||
|
||||
//:: Updated for .35 by Jaysyn 2023/03/11
|
||||
|
||||
//:: Test Void
|
||||
//void main (){}
|
||||
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Constants
|
||||
//:://////////////////////////////////////////////
|
||||
@@ -63,6 +60,14 @@ string GetMetaMagicString(int nMetaMagic);
|
||||
int GetMetaMagicFromFeat(int nFeat);
|
||||
int GetMetaMagicOfCaster(object oPC = OBJECT_SELF);
|
||||
|
||||
string GetFileForClass(int nClass);
|
||||
int GetSpellslotLevel(int nClass, object oPC);
|
||||
int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC);
|
||||
int GetSpellbookTypeForClass(int nClass);
|
||||
|
||||
#include "inc_pers_array"
|
||||
#include "inc_2dacache"
|
||||
|
||||
// name of the new spellbook file (cls_spell_*)
|
||||
string GetNSBDefinitionFileName(int nClass)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ void CreateSwitchNameArray();
|
||||
|
||||
#include "prc_inc_array" // Needs direct include instead of inc_utility
|
||||
#include "prc_inc_switch"
|
||||
#include "inc_2dacache"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
@@ -221,9 +222,9 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_bard", 144);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_beguil", 142);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_blkgrd", 47);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_dnecro", 137);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_dnecro", 138);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_duskbl", 69);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_favsol", 290);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_favsol", 300);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_harper", 35);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_healer", 77);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spcr_hexbl", 73);
|
||||
@@ -251,9 +252,9 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_bard", 169);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_beguil", 119);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_blkgrd", 163);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_dnecro", 134);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_dnecro", 135);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_duskbl", 84);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_favsol", 363);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_favsol", 373);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_harper", 21);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_healer", 271);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_hexbl", 79);
|
||||
@@ -267,7 +268,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_sod", 110);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_sohei", 131);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_sol", 114);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_sorc", 541);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_sorc", 550);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_suel", 160);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_templ", 95);
|
||||
SetPRCSwitch("PRC_FILE_END_cls_spell_tfshad", 70);
|
||||
@@ -335,7 +336,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_craft_golem", 40);
|
||||
SetPRCSwitch("PRC_FILE_END_craft_ring", 41);
|
||||
SetPRCSwitch("PRC_FILE_END_craft_weapon", 46);
|
||||
SetPRCSwitch("PRC_FILE_END_craft_wondrous", 115);
|
||||
SetPRCSwitch("PRC_FILE_END_craft_wondrous", 131);
|
||||
SetPRCSwitch("PRC_FILE_END_creaturesize", 5);
|
||||
SetPRCSwitch("PRC_FILE_END_creaturespeed", 8);
|
||||
SetPRCSwitch("PRC_FILE_END_crtemplates", 10);
|
||||
@@ -355,7 +356,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_poison", 100);
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_props", 27);
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_scroll", 3999);
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_spells", 19348);
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_spells", 20000);
|
||||
SetPRCSwitch("PRC_FILE_END_des_crft_weapon", 29);
|
||||
SetPRCSwitch("PRC_FILE_END_des_cutconvdur", 26);
|
||||
SetPRCSwitch("PRC_FILE_END_des_feat2item", 1000);
|
||||
@@ -408,7 +409,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_ammocost", 15);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_ammotype", 2);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_amount", 4);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_aoe", 7);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_aoe", 8);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_arcspell", 19);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_base1", -1);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_bladecost", 5);
|
||||
@@ -423,15 +424,15 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_damvulcost", 7);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_decvalue1", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_decvalue2", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_feats", 24819);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_feats", 26999);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_immuncost", 7);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_immunity", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_incvalue1", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_incvalue2", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_kitcost", 50);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_lightcost", 4);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_matcost", 77);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_material", 77);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_matcost", 145);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_material", 145);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_maxpp", 8);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_meleecost", 20);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_metamagic", 6);
|
||||
@@ -458,11 +459,11 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_soakcost", 50);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_speed_dec", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_speed_enh", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spellcost", 243);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spellcost", 298);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spellcstr", 42);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spelllvcost", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spelllvlimm", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spells", 1456);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spells", 1552);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_spellshl", 7);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_srcost", 99);
|
||||
SetPRCSwitch("PRC_FILE_END_iprp_staminacost", -1);
|
||||
@@ -492,9 +493,9 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_itmwizwands", 38);
|
||||
SetPRCSwitch("PRC_FILE_END_keymap", 70);
|
||||
SetPRCSwitch("PRC_FILE_END_lightcolor", 32);
|
||||
SetPRCSwitch("PRC_FILE_END_loadhints", 88);
|
||||
SetPRCSwitch("PRC_FILE_END_loadhints", 101);
|
||||
SetPRCSwitch("PRC_FILE_END_loadscreens", 259);
|
||||
SetPRCSwitch("PRC_FILE_END_masterfeats", 113);
|
||||
SetPRCSwitch("PRC_FILE_END_masterfeats", 125);
|
||||
SetPRCSwitch("PRC_FILE_END_materialcomp", 200);
|
||||
SetPRCSwitch("PRC_FILE_END_metamagic", 6);
|
||||
SetPRCSwitch("PRC_FILE_END_namefilter", 3);
|
||||
@@ -720,7 +721,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_polymorph", 155);
|
||||
SetPRCSwitch("PRC_FILE_END_portraits", 1300);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_craft_alchem", 37);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_craft_gen_it", 204);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_craft_gen_it", 253);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_craft_poison", 62);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_domains", 59);
|
||||
SetPRCSwitch("PRC_FILE_END_prc_familiar", 10);
|
||||
@@ -767,7 +768,7 @@ void SetDefaultFileEnds()
|
||||
SetPRCSwitch("PRC_FILE_END_soundset", 453);
|
||||
SetPRCSwitch("PRC_FILE_END_soundsettype", 4);
|
||||
SetPRCSwitch("PRC_FILE_END_soundtypes", 1);
|
||||
SetPRCSwitch("PRC_FILE_END_spells", 19348);
|
||||
SetPRCSwitch("PRC_FILE_END_spells", 19400);
|
||||
//SetPRCSwitch("PRC_FILE_END_spellschools", 9);
|
||||
SetPRCSwitch("PRC_FILE_END_statescripts", 35);
|
||||
SetPRCSwitch("PRC_FILE_END_stringtokens", 92);
|
||||
@@ -866,6 +867,31 @@ void CreateSwitchNameArray()
|
||||
//if you add more switches, add them to this list
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DEBUG);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_COMBAT_DEBUG);
|
||||
|
||||
//craft
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CRAFT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MULTIPLIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MAX);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MIN);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BREW_POTION_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SCRIBE_SCROLL_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_WAND_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_ROD_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_STAFF_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_BASE_ITEMS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_MAXLEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_SCRIBESCROLL_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_MAXLEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CREATEINFUSION_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_ARBITRARY);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_COST_SCALE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_TIME_SCALE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_OPTIONAL_HERBS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_SCEPTER_CASTER_LEVEL);
|
||||
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_MATERIAL_COMPONENTS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_COMPONENTS_SHOP);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_TRUESEEING);
|
||||
@@ -876,6 +902,10 @@ void CreateSwitchNameArray()
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_HARM);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_NEUTRALIZE_POISON);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIOWARE_REMOVE_DISEASE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOWED_TO_REMOVE_FRIENDLY_SPELLS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_ALLOWED_TO_SEE_HOSTILE_SPELLS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BIO_UNLEARN);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_UNLEARN_SPELL_MAXNR);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_BIOWARE_DURATION);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_LOCAL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_TIMESTOP_NO_HOSTILE);
|
||||
@@ -992,7 +1022,7 @@ void CreateSwitchNameArray()
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_WEAPON_POISON_COUNT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_USES_PER_WEAPON_POISON_DIE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_POISON_ALLOW_CLEAN_IN_EQUIP);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_POISON_USE_INGREDIENST);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_POISON_USE_INGREDIENTS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PSI_ASTRAL_CONSTRUCT_USE_2DA);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PSI_ASTRAL_CONSTRUCT_DUR_MOD);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_PNP_RAPID_METABOLISM);
|
||||
@@ -1056,29 +1086,31 @@ void CreateSwitchNameArray()
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_UNICORN_SQL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_LETOSCRIPT_GETNEWESTBIC);
|
||||
|
||||
//craft
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_DISABLE_CRAFT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MULTIPLIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MAX);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_TIMER_MIN);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_BREW_POTION_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_SCRIBE_SCROLL_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_WAND_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_ROD_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_STAFF_CASTER_LEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_BASE_ITEMS);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_BREWPOTION_MAXLEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_BREWPOTION_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_SCRIBESCROLL_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_CRAFTWAND_MAXLEVEL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_CRAFTWAND_COSTMODIFIER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_ARBITRARY);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_COST_SCALE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_TIME_SCALE);
|
||||
|
||||
//spells
|
||||
|
||||
//shifter
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPECHANGE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_USECR);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_HUGE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_LARGE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_MEDIUM);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_SMALL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_S_TINY);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OUTSIDER);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ELEMENTAL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_CONSTRUCT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_UNDEAD);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_DRAGON);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ABERRATION);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_OOZE);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MAGICALBEAST);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_GIANT);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_VERMIN);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_BEAST);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_ANIMAL);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_MONSTROUSHUMANOID);
|
||||
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PNP_SHFT_F_HUMANOID);
|
||||
|
||||
//general
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "prc_inc_clsfunc"
|
||||
#include "prc_inc_sp_tch"
|
||||
|
||||
int GetBlastDamageDices(object oInvoker, int nInvokerLevel)
|
||||
{
|
||||
|
||||
@@ -135,6 +135,9 @@ int GetHasInvocation(int nInvocation, object oCreature = OBJECT_SELF);
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
int GetPrimaryInvocationClass(object oCreature = OBJECT_SELF);
|
||||
int GetInvocationPRCLevels(object oCaster);
|
||||
|
||||
#include "inc_item_props"
|
||||
#include "prc_x2_itemprop"
|
||||
#include "inc_lookups"
|
||||
|
||||
@@ -123,7 +123,7 @@ void DeleteLocalInvocation(object oObject, string sName);
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
//#include "inv_inc_invfunc" //Access in parent
|
||||
#include "inv_inc_invfunc" //Access in parent
|
||||
#include "prc_spellf_inc"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
@@ -77,6 +77,15 @@ int PreInvocationCastCode()
|
||||
|
||||
int nContinue = !ExecuteScriptAndReturnInt("prespellcode", oInvoker);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Block forsakers from using invocations
|
||||
//---------------------------------------------------------------------------
|
||||
if(GetLevelByClass(CLASS_TYPE_FORSAKER, oInvoker) > 0)
|
||||
{
|
||||
SendMessageToPC(oInvoker, "Forsakers cannot use invocations.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Break any spell require maintaining concentration
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -168,3 +177,4 @@ int PreInvocationCastCode()
|
||||
return nContinue;
|
||||
}
|
||||
|
||||
//:: void main (){}
|
||||
@@ -1170,7 +1170,10 @@ int GetMaxEssentiaCapacityFeat(object oMeldshaper)
|
||||
{
|
||||
int nMax = 1; // Always can invest one
|
||||
int nHD = GetHitDice(oMeldshaper);
|
||||
if (nHD >= 31) nMax = 5;
|
||||
if (nHD >= 61) nMax = 8;
|
||||
else if (nHD >= 51) nMax = 7;
|
||||
else if (nHD >= 41) nMax = 6;
|
||||
else if (nHD >= 31) nMax = 5;
|
||||
else if (nHD >= 18) nMax = 4;
|
||||
else if (nHD >= 12) nMax = 3;
|
||||
else if (nHD >= 6) nMax = 2;
|
||||
@@ -1182,7 +1185,7 @@ int GetMaxEssentiaCapacityFeat(object oMeldshaper)
|
||||
// Don't allow more than they have
|
||||
if (nMax > GetTotalUsableEssentia(oMeldshaper)) nMax = GetTotalUsableEssentia(oMeldshaper);
|
||||
|
||||
//if (DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
|
||||
if(DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
|
||||
return nMax;
|
||||
}
|
||||
|
||||
|
||||
623
src/include/nw_inc_gff.nss
Normal file
623
src/include/nw_inc_gff.nss
Normal file
@@ -0,0 +1,623 @@
|
||||
// This is a helper library for advanced use: It allows constructing arbitrary gff data.
|
||||
// You can then spawn your object via JsonToObject().
|
||||
//
|
||||
// The data format is the same as https://github.com/niv/neverwinter.nim@1.4.3+.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// json j = GffCreateObject(OBJECT_TYPE_ITEM);
|
||||
// j = GffAddInt(j, "BaseItem", BASE_ITEM_BELT);
|
||||
// j = GffAddInt(j, "ModelPart1", 12);
|
||||
// j = GffAddLocString(j, "LocalizedName", "hi!");
|
||||
// object belt = JsonToObject(j, GetLocation(OBJECT_SELF));
|
||||
|
||||
|
||||
const string GFF_FIELD_TYPE_STRUCT = "struct";
|
||||
const string GFF_FIELD_TYPE_LIST = "list";
|
||||
const string GFF_FIELD_TYPE_BYTE = "byte";
|
||||
const string GFF_FIELD_TYPE_CHAR = "char";
|
||||
const string GFF_FIELD_TYPE_WORD = "word";
|
||||
const string GFF_FIELD_TYPE_SHORT = "short";
|
||||
const string GFF_FIELD_TYPE_DWORD = "dword";
|
||||
const string GFF_FIELD_TYPE_INT = "int";
|
||||
const string GFF_FIELD_TYPE_DWORD64 = "dword64";
|
||||
const string GFF_FIELD_TYPE_INT64 = "int64";
|
||||
const string GFF_FIELD_TYPE_FLOAT = "float";
|
||||
const string GFF_FIELD_TYPE_DOUBLE = "double";
|
||||
const string GFF_FIELD_TYPE_RESREF = "resref";
|
||||
const string GFF_FIELD_TYPE_STRING = "cexostring";
|
||||
const string GFF_FIELD_TYPE_LOC_STRING = "cexolocstring";
|
||||
|
||||
|
||||
// Create a empty object of the given type. You need to manually fill in all
|
||||
// GFF data with GffAddXXX. This will require understanding of the GFF file format
|
||||
// and what data fields each object type requires.
|
||||
json GffCreateObject(int nObjectType);
|
||||
// Create a combined area format(CAF) object. You need to manually create the ARE and GIT objects with their required data fields.
|
||||
json GffCreateArea(json jARE, json jGIT);
|
||||
|
||||
// Returns the OBJECT_TYPE_* of jGff.
|
||||
// Note: Will return 0 for invalid object types, including areas.
|
||||
int GffGetObjectType(json jGff);
|
||||
// Returns TRUE if jGff is a combined area format(CAF) object.
|
||||
int GffGetIsArea(json jGff);
|
||||
|
||||
// Returns TRUE if a field named sLabel of sType exists in jGff.
|
||||
// * sLabel: Can be a json pointer(path) without the starting /, see the documentation of JsonPointer() for details.
|
||||
// * sType: An optional GFF_FIELD_TYPE_*, leave empty to check if sLabel exists regardless of type.
|
||||
int GffGetFieldExists(json jGff, string sLabel, string sType = "");
|
||||
|
||||
|
||||
// Add a new field, will overwrite any existing fields with the same label even if the type is different.
|
||||
// Returns a json null value on error with GetJsonError() filled in.
|
||||
//
|
||||
// sLabel can be a json pointer(path) without the starting /, see the documentation of JsonPointer() for details.
|
||||
// For example, to add the tag of an area to an empty combined area format(CAF) object you can do the following:
|
||||
// json jArea = GffCreateArea(JsonObject(), JsonObject());
|
||||
// jArea = GffAddString(jArea, "ARE/value/Tag", "AREA_TAG");
|
||||
|
||||
json GffAddStruct(json jGff, string sLabel, json jStruct, int nType = -1);
|
||||
json GffAddList(json jGff, string sLabel, json jList);
|
||||
json GffAddByte(json jGff, string sLabel, int v);
|
||||
json GffAddChar(json jGff, string sLabel, int v);
|
||||
json GffAddWord(json jGff, string sLabel, int v);
|
||||
json GffAddShort(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffAddDword(json jGff, string sLabel, int v);
|
||||
json GffAddInt(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffAddDword64(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffAddInt64(json jGff, string sLabel, int v);
|
||||
json GffAddFloat(json jGff, string sLabel, float v);
|
||||
// Note: Only data of type float will fit, because that's all that NWScript supports.
|
||||
json GffAddDouble(json jGff, string sLabel, float v);
|
||||
json GffAddResRef(json jGff, string sLabel, string v);
|
||||
json GffAddString(json jGff, string sLabel, string v);
|
||||
json GffAddLocString(json jGff, string sLabel, string v, int nStrRef = -1);
|
||||
|
||||
|
||||
// Replace a field, the type must match and the field must exist.
|
||||
// Returns a json null value on error with GetJsonError() filled in.
|
||||
//
|
||||
// sLabel can be a json pointer(path) without the starting /, see the documentation of JsonPointer() for details.
|
||||
// For example, to replace the name of an area in a combined area format(CAF) object you can do the following:
|
||||
// json jArea = ObjectToStruct(GetFirstArea());
|
||||
// jArea = GffReplaceLocString(jArea, "ARE/value/Name", "New Area Name");
|
||||
|
||||
json GffReplaceStruct(json jGff, string sLabel, json jStruct);
|
||||
json GffReplaceList(json jGff, string sLabel, json jList);
|
||||
json GffReplaceByte(json jGff, string sLabel, int v);
|
||||
json GffReplaceChar(json jGff, string sLabel, int v);
|
||||
json GffReplaceWord(json jGff, string sLabel, int v);
|
||||
json GffReplaceShort(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffReplaceDword(json jGff, string sLabel, int v);
|
||||
json GffReplaceInt(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffReplaceDword64(json jGff, string sLabel, int v);
|
||||
// Note: Only data of type int32 will fit, because that's all that NWScript supports.
|
||||
json GffReplaceInt64(json jGff, string sLabel, int v);
|
||||
json GffReplaceFloat(json jGff, string sLabel, float v);
|
||||
// Note: Only data of type float will fit, because that's all that NWScript supports.
|
||||
json GffReplaceDouble(json jGff, string sLabel, float v);
|
||||
json GffReplaceResRef(json jGff, string sLabel, string v);
|
||||
json GffReplaceString(json jGff, string sLabel, string v);
|
||||
json GffReplaceLocString(json jGff, string sLabel, string v, int nStrRef = -1);
|
||||
|
||||
|
||||
// Remove a field, the type must match and the field must exist.
|
||||
// Returns a json null value on error with GetJsonError() filled in.
|
||||
//
|
||||
// sLabel can be a json pointer(path) without the starting /, see the documentation of JsonPointer() for details.
|
||||
// For example, to remove all placeables from an area in a combined area format(CAF) object you can do the following:
|
||||
// json jArea = ObjectToStruct(GetFirstArea());
|
||||
// jArea = GffRemoveList(jArea, "GIT/value/Placeable List");
|
||||
|
||||
json GffRemoveStruct(json jGff, string sLabel);
|
||||
json GffRemoveList(json jGff, string sLabel);
|
||||
json GffRemoveByte(json jGff, string sLabel);
|
||||
json GffRemoveChar(json jGff, string sLabel);
|
||||
json GffRemoveWord(json jGff, string sLabel);
|
||||
json GffRemoveShort(json jGff, string sLabel);
|
||||
json GffRemoveDword(json jGff, string sLabel);
|
||||
json GffRemoveInt(json jGff, string sLabel);
|
||||
json GffRemoveDword64(json jGff, string sLabel);
|
||||
json GffRemoveInt64(json jGff, string sLabel);
|
||||
json GffRemoveFloat(json jGff, string sLabel);
|
||||
json GffRemoveDouble(json jGff, string sLabel);
|
||||
json GffRemoveResRef(json jGff, string sLabel);
|
||||
json GffRemoveString(json jGff, string sLabel);
|
||||
json GffRemoveLocString(json jGff, string sLabel);
|
||||
|
||||
|
||||
// Get a field's value as json object.
|
||||
// Returns a json null value on error with GetJsonError() filled in.
|
||||
//
|
||||
// Note: Json types do not implicitly convert between types, this means you cannot convert a JsonInt to a string with JsonGetString(), etc.
|
||||
// You may need to check the type with JsonGetType() and then do the appropriate cast yourself.
|
||||
// For GffGet*() functions the json type returned is noted in the function description.
|
||||
//
|
||||
// Example:
|
||||
// INCORRECT: string s = JsonGetString(GffGetInt());
|
||||
// CORRECT: string s = IntToString(JsonGetInt(GffGetInt()));
|
||||
//
|
||||
// sLabel can be a json pointer(path) without the starting /, see the documentation of JsonPointer() for details.
|
||||
// For example, to get the resref of an area in a combined area format(CAF) object you can do the following:
|
||||
// json jResRef = GffGetResRef(ObjectToStruct(GetFirstArea()), "ARE/value/ResRef");
|
||||
// if (jResRef != JsonNull())
|
||||
// {
|
||||
// string sResRef = JsonGetString(jResRef);
|
||||
// }
|
||||
// else
|
||||
// WriteTimestampedLogEntry("Failed to get area ResRef: " + JsonGetError(jResRef));
|
||||
|
||||
// Returns the struct as JsonObject() on success.
|
||||
json GffGetStruct(json jGff, string sLabel);
|
||||
// Returns a JsonArray() with all the list elements on success.
|
||||
json GffGetList(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetByte(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetChar(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetWord(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetShort(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetDword(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetInt(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetDword64(json jGff, string sLabel);
|
||||
// Returns a JsonInt() on success.
|
||||
json GffGetInt64(json jGff, string sLabel);
|
||||
// Returns a JsonFloat() on success.
|
||||
json GffGetFloat(json jGff, string sLabel);
|
||||
// Returns a JsonFloat() on success.
|
||||
json GffGetDouble(json jGff, string sLabel);
|
||||
// Returns a JsonString() on success.
|
||||
json GffGetResRef(json jGff, string sLabel);
|
||||
// Returns a JsonString() on success.
|
||||
json GffGetString(json jGff, string sLabel);
|
||||
// Returns a JsonObject() on success.
|
||||
// Key "0" will have a JsonString() with the string, if set.
|
||||
// Key "id" will have a JsonInt() with the strref, if set.
|
||||
json GffGetLocString(json jGff, string sLabel);
|
||||
|
||||
|
||||
// *** Internal Helper Functions
|
||||
json AddPatchOperation(json jPatchArray, string sOp, string sPath, json jValue)
|
||||
{
|
||||
json jOperation = JsonObject();
|
||||
jOperation = JsonObjectSet(jOperation, "op", JsonString(sOp));
|
||||
jOperation = JsonObjectSet(jOperation, "path", JsonString(sPath));
|
||||
jOperation = JsonObjectSet(jOperation, "value", jValue);
|
||||
return JsonArrayInsert(jPatchArray, jOperation);
|
||||
}
|
||||
|
||||
json GffAddField(json jGff, string sLabel, string sType, json jValue, int nType = -1)
|
||||
{
|
||||
json jField = JsonObject();
|
||||
jField = JsonObjectSet(jField, "type", JsonString(sType));
|
||||
jField = JsonObjectSet(jField, "value", jValue);
|
||||
if (sType == GFF_FIELD_TYPE_STRUCT && nType != -1)
|
||||
jField = JsonObjectSet(jField, "__struct_id", JsonInt(nType));
|
||||
|
||||
return JsonPatch(jGff, AddPatchOperation(JsonArray(), "add", "/" + sLabel, jField));
|
||||
}
|
||||
|
||||
json GffReplaceField(json jGff, string sLabel, string sType, json jValue)
|
||||
{
|
||||
json jPatch = JsonArray();
|
||||
jPatch = AddPatchOperation(jPatch, "test", "/" + sLabel + "/type", JsonString(sType));
|
||||
jPatch = AddPatchOperation(jPatch, "replace", "/" + sLabel + "/value", jValue);
|
||||
return JsonPatch(jGff, jPatch);
|
||||
}
|
||||
|
||||
json GffRemoveField(json jGff, string sLabel, string sType)
|
||||
{
|
||||
json jPatch = JsonArray();
|
||||
jPatch = AddPatchOperation(jPatch, "test", "/" + sLabel + "/type", JsonString(sType));
|
||||
jPatch = AddPatchOperation(jPatch, "remove", "/" + sLabel, JsonNull());
|
||||
return JsonPatch(jGff, jPatch);
|
||||
}
|
||||
|
||||
json GffGetFieldType(json jGff, string sLabel)
|
||||
{
|
||||
return JsonPointer(jGff, "/" + sLabel + "/type");
|
||||
}
|
||||
|
||||
json GffGetFieldValue(json jGff, string sLabel)
|
||||
{
|
||||
return JsonPointer(jGff, "/" + sLabel + "/value");
|
||||
}
|
||||
|
||||
json GffGetField(json jGff, string sLabel, string sType)
|
||||
{
|
||||
json jType = GffGetFieldType(jGff, sLabel);
|
||||
if (jType == JsonNull())
|
||||
return jType;
|
||||
else if (jType != JsonString(sType))
|
||||
return JsonNull("field type does not match");
|
||||
else
|
||||
return GffGetFieldValue(jGff, sLabel);
|
||||
}
|
||||
|
||||
json GffLocString(string v, int nStrRef = -1)
|
||||
{
|
||||
json jLocString = JsonObject();
|
||||
if (v != "")
|
||||
jLocString = JsonObjectSet(jLocString, "0", JsonString(v)); // english/any
|
||||
if (nStrRef != -1)
|
||||
jLocString = JsonObjectSet(jLocString, "id", JsonInt(nStrRef));
|
||||
|
||||
return jLocString;
|
||||
}
|
||||
//***
|
||||
|
||||
json GffCreateObject(int nObjectType)
|
||||
{
|
||||
string ot;
|
||||
if (nObjectType == OBJECT_TYPE_CREATURE) ot = "UTC ";
|
||||
else if (nObjectType == OBJECT_TYPE_ITEM) ot = "UTI ";
|
||||
else if (nObjectType == OBJECT_TYPE_TRIGGER) ot = "UTT ";
|
||||
else if (nObjectType == OBJECT_TYPE_DOOR) ot = "UTD ";
|
||||
else if (nObjectType == OBJECT_TYPE_WAYPOINT) ot = "UTW ";
|
||||
else if (nObjectType == OBJECT_TYPE_PLACEABLE) ot = "UTP ";
|
||||
else if (nObjectType == OBJECT_TYPE_STORE) ot = "UTM ";
|
||||
else if (nObjectType == OBJECT_TYPE_ENCOUNTER) ot = "UTE ";
|
||||
|
||||
if (ot == "") return JsonNull("invalid object type");
|
||||
|
||||
json ret = JsonObject();
|
||||
ret = JsonObjectSet(ret, "__data_type", JsonString(ot));
|
||||
return ret;
|
||||
}
|
||||
|
||||
json GffCreateArea(json jARE, json jGIT)
|
||||
{
|
||||
json jCAF = JsonObject();
|
||||
jCAF = JsonObjectSet(jCAF, "__data_type", JsonString("CAF "));
|
||||
jCAF = GffAddStruct(jCAF, "ARE", jARE, 0);
|
||||
jCAF = GffAddStruct(jCAF, "GIT", jGIT, 1);
|
||||
return jCAF;
|
||||
}
|
||||
|
||||
|
||||
int GffGetObjectType(json jGff)
|
||||
{
|
||||
json jDataType = JsonObjectGet(jGff, "__data_type");
|
||||
if (jDataType == JsonNull())
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
string sObjectType = JsonGetString(jDataType);
|
||||
|
||||
if (sObjectType == "UTC ") return OBJECT_TYPE_CREATURE;
|
||||
else if (sObjectType == "UTI ") return OBJECT_TYPE_ITEM;
|
||||
else if (sObjectType == "UTT ") return OBJECT_TYPE_TRIGGER;
|
||||
else if (sObjectType == "UTD ") return OBJECT_TYPE_DOOR;
|
||||
else if (sObjectType == "UTW ") return OBJECT_TYPE_WAYPOINT;
|
||||
else if (sObjectType == "UTP ") return OBJECT_TYPE_PLACEABLE;
|
||||
else if (sObjectType == "UTM ") return OBJECT_TYPE_STORE;
|
||||
else if (sObjectType == "UTE ") return OBJECT_TYPE_ENCOUNTER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GffGetIsArea(json jGff)
|
||||
{
|
||||
return JsonObjectGet(jGff, "__data_type") == JsonString("CAF ");
|
||||
}
|
||||
|
||||
int GffGetFieldExists(json jGff, string sLabel, string sType = "")
|
||||
{
|
||||
json jFieldType = GffGetFieldType(jGff, sLabel);
|
||||
return sType == "" ? jFieldType != JsonNull() : jFieldType == JsonString(sType);
|
||||
}
|
||||
|
||||
|
||||
json GffAddStruct(json jGff, string sLabel, json jStruct, int nType = -1)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_STRUCT, jStruct, nType);
|
||||
}
|
||||
|
||||
json GffAddList(json jGff, string sLabel, json jList)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_LIST, jList);
|
||||
}
|
||||
|
||||
json GffAddByte(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_BYTE, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddChar(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_CHAR, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddWord(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_WORD, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddShort(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_SHORT, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddDword(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_DWORD, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddInt(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_INT, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddDword64(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_DWORD64, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddInt64(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_INT64, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffAddFloat(json jGff, string sLabel, float v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_FLOAT, JsonFloat(v));
|
||||
}
|
||||
|
||||
json GffAddDouble(json jGff, string sLabel, float v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_DOUBLE, JsonFloat(v));
|
||||
}
|
||||
|
||||
json GffAddResRef(json jGff, string sLabel, string v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_RESREF, JsonString(v));
|
||||
}
|
||||
|
||||
json GffAddString(json jGff, string sLabel, string v)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_STRING, JsonString(v));
|
||||
}
|
||||
|
||||
json GffAddLocString(json jGff, string sLabel, string v, int nStrRef = -1)
|
||||
{
|
||||
return GffAddField(jGff, sLabel, GFF_FIELD_TYPE_LOC_STRING, GffLocString(v, nStrRef));
|
||||
}
|
||||
|
||||
|
||||
json GffReplaceStruct(json jGff, string sLabel, json jStruct)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_STRUCT, jStruct);
|
||||
}
|
||||
|
||||
json GffReplaceList(json jGff, string sLabel, json jList)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_LIST, jList);
|
||||
}
|
||||
|
||||
json GffReplaceByte(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_BYTE, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceChar(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_CHAR, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceWord(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_WORD, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceShort(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_SHORT, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceDword(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_DWORD, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceInt(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_INT, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceDword64(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_DWORD64, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceInt64(json jGff, string sLabel, int v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_INT64, JsonInt(v));
|
||||
}
|
||||
|
||||
json GffReplaceFloat(json jGff, string sLabel, float v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_FLOAT, JsonFloat(v));
|
||||
}
|
||||
|
||||
json GffReplaceDouble(json jGff, string sLabel, float v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_DOUBLE, JsonFloat(v));
|
||||
}
|
||||
|
||||
json GffReplaceResRef(json jGff, string sLabel, string v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_RESREF, JsonString(v));
|
||||
}
|
||||
|
||||
json GffReplaceString(json jGff, string sLabel, string v)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_STRING, JsonString(v));
|
||||
}
|
||||
|
||||
json GffReplaceLocString(json jGff, string sLabel, string v, int nStrRef = -1)
|
||||
{
|
||||
return GffReplaceField(jGff, sLabel, GFF_FIELD_TYPE_LOC_STRING, GffLocString(v, nStrRef));
|
||||
}
|
||||
|
||||
|
||||
json GffRemoveStruct(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_STRUCT);
|
||||
}
|
||||
|
||||
json GffRemoveList(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_LIST);
|
||||
}
|
||||
|
||||
json GffRemoveByte(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_BYTE);
|
||||
}
|
||||
|
||||
json GffRemoveChar(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_CHAR);
|
||||
}
|
||||
|
||||
json GffRemoveWord(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_WORD);
|
||||
}
|
||||
|
||||
json GffRemoveShort(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_SHORT);
|
||||
}
|
||||
|
||||
json GffRemoveDword(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_DWORD);
|
||||
}
|
||||
|
||||
json GffRemoveInt(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_INT);
|
||||
}
|
||||
|
||||
json GffRemoveDword64(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_DWORD64);
|
||||
}
|
||||
|
||||
json GffRemoveInt64(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_INT64);
|
||||
}
|
||||
|
||||
json GffRemoveFloat(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_FLOAT);
|
||||
}
|
||||
|
||||
json GffRemoveDouble(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
json GffRemoveResRef(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_RESREF);
|
||||
}
|
||||
|
||||
json GffRemoveString(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_STRING);
|
||||
}
|
||||
|
||||
json GffRemoveLocString(json jGff, string sLabel)
|
||||
{
|
||||
return GffRemoveField(jGff, sLabel, GFF_FIELD_TYPE_LOC_STRING);
|
||||
}
|
||||
|
||||
|
||||
json GffGetStruct(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_STRUCT);
|
||||
}
|
||||
|
||||
json GffGetList(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_LIST);
|
||||
}
|
||||
|
||||
json GffGetByte(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_BYTE);
|
||||
}
|
||||
|
||||
json GffGetChar(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_CHAR);
|
||||
}
|
||||
|
||||
json GffGetWord(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_WORD);
|
||||
}
|
||||
|
||||
json GffGetShort(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_SHORT);
|
||||
}
|
||||
|
||||
json GffGetDword(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_DWORD);
|
||||
}
|
||||
|
||||
json GffGetInt(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_INT);
|
||||
}
|
||||
|
||||
json GffGetDword64(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_DWORD64);
|
||||
}
|
||||
|
||||
json GffGetInt64(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_INT64);
|
||||
}
|
||||
|
||||
json GffGetFloat(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_FLOAT);
|
||||
}
|
||||
|
||||
json GffGetDouble(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
json GffGetResRef(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_RESREF);
|
||||
}
|
||||
|
||||
json GffGetString(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_STRING);
|
||||
}
|
||||
|
||||
json GffGetLocString(json jGff, string sLabel)
|
||||
{
|
||||
return GffGetField(jGff, sLabel, GFF_FIELD_TYPE_LOC_STRING);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,9 +10,586 @@ void ShifterCheck(object oPC);
|
||||
#include "pnp_shft_main"
|
||||
#include "prc_inc_shifting"
|
||||
|
||||
//::////////////////Begin Werewolf//////////////////
|
||||
const string PRC_PNP_SHIFTING = "PRC_Shift";
|
||||
|
||||
////////////////Begin Werewolf//////////////////
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
effect ePoly = SupernaturalEffect(EffectPolymorph(nPoly));
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
int bArmsSlotAllowed = GetPRCSwitch(PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
|
||||
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
|
||||
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
|
||||
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
|
||||
|
||||
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
|
||||
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
|
||||
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC);
|
||||
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,oPC);
|
||||
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
|
||||
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
|
||||
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
|
||||
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
object oGlovesOld = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
|
||||
|
||||
if (GetIsObjectValid(oShield))
|
||||
{
|
||||
int nShieldType = GetBaseItemType(oShield);
|
||||
if (nShieldType != BASE_ITEM_LARGESHIELD &&
|
||||
nShieldType != BASE_ITEM_SMALLSHIELD &&
|
||||
nShieldType != BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
oShield = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ShifterCheck(oPC);
|
||||
ClearAllActions();
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, oPC);
|
||||
|
||||
object oWeaponNewRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
|
||||
object oWeaponNewLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
|
||||
object oWeaponNewBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
|
||||
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,oPC);
|
||||
|
||||
//:: Weapon & Armor merge block
|
||||
object oMergeWeaponSource = OBJECT_INVALID;
|
||||
object oMergeArmorSource = OBJECT_INVALID;
|
||||
|
||||
//:: Determine Weapon Merge Source
|
||||
if (bWeapon)
|
||||
{
|
||||
if (bMonkGloves)
|
||||
{
|
||||
if (GetIsObjectValid(oGlovesOld))
|
||||
oMergeWeaponSource = oGlovesOld;
|
||||
}
|
||||
else
|
||||
{
|
||||
//:: Always attempt to merge melee weapon to creature weapon
|
||||
oMergeWeaponSource = oWeaponOld; // even if empty, ensures proper state
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//:: Weapon not requested, but arms-slot allowed monk gloves can merge via armor branch
|
||||
if (bMonkGloves && bArmsSlotAllowed && GetIsObjectValid(oGlovesOld))
|
||||
oMergeWeaponSource = oGlovesOld;
|
||||
}
|
||||
|
||||
//:: Determine Armor Merge Source
|
||||
if (bArmor && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (!bMonkGloves)
|
||||
{
|
||||
if (bArmsSlotAllowed && GetIsObjectValid(oGlovesOld))
|
||||
oMergeArmorSource = oGlovesOld;
|
||||
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
else if (bArmor && !GetIsObjectValid(oArmorNew) && DEBUG)
|
||||
{
|
||||
DoDebug("LycanthropePoly: MergeA set, but oArmorNew invalid.");
|
||||
}
|
||||
|
||||
//:: Apply Weapon Merge
|
||||
if (GetIsObjectValid(oMergeWeaponSource) || bWeapon)
|
||||
{
|
||||
//:: Always attempt to merge weapon properties even if source is OBJECT_INVALID
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewBite, TRUE);
|
||||
}
|
||||
|
||||
//:: Apply Armor Merge
|
||||
if (GetIsObjectValid(oMergeArmorSource))
|
||||
{
|
||||
if (GetIsObjectValid(oArmorNew)) IPWildShapeCopyItemProperties(oMergeArmorSource, oArmorNew);
|
||||
}
|
||||
|
||||
//:: General item merge block
|
||||
if (bItems && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oRing1Old)) IPWildShapeCopyItemProperties(oRing1Old, oArmorNew);
|
||||
if (GetIsObjectValid(oRing2Old)) IPWildShapeCopyItemProperties(oRing2Old, oArmorNew);
|
||||
if (GetIsObjectValid(oAmuletOld)) IPWildShapeCopyItemProperties(oAmuletOld, oArmorNew);
|
||||
if (GetIsObjectValid(oCloakOld)) IPWildShapeCopyItemProperties(oCloakOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBootsOld)) IPWildShapeCopyItemProperties(oBootsOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBeltOld)) IPWildShapeCopyItemProperties(oBeltOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
//::////////////////End Werewolf//////////////////
|
||||
|
||||
|
||||
/* //::////////////////Begin Werewolf//////////////////
|
||||
const string PRC_PNP_SHIFTING = "PRC_Shift";
|
||||
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
effect ePoly = SupernaturalEffect(EffectPolymorph(nPoly));
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
int bArmsSlotAllowed = GetPRCSwitch(PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
|
||||
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
|
||||
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
|
||||
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
|
||||
|
||||
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
|
||||
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
|
||||
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC);
|
||||
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,oPC);
|
||||
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
|
||||
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
|
||||
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
|
||||
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
object oGlovesOld = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
|
||||
|
||||
if (GetIsObjectValid(oShield))
|
||||
{
|
||||
int nShieldType = GetBaseItemType(oShield);
|
||||
if (nShieldType != BASE_ITEM_LARGESHIELD &&
|
||||
nShieldType != BASE_ITEM_SMALLSHIELD &&
|
||||
nShieldType != BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
oShield = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ShifterCheck(oPC);
|
||||
ClearAllActions();
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, oPC);
|
||||
|
||||
object oWeaponNewRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
|
||||
object oWeaponNewLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
|
||||
object oWeaponNewBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
|
||||
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,oPC);
|
||||
|
||||
//:: Weapon & Armor merge block
|
||||
object oMergeWeaponSource = OBJECT_INVALID;
|
||||
object oMergeArmorSource = OBJECT_INVALID;
|
||||
|
||||
// ---- Determine Weapon Merge Source ----
|
||||
if (bWeapon)
|
||||
{
|
||||
if (bMonkGloves)
|
||||
{
|
||||
if (GetIsObjectValid(oGlovesOld))
|
||||
oMergeWeaponSource = oGlovesOld;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponOld))
|
||||
oMergeWeaponSource = oWeaponOld;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bMonkGloves && bArmsSlotAllowed && GetIsObjectValid(oGlovesOld))
|
||||
oMergeWeaponSource = oGlovesOld;
|
||||
}
|
||||
|
||||
// ---- Determine Armor Merge Source ----
|
||||
if (bArmor && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (!bMonkGloves)
|
||||
{
|
||||
if (bArmsSlotAllowed && GetIsObjectValid(oGlovesOld))
|
||||
oMergeArmorSource = oGlovesOld;
|
||||
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
else if (bArmor && !GetIsObjectValid(oArmorNew) && DEBUG)
|
||||
{
|
||||
DoDebug("LycanthropePoly: MergeA set, but oArmorNew invalid.");
|
||||
}
|
||||
|
||||
// ---- Apply Weapon Merge ----
|
||||
if (GetIsObjectValid(oMergeWeaponSource))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oMergeWeaponSource, oWeaponNewBite, TRUE);
|
||||
}
|
||||
|
||||
// ---- Apply Armor Merge ----
|
||||
if (GetIsObjectValid(oMergeArmorSource))
|
||||
{
|
||||
if (GetIsObjectValid(oArmorNew)) IPWildShapeCopyItemProperties(oMergeArmorSource, oArmorNew);
|
||||
}
|
||||
|
||||
//:: General item merge block
|
||||
if (bItems && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oRing1Old)) IPWildShapeCopyItemProperties(oRing1Old, oArmorNew);
|
||||
if (GetIsObjectValid(oRing2Old)) IPWildShapeCopyItemProperties(oRing2Old, oArmorNew);
|
||||
if (GetIsObjectValid(oAmuletOld)) IPWildShapeCopyItemProperties(oAmuletOld, oArmorNew);
|
||||
if (GetIsObjectValid(oCloakOld)) IPWildShapeCopyItemProperties(oCloakOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBootsOld)) IPWildShapeCopyItemProperties(oBootsOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBeltOld)) IPWildShapeCopyItemProperties(oBeltOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
//::////////////////End Werewolf////////////////// */
|
||||
|
||||
|
||||
/* //::////////////////Begin Werewolf//////////////////
|
||||
const string PRC_PNP_SHIFTING = "PRC_Shift";
|
||||
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
effect ePoly = SupernaturalEffect(EffectPolymorph(nPoly));
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
int bArmsSlotAllowed = GetPRCSwitch(PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
|
||||
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
|
||||
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
|
||||
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
|
||||
|
||||
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
|
||||
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
|
||||
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC);
|
||||
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,oPC);
|
||||
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
|
||||
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
|
||||
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
|
||||
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
object oGlovesOld = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
|
||||
|
||||
if (GetIsObjectValid(oShield))
|
||||
{
|
||||
int nShieldType = GetBaseItemType(oShield);
|
||||
if (nShieldType != BASE_ITEM_LARGESHIELD &&
|
||||
nShieldType != BASE_ITEM_SMALLSHIELD &&
|
||||
nShieldType != BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
oShield = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ShifterCheck(oPC);
|
||||
ClearAllActions();
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, oPC);
|
||||
|
||||
object oWeaponNewRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
|
||||
object oWeaponNewLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
|
||||
object oWeaponNewBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
|
||||
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,oPC);
|
||||
|
||||
//:: Weapon merge block
|
||||
if (bWeapon)
|
||||
{
|
||||
object oMergeSource = OBJECT_INVALID;
|
||||
|
||||
// Priority: monk gloves override if worn and arms-slot not allowed
|
||||
if (bMonkGloves && !bArmsSlotAllowed)
|
||||
{
|
||||
if (GetIsObjectValid(oGlovesOld))
|
||||
oMergeSource = oGlovesOld;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise use main-hand weapon if it exists
|
||||
if (GetIsObjectValid(oWeaponOld))
|
||||
oMergeSource = oWeaponOld;
|
||||
}
|
||||
|
||||
// Apply merge to creature weapons if we have a source
|
||||
if (GetIsObjectValid(oMergeSource))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oMergeSource, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oMergeSource, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oMergeSource, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//:: Armor merge block
|
||||
if (bArmor && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
|
||||
// Arms-slot allowed -> apply gloves & bracers to creature weapons
|
||||
if (bArmsSlotAllowed && GetIsObjectValid(oGlovesOld))
|
||||
{
|
||||
if (DEBUG) DoDebug("LycanthropePoly: Arms-slot allowed -> applying gloves/bracers to creature weapons from armor branch.");
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
else if (bArmor && !GetIsObjectValid(oArmorNew) && DEBUG)
|
||||
{
|
||||
DoDebug("LycanthropePoly: MergeA set, but oArmorNew invalid.");
|
||||
}
|
||||
|
||||
//:: General item merge block
|
||||
if (bItems && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oRing1Old)) IPWildShapeCopyItemProperties(oRing1Old, oArmorNew);
|
||||
if (GetIsObjectValid(oRing2Old)) IPWildShapeCopyItemProperties(oRing2Old, oArmorNew);
|
||||
if (GetIsObjectValid(oAmuletOld)) IPWildShapeCopyItemProperties(oAmuletOld, oArmorNew);
|
||||
if (GetIsObjectValid(oCloakOld)) IPWildShapeCopyItemProperties(oCloakOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBootsOld)) IPWildShapeCopyItemProperties(oBootsOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBeltOld)) IPWildShapeCopyItemProperties(oBeltOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
//::////////////////End Werewolf//////////////////
|
||||
*/
|
||||
|
||||
/* //::////////////////Begin Werewolf//////////////////
|
||||
const string PRC_PNP_SHIFTING = "PRC_Shift";
|
||||
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
effect ePoly = SupernaturalEffect(EffectPolymorph(nPoly));
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
int bArmsSlotAllowed = GetPRCSwitch(PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
|
||||
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
|
||||
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
|
||||
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
|
||||
|
||||
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
|
||||
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
|
||||
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC);
|
||||
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,oPC);
|
||||
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
|
||||
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
|
||||
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
|
||||
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
object oGlovesOld = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
|
||||
|
||||
if (GetIsObjectValid(oShield))
|
||||
{
|
||||
int nShieldType = GetBaseItemType(oShield);
|
||||
if (nShieldType != BASE_ITEM_LARGESHIELD &&
|
||||
nShieldType != BASE_ITEM_SMALLSHIELD &&
|
||||
nShieldType != BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
oShield = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ShifterCheck(oPC);
|
||||
ClearAllActions();
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, oPC);
|
||||
|
||||
object oWeaponNewRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
|
||||
object oWeaponNewLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
|
||||
object oWeaponNewBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
|
||||
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,oPC);
|
||||
|
||||
//:: Weapon merge block
|
||||
//:: Only blocked if monk gloves are equipped AND arms-slot merge is NOT allowed
|
||||
if (bWeapon && !bMonkGloves)
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponOld))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
else if (bWeapon && bMonkGloves && !bArmsSlotAllowed)
|
||||
{
|
||||
if (DEBUG) DoDebug("LycanthropePoly: Monk gloves overriding weapon merge (arms slot NOT allowed).");
|
||||
if (GetIsObjectValid(oGlovesOld))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//:: Armor merge block
|
||||
//:: Apply armor and gloves (if arms-slot allowed)
|
||||
|
||||
if (bArmor && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
|
||||
if (bArmsSlotAllowed && bMonkGloves && GetIsObjectValid(oGlovesOld))
|
||||
{
|
||||
if (DEBUG) DoDebug("LycanthropePoly: Arms-slot allowed -> applying gloves to creature weapons from armor branch.");
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
else if (bArmor && !GetIsObjectValid(oArmorNew) && DEBUG)
|
||||
{
|
||||
DoDebug("LycanthropePoly: MergeA set, but oArmorNew invalid.");
|
||||
}
|
||||
|
||||
//:: General item merge block
|
||||
if (bItems && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oRing1Old)) IPWildShapeCopyItemProperties(oRing1Old, oArmorNew);
|
||||
if (GetIsObjectValid(oRing2Old)) IPWildShapeCopyItemProperties(oRing2Old, oArmorNew);
|
||||
if (GetIsObjectValid(oAmuletOld)) IPWildShapeCopyItemProperties(oAmuletOld, oArmorNew);
|
||||
if (GetIsObjectValid(oCloakOld)) IPWildShapeCopyItemProperties(oCloakOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBootsOld)) IPWildShapeCopyItemProperties(oBootsOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBeltOld)) IPWildShapeCopyItemProperties(oBeltOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
//::////////////////End Werewolf////////////////// */
|
||||
|
||||
|
||||
/* //::////////////////Begin Werewolf//////////////////
|
||||
const string PRC_PNP_SHIFTING = "PRC_Shift";
|
||||
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
effect ePoly = SupernaturalEffect(EffectPolymorph(nPoly));
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
int bArmsSlotAllowed = GetPRCSwitch(PRC_WILDSHAPE_ALLOWS_ARMS_SLOT);
|
||||
|
||||
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
|
||||
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
|
||||
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
|
||||
|
||||
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
|
||||
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
|
||||
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC);
|
||||
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,oPC);
|
||||
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC);
|
||||
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC);
|
||||
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,oPC);
|
||||
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,oPC);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
object oGlovesOld = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
|
||||
|
||||
if (GetIsObjectValid(oShield))
|
||||
{
|
||||
int nShieldType = GetBaseItemType(oShield);
|
||||
if (nShieldType != BASE_ITEM_LARGESHIELD &&
|
||||
nShieldType != BASE_ITEM_SMALLSHIELD &&
|
||||
nShieldType != BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
oShield = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
ShifterCheck(oPC);
|
||||
ClearAllActions();
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, oPC);
|
||||
|
||||
object oWeaponNewRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
|
||||
object oWeaponNewLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
|
||||
object oWeaponNewBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
|
||||
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,oPC);
|
||||
|
||||
//:: Weapon merge block
|
||||
//:: Only blocked if monk gloves are equipped AND arms-slot merge is NOT allowed
|
||||
if (bWeapon && !bMonkGloves)
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponOld))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oWeaponOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
else if (bWeapon && bMonkGloves && !bArmsSlotAllowed)
|
||||
{
|
||||
if (DEBUG) DoDebug("LycanthropePoly: Monk gloves overriding weapon merge (arms slot NOT allowed).");
|
||||
if (GetIsObjectValid(oGlovesOld))
|
||||
{
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//:: Armor merge block
|
||||
//:: Apply armor and gloves (if arms-slot allowed)
|
||||
|
||||
if (bArmor && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oShield)) IPWildShapeCopyItemProperties(oShield, oArmorNew);
|
||||
if (GetIsObjectValid(oHelmetOld)) IPWildShapeCopyItemProperties(oHelmetOld, oArmorNew);
|
||||
if (GetIsObjectValid(oArmorOld)) IPWildShapeCopyItemProperties(oArmorOld, oArmorNew);
|
||||
|
||||
if (bArmsSlotAllowed && bMonkGloves && GetIsObjectValid(oGlovesOld))
|
||||
{
|
||||
if (DEBUG) DoDebug("LycanthropePoly: Arms-slot allowed -> applying gloves to creature weapons from armor branch.");
|
||||
if (GetIsObjectValid(oWeaponNewLeft)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewLeft, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewRight)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewRight, TRUE);
|
||||
if (GetIsObjectValid(oWeaponNewBite)) IPWildShapeCopyItemProperties(oGlovesOld, oWeaponNewBite, TRUE);
|
||||
}
|
||||
}
|
||||
else if (bArmor && !GetIsObjectValid(oArmorNew) && DEBUG)
|
||||
{
|
||||
DoDebug("LycanthropePoly: MergeA set, but oArmorNew invalid.");
|
||||
}
|
||||
|
||||
//:: General item merge block
|
||||
if (bItems && GetIsObjectValid(oArmorNew))
|
||||
{
|
||||
if (GetIsObjectValid(oRing1Old)) IPWildShapeCopyItemProperties(oRing1Old, oArmorNew);
|
||||
if (GetIsObjectValid(oRing2Old)) IPWildShapeCopyItemProperties(oRing2Old, oArmorNew);
|
||||
if (GetIsObjectValid(oAmuletOld)) IPWildShapeCopyItemProperties(oAmuletOld, oArmorNew);
|
||||
if (GetIsObjectValid(oCloakOld)) IPWildShapeCopyItemProperties(oCloakOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBootsOld)) IPWildShapeCopyItemProperties(oBootsOld, oArmorNew);
|
||||
if (GetIsObjectValid(oBeltOld)) IPWildShapeCopyItemProperties(oBeltOld, oArmorNew);
|
||||
}
|
||||
}
|
||||
//::////////////////End Werewolf////////////////// */
|
||||
|
||||
|
||||
/* ////////////////Begin Werewolf//////////////////
|
||||
|
||||
void LycanthropePoly(object oPC, int nPoly)
|
||||
{
|
||||
@@ -84,7 +661,7 @@ void LycanthropePoly(object oPC, int nPoly)
|
||||
|
||||
}
|
||||
|
||||
////////////////End Werewolf//////////////////
|
||||
////////////////End Werewolf////////////////// */
|
||||
|
||||
void ShifterCheck(object oPC)
|
||||
{
|
||||
@@ -246,4 +823,6 @@ void DoTail(object oPC, int nTailType)
|
||||
SetCreatureTailType(nTailType, oPC);
|
||||
//override any stored default appearance
|
||||
SetPersistantLocalInt(oPC, "AppearanceStoredTail", nTailType);
|
||||
}
|
||||
}
|
||||
|
||||
//::void main (){}
|
||||
@@ -513,6 +513,8 @@ int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJE
|
||||
|
||||
if(nClass == CLASS_TYPE_BARD)
|
||||
nDC += StringToInt(Get2DACache("Spells", "Bard", nSpellID));
|
||||
else if(nClass == CLASS_TYPE_ASSASSIN)
|
||||
nDC += StringToInt(Get2DACache("Spells", "Assassin", nSpellID));
|
||||
else if(nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_UR_PRIEST || nClass == CLASS_TYPE_OCULAR)
|
||||
nDC += StringToInt(Get2DACache("Spells", "Cleric", nSpellID));
|
||||
else if(nClass == CLASS_TYPE_DRUID)
|
||||
|
||||
@@ -54,11 +54,11 @@ int SPGetPenetrAOE(object oCaster = OBJECT_SELF, int nCasterLvl = 0);
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
//#include "prc_inc_spells"
|
||||
#include "prc_inc_spells"
|
||||
//#include "prc_alterations"
|
||||
//#include "prcsp_archmaginc"
|
||||
//#include "prc_inc_racial"
|
||||
|
||||
#include "inc_2dacache"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
|
||||
@@ -143,7 +143,7 @@ const int CLASS_TYPE_MASTER_HARPER = 176;
|
||||
const int CLASS_TYPE_FRE_BERSERKER = 177;
|
||||
const int CLASS_TYPE_TEMPEST = 178;
|
||||
const int CLASS_TYPE_FOE_HUNTER = 179;
|
||||
//:: Free = 180
|
||||
const int CLASS_TYPE_VERDANT_LORD = 180;
|
||||
const int CLASS_TYPE_ORC_WARLORD = 181;
|
||||
const int CLASS_TYPE_THRALL_OF_GRAZZT_A = 182;
|
||||
const int CLASS_TYPE_NECROCARNATE = 183;
|
||||
@@ -162,7 +162,7 @@ const int CLASS_TYPE_MASTER_OF_NINE = 195;
|
||||
const int CLASS_TYPE_ETERNAL_BLADE = 196;
|
||||
const int CLASS_TYPE_SHADOW_SUN_NINJA = 197;
|
||||
const int CLASS_TYPE_WITCHBORN_BINDER = 198;
|
||||
const int CLASS_TYPE_BAELNORN = 199;
|
||||
const int CLASS_TYPE_LION_OF_TALISID = 199;
|
||||
const int CLASS_TYPE_DISCIPLE_OF_MEPH = 200;
|
||||
const int CLASS_TYPE_SOUL_EATER = 201;
|
||||
const int CLASS_TYPE_HENSHIN_MYSTIC = 202;
|
||||
@@ -236,6 +236,7 @@ const int CLASS_TYPE_WITCH = -1;
|
||||
const int CLASS_TYPE_TEMPLAR = -1;
|
||||
const int CLASS_TYPE_MYSTIC = -1;
|
||||
const int CLASS_TYPE_NOBLE = -1;
|
||||
const int CLASS_TYPE_BAELNORN = -2;
|
||||
|
||||
|
||||
//void main (){}
|
||||
@@ -444,6 +444,7 @@ int Get2DALineFromItemprop(string sFile, itemproperty ip, object oItem)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ITEM_PROPERTY_ECHOBLADE: return 46; break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -1529,7 +1530,12 @@ void ApplyItemProps(object oItem, string sFile, int nLine)
|
||||
break; //no more itemprops, no gaps, assuming no errors
|
||||
}
|
||||
if(sFile != "craft_weapon" && sFile != "craft_armour")
|
||||
SetName(oItem, GetStringByStrRef(StringToInt(Get2DACache(sFile, "Name", nLine))));
|
||||
{
|
||||
SetName(oItem, GetStringByStrRef(StringToInt(Get2DACache(sFile, "Name", nLine))));
|
||||
string sDescRef = Get2DACache(sFile, "CraftedDescription", nLine);
|
||||
if(sDescRef != "")
|
||||
SetDescription(oItem, GetStringByStrRef(StringToInt(sDescRef)));
|
||||
}
|
||||
}
|
||||
|
||||
//Partly ripped off the lexicon :P
|
||||
@@ -1620,7 +1626,8 @@ string GetCrafting2DA(object oItem)
|
||||
(nBase == BASE_ITEM_BOOTS) ||
|
||||
(nBase == BASE_ITEM_GLOVES) ||
|
||||
(nBase == BASE_ITEM_BRACER) ||
|
||||
(nBase == BASE_ITEM_CLOAK))
|
||||
(nBase == BASE_ITEM_CLOAK) ||
|
||||
(nBase == BASE_ITEM_CRAFTED_VIAL))
|
||||
)
|
||||
return "craft_wondrous";
|
||||
|
||||
@@ -1657,19 +1664,28 @@ int GetCraftingFeat(object oItem)
|
||||
if(nBase == BASE_ITEM_RING) return FEAT_FORGE_RING;
|
||||
|
||||
//routing bioware feats through this convo
|
||||
if((nBase == BASE_ITEM_CRAFTED_SCEPTER) ||
|
||||
(nBase == BASE_ITEM_CRAFTED_SCEPTER)
|
||||
)
|
||||
return FEAT_CRAFT_SCEPTER;
|
||||
|
||||
if((nBase == BASE_ITEM_MAGICROD) ||
|
||||
(nBase == BASE_ITEM_CRAFTED_ROD)
|
||||
)
|
||||
return FEAT_CRAFT_ROD;
|
||||
|
||||
if((nBase == BASE_ITEM_MAGICSTAFF) ||
|
||||
(nBase == BASE_ITEM_CRAFTED_STAFF)
|
||||
)
|
||||
return FEAT_CRAFT_STAFF;
|
||||
|
||||
if((nBase == BASE_ITEM_MAGICWAND) ||
|
||||
(nBase == BASE_ITEM_BLANK_WAND)
|
||||
)
|
||||
return FEAT_CRAFT_WAND;
|
||||
|
||||
if(nBase == BASE_ITEM_BLANK_POTION) return FEAT_BREW_POTION;
|
||||
|
||||
if(nBase == BASE_ITEM_BLANK_SCROLL) return FEAT_SCRIBE_SCROLL;
|
||||
|
||||
if(((nBase == BASE_ITEM_HELMET) ||
|
||||
@@ -1678,7 +1694,8 @@ int GetCraftingFeat(object oItem)
|
||||
(nBase == BASE_ITEM_BOOTS) ||
|
||||
(nBase == BASE_ITEM_GLOVES) ||
|
||||
(nBase == BASE_ITEM_BRACER) ||
|
||||
(nBase == BASE_ITEM_CLOAK))
|
||||
(nBase == BASE_ITEM_CLOAK) ||
|
||||
(nBase == BASE_ITEM_CRAFTED_VIAL))
|
||||
)
|
||||
return FEAT_CRAFT_WONDROUS;
|
||||
|
||||
|
||||
@@ -75,6 +75,14 @@ void DeathlessFrenzyCheck(object oTarget);
|
||||
// * PRC Version of a Bioware function to disable include loops
|
||||
void PRCRemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget);
|
||||
|
||||
|
||||
/**
|
||||
* Target is immune to gaze attacks
|
||||
*
|
||||
* @return the Gaze Immunity effect
|
||||
*/
|
||||
effect EffectGazeImmune();
|
||||
|
||||
/**
|
||||
* Dazzles the target: -1 Attack, Search, Spot, and VFX
|
||||
*
|
||||
@@ -82,6 +90,9 @@ void PRCRemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget);
|
||||
*/
|
||||
effect EffectDazzle();
|
||||
|
||||
//ebonfowl: adding this function to check if a target is already shaken
|
||||
int GetIsShaken(object oTarget);
|
||||
|
||||
/**
|
||||
* Shaken effect: -2 to attack, all skills and saving throws
|
||||
*
|
||||
@@ -170,14 +181,11 @@ effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1);
|
||||
*/
|
||||
effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1);
|
||||
|
||||
//ebonfowl: adding this function to check if a target is already shaken
|
||||
int GetIsShaken(object oTarget);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Include section */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_castlvl" // get prc_racial_const, prc_inc_nwscript, prc_inc_newip
|
||||
#include "inc_epicspelldef"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
@@ -261,6 +269,8 @@ object GetObjectToApplyNewEffect(string sTag, object oPC, int nStripEffects = TR
|
||||
SetCreatureAppearanceType(oWP, APPEARANCE_TYPE_INVISIBLE_HUMAN_MALE);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oWP);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oWP);
|
||||
AssignCommand(oWP, ActionUseSkill(SKILL_HIDE, oWP));
|
||||
|
||||
}
|
||||
//remove previous effects
|
||||
if(nStripEffects)
|
||||
@@ -583,7 +593,8 @@ effect PRCEffectHeal(int nHP, object oTarget)
|
||||
return EffectHeal(nHP);
|
||||
}
|
||||
|
||||
effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1){
|
||||
effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1)
|
||||
{
|
||||
effect eReturn;
|
||||
switch(iAbility)
|
||||
{
|
||||
@@ -639,7 +650,8 @@ effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1){
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1){
|
||||
effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1)
|
||||
{
|
||||
effect eReturn;
|
||||
switch(iAbility)
|
||||
{
|
||||
@@ -695,7 +707,8 @@ effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1){
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
effect EffectDamageImmunityAll(){
|
||||
effect EffectDamageImmunityAll()
|
||||
{
|
||||
effect eReturn = EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, 100);
|
||||
eReturn = EffectLinkEffects(eReturn, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 100));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100));
|
||||
@@ -712,7 +725,8 @@ effect EffectDamageImmunityAll(){
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
effect EffectImmunityMiscAll(){
|
||||
effect EffectImmunityMiscAll()
|
||||
{
|
||||
effect eReturn = EffectImmunity(IMMUNITY_TYPE_ABILITY_DECREASE);
|
||||
eReturn = EffectLinkEffects(eReturn, EffectImmunity(IMMUNITY_TYPE_BLINDNESS));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectImmunity(IMMUNITY_TYPE_DEAFNESS));
|
||||
@@ -732,6 +746,47 @@ effect EffectImmunityMiscAll(){
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
//:: Immunity to all gaze attacks
|
||||
effect EffectGazeImmune()
|
||||
{
|
||||
|
||||
effect eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CHARM);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CONFUSION);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DAZE);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DEATH);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_CHAOS);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_EVIL);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_GOOD);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_LAW);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DOMINATE);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DOOM);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_FEAR);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PARALYSIS);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PETRIFY);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_STUNNED);
|
||||
|
||||
eReturn = TagEffect(eReturn, "PRCGazeImmune");
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
//:: Immunity to all perification attacks
|
||||
effect EffectPetrificationImmune()
|
||||
{
|
||||
effect eReturn = EffectSpellImmunity(SPELLABILITY_TOUCH_PETRIFY);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_BREATH_PETRIFY);
|
||||
eReturn = EffectSpellImmunity(SPELL_FLESH_TO_STONE);
|
||||
eReturn = EffectSpellImmunity(SPELL_STONEHOLD);
|
||||
eReturn = EffectSpellImmunity(SPELL_EPIC_A_STONE);
|
||||
eReturn = EffectSpellImmunity(POWER_CRYSTALLIZE);
|
||||
eReturn = EffectSpellImmunity(MELD_BASILISK_MASK);
|
||||
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PETRIFY);
|
||||
|
||||
eReturn = TagEffect(eReturn, "PRCPetrificationImmune");
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
int GetIsShaken(object oTarget)
|
||||
{
|
||||
effect eEffect = GetFirstEffect(oTarget);
|
||||
@@ -747,4 +802,13 @@ int GetIsShaken(object oTarget)
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Forward declarations for size change effects
|
||||
// Implementations are in prc_inc_size
|
||||
effect EffectSizeChange(object oTarget, int nObjectType, int bEnlarge, int nChanges);
|
||||
void DelayedSetVisualTransform(int nExpectedGeneration, object oTarget, int nTransform, float fValue);
|
||||
void DelaySetVisualTransform(float fDelay, object oTarget, string sGenerationName, int nTransform, float fValue);
|
||||
|
||||
//:: Test void
|
||||
//::void main() {}
|
||||
@@ -4,6 +4,11 @@
|
||||
//:: PRC Options Conversation
|
||||
const int FEAT_OPTIONS_CONVERSATION = 2285;
|
||||
|
||||
//;; Builder Feats
|
||||
const int FEAT_ARCHETYPAL_FORM = 2918;
|
||||
const int FEAT_INTRINSIC_ARMOR = 25990;
|
||||
const int FEAT_INTRINSIC_WEAPON = 25991;
|
||||
|
||||
//:: Missing Bioware Feats
|
||||
const int FEAT_EPIC_PLANAR_TURNING = 854;
|
||||
|
||||
@@ -152,6 +157,9 @@ const int FEAT_EPIC_DIAMOND_DRAGON = 25115;
|
||||
const int FEAT_EPIC_CRUSADER = 25116;
|
||||
const int FEAT_EPIC_SWORDSAGE = 25117;
|
||||
const int FEAT_EPIC_WARBLADE = 25118;
|
||||
const int FEAT_EPIC_LION_OF_TALISID = 25600;
|
||||
const int FEAT_EPIC_VERDANT_LORD = 25618;
|
||||
|
||||
|
||||
//:: Vile Martial Strike Expansion
|
||||
const int FEAT_VILE_MARTIAL_EAGLE_CLAW = 24800;
|
||||
@@ -195,6 +203,31 @@ const int FEAT_CHARMING_THE_ARROW = 25998;
|
||||
//:: Skill Based Feats
|
||||
const int FEAT_JUMP = 2884;
|
||||
|
||||
//:: Lion of Talisid
|
||||
const int FEAT_LOT_LIONS_COURAGE = 25614;
|
||||
const int FEAT_LOT_LIONS_POUNCE = 25615;
|
||||
const int FEAT_LOT_LIONS_SWIFTNESS = 25616;
|
||||
const int FEAT_LOT_LEONALS_ROAR = 25617;
|
||||
|
||||
//::: Verdant Lord
|
||||
const int FEAT_VL_EXPERT_INFUSION = 25634;
|
||||
const int FEAT_VL_SUN_SUSTENANCE = 25635;
|
||||
const int FEAT_VL_SPONTANEITY = 25636;
|
||||
const int FEAT_VL_PLANT_FACILITY = 25637;
|
||||
const int FEAT_VL_WILD_SHAPE_TREANT = 25638;
|
||||
const int FEAT_VL_ANIMATE_TREE = 25639;
|
||||
const int FEAT_VL_GAEAS_EMBRACE = 25640;
|
||||
|
||||
//:: Masters of the Wild feats
|
||||
const int FEAT_CREATE_INFUSION = 25960;
|
||||
const int FEAT_MAGICAL_ARTISAN_CREATE_INFUSION = 25961;
|
||||
const int FEAT_PLANT_DEFIANCE = 25992;
|
||||
const int FEAT_PLANT_CONTROL = 25993;
|
||||
|
||||
//:: Lost Empires of Faerun feats
|
||||
const int FEAT_CRAFT_SCEPTER = 25962;
|
||||
const int FEAT_MAGICAL_ARTISAN_CRAFT_SCEPTER = 25963;
|
||||
|
||||
//:: Racial Feats
|
||||
const int FEAT_WEMIC_JUMP_8 = 4518;
|
||||
const int FEAT_URDINNIR_STONESKIN = 4644;
|
||||
@@ -782,6 +815,9 @@ const int FEAT_SUEL_IGNORE_SPELL_FAILURE = 2398;
|
||||
const int FEAT_SUEL_EXTENDED_SPELL = 2399;
|
||||
const int FEAT_SUEL_DISPELLING_STRIKE = 2400;
|
||||
|
||||
//:: Druid
|
||||
const int FEAT_SPONT_SUMMON = 2372;
|
||||
|
||||
//Passive Feats
|
||||
const int FEAT_ETERNAL_FREEDOM = 4298;
|
||||
const int FEAT_INTUITIVE_ATTACK = 3166;
|
||||
@@ -1286,6 +1322,7 @@ const int FEAT_SOMATIC_WEAPONRY = 5186;
|
||||
|
||||
// Forgotten Realms Campaign Setting
|
||||
const int FEAT_INSCRIBE_RUNE = 2462;
|
||||
const int EPIC_FEAT_INSCRIBE_EPIC_RUNES = 2549;
|
||||
|
||||
// Miniature Handbook
|
||||
const int FEAT_SHIELDMATE = 3258;
|
||||
@@ -1538,18 +1575,19 @@ const int FEAT_SELVETARMS_BLESSING = 2447;
|
||||
const int FEAT_RANGER_DUAL = 374;
|
||||
const int FEAT_CAMOUFLAGE = 4486;
|
||||
|
||||
//Exalted Feat
|
||||
const int FEAT_SAC_VOW = 3388;
|
||||
const int FEAT_VOW_OBED = 3389;
|
||||
const int FEAT_EXALTED_TURNING = 3168;
|
||||
const int FEAT_HAND_HEALER = 3167;
|
||||
const int FEAT_NIMBUSLIGHT = 3165;
|
||||
const int FEAT_HOLYRADIANCE = 3164;
|
||||
const int FEAT_STIGMATA = 3163;
|
||||
const int FEAT_SERVHEAVEN = 3355;
|
||||
const int FEAT_RANGED_SMITE = 3356;
|
||||
const int FEAT_VOW_PURITY = 5360;
|
||||
const int FEAT_VOWOFPOVERTY = 26001;
|
||||
//:: Exalted Feats
|
||||
const int FEAT_SAC_VOW = 3388;
|
||||
const int FEAT_VOW_OBED = 3389;
|
||||
const int FEAT_EXALTED_TURNING = 3168;
|
||||
const int FEAT_HAND_HEALER = 3167;
|
||||
const int FEAT_NIMBUSLIGHT = 3165;
|
||||
const int FEAT_HOLYRADIANCE = 3164;
|
||||
const int FEAT_STIGMATA = 3163;
|
||||
const int FEAT_SERVHEAVEN = 3355;
|
||||
const int FEAT_RANGED_SMITE = 3356;
|
||||
const int FEAT_VOW_PURITY = 5360;
|
||||
const int FEAT_VOWOFPOVERTY = 26002;
|
||||
const int FEAT_FAV_COMPANIONS = 25994;
|
||||
|
||||
//Vile Feat
|
||||
const int FEAT_LICHLOVED = 3395;
|
||||
@@ -1868,12 +1906,12 @@ const int FEAT_SANCTIFY_MARTIAL_SICKLE = 3169;
|
||||
const int FEAT_SANCTIFY_MARTIAL_MINDBLADE = 3623;
|
||||
const int FEAT_SANCTIFY_MARTIAL_WHIP = 3596;
|
||||
const int FEAT_SANCTIFY_MARTIAL_TRIDENT = 3597;
|
||||
const int FEAT_SANCTIFYKISTRIKE = 26002;
|
||||
const int FEAT_HOLYKISTRIKE = 26003;
|
||||
const int FEAT_FISTOFHEAVENS = 26004;
|
||||
const int FEAT_VOWABSTINENCE = 26005;
|
||||
const int FEAT_VOWCHASTITY = 26006;
|
||||
const int FEAT_GIFTOFFAITH = 26007;
|
||||
const int FEAT_SANCTIFYKISTRIKE = 26003;
|
||||
const int FEAT_HOLYKISTRIKE = 26004;
|
||||
const int FEAT_FISTOFHEAVENS = 26005;
|
||||
const int FEAT_VOWABSTINENCE = 26006;
|
||||
const int FEAT_VOWCHASTITY = 26007;
|
||||
const int FEAT_GIFTOFFAITH = 26008;
|
||||
|
||||
//heartwarder
|
||||
const int FEAT_CHARISMA_INC1 = 3230;
|
||||
@@ -3189,6 +3227,8 @@ const int FEAT_ETHEREAL = 4167;
|
||||
const int FEAT_TEMPLATE_ARCHLICH_MARKER = 22700;
|
||||
const int FEAT_TEMPLATE_ARCHLICH_TURN_UNDEAD = 22701;
|
||||
|
||||
const int FEAT_TEMPLATE_BAELNORN_MARKER = 22708;
|
||||
|
||||
const int FEAT_TEMPLATE_CELESTIAL_SMITE_EVIL = 22601;
|
||||
const int FEAT_TEMPLATE_CELESTIAL_MARKER = 22602;
|
||||
const int FEAT_TEMPLATE_FIENDISH_SMITE_GOOD = 22603;
|
||||
@@ -3695,6 +3735,9 @@ const int FEAT_EPIC_ARTIFICER = 4072;
|
||||
//////////////// END INFUSIONS /////////////////
|
||||
//////////////////////////////////////////////////*/
|
||||
|
||||
//:: Monk
|
||||
const int FEAT_MONK_ABUNDANT_STEP = 2351;
|
||||
|
||||
//Justice of Weald and Woe
|
||||
const int FEAT_LUCKY_SHOT = 24021;
|
||||
|
||||
@@ -3933,6 +3976,8 @@ const int FEAT_OPPORTUNISTIC_PIETY_HEAL = 5358;
|
||||
const int FEAT_OPPORTUNISTIC_PIETY_TURN = 5359;
|
||||
|
||||
// Combat Maneuver Feats
|
||||
const int FEAT_CM_CHARGE = 2823;
|
||||
const int FEAT_CM_GRAPPLE = 3414;
|
||||
const int FEAT_CURLING_WAVE_STRIKE = 2809;
|
||||
const int FEAT_SIDESTEP_CHARGE = 3505;
|
||||
const int FEAT_POWERFUL_CHARGE = 3506;
|
||||
@@ -6203,6 +6248,38 @@ const int FEAT_SHINING_BLADE_SPELLCASTING_VASSAL = 19587;
|
||||
const int FEAT_SWIFT_WING_SPELLCASTING_VASSAL = 19588;
|
||||
const int FEAT_WARPRIEST_SPELLCASTING_VASSAL = 19589;
|
||||
|
||||
//:: Lion of Talisid marker feats
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_ARCHIVIST = 25601;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_CLERIC = 25602;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_DRUID = 25603;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_FAVOURED_SOUL = 25604;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_HEALER = 25605;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_JOWAW = 25606;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_KOTMC = 25607;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_NENTYAR_HUNTER = 25608;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_RANGER = 25609;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_OASHAMAN = 25610;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_SOHEI = 25611;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_SOL = 25612;
|
||||
const int FEAT_LION_OF_TALISID_SPELLCASTING_SPSHAMAN = 25613;
|
||||
|
||||
//:: Verdant Lord marker feats
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_ARCHIVIST = 25619;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_CLERIC = 25620;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_DRUID = 25621;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_FAVOURED_SOUL = 25622;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_HEALER = 25623;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_JOWAW = 25624;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_KOTC = 25625;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_KOTMC = 25626;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_NENTYAR_HUNTER = 25627;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_PALADIN = 25628;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_RANGER = 25629;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_OASHAMAN = 25630;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_SOHEI = 25631;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_SOL = 25632;
|
||||
const int FEAT_VERDANT_LORD_SPELLCASTING_SPSHAMAN = 25633;
|
||||
|
||||
//:: No spellcasting or invoking marker feats
|
||||
const int FEAT_ASMODEUS_SPELLCASTING_NONE = 19590;
|
||||
const int FEAT_TIAMAT_SPELLCASTING_NONE = 19591;
|
||||
@@ -6210,6 +6287,7 @@ const int FEAT_DSONG_SPELLCASTING_NONE = 19592;
|
||||
const int FEAT_OLLAM_SPELLCASTING_NONE = 19593;
|
||||
|
||||
//:: PRC8 Hidden Talent Feats
|
||||
const int FEAT_HIDDEN_TALENT = 25900;
|
||||
const int FEAT_HIDDEN_TALENT_BIOFEEDBACK = 25901;
|
||||
const int FEAT_HIDDEN_TALENT_BITE_WOLF = 25902;
|
||||
const int FEAT_HIDDEN_TALENT_BOLT = 25903;
|
||||
|
||||
@@ -400,5 +400,4 @@ int GetBestAvailableSpell(object oTarget)
|
||||
if(nBestSpell == 99999) nBestSpell = GetBestL1Spell(oTarget, nBestSpell);
|
||||
if(nBestSpell == 99999) nBestSpell = GetBestL0Spell(oTarget, nBestSpell);
|
||||
return nBestSpell;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -124,6 +124,8 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prcsp_archmaginc"
|
||||
#include "prc_inc_spells"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
|
||||
@@ -575,8 +575,8 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
|
||||
iReturnLevel = GetLevelByClass(CLASS_TYPE_SHAPECHANGER);
|
||||
|
||||
}
|
||||
// Casting as a bard but don't have any levels in the class
|
||||
if(iCastingClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
|
||||
// Casting as a bard but don't have any levels in the class //:: Double-dipping?
|
||||
/* if(iCastingClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
|
||||
{
|
||||
int nRace = GetRacialType(oCaster);
|
||||
|
||||
@@ -584,7 +584,7 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
|
||||
//otherwise use RHD instead of bard levels
|
||||
if(nRace == RACIAL_TYPE_GLOURA)
|
||||
iReturnLevel = GetLevelByClass(CLASS_TYPE_FEY);
|
||||
}
|
||||
} */
|
||||
|
||||
//Spell Rage ability
|
||||
if(GetHasSpellEffect(SPELL_SPELL_RAGE, oCaster)
|
||||
@@ -960,8 +960,10 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
}
|
||||
//:: End Bard Arcane PrC casting calculations
|
||||
|
||||
if(nCastingClass == CLASS_TYPE_BARD && nRace == RACIAL_TYPE_GLOURA && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
|
||||
if(nCastingClass == CLASS_TYPE_BARD || nCastingClass == CLASS_TYPE_BARD && nRace == RACIAL_TYPE_GLOURA && !GetLevelByClass(CLASS_TYPE_BARD, oCaster))
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_inc_castlvl >> Found Fey RHD caster (not bard)");
|
||||
|
||||
if(GetHasFeat(FEAT_ABCHAMP_SPELLCASTING_FEY, oCaster))
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_ABJURANT_CHAMPION, oCaster);
|
||||
|
||||
@@ -1065,7 +1067,10 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_UNSEEN_SEER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VIRTUOSO_SPELLCASTING_FEY, oCaster))
|
||||
{
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_VIRTUOSO, oCaster);
|
||||
if(DEBUG) DoDebug("prc_inc_castlvl >> Found Fey + Virtuoso PrC. Arcane caster level is "+IntToString(nArcane)+".");
|
||||
}
|
||||
|
||||
if(GetHasFeat(FEAT_WWOC_SPELLCASTING_FEY, oCaster))
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_WAR_WIZARD_OF_CORMYR, oCaster);
|
||||
@@ -1143,8 +1148,8 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_DIABOLIST_SPELLCASTING_ASSASSIN, oCaster))
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_DIABOLIST, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_DHEART_SPELLCASTING_ASSASSIN, oCaster))
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_DRAGONHEART_MAGE, oCaster);
|
||||
//if(GetHasFeat(FEAT_DHEART_SPELLCASTING_ASSASSIN, oCaster))
|
||||
//nArcane += GetLevelByClass(CLASS_TYPE_DRAGONHEART_MAGE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_EKNIGHT_SPELLCASTING_ASSASSIN, oCaster))
|
||||
nArcane += GetLevelByClass(CLASS_TYPE_ELDRITCH_KNIGHT, oCaster);
|
||||
@@ -3817,6 +3822,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
|
||||
|
||||
@@ -3851,7 +3859,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_ARCHIVIST, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -4143,7 +4154,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
@@ -4182,7 +4196,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_CLERIC, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -4253,7 +4270,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_DRUID, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_DRUID, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_DRUID, oCaster))
|
||||
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
@@ -4295,9 +4315,12 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_DRUID, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_DRUID, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_DRUID, oCaster))
|
||||
/* if(GetHasFeat(FEAT_BFZ_SPELLCASTING_DRUID, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_BFZ, oCaster + 1) / 2 */
|
||||
|
||||
// if(GetHasFeat(FEAT_BRIMSTONE_SPEAKER_SPELLCASTING_DRUID, oCaster))
|
||||
@@ -4365,10 +4388,13 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_MORNINGLORD_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster);
|
||||
@@ -4404,7 +4430,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_FAVOURED_SOUL, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -4474,6 +4503,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
|
||||
|
||||
@@ -4514,7 +4546,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */
|
||||
|
||||
/* if(GetHasFeat(FEAT_BFZ_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; */
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; */
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BRIMSTONE_SPEAKER_SPELLCASTING_HEALER, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BRIMSTONE_SPEAKER, oCaster) + 1) / 2;
|
||||
@@ -4581,6 +4616,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_JUSTICEWW, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_JOWAW, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_JUSTICEWW, oCaster))
|
||||
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
|
||||
@@ -4618,7 +4656,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_JUSTICEWW, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_JOWAW, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_JUSTICEWW, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -4719,6 +4760,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
|
||||
if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_KNIGHT_CHALICE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_KOTC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_KNIGHT_CHALICE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
@@ -4791,6 +4835,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_KOTMC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
|
||||
|
||||
@@ -4823,6 +4870,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
|
||||
if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_KOTMC, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
@@ -4896,7 +4946,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster); */
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
|
||||
@@ -4933,6 +4986,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
|
||||
if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_NENTYAR_HUNTER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */
|
||||
@@ -5135,6 +5191,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
|
||||
if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_PALADIN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_PALADIN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_PALADIN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
@@ -5207,7 +5266,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster); */
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_MORNINGLORD_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster);
|
||||
@@ -5240,7 +5302,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_RANGER, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -5311,7 +5376,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SHAMAN, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
@@ -5350,7 +5418,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_OASHAMAN, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -5524,6 +5595,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_SOHEI, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_SOHEI, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_SOHEI, oCaster))
|
||||
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
|
||||
|
||||
@@ -5561,7 +5635,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_SOHEI, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_SOHEI, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_BFZ_SPELLCASTING_SOHEI, oCaster))
|
||||
nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2;
|
||||
@@ -5631,6 +5708,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
|
||||
|
||||
@@ -5663,6 +5743,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|
||||
|
||||
if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster);
|
||||
|
||||
if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster);
|
||||
|
||||
/* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_SOL, oCaster))
|
||||
nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster);
|
||||
|
||||
@@ -16,6 +16,7 @@ Command summary:
|
||||
*/
|
||||
|
||||
#include "prc_inc_chat"
|
||||
#include "inc_persist_loca"
|
||||
|
||||
const string CMD_POWER_ATTACK = "pow-erattack";
|
||||
|
||||
|
||||
@@ -380,6 +380,7 @@ int Vile_Feat(int iTypeWeap)
|
||||
case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_BASTARDSWORD);
|
||||
case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_VILE_MARTIAL_BATTLEAXE);
|
||||
case BASE_ITEM_CLUB: return GetHasFeat(FEAT_VILE_MARTIAL_CLUB);
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return GetHasFeat(FEAT_VILE_MARTIAL_CLUB);
|
||||
case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_VILE_MARTIAL_DAGGER);
|
||||
case BASE_ITEM_DART: return GetHasFeat(FEAT_VILE_MARTIAL_DART);
|
||||
case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_VILE_MARTIAL_DIREMACE);
|
||||
@@ -402,6 +403,7 @@ int Vile_Feat(int iTypeWeap)
|
||||
case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_LONGSWORD);
|
||||
case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_VILE_MARTIAL_MORNINGSTAR);
|
||||
case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_VILE_MARTIAL_QUARTERSTAFF);
|
||||
case BASE_ITEM_MAGICSTAFF: return GetHasFeat(FEAT_VILE_MARTIAL_QUARTERSTAFF);
|
||||
case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_VILE_MARTIAL_RAPIER);
|
||||
case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_VILE_MARTIAL_SCIMITAR);
|
||||
case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_VILE_MARTIAL_SCYTHE);
|
||||
@@ -425,7 +427,7 @@ int Vile_Feat(int iTypeWeap)
|
||||
GetHasFeat(FEAT_VILE_MARTIAL_RAPIER) ||
|
||||
GetHasFeat(FEAT_VILE_MARTIAL_ELVEN_THINBLADE));
|
||||
|
||||
case BASE_ITEM_ELVEN_COURTBLADE: return GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD ||
|
||||
case BASE_ITEM_ELVEN_COURTBLADE: return (GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD) ||
|
||||
GetHasFeat(FEAT_VILE_MARTIAL_ELVEN_COURTBLADE));
|
||||
|
||||
case BASE_ITEM_DOUBLE_SCIMITAR: return GetHasFeat(FEAT_VILE_MARTIAL_DBL_SCIMITAR);
|
||||
@@ -460,6 +462,7 @@ int GetSanctifedMartialFeat(int iTypeWeap)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_SANCTIFY_MARTIAL_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_SANCTIFY_MARTIAL_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_SANCTIFY_MARTIAL_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_SANCTIFY_MARTIAL_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_SANCTIFY_MARTIAL_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_SANCTIFY_MARTIAL_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_SANCTIFY_MARTIAL_DIREMACE;
|
||||
@@ -482,6 +485,7 @@ int GetSanctifedMartialFeat(int iTypeWeap)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_SANCTIFY_MARTIAL_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_SANCTIFY_MARTIAL_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_SANCTIFY_MARTIAL_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_SANCTIFY_MARTIAL_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_SANCTIFY_MARTIAL_SCYTHE;
|
||||
@@ -533,6 +537,7 @@ int Sanctify_Feat(int iTypeWeap)
|
||||
case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BASTARDSWORD);
|
||||
case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BATTLEAXE);
|
||||
case BASE_ITEM_CLUB: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_CLUB);
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_CLUB);
|
||||
case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DAGGER);
|
||||
case BASE_ITEM_DART: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DART);
|
||||
case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DIREMACE);
|
||||
@@ -555,6 +560,7 @@ int Sanctify_Feat(int iTypeWeap)
|
||||
case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGSWORD);
|
||||
case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_MORNINGSTAR);
|
||||
case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF);
|
||||
case BASE_ITEM_MAGICSTAFF: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF);
|
||||
case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER);
|
||||
case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCIMITAR);
|
||||
case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCYTHE);
|
||||
|
||||
@@ -1082,6 +1082,7 @@ int GetIsTwoHandedMeleeWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_HEAVYFLAIL: return TRUE;
|
||||
case BASE_ITEM_SCYTHE: return TRUE;
|
||||
case BASE_ITEM_QUARTERSTAFF: return TRUE;
|
||||
//case BASE_ITEM_MAGICSTAFF: return TRUE;
|
||||
case BASE_ITEM_ELVEN_COURTBLADE: return TRUE;
|
||||
case BASE_ITEM_MAUL: return TRUE;
|
||||
case BASE_ITEM_FALCHION: return TRUE;
|
||||
@@ -1093,7 +1094,7 @@ int GetIsTwoHandedMeleeWeapon(object oWeap)
|
||||
{
|
||||
return GetIsTwoHandedMeleeWeaponType(GetBaseItemType(oWeap));
|
||||
}
|
||||
|
||||
|
||||
int GetIsCreatureWeaponType(int iWeaponType)
|
||||
{
|
||||
// any of the three creature weapon types that produce bludgeoning, piercing or slashing damage
|
||||
@@ -1130,6 +1131,7 @@ int GetIsSimpleWeaponType(int iWeaponType)
|
||||
{
|
||||
case BASE_ITEM_MORNINGSTAR: return 1;
|
||||
case BASE_ITEM_QUARTERSTAFF: return 1;
|
||||
case BASE_ITEM_MAGICSTAFF: return 1;
|
||||
case BASE_ITEM_SHORTSPEAR: return 1;
|
||||
case BASE_ITEM_HEAVYCROSSBOW: return 1;
|
||||
case BASE_ITEM_INVALID: return 1;
|
||||
@@ -1139,8 +1141,8 @@ int GetIsSimpleWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_CSLSHPRCWEAP: return 1;
|
||||
case BASE_ITEM_GLOVES: return 1;
|
||||
case BASE_ITEM_BRACER: return 1;
|
||||
|
||||
case BASE_ITEM_CLUB: return 2;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return 1;
|
||||
|
||||
case BASE_ITEM_DAGGER: return 2;
|
||||
case BASE_ITEM_LIGHTMACE: return 2;
|
||||
case BASE_ITEM_SICKLE: return 2;
|
||||
@@ -1204,6 +1206,7 @@ int GetIsDoubleSidedWeaponType(int iWeaponType)
|
||||
return ( iWeaponType == BASE_ITEM_DIREMACE
|
||||
|| iWeaponType == BASE_ITEM_DOUBLEAXE
|
||||
|| iWeaponType == BASE_ITEM_TWOBLADEDSWORD
|
||||
|| iWeaponType == BASE_ITEM_DOUBLE_SCIMITAR
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1276,6 +1279,19 @@ struct WeaponFeat GetAllFeatsOfWeaponType(int iWeaponType)
|
||||
sFeat.VileMartialStrike = FEAT_VILE_MARTIAL_CLUB;
|
||||
break;
|
||||
}
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: {
|
||||
sFeat.Focus = FEAT_WEAPON_FOCUS_CLUB;
|
||||
sFeat.Specialization = FEAT_WEAPON_SPECIALIZATION_CLUB;
|
||||
sFeat.EpicFocus = FEAT_EPIC_WEAPON_FOCUS_CLUB;
|
||||
sFeat.EpicSpecialization = FEAT_EPIC_WEAPON_SPECIALIZATION_CLUB;
|
||||
sFeat.ImprovedCritical = FEAT_IMPROVED_CRITICAL_CLUB;
|
||||
sFeat.OverwhelmingCritical = FEAT_EPIC_OVERWHELMING_CRITICAL_CLUB;
|
||||
sFeat.DevastatingCritical = FEAT_EPIC_DEVASTATING_CRITICAL_CLUB;
|
||||
sFeat.WeaponOfChoice = FEAT_WEAPON_OF_CHOICE_CLUB;
|
||||
sFeat.SanctifyMartialStrike = FEAT_SANCTIFY_MARTIAL_CLUB;
|
||||
sFeat.VileMartialStrike = FEAT_VILE_MARTIAL_CLUB;
|
||||
break;
|
||||
}
|
||||
case BASE_ITEM_DAGGER: {
|
||||
sFeat.Focus = FEAT_WEAPON_FOCUS_DAGGER;
|
||||
sFeat.Specialization = FEAT_WEAPON_SPECIALIZATION_DAGGER;
|
||||
@@ -1562,6 +1578,19 @@ struct WeaponFeat GetAllFeatsOfWeaponType(int iWeaponType)
|
||||
sFeat.VileMartialStrike = FEAT_VILE_MARTIAL_QUARTERSTAFF;
|
||||
break;
|
||||
}
|
||||
case BASE_ITEM_MAGICSTAFF: {
|
||||
sFeat.Focus = FEAT_WEAPON_FOCUS_STAFF;
|
||||
sFeat.Specialization = FEAT_WEAPON_SPECIALIZATION_STAFF;
|
||||
sFeat.EpicFocus = FEAT_EPIC_WEAPON_FOCUS_QUARTERSTAFF;
|
||||
sFeat.EpicSpecialization = FEAT_EPIC_WEAPON_SPECIALIZATION_QUARTERSTAFF;
|
||||
sFeat.ImprovedCritical = FEAT_IMPROVED_CRITICAL_STAFF;
|
||||
sFeat.OverwhelmingCritical = FEAT_EPIC_OVERWHELMING_CRITICAL_QUARTERSTAFF;
|
||||
sFeat.DevastatingCritical = FEAT_EPIC_DEVASTATING_CRITICAL_QUARTERSTAFF;
|
||||
sFeat.WeaponOfChoice = FEAT_WEAPON_OF_CHOICE_QUARTERSTAFF;
|
||||
sFeat.SanctifyMartialStrike = FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF;
|
||||
sFeat.VileMartialStrike = FEAT_VILE_MARTIAL_QUARTERSTAFF;
|
||||
break;
|
||||
}
|
||||
case BASE_ITEM_RAPIER: {
|
||||
sFeat.Focus = FEAT_WEAPON_FOCUS_RAPIER;
|
||||
sFeat.Specialization = FEAT_WEAPON_SPECIALIZATION_RAPIER;
|
||||
@@ -8074,7 +8103,12 @@ void AttackLoopLogic(object oDefender, object oAttacker,
|
||||
if (DEBUG) DoDebug("entered AttackLoopLogic: bFirstAttack = " + IntToString(bFirstAttack) + ", cleave = " + IntToString(bIsCleaveAttack) + ", current action = " + GetActionName(iAction));
|
||||
if (DEBUG) DoDebug("AttackLoopLogic: iMainAttacks = " + IntToString(iMainAttacks) + ", iOffHandAttacks = " + IntToString(iOffHandAttacks) + ", iBonusAttacks = " + IntToString(iBonusAttacks));
|
||||
|
||||
int bIsRangedAttack = sAttackVars.bIsRangedWeapon || sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL || sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED;
|
||||
//int bIsRangedAttack = sAttackVars.bIsRangedWeapon || sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL || sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED;
|
||||
|
||||
int bIsRangedAttack = sAttackVars.bIsRangedWeapon ||
|
||||
sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL ||
|
||||
sAttackVars.iTouchAttackType == TOUCH_ATTACK_RANGED ||
|
||||
GetLocalInt(oAttacker, "WhirlingBlade");
|
||||
|
||||
// check for valid target etc., but only if it is not a cleave or circle kick (in this case we checked all of this before)
|
||||
if (!bIsCleaveAttack)
|
||||
|
||||
@@ -273,6 +273,7 @@ void TigerBlooded(object oInitiator, object oTarget);
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "prc_inc_sp_tch"
|
||||
#include "prc_feat_const"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
@@ -1140,6 +1141,9 @@ void DoCharge(object oPC, object oTarget, int nDoAttack = TRUE, int nGenerateAoO
|
||||
nPounce = TRUE;
|
||||
if (GetHasSpellEffect(VESTIGE_CHUPOCLOPS, oPC) && GetLocalInt(oPC, "ExploitVestige") != VESTIGE_CHUPOCLOPS_POUNCE)
|
||||
nPounce = TRUE;
|
||||
//:: Lion of Talisid
|
||||
if(GetHasFeat(FEAT_LOT_LIONS_POUNCE, oPC))
|
||||
nPounce = TRUE;
|
||||
|
||||
// Checks for a White Raven Stance
|
||||
// If it exists, +1 damage/initiator level
|
||||
@@ -1318,7 +1322,29 @@ int DoTrip(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TRUE,
|
||||
DelayCommand(0.0, PerformAttack(oTarget, oPC, eNone, 0.0, 0, 0, 0, "Improved Trip Free Attack Hit", "Improved Trip Free Attack Miss"));
|
||||
}
|
||||
}
|
||||
else // If you fail, enemy gets a counter trip attempt, using Strength
|
||||
else // If you fail, enemy gets a counter trip attempt, using Strength
|
||||
{
|
||||
if(!nCounterTrip)
|
||||
{
|
||||
nTargetStat = GetAbilityModifier(ABILITY_STRENGTH, oTarget) + GetCombatMoveCheckBonus(oTarget, COMBAT_MOVE_TRIP, FALSE, TRUE);
|
||||
FloatingTextStringOnCreature("You have failed on your Trip attempt",oPC, FALSE);
|
||||
// Roll counter trip attempt
|
||||
nTargetCheck = nTargetStat + nTargetBonus + d20();
|
||||
nPCCheck = nPCStat + nPCBonus + d20();
|
||||
// If counters aren't allowed, don't knock em down
|
||||
// Its down here to allow the text message to go through
|
||||
SendMessageToPC(oPC, "Enemy Counter Trip Check: "+IntToString(nPCCheck)+" vs "+IntToString(nTargetCheck));
|
||||
|
||||
SetLocalInt(oPC, "TripDifference", nTargetCheck - nPCCheck);
|
||||
DelayCommand(2.0, DeleteLocalInt(oPC, "TripDifference"));
|
||||
}
|
||||
if (nTargetCheck >= nPCCheck && nCounterTrip)
|
||||
{
|
||||
// Knock em down
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectKnockdown()), oPC, 6.0);
|
||||
}
|
||||
}
|
||||
/* else // If you fail, enemy gets a counter trip attempt, using Strength
|
||||
{
|
||||
nTargetStat = GetAbilityModifier(ABILITY_STRENGTH, oTarget) + GetCombatMoveCheckBonus(oTarget, COMBAT_MOVE_TRIP, FALSE, TRUE);
|
||||
FloatingTextStringOnCreature("You have failed on your Trip attempt",oPC, FALSE);
|
||||
@@ -1335,7 +1361,7 @@ int DoTrip(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TRUE,
|
||||
}
|
||||
SetLocalInt(oPC, "TripDifference", nTargetCheck - nPCCheck);
|
||||
DelayCommand(2.0, DeleteLocalInt(oPC, "TripDifference"));
|
||||
}
|
||||
} */
|
||||
}
|
||||
else
|
||||
FloatingTextStringOnCreature("You have failed on your Trip attempt",oPC, FALSE);
|
||||
@@ -1938,10 +1964,21 @@ void TigerBlooded(object oInitiator, object oTarget)
|
||||
int DoDisarm(object oPC, object oTarget, int nExtraBonus = 0, int nGenerateAoO = TRUE, int nCounter = TRUE)
|
||||
{
|
||||
object oTargetWep = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
|
||||
|
||||
int bNoDisarm = GetHasFeat(FEAT_INTRINSIC_WEAPON, oTarget);
|
||||
|
||||
string sName = GetName(oTarget);
|
||||
|
||||
if(bNoDisarm)
|
||||
{
|
||||
FloatingTextStringOnCreature(sName+" is wielding an intrinsic weapon", oPC, FALSE);
|
||||
AssignCommand(oPC, ActionAttack(oTarget));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetIsObjectValid(oTargetWep) || GetPlotFlag(oTargetWep) || (!GetIsCreatureDisarmable(oTarget) && !GetPRCSwitch(PRC_PNP_DISARM)) || GetLocalInt(oTarget, "TigerFangDisarm"))
|
||||
{
|
||||
FloatingTextStringOnCreature("Target is not a legal target", oPC, FALSE);
|
||||
FloatingTextStringOnCreature(sName+" is not a legal target", oPC, FALSE);
|
||||
AssignCommand(oPC, ActionAttack(oTarget));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2312,7 +2349,10 @@ void DoShieldCharge(object oPC, object oTarget, int nSlam = FALSE)
|
||||
if(GetLevelByClass(CLASS_TYPE_CELEBRANT_SHARESS, oPC) >= 5)
|
||||
nPounce = TRUE;
|
||||
if(GetRacialType(oPC) == RACIAL_TYPE_MARRUSAULT)
|
||||
nPounce = TRUE;
|
||||
nPounce = TRUE;
|
||||
//:: Lion of Talisid
|
||||
if(GetHasFeat(FEAT_LOT_LIONS_POUNCE, oPC))
|
||||
nPounce = TRUE;
|
||||
|
||||
// Checks for a White Raven Stance
|
||||
// If it exists, +1 damage/initiator level
|
||||
|
||||
@@ -133,6 +133,7 @@ const int METAMAGIC_QUICKEN_LEVEL = 4;
|
||||
#include "prc_inc_damage"
|
||||
#include "prc_inc_sb_const" // Spell Book Constants
|
||||
#include "x0_i0_position"
|
||||
#include "inc_newspellbook"
|
||||
|
||||
/*
|
||||
access to prc_inc_nwscript via prc_inc_damage
|
||||
@@ -410,6 +411,8 @@ int PRCGetSpellLevelForClass(int nSpell, int nClass)
|
||||
sSpellLevel = Get2DACache("spells", "Cleric", nSpell);
|
||||
else if (nClass == CLASS_TYPE_BARD)
|
||||
sSpellLevel = Get2DACache("spells", "Bard", nSpell);
|
||||
else if (nClass == CLASS_TYPE_ASSASSIN)
|
||||
sSpellLevel = Get2DACache("spells", "Assassin", nSpell);
|
||||
else if (nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK)
|
||||
sSpellLevel = Get2DACache("spells", "Cultist", nSpell);
|
||||
else if (nClass == CLASS_TYPE_NENTYAR_HUNTER)
|
||||
@@ -462,7 +465,7 @@ int PRCGetSpellLevelForClass(int nSpell, int nClass)
|
||||
return nSpellLevel;
|
||||
}
|
||||
|
||||
// returns the spelllevel of nSpell as it can be cast by oCreature
|
||||
// returns the spell circle level of nSpell as it can be cast by oCreature
|
||||
int PRCGetSpellLevel(object oCreature, int nSpell)
|
||||
{
|
||||
/*if (!PRCGetHasSpell(nSpell, oCreature))
|
||||
@@ -605,7 +608,7 @@ int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF)
|
||||
if(nSpellbookType == SPELLBOOK_TYPE_PREPARED)
|
||||
{
|
||||
nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), j);
|
||||
if(DEBUG) DoDebug("PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
|
||||
if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
|
||||
if(nCount > 0)
|
||||
{
|
||||
nUses += nCount;
|
||||
@@ -615,7 +618,7 @@ int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF)
|
||||
{
|
||||
nSpellLevel = StringToInt(Get2DACache(sFile, "Level", j));
|
||||
nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel);
|
||||
if(DEBUG) DoDebug("PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
|
||||
if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
|
||||
if(nCount > 0)
|
||||
{
|
||||
nUses += nCount;
|
||||
|
||||
@@ -169,8 +169,8 @@ int GetSubschoolFlags(int nSpellID);
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "inc_2dacache" // already has access via inc_utility
|
||||
//#include "inc_utility"
|
||||
#include "inc_2dacache"
|
||||
#include "inc_utility"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
|
||||
@@ -49,6 +49,8 @@ const int BRILLIANCE_SLOT_3 = 3919;
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
//////////////////////////////////////////////////
|
||||
void TriggerInspiration(object oPC, int nCombat);
|
||||
|
||||
|
||||
void PrepareArcDilSpell(object oPC, int nSpell)
|
||||
{
|
||||
@@ -188,7 +190,8 @@ void SetInspiration(object oPC)
|
||||
for(i = FEAT_FONT_INSPIRATION_1; i <= FEAT_FONT_INSPIRATION_10; i++)
|
||||
if(GetHasFeat(i, oPC)) nFont++;
|
||||
|
||||
nInspiration += nFont * (1 + nFont + 1) / 2;
|
||||
//nInspiration += nFont * (1 + nFont + 1) / 2;
|
||||
nInspiration += nFont * (nFont + 1) / 2;
|
||||
SetLocalInt(oPC, "InspirationPool", nInspiration);
|
||||
FloatingTextStringOnCreature("Encounter begins with "+IntToString(nInspiration)+" inspiration", oPC, FALSE);
|
||||
}
|
||||
@@ -201,6 +204,8 @@ void ClearInspiration(object oPC)
|
||||
|
||||
int ExpendInspiration(object oPC, int nCost)
|
||||
{
|
||||
if (nCost <= 0) return FALSE;
|
||||
|
||||
int nInspiration = GetLocalInt(oPC, "InspirationPool");
|
||||
if (nInspiration >= nCost)
|
||||
{
|
||||
@@ -261,6 +266,21 @@ void FactotumTriggerAbil(object oPC, int nAbil)
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 60.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
void TriggerInspiration(object oPC, int nCombat)
|
||||
{
|
||||
SetLocalInt(oPC, "InspirationHBRunning", TRUE);
|
||||
DelayCommand(0.249, DeleteLocalInt(oPC, "InspirationHBRunning"));
|
||||
int nCurrent = GetIsInCombat(oPC);
|
||||
// We just entered combat
|
||||
if (nCurrent == TRUE && nCombat == FALSE)
|
||||
SetInspiration(oPC);
|
||||
else if (nCurrent == FALSE && nCombat == TRUE) // Just left combat
|
||||
ClearInspiration(oPC);
|
||||
|
||||
DelayCommand(0.25, TriggerInspiration(oPC, nCurrent));
|
||||
}
|
||||
|
||||
|
||||
/*void AddCunningBrillianceAbility(object oPC, int nAbil)
|
||||
{
|
||||
if (DEBUG) DoDebug("AddCunningBrillianceAbility "+IntToString(nAbil));
|
||||
|
||||
@@ -23,11 +23,14 @@ const int FEAT_TYPE_IMPROVED_CRITICAL = 5;
|
||||
const int FEAT_TYPE_OVERWHELMING_CRITICAL = 6;
|
||||
const int FEAT_TYPE_DEVASTATING_CRITICAL = 7;
|
||||
const int FEAT_TYPE_WEAPON_OF_CHOICE = 8;
|
||||
const int FEAT_TYPE_WEAPON_PROFICIENCY = 9;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
int GetProficiencyFeatOfWeaponType(int iWeaponType);
|
||||
|
||||
/**
|
||||
* Returns the appropriate weapon feat given a weapon type.
|
||||
*
|
||||
@@ -210,10 +213,86 @@ int GetFeatOfWeaponType(int iWeaponType, int iFeatType)
|
||||
case FEAT_TYPE_OVERWHELMING_CRITICAL: return GetOverwhelmingCriticalFeatOfWeaponType(iWeaponType);
|
||||
case FEAT_TYPE_DEVASTATING_CRITICAL: return GetDevastatingCriticalFeatOfWeaponType(iWeaponType);
|
||||
case FEAT_TYPE_WEAPON_OF_CHOICE: return GetWeaponOfChoiceFeatOfWeaponType(iWeaponType);
|
||||
case FEAT_TYPE_WEAPON_PROFICIENCY: return GetProficiencyFeatOfWeaponType(iWeaponType);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetProficiencyFeatOfWeaponType(int iWeaponType)
|
||||
{
|
||||
switch(iWeaponType)
|
||||
{
|
||||
case BASE_ITEM_CBLUDGWEAPON:
|
||||
case BASE_ITEM_CPIERCWEAPON:
|
||||
case BASE_ITEM_CSLASHWEAPON:
|
||||
case BASE_ITEM_CSLSHPRCWEAP: return FEAT_WEAPON_PROFICIENCY_CREATURE;
|
||||
case BASE_ITEM_INVALID: return FEAT_IMPROVED_UNARMED_STRIKE;
|
||||
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_WEAPON_PROFICIENCY_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_WEAPON_PROFICIENCY_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_WEAPON_PROFICIENCY_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_WEAPON_PROFICIENCY_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_PROFICIENCY_DIRE_MACE;
|
||||
case BASE_ITEM_DOUBLEAXE: return FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE;
|
||||
case BASE_ITEM_DWARVENWARAXE: return FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE;
|
||||
case BASE_ITEM_GREATAXE: return FEAT_WEAPON_PROFICIENCY_GREATAXE;
|
||||
case BASE_ITEM_GREATSWORD: return FEAT_WEAPON_PROFICIENCY_GREATSWORD;
|
||||
case BASE_ITEM_HALBERD: return FEAT_WEAPON_PROFICIENCY_HALBERD;
|
||||
case BASE_ITEM_HANDAXE: return FEAT_WEAPON_PROFICIENCY_HANDAXE;
|
||||
case BASE_ITEM_HEAVYCROSSBOW: return FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW;
|
||||
case BASE_ITEM_HEAVYFLAIL: return FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL;
|
||||
case BASE_ITEM_KAMA: return FEAT_WEAPON_PROFICIENCY_KAMA;
|
||||
case BASE_ITEM_KATANA: return FEAT_WEAPON_PROFICIENCY_KATANA;
|
||||
case BASE_ITEM_KUKRI: return FEAT_WEAPON_PROFICIENCY_KUKRI;
|
||||
case BASE_ITEM_LIGHTCROSSBOW: return FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW;
|
||||
case BASE_ITEM_LIGHTFLAIL: return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
|
||||
case BASE_ITEM_LIGHTHAMMER: return FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER;
|
||||
case BASE_ITEM_LIGHTMACE: return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
|
||||
case BASE_ITEM_LONGBOW: return FEAT_WEAPON_PROFICIENCY_LONGBOW;
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_PROFICIENCY_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_PROFICIENCY_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_WEAPON_PROFICIENCY_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_PROFICIENCY_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_PROFICIENCY_SCYTHE;
|
||||
case BASE_ITEM_SHORTBOW: return FEAT_WEAPON_PROFICIENCY_SHORTBOW;
|
||||
case BASE_ITEM_SHORTSPEAR: return FEAT_WEAPON_PROFICIENCY_SHORTSPEAR;
|
||||
case BASE_ITEM_SHORTSWORD: return FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
|
||||
case BASE_ITEM_SHURIKEN: return FEAT_WEAPON_PROFICIENCY_SHURIKEN;
|
||||
case BASE_ITEM_SICKLE: return FEAT_WEAPON_PROFICIENCY_SICKLE;
|
||||
case BASE_ITEM_SLING: return FEAT_WEAPON_PROFICIENCY_SLING;
|
||||
case BASE_ITEM_THROWINGAXE: return FEAT_WEAPON_PROFICIENCY_THROWING_AXE;
|
||||
case BASE_ITEM_TRIDENT: return FEAT_WEAPON_PROFICIENCY_TRIDENT;
|
||||
case BASE_ITEM_TWOBLADEDSWORD: return FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD;
|
||||
case BASE_ITEM_WARHAMMER: return FEAT_WEAPON_PROFICIENCY_WARHAMMER;
|
||||
case BASE_ITEM_WHIP: return FEAT_WEAPON_PROFICIENCY_WHIP;
|
||||
|
||||
//:: new item types
|
||||
case BASE_ITEM_DOUBLE_SCIMITAR: return FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR;
|
||||
case BASE_ITEM_EAGLE_CLAW: return FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW;
|
||||
case BASE_ITEM_ELVEN_COURTBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE;
|
||||
case BASE_ITEM_ELVEN_LIGHTBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE;
|
||||
case BASE_ITEM_ELVEN_THINBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE;
|
||||
case BASE_ITEM_FALCHION: return FEAT_WEAPON_PROFICIENCY_FALCHION;
|
||||
case BASE_ITEM_GOAD: return FEAT_WEAPON_PROFICIENCY_GOAD;
|
||||
case BASE_ITEM_HEAVY_MACE: return FEAT_WEAPON_PROFICIENCY_HEAVY_MACE;
|
||||
case BASE_ITEM_HEAVY_PICK: return FEAT_WEAPON_PROFICIENCY_HEAVY_PICK;
|
||||
case BASE_ITEM_KATAR: return FEAT_WEAPON_PROFICIENCY_KATAR;
|
||||
case BASE_ITEM_LIGHT_LANCE: return FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE;
|
||||
case BASE_ITEM_LIGHT_PICK: return FEAT_WEAPON_PROFICIENCY_LIGHT_PICK;
|
||||
case BASE_ITEM_MAUL: return FEAT_WEAPON_PROFICIENCY_MAUL;
|
||||
case BASE_ITEM_NUNCHAKU: return FEAT_WEAPON_PROFICIENCY_NUNCHAKU;
|
||||
case BASE_ITEM_SAI: return FEAT_WEAPON_PROFICIENCY_SAI;
|
||||
case BASE_ITEM_SAP: return FEAT_WEAPON_PROFICIENCY_SAP;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int GetFocusFeatOfWeaponType(int iWeaponType)
|
||||
{
|
||||
switch(iWeaponType)
|
||||
@@ -226,6 +305,7 @@ int GetFocusFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_FOCUS_BASTARD_SWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_FOCUS_BATTLE_AXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_WEAPON_FOCUS_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_WEAPON_FOCUS_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_WEAPON_FOCUS_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_WEAPON_FOCUS_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_FOCUS_DIRE_MACE;
|
||||
@@ -248,6 +328,7 @@ int GetFocusFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_FOCUS_LONG_SWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_FOCUS_MORNING_STAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_FOCUS_STAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_WEAPON_FOCUS_STAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_WEAPON_FOCUS_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_FOCUS_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_FOCUS_SCYTHE;
|
||||
@@ -296,6 +377,7 @@ int GetSpecializationFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_SPECIALIZATION_BASTARD_SWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_SPECIALIZATION_BATTLE_AXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_WEAPON_SPECIALIZATION_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_WEAPON_SPECIALIZATION_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_WEAPON_SPECIALIZATION_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_WEAPON_SPECIALIZATION_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_SPECIALIZATION_DIRE_MACE;
|
||||
@@ -318,6 +400,7 @@ int GetSpecializationFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_SPECIALIZATION_LONG_SWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_SPECIALIZATION_MORNING_STAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_SPECIALIZATION_STAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_WEAPON_SPECIALIZATION_STAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_WEAPON_SPECIALIZATION_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_SPECIALIZATION_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_SPECIALIZATION_SCYTHE;
|
||||
@@ -366,6 +449,7 @@ int GetEpicFocusFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_WEAPON_FOCUS_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_WEAPON_FOCUS_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_EPIC_WEAPON_FOCUS_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_EPIC_WEAPON_FOCUS_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_EPIC_WEAPON_FOCUS_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_EPIC_WEAPON_FOCUS_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_EPIC_WEAPON_FOCUS_DIREMACE;
|
||||
@@ -388,6 +472,7 @@ int GetEpicFocusFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_WEAPON_FOCUS_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_WEAPON_FOCUS_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_WEAPON_FOCUS_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_EPIC_WEAPON_FOCUS_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_EPIC_WEAPON_FOCUS_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_WEAPON_FOCUS_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_EPIC_WEAPON_FOCUS_SCYTHE;
|
||||
@@ -436,6 +521,7 @@ int GetEpicSpecializationFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_WEAPON_SPECIALIZATION_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_EPIC_WEAPON_SPECIALIZATION_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_EPIC_WEAPON_SPECIALIZATION_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_EPIC_WEAPON_SPECIALIZATION_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_EPIC_WEAPON_SPECIALIZATION_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_EPIC_WEAPON_SPECIALIZATION_DIREMACE;
|
||||
@@ -458,7 +544,8 @@ int GetEpicSpecializationFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_WEAPON_SPECIALIZATION_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_WEAPON_SPECIALIZATION_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_WEAPON_SPECIALIZATION_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_EPIC_WEAPON_SPECIALIZATION_RAPIER;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_EPIC_WEAPON_SPECIALIZATION_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_EPIC_WEAPON_SPECIALIZATION_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_WEAPON_SPECIALIZATION_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_EPIC_WEAPON_SPECIALIZATION_SCYTHE;
|
||||
case BASE_ITEM_SHORTBOW: return FEAT_EPIC_WEAPON_SPECIALIZATION_SHORTBOW;
|
||||
@@ -506,6 +593,7 @@ int GetImprovedCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_IMPROVED_CRITICAL_BASTARD_SWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_IMPROVED_CRITICAL_BATTLE_AXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_IMPROVED_CRITICAL_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_IMPROVED_CRITICAL_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_IMPROVED_CRITICAL_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_IMPROVED_CRITICAL_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_IMPROVED_CRITICAL_DIRE_MACE;
|
||||
@@ -528,6 +616,7 @@ int GetImprovedCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_IMPROVED_CRITICAL_LONG_SWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_IMPROVED_CRITICAL_MORNING_STAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_IMPROVED_CRITICAL_STAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_IMPROVED_CRITICAL_STAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_IMPROVED_CRITICAL_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_IMPROVED_CRITICAL_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_IMPROVED_CRITICAL_SCYTHE;
|
||||
@@ -576,6 +665,7 @@ int GetOverwhelmingCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_OVERWHELMING_CRITICAL_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_OVERWHELMING_CRITICAL_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_EPIC_OVERWHELMING_CRITICAL_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_EPIC_OVERWHELMING_CRITICAL_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_EPIC_OVERWHELMING_CRITICAL_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_EPIC_OVERWHELMING_CRITICAL_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_EPIC_OVERWHELMING_CRITICAL_DIREMACE;
|
||||
@@ -598,6 +688,7 @@ int GetOverwhelmingCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_OVERWHELMING_CRITICAL_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_OVERWHELMING_CRITICAL_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_OVERWHELMING_CRITICAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_EPIC_OVERWHELMING_CRITICAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_EPIC_OVERWHELMING_CRITICAL_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_OVERWHELMING_CRITICAL_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_EPIC_OVERWHELMING_CRITICAL_SCYTHE;
|
||||
@@ -646,6 +737,7 @@ int GetDevastatingCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_EPIC_DEVASTATING_CRITICAL_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_EPIC_DEVASTATING_CRITICAL_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_EPIC_DEVASTATING_CRITICAL_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_EPIC_DEVASTATING_CRITICAL_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_EPIC_DEVASTATING_CRITICAL_DAGGER;
|
||||
case BASE_ITEM_DART: return FEAT_EPIC_DEVASTATING_CRITICAL_DART;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_EPIC_DEVASTATING_CRITICAL_DIREMACE;
|
||||
@@ -668,6 +760,7 @@ int GetDevastatingCriticalFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_EPIC_DEVASTATING_CRITICAL_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_EPIC_DEVASTATING_CRITICAL_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_EPIC_DEVASTATING_CRITICAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_EPIC_DEVASTATING_CRITICAL_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_EPIC_DEVASTATING_CRITICAL_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_EPIC_DEVASTATING_CRITICAL_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_EPIC_DEVASTATING_CRITICAL_SCYTHE;
|
||||
@@ -711,6 +804,7 @@ int GetWeaponOfChoiceFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_OF_CHOICE_BASTARDSWORD;
|
||||
case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_OF_CHOICE_BATTLEAXE;
|
||||
case BASE_ITEM_CLUB: return FEAT_WEAPON_OF_CHOICE_CLUB;
|
||||
case BASE_ITEM_CRAFTED_SCEPTER: return FEAT_WEAPON_OF_CHOICE_CLUB;
|
||||
case BASE_ITEM_DAGGER: return FEAT_WEAPON_OF_CHOICE_DAGGER;
|
||||
case BASE_ITEM_DIREMACE: return FEAT_WEAPON_OF_CHOICE_DIREMACE;
|
||||
case BASE_ITEM_DOUBLEAXE: return FEAT_WEAPON_OF_CHOICE_DOUBLEAXE;
|
||||
@@ -729,6 +823,7 @@ int GetWeaponOfChoiceFeatOfWeaponType(int iWeaponType)
|
||||
case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_OF_CHOICE_LONGSWORD;
|
||||
case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_OF_CHOICE_MORNINGSTAR;
|
||||
case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_OF_CHOICE_QUARTERSTAFF;
|
||||
case BASE_ITEM_MAGICSTAFF: return FEAT_WEAPON_OF_CHOICE_QUARTERSTAFF;
|
||||
case BASE_ITEM_RAPIER: return FEAT_WEAPON_OF_CHOICE_RAPIER;
|
||||
case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_OF_CHOICE_SCIMITAR;
|
||||
case BASE_ITEM_SCYTHE: return FEAT_WEAPON_OF_CHOICE_SCYTHE;
|
||||
@@ -787,6 +882,7 @@ int GetWeaponSize(object oWeapon)
|
||||
case BASE_ITEM_GREATAXE:
|
||||
case BASE_ITEM_HEAVYFLAIL:
|
||||
case BASE_ITEM_QUARTERSTAFF:
|
||||
//case BASE_ITEM_MAGICSTAFF:
|
||||
case BASE_ITEM_SCYTHE:
|
||||
case BASE_ITEM_SHORTSPEAR:
|
||||
case BASE_ITEM_ELVEN_COURTBLADE:
|
||||
@@ -823,6 +919,7 @@ int PRCLargeWeaponCheck(int iBaseType, int nSize)
|
||||
case BASE_ITEM_GREATAXE:
|
||||
case BASE_ITEM_HEAVYFLAIL:
|
||||
case BASE_ITEM_QUARTERSTAFF:
|
||||
//case BASE_ITEM_MAGICSTAFF:
|
||||
case BASE_ITEM_SCYTHE:
|
||||
case BASE_ITEM_SHORTSPEAR:
|
||||
case BASE_ITEM_ELVEN_COURTBLADE:
|
||||
@@ -834,4 +931,6 @@ int PRCLargeWeaponCheck(int iBaseType, int nSize)
|
||||
}
|
||||
}
|
||||
return sTest != "" && sTest != IntToString(nSize);
|
||||
}
|
||||
}
|
||||
|
||||
//::void main(){}
|
||||
@@ -108,8 +108,8 @@ void SetupCharacterData(object oPC)
|
||||
case CLASS_TYPE_ALIENIST: sScript = "prc_alienist"; break;
|
||||
case CLASS_TYPE_ARCANE_DUELIST: sScript = "prc_arcduel"; break;
|
||||
case CLASS_TYPE_ARCHIVIST: sScript = "prc_archivist"; iData |= 0x01; break;
|
||||
case CLASS_TYPE_ASSASSIN: iData |= 0x03; break;
|
||||
case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break;
|
||||
case CLASS_TYPE_ASSASSIN: break;
|
||||
//case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break;
|
||||
case CLASS_TYPE_BARD: iData |= 0x07; break;
|
||||
case CLASS_TYPE_BATTLESMITH: sScript = "prc_battlesmith"; break;
|
||||
case CLASS_TYPE_BEGUILER: iData |= 0x03; break;
|
||||
@@ -121,7 +121,7 @@ void SetupCharacterData(object oPC)
|
||||
case CLASS_TYPE_BLIGHTLORD: sScript = "prc_blightlord"; break;
|
||||
case CLASS_TYPE_BLOODCLAW_MASTER: sScript = "tob_bloodclaw"; break;
|
||||
case CLASS_TYPE_BONDED_SUMMONNER: sScript = "prc_bondedsumm"; break;
|
||||
case CLASS_TYPE_CELEBRANT_SHARESS: iData |= 0x03; break;
|
||||
case CLASS_TYPE_CELEBRANT_SHARESS: iData |= 0x07; break;
|
||||
case CLASS_TYPE_CHILD_OF_NIGHT: sScript = "shd_childnight"; break;
|
||||
case CLASS_TYPE_COC: sScript = "prc_coc"; break;
|
||||
case CLASS_TYPE_COMBAT_MEDIC: sScript = "prc_cbtmed"; break;
|
||||
@@ -180,6 +180,7 @@ void SetupCharacterData(object oPC)
|
||||
case CLASS_TYPE_LASHER: sScript = "prc_lasher"; break;
|
||||
case CLASS_TYPE_LEGENDARY_DREADNOUGHT: sScript = "prc_legendread"; break;
|
||||
case CLASS_TYPE_LICH: sScript = "pnp_lich_level"; break;
|
||||
case CLASS_TYPE_LION_OF_TALISID: sScript = "prc_lot"; break;
|
||||
case CLASS_TYPE_MAGEKILLER: sScript = "prc_magekill"; break;
|
||||
case CLASS_TYPE_MASTER_HARPER: sScript = "prc_masterh"; break;
|
||||
case CLASS_TYPE_MASTER_OF_NINE: sScript = "tob_masterofnine"; break;
|
||||
@@ -245,6 +246,7 @@ void SetupCharacterData(object oPC)
|
||||
case CLASS_TYPE_TOTEM_RAGER: sScript = "moi_totemrager"; break;
|
||||
case CLASS_TYPE_TRUENAMER: sScript = "true_truenamer"; iData |= 0x01; break;
|
||||
case CLASS_TYPE_VASSAL: sScript = "prc_vassal"; break;
|
||||
case CLASS_TYPE_VERDANT_LORD: sScript = "prc_verdantlord"; break;
|
||||
case CLASS_TYPE_VIGILANT: sScript = "prc_vigilant"; break;
|
||||
case CLASS_TYPE_WARBLADE: sScript = "tob_warblade"; iData |= 0x01; break;
|
||||
case CLASS_TYPE_WARCHIEF: sScript = "prc_warchief"; break;
|
||||
@@ -429,7 +431,7 @@ void EvalPRCFeats(object oPC)
|
||||
ExecuteScript("moi_events", oPC);
|
||||
|
||||
if (GetIsBinder(oPC))
|
||||
ExecuteScript("bnd_events", oPC);
|
||||
ExecuteScript("bnd_events", oPC);
|
||||
|
||||
// check if character with crafting feat has appropriate base item in her inventory
|
||||
// x - moved from prc_onhb_indiv.nss
|
||||
@@ -2264,6 +2266,8 @@ void FeatSpecialUsePerDay(object oPC)
|
||||
FeatUsePerDay(oPC, FEAT_FM_FOREST_DOMINION, ABILITY_CHARISMA, 3);
|
||||
FeatUsePerDay(oPC, FEAT_SOD_DEATH_TOUCH, -1, (GetLevelByClass(CLASS_TYPE_SLAYER_OF_DOMIEL, oPC)+4)/4);
|
||||
FeatUsePerDay(oPC, FEAT_SUEL_DISPELLING_STRIKE, -1, (GetLevelByClass(CLASS_TYPE_SUEL_ARCHANAMACH, oPC) + 2) / 4);
|
||||
FeatUsePerDay(oPC, FEAT_PLANT_CONTROL, ABILITY_CHARISMA, 3);
|
||||
FeatUsePerDay(oPC, FEAT_PLANT_DEFIANCE, ABILITY_CHARISMA, 3);
|
||||
FeatDiabolist(oPC);
|
||||
FeatAlaghar(oPC);
|
||||
ShadowShieldUses(oPC);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "prc_feat_const"
|
||||
#include "inc_item_props"
|
||||
#include "prc_inc_spells"
|
||||
|
||||
const string BRUTAL_STRIKE_MODE_VAR = "PRC_BRUTAL_STRIKE_MODE";
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ void CheckForPnPHolyAvenger(object oItem);
|
||||
|
||||
#include "inc_utility"
|
||||
#include "prc_inc_newip"
|
||||
#include "prc_inc_castlvl"
|
||||
#include "inc_newspellbook"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
1993
src/include/prc_inc_json.nss
Normal file
1993
src/include/prc_inc_json.nss
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,26 +16,28 @@ const int MATERIAL_TYPE_UNKNOWN = 0;
|
||||
const int MATERIAL_TYPE_BONE = 1;
|
||||
const int MATERIAL_TYPE_CERAMIC = 2;
|
||||
const int MATERIAL_TYPE_CRYSTAL = 3;
|
||||
const int MATERIAL_TYPE_FABRIC = 4;
|
||||
const int MATERIAL_TYPE_FIBER = 4;
|
||||
const int MATERIAL_TYPE_LEATHER = 5;
|
||||
const int MATERIAL_TYPE_METAL = 6;
|
||||
const int MATERIAL_TYPE_PAPER = 7;
|
||||
const int MATERIAL_TYPE_ROPE = 8;
|
||||
const int MATERIAL_TYPE_STONE = 9;
|
||||
const int MATERIAL_TYPE_WOOD = 10;
|
||||
const int MATERIAL_TYPE_BOTANICAL = 11;
|
||||
|
||||
const string MATERIAL_TYPE_NAME_INVALID = "";
|
||||
const string MATERIAL_TYPE_NAME_UNKNOWN = "Unknown";
|
||||
const string MATERIAL_TYPE_NAME_BONE = "Bone";
|
||||
const string MATERIAL_TYPE_NAME_CERAMIC = "Ceramic";
|
||||
const string MATERIAL_TYPE_NAME_CRYSTAL = "Crystal";
|
||||
const string MATERIAL_TYPE_NAME_FABRIC = "Fabric";
|
||||
const string MATERIAL_TYPE_NAME_FIBER = "Fiber";
|
||||
const string MATERIAL_TYPE_NAME_LEATHER = "Leather";
|
||||
const string MATERIAL_TYPE_NAME_METAL = "Metal";
|
||||
const string MATERIAL_TYPE_NAME_PAPER = "Paper";
|
||||
const string MATERIAL_TYPE_NAME_ROPE = "Rope";
|
||||
const string MATERIAL_TYPE_NAME_STONE = "Stone";
|
||||
const string MATERIAL_TYPE_NAME_WOOD = "Wood";
|
||||
const string MATERIAL_TYPE_NAME_BOTANICAL = "Bontanical";
|
||||
|
||||
//:: Material Itemproperty Constants
|
||||
//::////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -163,7 +165,8 @@ const int IP_MATERIAL_OBSIDIAN = 140;
|
||||
const int IP_MATERIAL_BAMBOO = 141;
|
||||
const int IP_MATERIAL_POTTERY = 142;
|
||||
const int IP_MATERIAL_GLASSTEEL = 143;
|
||||
const int IP_NUM_MATERIALS = 143;
|
||||
const int IP_MATERIAL_HERB = 144;
|
||||
const int IP_NUM_MATERIALS = 144;
|
||||
|
||||
const string IP_MATERIAL_NAME_INVALID = "";
|
||||
const string IP_MATERIAL_NAME_UNKNOWN = "Unknown";
|
||||
@@ -288,6 +291,7 @@ const string IP_MATERIAL_NAME_OBSIDIAN = "Obsidian";
|
||||
const string IP_MATERIAL_NAME_BAMBOO = "Bamboo";
|
||||
const string IP_MATERIAL_NAME_POTTERY = "Pottery";
|
||||
const string IP_MATERIAL_NAME_GLASSTEEL = "Glassteel";
|
||||
const string IP_MATERIAL_NAME_HERB = "Herbs";
|
||||
|
||||
//::///////////////////////////////////////////////////////////////
|
||||
// GetMaterialName( int iMaterialType, int bLowerCase = FALSE)
|
||||
@@ -426,8 +430,9 @@ string GetMaterialName( int iMaterialType, int bLowerCase = FALSE)
|
||||
case IP_MATERIAL_ROPE_GIANT_HAIR: sName = IP_MATERIAL_NAME_ROPE_GIANT_HAIR; break;
|
||||
case IP_MATERIAL_OBSIDIAN: sName = IP_MATERIAL_NAME_OBSIDIAN; break;
|
||||
case IP_MATERIAL_BAMBOO: sName = IP_MATERIAL_NAME_BAMBOO; break;
|
||||
case IP_MATERIAL_POTTERY: sName = IP_MATERIAL_NAME_POTTERY; break;
|
||||
case IP_MATERIAL_GLASSTEEL: sName = IP_MATERIAL_NAME_GLASSTEEL; break;
|
||||
case IP_MATERIAL_POTTERY: sName = IP_MATERIAL_NAME_POTTERY; break;
|
||||
case IP_MATERIAL_GLASSTEEL: sName = IP_MATERIAL_NAME_GLASSTEEL; break;
|
||||
case IP_MATERIAL_HERB: sName = IP_MATERIAL_NAME_HERB; break;
|
||||
|
||||
default: return "";
|
||||
}
|
||||
@@ -573,6 +578,7 @@ int GetIPMaterial( string sMaterialName)
|
||||
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_BAMBOO)) return IP_MATERIAL_BAMBOO;
|
||||
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_POTTERY)) return IP_MATERIAL_POTTERY;
|
||||
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_GLASSTEEL)) return IP_MATERIAL_GLASSTEEL;
|
||||
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_HERB)) return IP_MATERIAL_HERB;
|
||||
|
||||
return IP_MATERIAL_INVALID;
|
||||
}
|
||||
@@ -806,6 +812,9 @@ int GetMaterialType(int nMaterial)
|
||||
|| nMaterial == IP_MATERIAL_DRAKE_IVORY )
|
||||
return MATERIAL_TYPE_BONE;
|
||||
|
||||
else if ( nMaterial == IP_MATERIAL_HERB )
|
||||
return MATERIAL_TYPE_BOTANICAL;
|
||||
|
||||
else if ( nMaterial == IP_MATERIAL_ELUKIAN_CLAY
|
||||
|| nMaterial == IP_MATERIAL_POTTERY )
|
||||
return MATERIAL_TYPE_CERAMIC;
|
||||
@@ -814,7 +823,7 @@ int GetMaterialType(int nMaterial)
|
||||
|| nMaterial == IP_MATERIAL_COTTON
|
||||
|| nMaterial == IP_MATERIAL_SILK
|
||||
|| nMaterial == IP_MATERIAL_WOOL )
|
||||
return MATERIAL_TYPE_FABRIC;
|
||||
return MATERIAL_TYPE_FIBER;
|
||||
|
||||
else if ( nMaterial == IP_MATERIAL_GEM
|
||||
|| nMaterial == IP_MATERIAL_GEM_ALEXANDRITE
|
||||
|
||||
@@ -1,9 +1,68 @@
|
||||
//:: prc_inc_nat_hb
|
||||
//::
|
||||
//:: void main(){}
|
||||
|
||||
|
||||
void DoNaturalWeaponHB(object oPC = OBJECT_SELF);
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "prc_inc_template"
|
||||
|
||||
object GetProperTarget(object oPC, object oTarget)
|
||||
/**
|
||||
* Finds a valid enemy target in melee range when the original target is invalid.
|
||||
* Now includes input validation, LOS checks, configurable radius, and target priority.
|
||||
*
|
||||
* @param oPC The creature seeking a new target
|
||||
* @param oTarget The original (invalid) target
|
||||
* @param fRadius Search radius in meters (optional, defaults to melee range)
|
||||
* @return A valid enemy target or OBJECT_INVALID if none found
|
||||
*/
|
||||
object GetProperTarget(object oPC, object oTarget, float fRadius = MELEE_RANGE_METERS)
|
||||
{
|
||||
// Input validation
|
||||
if(!GetIsObjectValid(oPC))
|
||||
{
|
||||
DoDebug("GetProperTarget(): Invalid oPC parameter");
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// Use target list system for better target selection
|
||||
PurgeTargetList(oPC);
|
||||
|
||||
location lPC = GetLocation(oPC);
|
||||
object oTest = MyFirstObjectInShape(SHAPE_SPHERE, fRadius, lPC, TRUE, OBJECT_TYPE_CREATURE);
|
||||
|
||||
while(GetIsObjectValid(oTest))
|
||||
{
|
||||
// Basic validation checks
|
||||
if(oTest != oPC && // Not self
|
||||
GetIsEnemy(oPC, oTest) && // Is enemy
|
||||
GetIsInMeleeRange(oPC, oTest) && // In melee range
|
||||
!GetIsDead(oTest) && // Is alive
|
||||
LineOfSightObject(oPC, oTest)) // Has line of sight
|
||||
{
|
||||
// Add to target list with priority based on distance (nearest first)
|
||||
AddToTargetList(oTest, oPC, INSERTION_BIAS_DISTANCE, FALSE);
|
||||
}
|
||||
|
||||
oTest = MyNextObjectInShape(SHAPE_SPHERE, fRadius, lPC, TRUE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
|
||||
// Get the highest priority target (nearest enemy)
|
||||
object oBestTarget = GetTargetListHead(oPC);
|
||||
PurgeTargetList(oPC);
|
||||
|
||||
if(GetIsObjectValid(oBestTarget))
|
||||
{
|
||||
DoDebug("GetProperTarget(): Selected target " + GetName(oBestTarget) +
|
||||
" for " + GetName(oPC));
|
||||
return oBestTarget;
|
||||
}
|
||||
|
||||
// No valid target found
|
||||
DoDebug("GetProperTarget(): No valid target found for " + GetName(oPC));
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
/* object GetProperTarget(object oPC, object oTarget)
|
||||
{
|
||||
location lTarget = GetLocation(oPC);
|
||||
// Use the function to get the closest creature as a target
|
||||
@@ -21,7 +80,7 @@ object GetProperTarget(object oPC, object oTarget)
|
||||
}
|
||||
|
||||
return oTarget;
|
||||
}
|
||||
} */
|
||||
|
||||
void DoNaturalAttack(object oWeapon)
|
||||
{
|
||||
@@ -289,59 +348,72 @@ void DoOverflowOnhandAttack(int nAttackMod)
|
||||
);
|
||||
}
|
||||
|
||||
void DoNaturalWeaponHB(object oPC = OBJECT_SELF)
|
||||
/* void DoNaturalWeaponHB(object oPC = OBJECT_SELF)
|
||||
{
|
||||
//not in combat, abort
|
||||
if(!GetIsInCombat(oPC))
|
||||
return;
|
||||
|
||||
// if(DEBUG) DoDebug("entered DoNaturalWeaponHB");
|
||||
if(DEBUG) DoDebug("prc_inc_nat_hb: entered DoNaturalWeaponHB");
|
||||
|
||||
float fDelay = 0.1 + IntToFloat(Random(10))/100.0;
|
||||
|
||||
//no natural weapons, abort
|
||||
//in a different form, abort for now fix it later
|
||||
if(array_exists(oPC, ARRAY_NAT_SEC_WEAP_RESREF)
|
||||
&& !GetIsPolyMorphedOrShifted(oPC))
|
||||
if(array_exists(oPC, ARRAY_NAT_SEC_WEAP_RESREF)
|
||||
&& !GetIsPolyMorphedOrShifted(oPC))
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: creature has natural secondary weapons");
|
||||
UpdateSecondaryWeaponSizes(oPC);
|
||||
int i;
|
||||
while(i < array_get_size(oPC, ARRAY_NAT_SEC_WEAP_RESREF))
|
||||
{
|
||||
// DoDebug("DoNaturalWeaponHB: creature has natural secondary weapons");
|
||||
UpdateSecondaryWeaponSizes(oPC);
|
||||
int i;
|
||||
while(i < array_get_size(oPC, ARRAY_NAT_SEC_WEAP_RESREF))
|
||||
string sResRef = array_get_string(oPC, ARRAY_NAT_SEC_WEAP_RESREF, i);
|
||||
if(sResRef != "")
|
||||
{
|
||||
//get the resref to use
|
||||
string sResRef = array_get_string(oPC, ARRAY_NAT_SEC_WEAP_RESREF, i);
|
||||
//if null, move to next
|
||||
if(sResRef != "")
|
||||
// Get stored weapon object, or create if doesn't exist
|
||||
object oWeapon = GetLocalObject(oPC, "NAT_SEC_WEAP_" + sResRef);
|
||||
|
||||
if(!GetIsObjectValid(oWeapon))
|
||||
{
|
||||
//get the created item
|
||||
object oWeapon = GetObjectByTag(sResRef);
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: creating and storing creature weapon " + sResRef);
|
||||
oWeapon = CreateItemOnObject(sResRef, oPC);
|
||||
|
||||
if(!GetIsObjectValid(oWeapon))
|
||||
{
|
||||
object oLimbo = GetObjectByTag("HEARTOFCHAOS");
|
||||
location lLimbo = GetLocation(oLimbo);
|
||||
if(!GetIsObjectValid(oLimbo))
|
||||
lLimbo = GetStartingLocation();
|
||||
oWeapon = CreateObject(OBJECT_TYPE_ITEM, sResRef, lLimbo);
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: ERROR - CreateItemOnObject FAILED for " + sResRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: SUCCESS - weapon created, tag=" + GetTag(oWeapon) + ", name=" + GetName(oWeapon));
|
||||
SetIdentified(oWeapon, TRUE);
|
||||
SetLocalObject(oPC, "NAT_SEC_WEAP_" + sResRef, oWeapon);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: using stored creature weapon object");
|
||||
}
|
||||
|
||||
// DoDebug(COLOR_WHITE + "DoNaturalWeaponHB: scheduling a secondary natural attack with "+GetName(oWeapon)+" at delay "+FloatToString(fDelay));
|
||||
//do the attack within a delay
|
||||
/*
|
||||
// motu99: commented this out; AssignCommand ist not needed, because OBJECT_SELF is oPC - using AssignCommand will only degrade performance
|
||||
AssignCommand(oPC, DelayCommand(fDelay, DoNaturalAttack(oWeapon)));
|
||||
*/
|
||||
|
||||
// Double-check validity before scheduling
|
||||
if(GetIsObjectValid(oWeapon))
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: scheduling a secondary natural attack with "+GetName(oWeapon)+" at delay "+FloatToString(fDelay));
|
||||
DelayCommand(fDelay, DoNaturalAttack(oWeapon));
|
||||
|
||||
//calculate the delay to use next time
|
||||
fDelay += 2.05;
|
||||
if(fDelay > 6.0)
|
||||
fDelay -= 6.0;
|
||||
fDelay -= 6.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: ERROR - weapon object is INVALID, cannot schedule attack");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int iMod = 5; // motu99: added check for monk weapon
|
||||
if(GetHasMonkWeaponEquipped(oPC)) iMod = 3;
|
||||
@@ -357,10 +429,10 @@ void DoNaturalWeaponHB(object oPC = OBJECT_SELF)
|
||||
for(i = 0; i < nOverflowAttackCount; i++)
|
||||
{
|
||||
// DoDebug(COLOR_WHITE + "DoNaturalWeaponHB(): scheduling a scripted overflow attack with attack mod "+IntToString(nAttackPenalty)+" at delay "+FloatToString(fDelay));
|
||||
/*
|
||||
|
||||
// motu99: see comment above why this is commented out
|
||||
AssignCommand(oPC, DelayCommand(fDelay, DoOverflowOnhandAttack(nAttackPenalty)));
|
||||
*/
|
||||
//AssignCommand(oPC, DelayCommand(fDelay, DoOverflowOnhandAttack(nAttackPenalty)));
|
||||
|
||||
DelayCommand(fDelay, DoOverflowOnhandAttack(nAttackPenalty));
|
||||
|
||||
//calculate the delay to use
|
||||
@@ -399,6 +471,128 @@ void DoNaturalWeaponHB(object oPC = OBJECT_SELF)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void DoNaturalWeaponHB(object oPC = OBJECT_SELF)
|
||||
{
|
||||
//not in combat, abort
|
||||
if(!GetIsInCombat(oPC))
|
||||
return;
|
||||
|
||||
if(DEBUG) DoDebug("prc_inc_nat_hb: entered DoNaturalWeaponHB");
|
||||
|
||||
float fDelay = 0.1 + IntToFloat(Random(10))/100.0;
|
||||
|
||||
//no natural weapons, abort
|
||||
//in a different form, abort for now fix it later
|
||||
if(array_exists(oPC, ARRAY_NAT_SEC_WEAP_RESREF)
|
||||
&& !GetIsPolyMorphedOrShifted(oPC))
|
||||
{
|
||||
DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: creature has natural secondary weapons");
|
||||
UpdateSecondaryWeaponSizes(oPC);
|
||||
int i;
|
||||
while(i < array_get_size(oPC, ARRAY_NAT_SEC_WEAP_RESREF))
|
||||
{
|
||||
//get the resref to use
|
||||
string sResRef = array_get_string(oPC, ARRAY_NAT_SEC_WEAP_RESREF, i);
|
||||
//if null, move to next
|
||||
if(sResRef != "")
|
||||
{
|
||||
//get the created item
|
||||
object oWeapon = GetObjectByTag(sResRef);
|
||||
if(!GetIsObjectValid(oWeapon))
|
||||
{
|
||||
object oLimbo = GetObjectByTag("HEARTOFCHAOS");
|
||||
location lLimbo = GetLocation(oLimbo);
|
||||
if(!GetIsObjectValid(oLimbo))
|
||||
lLimbo = GetStartingLocation();
|
||||
oWeapon = CreateObject(OBJECT_TYPE_ITEM, sResRef, lLimbo);
|
||||
DoDebug(PRC_TEXT_WHITE + "prc_inc_nat_hb >> DoNaturalWeaponHB: creature weapon object found!!!");
|
||||
}
|
||||
|
||||
// Check for enhancements after creating the weapon object
|
||||
int nEnhance = GetLocalInt(oPC, "PRC_NAT_WEAPON_ENHANCE");
|
||||
if(nEnhance > 0)
|
||||
{
|
||||
|
||||
DoDebug(PRC_TEXT_WHITE + "prc_inc_nat_hb >> DoNaturalWeaponHB: Applying enhancement.");
|
||||
float fDuration = GetLocalFloat(oPC, "PRC_NAT_WEAPON_ENH_DUR");
|
||||
IPSafeAddItemProperty(oWeapon, ItemPropertyEnhancementBonus(nEnhance), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
|
||||
}
|
||||
|
||||
if(DEBUG) DoDebug("prc_inc_nat_hb >> DoNaturalWeaponHB: scheduling a secondary natural attack with "+GetName(oWeapon)+" at delay "+FloatToString(fDelay));
|
||||
//do the attack within a delay
|
||||
// motu99: commented this out; AssignCommand ist not needed, because OBJECT_SELF is oPC - using AssignCommand will only degrade performance
|
||||
//AssignCommand(oPC, DelayCommand(fDelay, DoNaturalAttack(oWeapon)));
|
||||
|
||||
DelayCommand(fDelay, DoNaturalAttack(oWeapon));
|
||||
|
||||
//calculate the delay to use next time
|
||||
fDelay += 2.05;
|
||||
if(fDelay > 6.0)
|
||||
fDelay -= 6.0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int iMod = 5; // motu99: added check for monk weapon
|
||||
if(GetHasMonkWeaponEquipped(oPC)) iMod = 3;
|
||||
|
||||
// check for overflow (main hand) attacks
|
||||
int nOverflowAttackCount = GetLocalInt(oPC, "OverflowBaseAttackCount");
|
||||
if(nOverflowAttackCount)
|
||||
{
|
||||
int i;
|
||||
// the first overflow attack would be the seventh main hand attack, at an AB of -30
|
||||
int nAttackPenalty = -6 * iMod; // -30 for normal bab, -18 for monks
|
||||
// DoDebug("DoNaturalWeaponHB(): number of scripted overflow attacks: "+IntToString(nOverflowAttackCount));
|
||||
for(i = 0; i < nOverflowAttackCount; i++)
|
||||
{
|
||||
// DoDebug(COLOR_WHITE + "DoNaturalWeaponHB(): scheduling a scripted overflow attack with attack mod "+IntToString(nAttackPenalty)+" at delay "+FloatToString(fDelay));
|
||||
|
||||
// motu99: see comment above why this is commented out
|
||||
// AssignCommand(oPC, DelayCommand(fDelay, DoOverflowOnhandAttack(nAttackPenalty)));
|
||||
|
||||
DelayCommand(fDelay, DoOverflowOnhandAttack(nAttackPenalty));
|
||||
|
||||
//calculate the delay to use
|
||||
fDelay += 2.05;
|
||||
if(fDelay > 6.0)
|
||||
fDelay -= 6.0;
|
||||
//calculate new attack penalty
|
||||
nAttackPenalty -= iMod; // motu99: usually -5, for monks -3 (unarmed or kama)
|
||||
}
|
||||
}
|
||||
|
||||
// motu99: this is only here for debugging in order to test PerformAttackRound()
|
||||
// must be deleted after debugging!!!
|
||||
//if (GetPRCSwitch(PRC_PNP_TRUESEEING)) DelayCommand(0.01, DoOffhandAttackRound());
|
||||
|
||||
|
||||
// check for overflow offhand attacks
|
||||
int nOffhandAttackCount = GetLocalInt(oPC, "OffhandOverflowAttackCount");
|
||||
// if (DEBUG) DoDebug("DoNaturalWeaponHB: number of scripted offhand attacks = "+IntToString(nOffhandAttackCount));
|
||||
if(nOffhandAttackCount)
|
||||
{
|
||||
int i;
|
||||
int nAttackPenalty = -2 * iMod; // offhand attacks always come at -5 per additional attack (but for monks we assume -3)
|
||||
for(i = 0; i < nOffhandAttackCount; i++)
|
||||
{
|
||||
// DoDebug(COLOR_WHITE + "DoNaturalWeaponHB(): scheduling a scripted offhand attack with attack mod "+IntToString(nAttackPenalty)+" at delay "+FloatToString(fDelay));
|
||||
|
||||
DelayCommand(fDelay, DoOffhandAttack(nAttackPenalty));
|
||||
|
||||
//calculate the delay to use
|
||||
fDelay += 2.05;
|
||||
if(fDelay > 6.0)
|
||||
fDelay -= 6.0;
|
||||
//calculate new attack penalty
|
||||
nAttackPenalty -= iMod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* motu99's test functions. Not actually used by PRC scripts
|
||||
|
||||
@@ -277,6 +277,32 @@ void ClearNaturalWeapons(object oPC)
|
||||
array_delete(oPC, ARRAY_NAT_PRI_WEAP_ATTACKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a natural primary weapon to a creature (PC/NPC).
|
||||
*
|
||||
* This function manages a creature's natural primary weapons by storing their
|
||||
* resource references and attack counts in persistent arrays. If the weapon
|
||||
* being added is the first natural weapon, it may automatically become the
|
||||
* creature's active primary natural weapon, unless the creature is a Monk or
|
||||
* Brawler. Optionally, the weapon can be forced to become the active primary
|
||||
* weapon regardless of class.
|
||||
*
|
||||
* @param oPC The creature object to which the natural weapon will be added.
|
||||
* @param sResRef The resource reference string of the natural weapon.
|
||||
* @param nCount (Optional) The number of attacks this natural weapon provides.
|
||||
* Default is 1.
|
||||
* @param nForceUse (Optional) If TRUE, forces this weapon to become the active
|
||||
* primary natural weapon regardless of the creature's class.
|
||||
* Default is FALSE.
|
||||
*
|
||||
* @details
|
||||
* - Creates persistent arrays for weapon references and attack counts if they
|
||||
* do not already exist.
|
||||
* - Checks if the weapon is already present to avoid duplicates.
|
||||
* - Adds the weapon and attack count to the arrays.
|
||||
* - Sets the primary natural weapon index to this weapon if it is the first
|
||||
* natural weapon added, unless the creature is a Monk or Brawler.
|
||||
*/
|
||||
void AddNaturalPrimaryWeapon(object oPC, string sResRef, int nCount = 1, int nForceUse = FALSE)
|
||||
{
|
||||
int nFirstNaturalWeapon = FALSE;
|
||||
|
||||
@@ -572,7 +572,10 @@ int GetMaxEssentiaCapacity(object oMeldshaper, int nClass, int nMeld)
|
||||
{
|
||||
int nMax = 1; // Always can invest one
|
||||
int nHD = GetHitDice(oMeldshaper);
|
||||
if (nHD >= 31) nMax = 5;
|
||||
if (nHD >= 61) nMax = 8;
|
||||
else if (nHD >= 51) nMax = 7;
|
||||
else if (nHD >= 41) nMax = 6;
|
||||
else if (nHD >= 31) nMax = 5;
|
||||
else if (nHD >= 18) nMax = 4;
|
||||
else if (nHD >= 12) nMax = 3;
|
||||
else if (nHD >= 6) nMax = 2;
|
||||
|
||||
@@ -808,7 +808,24 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI
|
||||
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is armor; attacker = "+GetName(oAttacker)+", defender = "+GetName(oDefender));
|
||||
}
|
||||
// is the spell type item a weapon?
|
||||
else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType)))
|
||||
int nWT = StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType));
|
||||
if (nWT > 0)
|
||||
{
|
||||
if (oSpellTarget == OBJECT_INVALID)
|
||||
oSpellTarget = PRCGetSpellTargetObject(oSpellOrigin);
|
||||
|
||||
oAttacker = oSpellOrigin;
|
||||
oDefender = oSpellTarget;
|
||||
|
||||
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is weapon [WT="+IntToString(nWT)+"]; attacker="+GetName(oAttacker)+", defender="+GetName(oDefender));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType)))
|
||||
{
|
||||
// determine the target, if not already given
|
||||
if (oSpellTarget == OBJECT_INVALID)
|
||||
@@ -823,7 +840,7 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI
|
||||
{
|
||||
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE");
|
||||
return FALSE;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
// the spell origin must possess the item that cast the spell (at least for the aurora engine, in prc_inc_combat that may differ)
|
||||
|
||||
@@ -1370,7 +1370,9 @@ void _prc_inc_shifting_ShiftIntoTemplateAux(object oShifter, int nShifterType, o
|
||||
if(GetIsObjectValid(oShifterCWpR)) MyDestroyObject(oShifterCWpR);
|
||||
if(GetIsObjectValid(oShifterCWpL)) MyDestroyObject(oShifterCWpL);
|
||||
if(GetIsObjectValid(oShifterCWpB)) MyDestroyObject(oShifterCWpB);
|
||||
oShifterCWpR = oShifterCWpL = oShifterCWpR = OBJECT_INVALID;
|
||||
oShifterCWpR = OBJECT_INVALID;
|
||||
oShifterCWpL = OBJECT_INVALID;
|
||||
oShifterCWpB = OBJECT_INVALID;
|
||||
|
||||
// Copy the template's weapons and assign equipping
|
||||
|
||||
|
||||
154
src/include/prc_inc_size.nss
Normal file
154
src/include/prc_inc_size.nss
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "prc_inc_util"
|
||||
#include "prc_inc_spells"
|
||||
#include "prc_inc_function"
|
||||
|
||||
// Wrapper function for delayed visual transform with generation tracking
|
||||
void DelayedSetVisualTransform(int nExpectedGeneration, object oTarget, int nTransform, float fValue)
|
||||
{
|
||||
// Read current generation at execution time, not when scheduled
|
||||
if (nExpectedGeneration != GetLocalInt(oTarget, "PRC_SIZE_GENERATION"))
|
||||
{
|
||||
// Generation has changed, don't apply the transform
|
||||
return;
|
||||
}
|
||||
SetObjectVisualTransform(oTarget, nTransform, fValue);
|
||||
}
|
||||
|
||||
// Main wrapper function that handles generation tracking
|
||||
void DelaySetVisualTransform(float fDelay, object oTarget, string sGenerationName, int nTransform, float fValue)
|
||||
{
|
||||
int nExpectedGeneration = GetLocalInt(oTarget, sGenerationName);
|
||||
DelayCommand(fDelay, DelayedSetVisualTransform(nExpectedGeneration, oTarget, nTransform, fValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a size change effect that can enlarge or reduce a creature
|
||||
*
|
||||
* @param oTarget Object to affect
|
||||
* @param nObjectType Object type filter (OBJECT_TYPE_CREATURE, etc.)
|
||||
* @param bEnlarge TRUE to enlarge, FALSE to reduce
|
||||
* @param nChanges Number of size categories to change (0 = reset to original)
|
||||
* @return The size change effect
|
||||
*/
|
||||
|
||||
effect EffectSizeChange(object oTarget, int nObjectType, int bEnlarge, int nChanges)
|
||||
{
|
||||
effect eBlank;
|
||||
|
||||
// Increment generation for any size change
|
||||
int nGeneration = PRC_NextGeneration(GetLocalInt(oTarget, "PRC_SIZE_GENERATION"));
|
||||
SetLocalInt(oTarget, "PRC_SIZE_GENERATION", nGeneration);
|
||||
|
||||
// Store original size if not already stored - READ ACTUAL CURRENT SCALE
|
||||
if(GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE") == 0.0f)
|
||||
{
|
||||
float fCurrentScale = GetObjectVisualTransform(oTarget, OBJECT_VISUAL_TRANSFORM_SCALE);
|
||||
SetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE", fCurrentScale);
|
||||
}
|
||||
|
||||
// Reset to original size
|
||||
if(nChanges == 0)
|
||||
{
|
||||
float fOriginalSize = GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE");
|
||||
DelaySetVisualTransform(0.0f, oTarget, "PRC_SIZE_GENERATION", OBJECT_VISUAL_TRANSFORM_SCALE, fOriginalSize);
|
||||
// DON'T delete PRC_ORIGINAL_SIZE here - keep it for future casts
|
||||
return eBlank;
|
||||
}
|
||||
|
||||
// Get the original scale
|
||||
float fOriginalScale = GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE");
|
||||
|
||||
// Calculate scale factor relative to original size
|
||||
float fScale = fOriginalScale;
|
||||
if(bEnlarge)
|
||||
fScale = fOriginalScale * pow(1.5f, IntToFloat(nChanges));
|
||||
else
|
||||
fScale = fOriginalScale * pow(0.5f, IntToFloat(nChanges));
|
||||
|
||||
// Create the effect link with sanctuary VFX
|
||||
effect eReturn = EffectLinkEffects(EffectVisualEffect(VFX_DUR_SANCTUARY),
|
||||
EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
|
||||
|
||||
if(bEnlarge)
|
||||
{
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAttackDecrease(nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityDecrease(ABILITY_DEXTERITY, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityIncrease(ABILITY_STRENGTH, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectACDecrease(nChanges));
|
||||
eReturn = TagEffect(eReturn, "PRC_SIZE_INCREASE");
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAttackIncrease(nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityIncrease(ABILITY_DEXTERITY, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityDecrease(ABILITY_STRENGTH, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectACIncrease(nChanges));
|
||||
eReturn = TagEffect(eReturn, "PRC_SIZE_DECREASE");
|
||||
}
|
||||
|
||||
// Apply visual transform using wrapper
|
||||
DelaySetVisualTransform(0.0f, oTarget, "PRC_SIZE_GENERATION", OBJECT_VISUAL_TRANSFORM_SCALE, fScale);
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* effect EffectSizeChange(object oTarget, int nObjectType, int bEnlarge, int nChanges)
|
||||
{
|
||||
effect eBlank;
|
||||
|
||||
// Increment generation for any size change
|
||||
int nGeneration = PRC_NextGeneration(GetLocalInt(oTarget, "PRC_SIZE_GENERATION"));
|
||||
SetLocalInt(oTarget, "PRC_SIZE_GENERATION", nGeneration);
|
||||
|
||||
// Store original size if not already stored (fixed check)
|
||||
if(GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE") == 0.0f)
|
||||
{
|
||||
SetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE", 1.0f);
|
||||
}
|
||||
|
||||
// Reset to original size
|
||||
if(nChanges == 0)
|
||||
{
|
||||
float fOriginalSize = GetLocalFloat(oTarget, "PRC_ORIGINAL_SIZE");
|
||||
DelaySetVisualTransform(0.0f, oTarget, "PRC_SIZE_GENERATION", OBJECT_VISUAL_TRANSFORM_SCALE, fOriginalSize);
|
||||
DeleteLocalFloat(oTarget, "PRC_ORIGINAL_SIZE");
|
||||
return eBlank;
|
||||
}
|
||||
|
||||
// Calculate scale factor using pow() for multi-step changes
|
||||
float fScale = 1.0f;
|
||||
if(bEnlarge)
|
||||
fScale = pow(1.5f, IntToFloat(nChanges)); // 1.5, 2.25, 3.375...
|
||||
else
|
||||
fScale = pow(0.5f, IntToFloat(nChanges)); // 0.5, 0.25, 0.125...
|
||||
|
||||
// Create the effect link based on enlarge/reduce
|
||||
effect eReturn;
|
||||
if(bEnlarge)
|
||||
{
|
||||
eReturn = EffectLinkEffects(EffectAttackDecrease(nChanges),
|
||||
EffectAbilityDecrease(ABILITY_DEXTERITY, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityIncrease(ABILITY_STRENGTH, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectACDecrease(nChanges));
|
||||
eReturn = TagEffect(eReturn, "PRC_SIZE_INCREASE");
|
||||
}
|
||||
else
|
||||
{
|
||||
eReturn = EffectLinkEffects(EffectAttackIncrease(nChanges),
|
||||
EffectAbilityIncrease(ABILITY_DEXTERITY, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectAbilityDecrease(ABILITY_STRENGTH, 2 * nChanges));
|
||||
eReturn = EffectLinkEffects(eReturn, EffectACIncrease(nChanges));
|
||||
eReturn = TagEffect(eReturn, "PRC_SIZE_DECREASE");
|
||||
}
|
||||
|
||||
// Apply visual transform using wrapper
|
||||
DelaySetVisualTransform(0.0f, oTarget, "PRC_SIZE_GENERATION", OBJECT_VISUAL_TRANSFORM_SCALE, fScale);
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
*/
|
||||
|
||||
//:: void main(){}
|
||||
@@ -115,11 +115,11 @@ int PerformJump(object oPC, location lLoc, int bDoKnockDown = TRUE)
|
||||
iBonus = 4;
|
||||
}
|
||||
}
|
||||
/*if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
|
||||
if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
|
||||
{
|
||||
bIsRunningJump = TRUE;
|
||||
iBonus = 10;
|
||||
} */
|
||||
//iBonus = 10; //:: This is granted in the stance.
|
||||
}
|
||||
// PnP rules are height * 6 for run and height * 2 for jump.
|
||||
// I can't get height so that is assumed to be 6.
|
||||
// Changed maxed jump distance because the NwN distance is rather short
|
||||
@@ -363,8 +363,11 @@ int PRCIsFlying(object oCreature)
|
||||
bFlying = TRUE;
|
||||
}
|
||||
if(!bFlying
|
||||
&& ((nWings > 0 && nWings < 79) || nWings == 90))//CEP and Project Q wing models
|
||||
bFlying = TRUE;
|
||||
&& ((nWings > 0 && nWings < 79)
|
||||
|| (nWings > 1959 && nWings < 1962)
|
||||
|| (nWings > 1962 && nWings < 1966)
|
||||
|| nWings == 90))//CEP and Project Q wing models
|
||||
bFlying = TRUE;
|
||||
|
||||
if (GetHasSpellEffect(MOVE_SH_BALANCE_SKY, oCreature))
|
||||
bFlying = TRUE;
|
||||
@@ -374,6 +377,12 @@ int PRCIsFlying(object oCreature)
|
||||
|
||||
if(GetRacialType(oCreature) == RACIAL_TYPE_GLOURA)
|
||||
bFlying = TRUE;
|
||||
|
||||
if(GetRacialType(oCreature) == RACIAL_TYPE_AVARIEL)
|
||||
bFlying = TRUE;
|
||||
|
||||
if(GetRacialType(oCreature) == RACIAL_TYPE_FEYRI)
|
||||
bFlying = TRUE;
|
||||
|
||||
if(GetRacialType(oCreature) == RACIAL_TYPE_SPIRETOPDRAGON)
|
||||
bFlying = TRUE;
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//:: Calculates total Shield AC bonuses from all sources
|
||||
int GetTotalShieldACBonus(object oCreature);
|
||||
|
||||
//:: Handles psuedo-Foritifcation
|
||||
void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25);
|
||||
|
||||
@@ -376,23 +381,53 @@ const int TYPE_DIVINE = -2;
|
||||
/* Function definitions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Returns TRUE if nSpellID is a subradial spell, FALSE otherwise
|
||||
int GetIsSubradialSpell(int nSpellID)
|
||||
{
|
||||
string sMaster = Get2DACache("spells", "Master", nSpellID);
|
||||
|
||||
// If the Master column is numeric, this spell is a subradial of that master
|
||||
if (sMaster != "" && sMaster != "****")
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Returns the masterspell SpellID for a subradial spell.
|
||||
int GetMasterSpellFromSubradial(int nSpellID)
|
||||
{
|
||||
string sMaster = Get2DAString("spells", "Master", nSpellID);
|
||||
|
||||
if (sMaster != "****")
|
||||
{
|
||||
return StringToInt(sMaster);
|
||||
}
|
||||
|
||||
return -1; // No master
|
||||
}
|
||||
|
||||
|
||||
|
||||
int GetPrCAdjustedClassLevel(int nClass, object oCaster = OBJECT_SELF)
|
||||
{
|
||||
int iTemp;
|
||||
// is it arcane, divine or neither?
|
||||
if(GetIsArcaneClass(nClass, oCaster) && nClass != CLASS_TYPE_SUBLIME_CHORD)
|
||||
{
|
||||
if (GetPrimaryArcaneClass(oCaster) == nClass) // adjust for any PrCs
|
||||
if (GetPrimaryArcaneClass(oCaster) == nClass) // adjust for any PrCs
|
||||
iTemp = GetArcanePRCLevels(oCaster, nClass);
|
||||
}
|
||||
else if(GetIsDivineClass(nClass, oCaster))
|
||||
{
|
||||
if (GetPrimaryDivineClass(oCaster) == nClass) // adjust for any PrCs
|
||||
iTemp = GetDivinePRCLevels(oCaster, nClass);
|
||||
if (GetPrimaryDivineClass(oCaster) == nClass) // adjust for any PrCs
|
||||
iTemp = GetDivinePRCLevels(oCaster, nClass);
|
||||
}
|
||||
else // a non-caster class or a PrC
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
// add the caster class levels
|
||||
return iTemp += GetLevelByClass(nClass, oCaster);
|
||||
@@ -412,7 +447,9 @@ int GetPrCAdjustedCasterLevelByType(int nClassType, object oCaster = OBJECT_SELF
|
||||
{
|
||||
int nClassLvl;
|
||||
int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8;
|
||||
int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl;
|
||||
int nClass1Lvl = 0, nClass2Lvl = 0, nClass3Lvl = 0, nClass4Lvl = 0,
|
||||
nClass5Lvl = 0, nClass6Lvl = 0, nClass7Lvl = 0, nClass8Lvl = 0;
|
||||
|
||||
|
||||
nClass1 = GetClassByPosition(1, oCaster);
|
||||
nClass2 = GetClassByPosition(2, oCaster);
|
||||
@@ -974,11 +1011,16 @@ int PRCMySavingThrow(int nSavingThrow, object oTarget, int nDC, int nSaveType =
|
||||
// Plague Resistant gives a +4 bonus on disease saves
|
||||
if(GetHasFeat(FEAT_PLAGUE_RESISTANT, oTarget))
|
||||
nDC -= 4;
|
||||
// Racial +2 vs disease saves
|
||||
if(GetHasFeat(FEAT_RACE_HARDINESS_VS_DISEASE, oTarget))
|
||||
nDC -= 2;
|
||||
// +4/+2 bonus on saves against disease, done here
|
||||
if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 13)
|
||||
nDC -= 4;
|
||||
else if(GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oTarget) > 3)
|
||||
nDC -= 2;
|
||||
|
||||
|
||||
}
|
||||
else if(nSaveType == SAVING_THROW_TYPE_POISON)
|
||||
{
|
||||
@@ -2223,6 +2265,78 @@ int GetControlledCelestialTotalHD(object oPC = OBJECT_SELF)
|
||||
return nTotalHD;
|
||||
}
|
||||
|
||||
//:: Calculates total Shield AC bonuses from all sources
|
||||
int GetTotalShieldACBonus(object oCreature)
|
||||
{
|
||||
int nShieldBonus = 0;
|
||||
object oItem;
|
||||
|
||||
// Check left hand for shield
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
if (GetIsObjectValid(oItem))
|
||||
{
|
||||
int nBaseItem = GetBaseItemType(oItem);
|
||||
if (nBaseItem == BASE_ITEM_SMALLSHIELD ||
|
||||
nBaseItem == BASE_ITEM_LARGESHIELD ||
|
||||
nBaseItem == BASE_ITEM_TOWERSHIELD)
|
||||
{
|
||||
nShieldBonus += GetItemACValue(oItem);
|
||||
if(DEBUG) DoDebug("prc_inc_spells >> GetTotalShieldACBonus: Found Shield AC, bonus = " + IntToString(nShieldBonus)+".");
|
||||
}
|
||||
}
|
||||
|
||||
// Check creature weapon slots for shield AC bonus
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oCreature);
|
||||
if (GetIsObjectValid(oItem))
|
||||
nShieldBonus += GetItemACValue(oItem);
|
||||
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oCreature);
|
||||
if (GetIsObjectValid(oItem))
|
||||
nShieldBonus += GetItemACValue(oItem);
|
||||
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oCreature);
|
||||
if (GetIsObjectValid(oItem))
|
||||
nShieldBonus += GetItemACValue(oItem);
|
||||
|
||||
// Add shield AC bonuses from magical effects
|
||||
effect eEffect = GetFirstEffect(oCreature);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
int nACType = GetEffectInteger(eEffect, 0);
|
||||
int nACAmount = GetEffectInteger(eEffect, 1);
|
||||
|
||||
if(GetEffectType(eEffect) == EFFECT_TYPE_AC_INCREASE && nACType == AC_SHIELD_ENCHANTMENT_BONUS)
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_inc_spells >> GetTotalShieldACBonus: Found Shield AC effect, bonus = " + IntToString(nACAmount)+".");
|
||||
nShieldBonus += nACAmount;
|
||||
}
|
||||
|
||||
eEffect = GetNextEffect(oCreature);
|
||||
}
|
||||
return nShieldBonus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Add shield AC bonuses from magical effects
|
||||
/* effect eEffect = GetFirstEffect(oCreature);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_AC_INCREASE &&
|
||||
GetEffectInteger(eEffect, 1) == AC_SHIELD_ENCHANTMENT_BONUS)
|
||||
{
|
||||
int nMod = GetEffectInteger(eEffect, 0);
|
||||
int nType = GetEffectInteger(eEffect, 1);
|
||||
nShieldBonus += GetEffectInteger(eEffect, 0);
|
||||
string s = "Found AC effect: bonus = " + IntToString(nMod) + ", type = " + IntToString(nType);
|
||||
SendMessageToPC(GetFirstPC(), s);
|
||||
}
|
||||
eEffect = GetNextEffect(oCreature);
|
||||
}
|
||||
|
||||
return nShieldBonus;
|
||||
}*/
|
||||
//
|
||||
//:: Handles psuedo-Foritifcation
|
||||
void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25)
|
||||
{
|
||||
@@ -2275,7 +2389,7 @@ void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25)
|
||||
IPSafeAddItemProperty(oHide, ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_BACKSTAB));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// wrapper for DecrementRemainingSpellUses, works for newspellbook 'fake' spells too
|
||||
// should also find and decrement metamagics for newspellbooks
|
||||
|
||||
@@ -70,11 +70,13 @@
|
||||
43 PRC_CRAFTING_BASE_ITEMS int 1
|
||||
44 PRC_XP_USE_SIMPLE_LA int 1
|
||||
45 PRC_XP_USE_SIMPLE_RACIAL_HD int 1
|
||||
46 PRC_CREATE_INFUSION_CASTER_LEVEL int 1
|
||||
47 PRC_CREATE_INFUSION_OPTIONAL_HERBS int 0
|
||||
*/
|
||||
|
||||
/* This variable MUST be updated with every new version of the PRC!!! */
|
||||
|
||||
const string PRC_VERSION = "PRC 3.9.0";
|
||||
const string PRC_VERSION = "PRC8 4.76";
|
||||
|
||||
/* This variable MUST be updated every time 'assemble_spellbooks.bat' is run!!! */
|
||||
|
||||
@@ -89,11 +91,11 @@
|
||||
* This allows material components in NWN through the materialcomp.2da
|
||||
* Just put the SpellID and UTC resref in, MINUS the .utc on the end.
|
||||
* This also requires the names of the items, formatted like so ("" included): "Object Name"
|
||||
*
|
||||
*
|
||||
* Set switch to 2 to activate this
|
||||
* Deducts gold instead of requiring material components
|
||||
* Put the gold value in the Cost column
|
||||
|
||||
|
||||
* Set switch to 3 to activate both at the same time
|
||||
* WARNING: This will slow spellcasting down due to 2da reads and inventory loops
|
||||
*/
|
||||
@@ -127,7 +129,7 @@ const string PRC_BIOWARE_NEUTRALIZE_POISON = "PRC_BIOWARE_NEUTRALIZE_P
|
||||
/** Remove the cap PRC added to this spell */
|
||||
const string PRC_BIOWARE_REMOVE_DISEASE = "PRC_BIOWARE_REMOVE_DISEASE";
|
||||
|
||||
/**
|
||||
/**
|
||||
* This replaces the 3.0 Spell Focus bonuses with the 3.5 edition ones
|
||||
*/
|
||||
const string PRC_35_SPELL_FOCUS = "PRC_35_SPELL_FOCUS";
|
||||
@@ -261,8 +263,8 @@ const string PRC_165_DEATH_IMMUNITY = "PRC_165_DEATH_IMMUNITY";
|
||||
|
||||
/*
|
||||
* PRC_ACTIVATE_MAX_SPELL_DC_CAP: activate a max cap on DC casted by creature/player
|
||||
* PRC_SET_MAX_SPELL_DC_CAP: the max value ex: 99
|
||||
*
|
||||
* PRC_SET_MAX_SPELL_DC_CAP: the max value ex: 99
|
||||
*
|
||||
*/
|
||||
const string PRC_ACTIVATE_MAX_SPELL_DC_CAP = "PRC_ACTIVATE_MAX_SPELL_DC_CAP";
|
||||
const string PRC_SET_MAX_SPELL_DC_CAP = "PRC_SET_MAX_SPELL_DC_CAP";
|
||||
@@ -289,8 +291,8 @@ const string PRC_DC_BASE_OVERRIDE = "PRC_DC_BASE_OVERRIDE";
|
||||
const string PRC_DC_ADJUSTMENT = "PRC_DC_ADJUSTMENT";
|
||||
|
||||
/*
|
||||
* By default when calculating caster level for characters with PrCs, the highest class rule will
|
||||
* be used (ie. Bard 2/Wizard 4/Elemental Savant 6 - Wizard is the highest arcane class so levels
|
||||
* By default when calculating caster level for characters with PrCs, the highest class rule will
|
||||
* be used (ie. Bard 2/Wizard 4/Elemental Savant 6 - Wizard is the highest arcane class so levels
|
||||
* form PrC will be added to that class, and the caster level will be 2 for Bard and 10 for Wizard).
|
||||
* When this is set, the first class rule will be used (with the same character caster level would
|
||||
* be 8 for Bard and 4 for Wizard).
|
||||
@@ -570,12 +572,12 @@ const string PRC_SOUL_EATER_MAX_SLAVES = "PRC_SOUL_EATER_MAX_SLAVES";
|
||||
* For the Psionic Slayer prestige class, this switch limits the Favored Enemy selection
|
||||
* to the Aberration racial type.
|
||||
*
|
||||
* This switch is provided to allow builders to more closely represent the Pen and Paper
|
||||
* This switch is provided to allow builders to more closely represent the Pen and Paper
|
||||
* Illithid Slayer class, instead of the broader Open Game License "Slayer" class.
|
||||
*
|
||||
* Type: Int
|
||||
* Type: Int
|
||||
* Values: 0 [Default] (Favored Enemy racial type is not limited)
|
||||
* 1 (Favored Enemy race is limited to Aberration only)
|
||||
* 1 (Favored Enemy race is limited to Aberration only)
|
||||
*/
|
||||
const string PRC_PSIONIC_SLAYER_FAV_ENEMY_ABERRATION_ONLY = "PRC_PSIONIC_SLAYER_FAV_ENEMY_ABERRATION_ONLY";
|
||||
|
||||
@@ -583,20 +585,20 @@ const string PRC_PSIONIC_SLAYER_FAV_ENEMY_ABERRATION_ONLY = "PRC_PSIONIC_S
|
||||
* For the Psionic Slayer prestige class, this switch requires a character to make a "kill"
|
||||
* of a specific type of creature before the class becomes available.
|
||||
*
|
||||
* Use of this switch requires that the module builder add a "Psionic Slayer Kill Token"
|
||||
* (included in the PRC Items) to the designated creature.
|
||||
* Use of this switch requires that the module builder add a "Psionic Slayer Kill Token"
|
||||
* (included in the PRC Items) to the designated creature.
|
||||
*
|
||||
* Alternately, a script or item can be made that will run the script "prc_psysly_killt"
|
||||
* Alternately, a script or item can be made that will run the script "prc_psysly_killt"
|
||||
* on the PC. This script will set the flag that allows the target PC to take the Psionic Slayer Class.
|
||||
* Example code:
|
||||
* ExecuteScript("prc_psysly_killt", oPC); // Where oPC is an player charcter object
|
||||
* Example code:
|
||||
* ExecuteScript("prc_psysly_killt", oPC); // Where oPC is an player charcter object
|
||||
*
|
||||
* This switch is provided to allow builders to more closely represent the Pen and Paper
|
||||
* This switch is provided to allow builders to more closely represent the Pen and Paper
|
||||
* Illithid Slayer class, instead of the broader Open Game License "Slayer" class.
|
||||
*
|
||||
* Type: Int
|
||||
* Type: Int
|
||||
* Values: 0 [Default] (Kill Token / Script NOT required for taking the Psionic Slayer Class)
|
||||
* 1 (Kill Token / Script REQUIRED before the Psionic Slayer Class is available to take)
|
||||
* 1 (Kill Token / Script REQUIRED before the Psionic Slayer Class is available to take)
|
||||
*/
|
||||
const string PRC_PSIONIC_SLAYER_REQUIRE_KILL_TOKEN = "PRC_PSIONIC_SLAYER_REQUIRE_KILL_TOKEN";
|
||||
|
||||
@@ -605,19 +607,19 @@ const string PRC_PSIONIC_SLAYER_REQUIRE_KILL_TOKEN = "PRC_PSIONIC_SLAYER_R
|
||||
* By default the Werewolf class uses the Bioware Polymorph effect to perfrom its
|
||||
* Hybrid Form Shapchange.
|
||||
*
|
||||
* This switch allows the Werewolf class to be toggled to use the PRC Shifter
|
||||
* Shapchange code instead.
|
||||
* This switch allows the Werewolf class to be toggled to use the PRC Shifter
|
||||
* Shapchange code instead.
|
||||
*
|
||||
* Type: Int
|
||||
* Type: Int
|
||||
* Values: 0 [Default] (Werewolf Hybrid Shapchange uses Bioware Polymorph)
|
||||
* 1 (Werewolf Hybrid Shapchange uses PRC Shifter shape change code)
|
||||
* 1 (Werewolf Hybrid Shapchange uses PRC Shifter shape change code)
|
||||
*/
|
||||
const string PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPCHANGE = "PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPCHANGE";
|
||||
const string PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPECHANGE = "PRC_WEREWOLF_HYBRID_USE_SHIFTER_SHAPECHANGE";
|
||||
|
||||
/**
|
||||
* Sets the max bonus for the PnP Shifter shifting systems
|
||||
*
|
||||
* Type: Int
|
||||
* Type: Int
|
||||
* Values: any greater than 0
|
||||
*/
|
||||
const string PRC_PNP_SHIFTER_BONUS = "PRC_PNP_SHIFTER_BONUS";
|
||||
@@ -781,7 +783,7 @@ const string PRC_STAFF_CASTER_LEVEL = "PRC_STAFF_CASTER_LEVEL";
|
||||
/**
|
||||
* [DEFUNCT]
|
||||
* A wand must be equipped before it can cast a spell
|
||||
*
|
||||
*
|
||||
* Any value above 0 turns off the requirement to have a wand equipped to use it
|
||||
*
|
||||
* This switch is defunct, wands must *always* be equipped to use them.
|
||||
@@ -929,7 +931,7 @@ const string PRC_PNP_FAMILIAR_FEEDING = "PRC_PNP_FAMILIAR_FEEDING
|
||||
|
||||
/**
|
||||
* Use PRC henchmen-familiars instead of BioWare's - this will allow
|
||||
* new classes to have familiars, but summoned creatures will no longer
|
||||
* new classes to have familiars, but summoned creatures will no longer
|
||||
* be 'true' familiars (ie. can't possess PRC familiar)
|
||||
*/
|
||||
const string PRC_FAMILIARS = "PRC_FAMILIARS";
|
||||
@@ -1112,7 +1114,7 @@ const string PRC_SPELL_ALIGNMENT_RESTRICT = "PRC_SPELL_ALIGNMENT_REST
|
||||
* Disable registration of custom cohorts
|
||||
*/
|
||||
const string PRC_DISABLE_REGISTER_COHORTS = "PRC_DISABLE_REGISTER_COHORTS";
|
||||
|
||||
|
||||
/*
|
||||
* Disable cohorts starting with gear
|
||||
*/
|
||||
@@ -1142,19 +1144,19 @@ const string PRC_SPELL_ALIGNMENT_RESTRICT = "PRC_SPELL_ALIGNMENT_REST
|
||||
* Medium armor is a 25% speed reduction, Heavy is a 33% reduction
|
||||
*/
|
||||
const string PRC_PNP_ARMOR_SPEED = "PRC_PNP_ARMOR_SPEED";
|
||||
|
||||
|
||||
/*
|
||||
* Applies a 99% speed boost when out of combat
|
||||
* Warning that it will likely cause PCs to be overly speedy when combat starts
|
||||
* Potential problem causer
|
||||
*/
|
||||
const string PRC_FAST_TRAVEL_SPEED = "PRC_FAST_TRAVEL_SPEED";
|
||||
|
||||
|
||||
/*
|
||||
* Applys a Discipline bonus equal to BAB to all characters if turned on
|
||||
* Bonus only applies to characters with 0 ranks in Discipline
|
||||
*/
|
||||
const string PRC_PNP_KNOCKDOWN = "PRC_PNP_KNOCKDOWN";
|
||||
const string PRC_PNP_KNOCKDOWN = "PRC_PNP_KNOCKDOWN";
|
||||
|
||||
/*
|
||||
* by Bioware rules, PCs have approximatly a 7th faster movement than NPCs
|
||||
@@ -1202,8 +1204,11 @@ const string PRC_SPELL_ALIGNMENT_RESTRICT = "PRC_SPELL_ALIGNMENT_REST
|
||||
*/
|
||||
const string PRC_APPEARNCE_CHANGE_DISABLE = "PRC_APPEARNCE_CHANGE_DISABLE";
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Allow "Monk" gloves to merge with a creature weapons when Wildshaped.
|
||||
* Will also merge bracers with creature hides when Wildshaped.
|
||||
*/
|
||||
const string PRC_WILDSHAPE_ALLOWS_ARMS_SLOT = "PRC_WILDSHAPE_ALLOWS_ARMS_SLOT";
|
||||
|
||||
/******************************************************************************\
|
||||
* Death/Bleeding system *
|
||||
@@ -1221,7 +1226,7 @@ const string PRC_PNP_DEATH_ENABLE = "PRC_PNP_DEATH_ENA
|
||||
* if FALSE, dont bleed just die
|
||||
* By PnP this would be 1 round, or 6 seconds
|
||||
*/
|
||||
const string PRC_DEATH_OR_BLEED = "PRC_DEATH_OR_BLEED";
|
||||
const string PRC_DEATH_OR_BLEED = "PRC_DEATH_OR_BLEED";
|
||||
|
||||
/*
|
||||
* Damage when bleeding
|
||||
@@ -1314,7 +1319,7 @@ const string PRC_ACP_DELAY = "PRC_ACP_DELAY";
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* File End switches
|
||||
* File End switches
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -1488,10 +1493,10 @@ const string PRC_POISON_IS_FOOD_SCRIPT_NAME = "PRC_POISON_IS_FOOD_SCRIP
|
||||
const string PRC_POISON_ALLOW_CLEAN_IN_EQUIP = "PRC_POISON_ALLOW_CLEAN_IN_EQUIP";
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Default: crafting requires only gold and xp
|
||||
*/
|
||||
const string PRC_CRAFT_POISON_USE_INGREDIENST = "PRC_CRAFT_POISON_USE_INGREDIENST";
|
||||
const string PRC_CRAFT_POISON_USE_INGREDIENTS = "PRC_CRAFT_POISON_USE_INGREDIENTS";
|
||||
|
||||
/******************************************************************************\
|
||||
* PRGT system switches *
|
||||
@@ -1540,10 +1545,10 @@ const string PRC_PSI_ASTRAL_CONSTRUCT_DUR_MOD = "PRC_PSI_ASTRAL_CONSTRUCT
|
||||
|
||||
/**
|
||||
* If this is set, The Astral Seed power will attempt to use the provided string as
|
||||
* the ResRef to create the Astral Seed object instead of the of the phylactery
|
||||
* the ResRef to create the Astral Seed object instead of the of the phylactery
|
||||
* ResRef("x2_plc_phylact").
|
||||
* May be used by builders to create an object that CAN be destroyed, or has other traits,
|
||||
* as desired.
|
||||
* as desired.
|
||||
* Type: String
|
||||
* Values: "" [Default] (Blank, or not set: Use default phylactery ResRef for Astral Seed)
|
||||
* STRING (Entered String will be used as the ResRef of created Astral Seed object)
|
||||
@@ -1551,14 +1556,14 @@ const string PRC_PSI_ASTRAL_CONSTRUCT_DUR_MOD = "PRC_PSI_ASTRAL_CONSTRUCT
|
||||
const string PRC_PSI_ASTRAL_SEED_RESREF = "PRC_PSI_ASTRAL_SEED_RESREF";
|
||||
|
||||
/**
|
||||
* By default the Astral Seed power respawns the player, and then makes them immobile for
|
||||
* By default the Astral Seed power respawns the player, and then makes them immobile for
|
||||
* 24-game-hours.
|
||||
* If this switch is set, it will adjust the imobility time period; shortening it, lengthing it, or
|
||||
* If this switch is set, it will adjust the imobility time period; shortening it, lengthing it, or
|
||||
* effectively eliminating it.
|
||||
* Type: Int
|
||||
* Values: 0 [Default] (Not set: Use default 24 hour duration)
|
||||
* -1 (Any negative value will result in a fixed duratoion of 2 seconds, which effectively eliminates the wait period)
|
||||
* 1 (Any potitive value: multiply duration by the value provided and then divide result by 1000.
|
||||
* 1 (Any potitive value: multiply duration by the value provided and then divide result by 1000.
|
||||
* Values less than 1000 will shorten the duration, values higher than 1000 will lengthen it.)
|
||||
*/
|
||||
const string PRC_PSI_ASTRAL_SEED_RESPAWN_DELAY_X1000 = "PRC_PSI_ASTRAL_SEED_RESPAWN_DELAY_X1000";
|
||||
@@ -1569,7 +1574,7 @@ const string PRC_PSI_ASTRAL_SEED_RESPAWN_DELAY_X1000 = "PRC_PSI_ASTRAL_SE
|
||||
* If this flag is set, the XP loss is completely eliminated. The standard PRC event hook script
|
||||
* of "prc_pw_astralseed" may be used to script any additional effects to occure upon Astral Seed
|
||||
* respawning, including scripting specific XP loss amount.
|
||||
* Type: Int
|
||||
* Type: Int
|
||||
* Values: 0 [Default] (Not set: lose 1 level worth of XP upon Astral Seed respawn)
|
||||
* 1 (Any potitive value: Remove all XP loss from Astral Seed respawn)
|
||||
*/
|
||||
@@ -1906,7 +1911,7 @@ const string PRC_CRAFT_TIMER_MAX = "PRC_CRAFT_TIMER_MAX";
|
||||
*/
|
||||
const string PRC_CRAFT_TIMER_MIN = "PRC_CRAFT_TIMER_MIN";
|
||||
|
||||
/**
|
||||
/*
|
||||
* These three switches modify Bioware crafting so that the items produced have the
|
||||
* casterlevel of the spellcaster who created them. Normally under Bioware, it is possible
|
||||
* for a level 3 caster to produce level 9 items and for a level 40 caster to only produce
|
||||
@@ -1952,6 +1957,23 @@ const string PRC_CRAFT_ROD_CASTER_LEVEL = "PRC_CRAFT_ROD_CASTER_LEVE
|
||||
*/
|
||||
const string PRC_CRAFT_STAFF_CASTER_LEVEL = "PRC_CRAFT_STAFF_CASTER_LEVEL";
|
||||
|
||||
/*
|
||||
* As above, except it applies to scepters
|
||||
*/
|
||||
const string PRC_CRAFT_SCEPTER_CASTER_LEVEL = "PRC_CRAFT_SCEPTER_CASTER_LEVEL";
|
||||
|
||||
/*
|
||||
* As above, except it applies to herbal infusions
|
||||
*/
|
||||
const string PRC_CREATE_INFUSION_CASTER_LEVEL = "PRC_CREATE_INFUSION_CASTER_LEVEL";
|
||||
|
||||
/*
|
||||
* Builder's Option: Enables the optional PnP herbs for creating infusions.
|
||||
* Each herb is keyed to a spell circle level & spell school as shown on pg. 33
|
||||
* of the Master's of the Wild sourcebook.
|
||||
*/
|
||||
const string PRC_CREATE_INFUSION_OPTIONAL_HERBS = "PRC_CREATE_INFUSION_OPTIONAL_HERBS";
|
||||
|
||||
/*
|
||||
* Characters with a crafting feat always have the appropriate base item in their inventory
|
||||
*/
|
||||
@@ -1961,45 +1983,59 @@ const string PRC_CRAFTING_BASE_ITEMS = "PRC_CRAFTING_BASE_ITEMS";
|
||||
* Max level of spells brewed into potions
|
||||
* defaults to 3
|
||||
*/
|
||||
const string X2_CI_BREWPOTION_MAXLEVEL = "X2_CI_BREWPOTION_MAXLEVEL";
|
||||
//const string X2_CI_BREWPOTION_MAXLEVEL = "X2_CI_BREWPOTION_MAXLEVEL";
|
||||
const string PRC_X2_BREWPOTION_MAXLEVEL = "PRC_X2_BREWPOTION_MAXLEVEL";
|
||||
|
||||
/*
|
||||
* cost modifier of spells brewed into poitions
|
||||
* defaults to 50
|
||||
*/
|
||||
const string X2_CI_BREWPOTION_COSTMODIFIER = "X2_CI_BREWPOTION_COSTMODIFIER";
|
||||
const string PRC_X2_BREWPOTION_COSTMODIFIER = "PRC_X2_BREWPOTION_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* cost modifier of spells scribed into scrolls
|
||||
* defaults to 25
|
||||
*/
|
||||
const string X2_CI_SCRIBESCROLL_COSTMODIFIER = "X2_CI_SCRIBESCROLL_COSTMODIFIER";
|
||||
const string PRC_X2_SCRIBESCROLL_COSTMODIFIER = "PRC_X2_SCRIBESCROLL_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* cost modifier of spells infused into herbs
|
||||
* defaults to 25
|
||||
*/
|
||||
const string PRC_X2_CREATEINFUSION_COSTMODIFIER = "PRC_X2_CREATEINFUSION_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* Max level of spells crafted into wands
|
||||
* defaults to 4
|
||||
*/
|
||||
const string X2_CI_CRAFTWAND_MAXLEVEL = "X2_CI_CRAFTWAND_MAXLEVEL";
|
||||
const string PRC_X2_CRAFTWAND_MAXLEVEL = "PRC_X2_CRAFTWAND_MAXLEVEL";
|
||||
|
||||
/*
|
||||
* cost modifier of spells crafted into wands
|
||||
* defaults to 750
|
||||
*/
|
||||
const string X2_CI_CRAFTWAND_COSTMODIFIER = "X2_CI_CRAFTWAND_COSTMODIFIER";
|
||||
const string PRC_X2_CRAFTWAND_COSTMODIFIER = "PRC_X2_CRAFTWAND_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* cost modifier of spells crafted into rods
|
||||
* note that adding a second spell costs 75% and 3 or more costs 50%
|
||||
* defaults to 750
|
||||
*/
|
||||
const string X2_CI_CRAFTROD_COSTMODIFIER = "X2_CI_CRAFTROD_COSTMODIFIER";
|
||||
const string PRC_X2_CRAFTROD_COSTMODIFIER = "PRC_X2_CRAFTROD_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* cost modifier of spells crafted into scepters
|
||||
* note that adding a second spell costs 75%
|
||||
* defaults to 750
|
||||
*/
|
||||
const string PRC_X2_CRAFTSCEPTER_COSTMODIFIER = "PRC_X2_CRAFTSCEPTER_COSTMODIFIER";
|
||||
|
||||
/*
|
||||
* cost modifier of spells crafted into staffs
|
||||
* note that adding a second spell costs 75% and 3 or more costs 50%
|
||||
* defaults to 750
|
||||
*/
|
||||
const string X2_CI_CRAFTSTAFF_COSTMODIFIER = "X2_CI_CRAFTSTAFF_COSTMODIFIER";
|
||||
const string PRC_X2_CRAFTSTAFF_COSTMODIFIER = "PRC_X2_CRAFTSTAFF_COSTMODIFIER";
|
||||
|
||||
/**
|
||||
* Allows the use of arbitrary itemproperties and uses NWN item costs
|
||||
@@ -2321,7 +2357,7 @@ const string PRC_XP_GIVE_XP_TO_NPCS = "PRC_XP_GIVE_XP_TO_NPCS";
|
||||
/**
|
||||
* Setting this switch will turn off the messages about being too far awy to gain XP
|
||||
*/
|
||||
const string PRC_XP_DISABLE_SPAM = "PRC_XP_DISABLE_SPAM";
|
||||
const string PRC_XP_DISABLE_SPAM = "PRC_XP_DISABLE_SPAM";
|
||||
|
||||
/**
|
||||
* PCs must be in the same area as the CR to gain XP.
|
||||
@@ -2880,13 +2916,13 @@ const string PRC_PERFECTED_MAP_MULTIPLIER = "PRC_PERFECTED_MAP_MULTIP
|
||||
\******************************************************************************/
|
||||
|
||||
/**
|
||||
* Sets how many seconds it takes to contact a vestige.
|
||||
* Sets how many seconds it takes to contact a vestige.
|
||||
* Any number less than 6 is ignored
|
||||
*/
|
||||
const string PRC_CONTACT_VESTIGE_TIMER = "PRC_CONTACT_VESTIGE_TIMER";
|
||||
|
||||
/**
|
||||
* Sets how many seconds it takes to bind a vestige.
|
||||
* Sets how many seconds it takes to bind a vestige.
|
||||
* Any number less than 12 is ignored
|
||||
*/
|
||||
const string PRC_BIND_VESTIGE_TIMER = "PRC_BIND_VESTIGE_TIMER";
|
||||
@@ -2920,6 +2956,20 @@ const string PRC_PW_SECURITY_CD_CHECK = "PRC_PW_SECURITY_CD_CHECK";
|
||||
*/
|
||||
const string PRC_DEBUG = "PRC_DEBUG";
|
||||
|
||||
/******************************************************************************\
|
||||
* Duration NUI Switches *
|
||||
\******************************************************************************/
|
||||
|
||||
/**
|
||||
* Toggles allowing player to remove friendly PC spells on player through Duration NUI
|
||||
* instead of just their own spells.
|
||||
*/
|
||||
const string PRC_ALLOWED_TO_REMOVE_FRIENDLY_SPELLS = "PRC_ALLOWED_TO_REMOVE_FRIENDLY_SPELLS";
|
||||
/**
|
||||
* Toggles allowing players to see the duration of hostile spells on them.
|
||||
*/
|
||||
const string PRC_ALLOWED_TO_SEE_HOSTILE_SPELLS = "PRC_ALLOWED_TO_SEE_HOSTILE_SPELLS";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,21 +10,12 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_spell_const"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//gets the number of class levels that count for turning
|
||||
int GetTurningClassLevel(object oCaster = OBJECT_SELF, int nTurnType = SPELL_TURN_UNDEAD);
|
||||
|
||||
@@ -191,6 +182,20 @@ int GetIsTurnOrRebuke(object oTarget, int nTurnType, int nTargetRace)
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_PLANT_DEFIANCE:
|
||||
{
|
||||
if(nTargetRace == RACIAL_TYPE_PLANT)
|
||||
nReturn = ACTION_TURN;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_PLANT_CONTROL:
|
||||
{
|
||||
if(nTargetRace == RACIAL_TYPE_PLANT)
|
||||
nReturn = ACTION_REBUKE;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_TURN_PLANT:
|
||||
{
|
||||
// Plant domain rebukes or commands plants
|
||||
@@ -383,6 +388,13 @@ int GetTurningClassLevel(object oCaster = OBJECT_SELF, int nTurnType = SPELL_TUR
|
||||
|
||||
if (nTurnType == SPELL_OPPORTUNISTIC_PIETY_TURN)
|
||||
return GetLevelByClass(CLASS_TYPE_FACTOTUM, oCaster);
|
||||
|
||||
if (nTurnType == SPELL_PLANT_DEFIANCE || nTurnType == SPELL_PLANT_CONTROL)
|
||||
{
|
||||
int nDivineLvl = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster);
|
||||
|
||||
return nDivineLvl;
|
||||
}
|
||||
|
||||
//Baelnorn & Archlich adds all class levels.
|
||||
if(GetLevelByClass(CLASS_TYPE_BAELNORN, oCaster) || GetHasFeat(FEAT_TEMPLATE_ARCHLICH_MARKER, oCaster)) //:: Archlich
|
||||
|
||||
@@ -91,6 +91,107 @@ float DamageAvg(int iDamage);
|
||||
/* Function defintions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
// StepDie: increases a damage die by 'nSteps' steps according to d20 SRD progression
|
||||
// Increment the unarmed damage by nSteps
|
||||
int StepDie(int nDamage, int nSteps)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nSteps; i++)
|
||||
{
|
||||
switch (nDamage)
|
||||
{
|
||||
// 1-dice increments
|
||||
case IP_CONST_MONSTERDAMAGE_1d2: nDamage = IP_CONST_MONSTERDAMAGE_1d3; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d3: nDamage = IP_CONST_MONSTERDAMAGE_1d4; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d4: nDamage = IP_CONST_MONSTERDAMAGE_1d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d6: nDamage = IP_CONST_MONSTERDAMAGE_1d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d8: nDamage = IP_CONST_MONSTERDAMAGE_1d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d10: nDamage = IP_CONST_MONSTERDAMAGE_1d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_1d12: nDamage = IP_CONST_MONSTERDAMAGE_2d8; break;
|
||||
|
||||
// 2-dice increments
|
||||
//case IP_CONST_MONSTERDAMAGE_2d3: nDamage = IP_CONST_MONSTERDAMAGE_2d4; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d4: nDamage = IP_CONST_MONSTERDAMAGE_2d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d6: nDamage = IP_CONST_MONSTERDAMAGE_2d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d8: nDamage = IP_CONST_MONSTERDAMAGE_2d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d10: nDamage = IP_CONST_MONSTERDAMAGE_2d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d12: nDamage = IP_CONST_MONSTERDAMAGE_3d10; break;
|
||||
|
||||
// 3-dice increments
|
||||
case IP_CONST_MONSTERDAMAGE_3d4: nDamage = IP_CONST_MONSTERDAMAGE_3d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_3d6: nDamage = IP_CONST_MONSTERDAMAGE_3d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_3d8: nDamage = IP_CONST_MONSTERDAMAGE_3d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_3d10: nDamage = IP_CONST_MONSTERDAMAGE_3d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_3d12: nDamage = IP_CONST_MONSTERDAMAGE_4d8; break;
|
||||
|
||||
// 4-dice increments
|
||||
case IP_CONST_MONSTERDAMAGE_4d4: nDamage = IP_CONST_MONSTERDAMAGE_4d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_4d6: nDamage = IP_CONST_MONSTERDAMAGE_4d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_4d8: nDamage = IP_CONST_MONSTERDAMAGE_4d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_4d10: nDamage = IP_CONST_MONSTERDAMAGE_4d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_4d12: nDamage = IP_CONST_MONSTERDAMAGE_5d8; break;
|
||||
|
||||
// 5-dice increments
|
||||
case IP_CONST_MONSTERDAMAGE_5d4: nDamage = IP_CONST_MONSTERDAMAGE_5d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_5d6: nDamage = IP_CONST_MONSTERDAMAGE_5d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_5d8: nDamage = IP_CONST_MONSTERDAMAGE_5d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_5d10: nDamage = IP_CONST_MONSTERDAMAGE_5d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_5d12: nDamage = IP_CONST_MONSTERDAMAGE_6d10; break;
|
||||
|
||||
// 6-dice increments
|
||||
//case IP_CONST_MONSTERDAMAGE_6d4: nDamage = IP_CONST_MONSTERDAMAGE_6d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_6d6: nDamage = IP_CONST_MONSTERDAMAGE_6d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_6d8: nDamage = IP_CONST_MONSTERDAMAGE_6d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_6d10: nDamage = IP_CONST_MONSTERDAMAGE_6d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_6d12: nDamage = IP_CONST_MONSTERDAMAGE_7d10; break;
|
||||
|
||||
// 7-dice increments
|
||||
case IP_CONST_MONSTERDAMAGE_7d4: nDamage = IP_CONST_MONSTERDAMAGE_7d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_7d6: nDamage = IP_CONST_MONSTERDAMAGE_7d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_7d8: nDamage = IP_CONST_MONSTERDAMAGE_7d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_7d10: nDamage = IP_CONST_MONSTERDAMAGE_7d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_7d12: nDamage = IP_CONST_MONSTERDAMAGE_9d10; break;
|
||||
|
||||
// 8-dice increments
|
||||
//case IP_CONST_MONSTERDAMAGE_8d4: nDamage = IP_CONST_MONSTERDAMAGE_8d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_8d6: nDamage = IP_CONST_MONSTERDAMAGE_8d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_8d8: nDamage = IP_CONST_MONSTERDAMAGE_8d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_8d10: nDamage = IP_CONST_MONSTERDAMAGE_8d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_8d12: nDamage = IP_CONST_MONSTERDAMAGE_10d10; break;
|
||||
|
||||
// 9-dice increments
|
||||
//case IP_CONST_MONSTERDAMAGE_9d4: nDamage = IP_CONST_MONSTERDAMAGE_9d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_9d6: nDamage = IP_CONST_MONSTERDAMAGE_9d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_9d8: nDamage = IP_CONST_MONSTERDAMAGE_9d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_9d10: nDamage = IP_CONST_MONSTERDAMAGE_9d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_9d12: nDamage = IP_CONST_MONSTERDAMAGE_6d20; break;
|
||||
|
||||
// 10-dice increments
|
||||
//case IP_CONST_MONSTERDAMAGE_10d4: nDamage = IP_CONST_MONSTERDAMAGE_10d6; break;
|
||||
case IP_CONST_MONSTERDAMAGE_10d6: nDamage = IP_CONST_MONSTERDAMAGE_10d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_10d8: nDamage = IP_CONST_MONSTERDAMAGE_10d10; break;
|
||||
case IP_CONST_MONSTERDAMAGE_10d10: nDamage = IP_CONST_MONSTERDAMAGE_10d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_10d12: nDamage = IP_CONST_MONSTERDAMAGE_7d20; break;
|
||||
|
||||
// d20 increments
|
||||
case IP_CONST_MONSTERDAMAGE_1d20: nDamage = IP_CONST_MONSTERDAMAGE_3d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_2d20: nDamage = IP_CONST_MONSTERDAMAGE_4d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_3d20: nDamage = IP_CONST_MONSTERDAMAGE_8d8; break;
|
||||
case IP_CONST_MONSTERDAMAGE_4d20: nDamage = IP_CONST_MONSTERDAMAGE_8d12; break;
|
||||
case IP_CONST_MONSTERDAMAGE_5d20: nDamage = IP_CONST_MONSTERDAMAGE_9d12; break; //:: Everything breaks down here
|
||||
case IP_CONST_MONSTERDAMAGE_6d20: nDamage = IP_CONST_MONSTERDAMAGE_1d20; break;
|
||||
case IP_CONST_MONSTERDAMAGE_7d20: nDamage = IP_CONST_MONSTERDAMAGE_8d20; break;
|
||||
case IP_CONST_MONSTERDAMAGE_8d20: nDamage = IP_CONST_MONSTERDAMAGE_9d20; break;
|
||||
case IP_CONST_MONSTERDAMAGE_9d20: nDamage = IP_CONST_MONSTERDAMAGE_10d20; break;
|
||||
|
||||
default: break; // top tier or unknown
|
||||
}
|
||||
}
|
||||
|
||||
return nDamage;
|
||||
}
|
||||
|
||||
|
||||
// Clean up any extras in the inventory.
|
||||
void CleanExtraFists(object oCreature)
|
||||
{
|
||||
@@ -168,12 +269,169 @@ void ApplyUnarmedAttackEffects(object oCreature)
|
||||
}
|
||||
|
||||
// Determines the amount of damage a character can do.
|
||||
// IoDM: +1 dice at level 4, +2 dice at level 8
|
||||
// IoDM: +1 die at level 4, +2 dice at level 8
|
||||
// Sacred Fist: Levels add to monk levels, or stand alone as monk levels.
|
||||
// Shou: 1d6 at level 1, 1d8 at level 2, 1d10 at level 3, 2d6 at level 5
|
||||
// Monk: 1d6 at level 1, 1d8 at level 4, 1d10 at level 8, 2d6 at level 12, 2d8 at level 16, 2d10 at level 20
|
||||
// Frostrager: 1d6 at level 1, 1d8 at level 4
|
||||
int FindUnarmedDamage(object oCreature)
|
||||
{
|
||||
int iDamage = 0;
|
||||
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
|
||||
int iShou = GetLevelByClass(CLASS_TYPE_SHOU, oCreature);
|
||||
int iBrawler = GetLevelByClass(CLASS_TYPE_BRAWLER, oCreature);
|
||||
int iSacredFist = GetLevelByClass(CLASS_TYPE_SACREDFIST, oCreature);
|
||||
int iEnlightenedFist = GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oCreature);
|
||||
int iHenshin = GetLevelByClass(CLASS_TYPE_HENSHIN_MYSTIC, oCreature);
|
||||
int iZuoken = GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature);
|
||||
int iShadowSunNinja = GetLevelByClass(CLASS_TYPE_SHADOW_SUN_NINJA, oCreature);
|
||||
int iFrost = GetLevelByClass(CLASS_TYPE_FROSTRAGER, oCreature);
|
||||
int iAscetic = GetLevelByClass(CLASS_TYPE_NINJA, oCreature);
|
||||
int iRonove = 0;
|
||||
int iMonkDamage = 1;
|
||||
int iShouDamage = 1;
|
||||
int iBrawlerDamage = 1;
|
||||
int iFrostDamage = 1;
|
||||
int iSUSDamage = 1;
|
||||
int iDieIncrease = 0;
|
||||
int iSize;
|
||||
|
||||
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature))
|
||||
iRonove = GetLocalInt(oCreature, "RonovesFists");
|
||||
|
||||
//:: Determine creature size
|
||||
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
|
||||
{
|
||||
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSize = 5; // medium
|
||||
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
|
||||
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
|
||||
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
|
||||
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
|
||||
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
|
||||
if (iSize < 1) iSize = 1;
|
||||
if (iSize > 9) iSize = 9;
|
||||
}
|
||||
|
||||
// Sacred Fist code break protection
|
||||
if (GetHasFeat(FEAT_SF_CODE, oCreature)) iSacredFist = 0;
|
||||
|
||||
// Combine monk-like levels
|
||||
iMonk += iSacredFist + iHenshin + iEnlightenedFist + iShou + iZuoken + iShadowSunNinja;
|
||||
|
||||
// Superior Unarmed Strike
|
||||
if (GetHasFeat(FEAT_SUPERIOR_UNARMED_STRIKE, oCreature))
|
||||
{
|
||||
iMonk += 4;
|
||||
int nHD = GetHitDice(oCreature);
|
||||
if (nHD >= 16) iSUSDamage = IP_CONST_MONSTERDAMAGE_2d6;
|
||||
else if (nHD >= 12) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d10;
|
||||
else if (nHD >= 8) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
else if (nHD >= 4) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
else if (nHD >= 3) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d4;
|
||||
}
|
||||
|
||||
// Ascetic Stalker
|
||||
if (GetHasFeat(FEAT_ASCETIC_STALKER, oCreature))
|
||||
iMonk += iAscetic;
|
||||
|
||||
// Cap monk progression
|
||||
if (iMonk > 16 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE)) iMonk = 16;
|
||||
else if (iMonk > 20) iMonk = 20;
|
||||
|
||||
// Ronove replacement
|
||||
if (iRonove > iMonk) iMonk = iRonove;
|
||||
|
||||
// Monk damage calculation (2DA row)
|
||||
if (iMonk > 0) iMonkDamage = iMonk / 4 + 3;
|
||||
if (iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
iMonkDamage = 8;
|
||||
|
||||
// Shou Disciple base damage
|
||||
if (iShou > 0)
|
||||
{
|
||||
int nRow;
|
||||
if (iShou == 1) nRow = 3;
|
||||
else if (iShou == 2) nRow = 4;
|
||||
else if (iShou == 3) nRow = 5;
|
||||
else if (iShou == 4) nRow = 5;
|
||||
else if (iShou == 5) nRow = 6;
|
||||
else nRow = 3;
|
||||
|
||||
if (nRow > 6) nRow = 6;
|
||||
|
||||
iShouDamage = StringToInt(Get2DACache("unarmed_dmg", "size" + IntToString(iSize), nRow));
|
||||
}
|
||||
|
||||
// Frostrager
|
||||
if (iFrost > 0) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
if (iFrost > 3) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
|
||||
// Brawler
|
||||
if (iBrawler > 0) iBrawlerDamage = iBrawler / 6 + 3;
|
||||
if (iBrawler >= 36) iBrawlerDamage += 2;
|
||||
|
||||
// Armor/shield penalties
|
||||
if (iMonkDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
if (GetBaseAC(oArmor) > 0 || bShieldEq)
|
||||
iMonkDamage = 1;
|
||||
}
|
||||
|
||||
if (iShouDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
if (GetBaseAC(oArmor) > 3 || bShieldEq)
|
||||
iShouDamage = 1;
|
||||
}
|
||||
|
||||
// Determine IoDM die increase
|
||||
if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease = 2;
|
||||
else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease = 1;
|
||||
|
||||
// Lookup monk damage in 2DA
|
||||
iMonkDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage));
|
||||
|
||||
// 3.0e monk special cases
|
||||
if (iSize <= 5 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
{
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d6) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d12;
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d10) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d20;
|
||||
}
|
||||
|
||||
// Apply IoDM die increase last, after 2DA lookups
|
||||
if (iMonkDamage > 0) iMonkDamage = StepDie(iMonkDamage, iDieIncrease);
|
||||
if (iShouDamage > 0) iShouDamage = StepDie(iShouDamage, iDieIncrease);
|
||||
if (iBrawlerDamage > 0) iBrawlerDamage = StepDie(iBrawlerDamage, iDieIncrease);
|
||||
if (iFrostDamage > 0) iFrostDamage = StepDie(iFrostDamage, iDieIncrease);
|
||||
if (iSUSDamage > 0) iSUSDamage = StepDie(iSUSDamage, iDieIncrease);
|
||||
|
||||
// Select best damage
|
||||
iDamage = iMonkDamage;
|
||||
iDamage = (DamageAvg(iShouDamage ) > DamageAvg(iDamage)) ? iShouDamage : iDamage;
|
||||
iDamage = (DamageAvg(iFrostDamage ) > DamageAvg(iDamage)) ? iFrostDamage : iDamage;
|
||||
iDamage = (DamageAvg(iSUSDamage ) > DamageAvg(iDamage)) ? iSUSDamage : iDamage;
|
||||
iDamage = (DamageAvg(iBrawlerDamage) > DamageAvg(iDamage)) ? iBrawlerDamage : iDamage;
|
||||
|
||||
if (DEBUG) DoDebug("prc_inc_unarmed: iDamage "+IntToString(iDamage));
|
||||
|
||||
return iDamage;
|
||||
}
|
||||
|
||||
|
||||
/* int FindUnarmedDamage(object oCreature)
|
||||
{
|
||||
int iDamage = 0;
|
||||
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
|
||||
@@ -195,36 +453,30 @@ int FindUnarmedDamage(object oCreature)
|
||||
int iDieIncrease = 0;
|
||||
int iSize;
|
||||
|
||||
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature)) iRonove = GetLocalInt(oCreature, "RonovesFists");
|
||||
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature))
|
||||
iRonove = GetLocalInt(oCreature, "RonovesFists");
|
||||
|
||||
// if the creature is shifted, use model size
|
||||
// otherwise, we want to stick to what the feats say they "should" be.
|
||||
// No making pixies with Dragon Appearance for "huge" fist damage.
|
||||
if( GetIsPolyMorphedOrShifted(oCreature)
|
||||
|| GetPRCSwitch(PRC_APPEARANCE_SIZE))
|
||||
// Determine creature size
|
||||
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
|
||||
{
|
||||
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5; // medium is size 5 for us
|
||||
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine creature size by feats.
|
||||
iSize = 5; // medium is size 5 for us
|
||||
iSize = 5; // medium
|
||||
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
|
||||
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
|
||||
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
|
||||
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
|
||||
// include size changes
|
||||
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
|
||||
// cap if needed
|
||||
if (iSize < 1) iSize = 1;
|
||||
if (iSize > 9) iSize = 9;
|
||||
}
|
||||
|
||||
// Sacred Fist cannot add their levels if they've broken their code.
|
||||
// Sacred Fist code break protection
|
||||
if (GetHasFeat(FEAT_SF_CODE, oCreature)) iSacredFist = 0;
|
||||
|
||||
// several classes add their levels to the monk class,
|
||||
// or use monk progression if the character has no monk levels
|
||||
// Combine monk-like levels
|
||||
iMonk += iSacredFist + iHenshin + iEnlightenedFist + iShou + iZuoken + iShadowSunNinja;
|
||||
|
||||
// Superior Unarmed Strike
|
||||
@@ -232,49 +484,66 @@ int FindUnarmedDamage(object oCreature)
|
||||
{
|
||||
iMonk += 4;
|
||||
int nHD = GetHitDice(oCreature);
|
||||
if (nHD >= 16) iSUSDamage = IP_CONST_MONSTERDAMAGE_2d6;
|
||||
if (nHD >= 16) iSUSDamage = IP_CONST_MONSTERDAMAGE_2d6;
|
||||
else if (nHD >= 12) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d10;
|
||||
else if (nHD >= 8) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
else if (nHD >= 4) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
else if (nHD >= 3) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d4;
|
||||
else if (nHD >= 8) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
else if (nHD >= 4) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
else if (nHD >= 3) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d4;
|
||||
}
|
||||
|
||||
// Ascetic Stalker
|
||||
if (GetHasFeat(FEAT_ASCETIC_STALKER, oCreature))
|
||||
iMonk += iAscetic;
|
||||
|
||||
// In 3.0e, Monk progression stops after level 16:
|
||||
if (iMonk > 16 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE) ) iMonk = 16;
|
||||
// in 3.5e, monk progression stops at 20.
|
||||
else if(iMonk > 20) iMonk = 20;
|
||||
// Cap monk progression
|
||||
if (iMonk > 16 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE)) iMonk = 16;
|
||||
else if (iMonk > 20) iMonk = 20;
|
||||
|
||||
// Ronove is in place of monk, does not stack
|
||||
// Ronove replacement
|
||||
if (iRonove > iMonk) iMonk = iRonove;
|
||||
|
||||
// monks damage progesses every four levels, starts at 1d6
|
||||
if (iMonk > 0)
|
||||
iMonkDamage = iMonk / 4 + 3;
|
||||
// Monk damage calculation
|
||||
if (iMonk > 0) iMonkDamage = iMonk / 4 + 3;
|
||||
|
||||
// For medium monks in 3.0e skip 2d8 and go to 1d20
|
||||
if(iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE) ) iMonkDamage = 8;
|
||||
if(iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
iMonkDamage = 8;
|
||||
|
||||
// Shou Disciple either adds its level to existing class or does its own damage, depending
|
||||
// on which is better. Here we will determine how much damage the Shou Disciple does
|
||||
// without stacking.
|
||||
if (iShou > 0) iShouDamage = iShou + 2; // Lv. 1: 1d6, Lv. 2: 1d8, Lv. 3: 1d10
|
||||
if (iShou > 3) iShouDamage--; // Lv. 4: 1d10, Lv. 5: 2d6
|
||||
iShouDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iShouDamage));
|
||||
|
||||
// Frostrager does not stack with other damage types
|
||||
if (iFrost > 0) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d6; // Lv. 1: 1d6
|
||||
if (iFrost > 3) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d8; // Lv. 3: 1d8
|
||||
//if (iShou > 0) iShouDamage = iShou + 2; // Lv. 1: 1d6, Lv. 2: 1d8, Lv. 3: 1d10
|
||||
//if (iShou > 3) iShouDamage--; // Lv. 4: 1d10, Lv. 5: 2d6
|
||||
//iShouDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iShouDamage));
|
||||
|
||||
if (iShou > 0)
|
||||
{
|
||||
// Determine 2DA row for Shou progression
|
||||
int nRow;
|
||||
if (iShou == 1) nRow = 3; // monk1
|
||||
else if (iShou == 2) nRow = 4; // monk2
|
||||
else if (iShou == 3) nRow = 5; // monk3
|
||||
else if (iShou == 4) nRow = 6; // monk4
|
||||
else if (iShou == 5) nRow = 7; // monk5
|
||||
else if (iShou == 6) nRow = 8; // monk6
|
||||
else if (iShou == 7) nRow = 9; // monk7
|
||||
else nRow = 10; // monk8+
|
||||
|
||||
nRow += iDieIncrease;
|
||||
if (nRow > 10) nRow = 10; // clamp to max row
|
||||
|
||||
// Brawler follows monk progression except for the last one (3d8)
|
||||
if (iBrawler > 0) iBrawlerDamage = iBrawler / 6 + 3; // 1d6, 1d8, 1d10, 2d6, 2d8, 2d10
|
||||
if (iBrawler >= 36) iBrawlerDamage += 2; // 3d8
|
||||
// Lookup damage in unarmed_damage.2da using size column
|
||||
iShouDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), nRow));
|
||||
}
|
||||
|
||||
// Monks and monk-like classes deal no additional damage when wearing any armor, at
|
||||
// least in NWN. This is to reflect that. No shields too.
|
||||
// Frostrager
|
||||
if (iFrost > 0) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
if (iFrost > 3) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
|
||||
// Brawler
|
||||
if (iBrawler > 0) iBrawlerDamage = iBrawler / 6 + 3;
|
||||
if (iBrawler >= 36) iBrawlerDamage += 2;
|
||||
|
||||
// Armor/shield penalties
|
||||
if (iMonkDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
@@ -284,13 +553,10 @@ int FindUnarmedDamage(object oCreature)
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
|
||||
if (GetBaseAC(oArmor) > 0 || bShieldEq)
|
||||
{
|
||||
iMonkDamage = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Shou Disciples can wear light armor
|
||||
if (iShouDamage > 1)
|
||||
if (iShouDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
@@ -299,53 +565,31 @@ int FindUnarmedDamage(object oCreature)
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
|
||||
if (GetBaseAC(oArmor) > 3 || bShieldEq)
|
||||
{
|
||||
iShouDamage = 1;
|
||||
}
|
||||
iShouDamage = 1;
|
||||
}
|
||||
|
||||
// For Initiate of Draconic Mysteries
|
||||
if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease = 2;
|
||||
else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease = 1;
|
||||
|
||||
//:: Expansion / Compression powers
|
||||
int nExpansion = GetLocalInt(oCreature, "PRC_Power_Expansion_SizeIncrease");
|
||||
int nCompression = GetLocalInt(oCreature, "PRC_Power_Compression_SizeReduction");
|
||||
|
||||
if (nExpansion)
|
||||
{
|
||||
iSize += nExpansion;
|
||||
}
|
||||
|
||||
if (nCompression)
|
||||
{
|
||||
iSize -= nCompression;
|
||||
}
|
||||
// IoDM die increase
|
||||
if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease += 2;
|
||||
else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease += 1;
|
||||
|
||||
iMonkDamage += iDieIncrease;
|
||||
iShouDamage += iDieIncrease;
|
||||
iBrawlerDamage += iDieIncrease;
|
||||
iFrostDamage += iDieIncrease;
|
||||
iSUSDamage += iDieIncrease;
|
||||
|
||||
//FloatingTextStringOnCreature("prc_inc_unarmed: Size is: "+IntToString(iSize)+".", oCreature);
|
||||
//FloatingTextStringOnCreature("prc_inc_unarmed: Pre 2DA Lookup >> iMonkDamage = "+IntToString(iMonkDamage)+".", oCreature);
|
||||
|
||||
// now, read the damage from the table in unarmed_dmg.2da
|
||||
// Lookup final monk damage in 2DA
|
||||
iMonkDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage));
|
||||
iShouDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iShouDamage));
|
||||
|
||||
//FloatingTextStringOnCreature("prc_inc_unarmed: Post 2DA Lookup >> iMonkDamage = "+IntToString(iMonkDamage)+".", oCreature);
|
||||
|
||||
// Medium+ monks have some special values on the table in 3.0:
|
||||
// 3.0e monk special cases
|
||||
if (iSize >= 5 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
{
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d6) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d12;
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d10) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d20;
|
||||
}
|
||||
|
||||
// Select best damage
|
||||
iDamage = iMonkDamage;
|
||||
// Future unarmed classes: if you do your own damage, add in "comparisons" below here.
|
||||
iDamage = (DamageAvg(iShouDamage ) > DamageAvg(iDamage)) ? iShouDamage : iDamage;
|
||||
iDamage = (DamageAvg(iFrostDamage ) > DamageAvg(iDamage)) ? iFrostDamage : iDamage;
|
||||
iDamage = (DamageAvg(iSUSDamage ) > DamageAvg(iDamage)) ? iSUSDamage : iDamage;
|
||||
@@ -354,6 +598,8 @@ int FindUnarmedDamage(object oCreature)
|
||||
|
||||
return iDamage;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Adds appropriate feats to the skin. Stolen from SoulTaker + expanded with overwhelming/devastating critical.
|
||||
void UnarmedFeats(object oCreature)
|
||||
@@ -426,13 +672,13 @@ void UnarmedFists(object oCreature)
|
||||
|
||||
// Sacred Fists who break their code get no benefits.
|
||||
if (GetHasFeat(FEAT_SF_CODE,oCreature)) iSacFist = 0;
|
||||
|
||||
|
||||
// The monk adds all these classes.
|
||||
int iMonkEq = iMonk + iShou + iSacFist + iHenshin + iZuoken + iShadowSunNinja;
|
||||
|
||||
int iMonkEq = iMonk + iShou + iSacFist + iHenshin + iZuoken + iShadowSunNinja;
|
||||
|
||||
// Ascetic Stalker
|
||||
if (GetHasFeat(FEAT_ASCETIC_STALKER, oCreature))
|
||||
iMonkEq += iAscetic;
|
||||
iMonkEq += iAscetic;
|
||||
|
||||
// Determine the type of damage the character should do.
|
||||
string sWeapType;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Weapon Restriction System Include
|
||||
//:: prc_inc_restwpn.nss
|
||||
//:: prc_inc_wpnrest.nss
|
||||
//::///////////////////////////////////////////////
|
||||
/*
|
||||
Functions to support PnP Weapon Proficiency and
|
||||
@@ -15,6 +15,56 @@
|
||||
#include "inc_item_props"
|
||||
#include "prc_x2_itemprop"
|
||||
|
||||
//:: Detects if "monk" gloves are being equipped & set a
|
||||
//:: variable if TRUE for use with other functions
|
||||
void DetectMonkGloveEquip(object oItem)
|
||||
{
|
||||
int nItemType = GetBaseItemType(oItem);
|
||||
|
||||
object oPC = GetItemPossessor(oItem);
|
||||
if (!GetIsObjectValid(oItem))
|
||||
{
|
||||
if (DEBUG) DoDebug("prc_inc_wpnrest >> DetectMonkGloveEquip(): Unable to determine item possessor");
|
||||
return;
|
||||
}
|
||||
|
||||
if(nItemType != BASE_ITEM_GLOVES && nItemType != BASE_ITEM_BRACER) {return;}
|
||||
|
||||
else if (nItemType == BASE_ITEM_BRACER)
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_inc_wpnrest >> DetectMonkGloveEquip(): Bracer found!");
|
||||
DeleteLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemproperty ipG = GetFirstItemProperty(oItem);
|
||||
|
||||
while(GetIsItemPropertyValid(ipG))
|
||||
{
|
||||
int nTypeG = GetItemPropertyType(ipG);
|
||||
|
||||
// Damage related properties we care about
|
||||
if(nTypeG == ITEM_PROPERTY_DAMAGE_BONUS
|
||||
|| nTypeG == ITEM_PROPERTY_ATTACK_BONUS
|
||||
|| nTypeG == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP
|
||||
|| nTypeG == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|
||||
|| nTypeG == ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT)
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_inc_wpnrest >> DetectMonkGloves(): Monk gloves found!");
|
||||
SetLocalInt(oPC, "WEARING_MONK_GLOVES", 1);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_inc_wpnrest >> DetectMonkGloves(): Monk gloves not found! You should never see this.");
|
||||
DeleteLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All of the following functions use the following parameters:
|
||||
*
|
||||
@@ -23,6 +73,69 @@
|
||||
* @param nHand The hand the weapon is wielded in. In the form of
|
||||
* ATTACK_BONUS_ONHAND or ATTACK_BONUS_OFFHAND.
|
||||
*/
|
||||
//:: returns TRUE if the wielded weapon works with the Swashbuckler's class abilities.
|
||||
int GetHasSwashbucklerWeapon(object oPC)
|
||||
{
|
||||
object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
if (!GetIsObjectValid(oWeap)) return FALSE;
|
||||
|
||||
int nType = GetBaseItemType(oWeap);
|
||||
|
||||
switch (nType)
|
||||
{
|
||||
case BASE_ITEM_DAGGER:
|
||||
case BASE_ITEM_KATAR:
|
||||
case BASE_ITEM_HANDAXE:
|
||||
case BASE_ITEM_KAMA:
|
||||
case BASE_ITEM_KUKRI:
|
||||
case BASE_ITEM_LIGHTHAMMER:
|
||||
case BASE_ITEM_LIGHTMACE:
|
||||
case BASE_ITEM_LIGHT_PICK:
|
||||
case BASE_ITEM_RAPIER:
|
||||
case BASE_ITEM_SHORTSWORD:
|
||||
case BASE_ITEM_SICKLE:
|
||||
case BASE_ITEM_WHIP:
|
||||
case BASE_ITEM_SAI:
|
||||
case BASE_ITEM_SAP:
|
||||
case BASE_ITEM_NUNCHAKU:
|
||||
case BASE_ITEM_GOAD:
|
||||
case BASE_ITEM_ELVEN_LIGHTBLADE:
|
||||
case BASE_ITEM_ELVEN_THINBLADE:
|
||||
case BASE_ITEM_EAGLE_CLAW:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Iaijutsu Master allows katana
|
||||
if (GetLevelByClass(CLASS_TYPE_IAIJUTSU_MASTER, oPC) > 0)
|
||||
{
|
||||
if (nType == BASE_ITEM_KATANA) return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//:: returns TRUE if the wielded weapon works with the Champion of Corellon's Elegant Strike.
|
||||
int GetHasCorellonWeapon(object oPC)
|
||||
{
|
||||
object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
if (!GetIsObjectValid(oWeap)) return FALSE;
|
||||
|
||||
int nType = GetBaseItemType(oWeap);
|
||||
|
||||
switch (nType)
|
||||
{
|
||||
case BASE_ITEM_SCIMITAR:
|
||||
case BASE_ITEM_LONGSWORD:
|
||||
case BASE_ITEM_RAPIER:
|
||||
case BASE_ITEM_ELVEN_COURTBLADE:
|
||||
case BASE_ITEM_ELVEN_LIGHTBLADE:
|
||||
case BASE_ITEM_ELVEN_THINBLADE:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void DoRacialEquip(object oPC, int nBaseType);
|
||||
|
||||
//return if PC has proficiency in an item
|
||||
@@ -40,13 +153,31 @@ int IsProficient(object oPC, int nBaseItem)
|
||||
|
||||
case BASE_ITEM_CLUB:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_CLUB, oPC);
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_CLUB, oPC);
|
||||
|
||||
case BASE_ITEM_HEAVYCROSSBOW:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW, oPC);
|
||||
|
||||
case BASE_ITEM_LIGHTCROSSBOW:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW, oPC);
|
||||
|
||||
case BASE_ITEM_DAGGER:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DAGGER, oPC);
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DAGGER, oPC);
|
||||
|
||||
case BASE_ITEM_LONGSWORD:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oPC)
|
||||
@@ -152,10 +283,17 @@ int IsProficient(object oPC, int nBaseItem)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC);
|
||||
|
||||
case BASE_ITEM_QUARTERSTAFF:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF, oPC)
|
||||
||GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
|
||||
|
||||
case BASE_ITEM_MAGICSTAFF:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF, oPC)
|
||||
||GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
|
||||
|
||||
case BASE_ITEM_RAPIER:
|
||||
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_RAPIER, oPC)
|
||||
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oPC)
|
||||
@@ -295,167 +433,185 @@ int GetWeaponProfFeatByType(int nBaseType)
|
||||
{
|
||||
switch(nBaseType)
|
||||
{
|
||||
case BASE_ITEM_SHORTSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
|
||||
case BASE_ITEM_CLUB:
|
||||
return FEAT_WEAPON_PROFICIENCY_CLUB;
|
||||
|
||||
case BASE_ITEM_QUARTERSTAFF:
|
||||
return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
|
||||
|
||||
case BASE_ITEM_LONGSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_LONGSWORD;
|
||||
case BASE_ITEM_MAGICSTAFF:
|
||||
return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
|
||||
|
||||
case BASE_ITEM_DAGGER:
|
||||
return FEAT_WEAPON_PROFICIENCY_DAGGER;
|
||||
|
||||
case BASE_ITEM_BATTLEAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
|
||||
case BASE_ITEM_HEAVYCROSSBOW:
|
||||
return FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW;
|
||||
|
||||
case BASE_ITEM_BASTARDSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
|
||||
case BASE_ITEM_LIGHTCROSSBOW:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW;
|
||||
|
||||
case BASE_ITEM_SHORTSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
|
||||
|
||||
case BASE_ITEM_LIGHTFLAIL:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
|
||||
case BASE_ITEM_LONGSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_LONGSWORD;
|
||||
|
||||
case BASE_ITEM_WARHAMMER:
|
||||
return FEAT_WEAPON_PROFICIENCY_WARHAMMER;
|
||||
case BASE_ITEM_BATTLEAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
|
||||
|
||||
case BASE_ITEM_LONGBOW:
|
||||
return FEAT_WEAPON_PROFICIENCY_LONGBOW;
|
||||
case BASE_ITEM_BASTARDSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
|
||||
|
||||
case BASE_ITEM_LIGHTMACE:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
|
||||
case BASE_ITEM_LIGHTFLAIL:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
|
||||
|
||||
case BASE_ITEM_HALBERD:
|
||||
return FEAT_WEAPON_PROFICIENCY_HALBERD;
|
||||
case BASE_ITEM_WARHAMMER:
|
||||
return FEAT_WEAPON_PROFICIENCY_WARHAMMER;
|
||||
|
||||
case BASE_ITEM_SHORTBOW:
|
||||
case BASE_ITEM_LONGBOW:
|
||||
return FEAT_WEAPON_PROFICIENCY_LONGBOW;
|
||||
|
||||
case BASE_ITEM_LIGHTMACE:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
|
||||
|
||||
case BASE_ITEM_HALBERD:
|
||||
return FEAT_WEAPON_PROFICIENCY_HALBERD;
|
||||
|
||||
case BASE_ITEM_SHORTBOW:
|
||||
return FEAT_WEAPON_PROFICIENCY_SHORTBOW;
|
||||
|
||||
case BASE_ITEM_TWOBLADEDSWORD:
|
||||
case BASE_ITEM_TWOBLADEDSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD;
|
||||
|
||||
case BASE_ITEM_GREATSWORD:
|
||||
case BASE_ITEM_GREATSWORD:
|
||||
return FEAT_WEAPON_PROFICIENCY_GREATSWORD;
|
||||
|
||||
case BASE_ITEM_GREATAXE:
|
||||
case BASE_ITEM_GREATAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_GREATAXE;
|
||||
|
||||
case BASE_ITEM_DART:
|
||||
case BASE_ITEM_DART:
|
||||
return FEAT_WEAPON_PROFICIENCY_DART;
|
||||
|
||||
case BASE_ITEM_DIREMACE:
|
||||
case BASE_ITEM_DIREMACE:
|
||||
return FEAT_WEAPON_PROFICIENCY_DIRE_MACE;
|
||||
|
||||
case BASE_ITEM_DOUBLEAXE:
|
||||
case BASE_ITEM_DOUBLEAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE;
|
||||
|
||||
case BASE_ITEM_HEAVYFLAIL:
|
||||
case BASE_ITEM_HEAVYFLAIL:
|
||||
return FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL;
|
||||
|
||||
case BASE_ITEM_LIGHTHAMMER:
|
||||
case BASE_ITEM_LIGHTHAMMER:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER;
|
||||
|
||||
case BASE_ITEM_HANDAXE:
|
||||
case BASE_ITEM_HANDAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_HANDAXE;
|
||||
|
||||
case BASE_ITEM_KAMA:
|
||||
case BASE_ITEM_KAMA:
|
||||
return FEAT_WEAPON_PROFICIENCY_KAMA;
|
||||
|
||||
case BASE_ITEM_KATANA:
|
||||
case BASE_ITEM_KATANA:
|
||||
return FEAT_WEAPON_PROFICIENCY_KATANA;
|
||||
|
||||
case BASE_ITEM_KUKRI:
|
||||
case BASE_ITEM_KUKRI:
|
||||
return FEAT_WEAPON_PROFICIENCY_KUKRI;
|
||||
|
||||
case BASE_ITEM_MORNINGSTAR:
|
||||
case BASE_ITEM_MORNINGSTAR:
|
||||
return FEAT_WEAPON_PROFICIENCY_MORNINGSTAR;
|
||||
|
||||
case BASE_ITEM_RAPIER:
|
||||
case BASE_ITEM_RAPIER:
|
||||
return FEAT_WEAPON_PROFICIENCY_RAPIER;
|
||||
|
||||
case BASE_ITEM_SCIMITAR:
|
||||
case BASE_ITEM_SCIMITAR:
|
||||
return FEAT_WEAPON_PROFICIENCY_SCIMITAR;
|
||||
|
||||
case BASE_ITEM_SCYTHE:
|
||||
case BASE_ITEM_SCYTHE:
|
||||
return FEAT_WEAPON_PROFICIENCY_SCYTHE;
|
||||
|
||||
case BASE_ITEM_SHORTSPEAR:
|
||||
case BASE_ITEM_SHORTSPEAR:
|
||||
return FEAT_WEAPON_PROFICIENCY_SHORTSPEAR;
|
||||
|
||||
case BASE_ITEM_SHURIKEN:
|
||||
case BASE_ITEM_SHURIKEN:
|
||||
return FEAT_WEAPON_PROFICIENCY_SHURIKEN;
|
||||
|
||||
case BASE_ITEM_SICKLE:
|
||||
case BASE_ITEM_SICKLE:
|
||||
return FEAT_WEAPON_PROFICIENCY_SICKLE;
|
||||
|
||||
case BASE_ITEM_SLING:
|
||||
case BASE_ITEM_SLING:
|
||||
return FEAT_WEAPON_PROFICIENCY_SLING;
|
||||
|
||||
case BASE_ITEM_THROWINGAXE:
|
||||
case BASE_ITEM_THROWINGAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_THROWING_AXE;
|
||||
|
||||
case BASE_ITEM_CSLASHWEAPON:
|
||||
case BASE_ITEM_CSLASHWEAPON:
|
||||
return FEAT_WEAPON_PROFICIENCY_CREATURE;
|
||||
|
||||
case BASE_ITEM_CPIERCWEAPON:
|
||||
case BASE_ITEM_CPIERCWEAPON:
|
||||
return FEAT_WEAPON_PROFICIENCY_CREATURE;
|
||||
|
||||
case BASE_ITEM_CBLUDGWEAPON:
|
||||
case BASE_ITEM_CBLUDGWEAPON:
|
||||
return FEAT_WEAPON_PROFICIENCY_CREATURE;
|
||||
|
||||
case BASE_ITEM_CSLSHPRCWEAP:
|
||||
case BASE_ITEM_CSLSHPRCWEAP:
|
||||
return FEAT_WEAPON_PROFICIENCY_CREATURE;
|
||||
|
||||
case BASE_ITEM_TRIDENT:
|
||||
case BASE_ITEM_TRIDENT:
|
||||
return FEAT_WEAPON_PROFICIENCY_TRIDENT;
|
||||
|
||||
case BASE_ITEM_DWARVENWARAXE:
|
||||
case BASE_ITEM_DWARVENWARAXE:
|
||||
return FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE;
|
||||
|
||||
case BASE_ITEM_WHIP:
|
||||
case BASE_ITEM_WHIP:
|
||||
return FEAT_WEAPON_PROFICIENCY_WHIP;
|
||||
|
||||
case BASE_ITEM_ELVEN_LIGHTBLADE:
|
||||
case BASE_ITEM_ELVEN_LIGHTBLADE:
|
||||
return FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE;
|
||||
|
||||
case BASE_ITEM_ELVEN_THINBLADE:
|
||||
case BASE_ITEM_ELVEN_THINBLADE:
|
||||
return FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE;
|
||||
|
||||
case BASE_ITEM_ELVEN_COURTBLADE:
|
||||
case BASE_ITEM_ELVEN_COURTBLADE:
|
||||
return FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE;
|
||||
|
||||
case BASE_ITEM_HEAVY_PICK:
|
||||
case BASE_ITEM_HEAVY_PICK:
|
||||
return FEAT_WEAPON_PROFICIENCY_HEAVY_PICK;
|
||||
|
||||
case BASE_ITEM_LIGHT_PICK:
|
||||
case BASE_ITEM_LIGHT_PICK:
|
||||
return FEAT_WEAPON_PROFICIENCY_LIGHT_PICK;
|
||||
|
||||
case BASE_ITEM_SAI:
|
||||
case BASE_ITEM_SAI:
|
||||
return FEAT_WEAPON_PROFICIENCY_SAI;
|
||||
|
||||
case BASE_ITEM_NUNCHAKU:
|
||||
case BASE_ITEM_NUNCHAKU:
|
||||
return FEAT_WEAPON_PROFICIENCY_NUNCHAKU;
|
||||
|
||||
case BASE_ITEM_FALCHION:
|
||||
case BASE_ITEM_FALCHION:
|
||||
return FEAT_WEAPON_PROFICIENCY_FALCHION;
|
||||
|
||||
case BASE_ITEM_SAP:
|
||||
case BASE_ITEM_SAP:
|
||||
return FEAT_WEAPON_PROFICIENCY_SAP;
|
||||
|
||||
case BASE_ITEM_KATAR:
|
||||
case BASE_ITEM_KATAR:
|
||||
return FEAT_WEAPON_PROFICIENCY_KATAR;
|
||||
|
||||
case BASE_ITEM_HEAVY_MACE:
|
||||
case BASE_ITEM_HEAVY_MACE:
|
||||
return FEAT_WEAPON_PROFICIENCY_HEAVY_MACE;
|
||||
|
||||
case BASE_ITEM_MAUL:
|
||||
case BASE_ITEM_MAUL:
|
||||
return FEAT_WEAPON_PROFICIENCY_MAUL;
|
||||
|
||||
case BASE_ITEM_DOUBLE_SCIMITAR:
|
||||
case BASE_ITEM_DOUBLE_SCIMITAR:
|
||||
return FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR;
|
||||
|
||||
case BASE_ITEM_GOAD:
|
||||
case BASE_ITEM_GOAD:
|
||||
return FEAT_WEAPON_PROFICIENCY_GOAD;
|
||||
|
||||
case BASE_ITEM_EAGLE_CLAW:
|
||||
case BASE_ITEM_EAGLE_CLAW:
|
||||
return FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW;
|
||||
|
||||
default:
|
||||
return FEAT_WEAPON_PROFICIENCY_SIMPLE;
|
||||
default:
|
||||
return FEAT_WEAPON_PROFICIENCY_SIMPLE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -720,6 +876,7 @@ int IsMeleeWeapon(int nBaseItemType)
|
||||
case BASE_ITEM_CLOAK:
|
||||
case BASE_ITEM_CRAFTED_ROD:
|
||||
case BASE_ITEM_CRAFTED_STAFF:
|
||||
case BASE_ITEM_CRAFTED_SCEPTER:
|
||||
case BASE_ITEM_CRAFTMATERIALMED:
|
||||
case BASE_ITEM_CRAFTMATERIALSML:
|
||||
case BASE_ITEM_CREATUREITEM:
|
||||
|
||||
@@ -262,7 +262,7 @@ const int IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE = 4638;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_PICK = 4639;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_PICK = 4640;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_SAI = 4641;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_NUNCHUKU = 4642;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_NUNCHAKU = 4642;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_FALCHION = 4643;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_SAP = 4644;
|
||||
const int IP_CONST_FEAT_WEAPON_PROFICIENCY_KATAR = 4645;
|
||||
@@ -1206,11 +1206,12 @@ const int IP_CONST_FEAT_REGENERATION_5 = 24820;
|
||||
const int IP_CONST_FEAT_SCENT = 24821;
|
||||
const int IP_CONST_FEAT_GIANT_RACIAL_TYPE = 24822;
|
||||
|
||||
const int IP_CONST_FEAT_TEMPLATE_ARCHLICH_MARKER = 16401; //:: Archlich
|
||||
const int IP_CONST_FEAT_TEMPLATE_TURN_UNDEAD = 16402;
|
||||
const int IP_CONST_FEAT_TEMPLATE_PROJECTION = 24823;
|
||||
const int IP_CONST_FEAT_TEMPLATE_END_PROJECTION = 24824;
|
||||
const int IP_CONST_FEAT_TEMPLATE_ANIMATE_DEAD = 24825;
|
||||
const int IP_CONST_FEAT_TEMPLATE_ARCHLICH_MARKER = 16401; //:: Archlich
|
||||
const int IP_CONST_FEAT_TEMPLATE_TURN_UNDEAD = 16402;
|
||||
const int IP_CONST_FEAT_TEMPLATE_BAELNORN_MARKER = 16409; //:: Baelnorn
|
||||
const int IP_CONST_FEAT_TEMPLATE_PROJECTION = 24823;
|
||||
const int IP_CONST_FEAT_TEMPLATE_END_PROJECTION = 24824;
|
||||
const int IP_CONST_FEAT_TEMPLATE_ANIMATE_DEAD = 24825;
|
||||
const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_BLESS = 16403; //:: Saint
|
||||
//const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_GUIDANCE = 16404;
|
||||
const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_RESISTANCE = 16405;
|
||||
|
||||
@@ -29,6 +29,10 @@ const int BASE_ITEM_CRAFTED_STAFF = 201;
|
||||
const int BASE_ITEM_ELVEN_LIGHTBLADE = 202;
|
||||
const int BASE_ITEM_ELVEN_THINBLADE = 203;
|
||||
const int BASE_ITEM_ELVEN_COURTBLADE = 204;
|
||||
const int BASE_ITEM_CRAFTED_SCEPTER = 249;
|
||||
const int BASE_ITEM_CRAFTED_VIAL = 250;
|
||||
const int BASE_ITEM_MUNDANE_HERB = 252;
|
||||
const int BASE_ITEM_INFUSED_HERB = 253;
|
||||
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Player Health Const
|
||||
|
||||
615
src/include/prc_nui_com_inc.nss
Normal file
615
src/include/prc_nui_com_inc.nss
Normal file
@@ -0,0 +1,615 @@
|
||||
#include "prc_nui_consts"
|
||||
#include "inc_newspellbook"
|
||||
#include "psi_inc_psifunc"
|
||||
#include "inc_lookups"
|
||||
#include "nw_inc_nui"
|
||||
#include "tob_inc_tobfunc"
|
||||
|
||||
//
|
||||
// GetCurrentSpellLevel
|
||||
// Gets the current spell level the class can achieve at the current
|
||||
// caster level (ranging from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
// nLevel:int the caster level
|
||||
//
|
||||
// Returns:
|
||||
// int the circle the class can achieve currently
|
||||
//
|
||||
int GetCurrentSpellLevel(int nClass, int nLevel);
|
||||
|
||||
//
|
||||
// GetMaxSpellLevel
|
||||
// Gets the highest possible circle the class can achieve (from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the highest circle that can be achieved
|
||||
//
|
||||
int GetMaxSpellLevel(int nClass);
|
||||
|
||||
//
|
||||
// GetMinSpellLevel
|
||||
// Gets the lowest possible circle the class can achieve (from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the lowest circle that can be achieved
|
||||
//
|
||||
int GetMinSpellLevel(int nClass);
|
||||
|
||||
//
|
||||
// GetHighestLevelPossibleInClass
|
||||
// Given a class Id this will determine what the max level of a class can be
|
||||
// achieved
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the highest possible level the class can achieve
|
||||
//
|
||||
int GetHighestLevelPossibleInClass(int nClass);
|
||||
|
||||
//
|
||||
// GetClassSpellbookFile
|
||||
// Gets the class 2da spellbook/ability for the given class Id
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the classID
|
||||
//
|
||||
// Returns:
|
||||
// string the 2da file name for the spell/abilities of the ClassID
|
||||
//
|
||||
string GetClassSpellbookFile(int nClass);
|
||||
|
||||
//
|
||||
// GetBinderSpellToFeatDictionary
|
||||
// Sets up the Binder Spell Dictionary that is used to match a binder's vestige
|
||||
// to their feat. This is constructed based off the binder's known location of
|
||||
// their feat and spell ranges in the base 2das respectivly. After constructing
|
||||
// this it will be saved to the player locally as a cached result since we do
|
||||
// not need to call this again.
|
||||
//
|
||||
// Argument:
|
||||
// oPlayer:object the player
|
||||
//
|
||||
// Returns:
|
||||
// json:Dictionary<String,Int> a dictionary of mapping between the SpellID
|
||||
// and the FeatID of a vestige ability
|
||||
//
|
||||
json GetBinderSpellToFeatDictionary(object oPlayer=OBJECT_SELF);
|
||||
|
||||
//
|
||||
// GetSpellLevelIcon
|
||||
// Takes the spell circle int and gets the icon appropriate for it (i.e. 0 turns
|
||||
// into "ir_cantrips"
|
||||
//
|
||||
// Arguments:
|
||||
// spellLevel:int the spell level we want the icon for
|
||||
//
|
||||
// Returns:
|
||||
// string the spell level icon
|
||||
//
|
||||
string GetSpellLevelIcon(int spellLevel);
|
||||
|
||||
//
|
||||
// GetSpellLevelToolTip
|
||||
// Gets the spell level tool tip text based on the int spell level provided (i.e.
|
||||
// 0 turns into "Cantrips")
|
||||
//
|
||||
// Arguments:
|
||||
// spellLevel:int the spell level we want the tooltip for
|
||||
//
|
||||
// Returns:
|
||||
// string the spell level toop tip
|
||||
//
|
||||
string GetSpellLevelToolTip(int spellLevel);
|
||||
|
||||
//
|
||||
// GetSpellIcon
|
||||
// Gets the spell icon based off the spellId, or featId supplied
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the class Id
|
||||
// featId:int the featId we can use the icon for
|
||||
// spellId:int the spell Id we want the icon for
|
||||
//
|
||||
// Returns:
|
||||
// json:String the string of the icon we want.
|
||||
//
|
||||
json GetSpellIcon(int spellId, int featId=0, int nClass=0);
|
||||
string GetSpellName(int spellId, int realSpellID=0, int featId=0, int nClass=0);
|
||||
|
||||
//
|
||||
// GreyOutButton
|
||||
// Takes NUI Button along with it's width and height and greys it out it with a drawn
|
||||
// colored rectangle to represent it's not been selected or not valid.
|
||||
//
|
||||
// Arguments:
|
||||
// jButton:json the NUI Button
|
||||
// w:float the width of the button
|
||||
// h:float the height of the button
|
||||
//
|
||||
// Returns:
|
||||
// json the NUI button greyed out
|
||||
//
|
||||
json GreyOutButton(json jButton, float w, float h);
|
||||
|
||||
//
|
||||
// CreateGreyOutRectangle
|
||||
// Creates a grey out rectangle for buttons
|
||||
//
|
||||
// Arguments:
|
||||
// w:float the width of the button
|
||||
// h:float the height of the button
|
||||
//
|
||||
// Returns:
|
||||
// json the transparant black rectangle
|
||||
//
|
||||
json CreateGreyOutRectangle(float w, float h);
|
||||
|
||||
//
|
||||
// GetTrueClassType
|
||||
// Gets the true class Id for a provided class Id, mostly for RHD and for
|
||||
// ToB prestige classes
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int classId
|
||||
//
|
||||
// Returns:
|
||||
// int the true classId based off nClass
|
||||
//
|
||||
int GetTrueClassType(int nClass, object oPC=OBJECT_SELF);
|
||||
|
||||
void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int realSpellId=0, int nClass=0);
|
||||
|
||||
void CallSpellUnlevelScript(object oPC, int nClass, int nLevel);
|
||||
void ClearSpellDescriptionNUI(object oPlayer=OBJECT_SELF);
|
||||
void RemoveIPFeat(object oPC, int ipFeatID);
|
||||
|
||||
void CallSpellUnlevelScript(object oPC, int nClass, int nLevel)
|
||||
{
|
||||
SetScriptParam("UnLevel_ClassChoice", IntToString(nClass));
|
||||
SetScriptParam("UnLevel_LevelChoice", IntToString(nLevel));
|
||||
ExecuteScript("prc_unlvl_script", oPC);
|
||||
}
|
||||
|
||||
void RemoveIPFeat(object oPC, int ipFeatID)
|
||||
{
|
||||
object oSkin = GetPCSkin(oPC);
|
||||
itemproperty ipTest = GetFirstItemProperty(oSkin);
|
||||
while(GetIsItemPropertyValid(ipTest))
|
||||
{
|
||||
// Check if the itemproperty is a bonus feat that has been marked for removal
|
||||
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_BONUS_FEAT)
|
||||
{
|
||||
if (GetItemPropertySubType(ipTest) == ipFeatID)
|
||||
{
|
||||
if(DEBUG) DoDebug("_ManeuverRecurseRemoveArray(): Removing bonus feat itemproperty:\n" + DebugIProp2Str(ipTest));
|
||||
// If so, remove it
|
||||
RemoveItemProperty(oSkin, ipTest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ipTest = GetNextItemProperty(oSkin);
|
||||
}
|
||||
}
|
||||
|
||||
int GetCurrentSpellLevel(int nClass, int nLevel)
|
||||
{
|
||||
int currentLevel = nLevel;
|
||||
|
||||
// ToB doesn't have a concept of spell levels, but still match up to it
|
||||
if(nClass == CLASS_TYPE_WARBLADE
|
||||
|| nClass == CLASS_TYPE_SWORDSAGE
|
||||
|| nClass == CLASS_TYPE_CRUSADER
|
||||
|| nClass == CLASS_TYPE_SHADOWCASTER)
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
|
||||
// Binders don't really have a concept of spell level
|
||||
if (nClass == CLASS_TYPE_BINDER
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN) // they can only reach 1st circle
|
||||
return 1;
|
||||
|
||||
//Shadowsmith has no concept of spell levels
|
||||
if (nClass == CLASS_TYPE_SHADOWSMITH)
|
||||
return 2;
|
||||
|
||||
if (nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT)
|
||||
return 4;
|
||||
|
||||
// Spont casters have their own function
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
|
||||
int maxLevel = GetMaxSpellLevelForCasterLevel(nClass, currentLevel);
|
||||
return maxLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everyone else uses this
|
||||
string spellLevel2da = GetAMSKnownFileName(nClass);
|
||||
|
||||
currentLevel = nLevel - 1; // Level is 1 off of the row in the 2da
|
||||
|
||||
if (nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_PSION
|
||||
|| nClass == CLASS_TYPE_PSYWAR
|
||||
|| nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_WARMIND)
|
||||
currentLevel = GetManifesterLevel(OBJECT_SELF, nClass, TRUE) - 1;
|
||||
|
||||
int totalLevel = Get2DARowCount(spellLevel2da);
|
||||
|
||||
// in case we somehow go over bounds just don't :)
|
||||
if (currentLevel >= totalLevel)
|
||||
currentLevel = totalLevel - 1;
|
||||
|
||||
//Psionics have MaxPowerLevel as their column name
|
||||
string columnName = "MaxPowerLevel";
|
||||
|
||||
//Invokers have MaxInvocationLevel
|
||||
if (nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT)
|
||||
columnName = "MaxInvocationLevel";
|
||||
|
||||
// Truenamers have 3 sets of utterances, ranging from 1-6, EvolvingMind covers the entire range
|
||||
if (nClass == CLASS_TYPE_TRUENAMER)
|
||||
{
|
||||
columnName = "EvolvingMind";
|
||||
spellLevel2da = "cls_true_maxlvl"; //has a different 2da we want to look at
|
||||
}
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
columnName = "VestigeLvl";
|
||||
spellLevel2da = "cls_bind_binder";
|
||||
}
|
||||
|
||||
// ToB doesn't have a concept of this, but we don't care.
|
||||
|
||||
int maxLevel = StringToInt(Get2DACache(spellLevel2da, columnName, currentLevel));
|
||||
return maxLevel;
|
||||
}
|
||||
}
|
||||
|
||||
int GetMinSpellLevel(int nClass)
|
||||
{
|
||||
// again sponts have their own function
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
return GetMinSpellLevelForCasterLevel(nClass, GetHighestLevelPossibleInClass(nClass));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_PSION
|
||||
|| nClass == CLASS_TYPE_PSYWAR
|
||||
|| nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_WARMIND
|
||||
|| nClass == CLASS_TYPE_WARBLADE
|
||||
|| nClass == CLASS_TYPE_SWORDSAGE
|
||||
|| nClass == CLASS_TYPE_CRUSADER
|
||||
|| nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN
|
||||
|| nClass == CLASS_TYPE_SHADOWCASTER
|
||||
|| nClass == CLASS_TYPE_SHADOWSMITH
|
||||
|| nClass == CLASS_TYPE_BINDER)
|
||||
return 1;
|
||||
|
||||
return GetCurrentSpellLevel(nClass, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int GetMaxSpellLevel(int nClass)
|
||||
{
|
||||
if (nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSION)
|
||||
return 9;
|
||||
if (nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_WARMIND)
|
||||
return 5;
|
||||
if (nClass == CLASS_TYPE_PSYWAR)
|
||||
return 6;
|
||||
|
||||
return GetCurrentSpellLevel(nClass, GetHighestLevelPossibleInClass(nClass));
|
||||
}
|
||||
|
||||
int GetHighestLevelPossibleInClass(int nClass)
|
||||
{
|
||||
string sFile;
|
||||
|
||||
//sponts have their spells in the classes.2da
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
sFile = Get2DACache("classes", "SpellGainTable", nClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// everyone else uses this
|
||||
sFile = GetAMSKnownFileName(nClass);
|
||||
|
||||
if (nClass == CLASS_TYPE_TRUENAMER)
|
||||
{
|
||||
sFile = "cls_true_maxlvl"; //has a different 2da we want to look at
|
||||
}
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
sFile = "cls_bind_binder";
|
||||
}
|
||||
}
|
||||
|
||||
return Get2DARowCount(sFile);
|
||||
}
|
||||
|
||||
string GetClassSpellbookFile(int nClass)
|
||||
{
|
||||
string sFile;
|
||||
// Spontaneous casters use a specific file name structure
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
sFile = GetFileForClass(nClass);
|
||||
}
|
||||
// everyone else uses this structure
|
||||
else
|
||||
{
|
||||
sFile = GetAMSDefinitionFileName(nClass);
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
sFile = "vestiges";
|
||||
}
|
||||
}
|
||||
|
||||
return sFile;
|
||||
}
|
||||
|
||||
string GetSpellLevelIcon(int spellLevel)
|
||||
{
|
||||
switch (spellLevel)
|
||||
{
|
||||
case 0: return "ir_cantrips";
|
||||
case 1: return "ir_level1";
|
||||
case 2: return "ir_level2";
|
||||
case 3: return "ir_level3";
|
||||
case 4: return "ir_level4";
|
||||
case 5: return "ir_level5";
|
||||
case 6: return "ir_level6";
|
||||
case 7: return "ir_level789";
|
||||
case 8: return "ir_level789";
|
||||
case 9: return "ir_level789";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
string GetSpellLevelToolTip(int spellLevel)
|
||||
{
|
||||
switch (spellLevel)
|
||||
{
|
||||
case 0: return "Cantrips";
|
||||
case 1: return "Level 1";
|
||||
case 2: return "Level 2";
|
||||
case 3: return "Level 3";
|
||||
case 4: return "Level 4";
|
||||
case 5: return "Level 5";
|
||||
case 6: return "Level 6";
|
||||
case 7: return "Level 7";
|
||||
case 8: return "Level 8";
|
||||
case 9: return "Level 9";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
json GetSpellIcon(int spellId,int featId=0,int nClass=0)
|
||||
{
|
||||
// Binder's spells don't have the FeatID on the spells.2da, so we have to use
|
||||
// the mapping we constructed to get it.
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
json binderDict = GetBinderSpellToFeatDictionary();
|
||||
int nFeatID = JsonGetInt(JsonObjectGet(binderDict, IntToString(spellId)));
|
||||
return JsonString(Get2DACache("feat", "Icon", featId));
|
||||
}
|
||||
|
||||
if (featId)
|
||||
return JsonString(Get2DACache("feat", "Icon", featId));
|
||||
|
||||
int masterSpellID = StringToInt(Get2DACache("spells", "Master", spellId));
|
||||
|
||||
// if this is a sub radial spell, then we use spell's icon instead
|
||||
if (masterSpellID)
|
||||
return JsonString(Get2DACache("spells", "IconResRef", spellId));
|
||||
|
||||
// the FeatID holds the accurate spell icon, not the SpellID
|
||||
int nFeatID = StringToInt(Get2DACache("spells", "FeatID", spellId));
|
||||
// however if no featId was found use the spell's icon instead
|
||||
if (!nFeatID)
|
||||
return JsonString(Get2DACache("spells", "IconResRef", spellId));
|
||||
|
||||
return JsonString(Get2DACache("feat", "Icon", nFeatID));
|
||||
}
|
||||
|
||||
string GetSpellName(int spellId, int realSpellID=0, int featId=0, int nClass=0)
|
||||
{
|
||||
if ((nClass == CLASS_TYPE_SHADOWSMITH
|
||||
|| nClass == CLASS_TYPE_SHADOWCASTER) && spellId)
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellId)));
|
||||
if (nClass == CLASS_TYPE_TRUENAMER && featId)
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", featId)));
|
||||
if (realSpellID)
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", realSpellID)));
|
||||
if (spellId)
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellId)));
|
||||
if (featId)
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", featId)));
|
||||
|
||||
return GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellId)));
|
||||
}
|
||||
|
||||
json GetBinderSpellToFeatDictionary(object oPlayer=OBJECT_SELF)
|
||||
{
|
||||
// a dictionary of <SpellID, FeatID>
|
||||
json binderDict = GetLocalJson(oPlayer, NUI_SPELLBOOK_BINDER_DICTIONARY_CACHE_VAR);
|
||||
// if this hasn't been created, create it now.
|
||||
if (binderDict == JsonNull())
|
||||
binderDict = JsonObject();
|
||||
else
|
||||
return binderDict;
|
||||
|
||||
// the starting row for binder spells
|
||||
int spellIndex = 19070;
|
||||
// the starting row for binder feats
|
||||
int featIndex = 9030;
|
||||
//the end of the binder spells/feats
|
||||
while (spellIndex <= 19156 && featIndex <= 9104)
|
||||
{
|
||||
// get the SpellID tied to the feat
|
||||
int spellID = StringToInt(Get2DACache("feat", "SPELLID", featIndex));
|
||||
// if the spellID matches the current index, then this is the spell
|
||||
// attached to the feat
|
||||
if (spellID == spellIndex)
|
||||
{
|
||||
binderDict = JsonObjectSet(binderDict, IntToString(spellID), JsonInt(featIndex));
|
||||
|
||||
// move to next spell/feat
|
||||
featIndex++;
|
||||
spellIndex++;
|
||||
}
|
||||
// else we have reached a subdial spell
|
||||
else
|
||||
{
|
||||
// loop through until we reach back at spellID
|
||||
while (spellIndex < spellID)
|
||||
{
|
||||
int masterSpell = StringToInt(Get2DACache("spells", "Master", spellIndex));
|
||||
|
||||
// add the sub radial to the dict, tied to the master's FeatID
|
||||
int featId = JsonGetInt(JsonObjectGet(binderDict, IntToString(masterSpell)));
|
||||
binderDict = JsonObjectSet(binderDict, IntToString(spellIndex), JsonInt(featId));
|
||||
|
||||
spellIndex++;
|
||||
}
|
||||
|
||||
|
||||
// some feats overlap the same FeatID, can cause this to get stuck.
|
||||
// if it happens then move on
|
||||
if (spellIndex > spellID)
|
||||
featIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// cache the result
|
||||
SetLocalJson(oPlayer, NUI_SPELLBOOK_BINDER_DICTIONARY_CACHE_VAR, binderDict);
|
||||
return binderDict;
|
||||
}
|
||||
|
||||
json GreyOutButton(json jButton, float w, float h)
|
||||
{
|
||||
json retValue = jButton;
|
||||
|
||||
json jBorders = JsonArray();
|
||||
jBorders = JsonArrayInsert(jBorders, CreateGreyOutRectangle(w, h));
|
||||
|
||||
return NuiDrawList(jButton, JsonBool(FALSE), jBorders);
|
||||
}
|
||||
|
||||
json CreateGreyOutRectangle(float w, float h)
|
||||
{
|
||||
// set the points of the button shape
|
||||
json jPoints = JsonArray();
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(h));
|
||||
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(w));
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(h));
|
||||
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(w));
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
jPoints = JsonArrayInsert(jPoints, JsonFloat(0.0));
|
||||
|
||||
return NuiDrawListPolyLine(JsonBool(TRUE), NuiColor(0, 0, 0, 127), JsonBool(TRUE), JsonFloat(2.0), jPoints);
|
||||
}
|
||||
|
||||
void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int realSpellId=0, int nClass=0)
|
||||
{
|
||||
SetLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_FEATID_VAR, featID);
|
||||
SetLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_SPELLID_VAR, spellId);
|
||||
SetLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_REAL_SPELLID_VAR, realSpellId);
|
||||
SetLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_CLASSID_VAR, nClass);
|
||||
ExecuteScript("prc_nui_dsc_view", oPlayer);
|
||||
}
|
||||
|
||||
void ClearSpellDescriptionNUI(object oPlayer=OBJECT_SELF)
|
||||
{
|
||||
DeleteLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_FEATID_VAR);
|
||||
DeleteLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_SPELLID_VAR);
|
||||
DeleteLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_REAL_SPELLID_VAR);
|
||||
DeleteLocalInt(oPlayer, NUI_SPELL_DESCRIPTION_CLASSID_VAR);
|
||||
}
|
||||
|
||||
int GetTrueClassType(int nClass, object oPC=OBJECT_SELF)
|
||||
{
|
||||
if (nClass == CLASS_TYPE_JADE_PHOENIX_MAGE
|
||||
|| nClass == CLASS_TYPE_MASTER_OF_NINE
|
||||
|| nClass == CLASS_TYPE_DEEPSTONE_SENTINEL
|
||||
|| nClass == CLASS_TYPE_BLOODCLAW_MASTER
|
||||
|| nClass == CLASS_TYPE_RUBY_VINDICATOR
|
||||
|| nClass == CLASS_TYPE_ETERNAL_BLADE
|
||||
|| nClass == CLASS_TYPE_SHADOW_SUN_NINJA)
|
||||
{
|
||||
int trueClass = GetPrimaryBladeMagicClass(oPC);
|
||||
return trueClass;
|
||||
}
|
||||
|
||||
if ((nClass == CLASS_TYPE_SHAPECHANGER
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_ARANEA)
|
||||
|| (nClass == CLASS_TYPE_OUTSIDER
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_RAKSHASA)
|
||||
|| (nClass == CLASS_TYPE_ABERRATION
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_DRIDER)
|
||||
|| (nClass == CLASS_TYPE_MONSTROUS
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_ARKAMOI)
|
||||
|| (nClass == CLASS_TYPE_MONSTROUS
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
|
||||
|| (nClass == CLASS_TYPE_MONSTROUS
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_REDSPAWN_ARCANISS)
|
||||
|| (nClass == CLASS_TYPE_MONSTROUS
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_MARRUTACT))
|
||||
return CLASS_TYPE_SORCERER;
|
||||
if (nClass == CLASS_TYPE_FEY
|
||||
&& GetRacialType(oPC) == RACIAL_TYPE_GLOURA)
|
||||
return CLASS_TYPE_BARD;
|
||||
|
||||
return nClass;
|
||||
}
|
||||
|
||||
@@ -110,4 +110,62 @@ const string NUI_PRC_PA_TEXT_BIND = "nui_prc_pa_text_bind";
|
||||
// Left Button Enabled Bind for Power Attack NUI
|
||||
const string NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND = "leftButtonEnabled";
|
||||
// Right Button Enabled Bind for Power Attack NUI
|
||||
const string NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND = "rightButtonEnabled";
|
||||
const string NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND = "rightButtonEnabled";
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// //
|
||||
// NUI Level Up //
|
||||
// //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
const string NUI_LEVEL_UP_WINDOW_ID = "prcLevelUpNui";
|
||||
|
||||
const string NUI_LEVEL_UP_SPELL_CIRCLE_BUTTON_BASEID = "NuiLevelUpCircleButton_";
|
||||
const string NUI_LEVEL_UP_SPELL_BUTTON_BASEID = "NuiLevelUpSpellButton_";
|
||||
const string NUI_LEVEL_UP_SPELL_DISABLED_BUTTON_BASEID = "NuiLevelUpDisabledSpellButton_";
|
||||
const string NUI_LEVEL_UP_SPELL_CHOSEN_BUTTON_BASEID = "NuiLevelUpChosenSpellButton_";
|
||||
const string NUI_LEVEL_UP_SPELL_CHOSEN_DISABLED_BUTTON_BASEID = "NuiLevelUpDisabledChosenSpellButton_";
|
||||
const string NUI_LEVEL_UP_DONE_BUTTON = "NuiLevelUpDoneButton";
|
||||
const string NUI_LEVEL_UP_RESET_BUTTON = "NuiLevelUpResetButton";
|
||||
|
||||
const string NUI_LEVEL_UP_SELECTED_CLASS_VAR = "NUILevelUpSelectedClass";
|
||||
const string NUI_LEVEL_UP_SELECTED_CIRCLE_VAR = "NUILevelUpSelectedCircle";
|
||||
const string NUI_LEVEL_UP_KNOWN_SPELLS_VAR = "NUILevelUpKnownSpells";
|
||||
const string NUI_LEVEL_UP_CHOSEN_SPELLS_VAR = "NUILevelUpChosenSpells";
|
||||
const string NUI_LEVEL_UP_EXPANDED_KNOW_LIST_VAR = "NUILevelUpExpKnowList";
|
||||
const string NUI_LEVEL_UP_POWER_LIST_VAR = "NUILevelUpPowerList";
|
||||
const string NUI_LEVEL_UP_DISCIPLINE_INFO_VAR = "GetDisciplineInfoObjectCache_";
|
||||
const string NUI_LEVEL_UP_SPELLID_LIST_VAR = "NUILevelUpSpellIDList_";
|
||||
const string NUI_LEVEL_UP_REMAINING_CHOICES_CACHE_VAR = "NUIRemainingChoicesCache";
|
||||
const string NUI_LEVEL_UP_RELEARN_LIST_VAR = "NUILevelUpRelearnList";
|
||||
const string NUI_LEVEL_UP_ARCHIVIST_NEW_SPELLS_LIST_VAR = "NUILevelUpArchivistNewSpellsList";
|
||||
|
||||
const string NUI_LEVEL_UP_EXPANDED_CHOICES_VAR = "NUIExpandedChoices";
|
||||
const string NUI_LEVEL_UP_EPIC_EXPANDED_CHOICES_VAR = "NUIEpicExpandedChoices";
|
||||
|
||||
const int NUI_LEVEL_UP_MANEUVER_PREREQ_LIMIT = 6;
|
||||
|
||||
const string NUI_LEVEL_UP_MANEUVER_TOTAL = "ManeuverTotal";
|
||||
const string NUI_LEVEL_UP_STANCE_TOTAL = "StanceTotal";
|
||||
|
||||
const string NUI_LEVEL_UP_SPELLBOOK_OBJECT_CACHE_VAR = "GetSpellListObjectCache_";
|
||||
const string NUI_LEVEL_UP_KNOWN_INVOCATIONS_CACHE_VAR = "GetInvokerKnownListObjectCache_";
|
||||
|
||||
const string NUI_SPELL_DESCRIPTION_FEATID_VAR = "NUISpellDescriptionFeatID";
|
||||
const string NUI_SPELL_DESCRIPTION_CLASSID_VAR = "NUISpellDescriptionClassID";
|
||||
const string NUI_SPELL_DESCRIPTION_SPELLID_VAR = "NUISpellDescriptionSpellID";
|
||||
const string NUI_SPELL_DESCRIPTION_REAL_SPELLID_VAR = "NUISpellDescriptionRealSpellID";
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// //
|
||||
// Spell Duration NUI //
|
||||
// //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
const string DURATION_NUI_WINDOW_ID = "DurationNUI";
|
||||
const string NUI_DURATION_MANUALLY_OPENED_PARAM = "DurationNUIManuallyOpenedParam";
|
||||
const string NUI_DURATION_NO_LOOP_PARAM = "DurationNUINoLoopParam";
|
||||
const string NUI_DURATION_TRACKED_SPELLS = "durationNUI_trackedSpellList";
|
||||
const string NUI_SPELL_DURATION_BASE_BIND = "durationNUI_durationSpellId";
|
||||
const string NUI_SPELL_DURATION_SPELLID_BASE_CANCEL_BUTTON = "NuiDurationCancelButtonSpellID";
|
||||
|
||||
3316
src/include/prc_nui_lv_inc.nss
Normal file
3316
src/include/prc_nui_lv_inc.nss
Normal file
File diff suppressed because it is too large
Load Diff
@@ -10,10 +10,8 @@
|
||||
//:: Created By: Rakiov
|
||||
//:: Created On: 24.05.2005
|
||||
//:://////////////////////////////////////////////
|
||||
#include "inc_newspellbook"
|
||||
#include "psi_inc_psifunc"
|
||||
#include "inc_lookups"
|
||||
#include "prc_nui_consts"
|
||||
|
||||
#include "prc_nui_com_inc"
|
||||
|
||||
//
|
||||
// GetSpellListForCircle
|
||||
@@ -43,69 +41,6 @@ json GetSpellListForCircle(object oPlayer, int nClass, int circle);
|
||||
//
|
||||
json GetSupportedNUISpellbookClasses(object oPlayer);
|
||||
|
||||
//
|
||||
// GetCurrentSpellLevel
|
||||
// Gets the current spell level the class can achieve at the current
|
||||
// caster level (ranging from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
// nLevel:int the caster level
|
||||
//
|
||||
// Returns:
|
||||
// int the circle the class can achieve currently
|
||||
//
|
||||
int GetCurrentSpellLevel(int nClass, int nLevel);
|
||||
|
||||
//
|
||||
// GetMaxSpellLevel
|
||||
// Gets the highest possible circle the class can achieve (from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the highest circle that can be achieved
|
||||
//
|
||||
int GetMaxSpellLevel(int nClass);
|
||||
|
||||
//
|
||||
// GetMinSpellLevel
|
||||
// Gets the lowest possible circle the class can achieve (from 0-9)
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the lowest circle that can be achieved
|
||||
//
|
||||
int GetMinSpellLevel(int nClass);
|
||||
|
||||
//
|
||||
// GetHighestLevelPossibleInClass
|
||||
// Given a class Id this will determine what the max level of a class can be
|
||||
// achieved
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the ClassID
|
||||
//
|
||||
// Returns:
|
||||
// int the highest possible level the class can achieve
|
||||
//
|
||||
int GetHighestLevelPossibleInClass(int nClass);
|
||||
|
||||
//
|
||||
// GetClassSpellbookFile
|
||||
// Gets the class 2da spellbook/ability for the given class Id
|
||||
//
|
||||
// Arguments:
|
||||
// nClass:int the classID
|
||||
//
|
||||
// Returns:
|
||||
// string the 2da file name for the spell/abilities of the ClassID
|
||||
//
|
||||
string GetClassSpellbookFile(int nClass);
|
||||
|
||||
//
|
||||
// IsSpellKnown
|
||||
// Returns whether the player with the given class, spell file, and spellbook id
|
||||
@@ -234,23 +169,6 @@ json GetMetaMysteryFeatList();
|
||||
//
|
||||
int GetTrueClassIfRHD(object oPlayer, int nClass);
|
||||
|
||||
//
|
||||
// GetBinderSpellToFeatDictionary
|
||||
// Sets up the Binder Spell Dictionary that is used to match a binder's vestige
|
||||
// to their feat. This is constructed based off the binder's known location of
|
||||
// their feat and spell ranges in the base 2das respectivly. After constructing
|
||||
// this it will be saved to the player locally as a cached result since we do
|
||||
// not need to call this again.
|
||||
//
|
||||
// Argument:
|
||||
// oPlayer:object the player
|
||||
//
|
||||
// Returns:
|
||||
// json:Dictionary<String,Int> a dictionary of mapping between the SpellID
|
||||
// and the FeatID of a vestige ability
|
||||
//
|
||||
json GetBinderSpellToFeatDictionary(object oPlayer=OBJECT_SELF);
|
||||
|
||||
//
|
||||
// ShouldAddSpell
|
||||
// Given a spellId and a class, determines if the spell should be added to the
|
||||
@@ -318,6 +236,18 @@ json GetInvokerEssenceSpellList(int nClass, object oPlayer=OBJECT_SELF);
|
||||
//
|
||||
int JsonArrayContainsInt(json list, int item);
|
||||
|
||||
//
|
||||
// IsSpellbookNUIOpen
|
||||
// Checks to see if the Spellbook NUI is open on a given player.
|
||||
//
|
||||
// Arguments:
|
||||
// oPC:object the player
|
||||
//
|
||||
// Returns:
|
||||
// int:Boolean TRUE if window is open, FALSE otherwise
|
||||
//
|
||||
int IsSpellbookNUIOpen(object oPC);
|
||||
|
||||
json GetSpellListForCircle(object oPlayer, int nClass, int circle)
|
||||
{
|
||||
json retValue = JsonArray();
|
||||
@@ -397,86 +327,6 @@ int ShouldAddSpell(int nClass, int spellId, object oPlayer=OBJECT_SELF)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
json GetBinderSpellToFeatDictionary(object oPlayer=OBJECT_SELF)
|
||||
{
|
||||
// a dictionary of <SpellID, FeatID>
|
||||
json binderDict = GetLocalJson(oPlayer, NUI_SPELLBOOK_BINDER_DICTIONARY_CACHE_VAR);
|
||||
// if this hasn't been created, create it now.
|
||||
if (binderDict == JsonNull())
|
||||
binderDict = JsonObject();
|
||||
else
|
||||
return binderDict;
|
||||
|
||||
// the starting row for binder spells
|
||||
int spellIndex = 19070;
|
||||
// the starting row for binder feats
|
||||
int featIndex = 9030;
|
||||
//the end of the binder spells/feats
|
||||
while (spellIndex <= 19156 && featIndex <= 9104)
|
||||
{
|
||||
// get the SpellID tied to the feat
|
||||
int spellID = StringToInt(Get2DACache("feat", "SPELLID", featIndex));
|
||||
// if the spellID matches the current index, then this is the spell
|
||||
// attached to the feat
|
||||
if (spellID == spellIndex)
|
||||
{
|
||||
binderDict = JsonObjectSet(binderDict, IntToString(spellID), JsonInt(featIndex));
|
||||
|
||||
// move to next spell/feat
|
||||
featIndex++;
|
||||
spellIndex++;
|
||||
}
|
||||
// else we have reached a subdial spell
|
||||
else
|
||||
{
|
||||
// loop through until we reach back at spellID
|
||||
while (spellIndex < spellID)
|
||||
{
|
||||
int masterSpell = StringToInt(Get2DACache("spells", "Master", spellIndex));
|
||||
|
||||
// add the sub radial to the dict, tied to the master's FeatID
|
||||
int featId = JsonGetInt(JsonObjectGet(binderDict, IntToString(masterSpell)));
|
||||
binderDict = JsonObjectSet(binderDict, IntToString(spellIndex), JsonInt(featId));
|
||||
|
||||
spellIndex++;
|
||||
}
|
||||
|
||||
|
||||
// some feats overlap the same FeatID, can cause this to get stuck.
|
||||
// if it happens then move on
|
||||
if (spellIndex > spellID)
|
||||
featIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// cache the result
|
||||
SetLocalJson(oPlayer, NUI_SPELLBOOK_BINDER_DICTIONARY_CACHE_VAR, binderDict);
|
||||
return binderDict;
|
||||
}
|
||||
|
||||
string GetClassSpellbookFile(int nClass)
|
||||
{
|
||||
string sFile;
|
||||
// Spontaneous casters use a specific file name structure
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
sFile = GetFileForClass(nClass);
|
||||
}
|
||||
// everyone else uses this structure
|
||||
else
|
||||
{
|
||||
sFile = GetAMSDefinitionFileName(nClass);
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
sFile = "vestiges";
|
||||
}
|
||||
}
|
||||
|
||||
return sFile;
|
||||
}
|
||||
|
||||
json GetSupportedNUISpellbookClasses(object oPlayer)
|
||||
{
|
||||
json retValue = JsonArray();
|
||||
@@ -526,167 +376,6 @@ int IsSpellKnown(object oPlayer, int nClass, int spellId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GetCurrentSpellLevel(int nClass, int nLevel)
|
||||
{
|
||||
int currentLevel = nLevel;
|
||||
|
||||
// ToB doesn't have a concept of spell levels, but still match up to it
|
||||
if(nClass == CLASS_TYPE_WARBLADE
|
||||
|| nClass == CLASS_TYPE_SWORDSAGE
|
||||
|| nClass == CLASS_TYPE_CRUSADER
|
||||
|| nClass == CLASS_TYPE_SHADOWCASTER)
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
|
||||
// Binders don't really have a concept of spell level
|
||||
if (nClass == CLASS_TYPE_BINDER
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN) // they can only reach 1st circle
|
||||
return 1;
|
||||
|
||||
//Shadowsmith has no concept of spell levels
|
||||
if (nClass == CLASS_TYPE_SHADOWSMITH)
|
||||
return 2;
|
||||
|
||||
if (nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT)
|
||||
return 4;
|
||||
|
||||
// Spont casters have their own function
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
|
||||
int maxLevel = GetMaxSpellLevelForCasterLevel(nClass, currentLevel);
|
||||
return maxLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everyone else uses this
|
||||
string spellLevel2da = GetAMSKnownFileName(nClass);
|
||||
|
||||
currentLevel = nLevel - 1; // Level is 1 off of the row in the 2da
|
||||
|
||||
if (nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_PSION
|
||||
|| nClass == CLASS_TYPE_PSYWAR
|
||||
|| nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_WARMIND)
|
||||
currentLevel = GetManifesterLevel(OBJECT_SELF, nClass, TRUE) - 1;
|
||||
|
||||
int totalLevel = Get2DARowCount(spellLevel2da);
|
||||
|
||||
// in case we somehow go over bounds just don't :)
|
||||
if (currentLevel >= totalLevel)
|
||||
currentLevel = totalLevel - 1;
|
||||
|
||||
//Psionics have MaxPowerLevel as their column name
|
||||
string columnName = "MaxPowerLevel";
|
||||
|
||||
//Invokers have MaxInvocationLevel
|
||||
if (nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT)
|
||||
columnName = "MaxInvocationLevel";
|
||||
|
||||
// Truenamers have 3 sets of utterances, ranging from 1-6, EvolvingMind covers the entire range
|
||||
if (nClass == CLASS_TYPE_TRUENAMER)
|
||||
{
|
||||
columnName = "EvolvingMind";
|
||||
spellLevel2da = "cls_true_maxlvl"; //has a different 2da we want to look at
|
||||
}
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
columnName = "VestigeLvl";
|
||||
spellLevel2da = "cls_bind_binder";
|
||||
}
|
||||
|
||||
// ToB doesn't have a concept of this, but we don't care.
|
||||
|
||||
int maxLevel = StringToInt(Get2DACache(spellLevel2da, columnName, currentLevel));
|
||||
return maxLevel;
|
||||
}
|
||||
}
|
||||
|
||||
int GetMinSpellLevel(int nClass)
|
||||
{
|
||||
// again sponts have their own function
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
return GetMinSpellLevelForCasterLevel(nClass, GetHighestLevelPossibleInClass(nClass));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_PSION
|
||||
|| nClass == CLASS_TYPE_PSYWAR
|
||||
|| nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_WARMIND
|
||||
|| nClass == CLASS_TYPE_WARBLADE
|
||||
|| nClass == CLASS_TYPE_SWORDSAGE
|
||||
|| nClass == CLASS_TYPE_CRUSADER
|
||||
|| nClass == CLASS_TYPE_WARLOCK
|
||||
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT
|
||||
|| nClass == CLASS_TYPE_DRAGON_SHAMAN
|
||||
|| nClass == CLASS_TYPE_SHADOWCASTER
|
||||
|| nClass == CLASS_TYPE_SHADOWSMITH
|
||||
|| nClass == CLASS_TYPE_BINDER)
|
||||
return 1;
|
||||
|
||||
return GetCurrentSpellLevel(nClass, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int GetMaxSpellLevel(int nClass)
|
||||
{
|
||||
if (nClass == CLASS_TYPE_WILDER
|
||||
|| nClass == CLASS_TYPE_PSION)
|
||||
return 9;
|
||||
if (nClass == CLASS_TYPE_PSYCHIC_ROGUE
|
||||
|| nClass == CLASS_TYPE_FIST_OF_ZUOKEN
|
||||
|| nClass == CLASS_TYPE_WARMIND)
|
||||
return 5;
|
||||
if (nClass == CLASS_TYPE_PSYWAR)
|
||||
return 6;
|
||||
|
||||
return GetCurrentSpellLevel(nClass, GetHighestLevelPossibleInClass(nClass));
|
||||
}
|
||||
|
||||
int GetHighestLevelPossibleInClass(int nClass)
|
||||
{
|
||||
string sFile;
|
||||
|
||||
//sponts have their spells in the classes.2da
|
||||
if(GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_SPONTANEOUS
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST)
|
||||
{
|
||||
sFile = Get2DACache("classes", "SpellGainTable", nClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// everyone else uses this
|
||||
sFile = GetAMSKnownFileName(nClass);
|
||||
|
||||
if (nClass == CLASS_TYPE_TRUENAMER)
|
||||
{
|
||||
sFile = "cls_true_maxlvl"; //has a different 2da we want to look at
|
||||
}
|
||||
|
||||
if (nClass == CLASS_TYPE_BINDER)
|
||||
{
|
||||
sFile = "cls_bind_binder";
|
||||
}
|
||||
}
|
||||
|
||||
return Get2DARowCount(sFile);
|
||||
}
|
||||
|
||||
int IsClassAllowedToUseNUISpellbook(object oPlayer, int nClass)
|
||||
{
|
||||
// This controls who can use the Spellbook NUI, if for some reason you don't
|
||||
@@ -698,8 +387,7 @@ int IsClassAllowedToUseNUISpellbook(object oPlayer, int nClass)
|
||||
return TRUE;
|
||||
|
||||
// Arcane Spont
|
||||
if (nClass == CLASS_TYPE_ASSASSIN
|
||||
|| nClass == CLASS_TYPE_BEGUILER
|
||||
if (nClass == CLASS_TYPE_BEGUILER
|
||||
|| nClass == CLASS_TYPE_CELEBRANT_SHARESS
|
||||
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
|
||||
|| nClass == CLASS_TYPE_DUSKBLADE
|
||||
@@ -817,8 +505,7 @@ int CanClassUseMetamagicFeats(int nClass)
|
||||
// I don't want to spend the time looping through each class's
|
||||
// feat 2da so this is the list of all classes that are allowed to use the
|
||||
// Spellbook NUI and can use Metamagic
|
||||
return (nClass == CLASS_TYPE_ASSASSIN
|
||||
|| nClass == CLASS_TYPE_BARD
|
||||
return (nClass == CLASS_TYPE_BARD
|
||||
|| nClass == CLASS_TYPE_SORCERER
|
||||
|| nClass == CLASS_TYPE_BEGUILER
|
||||
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
|
||||
@@ -838,7 +525,6 @@ int CanClassUseSuddenMetamagicFeats(int nClass)
|
||||
// Spellbook NUI and can use Sudden Metamagic
|
||||
return (nClass == CLASS_TYPE_SHADOWLORD
|
||||
|| nClass == CLASS_TYPE_ARCHIVIST
|
||||
|| nClass == CLASS_TYPE_ASSASSIN
|
||||
|| nClass == CLASS_TYPE_BARD
|
||||
|| nClass == CLASS_TYPE_BEGUILER
|
||||
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
|
||||
@@ -1144,5 +830,16 @@ int JsonArrayContainsInt(json list, int item)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsSpellbookNUIOpen(object oPC)
|
||||
{
|
||||
int nPreviousToken = NuiFindWindow(oPC, PRC_SPELLBOOK_NUI_WINDOW_ID);
|
||||
if (nPreviousToken != 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -28,11 +28,17 @@ void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int re
|
||||
void CreateSpellDescriptionNUI(object oPlayer, int featID, int spellId=0, int realSpellId=0)
|
||||
{
|
||||
// look for existing window and destroy
|
||||
int nPreviousToken = NuiFindWindow(OBJECT_SELF, NUI_SPELL_DESCRIPTION_WINDOW_ID);
|
||||
int nPreviousToken = NuiFindWindow(oPlayer, NUI_SPELL_DESCRIPTION_WINDOW_ID);
|
||||
if(nPreviousToken != 0)
|
||||
{
|
||||
NuiDestroy(oPlayer, nPreviousToken);
|
||||
}
|
||||
|
||||
/* int nPreviousToken = NuiFindWindow(OBJECT_SELF, NUI_SPELL_DESCRIPTION_WINDOW_ID);
|
||||
if(nPreviousToken != 0)
|
||||
{
|
||||
NuiDestroy(OBJECT_SELF, nPreviousToken);
|
||||
}
|
||||
} */
|
||||
|
||||
// in order of accuracy for names it goes RealSpellID > SpellID > FeatID
|
||||
string spellName;
|
||||
|
||||
@@ -180,6 +180,24 @@ void RunImpactScript(object oPC, int nSpellID, int nEventType)
|
||||
DeleteLocalInt(oPC, PRC_SPELLID_OVERRIDE);
|
||||
}
|
||||
|
||||
//Returns true if the spell is one of the repair spells
|
||||
int IsRepair(int nSpellID)
|
||||
{
|
||||
return ((nSpellID >= SPELL_REPAIR_MINOR_DAMAGE) && (nSpellID <= SPELL_REPAIR_CRITICAL_DAMAGE));
|
||||
}
|
||||
|
||||
//Returns true if the spell is one of the mass repair spells
|
||||
int IsMassRepair(int nSpellID)
|
||||
{
|
||||
return ((nSpellID >= SPELL_MASS_REPAIR_LIGHT_DAMAGE) && (nSpellID <= SPELL_MASS_REPAIR_CRITICAL_DAMAGE));
|
||||
}
|
||||
|
||||
//Returns true if the spell is one of the mass inflict damage spells
|
||||
int IsMassInflictDamage(int nSpellID)
|
||||
{
|
||||
return ((nSpellID >= SPELL_MASS_INFLICT_LIGHT_DAMAGE) && (nSpellID <= SPELL_MASS_INFLICT_CRITICAL_DAMAGE));
|
||||
}
|
||||
|
||||
//Returns true if the spell is one of the cure spells
|
||||
int IsCure(int nSpellID)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,9 @@ const int SPELL_BLACKLIGHT = 2091;
|
||||
const int SPELL_BARD_SONG = 411;
|
||||
const int SPELL_BARD_CURSE_SONG = 644;
|
||||
|
||||
//:: Monk
|
||||
const int SPELL_MONK_ABUNDANT_STEP = 17986;
|
||||
|
||||
//:: Epic Level Handbook
|
||||
const int SPELL_EPIC_SWARM_OF_ARROWS = 17996;
|
||||
|
||||
@@ -22,6 +25,9 @@ const int SPELL_BCM_RENDING_CLAWS = 17997;
|
||||
//:: Complete Warrior
|
||||
const int SPELL_RANGED_DISARM = 3493;
|
||||
|
||||
//:: Tome of Battle
|
||||
const int SPELL_TOB_SNAP_KICK = 3794;
|
||||
|
||||
//marshal
|
||||
const int SPELL_MINAUR_DEMFORT = 3500;
|
||||
const int SPELL_MINAUR_FORCEWILL = 3501;
|
||||
@@ -1289,20 +1295,128 @@ const int SPELL_SUMMON_CREATURE_IX_WATER = 3200;
|
||||
//:: Player's Handbook Spells
|
||||
const int SPELL_SPIRITUAL_WEAPON = 17249;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1 = 17000;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1_DIREBADGER = 17001;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1_DIRERAT = 17002;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1_DOG = 17003;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1_HAWK = 17004;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_1_TINY_VIPER = 17005;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2 = 17010;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2_DIREBOAR = 17011;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2_COOSHEE = 17012;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2_WOLF = 17013;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2_SMALL_VIPER = 17014;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_2_BLACKBEAR = 17015;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3 = 17020;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3_BROWNBEAR = 17021;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3_DIREWOLK = 17022;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3_LARGE_VIPER = 17023;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3_LEOPARD = 17024;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_3_SATYR = 17025;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4 = 17030;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4_LION = 17031;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4_POLAR_BEAR = 17032;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4_DIRE_SPIDER = 17033;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4_HUGE_VIPER = 17034;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_4_WEREBOAR = 17035;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5 = 17040;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5_MED_AIR = 17041;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5_MED_EARTH = 17042;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5_MED_FIRE = 17043;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5_MED_WATER = 17044;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_5_DIRE_BEAR = 17045;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6 = 17050;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6_LG_AIR = 17051;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6_LG_EARTH = 17052;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6_LG_FIRE = 17053;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6_LG_WATER = 17054;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_6_DIRETIGER = 17055;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7 = 17060;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7_BULETTE = 17061;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7_INVSTALKER = 17062;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7_PIXIE = 17063;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7_GORGON = 17064;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_7_MANTICORE = 17065;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8 = 17070;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8_GR_AIR = 17071;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8_GR_EARTH = 17072;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8_GR_FIRE = 17073;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8_GR_WATER = 17074;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_8_NYMPH = 17075;
|
||||
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9 = 17080;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_AIR = 17081;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_EARTH = 17082;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_FIRE = 17083;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_WATER = 17084;
|
||||
const int SPELL_SUMMON_NATURES_ALLY_9_ARANEA = 17085;
|
||||
|
||||
//:: Player's Handbook II Spells
|
||||
const int SPELL_CHASING_PERFECTION = 2479;
|
||||
|
||||
//:: Spell Compendium Spells
|
||||
const int SPELL_SPIRIT_WORM = 17248;
|
||||
const int SPELL_FORCE_MISSILES = 2480;
|
||||
const int SPELL_FORCE_MISSILES = 2480;
|
||||
const int SPELL_REPAIR_MINOR_DAMAGE = 17094;
|
||||
const int SPELL_REPAIR_LIGHT_DAMAGE = 17095;
|
||||
const int SPELL_REPAIR_MODERATE_DAMAGE = 17096;
|
||||
const int SPELL_REPAIR_SERIOUS_DAMAGE = 17097;
|
||||
const int SPELL_REPAIR_CRITICAL_DAMAGE = 17098;
|
||||
const int SPELL_INFLICT_LIGHT_DAMAGE = 17100;
|
||||
const int SPELL_INFLICT_MODERATE_DAMAGE = 17101;
|
||||
const int SPELL_INFLICT_SERIOUS_DAMAGE = 17102;
|
||||
const int SPELL_INFLICT_CRITICAL_DAMAGE = 17103;
|
||||
const int SPELL_SPIRIT_WORM = 17248;
|
||||
|
||||
//:: Races of Eberron
|
||||
const int SPELL_MASS_REPAIR_LIGHT_DAMAGE = 17105;
|
||||
const int SPELL_MASS_REPAIR_MODERATE_DAMAGE = 17106;
|
||||
const int SPELL_MASS_REPAIR_SERIOUS_DAMAGE = 17107;
|
||||
const int SPELL_MASS_REPAIR_CRITICAL_DAMAGE = 17108;
|
||||
const int SPELL_MASS_INFLICT_LIGHT_DAMAGE = 17110;
|
||||
const int SPELL_MASS_INFLICT_MODERATE_DAMAGE = 17111;
|
||||
const int SPELL_MASS_INFLICT_SERIOUS_DAMAGE = 17112;
|
||||
const int SPELL_MASS_INFLICT_CRITICAL_DAMAGE = 17113;
|
||||
|
||||
//:: Masters of the Wild Spells
|
||||
const int SPELL_FORESTFOLD = 17090;
|
||||
const int SPELL_CREEPING_COLD = 17091;
|
||||
const int SPELL_GREATER_CREEPING_COLD = 17092;
|
||||
const int SPELL_CONTROL_PLANTS = 17237;
|
||||
const int SPELL_ADRENALINE_SURGE = 17238;
|
||||
const int SPELL_INVULNERABILITY_TO_ELEMENTS = 17239;
|
||||
const int SPELL_REGEN_RING = 17241;
|
||||
const int SPELL_REGEN_CIRCLE = 17242;
|
||||
const int SPELL_REGEN_LIGHT_WOUNDS = 17243;
|
||||
const int SPELL_REGEN_MODERATE_WOUNDS = 17244;
|
||||
const int SPELL_REGEN_SERIOUS_WOUNDS = 17245;
|
||||
const int SPELL_REGEN_CRITICAL_WOUNDS = 17246;
|
||||
const int SPELL_SPEED_WIND = 17247;
|
||||
const int SPELL_TORTISE_SHELL = 17250;
|
||||
const int SPELL_TORTISE_SHELL = 17250;
|
||||
|
||||
//:: Book of Exalted Deeds Spells
|
||||
const int SPELL_LEONALS_ROAR = 17240;
|
||||
|
||||
//:: Master of the Wild Feats
|
||||
const int SPELL_VL_WILD_SHAPE_TREANT = 17989;
|
||||
const int SPELL_VL_ANIMATE_TREE = 17990;
|
||||
const int SPELL_PLANT_DEFIANCE = 17991;
|
||||
const int SPELL_PLANT_CONTROL = 17992;
|
||||
|
||||
//:: Book of Exalted Deeds Feats
|
||||
const int SPELL_FOT_LEONALS_ROAR = 17993;
|
||||
const int SPELL_FOT_LIONS_SWIFTNESS = 17994;
|
||||
const int SPELL_FAVORED_OF_THE_COMPANIONS = 17995;
|
||||
|
||||
//:: Magic Item Compendium
|
||||
const int SPELL_AROMA_OF_CURDLED_DEATH = 17987;
|
||||
const int SPELL_ELIXIR_OF_THE_BEETLE = 17987;
|
||||
|
||||
//x
|
||||
const int SPELL_TENSERS_FLOATING_DISK = 3849;
|
||||
|
||||
@@ -299,6 +299,7 @@ int SpellfireDrainItem(object oPC, object oItem, int bCharged = TRUE, int bSingl
|
||||
{
|
||||
|
||||
if((nBase == BASE_ITEM_POTIONS) ||
|
||||
(nBase == BASE_ITEM_INFUSED_HERB) ||
|
||||
(nBase == BASE_ITEM_SCROLL) ||
|
||||
(nBase == BASE_ITEM_SPELLSCROLL) ||
|
||||
(nBase == BASE_ITEM_BLANK_POTION) ||
|
||||
@@ -382,6 +383,7 @@ void SpellfireDrain(object oPC, object oTarget, int bCharged = TRUE, int bExempt
|
||||
if(GetPRCSwitch(PRC_SPELLFIRE_DISALLOW_DRAIN_SCROLL_POTION) &&
|
||||
((nBase == BASE_ITEM_POTIONS) ||
|
||||
(nBase == BASE_ITEM_SCROLL) ||
|
||||
(nBase == BASE_ITEM_INFUSED_HERB) ||
|
||||
(nBase == BASE_ITEM_BLANK_POTION) ||
|
||||
(nBase == BASE_ITEM_BLANK_SCROLL)
|
||||
)
|
||||
@@ -485,7 +487,8 @@ void SpellfireChargeItem(object oPC, object oItem)
|
||||
AddSpellfireLevels(oPC, nNewCharges - 50);
|
||||
nNewCharges = 50;
|
||||
}
|
||||
SetItemCharges(oItem, nCharges + nExpend);
|
||||
//SetItemCharges(oItem, nCharges + nExpend);
|
||||
SetItemCharges(oItem, nNewCharges);
|
||||
//Assuming 50 is the maximum
|
||||
//refunding excess charges
|
||||
}
|
||||
@@ -525,3 +528,4 @@ void SpellfireCrown(object oPC)
|
||||
}
|
||||
}
|
||||
|
||||
//:: void main() {}
|
||||
@@ -18,6 +18,7 @@ const int TEMPLATE_CURST = 26;
|
||||
const int TEMPLATE_GRAVETOUCHED_GHOUL = 29;
|
||||
const int TEMPLATE_CRYPTSPAWN = 30;
|
||||
const int TEMPLATE_ARCHLICH = 99;
|
||||
const int TEMPLATE_BAELNORN = 100;
|
||||
const int TEMPLATE_LICH = 101;
|
||||
const int TEMPLATE_DEMILICH = 102;
|
||||
const int TEMPLATE_NECROPOLITAN = 105;
|
||||
|
||||
@@ -47,12 +47,10 @@ int GetWeaponFocusFeatItemProperty(int nFeatNumber)
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_TRIDENT, IP_CONST_FEAT_WEAPON_FOCUS_TRIDENT);
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_LANCE, IP_CONST_FEAT_WEAPON_FOCUS_GOAD);
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_EAGLE_CLAW, IP_CONST_FEAT_WEAPON_FOCUS_GOAD);
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_LIGHTBLADE, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_LIGHTBLADE);
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_EAGLE_CLAW, IP_CONST_FEAT_WEAPON_FOCUS_EAGLE_CLAW);
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_THINBLADE, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_THINBLADE);
|
||||
if(nItemProperty != -1) return nItemProperty;
|
||||
nItemProperty = GetFeatItemProperty(nFeatNumber, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_COURTBLADE, IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_COURTBLADE);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
//:: Created On: 2003-05-09
|
||||
//:: Last Updated On: 2003-10-14
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_x2_itemprop"
|
||||
|
||||
struct craft_struct
|
||||
{
|
||||
@@ -44,22 +44,25 @@ const string X2_CI_CRAFTSKILL_CONV ="x2_p_craftskills";
|
||||
/* moved to be code switches
|
||||
|
||||
const int X2_CI_BREWPOTION_MAXLEVEL = 3; // Max Level for potions
|
||||
const int X2_CI_BREWPOTION_COSTMODIFIER = 50; // gp Brew Potion XPCost Modifier
|
||||
const int PRC_X2_BREWPOTION_COSTMODIFIER = 50; // gp Brew Potion XPCost Modifier
|
||||
|
||||
// Scribe Scroll related constants
|
||||
const int X2_CI_SCRIBESCROLL_COSTMODIFIER = 25; // Scribescroll Cost Modifier
|
||||
const int PRC_X2_SCRIBESCROLL_COSTMODIFIER = 25; // Scribescroll Cost Modifier
|
||||
|
||||
// Craft Wand related constants
|
||||
const int X2_CI_CRAFTWAND_MAXLEVEL = 4;
|
||||
const int X2_CI_CRAFTWAND_COSTMODIFIER = 750;
|
||||
const int PRC_X2_CRAFTWAND_MAXLEVEL = 4;
|
||||
const int PRC_X2_CRAFTWAND_COSTMODIFIER = 750;
|
||||
*/
|
||||
const int X2_CI_BREWPOTION_FEAT_ID = 944; // Brew Potion feat simulation
|
||||
const int X2_CI_SCRIBESCROLL_FEAT_ID = 945;
|
||||
const int X2_CI_CRAFTWAND_FEAT_ID = 946;
|
||||
const int X2_CI_CRAFTROD_FEAT_ID = 2927;
|
||||
const int X2_CI_CRAFTROD_EPIC_FEAT_ID = 3490;
|
||||
const int X2_CI_CRAFTSTAFF_FEAT_ID = 2928;
|
||||
const int X2_CI_CRAFTSTAFF_EPIC_FEAT_ID = 3491;
|
||||
const int X2_CI_BREWPOTION_FEAT_ID = 944; // Brew Potion feat simulation
|
||||
const int X2_CI_SCRIBESCROLL_FEAT_ID = 945;
|
||||
const int X2_CI_CRAFTWAND_FEAT_ID = 946;
|
||||
const int X2_CI_CRAFTROD_FEAT_ID = 2927;
|
||||
const int X2_CI_CRAFTROD_EPIC_FEAT_ID = 3490;
|
||||
const int X2_CI_CRAFTSTAFF_FEAT_ID = 2928;
|
||||
const int X2_CI_CRAFTSTAFF_EPIC_FEAT_ID = 3491;
|
||||
const int X2_CI_CREATEINFUSION_FEAT_ID = 25960;
|
||||
const int X2_CI_CRAFTSCEPTER_FEAT_ID = 25962;
|
||||
|
||||
const string X2_CI_BREWPOTION_NEWITEM_RESREF = "x2_it_pcpotion"; // ResRef for new potion item
|
||||
const string X2_CI_SCRIBESCROLL_NEWITEM_RESREF = "x2_it_pcscroll"; // ResRef for new scroll item
|
||||
const string X2_CI_CRAFTWAND_NEWITEM_RESREF = "x2_it_pcwand";
|
||||
@@ -185,6 +188,17 @@ int CheckAlternativeCrafting(object oPC, int nSpell, struct craft_cost_struct co
|
||||
// Returns the maximum of caster level used and other effective levels from emulating spells
|
||||
int GetAlternativeCasterLevel(object oPC, int nLevel);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Create and Return an herbal infusion with an item property
|
||||
// matching nSpellID.
|
||||
// -----------------------------------------------------------------------------
|
||||
object CICreateInfusion(object oCreator, int nSpellID);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player successfully performed Create Infusion
|
||||
// -----------------------------------------------------------------------------
|
||||
int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Include section */
|
||||
//////////////////////////////////////////////////
|
||||
@@ -194,6 +208,7 @@ int GetAlternativeCasterLevel(object oPC, int nLevel);
|
||||
#include "prc_inc_newip"
|
||||
#include "prc_inc_spells"
|
||||
#include "prc_add_spell_dc"
|
||||
#include "inc_infusion"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
@@ -261,7 +276,9 @@ int CIGetIsCraftFeatBaseItem(object oItem)
|
||||
nBt == BASE_ITEM_BLANK_SCROLL ||
|
||||
nBt == BASE_ITEM_BLANK_WAND ||
|
||||
nBt == BASE_ITEM_CRAFTED_ROD ||
|
||||
nBt == BASE_ITEM_CRAFTED_STAFF)
|
||||
nBt == BASE_ITEM_CRAFTED_STAFF ||
|
||||
nBt == BASE_ITEM_CRAFTED_SCEPTER ||
|
||||
nBt == BASE_ITEM_MUNDANE_HERB)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@@ -287,7 +304,7 @@ object CICraftBrewPotion(object oCreator, int nSpellID )
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
/* //just a tad retarded, don't you think? other crafting feats are not similarly restricted
|
||||
/* //just a tad silly, don't you think? other crafting feats are not similarly restricted
|
||||
//Uses per day
|
||||
int nUsesAllowed;
|
||||
|
||||
@@ -453,11 +470,159 @@ object CICraftCraftWand(object oCreator, int nSpellID )
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Georg, 2003-06-12
|
||||
// Create and Return a magic wand with an item property
|
||||
// matching nSpellID. Charges are set to d20 + casterlevel
|
||||
// capped at 50 max
|
||||
// Create and Return a magic scroll with an item property
|
||||
// matching nSpellID.
|
||||
// -----------------------------------------------------------------------------
|
||||
object CICraftScribeScroll(object oCreator, int nSpellID)
|
||||
{
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: Enter (nSpellID=" + IntToString(nSpellID) + ")");
|
||||
|
||||
// Keep original and compute one-step master (if subradial)
|
||||
int nSpellOriginal = nSpellID;
|
||||
int nSpellMaster = nSpellOriginal;
|
||||
if (GetIsSubradialSpell(nSpellOriginal))
|
||||
{
|
||||
nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal);
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: subradial detected original=" + IntToString(nSpellOriginal) + " master=" + IntToString(nSpellMaster));
|
||||
}
|
||||
|
||||
// Prefer iprp mapping for the original, fallback to master
|
||||
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal);
|
||||
int nSpellUsedForIP = nSpellOriginal;
|
||||
if (nPropID < 0)
|
||||
{
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: no iprp for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster));
|
||||
nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);
|
||||
nSpellUsedForIP = nSpellMaster;
|
||||
}
|
||||
|
||||
// If neither original nor master has an iprp row, we can still try templates,
|
||||
// but most templates expect a matching iprp. Bail out now if nothing found.
|
||||
if (nPropID < 0)
|
||||
{
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: no iprp_spells entry for original/master -> aborting");
|
||||
FloatingTextStringOnCreature("This spell cannot be scribed (no item property mapping).", oCreator, FALSE);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: using spell " + IntToString(nSpellUsedForIP) + " (iprp row " + IntToString(nPropID) + ") for item property");
|
||||
|
||||
// Material component check (based on resolved iprp row)
|
||||
string sMat = GetMaterialComponentTag(nPropID);
|
||||
if (sMat != "")
|
||||
{
|
||||
object oMat = GetItemPossessedBy(oCreator, sMat);
|
||||
if (oMat == OBJECT_INVALID)
|
||||
{
|
||||
FloatingTextStrRefOnCreature(83374, oCreator); // Missing material component
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyObject(oMat);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve class and scroll template
|
||||
int nClass = PRCGetLastSpellCastClass();
|
||||
string sClass = "";
|
||||
switch (nClass)
|
||||
{
|
||||
case CLASS_TYPE_WIZARD:
|
||||
case CLASS_TYPE_SORCERER: sClass = "Wiz_Sorc"; break;
|
||||
case CLASS_TYPE_CLERIC:
|
||||
case CLASS_TYPE_OCULAR:
|
||||
case CLASS_TYPE_UR_PRIEST: sClass = "Cleric"; break;
|
||||
case CLASS_TYPE_PALADIN: sClass = "Paladin"; break;
|
||||
case CLASS_TYPE_DRUID:
|
||||
case CLASS_TYPE_BLIGHTER: sClass = "Druid"; break;
|
||||
case CLASS_TYPE_RANGER: sClass = "Ranger"; break;
|
||||
case CLASS_TYPE_BARD: sClass = "Bard"; break;
|
||||
case CLASS_TYPE_ASSASSIN: sClass = "Assassin"; break;
|
||||
}
|
||||
|
||||
object oTarget = OBJECT_INVALID;
|
||||
string sResRef = "";
|
||||
|
||||
// Try to find a class-specific scroll template.
|
||||
if (sClass != "")
|
||||
{
|
||||
// Try original first (so if you made a subradial-specific template it will be used)
|
||||
sResRef = Get2DACache(X2_CI_2DA_SCROLLS, sClass, nSpellOriginal);
|
||||
if (sResRef == "")
|
||||
{
|
||||
// fallback to the spell that matched an iprp row (master or original)
|
||||
sResRef = Get2DACache(X2_CI_2DA_SCROLLS, sClass, nSpellUsedForIP);
|
||||
}
|
||||
if (sResRef != "")
|
||||
{
|
||||
oTarget = CreateItemOnObject(sResRef, oCreator);
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: created template " + sResRef + " for class " + sClass);
|
||||
// Ensure template uses the correct cast-spell property: replace the template's cast-spell IP with ours
|
||||
if (oTarget != OBJECT_INVALID)
|
||||
{
|
||||
itemproperty ipIter = GetFirstItemProperty(oTarget);
|
||||
while (GetIsItemPropertyValid(ipIter))
|
||||
{
|
||||
if (GetItemPropertyType(ipIter) == ITEM_PROPERTY_CAST_SPELL)
|
||||
{
|
||||
RemoveItemProperty(oTarget, ipIter);
|
||||
break;
|
||||
}
|
||||
ipIter = GetNextItemProperty(oTarget);
|
||||
}
|
||||
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no template or sClass was empty, create generic scroll and add itemprop.
|
||||
if (oTarget == OBJECT_INVALID)
|
||||
{
|
||||
sResRef = "craft_scroll";
|
||||
oTarget = CreateItemOnObject(sResRef, oCreator);
|
||||
if (oTarget == OBJECT_INVALID)
|
||||
{
|
||||
WriteTimestampedLogEntry("CICraftScribeScroll: failed to create craft_scroll template.");
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
// Remove existing default IP and add correct one
|
||||
itemproperty ipFirst = GetFirstItemProperty(oTarget);
|
||||
if (GetIsItemPropertyValid(ipFirst))
|
||||
RemoveItemProperty(oTarget, ipFirst);
|
||||
|
||||
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
|
||||
}
|
||||
|
||||
// Add PRC metadata (use the same spell that matched the iprp row so metadata and IP line up)
|
||||
if (GetPRCSwitch(PRC_SCRIBE_SCROLL_CASTER_LEVEL))
|
||||
{
|
||||
int nCasterLevel = GetAlternativeCasterLevel(oCreator, PRCGetCasterLevel(oCreator));
|
||||
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpellUsedForIP, nCasterLevel);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipLevel, oTarget);
|
||||
|
||||
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpellUsedForIP, PRCGetMetaMagicFeat());
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipMeta, oTarget);
|
||||
|
||||
int nDC = PRCGetSpellSaveDC(nSpellUsedForIP, GetSpellSchool(nSpellUsedForIP), OBJECT_SELF);
|
||||
itemproperty ipDC = ItemPropertyCastSpellDC(nSpellUsedForIP, nDC);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipDC, oTarget);
|
||||
}
|
||||
|
||||
if (oTarget == OBJECT_INVALID)
|
||||
{
|
||||
WriteTimestampedLogEntry("prc_x2_craft::CICraftScribeScroll failed - Resref: " + sResRef + " Class: " + sClass + "(" + IntToString(nClass) + ") " + " SpellID " + IntToString(nSpellID));
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
if (DEBUG) DoDebug("CICraftScribeScroll: Success - created scroll " + sResRef + " for spell " + IntToString(nSpellUsedForIP));
|
||||
return oTarget;
|
||||
}
|
||||
|
||||
|
||||
/* object CICraftScribeScroll(object oCreator, int nSpellID)
|
||||
{
|
||||
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellID);
|
||||
object oTarget;
|
||||
@@ -491,6 +656,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
|
||||
break;
|
||||
case CLASS_TYPE_CLERIC:
|
||||
case CLASS_TYPE_UR_PRIEST:
|
||||
case CLASS_TYPE_OCULAR:
|
||||
sClass = "Cleric";
|
||||
break;
|
||||
case CLASS_TYPE_PALADIN:
|
||||
@@ -506,6 +672,9 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
|
||||
case CLASS_TYPE_BARD:
|
||||
sClass = "Bard";
|
||||
break;
|
||||
case CLASS_TYPE_ASSASSIN:
|
||||
sClass = "Assassin";
|
||||
break;
|
||||
}
|
||||
string sResRef;
|
||||
if (sClass != "")
|
||||
@@ -542,6 +711,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
|
||||
}
|
||||
return oTarget;
|
||||
}
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player used the last spell to brew a potion
|
||||
@@ -593,7 +763,7 @@ These dont work as IPs since they are hardcoded */
|
||||
// -------------------------------------------------------------------------
|
||||
// check if spell is below maxlevel for brew potions
|
||||
// -------------------------------------------------------------------------
|
||||
int nPotionMaxLevel = GetPRCSwitch(X2_CI_BREWPOTION_MAXLEVEL);
|
||||
int nPotionMaxLevel = GetPRCSwitch(PRC_X2_BREWPOTION_MAXLEVEL);
|
||||
if(nPotionMaxLevel == 0)
|
||||
nPotionMaxLevel = 3;
|
||||
|
||||
@@ -624,7 +794,7 @@ These dont work as IPs since they are hardcoded */
|
||||
// -------------------------------------------------------------------------
|
||||
// XP/GP Cost Calculation
|
||||
// -------------------------------------------------------------------------
|
||||
int nCostModifier = GetPRCSwitch(X2_CI_BREWPOTION_COSTMODIFIER);
|
||||
int nCostModifier = GetPRCSwitch(PRC_X2_BREWPOTION_COSTMODIFIER);
|
||||
if(nCostModifier == 0)
|
||||
nCostModifier = 50;
|
||||
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_BREW_POTION_CASTER_LEVEL);
|
||||
@@ -698,7 +868,6 @@ These dont work as IPs since they are hardcoded */
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player used the last spell to create a scroll
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -728,7 +897,7 @@ int CICraftCheckScribeScroll(object oSpellTarget, object oCaster, int nID = 0)
|
||||
// XP/GP Cost Calculation
|
||||
// -------------------------------------------------------------------------
|
||||
int nLevel = CIGetSpellInnateLevel(nID,TRUE);
|
||||
int nCostModifier = GetPRCSwitch(X2_CI_SCRIBESCROLL_COSTMODIFIER);
|
||||
int nCostModifier = GetPRCSwitch(PRC_X2_SCRIBESCROLL_COSTMODIFIER);
|
||||
if(nCostModifier == 0)
|
||||
nCostModifier = 25;
|
||||
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_SCRIBE_SCROLL_CASTER_LEVEL);
|
||||
@@ -884,7 +1053,7 @@ These dont work as IPs since they are hardcoded */
|
||||
// -------------------------------------------------------------------------
|
||||
// check if spell is below maxlevel for craft want
|
||||
// -------------------------------------------------------------------------
|
||||
int nMaxLevel = GetPRCSwitch(X2_CI_CRAFTWAND_MAXLEVEL);
|
||||
int nMaxLevel = GetPRCSwitch(PRC_X2_CRAFTWAND_MAXLEVEL);
|
||||
if(nMaxLevel == 0)
|
||||
nMaxLevel = 4;
|
||||
if (nLevel > nMaxLevel)
|
||||
@@ -896,7 +1065,7 @@ These dont work as IPs since they are hardcoded */
|
||||
// -------------------------------------------------------------------------
|
||||
// XP/GP Cost Calculation
|
||||
// -------------------------------------------------------------------------
|
||||
int nCostMod = GetPRCSwitch(X2_CI_CRAFTWAND_COSTMODIFIER);
|
||||
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTWAND_COSTMODIFIER);
|
||||
if(nCostMod == 0)
|
||||
nCostMod = 750;
|
||||
int nCost = CIGetCraftGPCost(nLevel, nCostMod, PRC_CRAFT_WAND_CASTER_LEVEL);
|
||||
@@ -966,6 +1135,169 @@ These dont work as IPs since they are hardcoded */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player used the last spell to craft a scepter
|
||||
// -----------------------------------------------------------------------------
|
||||
int CICraftCheckCraftScepter(object oSpellTarget, object oCaster, int nSpellID = 0)
|
||||
{
|
||||
|
||||
if(nSpellID == 0) nSpellID = PRCGetSpellId();
|
||||
int nCasterLevel = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
|
||||
int bSuccess = TRUE;
|
||||
int nCount = 0;
|
||||
itemproperty ip = GetFirstItemProperty(oSpellTarget);
|
||||
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||
|
||||
while(GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if(GetItemPropertyType(ip) == ITEM_PROPERTY_CAST_SPELL)
|
||||
nCount++;
|
||||
ip = GetNextItemProperty(oSpellTarget);
|
||||
}
|
||||
if(nCount >= 2) //:: Scepters are limited to two spells
|
||||
{
|
||||
FloatingTextStringOnCreature("* Failure - Too many castspell itemproperties *", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
if(!GetHasFeat(X2_CI_CRAFTSCEPTER_FEAT_ID, oCaster))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(40487, oCaster); // Item Creation Failed - Don't know how to create that type of item
|
||||
return TRUE; // tried item creation but do not know how to do it
|
||||
}
|
||||
if(CIGetIsSpellRestrictedFromCraftFeat(nSpellID, X2_CI_CRAFTSCEPTER_FEAT_ID))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(16829169, oCaster); // can not be used with this feat
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Get the base spell level (circle) before metamagic adjustments
|
||||
int nBaseLevel = CIGetSpellInnateLevel(nSpellID, TRUE);
|
||||
|
||||
// Check if spell circle is 7th level or lower
|
||||
if (nBaseLevel > 7)
|
||||
{
|
||||
//FloatingTextStrRefOnCreature(83623, oCaster); // Spell level too high
|
||||
FloatingTextStringOnCreature("* Failure - scepters can not hold spells higher than level 7", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int nLevel = nBaseLevel;
|
||||
|
||||
if(GetPRCSwitch(PRC_CRAFT_SCEPTER_CASTER_LEVEL))
|
||||
{
|
||||
switch(nMetaMagic)
|
||||
{
|
||||
case METAMAGIC_EMPOWER:
|
||||
nLevel += 2;
|
||||
break;
|
||||
case METAMAGIC_EXTEND:
|
||||
nLevel += 1;
|
||||
break;
|
||||
case METAMAGIC_MAXIMIZE:
|
||||
nLevel += 3;
|
||||
break;
|
||||
/* case METAMAGIC_QUICKEN:
|
||||
nLevel += 1;
|
||||
break;
|
||||
case METAMAGIC_SILENT:
|
||||
nLevel += 5;
|
||||
break;
|
||||
case METAMAGIC_STILL:
|
||||
nLevel += 6;
|
||||
break;
|
||||
These dont work as IPs since they are hardcoded */
|
||||
}
|
||||
}
|
||||
|
||||
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTSCEPTER_COSTMODIFIER);
|
||||
if(!nCostMod) nCostMod = 750;
|
||||
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
|
||||
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
|
||||
int nCost = CIGetCraftGPCost(nLevel, nCostMod, PRC_CRAFT_SCEPTER_CASTER_LEVEL);
|
||||
|
||||
//discount for second spell
|
||||
if(nCount+1 == 2)
|
||||
nCost = (nCost/2);
|
||||
|
||||
//takes epic xp costs into account
|
||||
struct craft_cost_struct costs = GetModifiedCostsFromBase(nCost, oCaster, FEAT_CRAFT_SCEPTER, (nMetaMagic > 0));
|
||||
|
||||
if(costs.nGoldCost < 1) costs.nXPCost = 1;
|
||||
if(costs.nXPCost < 1) costs.nXPCost = 1;
|
||||
//if(GetGold(oCaster) < nGoldCost) // enough gold?
|
||||
if (!GetHasGPToSpend(oCaster, costs.nGoldCost))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(3786, oCaster); // Item Creation Failed - not enough gold!
|
||||
return TRUE;
|
||||
}
|
||||
int nHD = GetHitDice(oCaster);
|
||||
int nMinXPForLevel = (nHD * (nHD - 1)) * 500;
|
||||
int nNewXP = GetXP(oCaster) - costs.nXPCost;
|
||||
//if (nMinXPForLevel > nNewXP || nNewXP == 0 )
|
||||
if (!GetHasXPToSpend(oCaster, costs.nXPCost))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(3785, oCaster); // Item Creation Failed - Not enough XP
|
||||
return TRUE;
|
||||
}
|
||||
//check spell emulation
|
||||
if(!CheckAlternativeCrafting(oCaster, nSpellID, costs))
|
||||
{
|
||||
FloatingTextStringOnCreature("*Crafting failed!*", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellID);
|
||||
if (nPropID == 0 && nSpellID != 0)
|
||||
{
|
||||
FloatingTextStrRefOnCreature(84544,oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
if (nPropID != -1)
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpell(nPropID,IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE),oSpellTarget);
|
||||
|
||||
if(GetPRCSwitch(PRC_CRAFT_SCEPTER_CASTER_LEVEL))
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellCasterLevel(nSpellID, nCasterLevel),oSpellTarget);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellMetamagic(nSpellID, PRCGetMetaMagicFeat()),oSpellTarget);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellDC(nSpellID, PRCGetSaveDC(PRCGetSpellTargetObject(), OBJECT_SELF)),oSpellTarget);
|
||||
}
|
||||
}
|
||||
else
|
||||
bSuccess = FALSE;
|
||||
|
||||
if(bSuccess)
|
||||
{
|
||||
//TakeGoldFromCreature(nGoldCost, oCaster, TRUE);
|
||||
//SetXP(oCaster, nNewXP);
|
||||
SpendXP(oCaster, costs.nXPCost);
|
||||
SpendGP(oCaster, costs.nGoldCost);
|
||||
//DestroyObject (oSpellTarget);
|
||||
FloatingTextStrRefOnCreature(8502, oCaster); // Item Creation successful
|
||||
|
||||
//advance time here
|
||||
if(!costs.nTimeCost) costs.nTimeCost = 1;
|
||||
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
|
||||
string sName;
|
||||
sName = GetName(oCaster)+"'s Magic Scepter";
|
||||
SetItemCharges(oSpellTarget, 50);
|
||||
//sName = Get2DACache("spells", "Name", nID);
|
||||
//sName = "Wand of "+GetStringByStrRef(StringToInt(sName));
|
||||
SetName(oSpellTarget, sName);
|
||||
SetItemCursedFlag(oSpellTarget, FALSE);
|
||||
SetDroppableFlag(oSpellTarget, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStrRefOnCreature(76417, oCaster); // Item Creation Failed
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player used the last spell to craft a staff
|
||||
// -----------------------------------------------------------------------------
|
||||
int CICraftCheckCraftStaff(object oSpellTarget, object oCaster, int nSpellID = 0)
|
||||
{
|
||||
|
||||
@@ -1027,7 +1359,7 @@ int CICraftCheckCraftStaff(object oSpellTarget, object oCaster, int nSpellID = 0
|
||||
These dont work as IPs since they are hardcoded */
|
||||
}
|
||||
}
|
||||
int nCostMod = GetPRCSwitch(X2_CI_CRAFTSTAFF_COSTMODIFIER);
|
||||
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTSTAFF_COSTMODIFIER);
|
||||
if(!nCostMod) nCostMod = 750;
|
||||
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
|
||||
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
|
||||
@@ -1114,6 +1446,9 @@ These dont work as IPs since they are hardcoded */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player used the last spell to craft a rod
|
||||
// -----------------------------------------------------------------------------
|
||||
int CICraftCheckCraftRod(object oSpellTarget, object oCaster, int nSpellID = 0)
|
||||
{
|
||||
|
||||
@@ -1175,7 +1510,7 @@ int CICraftCheckCraftRod(object oSpellTarget, object oCaster, int nSpellID = 0)
|
||||
These dont work as IPs since they are hardcoded */
|
||||
}
|
||||
}
|
||||
int nCostMod = GetPRCSwitch(X2_CI_CRAFTROD_COSTMODIFIER);
|
||||
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTROD_COSTMODIFIER);
|
||||
if(!nCostMod) nCostMod = 750;
|
||||
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
|
||||
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
|
||||
@@ -1260,6 +1595,7 @@ These dont work as IPs since they are hardcoded */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, int nSpell = 0)
|
||||
{
|
||||
if(!GetIsObjectValid(oCaster)) oCaster = OBJECT_SELF;
|
||||
@@ -1310,6 +1646,11 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
|
||||
|
||||
if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject();
|
||||
int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
|
||||
|
||||
//:: Check for Inscribe Epic Runes and cap CL at 20 if it doesn't exist.
|
||||
int bEpicRunes = GetHasFeat(EPIC_FEAT_INSCRIBE_EPIC_RUNES, oCaster);
|
||||
if (!bEpicRunes) { if(nCaster > 20) nCaster = 20; }
|
||||
|
||||
int nDC = PRCGetSaveDC(oTarget, oCaster);
|
||||
if(!nSpell) nSpell = PRCGetSpellId();
|
||||
int nSpellLevel = 0;
|
||||
@@ -1332,6 +1673,7 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
|
||||
// Minimum level.
|
||||
if (nSpellLevel == 0) nSpellLevel = 1;
|
||||
|
||||
|
||||
// This will be modified with Runecaster code later.
|
||||
int nCharges = 1;
|
||||
if (GetLocalInt(oCaster, "RuneCharges")) nCharges = nCount;
|
||||
@@ -1440,9 +1782,14 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
|
||||
// If they have this active, the bonuses are already added, so skip
|
||||
// If they don't, add the bonuses down below
|
||||
if(GetHasSpellEffect(SPELL_RUNE_CHANT))
|
||||
nRuneChant = 0;
|
||||
nRuneChant = 0;
|
||||
|
||||
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, PRCGetCasterLevel());
|
||||
//:: Check for Inscribe Epic Runes and cap CL at 20 if it doesn't exist.
|
||||
nCaster = PRCGetCasterLevel();
|
||||
|
||||
if (!bEpicRunes) { if(nCaster > 20) nCaster = 20; }
|
||||
|
||||
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, nCaster);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ipLevel,oRune);
|
||||
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpell, PRCGetMetaMagicFeat());
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ipMeta,oRune);
|
||||
@@ -1544,18 +1891,28 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID,
|
||||
// No point scribing Gems from items, and its not allowed.
|
||||
if (oItem != OBJECT_INVALID)
|
||||
{
|
||||
FloatingTextStringOnCreature("You cannot scribe a Gem from an item.", oCaster, FALSE);
|
||||
FloatingTextStringOnCreature("You cannot attune a Gem from an item.", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
// oTarget here should be the gem. If it's not, fail.
|
||||
if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject();
|
||||
// Only accepts bioware gems
|
||||
if (GetStringLeft(GetResRef(oTarget), 5) == "it_gem")
|
||||
// Only accepts bioware gems & Craftable Natural Resources gems, but not gem dust.
|
||||
int bIsBioGem = (GetStringLeft(GetResRef(oTarget), 5) == "it_gem");
|
||||
int bIsCNRGem = (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem");
|
||||
int bIsDust = (GetStringLeft(GetResRef(oTarget), 10) == "cnrgemdust");
|
||||
|
||||
if (!(bIsBioGem || bIsCNRGem) || bIsDust)
|
||||
{
|
||||
FloatingTextStringOnCreature("Spell target is not a valid gem.", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* if ((GetStringLeft(GetResRef(oTarget), 5) == "it_gem") || (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem") && (GetStringLeft(GetResRef(oTarget), 10) != "cnrgemdust"))
|
||||
{
|
||||
FloatingTextStringOnCreature("Spell target is not a valid gem.", oCaster, FALSE);
|
||||
// And out we go
|
||||
return TRUE;
|
||||
}
|
||||
} */
|
||||
|
||||
int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
|
||||
int nDC = PRCGetSaveDC(oTarget, oCaster);
|
||||
@@ -1952,6 +2309,19 @@ int CIGetSpellWasUsedForItemCreation(object oSpellTarget)
|
||||
nRet = CICraftCheckCraftStaff(oSpellTarget,oCaster);
|
||||
break;
|
||||
|
||||
case BASE_ITEM_CRAFTED_SCEPTER :
|
||||
// -------------------------------------------------
|
||||
// Craft Scepter
|
||||
// -------------------------------------------------
|
||||
nRet = CICraftCheckCraftScepter(oSpellTarget,oCaster);
|
||||
break;
|
||||
|
||||
case BASE_ITEM_MUNDANE_HERB :
|
||||
// -------------------------------------------------
|
||||
// Create Infusion
|
||||
// -------------------------------------------------
|
||||
nRet = CICraftCheckCreateInfusion(oSpellTarget,oCaster);
|
||||
break;
|
||||
// you could add more crafting basetypes here....
|
||||
}
|
||||
|
||||
@@ -2740,6 +3110,16 @@ int GetMagicalArtisanFeat(int nCraftingFeat)
|
||||
nReturn = FEAT_MAGICAL_ARTISAN_CRAFT_SKULL_TALISMAN;
|
||||
break;
|
||||
}
|
||||
case FEAT_CREATE_INFUSION:
|
||||
{
|
||||
nReturn = FEAT_MAGICAL_ARTISAN_CREATE_INFUSION;
|
||||
break;
|
||||
}
|
||||
case FEAT_CRAFT_SCEPTER:
|
||||
{
|
||||
nReturn = FEAT_MAGICAL_ARTISAN_CRAFT_SCEPTER;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if(DEBUG) DoDebug("GetMagicalArtisanFeat: invalid crafting feat");
|
||||
@@ -2941,6 +3321,306 @@ int GetAlternativeCasterLevel(object oPC, int nLevel)
|
||||
return nLevel;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns TRUE if the player successfully performed Create Infusion
|
||||
// -----------------------------------------------------------------------------
|
||||
int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0)
|
||||
{
|
||||
if (nID == 0) nID = PRCGetSpellId();
|
||||
|
||||
int bIsSubradial = GetIsSubradialSpell(nID);
|
||||
|
||||
if(bIsSubradial)
|
||||
{
|
||||
nID = GetMasterSpellFromSubradial(nID);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if the caster has the Create Infusion feat
|
||||
// -------------------------------------------------------------------------
|
||||
if (!GetHasFeat(FEAT_CREATE_INFUSION, oCaster))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(40487, oCaster); // Missing feat
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Divine spellcasters only
|
||||
// -------------------------------------------------------------------------
|
||||
int nClass = PRCGetLastSpellCastClass();
|
||||
if (!GetIsDivineClass(nClass))
|
||||
{
|
||||
FloatingTextStringOnCreature("Only divine casters can create infusions.", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check if spell is restricted for Create Infusion
|
||||
// -------------------------------------------------------------------------
|
||||
if (CIGetIsSpellRestrictedFromCraftFeat(nID, X2_CI_CREATEINFUSION_FEAT_ID))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(83451, oCaster); // Spell not allowed
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Optional PnP Herb check
|
||||
// -------------------------------------------------------------------------
|
||||
int bPnPHerbs = GetPRCSwitch(PRC_CREATE_INFUSION_OPTIONAL_HERBS);
|
||||
if(bPnPHerbs)
|
||||
{
|
||||
int nSpellschool = GetSpellSchool(nID);
|
||||
int nHerbSchool = GetHerbsSpellSchool(oSpellTarget);
|
||||
|
||||
int nSpellLevel = PRCGetSpellLevelForClass(nID, nClass);
|
||||
int nHerbLevel = GetHerbsInfusionSpellLevel(oSpellTarget);
|
||||
|
||||
if(nSpellschool != nHerbSchool)
|
||||
{
|
||||
// Herb is for wrong spellschool
|
||||
FloatingTextStringOnCreature("This herb isn't appropriate for this spell school", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(nSpellLevel > nHerbLevel)
|
||||
{
|
||||
// Herb spell circle level too low
|
||||
FloatingTextStringOnCreature("This herb isn't appropriate for this spell level", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XP/GP Cost Calculation
|
||||
// -------------------------------------------------------------------------
|
||||
int nLevel = CIGetSpellInnateLevel(nID, TRUE);
|
||||
int nCostModifier = GetPRCSwitch(PRC_X2_CREATEINFUSION_COSTMODIFIER);
|
||||
if (nCostModifier == 0)
|
||||
nCostModifier = 25;
|
||||
|
||||
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_CREATE_INFUSION_CASTER_LEVEL);
|
||||
struct craft_cost_struct costs = GetModifiedCostsFromBase(nCost, oCaster, FEAT_CREATE_INFUSION, FALSE);
|
||||
|
||||
// Adjust level for metamagic
|
||||
if (GetPRCSwitch(PRC_CREATE_INFUSION_CASTER_LEVEL))
|
||||
{
|
||||
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||
switch(nMetaMagic)
|
||||
{
|
||||
case METAMAGIC_EMPOWER: nLevel += 2; break;
|
||||
case METAMAGIC_EXTEND: nLevel += 1; break;
|
||||
case METAMAGIC_MAXIMIZE: nLevel += 3; break;
|
||||
// Unsupported metamagic IPs not added
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check Gold
|
||||
// -------------------------------------------------------------------------
|
||||
if (!GetHasGPToSpend(oCaster, costs.nGoldCost))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(3786, oCaster); // Not enough gold
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check XP
|
||||
// -------------------------------------------------------------------------
|
||||
if (!GetHasXPToSpend(oCaster, costs.nXPCost))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(3785, oCaster); // Not enough XP
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check alternative spell emulation requirements
|
||||
// -------------------------------------------------------------------------
|
||||
if (!CheckAlternativeCrafting(oCaster, nID, costs))
|
||||
{
|
||||
FloatingTextStringOnCreature("*Crafting failed!*", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Create the infused herb item
|
||||
// -------------------------------------------------------------------------
|
||||
object oInfusion = CICreateInfusion(oCaster, nID);
|
||||
|
||||
if (GetIsObjectValid(oInfusion))
|
||||
{
|
||||
// Get the spell's display name from spells.2da via TLK
|
||||
int nNameStrRef = StringToInt(Get2DAString("spells", "Name", nID));
|
||||
string sSpellName = GetStringByStrRef(nNameStrRef);
|
||||
|
||||
// Rename the item
|
||||
string sNewName = "Infusion of " + sSpellName;
|
||||
SetName(oInfusion, sNewName);
|
||||
|
||||
// Post-creation actions
|
||||
SetIdentified(oInfusion, TRUE);
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_READ, 1.0);
|
||||
SpendXP(oCaster, costs.nXPCost);
|
||||
SpendGP(oCaster, costs.nGoldCost);
|
||||
DestroyObject(oSpellTarget);
|
||||
FloatingTextStrRefOnCreature(8502, oCaster); // Item creation successful
|
||||
|
||||
if (!costs.nTimeCost) costs.nTimeCost = 1;
|
||||
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStringOnCreature("Infusion creation failed", oCaster); // Item creation failed
|
||||
FloatingTextStrRefOnCreature(76417, oCaster); // Item creation failed
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* // -------------------------------------------------------------------------
|
||||
// Create the infused herb item
|
||||
// -------------------------------------------------------------------------
|
||||
object oInfusion = CICreateInfusion(oCaster, nID);
|
||||
|
||||
if (GetIsObjectValid(oInfusion))
|
||||
{
|
||||
SetIdentified(oInfusion, TRUE);
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_READ, 1.0);
|
||||
SpendXP(oCaster, costs.nXPCost);
|
||||
SpendGP(oCaster, costs.nGoldCost);
|
||||
DestroyObject(oSpellTarget);
|
||||
FloatingTextStrRefOnCreature(8502, oCaster); // Item creation successful
|
||||
|
||||
if (!costs.nTimeCost) costs.nTimeCost = 1;
|
||||
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStringOnCreature("Infusion creation failed", oCaster); // Item creation failed
|
||||
FloatingTextStrRefOnCreature(76417, oCaster); // Item creation failed
|
||||
return TRUE;
|
||||
} */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Create and return an herbal infusion with an item property matching nSpellID
|
||||
// -----------------------------------------------------------------------------
|
||||
object CICreateInfusion(object oCreator, int nSpellID)
|
||||
{
|
||||
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: Entering function");
|
||||
|
||||
// Keep the original spell id the engine gave us (may be a subradial)
|
||||
int nSpellOriginal = nSpellID;
|
||||
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellOriginal is "+IntToString(nSpellOriginal)+".");
|
||||
|
||||
// Compute the master if this is a subradial. Keep original intact.
|
||||
int nSpellMaster = nSpellOriginal;
|
||||
if (GetIsSubradialSpell(nSpellOriginal))
|
||||
{
|
||||
nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal);
|
||||
if (DEBUG) DoDebug("CICreateInfusion: detected subradial " + IntToString(nSpellOriginal) + " master -> " + IntToString(nSpellMaster));
|
||||
}
|
||||
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellMaster is "+IntToString(nSpellMaster)+".");
|
||||
|
||||
// Try to find an iprp_spells row for the original subradial first (preferred).
|
||||
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal);
|
||||
int nSpellUsedForIP = nSpellOriginal;
|
||||
|
||||
// If not found for original, fall back to the master/base spell.
|
||||
if (nPropID < 0)
|
||||
{
|
||||
if (DEBUG) DoDebug("CICreateInfusion: no iprp row for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster));
|
||||
nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);
|
||||
nSpellUsedForIP = nSpellMaster;
|
||||
}
|
||||
|
||||
// If still invalid, bail out with a helpful message
|
||||
if (nPropID < 0)
|
||||
{
|
||||
if (DEBUG) DoDebug("CICreateInfusion: No iprp_spells entry for either original " + IntToString(nSpellOriginal) + " or master " + IntToString(nSpellMaster));
|
||||
FloatingTextStringOnCreature("This spell cannot be infused (no item property mapping).", oCreator, FALSE);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
if (DEBUG) DoDebug("CICreateInfusion: using spell " + IntToString(nSpellUsedForIP) + " (iprp row " + IntToString(nPropID) + ") for item property");
|
||||
|
||||
// Optional: check for material component (use the resolved iprp row)
|
||||
string sMat = GetMaterialComponentTag(nPropID);
|
||||
if (sMat != "")
|
||||
{
|
||||
object oMat = GetItemPossessedBy(oCreator, sMat);
|
||||
if (oMat == OBJECT_INVALID)
|
||||
{
|
||||
FloatingTextStrRefOnCreature(83374, oCreator); // Missing material component
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyObject(oMat);
|
||||
}
|
||||
}
|
||||
|
||||
// Only allow divine spellcasters
|
||||
int nClass = PRCGetLastSpellCastClass();
|
||||
if (!GetIsDivineClass(nClass))
|
||||
{
|
||||
FloatingTextStringOnCreature("Only divine casters can use Create Infusion.", oCreator, FALSE);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// Create base infusion item (herb)
|
||||
string sResRef = "prc_infusion_000";
|
||||
object oTarget = CreateItemOnObject(sResRef, oCreator);
|
||||
if (oTarget == OBJECT_INVALID)
|
||||
{
|
||||
WriteTimestampedLogEntry("Create Infusion failed: couldn't create item with resref " + sResRef);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// Confirm that the item is a herb
|
||||
int nBaseItem = GetBaseItemType(oTarget);
|
||||
if (nBaseItem != BASE_ITEM_INFUSED_HERB)
|
||||
{
|
||||
FloatingTextStringOnCreature("Only herbs may be infused.", oCreator, FALSE);
|
||||
DestroyObject(oTarget);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// Remove all non-material item properties from the herb
|
||||
itemproperty ipRemove = GetFirstItemProperty(oTarget);
|
||||
while (GetIsItemPropertyValid(ipRemove))
|
||||
{
|
||||
itemproperty ipNext = GetNextItemProperty(oTarget);
|
||||
if (GetItemPropertyType(ipRemove) != ITEM_PROPERTY_MATERIAL)
|
||||
RemoveItemProperty(oTarget, ipRemove);
|
||||
ipRemove = ipNext;
|
||||
}
|
||||
|
||||
// Add the cast-spell itemproperty using the iprp row we resolved
|
||||
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
|
||||
|
||||
// Optional PRC casting metadata: use the SAME spell id that matched the iprp row
|
||||
// so caster level/DC/meta line up with the actual cast property on the item.
|
||||
if (GetPRCSwitch(PRC_CREATE_INFUSION_CASTER_LEVEL))
|
||||
{
|
||||
int nCasterLevel = GetAlternativeCasterLevel(oCreator, PRCGetCasterLevel(oCreator));
|
||||
// nSpellUsedForIP is either original (if that had an iprp row) or the master (fallback)
|
||||
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpellUsedForIP, nCasterLevel);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipLevel, oTarget);
|
||||
|
||||
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpellUsedForIP, PRCGetMetaMagicFeat());
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipMeta, oTarget);
|
||||
|
||||
int nDC = PRCGetSpellSaveDC(nSpellUsedForIP, GetSpellSchool(nSpellUsedForIP), OBJECT_SELF);
|
||||
itemproperty ipDC = ItemPropertyCastSpellDC(nSpellUsedForIP, nDC);
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ipDC, oTarget);
|
||||
}
|
||||
|
||||
return oTarget;
|
||||
}
|
||||
|
||||
|
||||
// Test main
|
||||
//void main(){}
|
||||
// void main(){}
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
//:: Last Update: 2003-10-07
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
//:: Test void
|
||||
//:: void main (){}
|
||||
|
||||
//Changed by primogenitor to include CEP itemtypes
|
||||
|
||||
// * The tag of the ip work container, a placeable which has to be set into each
|
||||
@@ -697,6 +694,7 @@ if(nItem == BASE_ITEM_BASTARDSWORD
|
||||
|| nItem == BASE_ITEM_SICKLE
|
||||
|| nItem == BASE_ITEM_TWOBLADEDSWORD
|
||||
|| nItem == BASE_ITEM_CLUB
|
||||
|| nItem == BASE_ITEM_CRAFTED_SCEPTER
|
||||
|| nItem == BASE_ITEM_DAGGER
|
||||
|| nItem == BASE_ITEM_DIREMACE
|
||||
|| nItem == BASE_ITEM_HEAVYFLAIL
|
||||
@@ -729,6 +727,7 @@ if(nItem == BASE_ITEM_BASTARDSWORD
|
||||
|| nItem == BASE_ITEM_ELVEN_THINBLADE
|
||||
|| nItem == BASE_ITEM_ELVEN_COURTBLADE
|
||||
|| nItem == BASE_ITEM_CRAFTED_STAFF
|
||||
|| nItem == BASE_ITEM_CRAFTED_SCEPTER
|
||||
|| nItem == 300 //CEP Trident
|
||||
|| nItem == 303 //CEP Sai
|
||||
|| nItem == 304 //CEP nunchaku
|
||||
@@ -768,7 +767,6 @@ int IPGetIsBludgeoningWeapon(object oItem)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return the IP_CONST_CASTSPELL_* ID matching to the SPELL_* constant given
|
||||
// in nSPELL_ID.
|
||||
// This uses Get2DAstring, so it is slow. Avoid using in loops!
|
||||
// returns -1 if there is no matching property for a spell
|
||||
// ----------------------------------------------------------------------------
|
||||
int IPGetIPConstCastSpellFromSpellID(int nSpellID)
|
||||
@@ -1613,31 +1611,140 @@ int IPGetDamageBonusConstantFromNumber(int nNumber)
|
||||
// oOld - Item equipped before polymorphing (source for item props)
|
||||
// oNew - Item equipped after polymorphing (target for item props)
|
||||
// bWeapon - Must be set TRUE when oOld is a weapon.
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
void IPWildShapeCopyItemProperties(object oOld, object oNew, int bWeapon = FALSE)
|
||||
{
|
||||
if (GetIsObjectValid(oOld) && GetIsObjectValid(oNew))
|
||||
{
|
||||
itemproperty ip = GetFirstItemProperty(oOld);
|
||||
while (GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if (bWeapon)
|
||||
{
|
||||
if (GetWeaponRanged(oOld) == GetWeaponRanged(oNew) )
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
|
||||
}
|
||||
ip = GetNextItemProperty(oOld);
|
||||
// Invalid source/target
|
||||
if (!GetIsObjectValid(oOld) || !GetIsObjectValid(oNew))
|
||||
return;
|
||||
|
||||
// Determine possessor
|
||||
object oPC = GetItemPossessor(oOld);
|
||||
if (!GetIsObjectValid(oPC))
|
||||
oPC = GetItemPossessor(oNew);
|
||||
|
||||
}
|
||||
}
|
||||
if (!GetIsObjectValid(oPC))
|
||||
{
|
||||
if (DEBUG) DoDebug("IPWS: Unable to determine item possessor");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine glove state once
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
|
||||
// Weapon ranged mismatch = do nothing (intent is no partial copy)
|
||||
if (bWeapon && GetWeaponRanged(oOld) != GetWeaponRanged(oNew))
|
||||
{
|
||||
if (DEBUG) DoDebug("IPWS: Weapon ranged mismatch <20> skipping all IP copy");
|
||||
return;
|
||||
}
|
||||
|
||||
// Begin property copy
|
||||
itemproperty ip = GetFirstItemProperty(oOld);
|
||||
while (GetIsItemPropertyValid(ip))
|
||||
{
|
||||
int nType = GetItemPropertyType(ip);
|
||||
|
||||
// If copying from gloves and monk gloves are active
|
||||
if (bMonkGloves
|
||||
&& (nType == ITEM_PROPERTY_DAMAGE_BONUS
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP))
|
||||
{
|
||||
// Always apply glove damage IPs
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oNew);
|
||||
ip = GetNextItemProperty(oOld);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normal weapon pass
|
||||
if (bWeapon)
|
||||
{
|
||||
// If monk gloves active ? skip ALL weapon damage IPs
|
||||
if (bMonkGloves
|
||||
&& (nType == ITEM_PROPERTY_DAMAGE_BONUS
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP))
|
||||
{
|
||||
ip = GetNextItemProperty(oOld);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oNew);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oNew);
|
||||
}
|
||||
|
||||
ip = GetNextItemProperty(oOld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* // ----------------------------------------------------------------------------
|
||||
// GZ, Sept. 30 2003
|
||||
// Special Version of Copy Item Properties for use with greater wild shape
|
||||
// oOld - Item equipped before polymorphing (source for item props)
|
||||
// oNew - Item equipped after polymorphing (target for item props)
|
||||
// bWeapon - Must be set TRUE when oOld is a weapon.
|
||||
// ----------------------------------------------------------------------------
|
||||
void IPWildShapeCopyItemProperties(object oOld, object oNew, int bWeapon = FALSE)
|
||||
{
|
||||
if (!GetIsObjectValid(oOld) || !GetIsObjectValid(oNew))
|
||||
return;
|
||||
|
||||
object oPC = GetItemPossessor(oOld);
|
||||
if (!GetIsObjectValid(oPC))
|
||||
{
|
||||
oPC = GetItemPossessor(oNew);
|
||||
}
|
||||
if (!GetIsObjectValid(oPC))
|
||||
{
|
||||
if (DEBUG) DoDebug("IPWS: Unable to determine item possessor");
|
||||
return;
|
||||
}
|
||||
|
||||
int bMonkGloves = GetLocalInt(oPC, "WEARING_MONK_GLOVES");
|
||||
|
||||
itemproperty ip = GetFirstItemProperty(oOld);
|
||||
while (GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if (bWeapon)
|
||||
{
|
||||
// Gloves override weapon damage <20> skip weapon damage properties
|
||||
if (bMonkGloves)
|
||||
{
|
||||
int nType = GetItemPropertyType(ip);
|
||||
|
||||
// skip damage props
|
||||
if (nType == ITEM_PROPERTY_DAMAGE_BONUS
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|
||||
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP)
|
||||
{
|
||||
if (DEBUG) DoDebug("IPWS: SKIPPED weapon damage IP");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG) DoDebug("IPWS: Applied non-damage weapon IP");
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oNew);
|
||||
}
|
||||
|
||||
}
|
||||
else if (GetWeaponRanged(oOld) == GetWeaponRanged(oNew) )
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
|
||||
}
|
||||
|
||||
ip = GetNextItemProperty(oOld);
|
||||
}
|
||||
} */
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Returns the current enhancement bonus of a weapon (+1 to +20), 0 if there is
|
||||
// no enhancement bonus. You can test for a specific type of enhancement bonus
|
||||
@@ -1883,7 +1990,7 @@ int IPDamageConstant(int nDamBon)
|
||||
case 49: nIPBonus = IP_CONST_DAMAGEBONUS_49; break;
|
||||
case 50: nIPBonus = IP_CONST_DAMAGEBONUS_50; break;
|
||||
}
|
||||
if (nDamBon > 20) nIPBonus = IP_CONST_DAMAGEBONUS_50;
|
||||
if (nDamBon > 50) nIPBonus = IP_CONST_DAMAGEBONUS_50;
|
||||
|
||||
return nIPBonus;
|
||||
}
|
||||
@@ -2019,4 +2126,6 @@ int IPOnHitSaveDC(int nSaveDC)
|
||||
if (nSaveDC > 26) nIPBonus = IP_CONST_ONHIT_SAVEDC_26;
|
||||
|
||||
return nIPBonus;
|
||||
} */
|
||||
} */
|
||||
|
||||
//:: void main(){}
|
||||
@@ -73,6 +73,7 @@ void SetMasteryOfElements();
|
||||
|
||||
//#include "lookup_2da_spell"
|
||||
#include "prcsp_reputation"
|
||||
#include "prc_inc_core"
|
||||
//#include "prc_inc_spells"
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "prc_ipfeat_const"
|
||||
#include "prc_feat_const"
|
||||
#include "inc_vfx_const"
|
||||
#include "prc_inc_nwscript"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
@@ -41,6 +41,8 @@ const int POWER_LIST_WARMIND = CLASS_TYPE_WARMIND;
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
int IsHiddenTalent(object oPC = OBJECT_SELF);
|
||||
|
||||
/**
|
||||
* Attempts to use psionic focus. If the creature was focused, it
|
||||
* loses the focus. If it has Epic Psionic Focus feats, it will
|
||||
@@ -520,9 +522,9 @@ void GainPsionicFocus(object oGainee = OBJECT_SELF)
|
||||
{
|
||||
int nPsySneak = 1;
|
||||
if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_2d6, oGainee))
|
||||
nPsySneak += 2;
|
||||
nPsySneak += 1;
|
||||
if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_3d6, oGainee))
|
||||
nPsySneak += 3;
|
||||
nPsySneak += 1;
|
||||
|
||||
SetLocalInt(oGainee, "PsyRogueSneak",nPsySneak);
|
||||
DelayCommand(0.1, ExecuteScript("prc_sneak_att", oGainee));
|
||||
@@ -786,69 +788,12 @@ int GetIsPsionicCharacter(object oCreature)
|
||||
GetHasFeat(FEAT_KALASHTAR_PP, oCreature) ||
|
||||
GetHasFeat(FEAT_NATPSIONIC_1, oCreature) ||
|
||||
GetHasFeat(FEAT_NATPSIONIC_2, oCreature) ||
|
||||
GetHasFeat(FEAT_NATPSIONIC_3, oCreature)
|
||||
GetHasFeat(FEAT_NATPSIONIC_3, oCreature) ||
|
||||
IsHiddenTalent(oCreature)
|
||||
// Racial psionicity signifying feats go here
|
||||
);
|
||||
}
|
||||
|
||||
int IsHiddenTalent(object oPC = OBJECT_SELF)
|
||||
{
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BIOFEEDBACK, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BITE_WOLF, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BOLT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BURST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CALLTOMIND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CALL_WEAPONRY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CHAMELEON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CLAWS_BEAST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_COMPRESSION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CONCEALTHOUGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CREATESOUND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CRYSTALSHARD, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DAZE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DECELERATION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DEFPRECOG, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DEMORALIZE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISABLE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISSIPATINGTOUCH, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISTRACT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC) ||
|
||||
//GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_FORCESCREEN, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_GREASE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_HAMMER, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_INERTIALARMOUR, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MATTERAGITATION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_CLAW, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_WEAPON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MINDTHRUST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MYLIGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRECOG, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRESC, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM_WEAPON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_SKATE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_STOMP, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_SYNESTHETE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_TELEMPATHICPRO, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_THICKSKIN, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_VIGOR, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_GRIP_IRON, oPC))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LocalCleanExtraFists(object oCreature)
|
||||
{
|
||||
int iIsCWeap, iIsEquip;
|
||||
@@ -985,6 +930,48 @@ int PracticedManifesting(object oManifester, int iManifestingClass, int iManifes
|
||||
|
||||
int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVALID, int nMaxPowerLevel = FALSE)
|
||||
{
|
||||
// Handle POWER_LIST_MISC (Hidden Talent) powers
|
||||
// Check if this is a power list call
|
||||
int nPowerType = GetLocalInt(oManifester, "PRC_UsePowerList");
|
||||
|
||||
if(nSpecificClass == CLASS_TYPE_INVALID && nPowerType == POWER_LIST_MISC)
|
||||
{
|
||||
if(DEBUG) DoDebug("psi_inc_core >> GetManifesterLevel: CLASS_TYPE_INVALID + POWER_LIST_MISC found!");
|
||||
// Check if character has psionic class levels
|
||||
int nPsionLevel = GetLevelByClass(CLASS_TYPE_PSION, oManifester);
|
||||
int nPsywarLevel = GetLevelByClass(CLASS_TYPE_PSYWAR, oManifester);
|
||||
int nWilderLevel = GetLevelByClass(CLASS_TYPE_WILDER, oManifester);
|
||||
int nWarmindLevel = GetLevelByClass(CLASS_TYPE_WARMIND, oManifester);
|
||||
int nFistOfZuokenLevel = GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oManifester);
|
||||
int nPsychicRogueLevel = GetLevelByClass(CLASS_TYPE_PSYCHIC_ROGUE, oManifester);
|
||||
|
||||
// If no psionic levels, use Charisma-based calculation (treat as 1st level)
|
||||
if(nPsionLevel + nPsywarLevel + nWilderLevel + nWarmindLevel +
|
||||
nFistOfZuokenLevel + nPsychicRogueLevel == 0)
|
||||
{
|
||||
// Hidden Talent: considered 1st-level manifester, but must have CHA 11+
|
||||
if(DEBUG) DoDebug("psi_inc_core >> GetManifesterLevel: Hidden Talent found!");
|
||||
if(GetAbilityScore(oManifester, ABILITY_CHARISMA) >= 11)
|
||||
return 1;
|
||||
else
|
||||
return 0; // Cannot manifest without CHA 11+
|
||||
}
|
||||
|
||||
if(DEBUG) DoDebug("psi_inc_core >> GetManifesterLevel: nSpecificClass=" + IntToString(nSpecificClass) +
|
||||
", nPowerType=" + IntToString(nPowerType));
|
||||
|
||||
// Has psionic levels - return highest manifester level
|
||||
int nHighest = 0;
|
||||
if(nPsionLevel > 0) nHighest = GetManifesterLevel(oManifester, CLASS_TYPE_PSION);
|
||||
if(nPsywarLevel > 0) nHighest = PRCMax(nHighest, GetManifesterLevel(oManifester, CLASS_TYPE_PSYWAR));
|
||||
if(nWilderLevel > 0) nHighest = PRCMax(nHighest, GetManifesterLevel(oManifester, CLASS_TYPE_WILDER));
|
||||
if(nWarmindLevel > 0) nHighest = PRCMax(nHighest, GetManifesterLevel(oManifester, CLASS_TYPE_WARMIND));
|
||||
if(nFistOfZuokenLevel > 0) nHighest = PRCMax(nHighest, GetManifesterLevel(oManifester, CLASS_TYPE_FIST_OF_ZUOKEN));
|
||||
if(nPsychicRogueLevel > 0) nHighest = PRCMax(nHighest, GetManifesterLevel(oManifester, CLASS_TYPE_PSYCHIC_ROGUE));
|
||||
|
||||
return nHighest;
|
||||
}
|
||||
|
||||
int nLevel;
|
||||
int nAdjust = GetLocalInt(oManifester, PRC_CASTERLEVEL_ADJUSTMENT);
|
||||
nAdjust -= GetLocalInt(oManifester, "WoLManifPenalty");
|
||||
@@ -1049,17 +1036,27 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
|
||||
|
||||
DelayCommand(1.0, DeleteLocalInt(oManifester, PRC_CASTERLEVEL_OVERRIDE));
|
||||
nLevel = GetLocalInt(oManifester, PRC_CASTERLEVEL_OVERRIDE);
|
||||
}
|
||||
else if(GetManifestingClass(oManifester) != CLASS_TYPE_INVALID)
|
||||
{
|
||||
//Gets the manifesting class
|
||||
int nManifestingClass = GetManifestingClass(oManifester);
|
||||
if(DEBUG) DoDebug("Manifesting Class #2: " + IntToString(nManifestingClass), oManifester);
|
||||
nLevel = GetLevelByClass(nManifestingClass, oManifester);
|
||||
// Add levels from +ML PrCs only for the first manifesting class
|
||||
nLevel += GetPsionicPRCLevels(oManifester, nManifestingClass);
|
||||
//nLevel += nManifestingClass == GetPrimaryPsionicClass(oManifester) ? GetPsionicPRCLevels(oManifester) : 0;
|
||||
|
||||
}
|
||||
else if(GetManifestingClass(oManifester) != CLASS_TYPE_INVALID)
|
||||
{
|
||||
//Gets the manifesting class
|
||||
int nManifestingClass = GetManifestingClass(oManifester);
|
||||
if(DEBUG) DoDebug("Manifesting Class #2: " + IntToString(nManifestingClass), oManifester);
|
||||
|
||||
nLevel = GetLevelByClass(nManifestingClass, oManifester);
|
||||
// Add levels from +ML PrCs only for the first manifesting class
|
||||
nLevel += GetPsionicPRCLevels(oManifester, nManifestingClass);
|
||||
|
||||
// CHECK: If this is Hidden Talent and character has no levels, set to 1
|
||||
if(nLevel == 0 && GetLocalInt(oManifester, "PRC_UsePowerList") == TRUE &&
|
||||
GetLocalInt(oManifester, "PRC_PowerListType") == POWER_LIST_MISC)
|
||||
{
|
||||
if(GetAbilityScore(oManifester, ABILITY_CHARISMA) >= 11)
|
||||
{
|
||||
if(DEBUG) DoDebug("GetManifesterLevel: Hidden Talent with no psionic levels, returning 1");
|
||||
nLevel = 1;
|
||||
}
|
||||
}
|
||||
// Psionic vestiges are tucked in here to override things.
|
||||
// This assumes that there will never be a psion with this spell effect manifesting things
|
||||
if (nManifestingClass == CLASS_TYPE_PSION && GetHasSpellEffect(VESTIGE_ARETE, oManifester) && !nMaxPowerLevel)
|
||||
@@ -1085,7 +1082,37 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
|
||||
// if(DEBUG) DoDebug("Level gotten via GetLevelByClass: " + IntToString(nLevel), oManifester);
|
||||
}
|
||||
|
||||
// If you have a primary psionic class and no manifester level yet, get levels based on that
|
||||
// If you have a primary psionic class and no manifester level yet, get levels based on that
|
||||
if (GetPrimaryPsionicClass(oManifester) && nLevel == 0)
|
||||
{
|
||||
int nClass = GetPrimaryPsionicClass(oManifester);
|
||||
nLevel = GetLevelByClass(nClass, oManifester);
|
||||
nLevel += GetPsionicPRCLevels(oManifester, nClass);
|
||||
nLevel += PracticedManifesting(oManifester, nClass, nLevel);
|
||||
}
|
||||
|
||||
// If everything else fails, check for Hidden Talent before returning 0
|
||||
if(nLevel == 0)
|
||||
{
|
||||
// Check if this is a Hidden Talent power
|
||||
if(GetLocalInt(oManifester, "PRC_UsePowerList") == POWER_LIST_MISC)
|
||||
{
|
||||
// Hidden Talent: manifester level is 1 if they have CHA 11+
|
||||
if(GetAbilityScore(oManifester, ABILITY_CHARISMA) >= 11)
|
||||
{
|
||||
if(DEBUG) DoDebug("GetManifesterLevel: Hidden Talent character, returning level 1");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(DEBUG) DoDebug("Failed to get manifester level for creature " + DebugObject2Str(oManifester) + ", using first class slot");
|
||||
//else WriteTimestampedLogEntry("Failed to get manifester level for creature " + DebugObject2Str(oManifester) + ", using first class slot");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* // If you have a primary psionic class and no manifester level yet, get levels based on that
|
||||
if (GetPrimaryPsionicClass(oManifester) && nLevel == 0)
|
||||
{
|
||||
int nClass = GetPrimaryPsionicClass(oManifester);
|
||||
@@ -1102,7 +1129,7 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// The bonuses inside only apply to normal manifestation
|
||||
if(!GetLocalInt(oManifester, PRC_IS_PSILIKE))
|
||||
@@ -1665,4 +1692,225 @@ int GetMaxPowerLevel(object oManifester)
|
||||
int nMax = StringToInt(Get2DACache(sFile, "MaxPowerLevel", nLevel));
|
||||
if (DEBUG) DoDebug("GetMaxPowerLevel is "+IntToString(nMax));
|
||||
return nMax;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/* START HIDDEN TALENT */
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
int IsHiddenTalent(object oPC = OBJECT_SELF)
|
||||
{
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BIOFEEDBACK, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BITE_WOLF, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BOLT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_BURST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CALLTOMIND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CALL_WEAPONRY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CHAMELEON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CLAWS_BEAST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_COMPRESSION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CONCEALTHOUGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CREATESOUND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_CRYSTALSHARD, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DAZE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DECELERATION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DEFPRECOG, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DEMORALIZE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISABLE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISSIPATINGTOUCH, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_DISTRACT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC) ||
|
||||
//GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_FORCESCREEN, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_GREASE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_HAMMER, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_INERTIALARMOUR, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MATTERAGITATION, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_CLAW, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_WEAPON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MINDTHRUST, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_MYLIGHT, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRECOG, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRESC, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM_WEAPON, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_SKATE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_STOMP, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_SYNESTHETE, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_TELEMPATHICPRO, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_THICKSKIN, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_VIGOR, oPC) ||
|
||||
GetHasFeat(FEAT_HIDDEN_TALENT_GRIP_IRON, oPC))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int GetHiddenTalentPowerFromFeat(int nFeatID)
|
||||
{
|
||||
// Map Hidden Talent feats to their corresponding power IDs
|
||||
// Using the same mappings as GetIsHiddenTalentPower()
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_BIOFEEDBACK) return POWER_BIOFEEDBACK;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_BITE_WOLF) return POWER_BITE_WOLF;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_BOLT) return POWER_BOLT;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_BURST) return POWER_BURST;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CALLTOMIND) return POWER_CALLTOMIND;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CALL_WEAPONRY) return POWER_CALL_WEAPONRY;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CHAMELEON) return POWER_CHAMELEON;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CLAWS_BEAST) return POWER_CLAWS_BEAST;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_COMPRESSION) return POWER_COMPRESSION;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CONCEALTHOUGHT) return POWER_CONCEALTHOUGHT;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CREATESOUND) return POWER_CREATESOUND;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_CRYSTALSHARD) return POWER_CRYSTALSHARD;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DAZE) return POWER_DAZE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DECELERATION) return POWER_DECELERATION;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DEFPRECOG) return POWER_DEFPRECOG;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DEMORALIZE) return POWER_DEMORALIZE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DISABLE) return POWER_DISABLE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DISSIPATINGTOUCH)return POWER_DISSIPATINGTOUCH;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_DISTRACT) return POWER_DISTRACT;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_ELFSIGHT) return POWER_ELFSIGHT;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_EMPATHY) return POWER_EMPATHY;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_EMPTYMIND) return POWER_EMPTYMIND;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_ENTANGLE) return POWER_ENTANGLE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_EXPANSION) return POWER_EXPANSION;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_FARHAND) return POWER_FARHAND;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_FORCESCREEN) return POWER_FORCESCREEN;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_GREASE) return POWER_GREASE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_HAMMER) return POWER_HAMMER;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_INERTIALARMOUR) return POWER_INERTIALARMOUR;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_MATTERAGITATION) return POWER_MATTERAGITATION;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_METAPHYSICAL_CLAW) return POWER_METAPHYSICAL_CLAW;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_METAPHYSICAL_WEAPON) return POWER_METAPHYSICAL_WEAPON;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_MINDTHRUST) return POWER_MINDTHRUST;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_MYLIGHT) return POWER_MYLIGHT;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_OFFPRECOG) return POWER_OFFPRECOG;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_OFFPRESC) return POWER_OFFPRESC;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_PREVENOM) return POWER_PREVENOM;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_PREVENOM_WEAPON) return POWER_PREVENOM_WEAPON;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_SKATE) return POWER_SKATE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_STOMP) return POWER_STOMP;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_SYNESTHETE) return POWER_SYNESTHETE;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_TELEMPATHICPRO) return POWER_TELEMPATHICPRO;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_THICKSKIN) return POWER_THICKSKIN;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_VIGOR) return POWER_VIGOR;
|
||||
if(nFeatID == FEAT_HIDDEN_TALENT_GRIP_IRON) return POWER_GRIP_IRON;
|
||||
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
int GetHiddenTalentCount(object oPC = OBJECT_SELF)
|
||||
{
|
||||
int nCount = 0;
|
||||
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BIOFEEDBACK, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BITE_WOLF, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BOLT, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_BURST, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CALLTOMIND, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CALL_WEAPONRY, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CHAMELEON, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CLAWS_BEAST, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_COMPRESSION, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CONCEALTHOUGHT, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CREATESOUND, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_CRYSTALSHARD, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DAZE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DECELERATION, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DEFPRECOG, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DEMORALIZE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DISABLE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DISSIPATINGTOUCH, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_DISTRACT, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) nCount++;
|
||||
//if (GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_FORCESCREEN, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_GREASE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_HAMMER, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_INERTIALARMOUR, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_MATTERAGITATION, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_CLAW, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_WEAPON, oPC))nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_MINDTHRUST, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_MYLIGHT, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRECOG, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRESC, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM_WEAPON, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_SKATE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_STOMP, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_SYNESTHETE, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_TELEMPATHICPRO, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_THICKSKIN, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_VIGOR, oPC)) nCount++;
|
||||
if (GetHasFeat(FEAT_HIDDEN_TALENT_GRIP_IRON, oPC)) nCount++;
|
||||
|
||||
return nCount;
|
||||
}
|
||||
|
||||
int GetIsHiddenTalentPower(object oPC, int nPower)
|
||||
{
|
||||
// Check each Hidden Talent feat to see if it grants this power
|
||||
if(nPower == POWER_BIOFEEDBACK && GetHasFeat(FEAT_HIDDEN_TALENT_BIOFEEDBACK, oPC)) return TRUE;
|
||||
if(nPower == POWER_BITE_WOLF && GetHasFeat(FEAT_HIDDEN_TALENT_BITE_WOLF, oPC)) return TRUE;
|
||||
if(nPower == POWER_BOLT && GetHasFeat(FEAT_HIDDEN_TALENT_BOLT, oPC)) return TRUE;
|
||||
if(nPower == POWER_BURST && GetHasFeat(FEAT_HIDDEN_TALENT_BURST, oPC)) return TRUE;
|
||||
if(nPower == POWER_CALLTOMIND && GetHasFeat(FEAT_HIDDEN_TALENT_CALLTOMIND, oPC)) return TRUE;
|
||||
if(nPower == POWER_CALL_WEAPONRY && GetHasFeat(FEAT_HIDDEN_TALENT_CALL_WEAPONRY, oPC)) return TRUE;
|
||||
if(nPower == POWER_CHAMELEON && GetHasFeat(FEAT_HIDDEN_TALENT_CHAMELEON, oPC)) return TRUE;
|
||||
if(nPower == POWER_CLAWS_BEAST && GetHasFeat(FEAT_HIDDEN_TALENT_CLAWS_BEAST, oPC)) return TRUE;
|
||||
if(nPower == POWER_COMPRESSION && GetHasFeat(FEAT_HIDDEN_TALENT_COMPRESSION, oPC)) return TRUE;
|
||||
if(nPower == POWER_CONCEALTHOUGHT && GetHasFeat(FEAT_HIDDEN_TALENT_CONCEALTHOUGHT, oPC)) return TRUE;
|
||||
if(nPower == POWER_CREATESOUND && GetHasFeat(FEAT_HIDDEN_TALENT_CREATESOUND, oPC)) return TRUE;
|
||||
if(nPower == POWER_CRYSTALSHARD && GetHasFeat(FEAT_HIDDEN_TALENT_CRYSTALSHARD, oPC)) return TRUE;
|
||||
if(nPower == POWER_DAZE && GetHasFeat(FEAT_HIDDEN_TALENT_DAZE, oPC)) return TRUE;
|
||||
if(nPower == POWER_DECELERATION && GetHasFeat(FEAT_HIDDEN_TALENT_DECELERATION, oPC)) return TRUE;
|
||||
if(nPower == POWER_DEFPRECOG && GetHasFeat(FEAT_HIDDEN_TALENT_DEFPRECOG, oPC)) return TRUE;
|
||||
if(nPower == POWER_DEMORALIZE && GetHasFeat(FEAT_HIDDEN_TALENT_DEMORALIZE, oPC)) return TRUE;
|
||||
if(nPower == POWER_DISABLE && GetHasFeat(FEAT_HIDDEN_TALENT_DISABLE, oPC)) return TRUE;
|
||||
if(nPower == POWER_DISSIPATINGTOUCH && GetHasFeat(FEAT_HIDDEN_TALENT_DISSIPATINGTOUCH, oPC)) return TRUE;
|
||||
if(nPower == POWER_DISTRACT && GetHasFeat(FEAT_HIDDEN_TALENT_DISTRACT, oPC)) return TRUE;
|
||||
if(nPower == POWER_ELFSIGHT && GetHasFeat(FEAT_HIDDEN_TALENT_ELFSIGHT, oPC)) return TRUE;
|
||||
if(nPower == POWER_EMPATHY && GetHasFeat(FEAT_HIDDEN_TALENT_EMPATHY, oPC)) return TRUE;
|
||||
if(nPower == POWER_EMPTYMIND && GetHasFeat(FEAT_HIDDEN_TALENT_EMPTYMIND, oPC)) return TRUE;
|
||||
//if(nPower == POWER_ENERGYRAY && GetHasFeat(FEAT_HIDDEN_TALENT_ENERGYRAY, oPC)) return TRUE;
|
||||
if(nPower == POWER_ENTANGLE && GetHasFeat(FEAT_HIDDEN_TALENT_ENTANGLE, oPC)) return TRUE;
|
||||
if(nPower == POWER_EXPANSION && GetHasFeat(FEAT_HIDDEN_TALENT_EXPANSION, oPC)) return TRUE;
|
||||
if(nPower == POWER_FARHAND && GetHasFeat(FEAT_HIDDEN_TALENT_FARHAND, oPC)) return TRUE;
|
||||
if(nPower == POWER_FORCESCREEN && GetHasFeat(FEAT_HIDDEN_TALENT_FORCESCREEN, oPC)) return TRUE;
|
||||
if(nPower == POWER_GREASE && GetHasFeat(FEAT_HIDDEN_TALENT_GREASE, oPC)) return TRUE;
|
||||
if(nPower == POWER_HAMMER && GetHasFeat(FEAT_HIDDEN_TALENT_HAMMER, oPC)) return TRUE;
|
||||
if(nPower == POWER_INERTIALARMOUR && GetHasFeat(FEAT_HIDDEN_TALENT_INERTIALARMOUR, oPC)) return TRUE;
|
||||
if(nPower == POWER_MATTERAGITATION && GetHasFeat(FEAT_HIDDEN_TALENT_MATTERAGITATION, oPC)) return TRUE;
|
||||
if(nPower == POWER_METAPHYSICAL_CLAW && GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_CLAW, oPC)) return TRUE;
|
||||
if(nPower == POWER_METAPHYSICAL_WEAPON && GetHasFeat(FEAT_HIDDEN_TALENT_METAPHYSICAL_WEAPON, oPC)) return TRUE;
|
||||
if(nPower == POWER_MINDTHRUST && GetHasFeat(FEAT_HIDDEN_TALENT_MINDTHRUST, oPC)) return TRUE;
|
||||
if(nPower == POWER_MYLIGHT && GetHasFeat(FEAT_HIDDEN_TALENT_MYLIGHT, oPC)) return TRUE;
|
||||
if(nPower == POWER_OFFPRECOG && GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRECOG, oPC)) return TRUE;
|
||||
if(nPower == POWER_OFFPRESC && GetHasFeat(FEAT_HIDDEN_TALENT_OFFPRESC, oPC)) return TRUE;
|
||||
if(nPower == POWER_PREVENOM && GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM, oPC)) return TRUE;
|
||||
if(nPower == POWER_PREVENOM_WEAPON && GetHasFeat(FEAT_HIDDEN_TALENT_PREVENOM_WEAPON, oPC)) return TRUE;
|
||||
if(nPower == POWER_SKATE && GetHasFeat(FEAT_HIDDEN_TALENT_SKATE, oPC)) return TRUE;
|
||||
if(nPower == POWER_STOMP && GetHasFeat(FEAT_HIDDEN_TALENT_STOMP, oPC)) return TRUE;
|
||||
if(nPower == POWER_SYNESTHETE && GetHasFeat(FEAT_HIDDEN_TALENT_SYNESTHETE, oPC)) return TRUE;
|
||||
if(nPower == POWER_TELEMPATHICPRO && GetHasFeat(FEAT_HIDDEN_TALENT_TELEMPATHICPRO, oPC)) return TRUE;
|
||||
if(nPower == POWER_THICKSKIN && GetHasFeat(FEAT_HIDDEN_TALENT_THICKSKIN, oPC)) return TRUE;
|
||||
if(nPower == POWER_VIGOR && GetHasFeat(FEAT_HIDDEN_TALENT_VIGOR, oPC)) return TRUE;
|
||||
if(nPower == POWER_GRIP_IRON && GetHasFeat(FEAT_HIDDEN_TALENT_GRIP_IRON, oPC)) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ object GetSplitPsionicRayTarget(struct manifestation manif, object oPrimaryTarge
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "psi_inc_core"
|
||||
#include "psi_inc_psifunc"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
|
||||
@@ -572,7 +572,11 @@ int GetMaxPowerCount(object oCreature, int nList)
|
||||
|
||||
int GetHasPower(int nPower, object oCreature = OBJECT_SELF)
|
||||
{
|
||||
if((GetLevelByClass(CLASS_TYPE_PSION, oCreature)
|
||||
// Check MISC list first (for Hidden Talent and similar feats)
|
||||
if(GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_INVALID), oCreature))
|
||||
return TRUE;
|
||||
|
||||
if((GetLevelByClass(CLASS_TYPE_PSION, oCreature)
|
||||
&& GetHasFeat(GetClassFeatFromPower(nPower, CLASS_TYPE_PSION), oCreature)
|
||||
) ||
|
||||
(GetLevelByClass(CLASS_TYPE_PSYWAR, oCreature)
|
||||
|
||||
@@ -93,9 +93,8 @@ void GainPowerPoints(object oChar, int nGain, int bCanExceedMax = FALSE, int bIn
|
||||
* @param bInform If TRUE, runs TellCharacterPowerPointStatus() on oChar
|
||||
* after making the modification.
|
||||
*/
|
||||
/*
|
||||
void GainTemporaryPowerPoints(object oChar, int nGain, float fDuration, int bInform = TRUE);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Decreases the character's current power point count by up to the given
|
||||
* amount, limited to not going below 0.
|
||||
@@ -138,8 +137,12 @@ int _GetFeatBonusPP(object oChar)
|
||||
{
|
||||
int nBonusPP = 0;
|
||||
|
||||
//:: Wild Talent & Hidden Talents
|
||||
if(GetHasFeat(FEAT_WILD_TALENT, oChar) || IsHiddenTalent())
|
||||
//:: Wild Talent
|
||||
if(GetHasFeat(FEAT_WILD_TALENT, oChar))
|
||||
nBonusPP += 2;
|
||||
|
||||
//:: Hidden Talent
|
||||
if(GetHasFeat(FEAT_HIDDEN_TALENT, oChar))
|
||||
nBonusPP += 2;
|
||||
|
||||
//:: Psionic Feats
|
||||
|
||||
@@ -40,7 +40,8 @@ void IdentifyPower(object oManifester, int nPowerId);
|
||||
|
||||
// Always access via psi_inc_psifunc.
|
||||
|
||||
//#include "psi_inc_core"
|
||||
#include "psi_inc_core"
|
||||
#include "inc_2dacache"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
|
||||
@@ -407,6 +407,8 @@ void _CleanManifestationVariables(object oManifester)
|
||||
DeleteLocalInt(oManifester, PRC_POWER_LEVEL);
|
||||
DeleteLocalInt(oManifester, PRC_IS_PSILIKE);
|
||||
DeleteLocalInt(oManifester, PRC_AUGMENT_OVERRIDE);
|
||||
DeleteLocalInt(oManifester, "PRC_UsePowerList");
|
||||
DeleteLocalInt(oManifester, "PRC_PowerListType");
|
||||
}
|
||||
|
||||
/** Internal function.
|
||||
@@ -692,10 +694,28 @@ void _UsePowerAux(object oManifester, object oMfToken, int nSpellId,
|
||||
|
||||
struct manifestation EvaluateManifestation(object oManifester, object oTarget, struct power_augment_profile pap, int nMetaPsiFlags)
|
||||
{
|
||||
/* Get some data */
|
||||
//:: Handle Hidden Talent
|
||||
int nSpellID = PRCGetSpellId();
|
||||
int bIsHiddenTalent = GetIsHiddenTalentPower(oManifester, nSpellID);
|
||||
if(bIsHiddenTalent)
|
||||
{
|
||||
SetLocalInt(oManifester, "PRC_UsePowerList", TRUE);
|
||||
SetLocalInt(oManifester, "PRC_PowerListType", POWER_LIST_MISC);
|
||||
}
|
||||
/* Get some data */
|
||||
int bIgnoreConstraints = (DEBUG) ? GetLocalInt(oManifester, PRC_DEBUG_IGNORE_CONSTRAINTS) : FALSE;
|
||||
|
||||
// Manifester-related stuff
|
||||
int nManifesterLevel = GetManifesterLevel(oManifester);
|
||||
//int nManifesterLevel = GetManifesterLevel(oManifester);
|
||||
int nManifesterLevel;
|
||||
if(bIsHiddenTalent)
|
||||
{
|
||||
nManifesterLevel = GetManifesterLevel(oManifester, CLASS_TYPE_INVALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
nManifesterLevel = GetManifesterLevel(oManifester);
|
||||
}
|
||||
int nPowerLevel = GetPowerLevel(oManifester);
|
||||
int nClass = GetManifestingClass(oManifester);
|
||||
int nWildSurge = GetWildSurge(oManifester);
|
||||
@@ -714,6 +734,8 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
|
||||
manif.nManifesterLevel = nManifesterLevel;
|
||||
manif.nSpellID = PRCGetSpellId();
|
||||
|
||||
|
||||
|
||||
// Run an ability score check to see if the manifester can manifest the power at all
|
||||
if (bIsPsiLike)
|
||||
{
|
||||
@@ -767,7 +789,9 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
|
||||
//If the manifester does not have enough points before hostile modifiers, cancel power
|
||||
if(manif.nPPCost > nManifesterPP && !bIsPsiLike && !bIgnoreConstraints)
|
||||
{
|
||||
FloatingTextStrRefOnCreature(16826412, oManifester, FALSE); // "You do not have enough Power Points to manifest this power"
|
||||
// DEBUG: show why the cost over cap branch triggered
|
||||
FloatingTextStringOnCreature("DEBUG: manif.nManifesterLevel=" + IntToString(manif.nManifesterLevel) + " manif.nPPCost=" + IntToString(manif.nPPCost) +" PRC_UsePowerList=" + IntToString(GetLocalInt(manif.oManifester, "PRC_UsePowerList")), manif.oManifester, FALSE);
|
||||
FloatingTextStrRefOnCreature(16826412, oManifester, FALSE); // "You do not have enough Power Points to manifest this power"
|
||||
manif.bCanManifest = FALSE;
|
||||
}
|
||||
// The manifester has enough power points that they would be able to use the power, barring extra costs
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "prc_class_const"
|
||||
*/
|
||||
#include "prc_alterations"
|
||||
#include "prcsp_engine"
|
||||
|
||||
// Constants that dictate ResistPower results
|
||||
const int POWER_RESIST_FAIL = 1;
|
||||
|
||||
@@ -75,6 +75,15 @@ int PsiPrePowerCastCode()
|
||||
|
||||
int nContinue = !ExecuteScriptAndReturnInt("prespellcode", oManifester);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Forsakers can't use psionics
|
||||
//---------------------------------------------------------------------------
|
||||
if (nContinue && GetLevelByClass(CLASS_TYPE_FORSAKER, oManifester))
|
||||
{
|
||||
FloatingTextStringOnCreature("Forsakers cannot manifest psionic powers!", oManifester, FALSE);
|
||||
nContinue = FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Break any spell require maintaining concentration
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -209,3 +218,4 @@ int PsiPrePowerCastCode()
|
||||
return nContinue;
|
||||
}
|
||||
|
||||
//:: void main (){}
|
||||
@@ -41,6 +41,7 @@ const string _MYSTERY_LIST_MISC_ARRAY = "_MysteriesKnownMiscArray";
|
||||
const string _MYSTERY_LIST_LEVEL_ARRAY = "_MysteriesKnownLevelArray_";
|
||||
const string _MYSTERY_LIST_GENERAL_ARRAY = "_MysteriesKnownGeneralArray";
|
||||
|
||||
#include "shd_inc_shdfunc"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
@@ -191,7 +192,8 @@ int PathFeatToIPFeat(int nFeat);
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "inc_lookups"
|
||||
#include "inc_pers_array"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
@@ -518,7 +520,7 @@ int GetMaxMysteryLevelLearnable(object oShadow, int nClass, int nType)
|
||||
if(DEBUG) DoDebug("GetMaxMysteryLevelLearnable nType: " + IntToString(nType));
|
||||
|
||||
// Rules Quote:
|
||||
// Within a category<72>Apprentice, Initiate, Master<65>you must have at least two mysteries of any given level
|
||||
// Within a category<72>Apprentice, Initiate, Master<65>you must have at least two mysteries of any given level
|
||||
// before you can take any mysteries of the next higher level. For instance, you must have two 1st-level
|
||||
// mysteries before you can take any 2nds, and at least two 2nds before you can take any 3rds.
|
||||
int nMaxLrn, i, nMystLevel, nCount1, nCount2;
|
||||
|
||||
@@ -210,6 +210,7 @@ int GetHasNocturnal(object oShadow, int nPath);
|
||||
#include "prc_alterations"
|
||||
#include "shd_inc_myst"
|
||||
#include "shd_inc_mystknwn"
|
||||
#include "lookup_2da_spell"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
@@ -236,12 +237,12 @@ int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLAS
|
||||
// For when you want to assign the caster level.
|
||||
if(nLevel)
|
||||
{
|
||||
if(DEBUG) SendMessageToPC(oShadow, "GetShadowcasterLevel(): Forced-level shadowcasting at level " + IntToString(nLevel));
|
||||
if(DEBUG) DoDebug("GetShadowcasterLevel(): Forced-level shadowcasting at level " + IntToString(nLevel));
|
||||
//DelayCommand(1.0, DeleteLocalInt(oShadow, PRC_CASTERLEVEL_OVERRIDE));
|
||||
return nLevel + nAdjust;
|
||||
}
|
||||
|
||||
if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: "+GetName(oShadow)+" is a "+IntToString(nSpecificClass), oShadow);
|
||||
if (DEBUG) DoDebug("GetShadowcasterLevel: "+GetName(oShadow)+" is a "+IntToString(nSpecificClass), oShadow);
|
||||
// The function user needs to know the character's Shadowcaster level in a specific class
|
||||
// instead of whatever the character last shadowcast a mystery as
|
||||
if(nSpecificClass != CLASS_TYPE_INVALID)
|
||||
@@ -288,7 +289,7 @@ int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLAS
|
||||
nLevel -= 4;
|
||||
}
|
||||
|
||||
if(DEBUG) FloatingTextStringOnCreature("Shadowcaster Level: " + IntToString(nLevel), oShadow, FALSE);
|
||||
if(DEBUG) DoDebug("Shadowcaster Level: " + IntToString(nLevel));
|
||||
|
||||
return nLevel + nAdjust;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "prc_inc_spells"
|
||||
#include "inc_utility"
|
||||
#include "prc_inc_itmrstr"
|
||||
#include "shd_inc_shdfunc"
|
||||
#include "lookup_2da_spell"
|
||||
|
||||
// This function holds all functions that are supposed to run before the actual
|
||||
// spellscript gets run. If this functions returns FALSE, the spell is aborted
|
||||
@@ -132,6 +134,15 @@ int ShadPreMystCastCode()
|
||||
|
||||
int nContinue = !ExecuteScriptAndReturnInt("prespellcode",oShadow);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Block forsakers from using shadowcasting
|
||||
//---------------------------------------------------------------------------
|
||||
if(GetLevelByClass(CLASS_TYPE_FORSAKER, oShadow) > 0)
|
||||
{
|
||||
SendMessageToPC(oShadow, "Forsakers cannot use the power of shadowcasting.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Break any spell require maintaining concentration
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -277,4 +288,6 @@ int ShadPreMystCastCode()
|
||||
|
||||
if(DEBUG) DoDebug("ShadPreMystCastCode nContinue #6: " + IntToString(nContinue));
|
||||
return nContinue;
|
||||
}
|
||||
}
|
||||
|
||||
//:: void main (){}
|
||||
|
||||
@@ -1154,6 +1154,7 @@ int GetIsDisciplineWeapon(object oWeapon, int nDiscipline)
|
||||
// Invalid is empty handed / Unarmed strike
|
||||
if(nType == BASE_ITEM_INVALID
|
||||
|| nType == BASE_ITEM_QUARTERSTAFF
|
||||
|| nType == BASE_ITEM_MAGICSTAFF
|
||||
|| nType == BASE_ITEM_SHORTSWORD
|
||||
|| nType == BASE_ITEM_NUNCHAKU)
|
||||
return TRUE;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "prc_inc_spells"
|
||||
#include "inc_utility"
|
||||
#include "x2_inc_spellhook"
|
||||
#include "tob_inc_tobfunc"
|
||||
|
||||
// This function holds all functions that are supposed to run before the actual
|
||||
// spellscript gets run. If this functions returns FALSE, the spell is aborted
|
||||
@@ -78,7 +79,14 @@ int PreManeuverCastCode()
|
||||
//---------------------------------------------------------------------------
|
||||
if(nContinue)
|
||||
nContinue = !GetLocalInt(oInitiator, "CrusaderBreak");
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Forsakers can't use supernatural maneuvers
|
||||
//---------------------------------------------------------------------------
|
||||
if (nContinue && GetIsManeuverSupernatural(nMoveId) && GetLevelByClass(CLASS_TYPE_FORSAKER, oInitiator))
|
||||
{
|
||||
FloatingTextStringOnCreature("Forsakers cannot use supernatural maneuvers!", oInitiator, FALSE);
|
||||
nContinue = FALSE;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
// Run NullPsionicsField Check
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -109,11 +109,14 @@ int GetIsSyllable(int nSpellId);
|
||||
*/
|
||||
int DoSpellTruenameCheck(object oTrueSpeaker, object oTarget, int nPersonal = FALSE);
|
||||
|
||||
string GetNormalUtterSpellId(int nSpellId);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Includes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_spells"
|
||||
#include "true_inc_trufunc"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
|
||||
@@ -260,6 +260,7 @@ int GetCadenceCount(object oTrueSpeaker);
|
||||
#include "prc_alterations"
|
||||
#include "true_inc_utter"
|
||||
#include "true_inc_truknwn"
|
||||
#include "true_inc_truespk"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
|
||||
@@ -141,6 +141,7 @@ int GetHasUtterance(int nUtter, object oCreature = OBJECT_SELF);
|
||||
#include "inc_pers_array"
|
||||
#include "prc_inc_nwscript"
|
||||
#include "inc_lookups"
|
||||
#include "prc_x2_itemprop"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Internal functions */
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "prc_inc_spells"
|
||||
#include "inc_utility"
|
||||
#include "prc_inc_itmrstr"
|
||||
#include "true_inc_trufunc"
|
||||
|
||||
|
||||
// This function holds all functions that are supposed to run before the actual
|
||||
@@ -42,6 +43,16 @@ int TruePreUtterCastCode()
|
||||
|
||||
int nContinue = !ExecuteScriptAndReturnInt("prespellcode",oTrueSpeaker);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Block forsakers from using truenaming
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
if(GetLevelByClass(CLASS_TYPE_FORSAKER, oTrueSpeaker) > 0)
|
||||
{
|
||||
SendMessageToPC(oTrueSpeaker, "Forsakers cannot use the power of truenaming.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Break any spell require maintaining concentration
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -144,8 +144,103 @@ int PRCGetUserSpecificSpellScriptFinished();
|
||||
#include "pnp_shft_main"
|
||||
#include "inc_dynconv"
|
||||
#include "inc_npc"
|
||||
#include "inc_infusion"
|
||||
#include "prc_add_spell_dc"
|
||||
|
||||
|
||||
int Spontaneity(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
|
||||
{
|
||||
if(GetLocalInt(oCaster, "PRC_SpontRegen"))
|
||||
{
|
||||
DeleteLocalInt(oCaster, "PRC_SpontRegen");
|
||||
|
||||
int nMetamagic = GetMetaMagicFeat();//we need bioware metamagic here
|
||||
nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nCastingClass);
|
||||
nSpellLevel += GetMetaMagicSpellLevelAdjustment(nMetamagic);
|
||||
|
||||
int nRegenSpell;
|
||||
|
||||
if(nCastingClass == CLASS_TYPE_DRUID)
|
||||
{
|
||||
switch(nSpellLevel)
|
||||
{
|
||||
case 0: return TRUE;
|
||||
case 1: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
|
||||
case 2: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
|
||||
case 3: nRegenSpell = SPELL_REGEN_RING; break;
|
||||
case 4: nRegenSpell = SPELL_REGEN_SERIOUS_WOUNDS; break;
|
||||
case 5: nRegenSpell = SPELL_REGEN_CRITICAL_WOUNDS; break;
|
||||
case 6: nRegenSpell = SPELL_REGEN_CIRCLE; break;
|
||||
case 7: nRegenSpell = SPELL_REGEN_CIRCLE; break;
|
||||
case 8: nRegenSpell = SPELL_REGEN_CIRCLE; break;
|
||||
case 9: nRegenSpell = SPELL_REGENERATE; break;
|
||||
}
|
||||
ActionCastSpell(nRegenSpell, 0, 0, 0, METAMAGIC_NONE, CLASS_TYPE_DRUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(nSpellLevel)
|
||||
{
|
||||
case 0: return TRUE;
|
||||
case 1: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
|
||||
case 2: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
|
||||
case 3: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
|
||||
case 4: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
|
||||
case 5: nRegenSpell = SPELL_REGEN_SERIOUS_WOUNDS; break;
|
||||
case 6: nRegenSpell = SPELL_REGEN_CRITICAL_WOUNDS; break;
|
||||
case 7: nRegenSpell = SPELL_REGENERATE; break;
|
||||
case 8: nRegenSpell = SPELL_REGENERATE; break;
|
||||
case 9: nRegenSpell = SPELL_REGENERATE; break;
|
||||
}
|
||||
|
||||
ActionCastSpell(nRegenSpell, 0, 0, 0, METAMAGIC_NONE, nCastingClass);
|
||||
}
|
||||
//Don't cast original spell
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
|
||||
{
|
||||
if(nCastingClass != CLASS_TYPE_DRUID)
|
||||
return TRUE;
|
||||
|
||||
if(GetLocalInt(oCaster, "PRC_SpontSummon"))
|
||||
{
|
||||
DeleteLocalInt(oCaster, "PRC_SpontSummon");
|
||||
int nMetamagic = GetMetaMagicFeat();//we need bioware metamagic here
|
||||
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, CLASS_TYPE_DRUID);
|
||||
nSpellLevel += GetMetaMagicSpellLevelAdjustment(nMetamagic);
|
||||
int nSummonSpell;
|
||||
switch(nSpellLevel)
|
||||
{
|
||||
case 0: return TRUE;
|
||||
case 1: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_1; break;
|
||||
case 2: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_2; break;
|
||||
case 3: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_3; break;
|
||||
case 4: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_4; break;
|
||||
case 5: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_5; break;
|
||||
case 6: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_6; break;
|
||||
case 7: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_7; break;
|
||||
case 8: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_8; break;
|
||||
case 9: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_9; break;
|
||||
}
|
||||
|
||||
//:: All SNA spells are subradial spells
|
||||
SetLocalInt(oCaster, "DomainOrigSpell", nSummonSpell);
|
||||
SetLocalInt(oCaster, "DomainCastLevel", nSpellLevel);
|
||||
SetLocalInt(oCaster, "DomainCastClass", CLASS_TYPE_DRUID);
|
||||
StartDynamicConversation("prc_domain_conv", oCaster, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oCaster);
|
||||
|
||||
//Don't cast original spell
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
|
||||
{
|
||||
if(nCastingClass != CLASS_TYPE_DRUID)
|
||||
return TRUE;
|
||||
@@ -191,6 +286,8 @@ int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpell
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int nMetamagic, string sComponents)
|
||||
{
|
||||
if(!GetIsArcaneClass(nCastingClass))
|
||||
@@ -904,7 +1001,8 @@ int ShifterCasting(object oCaster, object oSpellCastItem, int nSpellLevel, int n
|
||||
{
|
||||
// Potion drinking is not restricted
|
||||
if(GetBaseItemType(oSpellCastItem) == BASE_ITEM_ENCHANTED_POTION
|
||||
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_POTIONS)
|
||||
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_POTIONS
|
||||
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_INFUSED_HERB)
|
||||
return TRUE;
|
||||
|
||||
//OnHit properties on equipped items not restricted
|
||||
@@ -1441,8 +1539,9 @@ int CheckSecondaryPrC(object oPC = OBJECT_SELF)
|
||||
if (GetHasFeat(FEAT_WILDMAGE_SPELLCASTING_BARD)) return TRUE;
|
||||
if (GetHasFeat(FEAT_WWOC_SPELLCASTING_BARD)) return TRUE;
|
||||
}
|
||||
else if (bBeguiler)
|
||||
if (bBeguiler)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: CheckSecondaryPrC >>> Entering Beguiler", oPC);
|
||||
if (GetHasFeat(FEAT_ABCHAMP_SPELLCASTING_BEGUILER)) return TRUE;
|
||||
if (GetHasFeat(FEAT_AOTS_SPELLCASTING_BEGUILER)) return TRUE;
|
||||
if (GetHasFeat(FEAT_ALCHEM_SPELLCASTING_BEGUILER)) return TRUE;
|
||||
@@ -1492,8 +1591,9 @@ int CheckSecondaryPrC(object oPC = OBJECT_SELF)
|
||||
|
||||
|
||||
}
|
||||
else if (bDuskblade)
|
||||
if (bDuskblade)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: CheckSecondaryPrC >>> Entering Dusblade", oPC);
|
||||
if (GetHasFeat(FEAT_ABCHAMP_SPELLCASTING_DUSKBLADE)) return TRUE;
|
||||
if (GetHasFeat(FEAT_AOTS_SPELLCASTING_DUSKBLADE)) return TRUE;
|
||||
if (GetHasFeat(FEAT_ALCHEM_SPELLCASTING_DUSKBLADE)) return TRUE;
|
||||
@@ -1540,8 +1640,9 @@ int CheckSecondaryPrC(object oPC = OBJECT_SELF)
|
||||
|
||||
|
||||
}
|
||||
else if (bSorcerer)
|
||||
if (bSorcerer)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: CheckSecondaryPrC >>> Entering Sorcerer", oPC);
|
||||
if (GetHasFeat(FEAT_ABERRATION_SPELLCASTING_DRIDER)) return TRUE;
|
||||
if (GetHasFeat(FEAT_MONSTROUS_SPELLCASTING_ARKAMOI)) return TRUE;
|
||||
if (GetHasFeat(FEAT_MONSTROUS_SPELLCASTING_MARRUTACT)) return TRUE;
|
||||
@@ -1599,8 +1700,9 @@ int CheckSecondaryPrC(object oPC = OBJECT_SELF)
|
||||
if (GetHasFeat(FEAT_WILDMAGE_SPELLCASTING_SORCERER)) return TRUE;
|
||||
if (GetHasFeat(FEAT_WWOC_SPELLCASTING_SORCERER)) return TRUE;
|
||||
}
|
||||
else if (bWarmage)
|
||||
if (bWarmage)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: CheckSecondaryPrC >>> Entering Warmage", oPC);
|
||||
if (GetHasFeat(FEAT_AOTS_SPELLCASTING_WARMAGE)) return TRUE;
|
||||
if (GetHasFeat(FEAT_ALCHEM_SPELLCASTING_WARMAGE)) return TRUE;
|
||||
if (GetHasFeat(FEAT_ANIMA_SPELLCASTING_WARMAGE)) return TRUE;
|
||||
@@ -1662,14 +1764,71 @@ int BardSorcPrCCheck(object oCaster, int nCastingClass, object oSpellCastItem)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//check its a sorc spell
|
||||
//check its a sorcerer spell
|
||||
if(nCastingClass == CLASS_TYPE_SORCERER)
|
||||
{
|
||||
if (CheckSecondaryPrC(oCaster) == TRUE)
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> nCastingClass is Sorcerer.", oCaster);
|
||||
//no need to check further if new spellbooks are disabled
|
||||
if(GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK))
|
||||
{
|
||||
if (DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> Sorcerer w/RHD found.", oCaster);
|
||||
if (DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> PRC_SORC_DISALLOW_NEWSPELLBOOK.", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
//check they have sorcerer levels
|
||||
if(!GetLevelByClass(CLASS_TYPE_SORCERER, oCaster))
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> Not a sorcerer.", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
//check if they are casting via new spellbook
|
||||
if(GetLocalInt(oCaster, "NSB_Class") != CLASS_TYPE_SORCERER && GetLevelByClass(CLASS_TYPE_ULTIMATE_MAGUS, oCaster))
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> UltMagus using new spellbook.", oCaster);
|
||||
return FALSE;
|
||||
}
|
||||
//check if they are casting via new spellbook
|
||||
if(GetLocalInt(oCaster, "NSB_Class") == CLASS_TYPE_SORCERER)
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> Using new spellbook.", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
if(GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster) > 0 && CheckSecondaryPrC(oCaster) == TRUE)
|
||||
{
|
||||
if (DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> Sublime Chord w/RHD found.", oCaster);
|
||||
FloatingTextStringOnCreature("You must use the new spellbook on the class radial.", oCaster, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
if (CheckSecondaryPrC(oCaster) == TRUE)
|
||||
{
|
||||
if (DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> Sorcerer w/RHD found.", oCaster);
|
||||
FloatingTextStringOnCreature("You must use the new spellbook on the class radial.", oCaster, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
//check they have arcane PrC or Draconic Arcane Grace/Breath
|
||||
if(!(GetArcanePRCLevels(oCaster, nCastingClass) - GetLevelByClass(CLASS_TYPE_SUBLIME_CHORD, oCaster))
|
||||
&& !(GetHasFeat(FEAT_DRACONIC_GRACE, oCaster) || GetHasFeat(FEAT_DRACONIC_BREATH, oCaster)))
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> First Sublime Chord check.", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//check they have sorcerer in first arcane slot
|
||||
//if(GetPrimaryArcaneClass() != CLASS_TYPE_SORCERER)
|
||||
if(GetPrCAdjustedCasterLevelByType(TYPE_ARCANE, oCaster, TRUE) != GetPrCAdjustedCasterLevelByType(CLASS_TYPE_SORCERER, oCaster, TRUE))
|
||||
{
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook: BardSorcPrCCheck >>> GetPrCAdjustedCasterLevelByType.", oCaster);
|
||||
return TRUE;
|
||||
}
|
||||
//at this point, they must be using the bioware spellbook
|
||||
//from a class that adds to bard
|
||||
FloatingTextStringOnCreature("You must use the new spellbook on the class radial.", oCaster, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* //check its a sorc spell
|
||||
if(nCastingClass == CLASS_TYPE_SORCERER)
|
||||
{
|
||||
//no need to check further if new spellbooks are disabled
|
||||
if(GetPRCSwitch(PRC_SORC_DISALLOW_NEWSPELLBOOK))
|
||||
return TRUE;
|
||||
@@ -1708,7 +1867,7 @@ int BardSorcPrCCheck(object oCaster, int nCastingClass, object oSpellCastItem)
|
||||
//from a class that adds to sorc
|
||||
FloatingTextStringOnCreature("You must use the new spellbook on the class radial.", oCaster, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
} */
|
||||
|
||||
//check its a bard spell
|
||||
if(nCastingClass == CLASS_TYPE_BARD)
|
||||
@@ -2743,7 +2902,7 @@ int WandEquipped(object oCaster, object oSpellCastItem)
|
||||
|
||||
int nType = GetBaseItemType(oSpellCastItem);
|
||||
|
||||
if(nType == BASE_ITEM_MAGICWAND || nType == BASE_ITEM_ENCHANTED_WAND) // Has to be a wand, obv
|
||||
if(nType == BASE_ITEM_MAGICWAND || nType == BASE_ITEM_ENCHANTED_WAND || nType == BASE_ITEM_CRAFTED_SCEPTER) // Has to be a wand, obv
|
||||
{
|
||||
if(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCaster) == oSpellCastItem || GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCaster) == oSpellCastItem) // Needs to be equipped
|
||||
{
|
||||
@@ -2751,7 +2910,7 @@ int WandEquipped(object oCaster, object oSpellCastItem)
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStringOnCreature("You must equip a wand to cast from it.", oCaster, FALSE);
|
||||
FloatingTextStringOnCreature("You must equip this item to cast from it.", oCaster, FALSE);
|
||||
return FALSE; // It's a wand not equipped
|
||||
}
|
||||
}
|
||||
@@ -3188,6 +3347,28 @@ int X2PreSpellCastCode2()
|
||||
X2BreakConcentrationSpells();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Herbal Infusion Use check
|
||||
//---------------------------------------------------------------------------
|
||||
if(nContinue && (GetBaseItemType(oSpellCastItem) == BASE_ITEM_INFUSED_HERB))
|
||||
{
|
||||
int bIsSubradial = GetIsSubradialSpell(nSpellID);
|
||||
|
||||
if(bIsSubradial)
|
||||
{
|
||||
nSpellID = GetMasterSpellFromSubradial(nSpellID);
|
||||
}
|
||||
int nItemCL = GetCastSpellCasterLevelFromItem(oSpellCastItem, nSpellID);
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook >> X2PreSpellCastCode2: Item Spellcaster Level: "+IntToString(nItemCL)+".");
|
||||
|
||||
if(DEBUG) DoDebug("x2_inc_spellhook >> X2PreSpellCastCode2: Herbal Infusion Found");
|
||||
if(!DoInfusionUseChecks(oCaster, oSpellCastItem, nSpellID))
|
||||
{
|
||||
ApplyInfusionPoison(oCaster, nItemCL);
|
||||
nContinue = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// No casting while using expertise
|
||||
//---------------------------------------------------------------------------
|
||||
if(nContinue)
|
||||
@@ -3338,6 +3519,12 @@ int X2PreSpellCastCode2()
|
||||
if (nContinue)
|
||||
nContinue = SpellAlignmentRestrictions(oCaster, nSpellID, nCastingClass);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Verdant Lord Spontaneous Regernate
|
||||
//---------------------------------------------------------------------------
|
||||
if(nContinue)
|
||||
Spontaneity(oCaster, nCastingClass, nSpellID, nSpellLevel);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Druid spontaneous summoning
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "x0_i0_position"
|
||||
#include "X0_INC_HENAI"
|
||||
#include "x3_inc_skin"
|
||||
#include "prc_racial_const"
|
||||
|
||||
/*
|
||||
|
||||
@@ -638,7 +639,7 @@ int HorseGetMountTail(object oHorse);
|
||||
// FILE: x3_inc_horse FUNCTION: HorseGetMountFailureMessage()
|
||||
// This is a companion function to HorseGetCanBeMounted. If you need a text
|
||||
// message that explains why the horse cannot be mounted.
|
||||
string HorseGetMountFailureMessage(object oTarget,object oRider=OBJECT_INVALID);
|
||||
string HorseGetMountFailureMessage(object oHorse,object oRider=OBJECT_INVALID);
|
||||
|
||||
|
||||
// FILE: x3_inc_horse FUNCTION: HorseAddHorseMenu()
|
||||
@@ -1050,6 +1051,8 @@ void HORSE_SupportOriginalSpeed(object oRider)
|
||||
} // check to see if matches conditions
|
||||
eSearch=GetNextEffect(oRider);
|
||||
} // cycle through effects
|
||||
|
||||
|
||||
} // HORSE_SupportOriginalSpeed()
|
||||
|
||||
|
||||
|
||||
@@ -876,7 +876,7 @@
|
||||
},
|
||||
"Mod_OnPlrGuiEvt": {
|
||||
"type": "resref",
|
||||
"value": ""
|
||||
"value": "prc_onplayergui"
|
||||
},
|
||||
"Mod_OnPlrLvlUp": {
|
||||
"type": "resref",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "x2_inc_spellhook"
|
||||
//#include "x2_inc_spellhook"
|
||||
#include "prc_inc_spells"
|
||||
|
||||
void main()
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user