-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X do X`09`7B X`09 if (background`5Bcur_ptr`5D.chart == hist_ptr) X`09 `7B X`09 test_roll = randint(100); X`09 while (test_roll > background`5Bcur_ptr`5D.roll) X`09`09cur_ptr++; X`09 b_ptr = &background`5Bcur_ptr`5D; X`09 (void) strcat(history_block, b_ptr->info); X`09 social_class += b_ptr->bonus - 50; X`09 if (hist_ptr > b_ptr->next) X`09`09cur_ptr = 0; X`09 hist_ptr = b_ptr->next; X`09 flag = TRUE; X`09 `7D X`09 else X`09 cur_ptr++; X`09`7D X while (!flag); X `7D X while (hist_ptr >= 1); X X /* clear the previous history strings */ X for (hist_ptr = 0; hist_ptr < 4; hist_ptr++) X py.misc.history`5Bhist_ptr`5D`5B0`5D = '\0'; X X /* Process block of history text for pretty output`09*/ X start_pos = 0; X end_pos = strlen(history_block) - 1; X line_ctr = 0; X flag = FALSE; X while (history_block`5Bend_pos`5D == ' ') X end_pos--; X do X `7B X while (history_block`5Bstart_pos`5D == ' ') X`09start_pos++; X cur_len = end_pos - start_pos + 1; X if (cur_len > 60) X`09`7B X`09 cur_len = 60; X`09 while (history_block`5Bstart_pos+cur_len-1`5D != ' ') X`09 cur_len--; X`09 new_start = start_pos + cur_len; X`09 while (history_block`5Bstart_pos+cur_len-1`5D == ' ') X`09 cur_len--; X`09`7D X else X`09flag = TRUE; X (void) strncpy(py.misc.history`5Bline_ctr`5D, &history_block`5Bstart_p Vos`5D, X`09`09 cur_len); X py.misc.history`5Bline_ctr`5D`5Bcur_len`5D = '\0'; X line_ctr++; X start_pos = new_start; X `7D X while (!flag); X X /* Compute social class for player`09`09`09*/ X if (social_class > 100) X social_class = 100; X else if (social_class < 1) X social_class = 1; X py.misc.sc = social_class; X`7D X X X/* Gets the character's sex`09`09`09`09-JWT-`09*/ Xstatic void get_sex() X`7B X register int exit_flag; X char c; X X exit_flag = FALSE; X clear_from (20); X put_buffer("Choose a sex (? for Help):", 20, 2); X put_buffer("m) Male f) Female", 21, 2); X do X `7B X move_cursor (20, 29); X /* speed not important here */ X c = inkey(); X if (c == 'f' `7C`7C c == 'F') X`09`7B X`09 py.misc.male = FALSE; X`09 put_buffer("Female", 4, 15); X`09 exit_flag = TRUE; X`09`7D X else if (c == 'm' `7C`7C c == 'M') X`09`7B X`09 py.misc.male = TRUE; X`09 put_buffer("Male", 4, 15); X`09 exit_flag = TRUE; X`09`7D X else if (c == '?') X`09helpfile (MORIA_WELCOME); X else X`09bell (); X `7D X while (!exit_flag); X`7D X X X/* Computes character's age, height, and weight`09`09-JWT-`09*/ Xstatic void get_ahw() X`7B X register int i; X X i = py.misc.prace; X py.misc.age = race`5Bi`5D.b_age + randint((int)race`5Bi`5D.m_age); X if (py.misc.male) X `7B X py.misc.ht = randnor((int)race`5Bi`5D.m_b_ht, (int)race`5Bi`5D.m_m_ht) V; X py.misc.wt = randnor((int)race`5Bi`5D.m_b_wt, (int)race`5Bi`5D.m_m_wt) V; X `7D X else X `7B X py.misc.ht = randnor((int)race`5Bi`5D.f_b_ht, (int)race`5Bi`5D.f_m_ht) V; X py.misc.wt = randnor((int)race`5Bi`5D.f_b_wt, (int)race`5Bi`5D.f_m_wt) V; X `7D X py.misc.disarm = race`5Bi`5D.b_dis + todis_adj(); X`7D X X X/* Gets a character class`09`09`09`09-JWT-`09*/ Xstatic void get_class() X`7B X register int i, j; X int k, l, m, min_value, max_value; X int cl`5BMAX_CLASS`5D, exit_flag; X register struct misc *m_ptr; X register player_type *p_ptr; X class_type *c_ptr; X char tmp_str`5B80`5D, s; X int32u mask; X X for (j = 0; j < MAX_CLASS; j++) X cl`5Bj`5D = 0; X i = py.misc.prace; X j = 0; X k = 0; X l = 2; X m = 21; X mask = 0x1; X clear_from (20); X put_buffer("Choose a class (? for Help):", 20, 2); X do X `7B X if (race`5Bi`5D.rtclass & mask) X`09`7B X`09 (void) sprintf(tmp_str, "%c) %s", k+'a', class`5Bj`5D.title); X`09 put_buffer(tmp_str, m, l); X`09 cl`5Bk`5D = j; X`09 l += 15; X`09 if (l > 70) X`09 `7B X`09 l = 2; X`09 m++; X`09 `7D X`09 k++; X`09`7D X j++; X mask <<= 1; X `7D X while (j < MAX_CLASS); X py.misc.pclass = 0; X exit_flag = FALSE; X do X `7B X move_cursor (20, 31); X s = inkey(); X j = s - 'a'; X if ((j < k) && (j >= 0)) X`09`7B X`09 py.misc.pclass = cl`5Bj`5D; X`09 c_ptr = &class`5Bpy.misc.pclass`5D; X`09 exit_flag = TRUE; X`09 clear_from (20); X`09 put_buffer(c_ptr->title, 5, 15); X X`09 /* Adjust the stats for the class adjustment`09`09-RAK-`09*/ X`09 p_ptr = &py; X`09 change_stat (A_STR, c_ptr->madj_str); X`09 change_stat (A_INT, c_ptr->madj_int); X`09 change_stat (A_WIS, c_ptr->madj_wis); X`09 change_stat (A_DEX, c_ptr->madj_dex); X`09 change_stat (A_CON, c_ptr->madj_con); X`09 change_stat (A_CHR, c_ptr->madj_chr); X`09 for(i = 0; i < 6; i++) X`09 `7B X`09 p_ptr->stats.cur_stat`5Bi`5D = p_ptr->stats.max_stat`5Bi`5D; X`09 set_use_stat(i); X`09 `7D X X`09 p_ptr->misc.ptodam = todam_adj();`09/* Real values`09`09*/ X`09 p_ptr->misc.ptohit = tohit_adj(); X`09 p_ptr->misc.ptoac = toac_adj(); X`09 p_ptr->misc.pac = 0; X`09 p_ptr->misc.dis_td = p_ptr->misc.ptodam; /* Displayed values`09*/ X`09 p_ptr->misc.dis_th = p_ptr->misc.ptohit; X`09 p_ptr->misc.dis_tac= p_ptr->misc.ptoac; X`09 p_ptr->misc.dis_ac = p_ptr->misc.pac + p_ptr->misc.dis_tac; X X`09 /* now set misc stats, do this after setting stats because X`09 of con_adj() for hitpoints */ X`09 m_ptr = &py.misc; X`09 m_ptr->hitdie += c_ptr->adj_hd; X`09 m_ptr->mhp = con_adj() + m_ptr->hitdie; X`09 m_ptr->chp = m_ptr->mhp; X`09 m_ptr->chp_frac = 0; X X`09 /* initialize hit_points array */ X`09 /* put bounds on total possible hp, only succeed if it is within X`09 1/8 of average value */ X`09 min_value = (MAX_PLAYER_LEVEL*3/8 * (m_ptr->hitdie-1)) + X`09 MAX_PLAYER_LEVEL; X`09 max_value = (MAX_PLAYER_LEVEL*5/8 * (m_ptr->hitdie-1)) + X`09 MAX_PLAYER_LEVEL; X`09 player_hp`5B0`5D = m_ptr->hitdie; X`09 do X`09 `7B X`09 for (i = 1; i < MAX_PLAYER_LEVEL; i++) X`09`09`7B X#ifdef AMIGA`09`09/* Stupid Aztec C 5.0 bug work around CBG */ X`09`09 player_hp`5Bi`5D = player_hp`5Bi-1`5D + randint ((int)m_ptr->hitdie) V; X#else X`09`09 player_hp`5Bi`5D = randint((int)m_ptr->hitdie); X`09`09 player_hp`5Bi`5D += player_hp`5Bi-1`5D; X#endif X`09`09`7D X`09 `7D X`09 while ((player_hp`5BMAX_PLAYER_LEVEL-1`5D < min_value) `7C`7C X`09`09 (player_hp`5BMAX_PLAYER_LEVEL-1`5D > max_value)); X X`09 m_ptr->bth += c_ptr->mbth; X`09 m_ptr->bthb += c_ptr->mbthb;`09/*RAK*/ X`09 m_ptr->srh += c_ptr->msrh; X`09 m_ptr->disarm += c_ptr->mdis; X`09 m_ptr->fos += c_ptr->mfos; X`09 m_ptr->stl += c_ptr->mstl; X`09 m_ptr->save += c_ptr->msav; X`09 m_ptr->expfact += c_ptr->m_exp; X`09`7D X else if (s == '?') X`09helpfile (MORIA_WELCOME); X else X`09bell (); X `7D X while (!exit_flag); X`7D X X X/* Given a stat value, return a monetary value, which affects the amount X of gold a player has. */ Xstatic int monval (i) Xint8u i; X`7B X return 5 * ((int)i - 10); X`7D X X Xstatic void get_money() X`7B X register int tmp, gold; X register int8u *a_ptr; X X a_ptr = py.stats.max_stat; X tmp = monval (a_ptr`5BA_STR`5D) + monval (a_ptr`5BA_INT`5D) X + monval (a_ptr`5BA_WIS`5D) + monval (a_ptr`5BA_CON`5D) X + monval (a_ptr`5BA_DEX`5D); X X gold = py.misc.sc*6 + randint (25) + 325;`09/* Social Class adj */ X gold -= tmp;`09`09`09`09`09/* Stat adj */ X gold += monval (a_ptr`5BA_CHR`5D);`09`09/* Charisma adj`09*/ X if (!py.misc.male) X gold += 50;`09`09`09/* She charmed the banker into it! -CJS- */ X if (gold < 80) X gold = 80;`09`09`09/* Minimum */ X py.misc.au = gold; X`7D X X X/* ---------- M A I N for Character Creation Routine ---------- */ X/*`09`09`09`09`09`09`09-JWT-`09*/ Xvoid create_character() X`7B X register int exit_flag = 1; X register char c; X X put_character(); X choose_race(); X get_sex(); X X /* here we start a loop giving a player a choice of characters -RGM- */ X get_all_stats (); X get_history(); X get_ahw(); X print_history(); X put_misc1(); X put_stats(); X X clear_from (20); X put_buffer("Hit space to reroll or ESC to accept characteristics: ", 20, 2 V); X do X `7B X move_cursor (20, 56); X c = inkey(); X if (c == ESCAPE) X`09exit_flag = 0; X else if (c == ' ') X`09`7B X`09 get_all_stats (); X`09 get_history(); X`09 get_ahw(); X`09 print_history(); X`09 put_misc1(); X`09 put_stats(); X`09`7D X else X`09bell (); X `7D`09`09 /* done with stats generation */ X while (exit_flag == 1); X X get_class(); X get_money(); X put_stats(); X put_misc2(); X put_misc3(); X get_name(); X X /* This delay may be reduced, but is recommended to keep players`09*/ X /* from continuously rolling up characters, which can be VERY`09*/ X /* expensive CPU wise.`09`09`09`09`09`09*/ X pause_exit(23, PLAYER_EXIT_PAUSE); X`7D $ CALL UNPACK CREATE.C;1 624136983 $ create 'f' X/* source/creature.c: handle monster movement and attacks X X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke X X This software may be copied and distributed for educational, research, an Vd X not for profit purposes provided that this copyright and statement are X included in all such copies. */ X X#ifdef __TURBOC__ X#include`09 X#include`09 X#endif /* __TURBOC__ */ X`20 X#include "config.h" X#include "constant.h" X#include "types.h" X#include "externs.h" X X#ifdef USG X#ifndef ATARIST_MWC X#include X#else Xchar *strcat(); Xchar *strcpy(); X#endif X#else X#include X#endif X X#if defined(LINT_ARGS) Xstatic int movement_rate(int16); Xstatic int check_mon_lite(int, int); Xstatic void get_moves(int, int *); Xstatic void make_attack(int); Xstatic void make_move(int, int *, int32u *); Xstatic void mon_cast_spell(int, int *); Xstatic void mon_move(int, int32u *); X#endif X X#ifdef ATARIST_TC X/* Include this to get prototypes for standard library functions. */ X#include X#endif X X X/* Updates screen when monsters move about`09`09-RAK-`09*/ Xvoid update_mon(monptr) Xint monptr; X`7B X register int flag; X register cave_type *c_ptr; X register monster_type *m_ptr; X register creature_type *r_ptr; X#ifdef ATARIST_MWC X int32u holder; X#endif X X m_ptr = &m_list`5Bmonptr`5D; X flag = FALSE; X if ((m_ptr->cdis <= MAX_SIGHT) && X !(py.flags.status & PY_BLIND) && X (panel_contains((int)m_ptr->fy, (int)m_ptr->fx))) X `7B X /* Wizard sight.`09 */ X if (wizard) X`09flag = TRUE; X /* Normal sight.`09 */ X else if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) X`09`7B X`09 c_ptr = &cave`5Bm_ptr->fy`5D`5Bm_ptr->fx`5D; X`09 r_ptr = &c_list`5Bm_ptr->mptr`5D; X`09 if (c_ptr->pl `7C`7C c_ptr->tl `7C`7C X`09 (find_flag && m_ptr->cdis < 2 && player_light)) X`09 `7B X#ifdef ATARIST_MWC X`09 holder = CM_INVISIBLE; X`09 if ((holder & r_ptr->cmove) == 0) X#else X`09 if ((CM_INVISIBLE & r_ptr->cmove) == 0) X#endif X`09`09flag = TRUE; X`09 else if (py.flags.see_inv) X`09`09`7B X`09`09 flag = TRUE; X#ifdef ATARIST_MWC X`09`09 c_recall`5Bm_ptr->mptr`5D.r_cmove `7C= holder; X#else X`09`09 c_recall`5Bm_ptr->mptr`5D.r_cmove `7C= CM_INVISIBLE; X#endif X`09`09`7D X`09 `7D X`09 /* Infra vision.`09 */ X`09 else if ((py.flags.see_infra > 0) && X`09`09 (m_ptr->cdis <= py.flags.see_infra) && X`09`09 (CD_INFRA & r_ptr->cdefense)) X`09 `7B X`09 flag = TRUE; X`09 c_recall`5Bm_ptr->mptr`5D.r_cdefense `7C= CD_INFRA; X`09 `7D X`09`7D X `7D X /* Light it up.`09 */ X if (flag) X `7B X if (!m_ptr->ml) X`09`7B X`09 disturb (1, 0); X`09 m_ptr->ml = TRUE; X`09 lite_spot((int)m_ptr->fy, (int)m_ptr->fx); X`09 screen_change = TRUE; /* notify inven_command */ X`09`7D X `7D X /* Turn it off.`09 */ X else if (m_ptr->ml) X `7B X m_ptr->ml = FALSE; X lite_spot((int)m_ptr->fy, (int)m_ptr->fx); X screen_change = TRUE; /* notify inven_command */ X `7D X`7D X X X/* Given speed,`09 returns number of moves this turn.`09-RAK-`09*/ X/* NOTE: Player must always move at least once per iteration,`09 */ X/*`09 a slowed player is handled by moving monsters faster`09 */ Xstatic int movement_rate(speed) Xregister int16 speed; X`7B X if (speed > 0) X `7B X if (py.flags.rest != 0) X`09return 1; X else X`09return speed; X `7D X else X `7B X /* speed must be negative here */ X return ((turn % (2 - speed)) == 0); X `7D X`7D X X X/* Makes sure a new creature gets lit up.`09`09`09-CJS- */ Xstatic int check_mon_lite(y, x) Xint y, x; X`7B X register int monptr; X X monptr = cave`5By`5D`5Bx`5D.cptr; X if (monptr <= 1) X return FALSE; X else X `7B X update_mon(monptr); X return m_list`5Bmonptr`5D.ml; X `7D X`7D X X X/* Choose correct directions for monster movement`09-RAK-`09*/ Xstatic void get_moves(monptr, mm) Xint monptr; Xregister int *mm; X`7B X int y, ay, x, ax, move_val; X X y = m_list`5Bmonptr`5D.fy - char_row; X x = m_list`5Bmonptr`5D.fx - char_col; X if (y < 0) X `7B X move_val = 8; X ay = -y; X `7D X else X `7B X move_val = 0; X ay = y; X `7D X if (x > 0) X `7B X move_val += 4; X ax = x; X `7D X else X ax = -x; X /* this has the advantage of preventing the diamond maneuvre, also faster V */ X if (ay > (ax << 1)) X move_val += 2; X else if (ax > (ay << 1)) X move_val++; X switch(move_val) X `7B X case 0: X mm`5B0`5D = 9; X if (ay > ax) X`09`7B X`09 mm`5B1`5D = 8; X`09 mm`5B2`5D = 6; X`09 mm`5B3`5D = 7; X`09 mm`5B4`5D = 3; X`09`7D X else X`09`7B X`09 mm`5B1`5D = 6; X`09 mm`5B2`5D = 8; X`09 mm`5B3`5D = 3; X`09 mm`5B4`5D = 7; X`09`7D X break; X case 1: case 9: X mm`5B0`5D = 6; X if (y < 0) X`09`7B X`09 mm`5B1`5D = 3; X`09 mm`5B2`5D = 9; X`09 mm`5B3`5D = 2; X`09 mm`5B4`5D = 8; X`09`7D X else X`09`7B X`09 mm`5B1`5D = 9; X`09 mm`5B2`5D = 3; X`09 mm`5B3`5D = 8; X`09 mm`5B4`5D = 2; +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-