-+-+-+-+-+-+-+-+ START OF PART 7 -+-+-+-+-+-+-+-+ X if (randint(chance) != 1) X *took_turn`09= FALSE; X /* Must be within certain range`09`09 */ X else if (m_ptr->cdis > MAX_SPELL_DIS) X *took_turn`09= FALSE; X /* Must have unobstructed Line-Of-Sight`09 */ X else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) X *took_turn`09= FALSE; X else`09/* Creature is going to cast a spell`09 */ X `7B X *took_turn = TRUE; X /* Check to see if monster should be lit. */ X update_mon (monptr); X /* Describe the attack`09`09`09 */ X if (m_ptr->ml) X`09(void) sprintf(cdesc, "The %s ", r_ptr->name); X else X`09(void) strcpy(cdesc, "It "); X /* For "DIED_FROM" string`09 */ X#ifdef ATARIST_MWC X holder = CM_WIN; X if (holder & r_ptr->cmove) X#else X if (CM_WIN & r_ptr->cmove) X#endif X`09(void) sprintf(ddesc, "The %s", r_ptr->name); X else if (is_a_vowel (r_ptr->name`5B0`5D)) X`09(void) sprintf (ddesc, "an %s", r_ptr->name); X else X`09(void) sprintf(ddesc, "a %s", r_ptr->name); X /* End DIED_FROM`09`09 */ X X /* Extract all possible spells into spell_choice */ X#ifdef ATARIST_MWC X holder = `7ECS_FREQ; X i = (r_ptr->spells & holder); X#else X i = (r_ptr->spells & `7ECS_FREQ); X#endif X k = 0; X while (i != 0) X`09`7B X`09 spell_choice`5Bk`5D = bit_pos(&i); X`09 k++; X`09`7D X /* Choose a spell to cast`09`09`09 */ X thrown_spell = spell_choice`5Brandint(k) - 1`5D; X thrown_spell++; X /* all except teleport_away() and drain mana spells always disturb */ X if (thrown_spell > 6 && thrown_spell != 17) X`09disturb (1, 0); X /* save some code/data space here, with a small time penalty */ X if ((thrown_spell < 14 && thrown_spell > 6) `7C`7C (thrown_spell == 16 V)) X`09`7B X`09 (void) strcat(cdesc, "casts a spell."); X`09 msg_print(cdesc); X`09`7D X /* Cast the spell.`09`09`09 */ X switch(thrown_spell) X`09`7B X`09case 5:`09 /*Teleport Short*/ X`09 teleport_away(monptr, 5); X`09 break; X`09case 6:`09 /*Teleport Long */ X`09 teleport_away(monptr, MAX_SIGHT); X`09 break; X`09case 7:`09 /*Teleport To`09 */ X`09 teleport_to((int)m_ptr->fy, (int)m_ptr->fx); X`09 break; X`09case 8:`09 /*Light Wound`09 */ X`09 if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else X`09 take_hit(damroll(3, 8), ddesc); X`09 break; X`09case 9:`09 /*Serious Wound */ X`09 if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else X`09 take_hit(damroll(8, 8), ddesc); X`09 break; X`09case 10: /*Hold Person`09 */ X`09 if (py.flags.free_act) X`09 msg_print("You are unaffected."); X`09 else if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else if (py.flags.paralysis > 0) X`09 py.flags.paralysis += 2; X`09 else X`09 py.flags.paralysis = randint(5)+4; X`09 break; X`09case 11: /*Cause Blindness*/ X`09 if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else if (py.flags.blind > 0) X`09 py.flags.blind += 6; X`09 else X`09 py.flags.blind += 12 + randint(3); X`09 break; X`09case 12: /*Cause Confuse */ X`09 if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else if (py.flags.confused > 0) X`09 py.flags.confused += 2; X`09 else X`09 py.flags.confused = randint(5) + 3; X`09 break; X`09case 13: /*Cause Fear`09 */ X`09 if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else if (py.flags.afraid > 0) X`09 py.flags.afraid += 2; X`09 else X`09 py.flags.afraid = randint(5) + 3; X`09 break; X`09case 14: /*Summon Monster*/ X`09 (void) strcat(cdesc, "magically summons a monster!"); X`09 msg_print(cdesc); X`09 y = char_row; X`09 x = char_col; X`09 /* in case compact_monster() is called,it needs monptr */ X`09 hack_monptr = monptr; X`09 (void) summon_monster(&y, &x, FALSE); X`09 hack_monptr = -1; X`09 update_mon ((int)cave`5By`5D`5Bx`5D.cptr); X`09 break; X`09case 15: /*Summon Undead*/ X`09 (void) strcat(cdesc, "magically summons an undead!"); X`09 msg_print(cdesc); X`09 y = char_row; X`09 x = char_col; X`09 /* in case compact_monster() is called,it needs monptr */ X`09 hack_monptr = monptr; X`09 (void) summon_undead(&y, &x); X`09 hack_monptr = -1; X`09 update_mon ((int)cave`5By`5D`5Bx`5D.cptr); X`09 break; X`09case 16: /*Slow Person`09 */ X`09 if (py.flags.free_act) X`09 msg_print("You are unaffected."); X`09 else if (player_saves()) X`09 msg_print("You resist the effects of the spell."); X`09 else if (py.flags.slow > 0) X`09 py.flags.slow += 2; X`09 else X`09 py.flags.slow = randint(5) + 3; X`09 break; X`09case 17: /*Drain Mana`09 */ X`09 if (py.misc.cmana > 0) X`09 `7B X`09 disturb (1, 0); X`09 (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc); X`09 msg_print(outval); X`09 if (m_ptr->ml) X`09`09`7B X`09`09 (void) sprintf(outval, "%sappears healthier.", cdesc); X`09`09 msg_print(outval); X`09`09`7D X`09 r1 = (randint((int)r_ptr->level) >> 1) + 1; X`09 if (r1 > py.misc.cmana) X`09`09`7B X`09`09 r1 = py.misc.cmana; X`09`09 py.misc.cmana = 0; X`09`09 py.misc.cmana_frac = 0; X`09`09`7D X`09 else X`09`09py.misc.cmana -= r1; X`09 prt_cmana(); X`09 m_ptr->hp += 6*(r1); X`09 `7D X`09 break; X`09case 20: /*Breath Light */ X`09 (void) strcat(cdesc, "breathes lightning."); X`09 msg_print(cdesc); X`09 breath(GF_LIGHTNING, char_row, char_col, (m_ptr->hp / 4), ddesc, X`09`09 monptr); X`09 break; X`09case 21: /*Breath Gas`09 */ X`09 (void) strcat(cdesc, "breathes gas."); X`09 msg_print(cdesc); X`09 breath(GF_POISON_GAS, char_row, char_col, (m_ptr->hp / 3), ddesc, X`09`09 monptr); X`09 break; X`09case 22: /*Breath Acid`09 */ X`09 (void) strcat(cdesc, "breathes acid."); X`09 msg_print(cdesc); X`09 breath(GF_ACID, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr); X`09 break; X`09case 23: /*Breath Frost */ X`09 (void) strcat(cdesc, "breathes frost."); X`09 msg_print(cdesc); X`09 breath(GF_FROST, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr); X`09 break; X`09case 24: /*Breath Fire`09 */ X`09 (void) strcat(cdesc, "breathes fire."); X`09 msg_print(cdesc); X`09 breath(GF_FIRE, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr); X`09 break; X`09default: X`09 (void) strcat (cdesc, "cast unknown spell."); X`09 msg_print(cdesc); X`09`7D X /* End of spells`09`09`09`09 */ X if (m_ptr->ml) X`09`7B X`09 c_recall`5Bm_ptr->mptr`5D.r_spells `7C= 1L << (thrown_spell-1); X`09 if ((c_recall`5Bm_ptr->mptr`5D.r_spells & CS_FREQ) != CS_FREQ) X`09 c_recall`5Bm_ptr->mptr`5D.r_spells++; X`09 if (death && c_recall`5Bm_ptr->mptr`5D.r_deaths < MAX_SHORT) X`09 c_recall`5Bm_ptr->mptr`5D.r_deaths++; X`09`7D X `7D X`7D X X X/* Places creature adjacent to given location`09`09-RAK-`09*/ X/* Rats and Flys are fun!`09`09`09`09`09 */ Xint multiply_monster(y, x, cr_index, monptr) Xint y, x, cr_index; Xint monptr; X`7B X register int i, j, k; X register cave_type *c_ptr; X int result; X#ifdef ATARIST_MWC X int32u holder; X#endif X X i = 0; X do X `7B X j = y - 2 + randint(3); X k = x - 2 + randint(3); X /* don't create a new creature on top of the old one, that causes X`09 invincible/invisible creatures to appear */ X if (in_bounds(j, k) && (j != y `7C`7C k != x)) X`09`7B X`09 c_ptr = &cave`5Bj`5D`5Bk`5D; X`09 if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) && X`09 (c_ptr->cptr != 1)) X`09 `7B X`09 if (c_ptr->cptr > 1) /* Creature there already?`09*/ X`09`09`7B X`09`09 /* Some critters are cannibalistic!`09 */ X#ifdef ATARIST_MWC X`09`09 holder = CM_EATS_OTHER; X`09`09 if ((c_list`5Bcr_index`5D.cmove & holder) X#else X`09`09 if ((c_list`5Bcr_index`5D.cmove & CM_EATS_OTHER) X#endif X`09`09 /* Check the experience level -CJS- */ X`09`09 && c_list`5Bcr_index`5D.mexp >= X`09`09 c_list`5Bm_list`5Bc_ptr->cptr`5D.mptr`5D.mexp) X`09`09 `7B X`09`09 /* It ate an already processed monster.Handle normally.*/ X`09`09 if (monptr < c_ptr->cptr) X`09`09`09delete_monster((int) c_ptr->cptr); X`09`09 /* If it eats this monster, an already processed mosnter X`09`09`09 will take its place, causing all kinds of havoc. X`09`09`09 Delay the kill a bit. */ X`09`09 else X`09`09`09fix1_delete_monster((int) c_ptr->cptr); X X`09`09 /* in case compact_monster() is called,it needs monptr */ X`09`09 hack_monptr = monptr; X`09`09 /* Place_monster() may fail if monster list full. */ X`09`09 result = place_monster(j, k, cr_index, FALSE); X`09`09 hack_monptr = -1; X`09`09 if (! result) X`09`09`09return FALSE; X`09`09 mon_tot_mult++; X`09`09 return check_mon_lite(j, k); X`09`09 `7D X`09`09`7D X`09 else X`09`09/* All clear, place a monster`09 */ X`09`09`7B X`09`09 /* in case compact_monster() is called,it needs monptr */ X`09`09 hack_monptr = monptr; X`09`09 /* Place_monster() may fail if monster list full. */ X`09`09 result = place_monster(j, k, cr_index, FALSE); X`09`09 hack_monptr = -1; X`09`09 if (! result) X`09`09 return FALSE; X`09`09 mon_tot_mult++; X`09`09 return check_mon_lite(j, k); X`09`09`7D X`09 `7D X`09`7D X i++; X `7D X while (i <= 18); X return FALSE; X`7D X X X/* Move the critters about the dungeon`09`09`09-RAK-`09*/ Xstatic void mon_move(monptr, rcmove) Xint monptr; Xint32u *rcmove; X`7B X register int i, j; X int k, move_test, dir; X#ifdef M_XENIX X /* Avoid 'register' bug. */ X creature_type *r_ptr; X#else X register creature_type *r_ptr; X#endif X register monster_type *m_ptr; X int mm`5B9`5D; X#ifdef ATARIST_MWC X int32u holder; X#endif X int rest_val; X X m_ptr = &m_list`5Bmonptr`5D; X r_ptr = &c_list`5Bm_ptr->mptr`5D; X /* Does the critter multiply?`09`09`09`09 */ X /* rest could be negative, to be safe, only use mod with positive values. V */ X rest_val = abs (py.flags.rest); X#ifdef ATARIST_MWC X holder = CM_MULTIPLY; X if ((r_ptr->cmove & holder) && (MAX_MON_MULT >= mon_tot_mult) && X#else X if ((r_ptr->cmove & CM_MULTIPLY) && (MAX_MON_MULT >= mon_tot_mult) && X#endif X ((rest_val % MON_MULT_ADJ) == 0)) X `7B X k = 0; X for (i = m_ptr->fy-1; i <= m_ptr->fy+1; i++) X`09for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++) X`09 if (in_bounds(i, j) && (cave`5Bi`5D`5Bj`5D.cptr > 1)) X`09 k++; X /* can't call randint with a value of zero, increment counter X`09 to allow creature multiplication */ X if (k == 0) X`09k++; X if ((k < 4) && (randint(k*MON_MULT_ADJ) == 1)) X`09if (multiply_monster((int)m_ptr->fy, (int)m_ptr->fx, X`09`09`09 (int)m_ptr->mptr, monptr)) X#ifdef ATARIST_MWC X`09 *rcmove `7C= holder; X#else X`09 *rcmove `7C= CM_MULTIPLY; X#endif X `7D X move_test = FALSE; X X /* if in wall, must immediately escape to a clear area */ X#ifdef ATARIST_MWC X holder = CM_PHASE; X if (!(r_ptr->cmove & holder) && X#else X if (!(r_ptr->cmove & CM_PHASE) && X#endif X (cave`5Bm_ptr->fy`5D`5Bm_ptr->fx`5D.fval >= MIN_CAVE_WALL)) X `7B X /* If the monster is already dead, don't kill it again! X`09 This can happen for monsters moving faster than the player. They X`09 will get multiple moves, but should not if they die on the first X`09 move. This is only a problem for monsters stuck in rock. */ X if (m_ptr->hp < 0) X`09return; X X k = 0; X dir = 1; X /* note direction of for loops matches direction of keypad from 1 to 9 V*/ X /* do not allow attack against the player */ X /* Must cast fy-1 to signed int, so that a nagative value of i will X`09 fail the comparison. */ X for (i = m_ptr->fy+1; i >= (int)(m_ptr->fy-1); i--) X`09for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++) X`09 `7B X`09 if ((dir != 5) && (cave`5Bi`5D`5Bj`5D.fval <= MAX_OPEN_SPACE) X`09`09&& (cave`5Bi`5D`5Bj`5D.cptr != 1)) X`09 mm`5Bk++`5D = dir; X`09 dir++; X`09 `7D X if (k != 0) X`09`7B X`09 /* put a random direction first */ X`09 dir = randint (k) - 1; X`09 i = mm`5B0`5D; X`09 mm`5B0`5D = mm`5Bdir`5D; X`09 mm`5Bdir`5D = i; X`09 make_move (monptr, mm, rcmove); X`09 /* this can only fail if mm`5B0`5D has a rune of protection */ X`09`7D X /* if still in a wall, let it dig itself out, but also apply some X`09 more damage */ X if (cave`5Bm_ptr->fy`5D`5Bm_ptr->fx`5D.fval >= MIN_CAVE_WALL) X`09`7B X`09 /* in case the monster dies, may need to call fix1_delete_monster() X`09 instead of delete_monsters() */ X`09 hack_monptr = monptr; X`09 i = mon_take_hit(monptr, damroll (8, 8)); X`09 hack_monptr = -1; X`09 if (i >= 0) X`09 `7B X`09 msg_print("You hear a scream muffled by rock!"); X`09 prt_experience(); X`09 `7D X`09 else X`09 `7B X`09 msg_print ("A creature digs itself out from the rock!"); X`09 (void) twall ((int)m_ptr->fy, (int)m_ptr->fx, 1, 0); X`09 `7D X`09`7D X return; /* monster movement finished */ X `7D X /* Creature is confused? Chance it becomes un-confused */ X else if (m_ptr->confused) X `7B X mm`5B0`5D = randint(9); X mm`5B1`5D = randint(9); X mm`5B2`5D = randint(9); X mm`5B3`5D = randint(9); X mm`5B4`5D = randint(9); X /* don't move him if he is not supposed to move! */ X if (!(r_ptr->cmove & CM_ATTACK_ONLY)) X`09make_move(monptr, mm, rcmove); X if (randint(8) == 1) X`09m_ptr->confused = FALSE; X move_test = TRUE; X `7D X /* Creature may cast a spell */ X else if (r_ptr->spells != 0) X mon_cast_spell(monptr, &move_test); X if (!move_test) X `7B X /* 75% random movement */ X if ((r_ptr->cmove & CM_75_RANDOM) && (randint(100) < 75)) X`09`7B X`09 mm`5B0`5D = randint(9); X`09 mm`5B1`5D = randint(9); X`09 mm`5B2`5D = randint(9); X`09 mm`5B3`5D = randint(9); X`09 mm`5B4`5D = randint(9); X`09 *rcmove `7C= CM_75_RANDOM; X`09 make_move(monptr, mm, rcmove); X`09`7D X /* 40% random movement */ X else if ((r_ptr->cmove & CM_40_RANDOM) && (randint(100) < 40)) X`09`7B X`09 mm`5B0`5D = randint(9); X`09 mm`5B1`5D = randint(9); X`09 mm`5B2`5D = randint(9); +-+-+-+-+-+-+-+- END OF PART 7 +-+-+-+-+-+-+-+-