#include #include #include "global.h" #include "boe.fileio.h" #include "boe.graphics.h" #include "boe.newgraph.h" #include "boe.specials.h" #include "boe.itemdata.h" #include "boe.infodlg.h" #include "boe.items.h" #include #include "boe.party.h" #include "boe.monster.h" #include "tools/dlogtool.h" #include "boe.town.h" #include "boe.combat.h" #include "boe.locutils.h" #include "boe.fields.h" #include "boe.text.h" #include "tools/soundtool.h" #include "tools/mathutil.h" #include "boe.graphutil.h" #include "globvar.h" void draw_caster_buttons(); void draw_spell_info(); void draw_spell_pc_info(); void put_pc_caster_buttons(); void put_pc_target_buttons(); void put_spell_led_buttons(); void put_spell_list(); //mode; // 0 - prefab 1 - regular void init_party(short mode) { short i,j,k,l; Boolean store_help; boat_record_type null_boat = {location(),location(),location(),200,false,false}; horse_record_type null_horse = {location(),location(),location(),200,false,false}; party.age = 0; party.gold = 200; party.food = 100; store_help = PSD[SDF_NO_INSTANT_HELP]; for (i = 0; i < 310; i++) for (j = 0; j < 10; j++) party.stuff_done[i][j] = 0; if(scenario.prog_make_ver[0] < 2) PSD[SDF_LEGACY_SCENARIO] = 1; //old scenario format ? else PSD[SDF_LEGACY_SCENARIO] = 0; PSD[SDF_NO_INSTANT_HELP] = store_help; party.light_level = 0; party.outdoor_corner.x = 7; party.outdoor_corner.y = 8; party.i_w_c.x = 1; party.i_w_c.y = 1; party.loc_in_sec.x = 36; party.loc_in_sec.y = 36; party.p_loc.x = 84; party.p_loc.y = 84; for (i = 0; i < 30; i++) party.boats[i] = null_boat; for (i = 0; i < 30; i++) party.horses[i] = null_horse; party.in_boat = -1; party.in_horse = -1; for (i = 0; i < 4; i++) party.creature_save[i].which_town = 200; for (i = 0; i < 10; i++) party.out_c[i].exists = false; for (i = 0; i < 5; i++) for (j = 0; j < 10; j++) party.magic_store_items[i][j].variety = ITEM_TYPE_NO_ITEM; for (i = 0; i < 4; i++) party.imprisoned_monst[i] = 0; for (i = 0; i < 256; i++) party.m_seen[i] = 0; for (i = 0; i < 50; i++) party.journal_str[i] = -1; for (i = 0; i < 140; i++) for (j = 0; j < 2; j++) party.special_notes_str[i][j] = 0; for (i = 0; i < 120; i++) party.talk_save[i].personality = -1; party.total_m_killed = 0; party.total_dam_done = 0; party.total_xp_gained = 0; party.total_dam_taken = 0; party.direction = 0; party.at_which_save_slot = 0; for (i = 0; i < 20; i++) party.alchemy[i] = 0; for (i = 0; i < 200; i++) party.can_find_town[i] = 0; for (i = 0; i < 100; i++) party.key_times[i] = 30000; for (i = 0; i < 30; i++) party.party_event_timers[i] = 0; for (i = 0; i < 50; i++) party.spec_items[i] = 0; for (i = 0; i < 120; i++) party.help_received[i] = 0; for (i = 0; i < 200; i++) party.m_killed[i] = 0; sprintf((char *) party.scen_name,""); for (i = 0; i < 200; i++) for (j = 0; j < 8; j++) party.item_taken[i][j] = 0; refresh_store_items(); for (i = 0; i < 6; i++) { adven[i] = return_dummy_pc(); if (mode != 1) adven[i] = create_prefab_pc(i); } for (i = 0; i < 96; i++) for (j = 0; j < 96; j++) out_e[i][j] = 0; for (i = 0; i < 3;i++) for (j = 0; j < NUM_TOWN_ITEMS; j++) stored_items[i].items[j] = return_dummy_item(); for (i = 0; i < 200; i++) for (j = 0; j < 8; j++) for (k = 0; k < 64; k++) { town_maps.town_maps[i][j][k] = 0; } for (i = 0; i < 100; i++) for (k = 0; k < 6; k++) for (l = 0; l < 48; l++) o_maps.outdoor_maps[i][k][l] = 0; // Default is save maps party.stuff_done[SFD_NO_MAPS] = 0; save_maps = true; // NOT DEBUG build_outdoors(); get_reg_data(); } // This is only called after a scenario is loaded and the party is put into it. // Until that time, the party scen vals are uninited // Then, it inits the party properly for starting the scenario based // on the loaded scenario void init_party_scen_data() { short i,j,k,l; Boolean stored_item = false; short store_help; party.age = 0; store_help = PSD[SDF_NO_INSTANT_HELP]; for (i = 0; i < 310; i++) for (j = 0; j < 10; j++) party.stuff_done[i][j] = 0; PSD[SDF_NO_INSTANT_HELP] = store_help; if(scenario.prog_make_ver[0] < 2) PSD[SDF_LEGACY_SCENARIO] = 1; //old scenario format ? else PSD[SDF_LEGACY_SCENARIO] = 0; party.light_level = 0; party.outdoor_corner.x = scenario.out_sec_start.x; party.outdoor_corner.y = scenario.out_sec_start.y; party.i_w_c.x = 0; party.i_w_c.y = 0; party.loc_in_sec.x = scenario.out_start.x; party.loc_in_sec.y = scenario.out_start.y; party.p_loc.x = scenario.out_start.x; party.p_loc.y = scenario.out_start.y; for (i = 0; i < NUM_OF_BOATS; i++) party.boats[i] = scenario.scen_boats[i]; for (i = 0; i < NUM_OF_HORSES; i++) party.horses[i] = scenario.scen_horses[i]; for (i = 0; i < 30; i++) { if ((scenario.scen_boats[i].which_town >= 0) && (scenario.scen_boats[i].boat_loc.x >= 0)) { if (party.boats[i].exists == false) { party.boats[i] = scenario.scen_boats[i]; party.boats[i].exists = true; } } if ((scenario.scen_horses[i].which_town >= 0) && (scenario.scen_horses[i].horse_loc.x >= 0)) { if (party.horses[i].exists == false) { party.horses[i] = scenario.scen_horses[i]; party.horses[i].exists = true; } } } party.in_boat = -1; party.in_horse = -1; for (i = 0; i < 4; i++) party.creature_save[i].which_town = INVALID_TOWN; for (i = 0; i < 10; i++) party.out_c[i].exists = false; for (i = 0; i < 5; i++) for (j = 0; j < 10; j++) party.magic_store_items[i][j].variety = ITEM_TYPE_NO_ITEM; for (i = 0; i < 4; i++) party.imprisoned_monst[i] = 0; for (i = 0; i < 256; i++) party.m_seen[i] = 0; for (i = 0; i < 50; i++) party.journal_str[i] = -1; for (i = 0; i < 140; i++) for (j = 0; j < 2; j++) party.special_notes_str[i][j] = 0; for (i = 0; i < 120; i++) party.talk_save[i].personality = -1; party.direction = 0; party.at_which_save_slot = 0; for (i = 0; i < 200; i++) party.can_find_town[i] = 1 - scenario.town_hidden[i]; for (i = 0; i < 100; i++) party.key_times[i] = 30000; for (i = 0; i < 30; i++) party.party_event_timers[i] = 0; for (i = 0; i < 50; i++) party.spec_items[i] = (scenario.special_items[i] >= 10) ? 1 : 0; for (i = 0; i < 200; i++) party.m_killed[i] = 0; for (i = 0; i < 200; i++) for (j = 0; j < 8; j++) party.item_taken[i][j] = 0; refresh_store_items(); for (i = 0; i < 96; i++) for (j = 0; j < 96; j++) out_e[i][j] = 0; for (i = 0; i < 3;i++) for (j = 0; j < NUM_TOWN_ITEMS; j++) if (stored_items[i].items[j].variety != ITEM_TYPE_NO_ITEM) stored_item = true; if (stored_item == true) if (FCD(911,0) == 1) { for (i = 0; i < 3;i++) for (j = 0; j < NUM_TOWN_ITEMS; j++) if (stored_items[i].items[j].variety != ITEM_TYPE_NO_ITEM) if (give_to_party(stored_items[i].items[j],false) == false) { i = 20; j = NUM_TOWN_ITEMS + 1; } } for (i = 0; i < 3;i++) for (j = 0; j < NUM_TOWN_ITEMS; j++) { stored_items[i].items[j] = return_dummy_item(); } for (i = 0; i < 200; i++) for (j = 0; j < 8; j++) for (k = 0; k < 64; k++) { town_maps.town_maps[i][j][k] = 0; } for (i = 0; i < 100; i++) for (k = 0; k < 6; k++) for (l = 0; l < 48; l++) o_maps.outdoor_maps[i][k][l] = 0; get_reg_data(); } // When the party is placed into a scen from the startinbg screen, this is called to put the game into game // mode and load in the scen and init the party info // party record already contains scen name void put_party_in_scen() { short i,j; char strs[6][256] = {"","","","","",""}; short buttons[3] = {-1,-1,-1}; Boolean item_took = false; for (j = 0; j < 6; j++) for (i = 0; i < 15; i++) adven[j].status[i] = 0; for (j = 0; j < 6; j++) { // unite party if (adven[j].main_status >= MAIN_STATUS_SPLIT) adven[j].main_status -= MAIN_STATUS_SPLIT; // start with maximum health adven[j].cur_health = adven[j].max_health; // start with maximum amount of spell points adven[j].cur_sp = adven[j].max_sp; } for (j = 0; j < 6; j++) for (i = 23; i >= 0; i--) { adven[j].items[i].special_class = 0; if (adven[j].items[i].graphic_num >= 150)//custom item graphic? { adven[j].takeItem(i + 30); // strip away special items item_took = true; } if (adven[j].items[i].ability == ITEM_SPELL_SUMMONING) { adven[j].takeItem(i + 30); // strip away summoning items item_took = true; } if (adven[j].items[i].ability == ITEM_SPELL_MASS_SUMMONING) { adven[j].takeItem(i + 30); // strip away summoning items item_took = true; } } if (item_took == true) FCD(910,0); if (load_scenario() == false) return; init_party_scen_data(); // if at this point, startup must be over, so make this call to make sure we're ready, // graphics wise end_startup(); in_startup_mode = false; set_up_ter_pics(); load_outdoors(party.outdoor_corner.x + 1,party.outdoor_corner.y + 1,1,1,0,0,NULL); load_outdoors(party.outdoor_corner.x,party.outdoor_corner.y + 1,0,1,0,0,NULL); load_outdoors(party.outdoor_corner.x + 1,party.outdoor_corner.y,1,0,0,0,NULL); load_outdoors(party.outdoor_corner.x,party.outdoor_corner.y,0,0,0,0,NULL); stat_screen_mode = 0; build_outdoors(); erase_out_specials(); current_pc = first_active_pc(); force_town_enter(scenario.which_town_start, scenario.where_start); start_town_mode(scenario.which_town_start, 9); center = scenario.where_start; update_explored(scenario.where_start); overall_mode = MODE_TOWN; create_clip_region(); redraw_screen(0); set_stat_window(0); adjust_spell_menus(); adjust_monst_menu(); // Throw up intro dialog buttons[0] = 1; for (j = 0; j < 6; j++) if (strlen(data_store5->scen_strs[4 + j]) > 0) { for (i = 0; i < 6; i++) strcpy((char *) strs[i],data_store5->scen_strs[4 + i]); if(scenario.intro_pic == 100) custom_choice_dialog((char *) strs,2400,buttons) ; else custom_choice_dialog((char *) strs,-1 * (1600 + scenario.intro_pic),buttons) ; j = 6; } give_help(1,2,0); // this is kludgy, put here to prevent problems for (i = 0; i < 50; i++) party.spec_items[i] = (scenario.special_items[i] >= 10) ? 1 : 0; } pc_record_type return_dummy_pc() { pc_record_type dummy_pc; short i; dummy_pc.main_status = MAIN_STATUS_ABSENT; sprintf ((char *) dummy_pc.name, "\n"); for (i = 0; i < 30; i++) dummy_pc.skills[i] = (i < 3) ? 1 : 0; dummy_pc.cur_health = 6; dummy_pc.max_health = 6; dummy_pc.cur_sp = 0; dummy_pc.max_sp = 0; dummy_pc.experience = 0; dummy_pc.skill_pts = 60; dummy_pc.level = 1; for (i = 0; i < 15; i++) dummy_pc.status[i] = 0; for (i = 0; i < 24; i++) dummy_pc.items[i] = return_dummy_item(); for (i = 0; i < 24; i++) dummy_pc.equip[i] = false; for (i = 0; i < 62; i++) { dummy_pc.priest_spells[i] = (i < 30) ? true : false; dummy_pc.mage_spells[i] = (i < 30) ? true : false; } dummy_pc.which_graphic = 0; dummy_pc.weap_poisoned = 24; for (i = 0; i < 15; i++) { dummy_pc.advan[i] = false; dummy_pc.traits[i] = false; } dummy_pc.race = RACE_HUMAN; dummy_pc.exp_adj = 100; dummy_pc.direction = 0; return dummy_pc; } pc_record_type create_prefab_pc(short num) { pc_record_type dummy_pc; short i; short pc_stats[6][19] = { {8,6,2, 6,0,0,0,0,0, 0,0,0,0,1, 0,0,2,0,0}, {8,7,2, 0,0,6,3,0,3, 0,0,0,0,0, 0,0,0,2,0}, {8,6,2, 3,3,0,0,2,0, 0,0,0,0,0, 4,4,0,2,1}, {3,2,6, 2,0,0,2,0,0, 3,0,3,0,1, 0,0,0,0,0}, {2,2,6, 3,0,0,2,0,0, 2,1,4,0,0, 0,0,0,0,1}, {2,2,6, 0,2,0,2,0,1, 0,3,3,2,0, 0,0,0,0,0} }; short pc_health[6] = {22,24,24,16,16,18}; short pc_sp[6] = {0,0,0,20,20,21}; short pc_graphics[6] = {3,32,29,16,23,14}; short pc_race[6] = {0,2,1,0,0,0}; short pc_t[6][15] = {{0,0,1,0,0,0,1,0,0,0, 0,1,0,0,0}, {1,0,0,0,0,1,0,0,0,0, 1,0,0,0,0}, {0,0,0,1,0,0,0,0,0,0, 0,0,1,0,0}, {0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0}, {0,0,0,0,1,0,1,1,0,0, 0,0,0,0,1}, {0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0}}; dummy_pc.main_status = MAIN_STATUS_ALIVE; switch (num) { case 0: strncpy ((char *) dummy_pc.name, "Jenneke", (size_t) 20); break; case 1: strncpy ((char *) dummy_pc.name, "Thissa", (size_t) 20); break; case 2: strncpy ((char *) dummy_pc.name, "Frrrrrr", (size_t) 20); break; case 3: strncpy ((char *) dummy_pc.name, "Adrianna", (size_t) 20); break; case 4: strncpy ((char *) dummy_pc.name, "Feodoric", (size_t) 20); break; case 5: strncpy ((char *) dummy_pc.name, "Michael", (size_t) 20); break; } for (i = 0; i < 19; i++) dummy_pc.skills[i] = pc_stats[num][i]; dummy_pc.cur_health = pc_health[num]; dummy_pc.max_health = pc_health[num]; dummy_pc.experience = 0; dummy_pc.skill_pts = 0; dummy_pc.level = 1; for (i = 0; i < 15; i++) dummy_pc.status[i] = 0; for (i = 0; i < 24; i++) dummy_pc.items[i] = return_dummy_item(); for (i = 0; i < 24; i++) dummy_pc.equip[i] = false; dummy_pc.cur_sp = pc_sp[num]; dummy_pc.max_sp = pc_sp[num]; for (i = 0; i < 62; i++) { dummy_pc.priest_spells[i] = (i < 30) ? true : false;//// dummy_pc.mage_spells[i] = (i < 30) ? true : false; } for (i = 0; i < 15; i++) { dummy_pc.traits[i] = pc_t[num][i]; dummy_pc.advan[i] = false; } dummy_pc.race = pc_race[num]; dummy_pc.exp_adj = 100; dummy_pc.direction = 0; dummy_pc.which_graphic = pc_graphics[num]; return dummy_pc; } Boolean create_pc(short spot,short parent_num) //spot; // if spot is 6, find one { Boolean still_ok = true; if (spot == INVALID_PC) { for (spot = 0; spot < INVALID_PC; spot++) if (adven[spot].main_status == MAIN_STATUS_ABSENT) break; } if (spot == INVALID_PC) return false; adven[spot] = return_dummy_pc(); pick_race_abil(&adven[spot],0,parent_num); if (parent_num != 0) cd_initial_draw(989); still_ok = spend_xp(spot,0,parent_num); if (still_ok == false) return false; adven[spot].cur_health = adven[spot].max_health; adven[spot].cur_sp = adven[spot].max_sp; if (parent_num != 0) cd_initial_draw(989); pick_pc_graphic(spot,0,parent_num); if (parent_num != 0) cd_initial_draw(989); pick_pc_name(spot,parent_num); adven[spot].main_status = MAIN_STATUS_ALIVE; if (in_startup_mode == false) { adven[spot].items[0] = start_items[adven[spot].race * 2]; adven[spot].equip[0] = true; adven[spot].items[1] = start_items[adven[spot].race * 2 + 1]; adven[spot].equip[1] = true; // Do stat adjs for selected race. if (adven[spot].race == RACE_NEPHIL) adven[spot].skills[SKILL_DEXTERITY] += 2; if (adven[spot].race == RACE_SLITH) { adven[spot].skills[SKILL_STRENGTH] += 2; adven[spot].skills[SKILL_INTELLIGENCE] += 1; } adven[spot].max_sp += adven[spot].skills[SKILL_MAGE_SPELLS] * 3 + adven[spot].skills[SKILL_PRIEST_SPELLS] * 3; adven[spot].cur_sp = adven[spot].max_sp; } return true; } void pc_array::heal(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].heal(amt); } void pc_array::cure(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].cure(amt); } void pc_array::dumbfound(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].dumbfound(amt); } void pc_array::disease(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].disease(amt); } void increase_light(short amt) { short i; location where; party.light_level += amt; if (is_combat()) { for (i = 0; i < 6; i++) if (adven[i].isAlive()) { update_explored(pc_pos[i]); } } else { where = get_cur_loc(); update_explored(where); } put_pc_screen(); } void pc_array::restoreSP(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].restoreSP(amt); } void pc_array::giveXP(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].giveXP(amt); } void pc_array::drainXP(short amt) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].drainXP(amt); } void do_xp_keep(short pc_num,short mode) { for (i = 0; i < 20; i++) adven[pc_num].skills[i] = store_skills[i]; adven[pc_num].cur_health += store_h - adven[pc_num].max_health; adven[pc_num].max_health = store_h; adven[pc_num].cur_sp += store_sp - adven[pc_num].max_sp; adven[pc_num].max_sp = store_sp; if (mode == 1) party.gold = store_g; adven[pc_num].skill_pts = store_skp; } void draw_xp_skills() { short i; for (i = 0; i < 19; i++) { if ((store_skp >= skill_cost[i]) && (store_g >= skill_g_cost[i])) cd_text_frame(1010,54 + i,11); else cd_text_frame(1010,54 + i,1); cd_set_item_num(1010,54 + i,store_skills[i]); } if ((store_skp >= 1) && (store_g >= 10)) cd_text_frame(1010,52,11); else cd_text_frame(1010,52,1); cd_set_item_num(1010,52,store_h); if ((store_skp >= 1) && (store_g >= 15)) cd_text_frame(1010,53,11); else cd_text_frame(1010,53,1); cd_set_item_num(1010,53,store_sp); } void do_xp_draw() { char get_text[256]; short mode,pc_num; mode = store_train_mode; pc_num = store_train_pc; if (mode == 0) { if (adven[pc_num].main_status == MAIN_STATUS_ALIVE) sprintf((char *) get_text, "%s",(char *) adven[pc_num].name); else sprintf((char *) get_text, "New PC"); } else sprintf((char *) get_text, "%s",(char *) adven[pc_num].name); cd_set_item_text (1010, 51,get_text); for (i = 0; i < 20; i++) store_skills[i] = adven[pc_num].skills[i]; store_h = adven[pc_num].max_health; store_sp = adven[pc_num].max_sp; store_g = (mode == 0) ? 20000 : party.gold; store_skp = adven[pc_num].skill_pts; draw_xp_skills(); update_gold_skills(); } Boolean spend_xp_event_filter (short item_hit) { short mode,pc_num; Boolean talk_done = false; mode = store_train_mode; pc_num = store_train_pc; switch (item_hit) { case 73: if ((mode == 0) && (adven[pc_num].main_status < MAIN_STATUS_ABSENT)) adven[pc_num].main_status = MAIN_STATUS_ABSENT; dialog_answer = 0; talk_done = true; break; case 82: party.help_received[10] = 0; give_help(210,11,1010); break; case 3: case 4: if (((store_h >= 250) && (item_hit == 4)) || ((store_h == adven[pc_num].max_health) && (item_hit == 3) && (mode == 1)) || ((store_h == 6) && (item_hit == 3) && (mode == 0))) MessageBeep(MB_OK); else { if (item_hit == 3) { store_g += 10; store_h -= 2; store_skp += 1; } else { if ((store_g < 10) || (store_skp < 1)) { if (store_g < 10) give_help(24,0,1010); else give_help(25,0,1010); MessageBeep(MB_OK); } else { store_g -= 10; store_h += 2; store_skp -= 1; } } update_gold_skills(); cd_set_item_num(1010,52,store_h); draw_xp_skills(); } break; case 5: case 6: if (((store_sp >= 150) && (item_hit == 6)) || ((store_sp == adven[pc_num].max_sp) && (item_hit == 5) && (mode == 1)) || ((store_sp == 0) && (item_hit == 5) && (mode == 0))) MessageBeep(MB_OK); else { if (item_hit == 5) { store_g += 15; store_sp -= 1; store_skp += 1; } else { if ((store_g < 15) || (store_skp < 1)) { if (store_g < 15) give_help(24,0,1010); else give_help(25,0,1010); MessageBeep(MB_OK); } else { store_sp += 1; store_g -= 15; store_skp -= 1; } } update_gold_skills(); cd_set_item_num(1010,53,store_sp); draw_xp_skills(); } break; case 48: do_xp_keep(pc_num,mode); dialog_answer = 1; talk_done = true; break; case 49: if (mode == 0) { MessageBeep(MB_OK); break; } else { do_xp_keep(pc_num,mode); do { pc_num = (pc_num == 0) ? 5 : pc_num - 1; } while (adven[pc_num].isAlive() == false); store_train_pc = pc_num; do_xp_draw(); } break; case 50: if (mode == 0) { MessageBeep(MB_OK); break; } else { do_xp_keep(pc_num,mode); do { pc_num = (pc_num == 5) ? 0 : pc_num + 1; } while (adven[pc_num].isAlive() == false); store_train_pc = pc_num; do_xp_draw(); } break; case 100: break; default: if (item_hit >= 100) { item_hit -= 100; if ((item_hit == 3) || (item_hit == 4)) { display_strings_with_nums(10,63,0,0,"About Health",57,724,1010); } else if ((item_hit == 5) || (item_hit == 6)){ display_strings_with_nums(10,64,0,0,"About Spell Points",57,724,1010); } else { which_skill = (item_hit - 7) / 2; display_skills(which_skill,1010); } } else { which_skill = (item_hit - 7) / 2; if (((store_skills[which_skill] >= skill_max[which_skill]) && ((item_hit - 7) % 2 == 1)) || ((store_skills[which_skill] == adven[pc_num].skills[which_skill]) && ((item_hit - 7) % 2 == 0) && (mode == 1)) || ((store_skills[which_skill] == 0) && ((item_hit - 7) % 2 == 0) && (mode == 0) && (which_skill > 2)) || ((store_skills[which_skill] == 1) && ((item_hit - 7) % 2 == 0) && (mode == 0) && (which_skill <= 2))) MessageBeep(MB_OK); else { if ((item_hit - 7) % 2 == 0) { store_g += skill_g_cost[which_skill]; store_skills[which_skill] -= 1; store_skp += skill_cost[which_skill]; } else { if ((store_g < skill_g_cost[which_skill]) || (store_skp < skill_cost[which_skill])) { if (store_g < skill_g_cost[which_skill]) give_help(24,0,1010); else give_help(25,0,1010); MessageBeep(MB_OK); } else { store_skills[which_skill] += 1; store_g -= skill_g_cost[which_skill]; store_skp -= skill_cost[which_skill]; } } update_gold_skills(); cd_set_item_num(1010,54 + which_skill,store_skills[which_skill]); draw_xp_skills(); } } break; } store_train_pc = pc_num; if (talk_done == true) { dialog_not_toast = false; } return false; } void update_gold_skills() { cd_set_item_num(1010,47,((store_train_mode == 0) ? 0 : (short) store_g)); cd_set_item_num(1010,46,(short) store_skp); } Boolean spend_xp(short pc_num, short mode, short parent) //short mode; // 0 - create 1 - train // returns 1 if cancelled { char get_text[256],text2[256]; store_train_pc = pc_num; store_train_mode = mode; SetCursor(sword_curs); cd_create_dialog_parent_num(1010,parent); sprintf(get_text,"Health (%d/%d)",1,10); cd_add_label(1010,52,(char *) get_text,1075); sprintf(get_text,"Spell Pts. (%d/%d)",1,15); cd_add_label(1010,53,(char *) get_text,1075); for (i = 54; i < 73; i++) { GetIndString(text2,9,1 + 2 * (i - 54)); sprintf(get_text,"%s (%d/%d)",text2,skill_cost[i - 54],skill_g_cost[i - 54]); cd_add_label(1010,i, get_text,(i < 63) ? 1075 : 1069); } do_xp_draw(); dialog_answer = 0; if (party.help_received[10] == 0) { cd_initial_draw(1010); give_help(10,11,1010); } while (dialog_not_toast) ModalDialog(); cd_kill_dialog(1010,0); return dialog_answer; } short pc_array::getMageLore() { short total = 0; for (int i = 0; i < NUM_OF_PCS; i++) if (pc[i].isAlive()) total += pc[i].skills[SKILL_MAGE_LORE]; return total; } Boolean poison_weapon( short pc_num, short how_much,short safe) //short safe; // 1 - always succeeds { short i,weap = 24,p_level,r1; short p_chance[21] = {40,72,81,85,88,89,90, 91,92,93,94,94,95,95,96,97,98,100,100,100,100}; for (i = 0; i < 24; i++) if ((adven[pc_num].equip[i] == true) && (is_weapon(pc_num,i) == true)) { weap = i; i = 30; } if (weap == 24) { add_string_to_buf(" No weapon equipped. "); return false; } else { p_level = how_much; add_string_to_buf(" You poison your weapon. "); r1 = get_ran(1,0,100); // Nimble? if (adven[pc_num].traits[TRAIT_NIMBLE] == true) r1 -= 6; if ((r1 > p_chance[adven[pc_num].skills[SKILL_POISON]]) && (safe == 0)) { add_string_to_buf(" Poison put on badly. "); p_level = p_level / 2; r1 = get_ran(1,0,100); if (r1 > p_chance[adven[pc_num].skills[SKILL_POISON]] + 10) { add_string_to_buf(" You nick yourself. "); adven[pc_num].status[STATUS_POISON] += p_level; } } if (safe != 1) play_sound(55); adven[pc_num].weap_poisoned = weap; adven[pc_num].status[STATUS_POISONED_WEAPON] = max (adven[pc_num].status[STATUS_POISONED_WEAPON], p_level); return true; } } Boolean is_weapon(short pc_num,short item) { if ((adven[pc_num].items[item].variety == ITEM_TYPE_ONE_HANDED) || (adven[pc_num].items[item].variety == ITEM_TYPE_TWO_HANDED) || (adven[pc_num].items[item].variety == ITEM_TYPE_ARROW) || (adven[pc_num].items[item].variety == ITEM_TYPE_BOLTS)) return true; else return false; } void cast_spell(short type,short situation) //short type; // 0 - mage 1 - priest //short situation; // 0 - out 1 - town { short spell; if ((is_town()) && (is_antimagic(c_town.p_loc.x,c_town.p_loc.y))) { add_string_to_buf(" Not in antimagic field."); return; } if (spell_forced == false) spell = pick_spell(6, type, situation); else { if (repeat_cast_ok(type) == false) return; spell = (type == 0) ? store_mage : store_priest; } if (spell < 70) { print_spell_cast(spell,type); if (type == 0) do_mage_spell(pc_casting,spell); else do_priest_spell(pc_casting,spell); put_pc_screen(); } } Boolean repeat_cast_ok(short type) { short store_select,who_would_cast,what_spell; if (overall_mode == MODE_COMBAT) who_would_cast = current_pc; else if (overall_mode < MODE_TALK_TOWN) who_would_cast = pc_casting; else return false; if (is_combat()) what_spell = pc_last_cast[type][who_would_cast]; else what_spell = (type == 0) ? store_mage : store_priest; if (pc_can_cast_spell(who_would_cast,type,what_spell) == false) { add_string_to_buf("Repeat cast: Can't cast."); return false; } store_select = (type == 0) ? mage_need_select[what_spell] : priest_need_select[what_spell]; if ((store_select > 0) && (store_spell_target == 6)) { add_string_to_buf("Repeat cast: No target stored."); return false; } if ((store_select == 2) && ((adven[store_spell_target].main_status == MAIN_STATUS_ABSENT) || (adven[store_spell_target].main_status > MAIN_STATUS_STONE))) { add_string_to_buf("Repeat cast: No target stored."); return false; } if ((store_select == 1) && (adven[store_spell_target].isAlive() == false)) { add_string_to_buf("Repeat cast: No target stored."); return false; } return true; } void do_mage_spell(short pc_num,short spell_num) { short i,j,item,target,adj,store; location where; unsigned short r1; where = c_town.p_loc; play_sound(25); current_spell_range = 8; adj = adven[who_cast].statAdj(SKILL_INTELLIGENCE); switch (spell_num) { case SPELL_MAGE_LIGHT: // Light adven[pc_num].cur_sp -= spell_cost[0][spell_num]; increase_light(50); break; case SPELL_MAGE_IDENTIFY: // Identify adven[pc_num].cur_sp -= spell_cost[0][spell_num]; ASB("All of your items are identified."); for (i = 0; i < 6; i++) for (j = 0; j < 24; j++) adven[i].items[j].item_properties = adven[i].items[j].item_properties | 1; break; case SPELL_MAGE_TRUE_SIGHT: // true sight adven[pc_num].cur_sp -= spell_cost[0][spell_num]; for (where.x = 0; where.x < 64; where.x++) for (where.y = 0; where.y < 64; where.y++) if (dist(where,c_town.p_loc) <= 2) make_explored(where.x,where.y); clear_map(); break; case SPELL_MAGE_SUMMON_BEAST: // summon beast //// r1 = get_summon_monster(1); if (r1 == 0) break; adven[pc_num].cur_sp -= spell_cost[0][spell_num]; store = get_ran(3,1,4) + adj; if (summon_monster(r1,where,store,2) == false) add_string_to_buf(" Summon failed."); break; case SPELL_MAGE_WEAK_SUMMONING: // summon 1 store = adven[who_cast].level / 5 + adven[who_cast].statAdj(SKILL_INTELLIGENCE) / 3 + get_ran(1,0,2); j = minmax(1,7,(int)store); r1 = get_summon_monster(1); //// if (r1 == 0) break; adven[pc_num].cur_sp -= spell_cost[0][spell_num]; store = get_ran(4,1,4) + adj; for (i = 0; i < j; i++) if (summon_monster(r1,where,store,2) == false) add_string_to_buf(" Summon failed."); break; case SPELL_MAGE_SUMMONING: // summon 2 store = adven[who_cast].level / 7 + adven[who_cast].statAdj(SKILL_INTELLIGENCE) / 3 + get_ran(1,0,1); j = minmax(1,6,(int)store); r1 = get_summon_monster(2); //// if (r1 == 0) break; adven[pc_num].cur_sp -= spell_cost[0][spell_num]; store = get_ran(5,1,4) + adj; for (i = 0; i < j; i++) if (summon_monster(r1,where,store,2) == false) add_string_to_buf(" Summon failed."); break; case SPELL_MAGE_MAJOR_SUMMON: // summon 3 store = adven[who_cast].level / 10 + adven[who_cast].statAdj(SKILL_INTELLIGENCE) / 3 + get_ran(1,0,1); j = minmax(1,5,(int)store); r1 = get_summon_monster(3); //// if (r1 == 0) break; adven[pc_num].cur_sp -= spell_cost[0][spell_num]; store = get_ran(7,1,4) + adven[who_cast].statAdj(SKILL_INTELLIGENCE); for (i = 0; i < j; i++) if (summon_monster(r1,where,store,2) == false) add_string_to_buf(" Summon failed."); break; case SPELL_MAGE_DAEMON: store = get_ran(5,1,4) + 2 * adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster(85,where,store,2) == false) add_string_to_buf(" Summon failed."); else adven[pc_num].cur_sp -= spell_cost[0][spell_num]; break; case SPELL_MAGE_DISPEL_FIELDS: // dispel field add_string_to_buf(" Target spell. "); current_pat = square; overall_mode = MODE_TOWN_TARGET; set_town_spell(spell_num,pc_num); break; case SPELL_MAGE_LONG_LIGHT: // Long light adven[pc_num].cur_sp -= spell_cost[0][spell_num]; increase_light(200); break; case SPELL_MAGE_MAGIC_MAP: // Magic map item = adven[pc_num].hasAbil(ITEM_SAPPHIRE);//// if (item == 24) add_string_to_buf(" You need a sapphire. "); else if ((c_town.town.defy_scrying == 1) || (c_town.town.defy_mapping == 1)) add_string_to_buf(" The spell fails. "); else { adven[pc_num].removeCharge(item); adven[pc_num].cur_sp -= spell_cost[0][spell_num]; add_string_to_buf(" As the sapphire dissolves, "); add_string_to_buf(" you have a vision. "); for (i = 0; i < 64; i++) for (j = 0; j < 64; j++) make_explored(i,j); clear_map(); } break; case SPELL_MAGE_STEALTH: // Stealth adven[pc_num].cur_sp -= spell_cost[0][spell_num]; party.stuff_done[SDF_STEALTH] += max(6,adven[pc_num].level * 2); break; case SPELL_MAGE_SCRY_MONSTER: case SPELL_MAGE_UNLOCK: case SPELL_MAGE_CAPTURE_SOUL: case SPELL_MAGE_DISPEL_BARRIER: // Scry monster, Unlock, Capture Soul, Disp. barrier add_string_to_buf(" Target spell. "); current_pat = single; overall_mode = MODE_TOWN_TARGET; set_town_spell(spell_num,pc_num); break; case SPELL_MAGE_FIRE_BARRIER: case SPELL_MAGE_FORCE_BARRIER: case SPELL_MAGE_QUICKFIRE: // fire and force barriers, quickfire add_string_to_buf(" Target spell. "); overall_mode = MODE_TOWN_TARGET; current_pat = single; set_town_spell(spell_num,pc_num); break; case SPELL_MAGE_ANTIMAGIC_CLOUD: // antimagic add_string_to_buf(" Target spell. "); overall_mode = MODE_TOWN_TARGET; current_pat = radius2; set_town_spell(spell_num,pc_num); break; case SPELL_MAGE_FLIGHT: // fly if (party.stuff_done[SDF_FLYING] > 0) { add_string_to_buf(" Not while already flying. "); return; } if (party.in_boat >= 0) add_string_to_buf(" Leave boat first. "); else if (party.in_horse >= 0) //// add_string_to_buf(" Leave horse first. "); else { adven[pc_num].cur_sp -= spell_cost[0][spell_num]; add_string_to_buf(" You start flying! "); party.stuff_done[SDF_FLYING] = 3; } break; case SPELL_MAGE_RESIST_MAGIC: case SPELL_MAGE_PROTECTION: // resist magic, protection (!!! no cap ??? !!!) target = store_spell_target; if (target < 6) adven[pc_num].cur_sp -= spell_cost[0][spell_num]; if ((spell_num == SPELL_MAGE_PROTECTION) && (target < 6)) { adven[target].status[STATUS_INVULNERABLE] += 2 + adven[pc_num].statAdj(SKILL_INTELLIGENCE) + get_ran(2,1,2); for (i = 0; i < 6; i++) if (adven[i].isAlive()) { adven[i].status[STATUS_MAGIC_RESISTANCE] += 4 + adven[pc_num].level / 3 + adven[pc_num].statAdj(SKILL_INTELLIGENCE); } sprintf (c_line, " Party protected. "); } if ((spell_num == SPELL_MAGE_RESIST_MAGIC) && (target < 6)) { adven[target].status[STATUS_MAGIC_RESISTANCE] += 2 + adven[pc_num].statAdj(SKILL_INTELLIGENCE) + get_ran(2,1,2); sprintf (c_line, " %s protected.",adven[target].name); } add_string_to_buf(c_line); break; } } void do_priest_spell(short pc_num,short spell_num) { short r1,r2, target, i,item,store,adj,x,y; location loc; location where; short store_victim_health,store_caster_health,targ_damaged; // for symbiosis where = c_town.p_loc; adj = adven[pc_num].statAdj(SKILL_INTELLIGENCE); play_sound(24); current_spell_range = 8; switch (spell_num) { case SPELL_PRIEST_LOCATION: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; if (is_town()) { loc = (overall_mode == MODE_OUTDOORS) ? party.p_loc : c_town.p_loc; sprintf (c_line, " You're at: x %d y %d.", (short) loc.x, (short) loc.y); } if (is_out()) { loc = (overall_mode == MODE_OUTDOORS) ? party.p_loc : c_town.p_loc; x = loc.x; y = loc.y; x += 48 * party.outdoor_corner.x; y += 48 * party.outdoor_corner.y; sprintf (c_line, " You're outside at: x %d y %d.",x,y); } add_string_to_buf(c_line); break; case SPELL_PRIEST_MINOR_MANNA: case SPELL_PRIEST_MANNA: // manna spells adven[pc_num].cur_sp -= spell_cost[1][spell_num]; store = adven[pc_num].level / 3 + 2 * adven[who_cast].statAdj(SKILL_INTELLIGENCE) + get_ran(2,1,4); r1 = max(0,store); if (spell_num == SPELL_PRIEST_MINOR_MANNA) r1 = r1 / 3 + 1; sprintf (c_line, " You gain %d food. ",r1); add_string_to_buf(c_line); party.giveFood(r1,true); break; case SPELL_PRIEST_RITUAL_SANCTIFY: // Ritual - Sanctify add_string_to_buf(" Sanctify which space? "); current_pat = single; overall_mode = MODE_TOWN_TARGET; set_town_spell(100 + spell_num,pc_num); break; case SPELL_PRIEST_LIGHT: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; //party.light_level += 210; increase_light(210); break; case SPELL_PRIEST_SUMMON_SPIRIT: store = adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster(125,where,get_ran(2,1,4) + store,2) == false) add_string_to_buf(" Summon failed."); else adven[pc_num].cur_sp -= spell_cost[1][spell_num]; break; case SPELL_PRIEST_STICKS_TO_SNAKES: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; r1 = adven[who_cast].level / 6 + adven[who_cast].statAdj(SKILL_INTELLIGENCE) / 3 + get_ran(1,0,1); for (i = 0; i < r1; i++) { r2 = get_ran(1,0,7); store = get_ran(2,1,5) + adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster((r2 == 1) ? 100 : 99,where,store,2 ) == false) add_string_to_buf(" Summon failed."); } break; case SPELL_PRIEST_SUMMON_HOST: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; store = get_ran(2,1,4) + adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster(126,where,store,2) == false) add_string_to_buf(" Summon failed."); for (i = 0; i < 4; i++) { store = get_ran(2,1,4) + adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster(125,where,store,2) == false) add_string_to_buf(" Summon failed."); } break; case SPELL_PRIEST_GUARDIAN: store = get_ran(6,1,4) + adven[who_cast].statAdj(SKILL_INTELLIGENCE); if (summon_monster(122,where,store,2) == false) add_string_to_buf(" Summon failed."); else adven[pc_num].cur_sp -= spell_cost[1][spell_num]; break; case SPELL_PRIEST_MOVE_MOUNTAINS: add_string_to_buf(" Destroy what? "); //current_pat = (spell_num == SPELL_PRIEST_MOVE_MOUNTAINS) ? single : square; //apparently was planned (by Jeff) to do the shatter spell as well current_pat = single; overall_mode = MODE_TOWN_TARGET; set_town_spell(100 + spell_num,pc_num); break; case SPELL_PRIEST_DISPEL_FIELDS: // dispelling fields add_string_to_buf(" Target spell. "); //current_pat = (spell_num == SPELL_PRIEST_AWAKEN) ? single : radius2; current_pat = radius2; overall_mode = MODE_TOWN_TARGET; set_town_spell(100 + spell_num,pc_num); break; case SPELL_PRIEST_DETECT_LIFE: // Detect life add_string_to_buf(" Monsters now on map. "); party.stuff_done[SDF_DETECT_MONSTER] += 6 + get_ran(1,0,6); clear_map(); adven[pc_num].cur_sp -= spell_cost[1][spell_num]; break; case SPELL_PRIEST_FIREWALK: // firewalk add_string_to_buf(" You are now firewalking. "); party.stuff_done[SDF_LAVAWALK] += adven[pc_num].level / 12 + 2; adven[pc_num].cur_sp -= spell_cost[1][spell_num]; break; case SPELL_PRIEST_SHATTER: // shatter add_string_to_buf(" You send out a burst of energy. "); adven[pc_num].cur_sp -= spell_cost[1][spell_num]; for (loc.x = where.x - 1;loc.x < where.x + 2; loc.x++) for (loc.y = where.y - 1;loc.y < where.y + 2; loc.y++) loc.crumbleWall(); update_explored(c_town.p_loc); break; case SPELL_PRIEST_WORD_OF_RECALL: if (overall_mode > MODE_OUTDOORS) { add_string_to_buf(" Can only cast outdoors. "); return; } if (party.in_boat >= 0) { add_string_to_buf(" Not while in boat. "); return; } if (party.in_horse >= 0) {//// add_string_to_buf(" Not while on horseback. "); return; } adven[pc_num].cur_sp -= spell_cost[1][spell_num]; add_string_to_buf(" You are moved... "); force_town_enter(scenario.which_town_start,scenario.where_start); start_town_mode(scenario.which_town_start,9); position_party(scenario.out_sec_start.x,scenario.out_sec_start.y, scenario.out_start.x,scenario.out_start.y); center = c_town.p_loc = scenario.where_start; // overall_mode = MODE_OUTDOORS; // center = party.p_loc; // update_explored(party.p_loc); redraw_screen(0); break; case SPELL_PRIEST_MINOR_HEAL: case SPELL_PRIEST_HEAL: case SPELL_PRIEST_MAJOR_HEAL: case SPELL_PRIEST_WEAKEN_POISON: case SPELL_PRIEST_CURE_POISON: case SPELL_PRIEST_CURE_DISEASE: case SPELL_PRIEST_RESTORE_MIND: case SPELL_PRIEST_CLEANSE: case SPELL_PRIEST_AWAKEN: case SPELL_PRIEST_CURE_PARALYSIS: // target = select_pc(11,0); target = store_spell_target; if (target < 6) { adven[pc_num].cur_sp -= spell_cost[1][spell_num]; switch(spell_num) { case SPELL_PRIEST_MINOR_HEAL: case SPELL_PRIEST_HEAL: case SPELL_PRIEST_MAJOR_HEAL: r1 = get_ran(2 + 2 * (spell_num / 6), 1, 4); sprintf (c_line, " %s healed %d. ", adven[target].name,r1); adven[target].heal(r1); one_sound(52); break; case SPELL_PRIEST_WEAKEN_POISON: case SPELL_PRIEST_CURE_POISON: sprintf (c_line, " %s cured. ", adven[target].name); r1 = ((spell_num == SPELL_PRIEST_WEAKEN_POISON) ? 1 : 3) + get_ran(1,0,2) + adven[pc_num].statAdj(SKILL_INTELLIGENCE) / 2; adven[target].cure(r1); break; case SPELL_PRIEST_AWAKEN: // awaken if (adven[target].status[STATUS_ASLEEP] <= 0) { sprintf (c_line, " %s is already awake! " , adven[target].name); break; } sprintf (c_line, " %s wakes up. " , adven[target].name); adven[target].status[STATUS_ASLEEP] = 0; break; case SPELL_PRIEST_CURE_PARALYSIS: // cure paralysis if (adven[target].status[STATUS_PARALYZED] <= 0) { sprintf (c_line, " %s isn't paralyzed! " , adven[target].name); break; } sprintf (c_line, " %s can move now. " , adven[target].name); adven[target].status[STATUS_PARALYZED] = 0; break; case SPELL_PRIEST_CURE_DISEASE: sprintf (c_line, " %s recovers. " , adven[target].name); r1 = 2 + get_ran(1,0,2) + adven[pc_num].statAdj(SKILL_INTELLIGENCE) / 2; adven[target].status[STATUS_DISEASE] = max(0,adven[target].status[STATUS_DISEASE] - r1); break; case SPELL_PRIEST_RESTORE_MIND: sprintf (c_line, " %s restored. " , adven[target].name); r1 = 1 + get_ran(1,0,2) + adven[pc_num].statAdj(SKILL_INTELLIGENCE) / 2; adven[target].status[STATUS_DUMB] = max(0,adven[target].status[STATUS_DUMB] - r1); break; case SPELL_PRIEST_CLEANSE: sprintf (c_line, " %s cleansed. " , adven[target].name); adven[target].status[STATUS_DISEASE] = 0; adven[target].status[STATUS_WEBS] = 0; break; } } add_string_to_buf((char *) c_line); put_pc_screen(); break; case SPELL_PRIEST_REVIVE: case SPELL_PRIEST_DESTONE: case SPELL_PRIEST_RAISE_DEAD: case SPELL_PRIEST_RESURRECT: case SPELL_PRIEST_REMOVE_CURSE: case SPELL_PRIEST_SANCTUARY: case SPELL_PRIEST_SYMBIOSIS: case SPELL_PRIEST_MARTYRS_SHIELD: target = store_spell_target; if (target < 6) { if ((spell_num == 6) && (target == pc_num)) { // check symbiosis add_string_to_buf(" Can't cast on self."); return; } adven[pc_num].cur_sp -= spell_cost[1][spell_num]; if (spell_num == SPELL_PRIEST_MARTYRS_SHIELD) { // martyr's shield sprintf (c_line, " %s shielded. ", adven[target].name); r1 = max(1,get_ran((adven[pc_num].level + 5) / 5,1,3) + adj); adven[target].status[STATUS_MARTYRS_SHIELD] += r1; } if (spell_num == SPELL_PRIEST_SANCTUARY) { // sanctuary sprintf (c_line, " %s hidden. ", adven[target].name); r1 = max(0,get_ran(0,1,3) + adven[pc_num].level / 4 + adj); adven[target].status[STATUS_INVISIBLE] += r1; } if (spell_num == SPELL_PRIEST_SYMBIOSIS) { // symbiosis store_victim_health = adven[target].cur_health; store_caster_health = adven[pc_num].cur_health; targ_damaged = adven[target].max_health - adven[target].cur_health; while ((targ_damaged > 0) && (adven[pc_num].cur_health > 0)) { adven[target].cur_health++; r1 = get_ran(1,0,100) + adven[pc_num].level / 2 + 3 * adj; if (r1 < 100) adven[pc_num].cur_health--; if (r1 < 50) move_to_zero(adven[pc_num].cur_health); targ_damaged = adven[target].max_health - adven[target].cur_health; } add_string_to_buf(" You absorb damage."); sprintf (c_line, " %s healed %d. ", adven[target].name, adven[target].cur_health - store_victim_health); add_string_to_buf (c_line); sprintf (c_line, " %s takes %d. ", adven[pc_num].name, store_caster_health - adven[pc_num].cur_health); } if (spell_num == SPELL_PRIEST_REVIVE) { sprintf (c_line, " %s healed. ", adven[target].name); adven[target].heal(250); adven[target].status[STATUS_POISON] = 0; one_sound(-53); one_sound(52); } if (spell_num == SPELL_PRIEST_DESTONE) { if (adven[target].main_status == MAIN_STATUS_STONE) { adven[target].main_status = MAIN_STATUS_ALIVE; sprintf (c_line, " %s destoned. ", adven[target].name); play_sound(53); } else sprintf (c_line," Wasn't stoned. "); } if (spell_num == SPELL_PRIEST_REMOVE_CURSE) { for (i = 0; i < 24; i++) if (adven[target].items[i].isCursed()) { r1 = get_ran(1,0,200) - 10 * adven[pc_num].statAdj(SKILL_INTELLIGENCE); if (r1 < 60) { adven[target].items[i].item_properties = adven[target].items[i].item_properties & 239; } } play_sound(52); sprintf ( c_line," Your items glow. "); } if (PSD[SDF_LEGACY_SCENARIO] == 0 && ((spell_num == SPELL_PRIEST_RAISE_DEAD) || (spell_num == SPELL_PRIEST_RESURRECT))){ if ((item = adven[pc_num].hasAbil(ITEM_RESSURECTION_BALM)) == 24) { sprintf(c_line," Need resurrection balm. "); spell_num = 500; } else adven[pc_num].takeItem(item); } if (spell_num == SPELL_PRIEST_RAISE_DEAD) { if (adven[target].main_status == MAIN_STATUS_DEAD) if (get_ran(1,1,adven[pc_num].level / 2) == 1) { sprintf (c_line, " %s now dust. ", adven[target].name); play_sound(5); adven[target].main_status = MAIN_STATUS_DUST; } else { adven[target].main_status = MAIN_STATUS_ALIVE; for (i = 0; i < 3; i++) if (get_ran(1,0,2) < 2) adven[target].skills[i] -= (adven[target].skills[i] > 1) ? 1 : 0; adven[target].cur_health = 1; sprintf (c_line, " %s raised. ", adven[target].name); play_sound(52); } else sprintf ( c_line," Didn't work. "); } if (spell_num == SPELL_PRIEST_RESURRECT) { if (adven[target].isAlive() == false) { adven[target].main_status = MAIN_STATUS_ALIVE; for (i = 0; i < 3; i++) if (get_ran(1,0,2) < 1) adven[target].skills[i] -= (adven[target].skills[i] > 1) ? 1 : 0; adven[target].cur_health = 1; sprintf (c_line, " %s raised.", adven[target].name); play_sound(52); } else sprintf (c_line," Was OK. "); } add_string_to_buf(c_line); put_pc_screen(); } break; case SPELL_PRIEST_LIGHT_HEAL_ALL: case SPELL_PRIEST_HEAL_ALL: case SPELL_PRIEST_REVIVE_ALL: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; r1 = get_ran(spell_num / 7 + adj, 1, 4); if (spell_num < SPELL_PRIEST_REVIVE_ALL) { sprintf (c_line, " Party healed %d. ", r1); add_string_to_buf(c_line); adven.heal(r1); play_sound(52); } else if (spell_num == SPELL_PRIEST_REVIVE_ALL) { sprintf (c_line, " Party revived. "); add_string_to_buf(c_line); r1 = r1 * 2; adven.heal(r1); play_sound(-53); play_sound(-52); adven.cure(3 + adj); } break; case SPELL_PRIEST_CURE_PARTY: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; sprintf (c_line, " Party cured. "); add_string_to_buf(c_line); adven.cure(3 + adven[pc_num].statAdj(SKILL_INTELLIGENCE)); break; case SPELL_PRIEST_MASS_SANCTUARY: case SPELL_PRIEST_MAJOR_CLEANSING: case SPELL_PRIEST_HYPERACTIVITY: adven[pc_num].cur_sp -= spell_cost[1][spell_num]; switch (spell_num) { case SPELL_PRIEST_MASS_SANCTUARY: add_string_to_buf(" Party hidden.");break; case SPELL_PRIEST_MAJOR_CLEANSING: add_string_to_buf(" Party cleansed.");break; case SPELL_PRIEST_HYPERACTIVITY: add_string_to_buf(" Party is now really, REALLY awake.");break; } for (i = 0; i < 6; i++) if (adven[i].isAlive()) { if (spell_num == SPELL_PRIEST_MASS_SANCTUARY) { store = get_ran(0,1,3) + adven[pc_num].level / 6 + adven[pc_num].statAdj(SKILL_INTELLIGENCE); r1 = max(0,store); adven[i].status[STATUS_INVISIBLE] += r1; } if (spell_num == SPELL_PRIEST_MAJOR_CLEANSING) { adven[i].status[STATUS_WEBS] = 0; adven[i].status[STATUS_DISEASE] = 0; } if (spell_num == SPELL_PRIEST_HYPERACTIVITY) { // Hyperactivity adven[i].status[STATUS_ASLEEP] -= 6 + 2 * adven[pc_num].statAdj(SKILL_INTELLIGENCE); adven[i].status[STATUS_HASTE_SLOW] = max(0,adven[i].status[STATUS_HASTE_SLOW]); } } break; } } //priest spells : 100 + spell number void cast_town_spell(location where) { short adjust,r1,targ,store; location loc; unsigned char ter; if ((where.x <= c_town.town.in_town_rect.left) || (where.x >= c_town.town.in_town_rect.right) || (where.y <= c_town.town.in_town_rect.top) || (where.y >= c_town.town.in_town_rect.bottom)) { add_string_to_buf(" Can't target outside town."); return; } adjust = can_see(c_town.p_loc,where,0); if (town_spell < 1000) adven[who_cast].cur_sp -= spell_cost[town_spell / 100][town_spell % 100]; else town_spell -= 1000; ter = t_d.terrain[where.x][where.y]; if (adjust > 4) add_string_to_buf(" Can't see target. "); else switch (town_spell) { case SPELL_MAGE_SCRY_MONSTER: case SPELL_MAGE_CAPTURE_SOUL: // Scry, Capture Soul targ = monst_there(where); if (targ < T_M) { if (town_spell == SPELL_MAGE_SCRY_MONSTER) { party.m_seen[c_town.monst.dudes[targ].number] = true; adjust_monst_menu(); display_monst(0,&c_town.monst.dudes[targ],0); } else c_town.monst.dudes[targ].record(); } else add_string_to_buf(" No monster there."); break; case 100 + SPELL_PRIEST_DISPEL_FIELDS: case SPELL_MAGE_DISPEL_FIELDS://case 119: old (from previous Exile) leftover case add_string_to_buf(" You attempt to dispel. "); place_spell_pattern(current_pat,where,11,false,7); break; case 100 + SPELL_PRIEST_MOVE_MOUNTAINS: // Move M. add_string_to_buf(" You blast the area. "); where.crumbleWall(); update_explored(c_town.p_loc); break; case SPELL_MAGE_FIRE_BARRIER: if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) { add_string_to_buf(" Target space obstructed."); break; } make_fire_barrier(where.x,where.y); if (is_fire_barrier(where.x,where.y)) add_string_to_buf(" You create the barrier. "); else add_string_to_buf(" Failed."); break; case SPELL_MAGE_FORCE_BARRIER: if ((get_obscurity(where.x,where.y) == 5) || (monst_there(where) < 90)) { add_string_to_buf(" Target space obstructed."); break; } make_force_barrier(where.x,where.y); if (is_force_barrier(where.x,where.y)) add_string_to_buf(" You create the barrier. "); else add_string_to_buf(" Failed."); break; case SPELL_MAGE_QUICKFIRE: make_quickfire(where.x,where.y); if (is_quickfire(where.x,where.y)) add_string_to_buf(" You create quickfire. "); else add_string_to_buf(" Failed."); break; case SPELL_MAGE_ANTIMAGIC_CLOUD: // Antimagic Cloud add_string_to_buf(" You create an antimagic cloud. "); for (loc.x = 0; loc.x < town_size[town_type]; loc.x++) for (loc.y = 0; loc.y < town_size[town_type]; loc.y++) if ((dist(where,loc) <= 2) && (can_see(where,loc,2) < 5) && ((ex_abs(loc.x - where.x) < 2) || (ex_abs(loc.y - where.y) < 2))) make_antimagic(loc.x,loc.y); break; case 100 + SPELL_PRIEST_RITUAL_SANCTIFY: // Ritual - Sanctify check_spell_on_space(where,108); break; case SPELL_MAGE_UNLOCK: switch (scenario.ter_types[ter].special) { //// case TER_SPEC_UNLOCKABLE_TERRAIN: case TER_SPEC_UNLOCKABLE_BASHABLE: r1 = get_ran(1,0,100) - 5 * adven[who_cast].statAdj(SKILL_INTELLIGENCE) + 5 * c_town.difficulty; r1 += scenario.ter_types[ter].flag2 * 7; //unlock_adjust (door resistance) if (scenario.ter_types[ter].flag2 == 10) r1 = 10000; if (r1 < (135 - combat_percent[min(19,adven[who_cast].level)])) { add_string_to_buf(" Door unlocked. "); play_sound(9); t_d.terrain[where.x][where.y] = scenario.ter_types[ter].flag1; if(scenario.ter_types[scenario.ter_types[ter].flag1].special >= TER_SPEC_CONVEYOR_NORTH && scenario.ter_types[scenario.ter_types[ter].flag1].special <= TER_SPEC_CONVEYOR_WEST) belt_present = true; } else { play_sound(41); add_string_to_buf(" Didn't work. "); } break; default: add_string_to_buf(" Wrong terrain type. "); break; } break; case SPELL_MAGE_DISPEL_BARRIER: if ((is_fire_barrier(where.x,where.y)) || (is_force_barrier(where.x,where.y))) { r1 = get_ran(1,0,100) - 5 * adven[who_cast].statAdj(SKILL_INTELLIGENCE) + 5 * (c_town.difficulty / 10); if (is_fire_barrier(where.x,where.y)) r1 -= 8; if (r1 < (120 - combat_percent[min(19,adven[who_cast].level)])) { add_string_to_buf(" Barrier broken. "); take_fire_barrier(where.x,where.y); take_force_barrier(where.x,where.y); // Now, show party new things update_explored(c_town.p_loc); } else { store = get_ran(1,0,1); play_sound(41); add_string_to_buf(" Didn't work. "); } } else add_string_to_buf(" No barrier there."); break; } } void check_spell_on_space(location where, unsigned char spell) //code is basically done for a "Check spell" node, remains to do a check when targeting a space in all mode ... { short i,s1,s2,s3; if(PSD[SDF_LEGACY_SCENARIO] == 1){ if(spell == 108){ // legacy behavior, only checks Ritual of Sanctify for (i = 0; i < 50; i++) if (same_point(where,c_town.town.special_locs[i]) == true) { if (c_town.town.specials[c_town.town.spec_id[i]].type == SPEC_SANCTIFY) run_special(SPEC_TARGET,2,c_town.town.spec_id[i],where,&s1,&s2,&s3); return; } add_string_to_buf(" Nothing happens."); } } else{ for (i = 0; i < 50; i++) if (same_point(where,c_town.town.special_locs[i]) == true) { if ((c_town.town.specials[c_town.town.spec_id[i]].type == SPEC_SANCTIFY) && (c_town.town.specials[c_town.town.spec_id[i]].ex1a == spell)) run_special(SPEC_TARGET,2,c_town.town.spec_id[i],where,&s1,&s2,&s3); return; } if(spell == 108) add_string_to_buf(" Nothing happens."); } } void do_mindduel(short pc_num,creature_data_type *monst) { short i = 0,adjust,r1,r2,balance = 0; adjust = (adven[pc_num].level + adven[pc_num].skills[SKILL_INTELLIGENCE]) / 2 - monst->m_d.level * 2; if (adven[pc_num].hasAbilEquip(ITEM_WILL) < 24) adjust += 20; if (monst->attitude % 2 != 1) set_town_status(0); monst->attitude = 1; add_string_to_buf("Mindduel!"); while ((adven[pc_num].isAlive()) && (monst->active > 0) && (i < 10)) { play_sound(1); r1 = get_ran(1,0,100) + adjust; r1 += 5 * (monst->m_d.status[STATUS_DUMB] - adven[pc_num].status[STATUS_DUMB]); r1 += 5 * balance; r2 = get_ran(1,1,6); if (r1 < 30) { sprintf(c_line, " %s is drained %d.",adven[pc_num].name,r2); add_string_to_buf(c_line); monst->m_d.mp += r2; balance++; if (adven[pc_num].cur_sp == 0) { adven[pc_num].status[STATUS_DUMB] += 2; sprintf(c_line," %s is dumbfounded.",adven[pc_num].name); add_string_to_buf(c_line); if (adven[pc_num].status[STATUS_DUMB] > 7) { sprintf(c_line," %s is killed!",adven[pc_num].name); add_string_to_buf(c_line); adven[pc_num].kill(2); } } else adven[pc_num].cur_sp = max(0,adven[pc_num].cur_sp - r2); } if (r1 > 70) { sprintf(c_line, " %s drains %d.",adven[pc_num].name,r2); add_string_to_buf(c_line); adven[pc_num].cur_sp += r2; balance--; if (monst->m_d.mp == 0) { monst->m_d.status[STATUS_DUMB] += 2; monst_spell_note(monst->number,22); if (monst->m_d.status[STATUS_DUMB] > 7) kill_monst(monst,pc_num); } else monst->m_d.mp = max(0,monst->m_d.mp - r2); } print_buf(); i++; } } // mode 0 - dispel spell, 1 - always take 2 - always take and take fire and force too void dispel_fields(short i,short j,short mode) { short r1; if (mode == 2) { take_fire_barrier(i,j); take_force_barrier(i,j); take_barrel(i,j); take_crate(i,j); take_web(i,j); } if (mode >= 1) mode = -10; take_fire_wall(i,j); take_force_wall(i,j); take_scloud(i,j); r1 = get_ran(1,1,6) + mode; if (r1 <= 1) take_web(i,j); r1 = get_ran(1,1,6) + mode; if (r1 < 6) take_ice_wall(i,j); r1 = get_ran(1,1,6) + mode; if (r1 < 5) take_sleep_cloud(i,j); r1 = get_ran(1,1,8) + mode; if (r1 <= 1) take_quickfire(i,j); r1 = get_ran(1,1,7) + mode; if (r1 < 5) take_blade_wall(i,j); } Boolean pc_can_cast_spell(short pc_num,short type,short spell_num) //short type; // 0 - mage 1 - priest { short level,store_w_cast; level = spell_level[spell_num]; if (overall_mode >= MODE_TALKING) return false; if ((spell_num < 0) || (spell_num > 61)) return false; if (adven[pc_num].skills[SKILL_MAGE_SPELLS + type] < level) return false; if (adven[pc_num].isAlive() == false) return false; if (adven[pc_num].cur_sp < spell_cost[type][spell_num]) return false; if ((type == 0) && (adven[pc_num].mage_spells[spell_num] == false)) return false; if ((type == 1) && (adven[pc_num].priest_spells[spell_num] == false)) return false; if (adven[pc_num].status[STATUS_DUMB] >= 8 - level) return false; if (adven[pc_num].status[STATUS_PARALYZED] != 0) return false; if (adven[pc_num].status[STATUS_ASLEEP] > 0) return false; // 0 - everywhere 1 - combat only 2 - town only 3 - town & outdoor only 4 - town & combat only 5 - outdoor only store_w_cast = spell_w_cast[type][spell_num]; if (is_out()) if ((store_w_cast == 1) || (store_w_cast == 2) || (store_w_cast == 4)) return false; if (is_town()) if ((store_w_cast == 1) || (store_w_cast == 5)) return false; if (is_combat()) if ((store_w_cast == 2) || (store_w_cast == 3) || (store_w_cast == 5)) return false; return true; } void draw_caster_buttons() { short i; if (can_choose_caster == false) { for (i = 0; i < 6; i++) { if (i == pc_casting) cd_activate_item(1098,4 + i,1); else cd_activate_item(1098,4 + i,0); } } else { for (i = 0; i < 6; i++) { if (pc_can_cast_spell(i,store_situation,store_situation) == true) cd_activate_item(1098,4 + i,1); else cd_activate_item(1098,4 + i,0); } } } void draw_spell_info() { if (((store_situation == 0) && (store_mage == 70)) || ((store_situation == 1) && (store_priest == 70))) { // No spell selected for (i = 0; i < 6; i++) cd_activate_item(1098,10 + i,0); } else { // Spell selected for (i = 0; i < 6; i++) { switch (((store_situation == 0) ? mage_need_select[store_mage] : priest_need_select[store_priest])) { case 0: cd_activate_item(1098,10 + i,0); break; case 1: if (adven[i].isAlive() == false) cd_activate_item(1098,10 + i,0); else cd_activate_item(1098,10 + i,1); break; case 2: if (adven[i].main_status > MAIN_STATUS_ABSENT) cd_activate_item(1098,10 + i,1); else cd_activate_item(1098,10 + i,0); break; } } } } void draw_spell_pc_info() { for (int i = 0; i < 6; i++) { if (adven[i].main_status != MAIN_STATUS_ABSENT) { cd_set_item_text(1098,18 + i,adven[i].name); if (adven[i].isAlive()) { cd_set_item_num(1098,24 + i, adven[i].cur_health); cd_set_item_num(1098,30 + i, adven[i].cur_sp); } } } } void put_pc_caster_buttons() { for (int i = 0; i < 6; i++) if (cd_get_active(1098,i + 4) > 0) { if (i == pc_casting) cd_text_frame(1098,i + 18,11); else cd_text_frame(1098,i + 18,1); } } void put_pc_target_buttons() { if (store_spell_target < 6) { cd_text_frame(1098,24 + store_spell_target,11); cd_text_frame(1098,30 + store_spell_target,11); } if ((store_last_target_darkened < 6) && (store_last_target_darkened != store_spell_target)) { cd_text_frame(1098,24 + store_last_target_darkened,1); cd_text_frame(1098,30 + store_last_target_darkened,1); } store_last_target_darkened = store_spell_target; } void put_spell_led_buttons() { short i,spell_for_this_button; for (i = 0; i < 38; i++) { spell_for_this_button = (on_which_spell_page == 0) ? i : spell_index[i]; if (spell_for_this_button < 90) { if (((store_situation == 0) && (store_mage == spell_for_this_button)) || ((store_situation == 1) && (store_priest == spell_for_this_button))) { cd_set_led(1098,i + 37,2); } else if (pc_can_cast_spell(pc_casting,store_situation,spell_for_this_button) == true) cd_set_led(1098,i + 37,1); else cd_set_led(1098,i + 37,0); } } } void put_spell_list() { short i; char add_text[256]; if (on_which_spell_page == 0) { csit(1098,80,"Level 1:"); csit(1098,81,"Level 2:"); csit(1098,82,"Level 3:"); csit(1098,83,"Level 4:"); for (i = 0; i < 38; i++) { if (store_situation == 0) { if (i == 35) sprintf(add_text,"%s %c ?",mage_s_name[i], (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i)); else sprintf(add_text,"%s %c %d",mage_s_name[i], (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[0][i]); } else sprintf(add_text,"%s %c %d",priest_s_name[i], (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[1][i]); //for (j = 0; j < 30; i++) // if (add_text[j] == '&') // add_text[j] = (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i); cd_add_label(1098,37 + i, add_text,53); if (spell_index[i] == 90) cd_activate_item(1098,37 + i,1); } } else { csit(1098,80,"Level 5:"); csit(1098,81,"Level 6:"); csit(1098,82,"Level 7:"); csit(1098,83,""); for (i = 0; i < 38; i++) if (spell_index[i] < 90) { if (store_situation == 0) sprintf(add_text,"%s %c %d",mage_s_name[spell_index[i]], (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[0][spell_index[i]]); else sprintf(add_text,"%s %c %d",priest_s_name[spell_index[i]], (char) ((97 + i > 122) ? 65 + (i - 26) : 97 + i),spell_cost[1][spell_index[i]]); cd_add_label(1098,37 + i, add_text,53); } else cd_activate_item(1098,37 + i,0); } } void pick_spell_event_filter (short item_hit) { char *choose_target = " Now pick a target."; char *no_target = " No target needed."; char *bad_target = " Can't cast on him/her."; char *got_target = " Target selected."; char *bad_spell = " Spell not available."; Boolean spell_toast = false,dialog_done = false; switch (item_hit) { case 4: case 5: case 6: case 7: case 8: case 9: // pick caster if (cd_get_active(1098,item_hit) == 1) { pc_casting = item_hit - 4; if (pc_can_cast_spell(pc_casting,store_situation, ((store_situation == 0) ? store_mage : store_priest)) == false) { if (store_situation == 0) store_mage = 70; else store_priest = 70; store_spell_target = 6; } draw_spell_info(); draw_spell_pc_info(); put_spell_led_buttons(); put_pc_caster_buttons(); put_pc_target_buttons(); } break; case 10: case 11: case 12: case 13: case 14: case 15: // pick target if (cd_get_active(1098,10 + pc_casting) == false) { cd_set_item_text(1098,36,no_target); } else if (cd_get_active(1098,item_hit) == false) { cd_set_item_text(1098,36,bad_target); } else { cd_set_item_text(1098,36,got_target); store_spell_target = item_hit - 10; draw_spell_info(); put_pc_target_buttons(); } break; case 16: // cancel spell_toast = true; dialog_done = true; break; case 1: case 17: // cast! dialog_done = true; break; case 75: // other spells on_which_spell_page = 1 - on_which_spell_page; put_spell_list(); put_spell_led_buttons(); break; case 79: // help party.help_received[7] = 0; give_help(207,8,1098); break; case 100: break; default: if (item_hit >= 100) { item_hit -= 100; i = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37]; display_spells(store_situation,i,1098); } else if (cd_get_led(1098,item_hit) == 0) { cd_set_item_text(1098,36,bad_spell); } else { if (store_situation == 0) store_mage = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37]; else store_priest = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37]; draw_spell_info(); put_spell_led_buttons(); if (store_spell_target < 6) { if (cd_get_active(1098,10 + store_spell_target) == false) { store_spell_target = 6; draw_spell_info(); put_pc_target_buttons(); } } // Cute trick now... if a target is needed, caster can always be picked if ((store_spell_target == 6) && (cd_get_active(1098,10 + pc_casting) == 1)) { cd_set_item_text(1098,36,choose_target); draw_spell_info(); // force_play_sound(45); play_sound(45); } else if (cd_get_active(1098,10 + pc_casting) == 0) { store_spell_target = 6; put_pc_target_buttons(); } } break; } if (dialog_done == true) { if (spell_toast == true) { store_mage = store_mage_store; store_priest = store_priest_store; store_spell_target = store_store_target ; if (store_situation == 0) store_last_cast_mage = pc_casting; else store_last_cast_priest = pc_casting; dialog_not_toast = false; dialog_answer = 70; return; } if (((store_situation == 0) && (store_mage == 70)) || ((store_situation == 1) && (store_priest == 70))) { add_string_to_buf("Cast: No spell selected."); store_mage = store_mage_store; store_priest = store_priest_store; store_spell_target = store_store_target ; dialog_not_toast = false; dialog_answer = 70; return; } if ((store_situation == 0) && (mage_need_select[store_mage] == 0)) { store_last_cast_mage = pc_casting; pc_last_cast[store_situation][pc_casting] = store_mage; dialog_not_toast = false; dialog_answer = store_mage; return; } if ((store_situation == 1) && (priest_need_select[store_priest] == 0)) { store_last_cast_priest = pc_casting; pc_last_cast[store_situation][pc_casting] = store_priest; dialog_not_toast = false; dialog_answer = store_priest; return; } if (store_spell_target == 6) { add_string_to_buf("Cast: Need to select target."); store_mage = store_mage_store; store_priest = store_priest_store; store_spell_target = store_store_target ; dialog_not_toast = false; give_help(39,0,1098); dialog_answer = 70; return; } item_hit = ((store_situation == 0) ? store_mage : store_priest); if (store_situation == 0) store_last_cast_mage = pc_casting; else store_last_cast_priest = pc_casting; pc_last_cast[store_situation][pc_casting] = ((store_situation == 0) ? store_mage : store_priest); dialog_not_toast = false; dialog_answer = item_hit; } } short pick_spell(short pc_num,short type,short) // 70 - no spell OW spell num //short pc_num; // if 6, anyone //short type; // 0 - mage 1 - priest //short situation; // 0 - out 1 - town 2 - combat { store_mage_store = store_mage; store_priest_store = store_priest; store_store_target = store_spell_target; store_situation = type; store_last_target_darkened = 6; can_choose_caster = (pc_num < 6) ? false : true; pc_casting = (type == 0) ? store_last_cast_mage : store_last_cast_priest; if (pc_casting == 6) pc_casting = current_pc; if (pc_num == 6) { // See if can keep same caster can_choose_caster = true; if (pc_can_cast_spell(pc_casting,type,type) == false) { for (i = 0; i < 6; i++) if (pc_can_cast_spell(i,type,type)) { pc_casting = i; i = 500; } if (i == 6) { add_string_to_buf("Cast: Nobody can."); return 70; } } } else { can_choose_caster = false; pc_casting = pc_num; } if (can_choose_caster == false) { if ((type == 0) && (adven[pc_num].skills[SKILL_MAGE_SPELLS] == 0)) { add_string_to_buf("Cast: No mage skill."); return 70; } if ((type == 1) && (adven[pc_num].skills[SKILL_PRIEST_SPELLS] == 0)) { add_string_to_buf("Cast: No priest skill."); return 70; } if (adven[pc_casting].cur_sp == 0) { add_string_to_buf("Cast: No spell points."); return 70; } } // If in combat, make the spell being cast this PCs most recent spell if (is_combat()) { if (type == 0) store_mage = pc_last_cast[0][pc_casting]; else store_priest = pc_last_cast[1][pc_casting]; } // Keep the stored spell, if it's still castable if (pc_can_cast_spell(pc_casting,type,((type == 0) ? store_mage : store_priest)) == false) { if (type == 0) { store_mage = 0; store_mage_lev = 1; } else { store_priest = 1; store_priest_lev = 1; } } // If a target is needed, keep the same target if that PC still targetable if (((type == 0) && (mage_need_select[store_mage] > 0)) || ((type == 1) && (priest_need_select[store_priest] > 0))) { if (adven[store_spell_target].isAlive() == false) store_spell_target = 6; } else store_spell_target = 6; // Set the spell page, based on starting spell if (((type == 0) && (store_mage >= 38)) || ((type == 1) && (store_priest >= 38))) on_which_spell_page = 1; else on_which_spell_page = 0; SetCursor(sword_curs); cd_create_dialog(1098,mainPtr); cd_set_pict(1098,2,714 + type); for (i = 37; i < 75; i++) { cd_add_label(1098,i,"",55); if (i > 62) cd_attach_key(1098,i,(char ) (65 + i - 63)); else cd_attach_key(1098,i,(char) (97 + i - 37)); cd_set_led(1098,i,( pc_can_cast_spell(pc_casting,type, (on_which_spell_page == 0) ? i - 37 : spell_index[i - 37]) == true) ? 1 : 0); } cd_attach_key(1098,10,'!'); cd_attach_key(1098,11,'@'); cd_attach_key(1098,12,'#'); cd_attach_key(1098,13,'$'); cd_attach_key(1098,14,'%'); cd_attach_key(1098,15,'^'); for (i = 0; i < 6; i++) cd_key_label(1098,10 + i,0); for (i = 24; i < 36; i++) cd_text_frame(1098,i,1); cd_set_flag(1098,78,0); put_spell_list(); draw_spell_info(); put_pc_caster_buttons(); draw_spell_pc_info(); draw_caster_buttons(); put_spell_led_buttons(); if (party.help_received[7] == 0) { cd_initial_draw(1098); give_help(7,8,1098); } while (dialog_not_toast) ModalDialog(); final_process_dialog(1098); return dialog_answer; } void print_spell_cast(short spell_num,short which) //short which; // 0 - mage 1 - priest { sprintf (c_line, "Spell: %s ", (which == 0) ? mage_s_name[spell_num] : priest_s_name[spell_num]); add_string_to_buf(c_line); } void set_town_spell(short s_num,short who_c) { town_spell = s_num; who_cast = who_c; } void do_alchemy() { short abil1_needed[20] = {150,151,150,151,153, 152,152,153,156,153, 156,154,156,157,155, 157,157,152,156,157}; short abil2_needed[20] = {0,0,0,153,0, 0,0,152,0,154, 150,0,151,0,0, 154,155,155,154,155}; short difficulty[20] = {1,1,1,3,3, 4,5,5,7,9, 9,10,12,12,9, 14,19,10,16,20}; short fail_chance[20] = {50,40,30,20,10,8,6,4,2,0,0,0,0,0,0,0,0,0,0,0}; short which_p,which_item,which_item2,r1; short pc_num; item_record_type store_i = {7,0, 0,0,0,1,0,0, 50,0,0,0,0,0, 0, 8,0, location(),"Potion","Potion",0,5,0,0}; short potion_abils[20] = {ITEM_AFFECT_POISON,ITEM_AFFECT_HEALTH,ITEM_POISON_WEAPON,ITEM_HASTE_SLOW,ITEM_POISON_WEAPON, ITEM_AFFECT_HEALTH,ITEM_AFFECT_POISON,ITEM_HASTE_SLOW,ITEM_AFFECT_DISEASE,ITEM_AFFECT_SPELL_POINTS, ITEM_AFFECT_DUMBFOUND,ITEM_POISON_WEAPON,ITEM_AFFECT_HEALTH,ITEM_POISON_WEAPON,ITEM_RESSURECTION_BALM, ITEM_AFFECT_SPELL_POINTS,ITEM_AFFECT_SKILL_POINTS,ITEM_BLESS_CURSE,ITEM_BLISS,ITEM_AFFECT_SPELL_POINTS}; short potion_strs[20] = {2,2,2,2,4, 5,8,5,4,2, 8,6,8,8,0, 5,2,8,5,8}; short potion_val[20] = {40,60,15,50,50, 180,200,100,150,100, 200,150,300,400,100, 300,500,175,250,500}; pc_num = select_pc(1,0); if (pc_num == INVALID_PC) return; which_p = alch_choice(pc_num); if (which_p < 20) { if (adven[pc_num].hasSpace() == 24) { add_string_to_buf("Alchemy: Can't carry another item."); return; } if (((which_item = adven[pc_num].hasAbil(abil1_needed[which_p])) == 24) || ((abil2_needed[which_p] > 0) && ((which_item2 = adven[pc_num].hasAbil(abil2_needed[which_p])) == 24))) { add_string_to_buf("Alchemy: Don't have ingredients."); return; } play_sound(8); adven[pc_num].removeCharge(which_item); if (abil2_needed[which_p] > 0) adven[pc_num].removeCharge(which_item2); r1 = get_ran(1,0,100); if (r1 < fail_chance[adven[pc_num].skills[SKILL_ALCHEMY] - difficulty[which_p]]) { add_string_to_buf("Alchemy: Failed. "); r1 = get_ran(1,0,1); play_sound(41 ); } else { store_i.value = potion_val[which_p]; store_i.ability_strength = potion_strs[which_p]; store_i.ability = potion_abils[which_p]; if (which_p == 8) store_i.magic_use_type = 2; strcpy(store_i.full_name,alch_names_short[which_p]); if (adven[pc_num].skills[SKILL_ALCHEMY] - difficulty[which_p] >= 5) store_i.charges++; if (adven[pc_num].skills[SKILL_ALCHEMY] - difficulty[which_p] >= 11) store_i.charges++; if (store_i.variety == ITEM_TYPE_POTION) store_i.graphic_num += get_ran(1,0,2); if (adven[pc_num].giveToPC(store_i,0) == false) { ASB("No room in inventory."); ASB(" Potion placed on floor."); place_item(store_i,c_town.p_loc,true); } else add_string_to_buf("Alchemy: Successful. "); } put_item_screen(stat_window,0); } } void alch_choice_event_filter (short item_hit) { if (item_hit == 49) { //OBoE changed party.help_received[20] = 0; give_help(220,21,1047); return; } if (item_hit == 1) dialog_answer = 20; else { item_hit = (item_hit - 9) / 2; dialog_answer = item_hit; } dialog_not_toast = false; } short alch_choice(short pc_num) { short difficulty[20] = {1,1,1,3,3, 4,5,5,7,9, 9,10,12,12,9, 14,19,10,16,20}; short store_alchemy_pc; char get_text[256]; SetCursor(sword_curs); store_alchemy_pc = pc_num; cd_create_dialog(1047,mainPtr); for (i = 0; i < 20; i++) { cd_set_item_text(1047,10 + i * 2,alch_names[i]); if ((adven[pc_num].skills[SKILL_ALCHEMY] < difficulty[i]) || (party.alchemy[i] == 0)) cd_activate_item(1047,9 + i * 2,0); } sprintf(get_text, "%s (skill %d)", adven[pc_num].name,adven[pc_num].skills[SKILL_ALCHEMY]); cd_set_item_text(1047,4,get_text); if (party.help_received[20] == 0) { cd_initial_draw(1047); give_help(20,21,1047); } while (dialog_not_toast) ModalDialog(); final_process_dialog(1047); return dialog_answer; } void pc_graphic_event_filter (short item_hit) { switch (item_hit) { case 1: adven[store_graphic_pc_num].which_graphic = store_pc_graphic; if (store_graphic_mode == 0) dialog_not_toast = false; else { dialog_not_toast = false; dialog_answer = true; } break; case 4: if (store_graphic_mode == 0) { if (adven[store_graphic_pc_num].main_status < MAIN_STATUS_ABSENT) adven[store_graphic_pc_num].main_status = MAIN_STATUS_ABSENT; dialog_not_toast = false; } else { dialog_not_toast = false; dialog_answer = true; } break; default: cd_set_led(1050,store_pc_graphic + 5,0); store_pc_graphic = item_hit - 5; cd_set_led(1050,item_hit,1); break; } dialog_answer = false; } Boolean pick_pc_graphic(short pc_num,short mode,short parent_num) // mode ... 0 - create 1 - created { short i; store_graphic_pc_num = pc_num; store_graphic_mode = mode; store_pc_graphic = adven[pc_num].which_graphic; SetCursor(sword_curs); cd_create_dialog_parent_num(1050,parent_num); for (i = 41; i < 77; i++) csp(1050,i,800 + i - 41); for (i = 5; i < 41; i++) { if (store_pc_graphic + 5 == i) cd_set_led(1050,i,1); else cd_set_led(1050,i,0); } while (dialog_not_toast) ModalDialog(); cd_kill_dialog(1050,0); return dialog_answer; } void pc_name_event_filter () { char get_text[256]; cd_get_text_edit_str(1051,(char *) get_text); if ((get_text[0] < 33) || (get_text[0] > 126)) { csit(1051,6,"Must begin with a letter."); } else { sprintf((char *) adven[store_train_pc].name,"%.18s",(char *) get_text); dialog_not_toast = false; } } Boolean pick_pc_name(short pc_num,short parent_num) //town_num; // Will be 0 - 200 for town, 200 - 290 for outdoors //short sign_type; // terrain type { store_train_pc = pc_num; SetCursor(sword_curs); cd_create_dialog_parent_num(1051,parent_num); cd_set_edit_focus(); while (dialog_not_toast) ModalDialog(); cd_kill_dialog(1051,0); return 1; } void pick_trapped_monst_event_filter (short item_hit) { dialog_not_toast = false; dialog_answer = item_hit; } unsigned char pick_trapped_monst() // ignore parent in Mac version { short i; char sp[256]; monster_record_type get_monst; SetCursor(sword_curs); cd_create_dialog_parent_num(988,0); for (i = 0; i < 4; i++) if (party.imprisoned_monst[i] == 0) { cd_activate_item(988, 2 + 3 * i, 0); } else { get_m_name(sp,(unsigned char)(party.imprisoned_monst[i])); csit(988,3 + 3 * i, sp); get_monst = return_monster_template((unsigned char)(party.imprisoned_monst[i])); cdsin(988,4 + 3 * i,get_monst.level); } while (dialog_not_toast) ModalDialog(); cd_kill_dialog(988,0); if (dialog_answer == 1) return 0; else return ((unsigned char)(party.imprisoned_monst[(dialog_answer - 2) / 3])); } void pc_record_type::poison(short how_much) { short tlevel = 0; if (isAlive()) { if ((tlevel = getProtLevel(ITEM_POISON_PROTECTION)) > 0)//// how_much -= tlevel / 2; if ((tlevel = getProtLevel(ITEM_FULL_PROTECTION)) > 0)//// how_much -= tlevel / 3; if ((traits[TRAIT_FRAIL] == true) && (how_much > 1)) how_much++; if ((traits[TRAIT_FRAIL] == true) && (how_much == 1) && (get_ran(1,0,1) == 0)) how_much++; if (how_much > 0) { status[STATUS_POISON] = min(status[STATUS_POISON] + how_much,8); sprintf (c_line, " %s poisoned.", name); add_string_to_buf(c_line); one_sound(17); give_help(33,0,0); } } put_pc_screen(); } void pc_array::poison(short how_much) { for (int i = 0; i < 6; i++) pc[i].poison(how_much); } void affect_pc(short which_pc,short type,short how_much)//// //type; // which status to affect { if (adven[which_pc].isAlive() == false) return; adven[which_pc].status[type] = minmax (-8,8,adven[which_pc].status[type] + how_much); if (((type >= 4) && (type <= 10)) || (type == 12) || (type == 13)) adven[which_pc].status[type] = max(adven[which_pc].status[type],0); put_pc_screen(); } void pc_array::affect(short type, short how_much) //type; // which status to affect { for (int i = 0; i < 6; i++) adven[i].status[type] = minmax (-8,8,adven[i].status[type] + how_much); put_pc_screen(); } void void_sanctuary(short pc_num) { if (adven[pc_num].status[STATUS_INVISIBLE] > 0) { add_string_to_buf("You become visible!"); adven[pc_num].status[STATUS_INVISIBLE] = 0; } } void pc_array::damage(short how_much,short damage_type) { for (int i = 0; i < NUM_OF_PCS; i++) pc[i].damage(how_much,damage_type,-1); put_pc_screen(); } void pc_array::kill(short mode) { short i; boom_anim_active = false; for (i = 0; i < 6; i++) if (pc[i].isAlive()) pc[i].main_status = mode; put_pc_screen(); } bool pc_record_type::damage(short how_much, short damage_type, short type_of_attacker) //short damage_type; // 0 - weapon 1 - fire 2 - poison 3 - general magic 4 - unblockable // 5 - cold 6 - undead attack 7 - demon attack // 10 - marked damage, from during anim mode ... no boom, and totally unblockable // 30 + * same as *, but no print // 100s digit - sound data { short i, r1, sound_type, tlevel; bool do_print = true; if (!isAlive()) return false; sound_type = damage_type / 100; damage_type = damage_type % 100; if (damage_type >= DAMAGE_NO_PRINT) { do_print = false; damage_type -= DAMAGE_NO_PRINT; } if (sound_type == 0) { if ((damage_type == DAMAGE_FIRE) || (damage_type == DAMAGE_UNBLOCKABLE)) sound_type = 5; if (damage_type == DAMAGE_MAGIC) sound_type = 12; if (damage_type == DAMAGE_COLD) sound_type = 7; if (damage_type == DAMAGE_POISON) sound_type = 11; } // armor if ((damage_type == DAMAGE_WEAPON) || (damage_type == DAMAGE_UNDEAD) ||(damage_type == DAMAGE_DEMON)) { how_much -= minmax(-5, 5, (int)status[STATUS_BLESS_CURSE]); for (i = 0; i < 24; i++) if ((items[i].variety != ITEM_TYPE_NO_ITEM) && (equip[i] == true)) { if ((items[i].variety >= ITEM_TYPE_SHIELD) && (items[i].variety <= ITEM_TYPE_BOOTS)) {//armor r1 = get_ran(1,1,items[i].item_level); how_much -= r1; // bonus for magical items if (items[i].bonus > 0) { r1 = get_ran(1,1,items[i].bonus); how_much -= r1; how_much -= items[i].bonus / 2; } if (items[i].bonus < 0) how_much -= items[i].bonus; r1 = get_ran(1,0,100); if (r1 < hit_chance[skills[SKILL_DEFENSE]] - 20) how_much -= 1; } if (items[i].protection > 0) { r1 = get_ran(1,1,items[i].protection); how_much -= r1; } if (items[i].protection < 0) { r1 = get_ran(1,1,-1 * items[i].protection); how_much += r1; } } } // parry // ugly hack short which_pc = getNum(); // temporarily disabled if ((damage_type < DAMAGE_POISON) && (pc_parry[which_pc] < 100)) how_much -= pc_parry[which_pc] / 4; if (damage_type != DAMAGE_MARKED) { if (PSD[SDF_EASY_MODE] > 0) how_much -= 3; // toughness if (traits[TRAIT_TOUGHNESS] == true) how_much--; // luck if (get_ran(1,0,100) < 2 * (hit_chance[skills[SKILL_LUCK]] - 20)) how_much -= 1; } if ((damage_type == DAMAGE_WEAPON) && ((tlevel = getProtLevel(ITEM_PROTECTION)) > 0)) how_much -= tlevel; if ((damage_type == DAMAGE_UNDEAD) && ((tlevel = getProtLevel(ITEM_PROTECT_FROM_UNDEAD)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); if ((damage_type == DAMAGE_DEMON) && ((tlevel = getProtLevel(ITEM_PROTECT_FROM_DEMONS)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); if ((type_of_attacker == MONSTER_TYPE_HUMANOID) && ((tlevel = getProtLevel(ITEM_PROTECT_FROM_HUMANOIDS)) > 0))//protection from humanoids how_much /= ((tlevel >= 7) ? 4 : 2); if ((type_of_attacker == MONSTER_TYPE_REPTILE) && ((tlevel = getProtLevel(ITEM_PROTECT_FROM_REPTILES)) > 0))//protection from reptiles how_much /= ((tlevel >= 7) ? 4 : 2); if ((type_of_attacker == MONSTER_TYPE_GIANT) && ((tlevel = getProtLevel(ITEM_PROTECT_FROM_GIANTS)) > 0))//protection from giants how_much /= ((tlevel >= 7) ? 4 : 2); // invuln if (status[STATUS_INVULNERABLE] > 0) how_much = 0; // magic resistance if ((damage_type == DAMAGE_MAGIC) && ((tlevel = getProtLevel(ITEM_MAGIC_PROTECTION)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); // Mag. res helps w. fire and cold if (((damage_type == DAMAGE_FIRE) || (damage_type == DAMAGE_COLD)) && (status[STATUS_MAGIC_RESISTANCE] > 0)) how_much /= 2; // fire res. if ((damage_type == DAMAGE_FIRE) && ((tlevel = getProtLevel(ITEM_FIRE_PROTECTION)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); // cold res. if ((damage_type == DAMAGE_COLD) && ((tlevel = getProtLevel(ITEM_COLD_PROTECTION)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); // major resistance if (((damage_type == DAMAGE_FIRE) || (damage_type == DAMAGE_POISON) || (damage_type == DAMAGE_MAGIC) || (damage_type == DAMAGE_COLD)) && ((tlevel = getProtLevel(ITEM_FULL_PROTECTION)) > 0)) how_much /= ((tlevel >= 7) ? 4 : 2); //ugly hack // short which_pc = getNum(); // temporarily disabled if (boom_anim_active == true) { if (how_much < 0) how_much = 0; pc_marked_damage[which_pc] += how_much; if (is_town()) add_explosion(c_town.p_loc,how_much,0,(damage_type > DAMAGE_POISON) ? 2 : 0,0,0); else add_explosion(pc_pos[which_pc],how_much,0,(damage_type > DAMAGE_POISON) ? 2 : 0,0,0); if (how_much == 0) return false; else return true; } if (how_much <= 0) { if ((damage_type == DAMAGE_WEAPON) || (damage_type == DAMAGE_UNDEAD) || (damage_type == DAMAGE_DEMON)) play_sound(2); add_string_to_buf (" No damage."); return false; } else { // if asleep, get bonus if (status[11] > 0) status[11]--; sprintf (c_line, " %s takes %d. ", name, how_much); if (do_print) add_string_to_buf(c_line); if (damage_type != DAMAGE_MARKED) { if (is_combat()) boom_space(pc_pos[which_pc],overall_mode,boom_gr[damage_type],how_much,sound_type); else if (is_town()) boom_space(c_town.p_loc,overall_mode,boom_gr[damage_type],how_much,sound_type); else boom_space(party.p_loc,100,boom_gr[damage_type],how_much,sound_type); } if (overall_mode != MODE_OUTDOORS) FlushEvents(1); FlushEvents(0); } party.total_dam_taken += how_much; if (cur_health >= how_much) cur_health -= how_much; else if (cur_health > 0) cur_health = 0; else // Check if PC can die if (how_much > 25) { sprintf (c_line, " %s is obliterated. ", name); add_string_to_buf(c_line); kill(3); } else { sprintf (c_line, " %s is killed.", name); add_string_to_buf(c_line); kill(2); } if ((cur_health == 0) && isAlive()) play_sound(3); put_pc_screen(); return true; } void set_pc_moves() { short i,r,i_level; for (i = 0; i < 6; i++) if (adven[i].isAlive() == false) pc_moves[i] = 0; else { pc_moves[i] = (adven[i].traits[TRAIT_SLUGGISH] == true) ? 3 : 4; r = get_encumberance(i); pc_moves[i] = minmax(1,8,pc_moves[i] - (r / 3)); if ((i_level = adven[i].getProtLevel(ITEM_SPEED)) > 0) pc_moves[i] += i_level / 7 + 1; if ((i_level = adven[i].getProtLevel(ITEM_SLOW_WEARER)) > 0) pc_moves[i] -= i_level / 5; if ((adven[i].status[STATUS_HASTE_SLOW] < 0) && (party.age % 2 == 1)) // slowed? pc_moves[i] = 0; else { // do webs pc_moves[i] = max(0,pc_moves[i] - adven[i].status[STATUS_WEBS] / 2); if (pc_moves[i] == 0) { sprintf(c_line,"%s must clean webs.",adven[i].name); add_string_to_buf(c_line); adven[i].status[STATUS_WEBS] = max(0,adven[i].status[STATUS_WEBS] - 3); } } if (adven[i].status[STATUS_HASTE_SLOW] > 7) pc_moves[i] = pc_moves[i] * 3; else if (adven[i].status[STATUS_HASTE_SLOW] > 0) pc_moves[i] = pc_moves[i] * 2; if ((adven[i].status[STATUS_ASLEEP] > 0) || (adven[i].status[STATUS_PARALYZED] > 0)) pc_moves[i] = 0; } } void take_ap(short num) { pc_moves[current_pc] = max(0,pc_moves[current_pc] - num); } short cave_lore_present() { short i,ret = 0; for (i = 0; i < 6; i++) if ((adven[i].isAlive()) && (adven[i].traits[TRAIT_CAVE_LORE] > 0)) ret += 1; return ret; } // Time for some chicanery // The how to item for mage will be 399, for priest will be 499 // item 400 + i will mean cast mage spell i. // item 500 + i will mean cast priest spell i. void adjust_spell_menus() { short i,j,spell_pos = 0; short total_added = 0; char spell_name[256]; short old_on_spell_menu[2][62]; Boolean need_menu_change = false; HMENU menu,big_menu; if (in_startup_mode == true) return; big_menu = GetMenu(mainPtr); menu = GetSubMenu(big_menu,6); if (menu == NULL) return; for (i = 0; i < 2; i++) for (j = 0; j < 62; j++) old_on_spell_menu[i][j] = on_spell_menu[i][j]; for (i = 0; i < 62; i++) { on_spell_menu[0][i] = -1; } for (i = 0; i < 62; i++) if (pc_can_cast_spell(current_pc,0,i)) { on_spell_menu[0][spell_pos] = i; spell_pos++; } for (i = 0; i < 62; i++) if (on_spell_menu[0][i] != old_on_spell_menu[0][i]) need_menu_change = true; if (need_menu_change) { for (i = 0; i < 62; i++) { DeleteMenu(menu,400 + i,MF_BYCOMMAND); } for (i = 0; i < 62; i++) if (pc_can_cast_spell(current_pc,0,i) == true) { if (spell_cost[0][i] > 0) sprintf(spell_name,"L%d - %s, C %d",spell_level[i], mage_s_name[i],spell_cost[0][i]); else sprintf(spell_name,"L%d - %s, C ?",spell_level[i], mage_s_name[i]); total_added++; if (total_added % 24 == 0) InsertMenu(menu,399,MF_MENUBREAK | MF_BYCOMMAND | MF_ENABLED | MF_STRING, 400 + i, spell_name); else InsertMenu(menu,399,MF_BYCOMMAND | MF_ENABLED | MF_STRING, 400 + i, spell_name); //InsertMenu(menu,399,MF_BYCOMMAND | MF_ENABLED | MF_STRING, // 400 + i, spell_name); //beep(); } } need_menu_change = false; spell_pos = 0; total_added = 0; menu = GetSubMenu(big_menu,7); if (menu == NULL) return; for (i = 0; i < 62; i++) { on_spell_menu[1][i] = -1; } for (i = 0; i < 62; i++) if (pc_can_cast_spell(current_pc,1,i)) { on_spell_menu[1][spell_pos] = i; spell_pos++; } for (i = 0; i < 62; i++) if (on_spell_menu[1][i] != old_on_spell_menu[1][i]) need_menu_change = true; if (need_menu_change) { for (i = 0; i < 62; i++) { DeleteMenu(menu,500 + i,MF_BYCOMMAND); } for (i = 0; i < 62; i++) if (pc_can_cast_spell(current_pc,1,i) == true) { //spell_name[0] = strlen((char *) priest_s_name[on_spell_menu[1][i]]); //strcpy((char *) (spell_name + 1),priest_s_name[on_spell_menu[1][i]]); if (spell_cost[1][i] > 0) sprintf(spell_name," L%d - %s, C %d",spell_level[i], priest_s_name[i],spell_cost[1][i]); else sprintf(spell_name," L%d - %s, C ?",spell_level[i], priest_s_name[i]); total_added++; if (total_added % 24 == 0) InsertMenu(menu,499,MF_MENUBREAK | MF_BYCOMMAND | MF_ENABLED | MF_STRING, 500 + i, spell_name); else InsertMenu(menu,499,MF_BYCOMMAND | MF_ENABLED | MF_STRING, 500 + i, spell_name); } } }