added worldarea -> will be responsible for world map rendering
[dboe.git] / party.c
blob30282f33af4359f9e2745b9c59ea17a11a0dc4bd
2 #include <Windows.h>
3 #include "stdio.h"
5 #include "global.h"
7 #include "fileio.h"
8 #include "graphics.h"
9 #include "gutils.h"
10 #include "newgraph.h"
11 #include "specials.h"
12 #include "itemdata.h"
13 #include "infodlgs.h"
14 #include "items.h"
15 #include "string.h"
16 #include "party.h"
17 #include "monster.h"
18 #include "dlogtool.h"
19 #include "town.h"
20 #include "combat.h"
21 #include "locutils.h"
22 #include "fields.h"
23 #include "text.h"
24 #include "exlsound.h"
25 #include "graphutl.h"
27 short skill_cost[20] = {3,3,3,2,2,2, 1,2,2,6,
28 5, 1,2,4,2,1, 4,2,5,0};
29 extern short skill_max[20];
30 short skill_g_cost[20] = {50,50,50,40,40,40,30,50,40,250,
31 250,25,100,200,30,20,100,80,0,0};
32 short skill_bonus[21] = {-3,-3,-2,-1,0,0,1,1,1,2,
33 2,2,3,3,3,3,4,4,4,5,5};
35 short spell_level[62] = {1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,
36 4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7};
37 short spell_cost[2][62] = {{1,1,1,1,1,2,50,2,1,3, 2,3,2,2,2,2,4,4,2,6, 3,3,5,3,3,5,6,4,6,4,
38 4,5,4,8,30,-1,8,6, 5,8,8,6,9,10,6,6, 7,6,8,7,12,10,12,20, 12,8,20,10,14,10,50,10},
39 {1,1,1,2,1,1,3,5,50,1, 2,2,2,2,3,5,8,6,4,2, 3,4,3,3,3,10,5,3,4,6,
40 5,5,5,15,6,5,5,8, 6,7,25,8,10,12,12,6, 8,7,8,8,14,17,8,7, 10,10,35,10,12,12,30,10}};
41 char *mage_s_name[] = {"Light","Spark","Minor Haste","Strength","Scare",
42 "Flame Cloud","Identify","Scry Monster","Goo","True Sight",
43 "Minor Poison","Flame","Slow","Dumbfound","Envenom",
44 "Stinking Cloud","Summon Beast","Conflagration","Dispel Field","Sleep Cloud",
45 "Unlock","Haste","Fireball","Long Light","Fear",
46 "Wall of Force","Weak Summoning","Flame Arrows","Web","Resist Magic",
47 "Poison","Ice Bolt","Slow Group","Magic Map",
48 "Capture Soul","Simulacrum","Venom Arrows","Wall of Ice",
49 "Stealth","Major Haste","Fire Storm","D. Barrier",
50 "Fire Barrier","Summoning","Shockstorm","Spray Fields",
51 "Major Poison","Group Fear","Kill","Paralysis",
52 "Daemon","Antimagic Cloud","MindDuel","Flight",
53 "Shockwave","M. Blessing","Mass Paralysis","Protection",
54 "Major Summon","Force Barrier","Quickfire","Death Arrows"};
55 char *priest_s_name[] = {"Minor Bless","Minor Heal","Weaken Poison","Turn Undead","Location",
56 "Sanctuary","Symbiosis","Minor Manna","Ritual - Sanctify","Stumble",
57 "Bless","Cure Poison","Curse","Light","Wound",
58 "Summon Spirit","Move Mountains","Charm Foe","Disease","Awaken",
59 "Heal","Light Heal All","Holy Scourge","Detect Life","Cure Paralysis",
60 "Manna","Forcefield","Cure Disease","Restore Mind","Smite",
61 "Cure Party","Curse All","Dispel Undead","Remove Curse",
62 "Sticks to Snakes","Martyr's Shield","Cleanse","Firewalk",
63 "Bless Party","Major Heal","Raise Dead","Flamestrike",
64 "Mass Sanctuary","Summon Host","Shatter","Dispel Fields",
65 "Heal All","Revive","Hyperactivity","Destone",
66 "Guardian","Mass Charm","Protective Circle","Pestilence",
67 "Revive All","Ravage Spirit","Resurrect","Divine Thud",
68 "Avatar","Wall of Blades","Word of Recall","Major Cleansing"};
69 char *alch_names[] = {"Weak Curing Potion (1)","Weak Healing Potion (1)","Weak Poison (1)",
70 "Weak Speed Potion (3)","Medium Poison (3)",
71 "Medium Heal Potion (4)","Strong Curing (5)","Medium Speed Potion (5)",
72 "Graymold Salve (7)","Weak Energy Potion (9)",
73 "Potion of Clarity (9)","Strong Poison (10)","Strong Heal Potion (12)","Killer Poison (12)",
74 "Resurrection Balm (9)","Medium Energy Ptn. (14)","Knowledge Brew (19)" ,
75 "Strong Strength (10)","Bliss (16)","Strong Power (20)"
77 char *alch_names_short[] = {"Weak Curing Potion","Weak Healing Potion","Weak Poison",
78 "Weak Speed Potion","Medium Poison",
79 "Medium Heal Potion","Strong Curing","Medium Speed Potion",
80 "Graymold Salve","Weak Energy Potion",
81 "Potion of Clarity","Strong Poison","Strong Heal Potion","Killer Poison",
82 "Resurrection Bal","Medium Energy Ptn.","Knowledge Brew" ,
83 "Strong Strength","Bliss","Strong Power"
85 short spell_w_cast[2][62] = {{0,1,1,1,1,1,3,4,1,2, 1,1,1,1,1,1,4,1,4,1, 2,1,1,0,1,1,4,1,1,0,
86 1,1,1,2,4,1,1,1, 2,1,1,2,4,4,1,1, 1,1,1,1,4,4,1,5, 1,4,1,4,4,4,4,1},
87 {1,0,0,1,3,1,1,3,2,1, 1,0,1,0,1,4,2,1,1,0, 0,0,1,2,0,3,1,0,0,1,
88 0,1,1,3,4,1,0,0, 1,0,3,1,1,4,2,4, 0,0,0,3,4,1,1,1, 0,1,3,1,4,1,5,0}};
89 // 0 - everywhere 1 - combat only 2 - town only 3 - town & outdoor only 4 - town & combat only 5 - outdoor only
90 Boolean get_mage[30] = {1,1,1,1,1,1,0,1,1,0, 1,1,1,1,1,1,0,0,1,1, 1,1,1,1,1,0,0,0,1,1};
91 Boolean get_priest[30] = {1,1,1,1,1,1,0,0,0,1, 1,1,1,1,1,0,0,0,1,1, 1,0,1,1,0,0,0,1,0,0};
92 short combat_percent[20] = {150,120,100,90,80,80,80,70,70,70,
93 70,70,67,62,57,52,47,42,40,40};
96 short town_spell,who_cast,which_pc_displayed;
97 Boolean spell_button_active[90];
99 char empty_string[256] = " ";
101 extern Boolean fast_bang;
102 extern party_record_type far party;
103 extern pc_record_type far adven[6];
104 extern short stat_window,overall_mode,current_pc,town_size[3],town_type;
105 extern current_town_type far c_town;
106 extern big_tr_type far t_d;
107 extern unsigned char far out[96][96];
108 extern unsigned char far out_e[96][96];
109 extern location pc_pos[6],center;
110 extern HWND mainPtr;
111 extern Boolean in_startup_mode,spell_forced,save_maps,suppress_stat_screen,boom_anim_active;
112 extern stored_items_list_type far stored_items[3];
113 extern HCURSOR sword_curs;
114 extern setup_save_type far setup_save;
115 extern short store_mage, store_priest,stat_screen_mode;
116 extern short store_mage_lev, store_priest_lev;
117 extern short store_spell_target,pc_casting;
118 extern short pc_last_cast[2][6];
119 extern effect_pat_type far null_pat;
120 extern effect_pat_type far single;
121 extern effect_pat_type far t;
122 extern effect_pat_type far square;
123 extern effect_pat_type far rad2;
124 extern effect_pat_type far rad3;
125 extern effect_pat_type far current_pat;
126 extern short current_spell_range;
127 extern short hit_chance[21],pc_parry[6],pc_moves[6],combat_active_pc;
128 extern short boom_gr[8];
129 extern unsigned char beasts[5];
130 extern unsigned char m1[20];
131 extern unsigned char m2[16];
132 extern unsigned char m3[16];
133 extern stored_outdoor_maps_type far o_maps;
134 extern short current_ground,dialog_answer;
135 extern short on_spell_menu[2][62];
136 extern pascal Boolean cd_event_filter();
137 extern Boolean dialog_not_toast;
138 extern short far mage_need_select[62];
139 extern short far priest_need_select[62];
140 extern short pc_marked_damage[6];
141 extern short monst_marked_damage[T_M];
142 extern town_item_list far t_i;
143 extern HDC main_dc;
144 extern char far scen_strs2[110][256];
145 extern stored_town_maps_type far town_maps,town_maps2;
146 extern scenario_data_type far scenario;
147 extern piles_of_stuff_dumping_type *data_store;
148 extern piles_of_stuff_dumping_type2 *data_store2;
149 extern item_record_type start_items[6];
150 extern piles_of_stuff_dumping_type5 *data_store5;
152 char c_line[60];
154 // Variables for spell selection
155 short store_situation,store_last_target_darkened,on_which_spell_page = 0;
156 short store_last_cast_mage = 6,store_last_cast_priest = 6;
157 short buttons_on[38] = {1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0};
158 // buttons_on determines which buttons can be hit when on the second spell page
159 short spell_index[38] = {38,39,40,41,42,43,44,45,90,90,46,47,48,49,50,51,52,53,90,90,
160 54,55,56,57,58,59,60,61,90,90, 90,90,90,90,90,90,90,90};
161 // Says which buttons hit which spells on second spell page, 90 means no button
162 Boolean can_choose_caster;
164 // Variables for spending xp
165 Boolean talk_done = FALSE;
166 long val_for_text;
167 Boolean keep_change = FALSE;
168 short store_skills[20],store_h,store_sp,i,store_skp,which_skill;
169 long store_g;
170 short store_train_mode,store_train_pc;
172 extern HBITMAP pcs_gworld;
174 // Dialog vars
175 short store_mage_store ;
176 short store_priest_store ;
177 short store_store_target;
178 short store_graphic_pc_num ;
179 short store_graphic_mode ;
180 short store_pc_graphic;
183 void draw_caster_buttons();
185 void draw_spell_info();
186 void draw_spell_pc_info();
188 void put_pc_caster_buttons();
189 void put_pc_target_buttons();
190 void put_spell_led_buttons();
191 void put_spell_list();
192 void put_pick_spell_graphics();
195 //mode; // 0 - prefab 1 - regular
196 void init_party(short mode)
198 short i,j,k,l;
199 Boolean item_check;
201 boat_record_type null_boat = {{0,0},{0,0},{0,0},200,FALSE};
202 horse_record_type null_horse = {{0,0},{0,0},{0,0},200,FALSE};
204 party.age = 0;
205 party.gold = 200;
206 party.food = 100;
207 for (i = 0; i < 310; i++)
208 for (j = 0; j < 10; j++)
209 party.stuff_done[i][j] = 0;
210 party.light_level = 0;
211 party.outdoor_corner.x = 7;
212 party.outdoor_corner.y = 8;
213 party.i_w_c.x = 1;
214 party.i_w_c.y = 1;
215 party.loc_in_sec.x = 36;
216 party.loc_in_sec.y = 36;
217 party.p_loc.x = 84;
218 party.p_loc.y = 84;
219 for (i = 0; i < 30; i++)
220 party.boats[i] = null_boat;
221 for (i = 0; i < 30; i++)
222 party.horses[i] = null_horse;
223 party.in_boat = -1;
224 party.in_horse = -1;
225 for (i = 0; i < 4; i++)
226 party.creature_save[i].which_town = 200;
227 for (i = 0; i < 10; i++)
228 party.out_c[i].exists = FALSE;
229 for (i = 0; i < 5; i++)
230 for (j = 0; j < 10; j++)
231 party.magic_store_items[i][j].variety = 0;
232 for (i = 0; i < 4; i++)
233 party.imprisoned_monst[i] = 0;
234 for (i = 0; i < 256; i++)
235 party.m_seen[i] = 0;
236 for (i = 0; i < 50; i++)
237 party.journal_str[i] = -1;
238 for (i = 0; i < 140; i++)
239 for (j = 0; j < 2; j++)
240 party.special_notes_str[i][j] = 0;
241 for (i = 0; i < 120; i++)
242 party.talk_save[i].personality = -1;
244 party.total_m_killed = 0;
245 party.total_dam_done = 0;
246 party.total_xp_gained = 0;
247 party.total_dam_taken = 0;
248 party.direction = 0;
249 party.at_which_save_slot = 0;
250 for (i = 0; i < 20; i++)
251 party.alchemy[i] = 0;
252 for (i = 0; i < 200; i++)
253 party.can_find_town[i] = 0;
254 for (i = 0; i < 20; i++)
255 party.key_times[i] = 30000;
256 for (i = 0; i < 30; i++)
257 party.party_event_timers[i] = 0;
258 for (i = 0; i < 50; i++)
259 party.spec_items[i] = 0;
260 for (i = 0; i < 120; i++) {
261 party.help_received[i] = 0;
263 for (i = 0; i < 200; i++)
264 party.m_killed[i] = 0;
265 sprintf((char *) party.scen_name,"");
267 for (i = 0; i < 200; i++)
268 for (j = 0; j < 8; j++)
269 party.item_taken[i][j] = 0;
272 refresh_store_items();
274 for (i = 0; i < 6; i++) {
275 // adven[i] = create_debug_pc(i);
276 adven[i] = return_dummy_pc();
277 if (mode != 1)
278 //adven[i] = create_debug_pc(i);
279 adven[i] = create_prefab_pc(i);
282 for (i = 0; i < 96; i++)
283 for (j = 0; j < 96; j++)
284 out_e[i][j] = 0;
287 for (i = 0; i < 3;i++)
288 for (j = 0; j < NUM_TOWN_ITEMS; j++) {
289 stored_items[i].items[j] = return_dummy_item();
292 for (i = 0; i < 100; i++)
293 for (j = 0; j < 8; j++)
294 for (k = 0; k < 64; k++) {
295 town_maps.town_maps[i][j][k] = 0;
296 town_maps2.town_maps[i][j][k] = 0;
299 for (i = 0; i < 100; i++)
300 for (k = 0; k < 6; k++)
301 for (l = 0; l < 48; l++)
302 o_maps.outdoor_maps[i][k][l] = 0;
304 // Default is save maps
305 party.stuff_done[306][0] = 0;
306 save_maps = TRUE;
310 // NOT DEBUG
311 build_outdoors();
312 update_pc_graphics();
316 // This is only called after a scenario is loaded and the party is put into it.
317 // Until that time, the party scen vals are uninited
318 // Then, it inits the party properly for starting the scenario based
319 // on the loaded scenario
320 void init_party_scen_data()
322 short i,j,k,l;
323 Boolean stored_item = FALSE;
324 short store_help;
326 party.age = 0;
327 store_help = PSD[306][4];
328 for (i = 0; i < 310; i++)
329 for (j = 0; j < 10; j++)
330 party.stuff_done[i][j] = 0;
331 PSD[306][4] = store_help;
332 party.light_level = 0;
333 party.outdoor_corner.x = scenario.out_sec_start.x;
334 party.outdoor_corner.y = scenario.out_sec_start.y;
335 party.i_w_c.x = 0;
336 party.i_w_c.y = 0;
337 party.loc_in_sec.x = scenario.out_start.x;
338 party.loc_in_sec.y = scenario.out_start.y;
339 party.p_loc.x = scenario.out_start.x;
340 party.p_loc.y = scenario.out_start.y;
341 for (i = 0; i < 30; i++)
342 party.boats[i] = scenario.scen_boats[i];
343 for (i = 0; i < 30; i++)
344 party.horses[i] = scenario.scen_horses[i];
345 for (i = 0; i < 30; i++) {
346 if ((scenario.scen_boats[i].which_town >= 0) && (scenario.scen_boats[i].boat_loc.x >= 0)) {
347 if (party.boats[i].exists == FALSE) {
348 party.boats[i] = scenario.scen_boats[i];
349 party.boats[i].exists = TRUE;
352 if ((scenario.scen_horses[i].which_town >= 0) && (scenario.scen_horses[i].horse_loc.x >= 0)) {
353 if (party.horses[i].exists == FALSE) {
354 party.horses[i] = scenario.scen_horses[i];
355 party.horses[i].exists = TRUE;
359 party.in_boat = -1;
360 party.in_horse = -1;
361 for (i = 0; i < 4; i++)
362 party.creature_save[i].which_town = 200;
363 for (i = 0; i < 10; i++)
364 party.out_c[i].exists = FALSE;
365 for (i = 0; i < 5; i++)
366 for (j = 0; j < 10; j++)
367 party.magic_store_items[i][j].variety = 0;
368 for (i = 0; i < 4; i++)
369 party.imprisoned_monst[i] = 0;
370 for (i = 0; i < 256; i++)
371 party.m_seen[i] = 0;
372 for (i = 0; i < 50; i++)
373 party.journal_str[i] = -1;
374 for (i = 0; i < 140; i++)
375 for (j = 0; j < 2; j++)
376 party.special_notes_str[i][j] = 0;
377 for (i = 0; i < 120; i++)
378 party.talk_save[i].personality = -1;
380 party.direction = 0;
381 party.at_which_save_slot = 0;
382 for (i = 0; i < 200; i++)
383 party.can_find_town[i] = 1 - scenario.town_hidden[i];
384 for (i = 0; i < 20; i++)
385 party.key_times[i] = 30000;
386 for (i = 0; i < 30; i++)
387 party.party_event_timers[i] = 0;
388 for (i = 0; i < 50; i++)
389 party.spec_items[i] = (scenario.special_items[i] >= 10) ? 1 : 0;
391 for (i = 0; i < 200; i++)
392 party.m_killed[i] = 0;
394 for (i = 0; i < 200; i++)
395 for (j = 0; j < 8; j++)
396 party.item_taken[i][j] = 0;
399 refresh_store_items();
401 for (i = 0; i < 96; i++)
402 for (j = 0; j < 96; j++)
403 out_e[i][j] = 0;
405 for (i = 0; i < 3;i++)
406 for (j = 0; j < NUM_TOWN_ITEMS; j++)
407 if (stored_items[i].items[j].variety != 0)
408 stored_item = TRUE;
409 if (stored_item == TRUE)
410 if (FCD(911,0) == 1) {
411 for (i = 0; i < 3;i++)
412 for (j = 0; j < NUM_TOWN_ITEMS; j++)
413 if (stored_items[i].items[j].variety != 0)
414 if (give_to_party(stored_items[i].items[j],FALSE) == FALSE) {
415 i = 20; j = NUM_TOWN_ITEMS + 1;
418 for (i = 0; i < 3;i++)
419 for (j = 0; j < NUM_TOWN_ITEMS; j++) {
420 stored_items[i].items[j] = return_dummy_item();
423 for (i = 0; i < 100; i++)
424 for (j = 0; j < 8; j++)
425 for (k = 0; k < 64; k++) {
426 town_maps.town_maps[i][j][k] = 0;
427 town_maps2.town_maps[i][j][k] = 0;
430 for (i = 0; i < 100; i++)
431 for (k = 0; k < 6; k++)
432 for (l = 0; l < 48; l++)
433 o_maps.outdoor_maps[i][k][l] = 0;
437 // When the party is placed into a scen from the startinbg screen, this is called to put the game into game
438 // mode and load in the scen and init the party info
439 // party record already contains scen name
440 void put_party_in_scen()
442 short i,j,k;
443 char strs[6][256] = {"","","","","",""};
444 short buttons[3] = {-1,-1,-1};
445 Boolean item_took = FALSE;
447 for (j = 0; j < 6; j++)
448 for (i = 0; i < 15; i++)
449 adven[j].status[i] = 0;
450 for (j = 0; j < 6; j++) {
451 if (adven[j].main_status >= 10)
452 adven[j].main_status -= 10;
453 adven[j].cur_health = adven[j].max_health;
454 adven[j].cur_sp = adven[j].max_sp;
456 for (j = 0; j < 6; j++)
457 for (i = 23; i >= 0; i--) {
458 adven[j].items[i].special_class = 0;
459 if (adven[j].items[i].graphic_num >= 150) {
460 take_item(j,i + 30); // strip away special items
461 item_took = TRUE;
463 if (adven[j].items[i].ability == 119) {
464 take_item(j,i + 30); // strip away summoning items
465 item_took = TRUE;
467 if (adven[j].items[i].ability == 120) {
468 take_item(j,i + 30); // strip away summoning items
469 item_took = TRUE;
472 if (item_took == TRUE)
473 FCD(910,0);
474 party.age = 0;
475 for (i = 0; i < 200; i++)
476 party.m_killed[i] = 0;
477 for (i = 0; i < 30; i++)
478 party.party_event_timers[i] = 0;
480 if (load_scenario() == FALSE)
481 return;
482 init_party_scen_data();
485 // if at this point, startup must be over, so make this call to make sure we're ready,
486 // graphics wise
487 end_startup();
488 in_startup_mode = FALSE;
490 set_up_ter_pics();
492 load_outdoors(party.outdoor_corner.x + 1,party.outdoor_corner.y + 1,1,1,0,0,NULL);
493 load_outdoors(party.outdoor_corner.x,party.outdoor_corner.y + 1,0,1,0,0,NULL);
494 load_outdoors(party.outdoor_corner.x + 1,party.outdoor_corner.y,1,0,0,0,NULL);
495 load_outdoors(party.outdoor_corner.x,party.outdoor_corner.y,0,0,0,0,NULL);
496 stat_screen_mode = 0;
497 build_outdoors();
498 erase_out_specials();
499 update_pc_graphics();
501 current_pc = first_active_pc();
502 force_town_enter(scenario.which_town_start,scenario.where_start);
503 start_town_mode(scenario.which_town_start,9);
504 center = scenario.where_start;
505 update_explored(scenario.where_start);
506 overall_mode = 1;
507 load_area_graphics();
508 create_clip_region();
509 redraw_screen(0);
510 set_stat_window(0);
511 adjust_spell_menus();
513 adjust_monst_menu();
516 // Throw up intro dialog
517 buttons[0] = 1;
518 for (j = 0; j < 6; j++)
519 if (strlen(data_store5->scen_strs[4 + j]) > 0) {
520 for (i = 0; i < 6; i++)
521 strcpy((char *) strs[i],data_store5->scen_strs[4 + i]);
522 custom_choice_dialog((char *) strs,-1 * (1600 + scenario.intro_pic),buttons) ;
523 j = 6;
525 give_help(1,2,0);
526 // this is kludgy, put here to prevent problems
527 for (i = 0; i < 50; i++)
528 party.spec_items[i] = (scenario.special_items[i] >= 10) ? 1 : 0;
532 pc_record_type return_dummy_pc()
534 pc_record_type dummy_pc;
535 short i;
537 dummy_pc.main_status = 0;
538 sprintf ((char *) dummy_pc.name, "\n");
540 for (i = 0; i < 30; i++)
541 dummy_pc.skills[i] = (i < 3) ? 1 : 0;
542 dummy_pc.cur_health = 6;
543 dummy_pc.max_health = 6;
544 dummy_pc.cur_sp = 0;
545 dummy_pc.max_sp = 0;
546 dummy_pc.experience = 0;
547 dummy_pc.skill_pts = 60;
548 dummy_pc.level = 1;
549 for (i = 0; i < 15; i++)
550 dummy_pc.status[i] = 0;
551 for (i = 0; i < 24; i++)
552 dummy_pc.items[i] = return_dummy_item();
553 for (i = 0; i < 24; i++)
554 dummy_pc.equip[i] = FALSE;
556 for (i = 0; i < 62; i++) {
557 dummy_pc.priest_spells[i] = (i < 30) ? TRUE : FALSE;
558 dummy_pc.mage_spells[i] = (i < 30) ? TRUE : FALSE;
560 dummy_pc.which_graphic = 0;
561 dummy_pc.weap_poisoned = 24;
563 for (i = 0; i < 15; i++) {
564 dummy_pc.advan[i] = FALSE;
565 dummy_pc.traits[i] = FALSE;
567 dummy_pc.race = 0;
568 dummy_pc.exp_adj = 100;
569 dummy_pc.direction = 0;
571 return dummy_pc;
574 pc_record_type create_debug_pc(short num)
576 pc_record_type dummy_pc;
577 short i;
579 dummy_pc.main_status = 1;
580 switch (num) {
581 case 0: strncpy ((char *) dummy_pc.name, "Gunther", (size_t) 20);
582 break;
583 case 1: strncpy ((char *) dummy_pc.name, "Yanni", (size_t) 20);
584 break;
585 case 2: strncpy ((char *) dummy_pc.name, "Mandolin", (size_t) 20);
586 break;
587 case 3: strncpy ((char *) dummy_pc.name, "Pete", (size_t) 20);
588 break;
589 case 4: strncpy ((char *) dummy_pc.name, "Vraiment", (size_t) 20);
590 break;
591 case 5: strncpy ((char *) dummy_pc.name, "Goo", (size_t) 20);
592 break;
596 for (i = 0; i < 30; i++)
597 dummy_pc.skills[i] = (i < 3) ? 20 : 8;
598 dummy_pc.cur_health = 60;
599 dummy_pc.max_health = 60;
600 dummy_pc.cur_sp = 90;
601 dummy_pc.max_sp = 90;
602 dummy_pc.experience = 0;
603 dummy_pc.skill_pts = 60;
604 dummy_pc.level = 1;
605 for (i = 0; i < 15; i++)
606 dummy_pc.status[i] = 0;
607 for (i = 0; i < 24; i++)
608 dummy_pc.items[i] = return_dummy_item();
609 for (i = 0; i < 24; i++)
610 dummy_pc.equip[i] = FALSE;
612 for (i = 0; i < 62; i++) {
613 dummy_pc.priest_spells[i] = TRUE;
614 dummy_pc.mage_spells[i] = TRUE;
616 // dummy_pc.which_graphic = num * 3 + 1;
617 dummy_pc.which_graphic = num + 4;
618 dummy_pc.weap_poisoned = 16;
620 for (i = 0; i < 15; i++) {
621 dummy_pc.advan[i] = FALSE;
622 dummy_pc.traits[i] = FALSE;
625 dummy_pc.race = 0;
626 dummy_pc.exp_adj = 100;
627 dummy_pc.direction = 0;
629 return dummy_pc;
632 pc_record_type create_prefab_pc(short num)
635 pc_record_type dummy_pc;
636 short i;
637 short pc_stats[6][19] = {{8,6,2, 6,0,0,0,0,0, 0,0,0,0,1, 0,0,2,0,0},
638 {8,7,2, 0,0,6,3,0,3, 0,0,0,0,0, 0,0,0,2,0},
639 {8,6,2, 3,3,0,0,2,0, 0,0,0,0,0, 4,4,0,2,1},
640 {3,2,6, 2,0,0,2,0,0, 3,0,3,0,1, 0,0,0,0,0},
641 {2,2,6, 3,0,0,2,0,0, 2,1,4,0,0, 0,0,0,0,1},
642 {2,2,6, 0,2,0,2,0,1, 0,3,3,2,0, 0,0,0,0,0}};
643 short pc_health[6] = {22,24,24,16,16,18};
644 short pc_sp[6] = {0,0,0,20,20,21};
645 short pc_graphics[6] = {3,32,29,16,23,14};
646 short pc_race[6] = {0,2,1,0,0,0};
647 short pc_t[6][15] = {{0,0,1,0,0,0,1,0,0,0, 0,1,0,0,0},
648 {1,0,0,0,0,1,0,0,0,0, 1,0,0,0,0},
649 {0,0,0,1,0,0,0,0,0,0, 0,0,1,0,0},
650 {0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0},
651 {0,0,0,0,1,0,1,1,0,0, 0,0,0,0,1},
652 {0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0}};
655 dummy_pc.main_status = 1;
656 switch (num) {
657 case 0: strncpy ((char *) dummy_pc.name, "Jenneke", (size_t) 20);
658 break;
659 case 1: strncpy ((char *) dummy_pc.name, "Thissa", (size_t) 20);
660 break;
661 case 2: strncpy ((char *) dummy_pc.name, "Frrrrrr", (size_t) 20);
662 break;
663 case 3: strncpy ((char *) dummy_pc.name, "Adrianna", (size_t) 20);
664 break;
665 case 4: strncpy ((char *) dummy_pc.name, "Feodoric", (size_t) 20);
666 break;
667 case 5: strncpy ((char *) dummy_pc.name, "Michael", (size_t) 20);
668 break;
672 for (i = 0; i < 19; i++)
673 dummy_pc.skills[i] = pc_stats[num][i];
674 dummy_pc.cur_health = pc_health[num];
675 dummy_pc.max_health = pc_health[num];
676 dummy_pc.experience = 0;
677 dummy_pc.skill_pts = 0;
678 dummy_pc.level = 1;
680 for (i = 0; i < 15; i++)
681 dummy_pc.status[i] = 0;
682 for (i = 0; i < 24; i++)
683 dummy_pc.items[i] = return_dummy_item();
684 for (i = 0; i < 24; i++)
685 dummy_pc.equip[i] = FALSE;
686 dummy_pc.cur_sp = pc_sp[num];
687 dummy_pc.max_sp = pc_sp[num];
688 for (i = 0; i < 62; i++) {
689 dummy_pc.priest_spells[i] = (i < 30) ? TRUE : FALSE;////
690 dummy_pc.mage_spells[i] = (i < 30) ? TRUE : FALSE;
692 for (i = 0; i < 15; i++) {
693 dummy_pc.traits[i] = pc_t[num][i];
694 dummy_pc.advan[i] = FALSE;
697 dummy_pc.race = pc_race[num];
698 dummy_pc.exp_adj = 100;
699 dummy_pc.direction = 0;
701 dummy_pc.which_graphic = pc_graphics[num];
703 return dummy_pc;
706 Boolean create_pc(short spot,short parent_num)
707 //spot; // if spot is 6, find one
709 Boolean still_ok = TRUE;
710 short i;
712 if (spot == 6) {
713 for (spot = 0; spot < 6; spot++)
714 if (adven[spot].main_status == 0)
715 break;
717 if (spot == 6)
718 return FALSE;
720 adven[spot] = return_dummy_pc();
722 pick_race_abil(&adven[spot],0,parent_num);
724 if (parent_num != 0)
725 cd_initial_draw(989);
727 still_ok = spend_xp(spot,0,parent_num);
728 if (still_ok == FALSE)
729 return FALSE;
730 adven[spot].cur_health = adven[spot].max_health;
731 adven[spot].cur_sp = adven[spot].max_sp;
732 if (parent_num != 0)
733 cd_initial_draw(989);
735 pick_pc_graphic(spot,0,parent_num);
737 if (parent_num != 0)
738 cd_initial_draw(989);
739 pick_pc_name(spot,parent_num);
741 adven[spot].main_status = 1;
743 if (in_startup_mode == FALSE) {
744 adven[spot].items[0] = start_items[adven[spot].race * 2];
745 adven[spot].equip[0] = TRUE;
746 adven[spot].items[1] = start_items[adven[spot].race * 2 + 1];
747 adven[spot].equip[1] = TRUE;
749 // Do stat adjs for selected race.
750 if (adven[spot].race == 1)
751 adven[spot].skills[1] += 2;
752 if (adven[spot].race == 2) {
753 adven[spot].skills[0] += 2;
754 adven[spot].skills[2] += 1;
756 adven[spot].max_sp += adven[spot].skills[9] * 3 + adven[spot].skills[10] * 3;
757 adven[spot].cur_sp = adven[spot].max_sp;
760 update_pc_graphics();
761 return TRUE;
764 Boolean take_sp(short pc_num,short amt)
766 if (adven[pc_num].cur_sp < amt)
767 return FALSE;
768 adven[pc_num].cur_sp -= amt;
769 return TRUE;
775 void heal_pc(short pc_num,short amt)
777 if (adven[pc_num].cur_health > adven[pc_num].max_health)
778 return;
779 if (adven[pc_num].main_status != 1)
780 return;
781 adven[pc_num].cur_health += amt;
782 if (adven[pc_num].cur_health > adven[pc_num].max_health)
783 adven[pc_num].cur_health = adven[pc_num].max_health;
787 void heal_party(short amt)
789 short i;
791 for (i = 0; i < 6; i++)
792 if (adven[i].main_status == 1)
793 heal_pc(i,amt);
796 void cure_pc(short pc_num,short amt)
798 if (adven[pc_num].main_status != 1)
799 return;
800 if (adven[pc_num].status[2] <= amt)
801 adven[pc_num].status[2] = 0;
802 else adven[pc_num].status[2] -= amt;
803 one_sound(51);
806 void cure_party(short amt)
808 short i;
810 for (i = 0; i < 6; i++)
811 if (adven[i].main_status == 1)
812 cure_pc(i,amt);
816 void curse_pc(short which_pc,short how_much)
818 if (adven[which_pc].main_status != 1)
819 return;
820 if (adven[which_pc].main_status == 1) {
821 adven[which_pc].status[1] = max(adven[which_pc].status[1] - how_much,-8);
822 sprintf ((char *) c_line, " %s cursed.",(char *) adven[which_pc].name);
823 add_string_to_buf((char *) c_line);
825 put_pc_screen();
826 give_help(59,0,0);
829 void dumbfound_pc(short which_pc,short how_much)
831 short r1;
833 if (adven[which_pc].main_status != 1)
834 return;
835 r1 = get_ran(1,0,90);
836 if (pc_has_abil_equip(which_pc,53) < 24) {
837 add_string_to_buf(" Ring of Will glows.");
838 r1 -= 10;
840 if (r1 < adven[which_pc].level)
841 how_much -= 2;
842 if (how_much <= 0) {
843 sprintf ((char *) c_line, " %s saved.",(char *) adven[which_pc].name);
844 add_string_to_buf((char *) c_line);
845 return;
847 if (adven[which_pc].main_status == 1) {
848 adven[which_pc].status[9] = min(adven[which_pc].status[9] + how_much,8);
849 sprintf ((char *) c_line, " %s dumbfounded.",(char *) adven[which_pc].name);
850 add_string_to_buf((char *) c_line);
852 one_sound(67);
853 put_pc_screen();
854 adjust_spell_menus();
855 give_help(28,0,0);
857 void disease_pc(short which_pc,short how_much)
859 short r1,level;
861 if (adven[which_pc].main_status != 1)
862 return;
863 r1 = get_ran(1,0,100);
864 if (r1 < adven[which_pc].level * 2)
865 how_much -= 2;
866 if (how_much <= 0) {
867 sprintf ((char *) c_line, " %s saved.",(char *) adven[which_pc].name);
868 add_string_to_buf((char *) c_line);
869 return;
871 if ((level = get_prot_level(which_pc,62)) > 0)////
872 how_much -= level / 2;
873 if ((adven[which_pc].traits[12] == TRUE) &&
874 (how_much > 1))
875 how_much++;
876 if ((adven[which_pc].traits[12] == TRUE) &&
877 (how_much == 1) && (get_ran(1,0,1) == 0))
878 how_much++;
879 if (adven[which_pc].main_status == 1) {
880 adven[which_pc].status[7] = min(adven[which_pc].status[7] + how_much,8);
881 sprintf ((char *) c_line, " %s diseased.",(char *) adven[which_pc].name);
882 add_string_to_buf((char *) c_line);
884 one_sound(66);
885 put_pc_screen();
886 give_help(29,0,0);
888 void sleep_pc(short which_pc,short how_much,short what_type,short adjust)
889 // higher adjust, less chance of saving
891 short r1,level;
892 if (adven[which_pc].main_status != 1)
893 return;
894 if (how_much == 0)
895 return;
896 if ((what_type == 11) || (what_type == 12)) { ////
897 if ((level = get_prot_level(which_pc,53)) > 0)
898 how_much -= level / 2;
899 if ((level = get_prot_level(which_pc,54)) > 0)
900 how_much -= (what_type == 11) ? level : level * 300;
904 r1 = get_ran(1,0,100) + adjust;
905 if (r1 < 30 + adven[which_pc].level * 2)
906 how_much = -1;
907 if ((what_type == 11) && ((adven[which_pc].traits[7] > 0) || (adven[which_pc].status[11] < 0)))
908 how_much = -1;
909 if (how_much <= 0) {
910 sprintf ((char *) c_line, " %s resisted.",(char *) adven[which_pc].name);
911 add_string_to_buf((char *) c_line);
912 return;
914 if (adven[which_pc].main_status == 1) {
915 adven[which_pc].status[what_type] = how_much;
916 if (what_type == 11)
917 sprintf ((char *) c_line, " %s falls asleep.",(char *) adven[which_pc].name);
918 else sprintf ((char *) c_line, " %s paralyzed.",(char *) adven[which_pc].name);
919 if (what_type == 11)
920 play_sound(96);
921 else play_sound(90);
922 add_string_to_buf((char *) c_line);
923 pc_moves[which_pc] = 0;
925 put_pc_screen();
926 if (what_type == 11)
927 give_help(30,0,0);
928 else give_help(32,0,0);
932 void slow_pc(short which_pc,short how_much)
934 if (adven[which_pc].main_status != 1)
935 return;
936 if (adven[which_pc].main_status == 1) {
938 adven[which_pc].status[3] = minmax(-8,8,adven[which_pc].status[3] - how_much);
939 if (how_much < 0)
940 sprintf ((char *) c_line, " %s hasted.",(char *) adven[which_pc].name);
941 else sprintf ((char *) c_line, " %s slowed.",(char *) adven[which_pc].name);
942 add_string_to_buf((char *) c_line);
944 put_pc_screen();
945 if (how_much < 0)
946 give_help(35,0,0);
949 void web_pc(short which_pc,short how_much)
951 if (adven[which_pc].main_status != 1)
952 return;
953 if (adven[which_pc].main_status == 1) {
954 adven[which_pc].status[6] = min(adven[which_pc].status[6] + how_much,8);
955 sprintf ((char *) c_line, " %s webbed.",(char *) adven[which_pc].name);
956 add_string_to_buf((char *) c_line);
957 one_sound(17);
959 put_pc_screen();
960 give_help(31,0,0);
963 void acid_pc(short which_pc,short how_much)
965 if (adven[which_pc].main_status != 1)
966 return;
967 if (pc_has_abil_equip(which_pc,122) < 24) {
968 sprintf ((char *) c_line, " %s resists acid.",(char *) adven[which_pc].name);
969 add_string_to_buf((char *) c_line);
970 return;
972 if (adven[which_pc].main_status == 1) {
973 adven[which_pc].status[13] += how_much;
974 sprintf ((char *) c_line, " %s covered with acid!",(char *) adven[which_pc].name);
975 add_string_to_buf((char *) c_line);
976 one_sound(42);
978 put_pc_screen();
981 void increase_light(short amt)
983 short i;
984 location where;
986 party.light_level += amt;
987 if (is_combat()) {
988 for (i = 0; i < 6; i++)
989 if (adven[i].main_status == 1) {
990 update_explored(pc_pos[i]);
993 else {
994 where = get_cur_loc();
995 update_explored(where);
997 put_pc_screen();
1000 void restore_sp_pc(short pc_num,short amt)
1002 if (adven[pc_num].cur_sp > adven[pc_num].max_sp)
1003 return;
1004 adven[pc_num].cur_sp += amt;
1005 if (adven[pc_num].cur_sp > adven[pc_num].max_sp)
1006 adven[pc_num].cur_sp = adven[pc_num].max_sp;
1009 void restore_sp_party(short amt)
1011 short i;
1013 for (i = 0; i < 6; i++)
1014 if (adven[i].main_status == 1)
1015 restore_sp_pc(i,amt);
1018 void award_party_xp(short amt)
1020 short i;
1022 for (i = 0; i < 6; i++)
1023 if (adven[i].main_status == 1)
1024 award_xp(i,amt);
1027 void award_xp(short pc_num,short amt)
1029 short adjust,add_hp;
1030 short xp_percent[30] = {150,120,100,90,80,70,60,50,50,50,
1031 45,40,40,40,40,35,30,25,23,20,
1032 15,15,15,15,15,15,15,15,15,15};
1033 if (adven[pc_num].level > 49) {
1034 adven[pc_num].level = 50;
1035 return;
1037 if (amt > 200) { // debug
1038 SysBeep(50); SysBeep(50);
1039 ASB("Oops! Too much xp!");
1040 ASB("Report this!");
1041 return;
1043 if (amt < 0) { // debug
1044 SysBeep(50); SysBeep(50);
1045 ASB("Oops! Negative xp!");
1046 ASB("Report this!");
1047 return;
1049 if (adven[pc_num].main_status != 1)
1050 return;
1052 if (adven[pc_num].level >= 40)
1053 adjust = 15;
1054 else adjust = xp_percent[adven[pc_num].level / 2];
1056 if ((amt > 0) && (adven[pc_num].level > 7)) {
1057 if (get_ran(1,0,100) < xp_percent[adven[pc_num].level / 2])
1058 amt--;
1060 if (amt <= 0)
1061 return;
1064 // adven[pc_num].experience += (max(((amt * adjust) / 100), 0) * adven[pc_num].exp_adj) / 100;
1065 // party.total_xp_gained += (max(((amt * adjust) / 100), 0) * adven[pc_num].exp_adj) / 100;
1066 adven[pc_num].experience += (max(((amt * adjust) / 100), 0) * 100) / 100;
1067 party.total_xp_gained += (max(((amt * adjust) / 100), 0) * 100) / 100;
1071 if (adven[pc_num].experience < 0) {
1072 SysBeep(50); SysBeep(50);
1073 ASB("Oops! Xp became negative somehow!");
1074 ASB("Report this!");
1075 adven[pc_num].experience = adven[pc_num].level * (get_tnl(&adven[pc_num])) - 1;
1076 return;
1078 if (adven[pc_num].experience > 15000) {
1079 adven[pc_num].experience = 15000;
1080 return;
1083 while (adven[pc_num].experience >= (adven[pc_num].level * (get_tnl(&adven[pc_num])))) {
1084 play_sound(7);
1085 adven[pc_num].level++;
1086 sprintf ((char *) c_line, " %s is level %d! ",(char *) adven[pc_num].name,adven[pc_num].level);
1087 add_string_to_buf((char *) c_line);
1088 adven[pc_num].skill_pts += (adven[pc_num].level < 20) ? 5 : 4;
1089 add_hp = (adven[pc_num].level < 26) ? get_ran(1,2,6) + skill_bonus[adven[pc_num].skills[0]]
1090 : max (skill_bonus[adven[pc_num].skills[0]],0);
1091 if (add_hp < 0)
1092 add_hp = 0;
1093 adven[pc_num].max_health += add_hp;
1094 if (adven[pc_num].max_health > 250)
1095 adven[pc_num].max_health = 250;
1096 adven[pc_num].cur_health += add_hp;
1097 if (adven[pc_num].cur_health > 250)
1098 adven[pc_num].cur_health = 250;
1099 put_pc_screen();
1104 void drain_pc(short which_pc,short how_much)
1106 if (adven[which_pc].main_status == 1) {
1107 adven[which_pc].experience = max(adven[which_pc].experience - how_much,0);
1108 sprintf ((char *) c_line, " %s drained.",(char *) adven[which_pc].name);
1109 add_string_to_buf((char *) c_line);
1115 void do_xp_keep(short pc_num,short mode)
1117 for (i = 0; i < 20; i++)
1118 adven[pc_num].skills[i] = store_skills[i];
1119 adven[pc_num].cur_health += store_h - adven[pc_num].max_health;
1120 adven[pc_num].max_health = store_h;
1121 adven[pc_num].cur_sp += store_sp - adven[pc_num].max_sp;
1122 adven[pc_num].max_sp = store_sp;
1123 if (mode == 1)
1124 party.gold = store_g;
1125 adven[pc_num].skill_pts = store_skp;
1129 void draw_xp_skills()
1131 short i;
1132 for (i = 0; i < 19; i++) {
1133 if ((store_skp >= skill_cost[i]) && (store_g >= skill_g_cost[i]))
1134 cd_text_frame(1010,54 + i,11);
1135 else cd_text_frame(1010,54 + i,1);
1136 cd_set_item_num(1010,54 + i,store_skills[i]);
1139 if ((store_skp >= 1) && (store_g >= 10))
1140 cd_text_frame(1010,52,11);
1141 else cd_text_frame(1010,52,1);
1142 cd_set_item_num(1010,52,store_h);
1143 if ((store_skp >= 1) && (store_g >= 15))
1144 cd_text_frame(1010,53,11);
1145 else cd_text_frame(1010,53,1);
1146 cd_set_item_num(1010,53,store_sp);
1150 void do_xp_draw()
1154 short item_hit,what_talk_field;
1155 char get_text[256];
1156 short mode,pc_num;
1158 mode = store_train_mode;
1159 pc_num = store_train_pc;
1160 if (mode == 0) {
1161 if (adven[pc_num].main_status == 1)
1162 sprintf((char *) get_text, "%s",(char *) adven[pc_num].name);
1163 else sprintf((char *) get_text, "New PC");
1165 else sprintf((char *) get_text, "%s",(char *) adven[pc_num].name);
1167 cd_set_item_text (1010, 51,get_text);
1169 for (i = 0; i < 20; i++)
1170 store_skills[i] = adven[pc_num].skills[i];
1171 store_h = adven[pc_num].max_health;
1172 store_sp = adven[pc_num].max_sp;
1173 store_g = (mode == 0) ? 20000 : party.gold;
1174 store_skp = adven[pc_num].skill_pts;
1176 draw_xp_skills();
1179 update_gold_skills();
1182 Boolean spend_xp_event_filter (short item_hit)
1184 short what_talk_field,i,j,mode,pc_num;
1185 char get_text[256];
1186 Boolean talk_done = FALSE;
1188 mode = store_train_mode;
1189 pc_num = store_train_pc;
1191 switch (item_hit) {
1192 case 73:
1193 if ((mode == 0) && (adven[pc_num].main_status < 0))
1194 adven[pc_num].main_status = 0;
1195 dialog_answer = 0;
1196 talk_done = TRUE;
1197 break;
1199 case 82:
1200 party.help_received[10] = 0;
1201 give_help(210,11,1010);
1202 break;
1204 case 3: case 4:
1205 if (((store_h >= 250) && (item_hit == 4)) ||
1206 ((store_h == adven[pc_num].max_health) && (item_hit == 3) && (mode == 1)) ||
1207 ((store_h == 6) && (item_hit == 3) && (mode == 0)))
1208 SysBeep(2);
1209 else {
1210 if (item_hit == 3) {
1211 store_g += 10;
1212 store_h -= 2;
1213 store_skp += 1;
1215 else {
1216 if ((store_g < 10) || (store_skp < 1)) {
1217 if (store_g < 10)
1218 give_help(24,0,1010);
1219 else give_help(25,0,1010);
1220 SysBeep(2);
1222 else {
1223 store_g -= 10;
1224 store_h += 2;
1225 store_skp -= 1;
1229 update_gold_skills();
1230 cd_set_item_num(1010,52,store_h);
1231 draw_xp_skills();
1234 break;
1236 case 5: case 6:
1237 if (((store_sp >= 150) && (item_hit == 6)) ||
1238 ((store_sp == adven[pc_num].max_sp) && (item_hit == 5) && (mode == 1)) ||
1239 ((store_sp == 0) && (item_hit == 5) && (mode == 0)))
1240 SysBeep(2);
1241 else {
1242 if (item_hit == 5) {
1243 store_g += 15;
1244 store_sp -= 1;
1245 store_skp += 1;
1247 else {
1248 if ((store_g < 15) || (store_skp < 1)) {
1249 if (store_g < 15)
1250 give_help(24,0,1010);
1251 else give_help(25,0,1010);
1252 SysBeep(2);
1254 else {
1255 store_sp += 1;
1256 store_g -= 15;
1257 store_skp -= 1;
1261 update_gold_skills();
1262 cd_set_item_num(1010,53,store_sp);
1263 draw_xp_skills();
1265 break;
1267 case 48:
1268 do_xp_keep(pc_num,mode);
1269 dialog_answer = 1;
1270 talk_done = TRUE;
1271 break;
1273 case 49:
1274 if (mode == 0) {
1275 SysBeep(2);
1276 break;
1278 else {
1279 do_xp_keep(pc_num,mode);
1280 do {
1281 pc_num = (pc_num == 0) ? 5 : pc_num - 1;
1282 } while (adven[pc_num].main_status != 1);
1283 store_train_pc = pc_num;
1284 do_xp_draw();
1286 break;
1288 case 50:
1289 if (mode == 0) {
1290 SysBeep(2);
1291 break;
1293 else {
1294 do_xp_keep(pc_num,mode);
1295 do {
1296 pc_num = (pc_num == 5) ? 0 : pc_num + 1;
1297 } while (adven[pc_num].main_status != 1);
1298 store_train_pc = pc_num;
1299 do_xp_draw();
1301 break;
1303 case 100:
1304 break;
1306 default:
1307 if (item_hit >= 100) {
1308 item_hit -= 100;
1309 if ((item_hit == 3) || (item_hit == 4)) {
1310 display_strings_with_nums(10,63,0,0,"About Health",57,724,1010);
1312 else if ((item_hit == 5) || (item_hit == 6)){
1313 display_strings_with_nums(10,64,0,0,"About Spell Points",57,724,1010);
1315 else {
1316 which_skill = (item_hit - 7) / 2;
1317 display_skills(which_skill,1010);
1320 else {
1321 which_skill = (item_hit - 7) / 2;
1323 if (which_skill == 9) {
1324 if (PSD[4][0] == 3) {
1325 if (FCD(3049,1010) == 2) {
1326 FCD(3050,1010);
1327 PSD[4][0] = 1; party.spec_items[39] = 0;
1328 for (i = 0; i < 6; i++) {adven[i].max_sp -= 6; adven[i].skills[10] -= 2;
1329 for (j = 30; j < 62; j++) {if (get_ran(1,0,2) < 2) adven[i].priest_spells[j] = 0;}
1333 else break;
1335 do_xp_draw();
1336 break;
1339 if (((store_skills[which_skill] >= skill_max[which_skill]) && ((item_hit - 7) % 2 == 1)) ||
1340 ((store_skills[which_skill] == adven[pc_num].skills[which_skill]) && ((item_hit - 7) % 2 == 0) && (mode == 1)) ||
1341 ((store_skills[which_skill] == 0) && ((item_hit - 7) % 2 == 0) && (mode == 0) && (which_skill > 2)) ||
1342 ((store_skills[which_skill] == 1) && ((item_hit - 7) % 2 == 0) && (mode == 0) && (which_skill <= 2)))
1343 SysBeep(2);
1344 else {
1345 if ((item_hit - 7) % 2 == 0) {
1346 store_g += skill_g_cost[which_skill];
1347 store_skills[which_skill] -= 1;
1348 store_skp += skill_cost[which_skill];
1350 else {
1351 if ((store_g < skill_g_cost[which_skill]) || (store_skp < skill_cost[which_skill])) {
1352 if (store_g < skill_g_cost[which_skill])
1353 give_help(24,0,1010);
1354 else give_help(25,0,1010);
1355 SysBeep(2);
1357 else {
1358 store_skills[which_skill] += 1;
1359 store_g -= skill_g_cost[which_skill];
1360 store_skp -= skill_cost[which_skill];
1364 update_gold_skills();
1365 cd_set_item_num(1010,54 + which_skill,store_skills[which_skill]);
1366 draw_xp_skills();
1369 break;
1372 store_train_pc = pc_num;
1373 if (talk_done == TRUE) {
1374 dialog_not_toast = FALSE;
1376 return FALSE;
1378 void update_gold_skills()
1380 cd_set_item_num(1010,47,((store_train_mode == 0) ? 0 : (short) store_g));
1381 cd_set_item_num(1010,46,(short) store_skp);
1383 Boolean spend_xp(short pc_num, short mode, short parent)
1384 //short mode; // 0 - create 1 - train
1385 // returns 1 if cancelled
1387 char get_text[256],text2[256];
1388 short item_hit;
1390 store_train_pc = pc_num;
1391 store_train_mode = mode;
1393 make_cursor_sword();
1395 cd_create_dialog_parent_num(1010,parent);
1396 sprintf((char *) get_text,"Health (%d/%d)",1,10);
1397 cd_add_label(1010,52,(char *) get_text,1075);
1398 sprintf((char *) get_text,"Spell Pts. (%d/%d)",1,15);
1399 //cd_add_label(1010,5,get_text,1040);
1400 cd_add_label(1010,53,(char *) get_text,1075);
1401 for (i = 54; i < 73; i++) {
1402 get_str(text2,9,1 + 2 * (i - 54));
1403 sprintf((char *) get_text,"%s (%d/%d)",text2,skill_cost[i - 54],skill_g_cost[i - 54]);
1404 cd_add_label(1010,i,(char *) get_text,(i < 63) ? 1075 : 1069);
1406 do_xp_draw();
1408 dialog_answer = 0;
1410 if (party.help_received[10] == 0) {
1411 cd_initial_draw(1010);
1412 give_help(10,11,1010);
1415 while (dialog_not_toast)
1416 ModalDialog();
1417 cd_kill_dialog(1010,0);
1419 return dialog_answer;
1423 short mage_lore_total()
1425 short total = 0,i;
1427 for (i = 0; i < 6; i++)
1428 if (adven[i].main_status == 1)
1429 total += adven[i].skills[11];
1431 return total;
1435 Boolean poison_weapon( short pc_num, short how_much,short safe)
1436 //short safe; // 1 - always succeeds
1438 short i,weap = 24,p_level,r1;
1439 short p_chance[21] = {40,72,81,85,88,89,90,
1440 91,92,93,94,94,95,95,96,97,98,100,100,100,100};
1442 for (i = 0; i < 24; i++)
1443 if ((adven[pc_num].equip[i] == TRUE) && (is_weapon(pc_num,i) == TRUE)) {
1444 weap = i;
1445 i = 30;
1447 if (weap == 24) {
1448 add_string_to_buf(" No weapon equipped. ");
1449 return FALSE;
1451 else {
1452 p_level = how_much;
1453 add_string_to_buf(" You poison your weapon. ");
1454 r1 = get_ran(1,0,100);
1455 // Nimble?
1456 if (adven[pc_num].traits[3] == FALSE)
1457 r1 -= 6;
1458 if ((r1 > p_chance[adven[pc_num].skills[17]]) && (safe == 0)) {
1459 add_string_to_buf(" Poison put on badly. ");
1460 p_level = p_level / 2;
1461 r1 = get_ran(1,0,100);
1462 if (r1 > p_chance[adven[pc_num].skills[17]] + 10) {
1463 add_string_to_buf(" You nick yourself. ");
1464 adven[pc_num].status[2] += p_level;
1467 if (safe != 1)
1468 play_sound(55);
1469 adven[pc_num].weap_poisoned = weap;
1470 adven[pc_num].status[0] = max (adven[pc_num].status[0],
1471 p_level);
1473 return TRUE;
1477 Boolean is_weapon(short pc_num,short item)
1479 if ((adven[pc_num].items[item].variety == 1) ||
1480 (adven[pc_num].items[item].variety == 2) ||
1481 (adven[pc_num].items[item].variety == 5) ||
1482 (adven[pc_num].items[item].variety == 24))
1483 return TRUE;
1484 else return FALSE;
1488 void cast_spell(short type,short situation)
1489 //short type; // 0 - mage 1 - priest
1490 //short situation; // 0 - out 1 - town
1492 short spell;
1493 location loc;
1495 if ((is_town()) && (is_antimagic(c_town.p_loc.x,c_town.p_loc.y))) {
1496 add_string_to_buf(" Not in antimagic field.");
1497 return;
1500 if (spell_forced == FALSE)
1501 spell = pick_spell(6, type, situation);
1502 else {
1503 if (repeat_cast_ok(type) == FALSE)
1504 return;
1505 spell = (type == 0) ? store_mage : store_priest;
1507 if (spell < 70) {
1508 print_spell_cast(spell,type);
1510 if (type == 0)
1511 do_mage_spell(pc_casting,spell);
1512 else do_priest_spell(pc_casting,spell);
1513 put_pc_screen();
1518 Boolean repeat_cast_ok(short type)
1520 short store_select,who_would_cast,what_spell;
1522 if (overall_mode == 10)
1523 who_would_cast = current_pc;
1524 else if (overall_mode < 2)
1525 who_would_cast = pc_casting;
1526 else return FALSE;
1528 if (is_combat())
1529 what_spell = pc_last_cast[type][who_would_cast];
1530 else what_spell = (type == 0) ? store_mage : store_priest;
1532 if (pc_can_cast_spell(who_would_cast,type,what_spell) == FALSE) {
1533 add_string_to_buf("Repeat cast: Can't cast.");
1534 return FALSE;
1536 store_select = (type == 0) ? mage_need_select[what_spell] :
1537 priest_need_select[what_spell];
1538 if ((store_select > 0) && (store_spell_target == 6)) {
1539 add_string_to_buf("Repeat cast: No target stored.");
1540 return FALSE;
1542 if ((store_select == 2) &&
1543 ((adven[store_spell_target].main_status == 0) ||
1544 (adven[store_spell_target].main_status > 4))) {
1545 add_string_to_buf("Repeat cast: No target stored.");
1546 return FALSE;
1548 if ((store_select == 1) &&
1549 (adven[store_spell_target].main_status != 1)) {
1550 add_string_to_buf("Repeat cast: No target stored.");
1551 return FALSE;
1554 return TRUE;
1558 void give_party_spell(short which)
1559 //which; // 100 + x : priest spell x
1561 short i;
1562 Boolean sound_done = FALSE;
1563 char str[60];
1565 if ((which < 0) || (which > 161) || ((which > 61) && (which < 100))) {
1566 give_error("The scenario has tried to give you a non-existant spell.","",0);
1567 return;}
1569 if (which < 100)
1570 for (i = 0; i < 6; i++)
1571 if (adven[i].mage_spells[which] == FALSE) {
1572 adven[i].mage_spells[which] = TRUE;
1573 if (adven[i].main_status == 1)
1574 sprintf((char *) str,"%s learns spell.",adven[i].name);
1575 give_help(41,0,0);
1576 if (sound_done == FALSE) {sound_done = TRUE; play_sound(62);};
1578 if (which >= 100)
1579 for (i = 0; i < 6; i++)
1580 if (adven[i].priest_spells[which - 100] == FALSE) {
1581 adven[i].priest_spells[which - 100] = TRUE;
1582 if (adven[i].main_status == 1)
1583 sprintf((char *) str,"%s learns spell.",adven[i].name);
1584 give_help(41,0,0);
1585 if (sound_done == FALSE) {sound_done = TRUE; play_sound(62);};
1589 void do_mage_spell(short pc_num,short spell_num)
1591 short i,j,item,target,r1,adj,store;
1592 location where;
1594 where = c_town.p_loc;
1595 play_sound(25);
1596 current_spell_range = 8;
1598 adj = stat_adj(who_cast,2);
1600 switch (spell_num) {
1601 case 0: // Light
1602 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1603 increase_light(50);
1604 break;
1606 case 6: // Identify
1607 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1608 ASB("All of your items are identified.");
1609 for (i = 0; i < 6; i++)
1610 for (j = 0; j < 24; j++)
1611 adven[i].items[j].item_properties = adven[i].items[j].item_properties | 1;
1612 break;
1614 case 9: // true sight
1615 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1616 for (where.x = 0; where.x < 64; where.x++)
1617 for (where.y = 0; where.y < 64; where.y++)
1618 if (dist(where,c_town.p_loc) <= 2)
1619 make_explored(where.x,where.y);
1620 clear_map();
1621 break;
1623 case 16: // summon beast ////
1624 r1 = get_summon_monster(1);
1625 if (r1 < 0) break;
1626 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1627 store = get_ran(3,1,4) + adj;
1628 if (summon_monster(r1,where,store,2) == FALSE)
1629 add_string_to_buf(" Summon failed.");
1630 break;
1631 case 26: // summon 1
1632 store = adven[who_cast].level / 5 + stat_adj(who_cast,2) / 3 + get_ran(1,0,2);
1633 j = minmax(1,7,store);
1634 r1 = get_summon_monster(1); ////
1635 if (r1 < 0) break;
1636 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1637 store = get_ran(4,1,4) + adj;
1638 for (i = 0; i < j; i++)
1639 if (summon_monster(r1,where,store,2) == FALSE)
1640 add_string_to_buf(" Summon failed.");
1641 break;
1642 case 43: // summon 2
1643 store = adven[who_cast].level / 7 + stat_adj(who_cast,2) / 3 + get_ran(1,0,1);
1644 j = minmax(1,6,store);
1645 r1 = get_summon_monster(2); ////
1646 if (r1 < 0) break;
1647 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1648 store = get_ran(5,1,4) + adj;
1649 for (i = 0; i < j; i++)
1650 if (summon_monster(r1,where,store,2) == FALSE)
1651 add_string_to_buf(" Summon failed.");
1652 break;
1653 case 58: // summon 3
1654 store = adven[who_cast].level / 10 + stat_adj(who_cast,2) / 3 + get_ran(1,0,1);
1655 j = minmax(1,5,store);
1656 r1 = get_summon_monster(3); ////
1657 if (r1 < 0) break;
1658 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1659 store = get_ran(7,1,4) + stat_adj(who_cast,2);
1660 for (i = 0; i < j; i++)
1661 if (summon_monster(r1,where,store,2) == FALSE)
1662 add_string_to_buf(" Summon failed.");
1663 break;
1664 case 50:
1665 store = get_ran(5,1,4) + 2 * stat_adj(who_cast,2);
1666 if (summon_monster(85,where,store,2) == FALSE)
1667 add_string_to_buf(" Summon failed.");
1668 else adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1669 break;
1671 case 18: // dispel field
1672 add_string_to_buf(" Target spell. ");
1673 current_pat = square;
1674 overall_mode = 3;
1675 set_town_spell(spell_num,pc_num);
1676 break;
1678 case 23: // Long light
1679 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1680 increase_light(200);
1681 break;
1683 case 33: // Magic map
1684 item = pc_has_abil(pc_num,158);////
1685 if (item == 24)
1686 add_string_to_buf(" You need a sapphire. ");
1687 else if (c_town.town.specials2 % 10 == 1)
1688 add_string_to_buf(" The spell fails. ");
1689 else {
1690 remove_charge(pc_num,item);
1691 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1692 add_string_to_buf(" As the sapphire dissolves, ");
1693 add_string_to_buf(" you have a vision. ");
1694 for (i = 0; i < 64; i++)
1695 for (j = 0; j < 64; j++)
1696 make_explored(i,j);
1697 clear_map();
1699 break;
1702 case 38: // Stealth
1703 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1704 party.stuff_done[305][0] += max(6,adven[pc_num].level * 2);
1705 break;
1708 case 7: case 20: case 34: case 41: // Scry monster, Unlock, disp. barrier, Capture SOul
1710 add_string_to_buf(" Target spell. ");
1711 current_pat = single;
1712 overall_mode = 3;
1713 set_town_spell(spell_num,pc_num);
1714 break;
1716 case 42: case 59: case 60: // fire and force barriers, quickfire
1717 add_string_to_buf(" Target spell. ");
1718 overall_mode = 3;
1719 current_pat = single;
1720 set_town_spell(spell_num,pc_num);
1721 break;
1723 case 51: // antimagic
1724 add_string_to_buf(" Target spell. ");
1725 overall_mode = 3;
1726 current_pat = rad2;
1727 set_town_spell(spell_num,pc_num);
1728 break;
1730 case 53: // fly
1731 if (party.stuff_done[305][1] > 0) {
1732 add_string_to_buf(" Not while already flying. ");
1733 return;
1735 if (party.in_boat >= 0)
1736 add_string_to_buf(" Leave boat first. ");
1737 else if (party.in_horse >= 0) ////
1738 add_string_to_buf(" Leave horse first. ");
1739 else {
1740 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1741 add_string_to_buf(" You start flying! ");
1742 party.stuff_done[305][1] = 3;
1744 break;
1746 case 29: case 57: // resist magic protection
1747 target = store_spell_target;
1748 if (target < 6)
1749 adven[pc_num].cur_sp -= spell_cost[0][spell_num];
1750 if ((spell_num == 57) && (target < 6)) {
1751 adven[target].status[4] += 2 + stat_adj(pc_num,2) + get_ran(2,1,2);
1752 for (i = 0; i < 6; i++)
1753 if (adven[i].main_status == 1) {
1754 adven[i].status[5] += 4 + adven[pc_num].level / 3 + stat_adj(pc_num,2);
1756 sprintf ((char *) c_line, " Party protected. ");
1758 if ((spell_num == 29) && (target < 6)) {
1759 adven[target].status[5] += 2 + stat_adj(pc_num,2) + get_ran(2,1,2);
1760 sprintf ((char *) c_line, " %s protected.",adven[target].name);
1762 add_string_to_buf((char *) c_line);
1763 break;
1767 void do_priest_spell(short pc_num,short spell_num)
1769 short r1,r2, target, i,j,item,store,adj,x,y;
1770 location loc;
1771 location where,dest = {27,1};
1773 short store_victim_health,store_caster_health,targ_damaged; // for symbiosis
1775 where = c_town.p_loc;
1777 adj = stat_adj(pc_num,2);
1779 play_sound(24);
1780 current_spell_range = 8;
1782 switch (spell_num) {
1783 case 4:
1784 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1786 if (is_town()) {
1787 loc = (overall_mode == 0) ? party.p_loc : c_town.p_loc;
1788 sprintf ((char *) c_line, " You're at: x %d y %d.",
1789 (short) loc.x, (short) loc.y);
1791 if (is_out()) {
1792 loc = (overall_mode == 0) ? party.p_loc : c_town.p_loc;
1793 x = loc.x; y = loc.y;
1794 x += 48 * party.outdoor_corner.x; y += 48 * party.outdoor_corner.y;
1795 sprintf ((char *) c_line, " You're outside at: x %d y %d.",x,y);
1798 add_string_to_buf((char *) c_line);
1799 break;
1801 case 7: case 25: // manna spells
1802 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1803 store = adven[pc_num].level / 3 + 2 * stat_adj(who_cast,2) + get_ran(2,1,4);
1804 r1 = max(0,store);
1805 if (spell_num == 7)
1806 r1 = r1 / 3 + 1;
1807 sprintf ((char *) c_line, " You gain %d food. ",r1);
1808 add_string_to_buf((char *) c_line);
1809 give_food(r1,TRUE);
1810 break;
1812 case 8: // Ritual - Sanctify
1813 add_string_to_buf(" Sanctify which space? ");
1814 current_pat = single;
1815 overall_mode = 3;
1816 set_town_spell(100 + spell_num,pc_num);
1817 break;
1819 case 13:
1820 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1821 party.light_level += 210;
1822 break;
1824 case 15:
1825 store = stat_adj(who_cast,2);
1826 if (summon_monster(125,where,get_ran(2,1,4) + store,2) == FALSE)
1827 add_string_to_buf(" Summon failed.");
1828 else adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1829 break;
1830 case 34:
1831 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1832 r1 = adven[who_cast].level / 6 + stat_adj(who_cast,2) / 3 + get_ran(1,0,1);
1833 for (i = 0; i < r1; i++) {
1834 r2 = get_ran(1,0,7);
1835 store = get_ran(2,1,5) + stat_adj(who_cast,2);
1836 if (summon_monster((r2 == 1) ? 100 : 99,where,store,2 ) == FALSE)
1837 add_string_to_buf(" Summon failed.");
1839 break;
1840 case 43:
1841 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1842 store = get_ran(2,1,4) + stat_adj(who_cast,2);
1843 if (summon_monster(126,where,store,2) == FALSE)
1844 add_string_to_buf(" Summon failed.");
1845 for (i = 0; i < 4; i++) {
1846 store = get_ran(2,1,4) + stat_adj(who_cast,2);
1847 if (summon_monster(125,where,store,2) == FALSE)
1848 add_string_to_buf(" Summon failed.");
1850 break;
1851 case 50:
1852 store = get_ran(6,1,4) + stat_adj(who_cast,2);
1853 if (summon_monster(122,where,store,2) == FALSE)
1854 add_string_to_buf(" Summon failed.");
1855 else adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1856 break;
1858 case 16:
1859 add_string_to_buf(" Destroy what? ");
1860 current_pat = (spell_num == 16) ? single : square;
1861 overall_mode = 3;
1862 set_town_spell(100 + spell_num,pc_num);
1863 break;
1865 case 45: // dispelling fields
1866 add_string_to_buf(" Target spell. ");
1867 current_pat = (spell_num == 19) ? single : rad2;
1868 overall_mode = 3;
1869 set_town_spell(100 + spell_num,pc_num);
1870 break;
1872 case 23: // Detect life
1873 add_string_to_buf(" Monsters now on map. ");
1874 party.stuff_done[305][2] += 6 + get_ran(1,0,6);
1875 clear_map();
1876 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1877 break;
1878 case 37: // firewalk
1879 add_string_to_buf(" You are now firewalking. ");
1880 party.stuff_done[305][3] += adven[pc_num].level / 12 + 2;
1881 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1882 break;
1884 case 44: // shatter
1885 add_string_to_buf(" You send out a burst of energy. ");
1886 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1887 for (loc.x = where.x - 1;loc.x < where.x + 2; loc.x++)
1888 for (loc.y = where.y - 1;loc.y < where.y + 2; loc.y++)
1889 crumble_wall(loc);
1890 update_explored(c_town.p_loc);
1891 break;
1893 case 60:
1894 if (overall_mode > 0) {
1895 add_string_to_buf(" Can only cast outdoors. ");
1896 return;
1898 if (party.in_boat >= 0) {
1899 add_string_to_buf(" Not while in boat. ");
1900 return;
1902 if (party.in_horse >= 0) {////
1903 add_string_to_buf(" Not while on horseback. ");
1904 return;
1906 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1907 add_string_to_buf(" You are moved... ");
1908 force_town_enter(scenario.which_town_start,scenario.where_start);
1909 start_town_mode(scenario.which_town_start,9);
1910 position_party(scenario.out_sec_start.x,scenario.out_sec_start.y,
1911 scenario.out_start.x,scenario.out_start.y);
1912 center = c_town.p_loc = scenario.where_start;
1913 // overall_mode = 0;
1914 // center = party.p_loc;
1915 // update_explored(party.p_loc);
1916 redraw_screen(0);
1917 break;
1919 case 1: case 20: case 39: case 2: case 11: case 27: case 28: case 36: case 19: case 24:
1920 // target = select_pc(11,0);
1921 target = store_spell_target;
1922 if (target < 6) {
1923 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1924 switch(spell_num) {
1925 case 1: case 20: case 39:
1926 r1 = get_ran(2 + 2 * (spell_num / 6), 1, 4);
1927 sprintf ((char *) c_line, " %s healed %d. ",
1928 (char *) adven[target].name,r1);
1929 heal_pc(target,r1);
1930 one_sound(52);
1931 break;
1933 case 2: case 11:
1934 sprintf ((char *) c_line, " %s cured. "
1935 ,(char *) adven[target].name);
1936 r1 = ((spell_num == 2) ? 1 : 3) + get_ran(1,0,2) + stat_adj(pc_num,2) / 2;
1937 cure_pc(target,r1);
1938 break;
1940 case 19: // awaken
1941 if (adven[target].status[11] <= 0) {
1942 sprintf ((char *) c_line, " %s is already awake! "
1943 ,(char *) adven[target].name);
1944 break;
1946 sprintf ((char *) c_line, " %s wakes up. "
1947 ,(char *) adven[target].name);
1948 adven[target].status[11] = 0;
1949 break;
1950 case 24: // cure paralysis
1951 if (adven[target].status[12] <= 0) {
1952 sprintf ((char *) c_line, " %s isn't paralyzed! "
1953 ,(char *) adven[target].name);
1954 break;
1956 sprintf ((char *) c_line, " %s can move now. "
1957 ,(char *) adven[target].name);
1958 adven[target].status[12] = 0;
1959 break;
1961 case 27:
1962 sprintf ((char *) c_line, " %s recovers. "
1963 ,(char *) adven[target].name);
1964 r1 = 2 + get_ran(1,0,2) + stat_adj(pc_num,2) / 2;
1965 adven[target].status[7] = max(0,adven[target].status[7] - r1);
1966 break;
1968 case 28:
1969 sprintf ((char *) c_line, " %s restored. "
1970 ,(char *) adven[target].name);
1971 r1 = 1 + get_ran(1,0,2) + stat_adj(pc_num,2) / 2;
1972 adven[target].status[9] = max(0,adven[target].status[9] - r1);
1973 break;
1975 case 36:
1976 sprintf ((char *) c_line, " %s cleansed. "
1977 ,(char *) adven[target].name);
1978 adven[target].status[7] = 0;
1979 adven[target].status[6] = 0;
1980 break;
1983 add_string_to_buf((char *) c_line);
1984 put_pc_screen();
1985 break;
1987 case 47: case 49: case 40: case 56: case 33: case 5: case 6: case 35:
1988 target = store_spell_target;
1990 if (target < 6) {
1991 if ((spell_num == 6) && (target == pc_num)) { // check symbiosis
1992 add_string_to_buf(" Can't cast on self.");
1993 return;
1996 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
1997 if (spell_num == 35) { // martyr's shield
1998 sprintf ((char *) c_line, " %s shielded. ",
1999 (char *) adven[target].name);
2000 r1 = max(1,get_ran((adven[pc_num].level + 5) / 5,1,3) + adj);
2001 adven[target].status[10] += r1;
2003 if (spell_num == 5) { // sanctuary
2004 sprintf ((char *) c_line, " %s hidden. ",
2005 (char *) adven[target].name);
2006 r1 = max(0,get_ran(0,1,3) + adven[pc_num].level / 4 + adj);
2007 adven[target].status[8] += r1;
2009 if (spell_num == 6) { // symbiosis
2010 store_victim_health = adven[target].cur_health;
2011 store_caster_health = adven[pc_num].cur_health;
2012 targ_damaged = adven[target].max_health - adven[target].cur_health;
2013 while ((targ_damaged > 0) && (adven[pc_num].cur_health > 0)) {
2014 adven[target].cur_health++;
2015 r1 = get_ran(1,0,100) + adven[pc_num].level / 2 + 3 * adj;
2016 if (r1 < 100)
2017 adven[pc_num].cur_health--;
2018 if (r1 < 50)
2019 adven[pc_num].cur_health = move_to_zero(adven[pc_num].cur_health);
2020 targ_damaged = adven[target].max_health - adven[target].cur_health;
2022 add_string_to_buf(" You absorb damage.");
2023 sprintf ((char *) c_line, " %s healed %d. ", (char *) adven[target].name,
2024 adven[target].cur_health - store_victim_health);
2025 add_string_to_buf ((char *) c_line);
2026 sprintf ((char *) c_line, " %s takes %d. ", (char *) adven[pc_num].name,
2027 store_caster_health - adven[pc_num].cur_health);
2029 if (spell_num == 47) {
2030 sprintf ((char *) c_line, " %s healed. ",
2031 (char *) adven[target].name);
2032 heal_pc(target,250);
2033 adven[target].status[2] = 0;
2034 one_sound(-53); one_sound(52);
2036 if (spell_num == 49) {
2037 if (adven[target].main_status == 4) {
2038 adven[target].main_status = 1;
2039 sprintf ((char *) c_line, " %s destoned. ",
2040 (char *) adven[target].name);
2041 play_sound(53);
2043 else sprintf ((char *) c_line," Wasn't stoned. ");
2045 if (spell_num == 33) {
2046 for (i = 0; i < 24; i++)
2047 if (is_cursed(adven[target].items[i]) == TRUE){
2048 r1 = get_ran(1,0,200) - 10 * stat_adj(pc_num,2);
2049 if (r1 < 60) {
2050 adven[target].items[i].item_properties =
2051 adven[target].items[i].item_properties & 239;
2054 play_sound(52);
2055 sprintf ((char *) c_line," Your items glow. ");
2058 if ((spell_num == 40) || (spell_num == 56))
2059 if ((item = pc_has_abil(pc_num,13)) == 16) {
2060 add_string_to_buf(" Need resurrection balm. ");
2061 spell_num = 500;
2063 else take_item(pc_num,item);
2064 if (spell_num == 40) {
2065 if (adven[target].main_status == 2)
2066 if (get_ran(1,1,adven[pc_num].level / 2) == 1) {
2067 sprintf ((char *) c_line, " %s now dust. ",
2068 (char *) adven[target].name);
2069 play_sound(5);
2070 adven[target].main_status = 3;
2072 else {
2073 adven[target].main_status = 1;
2074 for (i = 0; i < 3; i++)
2075 if (get_ran(1,0,2) < 2)
2076 adven[target].skills[i] -= (adven[target].skills[i] > 1) ? 1 : 0;
2077 adven[target].cur_health = 1;
2078 sprintf ((char *) c_line, " %s raised. ",
2079 (char *) adven[target].name);
2080 play_sound(52);
2082 else sprintf ((char *) c_line," Didn't work. ");
2085 if (spell_num == 56) {
2086 if (adven[target].main_status != 1) {
2087 adven[target].main_status = 1;
2088 for (i = 0; i < 3; i++)
2089 if (get_ran(1,0,2) < 1)
2090 adven[target].skills[i] -= (adven[target].skills[i] > 1) ? 1 : 0;
2091 adven[target].cur_health = 1;
2092 sprintf ((char *) c_line, " %s raised.",
2093 (char *) adven[target].name);
2094 play_sound(52);
2096 else sprintf ((char *) c_line," Was OK. ");
2098 add_string_to_buf((char *) c_line);
2099 put_pc_screen();
2101 break;
2103 case 21: case 46: case 54:
2104 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
2105 r1 = get_ran(spell_num / 7 + adj, 1, 4);
2106 if (spell_num < 54) {
2107 sprintf ((char *) c_line, " Party healed %d. ", r1);
2108 add_string_to_buf((char *) c_line);
2109 heal_party(r1);
2110 play_sound(52);
2112 else if (spell_num == 54) {
2113 sprintf ((char *) c_line, " Party revived. ");
2114 add_string_to_buf((char *) c_line);
2115 r1 = r1 * 2;
2116 heal_party(r1);
2117 play_sound(-53);
2118 play_sound(-52);
2119 cure_party(3 + adj);
2121 break;
2123 case 30:
2124 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
2125 sprintf ((char *) c_line, " Party cured. ");
2126 add_string_to_buf((char *) c_line);
2127 cure_party(3 + stat_adj(pc_num,2));
2128 break;
2130 case 42: case 61: case 48:
2131 adven[pc_num].cur_sp -= spell_cost[1][spell_num];
2132 switch (spell_num) {
2133 case 42: add_string_to_buf(" Party hidden.");break;
2134 case 61: add_string_to_buf(" Party cleansed.");break;
2135 case 48: add_string_to_buf(" Party is now really, REALLY awake.");break;
2138 for (i = 0; i < 6; i++)
2139 if (adven[i].main_status == 1) {
2140 if (spell_num == 42) {
2141 store = get_ran(0,1,3) + adven[pc_num].level / 6 + stat_adj(pc_num,2);
2142 r1 = max(0,store);
2143 adven[i].status[8] += r1;
2145 if (spell_num == 61) {
2146 adven[i].status[6] = 0;
2147 adven[i].status[7] = 0;
2149 if (spell_num == 48) { // Hyperactivity
2150 adven[i].status[11] -= 6 + 2 * stat_adj(pc_num,2);
2151 adven[i].status[3] = max(0,adven[i].status[3]);
2154 break;
2158 void cast_town_spell(location where)
2160 short adjust,r1,i,j,targ,store;
2161 location loc;
2162 unsigned char ter;
2164 if ((where.x <= c_town.town.in_town_rect.left) ||
2165 (where.x >= c_town.town.in_town_rect.right) ||
2166 (where.y <= c_town.town.in_town_rect.top) ||
2167 (where.y >= c_town.town.in_town_rect.bottom)) {
2168 add_string_to_buf(" Can't target outside town.");
2169 return;
2172 adjust = can_see(c_town.p_loc,where,0);
2173 if (town_spell < 1000)
2174 adven[who_cast].cur_sp -= spell_cost[town_spell / 100][town_spell % 100];
2175 else town_spell -= 1000;
2176 ter = t_d.terrain[where.x][where.y];
2178 if (adjust > 4)
2179 add_string_to_buf(" Can't see target. ");
2180 else switch (town_spell) {
2181 case 7: case 34: // Scry, Capture Soul
2182 targ = monst_there(where);
2183 if (targ < T_M) {
2184 if (town_spell == 7) {
2185 party.m_seen[c_town.monst.dudes[targ].number] = TRUE;
2186 adjust_monst_menu();
2187 display_monst(0,&c_town.monst.dudes[targ],0);
2189 else record_monst(&c_town.monst.dudes[targ]);
2191 else add_string_to_buf(" No monster there.");
2192 break;
2194 case 119: case 145: case 18:
2195 add_string_to_buf(" You attempt to dispel. ");
2196 place_spell_pattern(current_pat,where,11,FALSE,7);
2197 break;
2198 case 116: // Move M.
2199 add_string_to_buf(" You blast the area. ");
2200 crumble_wall(where);
2201 update_explored(c_town.p_loc);
2202 break;
2203 case 42:
2204 if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) {
2205 add_string_to_buf(" Target space obstructed.");
2206 break;
2208 make_fire_barrier(where.x,where.y);
2209 if (is_fire_barrier(where.x,where.y))
2210 add_string_to_buf(" You create the barrier. ");
2211 else add_string_to_buf(" Failed.");
2212 break;
2213 case 59:
2214 if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) {
2215 add_string_to_buf(" Target space obstructed.");
2216 break;
2218 make_force_barrier(where.x,where.y);
2219 if (is_force_barrier(where.x,where.y))
2220 add_string_to_buf(" You create the barrier. ");
2221 else add_string_to_buf(" Failed.");
2222 break;
2223 case 60:
2224 make_quickfire(where.x,where.y);
2225 if (is_quickfire(where.x,where.y))
2226 add_string_to_buf(" You create quickfire. ");
2227 else add_string_to_buf(" Failed.");
2228 break;
2230 case 51: // am cloud
2231 add_string_to_buf(" You create an antimagic cloud. ");
2232 for (loc.x = 0; loc.x < town_size[town_type]; loc.x++)
2233 for (loc.y = 0; loc.y < town_size[town_type]; loc.y++)
2234 if ((dist(where,loc) <= 2) && (can_see(where,loc,2) < 5) &&
2235 ((a_v(loc.x - where.x) < 2) || (a_v(loc.y - where.y) < 2)))
2236 make_antimagic(loc.x,loc.y);
2237 break;
2239 case 108: // RItual - sanctify
2240 sanctify_space(where);
2241 break;
2243 case 20:
2244 switch (scenario.ter_types[ter].special) { ////
2245 case 9: case 10:
2246 r1 = get_ran(1,0,100) - 5 * stat_adj(who_cast,2) + 5 * c_town.difficulty;
2247 r1 += scenario.ter_types[ter].flag2 * 7;
2248 if (scenario.ter_types[ter].flag2 == 10)
2249 r1 = 10000;
2250 if (r1 < (135 - combat_percent[min(19,adven[who_cast].level)])) {
2251 add_string_to_buf(" Door unlocked. ");
2252 play_sound(9);
2253 t_d.terrain[where.x][where.y] = scenario.ter_types[ter].flag1;
2255 else {
2256 play_sound(41);
2257 add_string_to_buf(" Didn't work. ");
2259 break;
2261 default:
2262 add_string_to_buf(" Wrong terrain type. ");
2263 break;
2265 break;
2267 case 41:
2268 if ((is_fire_barrier(where.x,where.y)) || (is_force_barrier(where.x,where.y))) {
2269 r1 = get_ran(1,0,100) - 5 * stat_adj(who_cast,2) + 5 * (c_town.difficulty / 10);
2270 if (is_fire_barrier(where.x,where.y))
2271 r1 -= 8;
2272 if (r1 < (120 - combat_percent[min(19,adven[who_cast].level)])) {
2273 add_string_to_buf(" Barrier broken. ");
2274 take_fire_barrier(where.x,where.y);
2275 take_force_barrier(where.x,where.y);
2277 // Now, show party new things
2278 update_explored(c_town.p_loc);
2280 else {
2281 store = get_ran(1,0,1);
2282 play_sound(41);
2283 add_string_to_buf(" Didn't work. ");
2287 else add_string_to_buf(" No barrier there.");
2289 break;
2294 void sanctify_space(location where)
2296 short r1,i,j,s1,s2,s3;
2297 location l = {25,13};
2299 for (i = 0; i < 50; i++)
2300 if ((same_point(where,c_town.town.special_locs[i]) == TRUE) &&
2301 (c_town.town.spec_id[i] >= 0)) {
2302 if (c_town.town.specials[c_town.town.spec_id[i]].type == 24)
2303 run_special(16,2,c_town.town.spec_id[i],where,&s1,&s2,&s3);
2304 return;
2306 add_string_to_buf(" Nothing happens.");
2309 void crumble_wall(location where)
2311 unsigned char ter,blastable[9] = {111,112,113,128,129, 130,143,144,145};
2312 short i;
2314 if (loc_off_act_area(where) == TRUE)
2315 return;
2316 ter = t_d.terrain[where.x][where.y];
2317 if (scenario.ter_types[ter].special == 7) {
2318 play_sound(60);
2319 t_d.terrain[where.x][where.y] = scenario.ter_types[ter].flag1;
2320 add_string_to_buf(" Barrier crumbles.");
2325 void do_mindduel(short pc_num,creature_data_type *monst)
2327 short i = 0,adjust,r1,r2,balance = 0;
2329 adjust = (adven[pc_num].level + adven[pc_num].skills[2]) / 2 - monst->m_d.level * 2;
2330 if (pc_has_abil_equip(pc_num,75) < 16)
2331 adjust += 20;
2332 if (monst->attitude % 2 != 1)
2333 make_town_hostile();
2334 monst->attitude = 1;
2336 add_string_to_buf("Mindduel!");
2337 while ((adven[pc_num].main_status == 1) && (monst->active > 0) && (i < 10)) {
2338 play_sound(1);
2339 r1 = get_ran(1,0,100) + adjust;
2340 r1 += 5 * (monst->m_d.status[9] - adven[pc_num].status[9]);
2341 r1 += 5 * balance;
2342 r2 = get_ran(1,1,6);
2343 if (r1 < 30) {
2344 sprintf((char *)c_line, " %s is drained %d.",adven[pc_num].name,r2);
2345 add_string_to_buf((char *) c_line);
2346 monst->m_d.mp += r2;
2347 balance++;
2348 if (adven[pc_num].cur_sp == 0) {
2349 adven[pc_num].status[9] += 2;
2350 sprintf((char *) c_line," %s is dumbfounded.",adven[pc_num].name);
2351 add_string_to_buf((char *) c_line);
2352 if (adven[pc_num].status[9] > 7) {
2353 sprintf((char *) c_line," %s is killed!",adven[pc_num].name);
2354 add_string_to_buf((char *) c_line);
2355 kill_pc(pc_num,2);
2359 else {
2360 adven[pc_num].cur_sp = max(0,adven[pc_num].cur_sp - r2);
2363 if (r1 > 70) {
2364 sprintf((char *)c_line, " %s drains %d.",adven[pc_num].name,r2);
2365 add_string_to_buf((char *) c_line);
2366 adven[pc_num].cur_sp += r2;
2367 balance--;
2368 if (monst->m_d.mp == 0) {
2369 monst->m_d.status[9] += 2;
2370 monst_spell_note(monst->number,22);
2371 if (monst->m_d.status[9] > 7) {
2372 kill_monst(monst,pc_num);
2376 else {
2377 monst->m_d.mp = max(0,monst->m_d.mp - r2);
2382 print_buf();
2383 i++;
2387 // mode 0 - dispel spell, 1 - always take 2 - always take and take fire and force too
2388 void dispel_fields(short i,short j,short mode)
2390 short r1;
2392 if (mode == 2) {
2393 take_fire_barrier(i,j);
2394 take_force_barrier(i,j);
2395 take_barrel(i,j);
2396 take_crate(i,j);
2397 take_web(i,j);
2399 if (mode >= 1)
2400 mode = -10;
2401 take_fire_wall(i,j);
2402 take_force_wall(i,j);
2403 take_scloud(i,j);
2404 r1 = get_ran(1,1,6) + mode;
2405 if (r1 <= 1)
2406 take_web(i,j);
2407 r1 = get_ran(1,1,6) + mode;
2408 if (r1 < 6)
2409 take_ice_wall(i,j);
2410 r1 = get_ran(1,1,6) + mode;
2411 if (r1 < 5)
2412 take_sleep_cloud(i,j);
2413 r1 = get_ran(1,1,8) + mode;
2414 if (r1 <= 1)
2415 take_quickfire(i,j);
2416 r1 = get_ran(1,1,7) + mode;
2417 if (r1 < 5)
2418 take_blade_wall(i,j);
2420 Boolean pc_can_cast_spell(short pc_num,short type,short spell_num)
2421 //short type; // 0 - mage 1 - priest
2423 short level,store_w_cast;
2425 level = spell_level[spell_num];
2427 if (overall_mode >= 20)
2428 return FALSE;
2429 if ((spell_num < 0) || (spell_num > 61))
2430 return FALSE;
2431 if (adven[pc_num].skills[9 + type] < level)
2432 return FALSE;
2433 if (adven[pc_num].main_status != 1)
2434 return FALSE;
2435 if (adven[pc_num].cur_sp < spell_cost[type][spell_num])
2436 return FALSE;
2437 if ((type == 0) && (adven[pc_num].mage_spells[spell_num] == FALSE))
2438 return FALSE;
2439 if ((type == 1) && (adven[pc_num].priest_spells[spell_num] == FALSE))
2440 return FALSE;
2441 if (adven[pc_num].status[9] >= 8 - level)
2442 return FALSE;
2443 if (adven[pc_num].status[12] != 0)
2444 return FALSE;
2445 if (adven[pc_num].status[11] > 0)
2446 return FALSE;
2448 // 0 - everywhere 1 - combat only 2 - town only 3 - town & outdoor only 4 - town & combat only 5 - outdoor only
2449 store_w_cast = spell_w_cast[type][spell_num];
2450 if (is_out()) {
2451 if ((store_w_cast == 1) || (store_w_cast == 2) || (store_w_cast == 4)) {
2452 return FALSE;
2455 if (is_town()) {
2456 if ((store_w_cast == 1) || (store_w_cast == 5)) {
2457 return FALSE;
2460 if (is_combat()) {
2461 if ((store_w_cast == 2) || (store_w_cast == 3) || (store_w_cast == 5)) {
2462 return FALSE;
2465 return TRUE;
2469 void draw_caster_buttons()
2471 short i;
2473 if (can_choose_caster == FALSE) {
2474 for (i = 0; i < 6; i++) {
2475 if (i == pc_casting) {
2476 cd_activate_item(1098,4 + i,1);
2478 else {
2479 cd_activate_item(1098,4 + i,0);
2483 else {
2484 for (i = 0; i < 6; i++) {
2485 if (pc_can_cast_spell(i,store_situation,store_situation) == TRUE) {
2486 cd_activate_item(1098,4 + i,1);
2488 else {
2489 cd_activate_item(1098,4 + i,0);
2497 void draw_spell_info()
2500 char string[256];
2502 if (((store_situation == 0) && (store_mage == 70)) ||
2503 ((store_situation == 1) && (store_priest == 70))) { // No spell selected
2504 for (i = 0; i < 6; i++) {
2505 cd_activate_item(1098,10 + i,0);
2509 else { // Spell selected
2511 for (i = 0; i < 6; i++) {
2512 switch (((store_situation == 0) ?
2513 mage_need_select[store_mage] : priest_need_select[store_priest])) {
2514 case 0:
2515 cd_activate_item(1098,10 + i,0);
2516 break;
2517 case 1:
2518 if (adven[i].main_status != 1) {
2519 cd_activate_item(1098,10 + i,0);
2521 else {
2522 cd_activate_item(1098,10 + i,1);
2524 break;
2525 case 2:
2526 if (adven[i].main_status > 0) {
2527 cd_activate_item(1098,10 + i,1);
2529 else {
2530 cd_activate_item(1098,10 + i,0);
2532 break;
2540 void draw_spell_pc_info()
2542 short i;
2543 char string[256];
2545 for (i = 0; i < 6; i++) {
2546 if (adven[i].main_status != 0) {
2547 cd_set_item_text(1098,18 + i,adven[i].name);
2548 //if (pc_casting == i)
2549 // cd_text_frame(1098,24 + store_spell_target,11);
2550 // else cd_text_frame(1098,24 + store_spell_target,1);
2552 if (adven[i].main_status == 1) {
2553 cd_set_item_num(1098,24 + i, adven[i].cur_health);
2554 cd_set_item_num(1098,30 + i, adven[i].cur_sp);
2561 void put_pc_caster_buttons()
2564 short item_hit,what_talk_field,i;
2566 for (i = 0; i < 6; i++)
2567 if (cd_get_active(1098,i + 4) > 0) {
2568 if (i == pc_casting)
2569 cd_text_frame(1098,i + 18,11);
2570 else cd_text_frame(1098,i + 18,1);
2573 void put_pc_target_buttons()
2575 short item_hit,what_talk_field,i;
2577 if (store_spell_target < 6) {
2578 cd_text_frame(1098,24 + store_spell_target,11);
2579 cd_text_frame(1098,30 + store_spell_target,11);
2581 if ((store_last_target_darkened < 6) && (store_last_target_darkened != store_spell_target)) {
2582 cd_text_frame(1098,24 + store_last_target_darkened,1);
2583 cd_text_frame(1098,30 + store_last_target_darkened,1);
2585 store_last_target_darkened = store_spell_target;
2588 void put_spell_led_buttons()
2590 short item_hit,what_talk_field,i,spell_for_this_button;
2592 for (i = 0; i < 38; i++) {
2593 spell_for_this_button = (on_which_spell_page == 0) ? i : spell_index[i];
2595 if (spell_for_this_button < 90) {
2596 if (((store_situation == 0) && (store_mage == spell_for_this_button)) ||
2597 ((store_situation == 1) && (store_priest == spell_for_this_button))) {
2598 cd_set_led(1098,i + 37,2);
2600 else if (pc_can_cast_spell(pc_casting,store_situation,spell_for_this_button) == TRUE) {
2601 cd_set_led(1098,i + 37,1);
2603 else {
2604 cd_set_led(1098,i + 37,0);
2611 void put_spell_list()
2614 short item_hit,what_talk_field,i,j;
2615 char add_text[256];
2617 if (on_which_spell_page == 0) {
2618 csit(1098,80,"Level 1:");
2619 csit(1098,81,"Level 2:");
2620 csit(1098,82,"Level 3:");
2621 csit(1098,83,"Level 4:");
2622 for (i = 0; i < 38; i++) {
2623 if (store_situation == 0) {
2624 if (i == 35)
2625 sprintf((char *) add_text,"%s %c ?",mage_s_name[i],
2626 (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i));
2627 else sprintf((char *) add_text,"%s %c %d",mage_s_name[i],
2628 (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[0][i]);
2630 else sprintf((char *) add_text,"%s %c %d",priest_s_name[i],
2631 (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[1][i]);
2632 //for (j = 0; j < 30; i++)
2633 // if (add_text[j] == '&')
2634 // add_text[j] = (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i);
2635 cd_add_label(1098,37 + i,(char *) add_text,53);
2636 if (spell_index[i] == 90)
2637 cd_activate_item(1098,37 + i,1);
2640 else {
2641 csit(1098,80,"Level 5:");
2642 csit(1098,81,"Level 6:");
2643 csit(1098,82,"Level 7:");
2644 csit(1098,83,"");
2645 for (i = 0; i < 38; i++)
2646 if (spell_index[i] < 90) {
2647 if (store_situation == 0)
2648 sprintf((char *) add_text,"%s %c %d",mage_s_name[spell_index[i]],
2649 (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[0][spell_index[i]]);
2650 else sprintf((char *) add_text,"%s %c %d",priest_s_name[spell_index[i]],
2651 (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[1][spell_index[i]]);
2652 cd_add_label(1098,37 + i,(char *) add_text,53);
2654 else cd_activate_item(1098,37 + i,0);
2659 void put_pick_spell_graphics()
2661 short i;
2664 put_spell_list();
2665 put_pc_caster_buttons();
2666 put_pc_target_buttons();
2667 put_spell_led_buttons();
2668 for (i = 0; i < 6; i++)
2669 if (adven[i].main_status == 1)
2670 cd_draw_item(1098,18 + i); // draws effects graphics
2673 void pick_spell_event_filter (short item_hit)
2675 char *choose_target = " Now pick a target.";
2676 char *no_target = " No target needed.";
2677 char *bad_target = " Can't cast on him/her.";
2678 char *got_target = " Target selected.";
2679 char *bad_spell = " Spell not available.";
2680 Boolean spell_toast = FALSE,dialog_done = FALSE;
2682 switch (item_hit) {
2683 case 4: case 5: case 6: case 7: case 8: case 9: // pick caster
2684 if (cd_get_active(1098,item_hit) == 1) {
2685 pc_casting = item_hit - 4;
2686 if (pc_can_cast_spell(pc_casting,store_situation,
2687 ((store_situation == 0) ? store_mage : store_priest)) == FALSE) {
2688 if (store_situation == 0)
2689 store_mage = 70;
2690 else store_priest = 70;
2691 store_spell_target = 6;
2693 draw_spell_info();
2694 draw_spell_pc_info();
2695 put_spell_led_buttons();
2696 put_pc_caster_buttons();
2697 put_pc_target_buttons();
2699 break;
2700 case 10: case 11: case 12: case 13: case 14: case 15: // pick target
2701 if (cd_get_active(1098,10 + pc_casting) == FALSE) {
2702 cd_set_item_text(1098,36,no_target);
2704 else if (cd_get_active(1098,item_hit) == FALSE) {
2705 cd_set_item_text(1098,36,bad_target);
2707 else {
2709 cd_set_item_text(1098,36,got_target);
2710 store_spell_target = item_hit - 10;
2711 draw_spell_info();
2712 put_pc_target_buttons();
2714 break;
2716 case 16: // cancel
2717 spell_toast = TRUE;
2718 dialog_done = TRUE;
2719 break;
2720 case 1: case 17: // cast!
2721 dialog_done = TRUE;
2722 break;
2724 case 75: // other spells
2725 on_which_spell_page = 1 - on_which_spell_page;
2726 put_spell_list();
2727 put_spell_led_buttons();
2728 break;
2730 case 79: // help
2731 party.help_received[7] = 0;
2732 give_help(207,8,1098);
2733 break;
2735 case 100:
2736 break;
2738 default:
2739 if (item_hit >= 100) {
2740 item_hit -= 100;
2741 i = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37];
2742 display_spells(store_situation,i,1098);
2744 else if (cd_get_led(1098,item_hit) == 0) {
2745 cd_set_item_text(1098,36,bad_spell);
2747 else {
2749 if (store_situation == 0)
2750 store_mage = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37];
2751 else store_priest = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37];
2752 draw_spell_info();
2753 put_spell_led_buttons();
2755 if (store_spell_target < 6) {
2756 if (cd_get_active(1098,10 + store_spell_target) == FALSE) {
2757 store_spell_target = 6;
2758 draw_spell_info();
2759 put_pc_target_buttons();
2762 // Cute trick now... if a target is needed, caster can always be picked
2763 if ((store_spell_target == 6) && (cd_get_active(1098,10 + pc_casting) == 1)) {
2764 cd_set_item_text(1098,36,choose_target);
2765 draw_spell_info();
2766 force_play_sound(45);
2768 else if (cd_get_active(1098,10 + pc_casting) == 0) {
2769 store_spell_target = 6;
2770 put_pc_target_buttons();
2774 break;
2776 if (dialog_done == TRUE) {
2777 if (spell_toast == TRUE) {
2778 store_mage = store_mage_store;
2779 store_priest = store_priest_store;
2780 store_spell_target = store_store_target ;
2781 if (store_situation == 0)
2782 store_last_cast_mage = pc_casting;
2783 else store_last_cast_priest = pc_casting;
2784 dialog_not_toast = FALSE;
2785 dialog_answer = 70;
2786 return;
2789 if (((store_situation == 0) && (store_mage == 70)) ||
2790 ((store_situation == 1) && (store_priest == 70))) {
2791 add_string_to_buf("Cast: No spell selected.");
2792 store_mage = store_mage_store;
2793 store_priest = store_priest_store;
2794 store_spell_target = store_store_target ;
2795 dialog_not_toast = FALSE;
2796 dialog_answer = 70;
2797 return;
2799 if ((store_situation == 0) && (mage_need_select[store_mage] == 0)) {
2800 store_last_cast_mage = pc_casting;
2801 pc_last_cast[store_situation][pc_casting] = store_mage;
2802 dialog_not_toast = FALSE;
2803 dialog_answer = store_mage;
2804 return;
2806 if ((store_situation == 1) && (priest_need_select[store_priest] == 0)) {
2807 store_last_cast_priest = pc_casting;
2808 pc_last_cast[store_situation][pc_casting] = store_priest;
2809 dialog_not_toast = FALSE;
2810 dialog_answer = store_priest;
2811 return;
2813 if (store_spell_target == 6) {
2814 add_string_to_buf("Cast: Need to select target.");
2815 store_mage = store_mage_store;
2816 store_priest = store_priest_store;
2817 store_spell_target = store_store_target ;
2818 dialog_not_toast = FALSE;
2819 give_help(39,0,1098);
2820 dialog_answer = 70;
2821 return;
2823 item_hit = ((store_situation == 0) ? store_mage : store_priest);
2824 if (store_situation == 0)
2825 store_last_cast_mage = pc_casting;
2826 else store_last_cast_priest = pc_casting;
2827 pc_last_cast[store_situation][pc_casting] = ((store_situation == 0) ? store_mage : store_priest);
2828 dialog_not_toast = FALSE;
2829 dialog_answer = item_hit;
2834 short pick_spell(short pc_num,short type,short situation) // 70 - no spell OW spell num
2835 //short pc_num; // if 6, anyone
2836 //short type; // 0 - mage 1 - priest
2837 //short situation; // 0 - out 1 - town 2 - combat
2839 short item_hit;
2841 store_mage_store = store_mage;
2842 store_priest_store = store_priest;
2843 store_store_target = store_spell_target;
2844 store_situation = type;
2845 store_last_target_darkened = 6;
2846 can_choose_caster = (pc_num < 6) ? FALSE : TRUE;
2848 pc_casting = (type == 0) ? store_last_cast_mage : store_last_cast_priest;
2849 if (pc_casting == 6)
2850 pc_casting = current_pc;
2852 if (pc_num == 6) { // See if can keep same caster
2853 can_choose_caster = TRUE;
2854 if (pc_can_cast_spell(pc_casting,type,type) == FALSE) {
2855 for (i = 0; i < 6; i++)
2856 if (pc_can_cast_spell(i,type,type)) {
2857 pc_casting = i;
2858 i = 500;
2860 if (i == 6) {
2861 add_string_to_buf("Cast: Nobody can.");
2862 return 70;
2866 else {
2867 can_choose_caster = FALSE;
2868 pc_casting = pc_num;
2871 if (can_choose_caster == FALSE) {
2872 if ((type == 0) && (adven[pc_num].skills[9] == 0)) {
2873 add_string_to_buf("Cast: No mage skill.");
2874 return 70;
2876 if ((type == 1) && (adven[pc_num].skills[10] == 0)) {
2877 add_string_to_buf("Cast: No priest skill.");
2878 return 70;
2880 if (adven[pc_casting].cur_sp == 0) {
2881 add_string_to_buf("Cast: No spell points.");
2882 return 70;
2887 // If in combat, make the spell being cast this PCs most recent spell
2888 if (is_combat()) {
2889 if (type == 0)
2890 store_mage = pc_last_cast[0][pc_casting];
2891 else store_priest = pc_last_cast[1][pc_casting];
2894 // Keep the stored spell, if it's still castable
2895 if (pc_can_cast_spell(pc_casting,type,((type == 0) ? store_mage : store_priest)) == FALSE) {
2896 if (type == 0) {
2897 store_mage = 0;
2898 store_mage_lev = 1;
2900 else {
2901 store_priest = 1;
2902 store_priest_lev = 1;
2906 // If a target is needed, keep the same target if that PC still targetable
2907 if (((type == 0) && (mage_need_select[store_mage] > 0)) ||
2908 ((type == 1) && (priest_need_select[store_priest] > 0))) {
2909 if (adven[store_spell_target].main_status != 1)
2910 store_spell_target = 6;
2912 else store_spell_target = 6;
2914 // Set the spell page, based on starting spell
2915 if (((type == 0) && (store_mage >= 38)) || ((type == 1) && (store_priest >= 38)))
2916 on_which_spell_page = 1;
2917 else on_which_spell_page = 0;
2920 make_cursor_sword();
2922 cd_create_dialog(1098,mainPtr);
2923 cd_set_pict(1098,2,714 + type);
2924 for (i = 37; i < 75; i++) {
2925 cd_add_label(1098,i,"",55);
2926 if (i > 62)
2927 cd_attach_key(1098,i,(char ) (65 + i - 63));
2928 else cd_attach_key(1098,i,(char) (97 + i - 37));
2929 cd_set_led(1098,i,( pc_can_cast_spell(pc_casting,type,
2930 (on_which_spell_page == 0) ? i - 37 : spell_index[i - 37]) == TRUE) ? 1 : 0);
2932 cd_attach_key(1098,10,'!');
2933 cd_attach_key(1098,11,'@');
2934 cd_attach_key(1098,12,'#');
2935 cd_attach_key(1098,13,'$');
2936 cd_attach_key(1098,14,'%');
2937 cd_attach_key(1098,15,'^');
2938 for (i = 0; i < 6; i++)
2939 cd_key_label(1098,10 + i,0);
2940 for (i = 24; i < 36; i++)
2941 cd_text_frame(1098,i,1);
2943 cd_set_flag(1098,78,0);
2945 put_spell_list();
2946 draw_spell_info();
2947 put_pc_caster_buttons();
2948 draw_spell_pc_info();
2949 draw_caster_buttons();
2950 put_spell_led_buttons();
2952 if (party.help_received[7] == 0) {
2953 cd_initial_draw(1098);
2954 give_help(7,8,1098);
2957 while (dialog_not_toast)
2958 ModalDialog();
2959 final_process_dialog(1098);
2961 return dialog_answer;
2965 void print_spell_cast(short spell_num,short which)
2966 //short which; // 0 - mage 1 - priest
2968 sprintf ((char *) c_line, "Spell: %s ",
2969 (which == 0) ? (char *) mage_s_name[spell_num] : (char *) priest_s_name[spell_num]);
2970 add_string_to_buf((char *) c_line);
2973 short stat_adj(short pc_num,short which)
2975 short tr;
2977 tr = skill_bonus[adven[pc_num].skills[which]];
2978 if (which == 2) {
2979 if (adven[pc_num].traits[1] == TRUE)
2980 tr++;
2981 if (pc_has_abil_equip(pc_num,99) < 16)
2982 tr++;
2984 if (which == 0) {
2985 if (adven[pc_num].traits[8] == TRUE)
2986 tr++;
2988 return tr;
2991 void set_town_spell(short s_num,short who_c)
2993 town_spell = s_num;
2994 who_cast = who_c;
2997 void do_alchemy()
2999 short abil1_needed[20] = {150,151,150,151,153, 152,152,153,156,153,
3000 156,154,156,157,155, 157,157,152,156,157};
3001 short abil2_needed[20] = {0,0,0,153,0, 0,0,152,0,154,
3002 150,0,151,0,0, 154,155,155,154,155};
3003 short difficulty[20] = {1,1,1,3,3, 4,5,5,7,9, 9,10,12,12,9, 14,19,10,16,20};
3004 short fail_chance[20] = {50,40,30,20,10,8,6,4,2,0,0,0,0,0,0,0,0,0,0,0};
3005 short which_p,which_item,which_item2,r1;
3006 short pc_num;
3007 item_record_type store_i = {7,0, 0,0,0,1,0,0, 50,0,0,0,0,0, 0, 8,0, {0,0},"Potion","Potion",0,5,0,0};
3009 // {7,0,0,0,0,1,1,30,59,0,0,250,1,0,1,{0,0},"Graymold Salve","Potion"},
3010 // {7,0,0,0,0,1,1,30,13,0,0,250,1,0,1,{0,0},"Resurrection Balm","Potion"},
3012 short potion_abils[20] = {72,87,70,73,70, 87,72,73,77,88,
3013 79,70,87,70,160, 88,86,71,84,88};
3014 short potion_strs[20] = {2,2,2,2,4, 5,8,5,4,2,
3015 8,6,8,8,0, 5,2,8,5,8};
3016 short potion_val[20] = {40,60,15,50,50, 180,200,100,150,100,
3017 200,150,300,400,100, 300,500,175,250,500};
3019 pc_num = select_pc(1,0);
3020 if (pc_num == 6)
3021 return;
3023 which_p = alch_choice(pc_num);
3024 if (which_p < 20) {
3025 if (pc_has_space(pc_num) == 24) {
3026 add_string_to_buf("Alchemy: Can't carry another item.");
3027 return;
3029 if (((which_item = pc_has_abil(pc_num,abil1_needed[which_p])) == 24) ||
3030 ((abil2_needed[which_p] > 0) && ((which_item2 = pc_has_abil(pc_num,abil2_needed[which_p])) == 24))) {
3031 add_string_to_buf("Alchemy: Don't have ingredients.");
3032 return;
3034 play_sound(8);
3035 remove_charge(pc_num,which_item);
3036 if (abil2_needed[which_p] > 0)
3037 remove_charge(pc_num,which_item2);
3039 r1 = get_ran(1,0,100);
3040 if (r1 < fail_chance[adven[pc_num].skills[12] - difficulty[which_p]]) {
3041 add_string_to_buf("Alchemy: Failed. ");
3042 r1 = get_ran(1,0,1);
3043 play_sound(41 );
3045 else {
3046 store_i.value = potion_val[which_p];
3047 store_i.ability_strength = potion_strs[which_p];
3048 store_i.ability = potion_abils[which_p];
3049 if (which_p == 8)
3050 store_i.magic_use_type = 2;
3051 strcpy(store_i.full_name,alch_names_short[which_p]);
3052 if (adven[pc_num].skills[12] - difficulty[which_p] >= 5)
3053 store_i.charges++;
3054 if (adven[pc_num].skills[12] - difficulty[which_p] >= 11)
3055 store_i.charges++;
3056 if (store_i.variety == 7)
3057 store_i.graphic_num += get_ran(1,0,2);
3058 if (give_to_pc(pc_num,store_i,0) == FALSE) {
3059 ASB("No room in inventory.");
3060 ASB(" Potion placed on floor.");
3061 place_item(store_i,c_town.p_loc,TRUE);
3063 else add_string_to_buf("Alchemy: Successful. ");
3065 put_item_screen(stat_window,0);
3070 void alch_choice_event_filter (short item_hit)
3072 if (item_hit == 43) {
3073 party.help_received[20] = 0;
3074 give_help(20,21,1047);
3075 return;
3077 if (item_hit == 1)
3078 dialog_answer = 20;
3079 else {
3080 item_hit = (item_hit - 9) / 2;
3081 dialog_answer = item_hit;
3083 dialog_not_toast = FALSE;
3087 short alch_choice(short pc_num)
3089 short difficulty[20] = {1,1,1,3,3, 4,5,5,7,9, 9,10,12,12,9, 14,19,10,16,20};
3090 short i,item_hit,store_alchemy_pc;
3091 char get_text[256];
3093 make_cursor_sword();
3095 store_alchemy_pc = pc_num;
3097 cd_create_dialog(1047,mainPtr);
3098 for (i = 0; i < 20; i++) {
3099 cd_set_item_text(1047,10 + i * 2,alch_names[i]);
3100 if ((adven[pc_num].skills[12] < difficulty[i]) || (party.alchemy[i] == 0))
3101 cd_activate_item(1047,9 + i * 2,0);
3103 sprintf((char *) get_text, "%s (skill %d)",
3104 adven[pc_num].name,adven[pc_num].skills[12]);
3105 cd_set_item_text(1047,4,get_text);
3106 if (party.help_received[20] == 0) {
3107 cd_initial_draw(1047);
3108 give_help(20,21,1047);
3110 while (dialog_not_toast)
3111 ModalDialog();
3113 final_process_dialog(1047);
3114 return dialog_answer;
3117 void pc_graphic_event_filter (short item_hit)
3119 switch (item_hit) {
3120 case 1:
3121 adven[store_graphic_pc_num].which_graphic = store_pc_graphic;
3122 update_pc_graphics();
3123 if (store_graphic_mode == 0)
3124 dialog_not_toast = FALSE;
3125 else {
3126 dialog_not_toast = FALSE;
3127 dialog_answer = TRUE;
3129 break;
3131 case 4:
3132 update_pc_graphics();
3133 if (store_graphic_mode == 0) {
3134 if (adven[store_graphic_pc_num].main_status < 0)
3135 adven[store_graphic_pc_num].main_status = 0;
3136 dialog_not_toast = FALSE;
3138 else {
3139 dialog_not_toast = FALSE;
3140 dialog_answer = TRUE;
3142 break;
3144 default:
3145 cd_set_led(1050,store_pc_graphic + 5,0);
3146 store_pc_graphic = item_hit - 5;
3147 cd_set_led(1050,item_hit,1);
3148 break;
3151 dialog_answer = FALSE;
3154 Boolean pick_pc_graphic(short pc_num,short mode,short parent_num)
3155 // mode ... 0 - create 1 - created
3157 short i,item_hit;
3158 Boolean munch_pc_graphic = FALSE;
3160 store_graphic_pc_num = pc_num;
3161 store_graphic_mode = mode;
3162 store_pc_graphic = adven[pc_num].which_graphic;
3164 make_cursor_sword();
3166 if (pcs_gworld == NULL) {
3167 munch_pc_graphic = TRUE;
3168 pcs_gworld = load_pict(902,main_dc);
3170 cd_create_dialog_parent_num(1050,parent_num);
3172 for (i = 41; i < 77; i++)
3173 csp(1050,i,800 + i - 41);
3174 for (i = 5; i < 41; i++) {
3175 if (store_pc_graphic + 5 == i)
3176 cd_set_led(1050,i,1);
3177 else cd_set_led(1050,i,0);
3179 while (dialog_not_toast)
3180 ModalDialog(); cd_kill_dialog(1050,0);
3182 if (munch_pc_graphic == TRUE) {
3183 DisposeGWorld(pcs_gworld);
3184 pcs_gworld = NULL;
3186 return dialog_answer;
3189 void pc_name_event_filter (short item_hit)
3191 char get_text[256];
3193 cd_get_text_edit_str(1051,(char *) get_text);
3194 if ((get_text[0] < 33) || (get_text[0] > 126)) {
3195 csit(1051,6,"Must begin with a letter.");
3197 else {
3198 sprintf((char *) adven[store_train_pc].name,"%.18s",(char *) get_text);
3199 dialog_not_toast = FALSE;
3204 Boolean pick_pc_name(short pc_num,short parent_num)
3205 //town_num; // Will be 0 - 200 for town, 200 - 290 for outdoors
3206 //short sign_type; // terrain type
3209 short item_hit;
3210 char sign_text[256];
3211 location view_loc;
3213 store_train_pc = pc_num;
3215 make_cursor_sword();
3217 cd_create_dialog_parent_num(1051,parent_num);
3218 cd_set_edit_focus();
3220 while (dialog_not_toast)
3221 ModalDialog();
3222 cd_kill_dialog(1051,0);
3224 return 1;
3227 void pick_trapped_monst_event_filter (short item_hit)
3229 dialog_not_toast = FALSE;
3230 dialog_answer = item_hit;
3233 unsigned char pick_trapped_monst()
3234 // ignore parent in Mac version
3236 short item_hit,i;
3237 char sp[256];
3238 monster_record_type get_monst;
3240 make_cursor_sword();
3242 cd_create_dialog_parent_num(988,0);
3244 for (i = 0; i < 4; i++)
3245 if (party.imprisoned_monst[i] == 0) {
3246 cd_activate_item(988, 2 + 3 * i, 0);
3248 else {
3249 get_m_name((char *) sp,(unsigned char)(party.imprisoned_monst[i]));
3250 csit(988,3 + 3 * i,(char *) sp);
3251 get_monst = return_monster_template((unsigned char)(party.imprisoned_monst[i]));
3252 cdsin(988,4 + 3 * i,get_monst.level);
3255 while (dialog_not_toast)
3256 ModalDialog(); cd_kill_dialog(988,0);
3258 if (dialog_answer == 1)
3259 return 0;
3260 else return ((unsigned char)(party.imprisoned_monst[(dialog_answer - 2) / 3]));
3265 Boolean flying()
3267 if (party.stuff_done[305][1] == 0)
3268 return FALSE;
3269 else return TRUE;
3272 void poison_pc(short which_pc,short how_much)
3274 short level = 0;
3276 if (adven[which_pc].main_status == 1) {
3277 if ((level = get_prot_level(which_pc,34)) > 0)////
3278 how_much -= level / 2;
3279 if ((level = get_prot_level(which_pc,31)) > 0)////
3280 how_much -= level / 3;
3281 if ((adven[which_pc].traits[12] == TRUE) &&
3282 (how_much > 1))
3283 how_much++;
3284 if ((adven[which_pc].traits[12] == TRUE) &&
3285 (how_much == 1) && (get_ran(1,0,1) == 0))
3286 how_much++;
3288 if (how_much > 0) {
3289 adven[which_pc].status[2] = min(adven[which_pc].status[2] + how_much,8);
3290 sprintf ((char *) c_line, " %s poisoned.",
3291 (char *) adven[which_pc].name);
3292 add_string_to_buf((char *) c_line);
3293 one_sound(17);
3294 give_help(33,0,0);
3297 put_pc_screen();
3300 void poison_party(short how_much)
3302 short i;
3304 for (i = 0; i < 6; i++)
3305 poison_pc(i,how_much);
3308 void affect_pc(short which_pc,short type,short how_much)////
3309 //type; // which status to affect
3312 if (adven[which_pc].main_status != 1)
3313 return;
3314 adven[which_pc].status[type] = minmax (-8,8,adven[which_pc].status[type] + how_much);
3315 if (((type >= 4) && (type <= 10)) || (type == 12) || (type == 13))
3316 adven[which_pc].status[type] = max(adven[which_pc].status[type],0);
3317 put_pc_screen();
3320 void affect_party(short type,short how_much)
3321 //type; // which status to affect
3323 short i;
3325 for (i = 0; i < 6; i++)
3326 if (adven[i].main_status == 1)
3327 adven[i].status[type] = minmax (-8,8,adven[i].status[type] + how_much);
3328 put_pc_screen();
3332 void void_sanctuary(short pc_num)
3334 if (adven[pc_num].status[8] > 0) {
3335 add_string_to_buf("You become visible!");
3336 adven[pc_num].status[8] = 0;
3340 void hit_party(short how_much,short damage_type)
3342 short i;
3343 Boolean dummy;
3345 for (i = 0; i < 6; i++)
3346 if (adven[i].main_status == 1)
3347 dummy = damage_pc(i,how_much,damage_type,-1);
3348 // dummy = damage_pc(i,how_much,damage_type + 30);
3349 put_pc_screen();
3352 void slay_party(short mode)
3354 short i;
3356 boom_anim_active = FALSE;
3357 for (i = 0; i < 6; i++)
3358 if (adven[i].main_status == 1)
3359 adven[i].main_status = mode;
3360 put_pc_screen();
3363 Boolean damage_pc(short which_pc,short how_much,short damage_type,short type_of_attacker)
3364 //short damage_type; // 0 - weapon 1 - fire 2 - poison 3 - general magic 4 - unblockable
3365 // 5 - cold 6 - undead attack 7 - demon attack
3366 // 10 - marked damage, from during anim mode ... no boom, and totally unblockable
3367 // 30 + * same as *, but no print
3368 // 100s digit - sound data
3370 short i, r1,sound_type,level;
3371 Boolean do_print = TRUE;
3373 if (adven[which_pc].main_status != 1)
3374 return FALSE;
3376 sound_type = damage_type / 100;
3377 damage_type = damage_type % 100;
3379 if (damage_type >= 30) {
3380 do_print = FALSE;
3381 damage_type -= 30;
3384 if (sound_type == 0) {
3385 if ((damage_type == 1) || (damage_type == 4) )
3386 sound_type = 5;
3387 if (damage_type == 3)
3388 sound_type = 12;
3389 if (damage_type == 5)
3390 sound_type = 7;
3391 if (damage_type == 2)
3392 sound_type = 11;
3395 // armor
3396 if ((damage_type == 0) || (damage_type == 6) ||(damage_type == 7)) {
3397 how_much -= minmax(-5,5,adven[which_pc].status[1]);
3398 for (i = 0; i < 24; i++)
3399 if ((adven[which_pc].items[i].variety != 0) && (adven[which_pc].equip[i] == TRUE)) {
3400 if ((adven[which_pc].items[i].variety >= 12) && (adven[which_pc].items[i].variety <= 17)) {
3401 r1 = get_ran(1,1,adven[which_pc].items[i].item_level);
3402 how_much -= r1;
3404 // bonus for magical items
3405 if (adven[which_pc].items[i].bonus > 0) {
3406 r1 = get_ran(1,1,adven[which_pc].items[i].bonus);
3407 how_much -= r1;
3408 how_much -= adven[which_pc].items[i].bonus / 2;
3410 if (adven[which_pc].items[i].bonus < 0) {
3411 how_much = how_much - adven[which_pc].items[i].bonus;
3413 r1 = get_ran(1,0,100);
3414 if (r1 < hit_chance[adven[which_pc].skills[8]] - 20)
3415 how_much -= 1;
3417 if (adven[which_pc].items[i].protection > 0) {
3418 r1 = get_ran(1,1,adven[which_pc].items[i].protection);
3419 how_much -= r1;
3421 if (adven[which_pc].items[i].protection < 0) {
3422 r1 = get_ran(1,1,-1 * adven[which_pc].items[i].protection);
3423 how_much += r1;
3428 // parry
3429 if ((damage_type < 2) && (pc_parry[which_pc] < 100))
3430 how_much -= pc_parry[which_pc] / 4;
3433 if (damage_type != 10) {
3434 if (PSD[306][7] > 0)
3435 how_much -= 3;
3436 // toughness
3437 if (adven[which_pc].traits[0] == TRUE)
3438 how_much--;
3439 // luck
3440 if (get_ran(1,0,100) < 2 * (hit_chance[adven[which_pc].skills[18]] - 20))
3441 how_much -= 1;
3444 if ((damage_type == 0) && ((level = get_prot_level(which_pc,30)) > 0))
3445 how_much = how_much - level;
3446 if ((damage_type == 6) && ((level = get_prot_level(which_pc,57)) > 0))
3447 how_much = how_much / ((level >= 7) ? 4 : 2);
3448 if ((damage_type == 7) && ((level = get_prot_level(which_pc,58)) > 0))
3449 how_much = how_much / ((level >= 7) ? 4 : 2);
3450 if ((type_of_attacker == 6) && ((level = get_prot_level(which_pc,59)) > 0))
3451 how_much = how_much / ((level >= 7) ? 4 : 2);
3452 if ((type_of_attacker == 1) && ((level = get_prot_level(which_pc,60)) > 0))
3453 how_much = how_much / ((level >= 7) ? 4 : 2);
3454 if ((type_of_attacker == 9) && ((level = get_prot_level(which_pc,61)) > 0))
3455 how_much = how_much / ((level >= 7) ? 4 : 2);
3458 // invuln
3459 if (adven[which_pc].status[4] > 0)
3460 how_much = 0;
3462 // magic resistance
3463 if ((damage_type == 3) && ((level = get_prot_level(which_pc,35)) > 0))
3464 how_much = how_much / ((level >= 7) ? 4 : 2);
3466 // Mag. res helps w. fire and cold
3467 if (((damage_type == 1) || (damage_type == 5)) &&
3468 (adven[which_pc].status[5] > 0))
3469 how_much = how_much / 2;
3471 // fire res.
3472 if ((damage_type == 1) && ((level = get_prot_level(which_pc,32)) > 0))
3473 how_much = how_much / ((level >= 7) ? 4 : 2);
3475 // cold res.
3476 if ((damage_type == 5) && ((level = get_prot_level(which_pc,33)) > 0))
3477 how_much = how_much / ((level >= 7) ? 4 : 2);
3479 // major resistance
3480 if (((damage_type == 1) || (damage_type == 2) || (damage_type == 3) || (damage_type == 5))
3481 && ((level = get_prot_level(which_pc,31)) > 0))
3482 how_much = how_much / ((level >= 7) ? 4 : 2);
3484 if (boom_anim_active == TRUE) {
3485 if (how_much < 0)
3486 how_much = 0;
3487 pc_marked_damage[which_pc] += how_much;
3488 if (is_town())
3489 add_explosion(c_town.p_loc,how_much,0,(damage_type > 2) ? 2 : 0,0,0);
3490 else add_explosion(pc_pos[which_pc],how_much,0,(damage_type > 2) ? 2 : 0,0,0);
3491 // sprintf ((char *) c_line, " %s takes %d. ",(char *) adven[which_pc].name, how_much);
3492 // if (do_print == TRUE)
3493 // add_string_to_buf((char *) c_line);
3494 if (how_much == 0)
3495 return FALSE;
3496 else return TRUE;
3499 if (how_much <= 0) {
3500 if ((damage_type == 0) || (damage_type == 6) || (damage_type == 7))
3501 play_sound(2);
3502 add_string_to_buf (" No damage.");
3503 return FALSE;
3505 else {
3506 // if asleep, get bonus
3507 if (adven[which_pc].status[11] > 0)
3508 adven[which_pc].status[11]--;
3510 sprintf ((char *) c_line, " %s takes %d. ",(char *) adven[which_pc].name, how_much);
3511 if (do_print == TRUE)
3512 add_string_to_buf((char *) c_line);
3513 if (damage_type != 10) {
3514 if (is_combat())
3515 boom_space(pc_pos[which_pc],overall_mode,boom_gr[damage_type],how_much,sound_type);
3516 else if (is_town())
3517 boom_space(c_town.p_loc,overall_mode,boom_gr[damage_type],how_much,sound_type);
3518 else boom_space(c_town.p_loc,100,boom_gr[damage_type],how_much,sound_type);
3520 if (overall_mode != 0)
3521 FlushEvents(1);
3522 FlushEvents(0);
3525 party.total_dam_taken += how_much;
3527 if (adven[which_pc].cur_health >= how_much)
3528 adven[which_pc].cur_health = adven[which_pc].cur_health - how_much;
3529 else if (adven[which_pc].cur_health > 0)
3530 adven[which_pc].cur_health = 0;
3531 else // Check if PC can die
3532 if (how_much > 25) {
3533 sprintf ((char *) c_line, " %s is obliterated. ",(char *) adven[which_pc].name);
3534 add_string_to_buf((char *) c_line);
3535 kill_pc(which_pc, 3);
3537 else {
3538 sprintf ((char *) c_line, " %s is killed.",(char *) adven[which_pc].name);
3539 add_string_to_buf((char *) c_line);
3540 kill_pc(which_pc,2);
3542 if ((adven[which_pc].cur_health == 0) && (adven[which_pc].main_status == 1))
3543 play_sound(3);
3544 put_pc_screen();
3545 return TRUE;
3548 void kill_pc(short which_pc,short type)
3550 short i = 24;
3551 Boolean dummy,no_save = FALSE;
3552 location item_loc;
3554 if (type >= 10) {
3555 type -= 10;
3556 no_save = TRUE;
3559 if (type != 4)
3560 i = pc_has_abil_equip(which_pc,9);
3562 if ((no_save == FALSE) && (type != 0) && (adven[which_pc].skills[18] > 0) &&
3563 (get_ran(1,0,100) < hit_chance[adven[which_pc].skills[18]])) {
3564 add_string_to_buf(" But you luck out! ");
3565 adven[which_pc].cur_health = 0;
3567 else if ((i == 24) || (type == 0)) {
3568 if (combat_active_pc == which_pc)
3569 combat_active_pc = 6;
3571 for (i = 0; i < 24; i++)
3572 adven[which_pc].equip[i] = FALSE;
3574 item_loc = (overall_mode >= 10) ? pc_pos[which_pc] : c_town.p_loc;
3576 if (type == 2)
3577 make_sfx(item_loc.x,item_loc.y,3);
3578 else if (type == 3)
3579 make_sfx(item_loc.x,item_loc.y,6);
3581 if (overall_mode != 0)
3582 for (i = 0; i < 24; i++)
3583 if (adven[which_pc].items[i].variety != 0) {
3584 dummy = place_item(adven[which_pc].items[i],item_loc,TRUE);
3585 adven[which_pc].items[i].variety = 0;
3587 if ((type == 2) || (type == 3))
3588 play_sound(21);
3589 adven[which_pc].main_status = type;
3590 pc_moves[which_pc] = 0;
3592 else {
3593 add_string_to_buf(" Life saved! ");
3594 take_item(which_pc,i);
3595 heal_pc(which_pc,200);
3597 if (adven[current_pc].main_status != 1)
3598 current_pc = first_active_pc();
3599 if (current_pc > 5) {
3600 for (i = 0; i < 6; i++)
3601 if (adven[i].status > 0)
3602 current_pc = i;
3604 put_pc_screen();
3605 set_stat_window(current_pc);
3608 void set_pc_moves()
3610 short i,r,i_level;
3612 for (i = 0; i < 6; i++)
3613 if (adven[i].main_status != 1)
3614 pc_moves[i] = 0;
3615 else {
3616 pc_moves[i] = (adven[i].traits[10] == TRUE) ? 3 : 4;
3617 r = get_encumberance(i);
3618 pc_moves[i] = minmax(1,8,pc_moves[i] - (r / 3));
3620 if ((i_level = get_prot_level(i,55)) > 0)
3621 pc_moves[i] += i_level / 7 + 1;
3622 if ((i_level = get_prot_level(i,56)) > 0)
3623 pc_moves[i] -= i_level / 5;
3625 if ((adven[i].status[3] < 0) && (party.age % 2 == 1)) // slowed?
3626 pc_moves[i] = 0;
3627 else { // do webs
3628 pc_moves[i] = max(0,pc_moves[i] - adven[i].status[6] / 2);
3629 if (pc_moves[i] == 0) {
3630 sprintf((char *) c_line,"%s must clean webs.",adven[i].name);
3631 add_string_to_buf((char *) c_line);
3632 adven[i].status[6] = max(0,adven[i].status[6] - 3);
3635 if (adven[i].status[3] > 7)
3636 pc_moves[i] = pc_moves[i] * 3;
3637 else if (adven[i].status[3] > 0)
3638 pc_moves[i] = pc_moves[i] * 2;
3639 if ((adven[i].status[11] > 0) || (adven[i].status[12] > 0))
3640 pc_moves[i] = 0;
3646 void take_ap(short num)
3648 pc_moves[current_pc] = max(0,pc_moves[current_pc] - num);
3651 short cave_lore_present()
3653 short i,ret = 0;
3654 for (i = 0; i < 6; i++)
3655 if ((adven[i].main_status == 1) && (adven[i].traits[4] > 0))
3656 ret += 1;
3657 return ret;
3660 short woodsman_present()
3662 short i,ret = 0;
3663 for (i = 0; i < 6; i++)
3664 if ((adven[i].main_status == 1) && (adven[i].traits[5] > 0))
3665 ret += 1;
3666 return ret;
3669 void init_spell_menus()
3671 short i,j;
3673 for (i = 0; i < 2; i++)
3674 for (j = 0; j < 62; j++)
3675 on_spell_menu[i][j] = -1;
3680 // Time for some chicanery
3681 // The how to item for mage will be 399, for priest will be 499
3682 // item 400 + i will mean cast mage spell i.
3683 // item 500 + i will mean cast priest spell i.
3684 void adjust_spell_menus()
3686 short i,j,spell_pos = 0;
3687 short total_added = 0;
3688 char spell_name[256];
3689 short old_on_spell_menu[2][62];
3690 Boolean need_menu_change = FALSE;
3691 HMENU menu,big_menu;
3693 if (in_startup_mode == TRUE)
3694 return;
3696 big_menu = GetMenu(mainPtr);
3697 menu = GetSubMenu(big_menu,6);
3698 if (menu == NULL)
3699 return;
3700 for (i = 0; i < 2; i++)
3701 for (j = 0; j < 62; j++)
3702 old_on_spell_menu[i][j] = on_spell_menu[i][j];
3704 for (i = 0; i < 62; i++) {
3705 on_spell_menu[0][i] = -1;
3707 for (i = 0; i < 62; i++)
3708 if (pc_can_cast_spell(current_pc,0,i)) {
3709 on_spell_menu[0][spell_pos] = i;
3710 spell_pos++;
3713 for (i = 0; i < 62; i++)
3714 if (on_spell_menu[0][i] != old_on_spell_menu[0][i])
3715 need_menu_change = TRUE;
3718 if (need_menu_change) {
3719 for (i = 0; i < 62; i++) {
3720 DeleteMenu(menu,400 + i,MF_BYCOMMAND);
3723 for (i = 0; i < 62; i++)
3724 if (pc_can_cast_spell(current_pc,0,i) == TRUE) {
3725 if (spell_cost[0][i] > 0)
3726 sprintf((char *)spell_name,"L%d - %s, C %d",spell_level[i],
3727 (char *) mage_s_name[i],spell_cost[0][i]);
3728 else sprintf((char *)spell_name,"L%d - %s, C ?",spell_level[i],
3729 (char *) mage_s_name[i]);
3730 total_added++;
3731 if (total_added % 24 == 0)
3732 InsertMenu(menu,399,MF_MENUBREAK | MF_BYCOMMAND | MF_ENABLED | MF_STRING, 400 + i, spell_name);
3733 else InsertMenu(menu,399,MF_BYCOMMAND | MF_ENABLED | MF_STRING, 400 + i, spell_name);
3735 //InsertMenu(menu,399,MF_BYCOMMAND | MF_ENABLED | MF_STRING,
3736 // 400 + i, spell_name);
3737 //beep();
3741 need_menu_change = FALSE;
3742 spell_pos = 0;
3743 total_added = 0;
3744 menu = GetSubMenu(big_menu,7);
3745 if (menu == NULL)
3746 return;
3748 for (i = 0; i < 62; i++) {
3749 on_spell_menu[1][i] = -1;
3751 for (i = 0; i < 62; i++)
3752 if (pc_can_cast_spell(current_pc,1,i)) {
3753 on_spell_menu[1][spell_pos] = i;
3754 spell_pos++;
3756 for (i = 0; i < 62; i++)
3757 if (on_spell_menu[1][i] != old_on_spell_menu[1][i])
3758 need_menu_change = TRUE;
3759 if (need_menu_change) {
3760 for (i = 0; i < 62; i++) {
3761 DeleteMenu(menu,500 + i,MF_BYCOMMAND);
3763 for (i = 0; i < 62; i++)
3764 if (pc_can_cast_spell(current_pc,1,i) == TRUE) {
3765 //spell_name[0] = strlen((char *) priest_s_name[on_spell_menu[1][i]]);
3766 //strcpy((char *) (spell_name + 1),priest_s_name[on_spell_menu[1][i]]);
3767 if (spell_cost[1][i] > 0)
3768 sprintf((char *)spell_name," L%d - %s, C %d",spell_level[i],
3769 (char *) priest_s_name[i],spell_cost[1][i]);
3770 else sprintf((char *)spell_name," L%d - %s, C ?",spell_level[i],
3771 (char *) priest_s_name[i]);
3772 total_added++;
3773 if (total_added % 24 == 0)
3774 InsertMenu(menu,499,MF_MENUBREAK | MF_BYCOMMAND | MF_ENABLED | MF_STRING, 500 + i, spell_name);
3775 else InsertMenu(menu,499,MF_BYCOMMAND | MF_ENABLED | MF_STRING, 500 + i, spell_name);