-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X if ( (testdir`5B2`5D = mon_ptr->dir) == -testdir`5B0`5D) testdir`5B0`5D V = testdir`5B1`5D; X if ( testdir`5B2`5D == -testdir`5B1`5D) testdir`5B1`5D = -testdir`5B1`5D V; X `7D X else `7B X if ( mon_ptr->posy > ppos.y) testdir`5B0`5D = NORTH; X else testdir`5B0`5D = SOUTH; X if ( mon_ptr->posx > ppos.x) testdir`5B1`5D = WEST; X else testdir`5B1`5D = EAST; X/* contiue moving the monster in the same direction (not back and forth) */ X if ( (testdir`5B2`5D = mon_ptr->dir) == -testdir`5B0`5D) testdir`5B0`5D V = testdir`5B1`5D; X if ( testdir`5B2`5D == -testdir`5B1`5D) testdir`5B1`5D = -testdir`5B1`5D V; X `7D `20 X testdir`5B3`5D = -testdir`5B0`5D; X testdir`5B4`5D = -testdir`5B1`5D; X X movedir = testdir`5B0`5D; X testchar = get_move( movedir, i, &newx, &newy); X if ( testchar == '@') `7B `09/* First choice -- attack */ X monster_attack( i, SWORD);`20 X return;`20 X `7D X else while( (!mon_ptr->fly && (testchar == WALL `7C`7C testchar == WATER)) X `7C`7C isamonster( testchar) `7C`7C testchar == ARENA) `7B X`09 movedir = testdir`5Bk++`5D; X testchar = get_move( movedir, i, &newx, &newy); X`09 if ( k > 4) break; `09 X `7D /* End while */ X X/* All choices for movement have been covered, reset monster direction */ X mon_ptr->dir = movedir; X `20 X if ( testchar == '@') `7B `09/* trapped monster in cove -- attack */ X monster_attack( i, SWORD);`20 X return;`20 X `7D X/* Can't run over walls if trapped */ X else if ( testchar == WALL && !mon_ptr->fly) return;`20 X X if ( !mon_ptr->fly) `7B X if ( testchar == MINE) X explode( mon_ptr->posy, mon_ptr->posx, MINE, map`5Bnewy`5D`5Bnewx`5D.nu Vmber, NULL); X if ( testchar == PIT) X do_attack( i, 77, NULL, NULL); X `7D X if ( mon_ptr->dead) `7B`09`09`09`09/* monster was killed */ X if ( monkilled == MAXMONSTERS*level) `7B`09 X map`5Bnewy`5D`5Bnewx`5D.mapchar = KEY; X map`5Bnewy`5D`5Bnewx`5D.number = 1; X sprintf(dropped,"%s drops the key as it writhes in agony and dies.", X`09`09 `09`09`09`09mon_names`5Bmon_ptr->n_num`5D); X prt_msg(dropped); X prt_char( KEY, newy, newx); X `7D X else `7B X if ( testchar == SPACE `7C`7C testchar == MINE) `7B X map`5Bnewy`5D`5Bnewx`5D.mapchar = CASH; X map`5Bnewy`5D`5Bnewx`5D.number = 1; X `7D X else `7B X sprintf(dropped,"%s's gold was lost when he died.",mon_names`5Bmon_ptr V->n_num`5D); X prt_msg(dropped); X map`5Bnewy`5D`5Bnewx`5D.mapchar = testchar; X map`5Bnewy`5D`5Bnewx`5D.number = 1; X `7D X prt_char(map`5Bnewy`5D`5Bnewx`5D.mapchar,newy,newx); X `7D X if ( mon_ptr->number == rival_num && in_arena) `7B X can_exit = TRUE; X map`5Bnewy`5D`5Bnewx`5D.mapchar = HAXE; X map`5Bnewy`5D`5Bnewx`5D.number = 1; X map`5Ba_posy`5D`5Ba_posx`5D.mapchar = BONES; X prt_char( map`5Ba_posy`5D`5Ba_posx`5D.mapchar, a_posy, a_posx);`20 X `7D X map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.mapchar = mon_ptr->underchar; X map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.number = 1; X prt_char(map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.mapchar, X mon_ptr->posy,mon_ptr->pos Vx);`20 X `7D /* End IF (dead) */ Xelse `7B `09`09`09`09`09`09/* monster was not killed */ X map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.mapchar = mon_ptr->underchar; X map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.number = 1; X prt_char(map`5Bmon_ptr->posy`5D`5Bmon_ptr->posx`5D.mapchar, X mon_ptr->posy,mon_ptr->pos Vx);`20 X map`5Bnewy`5D`5Bnewx`5D.mapchar = mon_ptr->mon_char; X map`5Bnewy`5D`5Bnewx`5D.number = i; X prt_char(map`5Bnewy`5D`5Bnewx`5D.mapchar,newy,newx); X X mon_ptr->posy = newy; X mon_ptr->posx = newx; X if ( eat( testchar) && !mon_ptr->fly) mon_ptr->underchar = SPACE; X else mon_ptr->underchar = testchar; X `7D /* End (dead) ELSE */ X `7D /* End movedist IF */ X else `7B /* if monster is hurting and it's time to heal, add one to the hea Vlth */ X if ( (hlspeed = mon_ptr->hlspd*mon_ptr->speed) < 1) hlspeed = 1; X if ( moves % hlspeed == 0 && mon_ptr->health < .8*3*(i+5))`20 X mon_ptr->health++; X `7D /* End movedist ELSE */ X X`7D /* End firing ELSE */ X`7D X X Xresurrect( num) Xint num; X`7B X Xmonsters`5Bnum`5D.dead = FALSE; Xmonsters`5Bnum`5D.underchar = SPACE; Xmonsters`5Bnum`5D.health = 3*(monsters`5Bnum`5D.n_num+5); X/* give him a new position */ Xdo `7B`09`09`09 `20 X monsters`5Bnum`5D.posy = random( MAXROWS);`20 X monsters`5Bnum`5D.posx = random( MAXCOLS); X `7Dwhile( !ISCLEAR( map`5Bmonsters`5Bnum`5D.posy`5D`5Bmonsters`5Bnum`5D.pos Vx`5D.mapchar)); X`7D X X Xshort read_monsters() X`7B XFILE *mfile; Xint mon_num, y, x, i, max_m_ct; Xint count = 0; Xshort ret = 0; Xchar dummy`5B80`5D; X Xmonsters_struct *m;`09/* new monster type read in */ Xmonsters_struct *nm;`09/* next monster number of that type */ X Xif ( (mfile = fopen( monfile,"r")) != NULL) `7B X do `7B`20 X if (count++ > 10) `7B X printf("\nNo ending comment in monsters datafile.");`20 X exit(0);`20 X `7D X fgets(dummy,80,mfile); X `7D while( strstr(dummy,"**/") == 0); X mon_num = -1; X do `7B X/* Note: monster 'type' defined by "n_num" (name number read in from file) * V/ X mon_num++; X m = &monsters`5Bmon_num`5D; X fscanf(mfile,"%d %d %d %c %d %d %d %d %d %d %d %d %d %d %d %d", X `09 &m->max_mon,&m->n_num,&m->a_num,&m->mon_char,&m->dam,&m->health, X `09 &m->follow,&m->speed,&m->firec,&m->range,&m->reschance,&m->f_num, X`09 &m->dead,&m->fly,&m->magic,&m->hlspd); X do `7B X x = random(MAXCOLS); X y = random(MAXROWS); X `7D while( !ISCLEAR( map`5By`5D`5Bx`5D.mapchar)); X m->posy = y;`20 X m->posx = x; X m->underchar = SPACE; X m->dir = NORTH; X m->number = mon_num; X max_m_ct = m->max_mon; X X/* Create the maximum number of monsters per 'type' -- eg. 4 ants, 3 clams * V/ X while( max_m_ct-- > 1) `7B`09`09/* if only one, skip next procedure */ X mon_num++; X nm = &monsters`5Bmon_num`5D; /* next monster number */ X nm->number = mon_num; X nm->max_mon = m->max_mon; X nm->n_num = m->n_num; X nm->a_num = m->a_num; X nm->mon_char = m->mon_char; X nm->dam = m->dam; X nm->health = m->health; X nm->follow = m->follow; X nm->speed = m->speed; X nm->firec = m->firec; X nm->range = m->range; X nm->reschance = m->reschance; X nm->f_num = m->f_num; X nm->dead = m->dead; X nm->fly = m->fly; X nm->magic = m->magic; X nm->hlspd = m->hlspd; X do `7B X x = random(MAXCOLS); X y = random(MAXROWS); X `7D while( !ISCLEAR( map`5By`5D`5Bx`5D.mapchar)); X nm->posy = y;`20 X nm->posy = y;`20 X nm->posx = x; X nm->underchar = SPACE; X nm->dir = NORTH; X `7D /* End while */ X `7D while( m->n_num < DIFFMON-1);`09/* use n_num as a counter for DIFFMON V */ Xfclose( mfile); X`7D Xelse ret = E_OPENMON; Xreturn( ret); X`7D X X Xprt_monsters()`09`09`09`09`09/* for restored games */ X`7B Xint i, j, k; Xint limit; X Xi = 0; Xk = 0; Xwhile( i++ < MAXMONSTERS*level) `7B X limit = monsters`5Bk`5D.max_mon; X for (j=0; j< limit; j++) `7B X map`5Bmonsters`5Bk`5D.posy`5D`5Bmonsters`5Bk`5D.posx`5D.mapchar = monst Vers`5Bk`5D.mon_char; X map`5Bmonsters`5Bk`5D.posy`5D`5Bmonsters`5Bk`5D.posx`5D.number = k; X prt_char( monsters`5Bk`5D.mon_char, monsters`5Bk`5D.posy, monsters`5Bk` V5D.posx); X k++; X `7D X `7D /* End while */ X`7D X X X Xmonster_attack( mon_num, obj)`09`09/* this is for monster attacks */ Xint mon_num; Xchar obj; X`7B Xint damage_done; Xchar op_msg`5B80`5D; Xchar mon_attack`5B80`5D; X Xif ( obj == ARROW)`20 X sprintf(mon_attack,"%s %s.",mon_names`5Bmonsters`5Bmon_num`5D.n_num`5D, X `09`09`09 monfire`5Bmonsters`5Bmon_num`5D.f_num`5D); Xelse X sprintf(mon_attack,"%s %s.",mon_names`5Bmonsters`5Bmon_num`5D.n_num`5D, X`09`09`09`09 attacks`5Bmonsters`5Bmon_num`5D.a_num`5D); Xdamage_done = monsters`5Bmon_num`5D.dam + random( monsters`5Bmon_num`5D.dam) V; Xif ( operator) `7B`20 X sprintf(op_msg,"MSock: %d",damage_done); X prt_msg(op_msg); X`7D Xprt_msg(mon_attack); Xtake_damage( damage_done, mon_names`5Bmonsters`5Bmon_num`5D.n_num`5D); X`7D X X Xdo_attack( mon_num, bp_num, spell, dir) Xint mon_num, bp_num, dir; Xchar spell; X`7B Xint add_damage, add_wealth, damage_done, miss_chance, mymiss, rnd, dy, dx; Xchar condmsg`5B80`5D; Xchar mymiss_msg`5B30`5D; Xchar op_msg`5B80`5D; Xchar killed`5B80`5D; Xchar player_attack`5B80`5D; Xchar dropped`5B80`5D; Xchar weapon; X Xmonsters_struct *mon_ptr; Xmon_ptr = &monsters`5Bmon_num`5D; X Xswitch( dir) `7B X case UP: dx = 0; dy = -1; break; X case DOWN: dx = 0; dy = 1; break; X case LEFT: dx = -1; dy = 0; break; X case RIGHT: dx = 1; dy = 0; break; X`7D /* End switch */ Xif ( bp_num < MAXINVEN) /* Not a PIT or MINE */ X if ( ping_monster( ppos.x+dx, ppos.y+dy, mon_num)) return; X Xif ( bp_num == 99) weapon = ORB; Xelse if ( bp_num == 999) weapon = ARROW; Xelse if ( bp_num == 88) weapon = MINE; Xelse if ( bp_num == 77) weapon = PIT; Xelse weapon = BACKPACK`5Bbp_num`5D.invenchar; Xif ( bp_num != 0) `7B X if ( weapon == ARROW) `7B X sprintf(player_attack,"The bolt finds its mark and hits %s.", X `09`09`09`09`09`09mon_names`5Bmon_ptr->n_num`5D); X add_damage = BUSE / (level*2); X damage_done = random( add_damage)+1 + ITEM_PROPS`5Bidentify( ARROW)`5D`5 VBDAMAGE`5D; X `7D`20 X else if ( weapon == ORB) `7B X if ( spell == 'a') `7B X sprintf(player_attack,"The lightning bolt strikes %s!", X `09`09`09`09`09`09mon_names`5Bmon_ptr->n_num`5D); X add_damage = (INT - 13)/3; X `7D X else if ( spell == 'b') `7B X sprintf(player_attack,"The fireball envelops %s!", X `09`09`09`09`09`09mon_names`5Bmon_ptr->n_num`5D); X add_damage = (INT - 13)/2; X `7D X else if ( spell == 'c') `7B X sprintf(player_attack,"The acid ball envelops %s!", X `09`09`09`09`09`09mon_names`5Bmon_ptr->n_num`5D); X add_damage = (INT - 13)*2; X `7D X else `7B X sprintf(player_attack,"%s explodes into dust!",mon_names`5Bmon_ptr->n_nu Vm`5D); X add_damage = 1000; X `7D X damage_done = random( add_damage) + ITEM_PROPS`5Bidentify( ORB)`5D`5BDAM VAGE`5D; `20 X switch( BACKPACK`5Bcheck_inven( ORB)`5D.condition) `7B X`09case 1: prt_msg("The Orb's power is very slight."); X`09 sprintf(player_attack,"The effect of the spell is greatly reduced V."); X`09`09damage_done *= 0.25; break; X`09case 2: prt_msg("The spell is cast at one half normal power."); X`09 sprintf(player_attack,"The effect of the spell is reduced."); X`09`09damage_done *= 0.5; break; X`09case 3: prt_msg("The Orb is weakened in power."); X`09 sprintf(player_attack,"The effect of the spell is reduced."); X`09`09damage_done *= 0.75; break; X`09case 4: prt_msg("The power of the Orb is slightly low."); X`09 sprintf(player_attack,"The effect of the spell is reduced slightl Vy."); X`09`09damage_done *= 0.9; X `7D /* End switch */ X `7D X else if ( weapon == MINE) `7B X sprintf(player_attack,"%s hits the mine!!",mon_names`5Bmon_ptr->n_num`5D V); X damage_done = random( ITEM_PROPS`5Bidentify( MINE)`5D`5BDAMAGE`5D) + 1; X `7D X else if ( weapon == PIT) `7B X sprintf(player_attack,"You hear %s wail in pain as it falls into a pit." V, X`09 mon_names`5Bmon_ptr->n_num`5D); X damage_done = random( 10) + 1; X `7D X else `7B X add_damage = (STR - 14)/2 + random( 4); X damage_done = random( add_damage)+1 + ITEM_PROPS`5Bidentify( weapon)`5D` V5BDAMAGE`5D; X if ( BACKPACK`5Bbp_num`5D.condition < 1) damage_done = 1; X else damage_done *= (0.20 * BACKPACK`5Bbp_num`5D.condition); X if ( damage_done <= 1) X sprintf(player_attack,"Your %s deflects harmlessly off %s.", X`09 BACKPACK`5Bbp_num`5D.name,mon_names`5Bmon_ptr->n_num`5D); X else if ( damage_done < 5) X sprintf(player_attack,"Your %s strikes %s.", X`09 BACKPACK`5Bbp_num`5D.name,mon_names`5Bmon_ptr->n_num`5D); X else if ( damage_done < 9) X sprintf(player_attack,"You pummel %s with your %s.", X`09 mon_names`5Bmon_ptr->n_num`5D,BACKPACK`5Bbp_num`5D.name); X else if ( damage_done < 12) X sprintf(player_attack,"You sever %s's disgusting body with your %s.", X`09 mon_names`5Bmon_ptr->n_num`5D,BACKPACK`5Bbp_num`5D.name); X else X sprintf(player_attack,"You utterly demolish %s with your %s!", X`09 mon_names`5Bmon_ptr->n_num`5D,BACKPACK`5Bbp_num`5D.name); X X if ( (miss_chance = DEX - 10) < 0) miss_chance = 0; X mymiss = random( ITEM_PROPS`5Bidentify( weapon)`5D`5BWEIGHT`5D/10)+1; X if ( operator) `7B X sprintf(mymiss_msg,"Miss chance: %d",mymiss); X prt_msg(mymiss_msg); X `7D X if ( miss_chance < mymiss) `7B X sprintf(player_attack,"You swing wildly at the %s and miss!",mon_names V`5Bmon_ptr->n_num`5D); X damage_done = 0; X `7D X else if ( random( 100) < 8 && BACKPACK`5Bbp_num`5D.condition < 2) `7B X sprintf(player_attack,"Your %s shatters into a thousand pieces.", X`09 `09 BACKPACK`5Bbp_num`5D.name); X`09 break_weapon( bp_num); X `7D X else if ( random( 100) < 5) `7B X sprintf(player_attack,"Your %s finds its way to %s's heart.", X`09 BACKPACK`5Bbp_num`5D.name,mon_names`5Bmon_ptr->n_num`5D); X damage_done = 1000;`09/* automatic kill */ X `7D X `7D X`7D Xelse `7B`09`09`09`09`09`09/* bare handed attack */ X sprintf(player_attack,"You graze %s with your fists.", X`09`09`09`09 mon_names`5Bmon_ptr->n_num`5D); X add_damage = (STR - 14)/2; X damage_done = random( add_damage)+1 + ITEM_PROPS`5BHANDS`5D`5BDAMAGE`5D; X`7D Xif ( operator) `7B`20 X sprintf(op_msg,"PSock: %d",damage_done); X prt_msg(op_msg); X`7D X Xif ( random( 100) < 8 && damage_done > 0 && bp_num != 0) `7B X if ( weapon == ORB) bp_num = check_inven( ORB); X else if ( weapon == ARROW) bp_num = check_inven( BOW); X if ( weapon != MINE && weapon != PIT && weapon != ORB) `7B X BACKPACK`5Bbp_num`5D.condition--; X prt_msg("Your weapon's condition is worsening."); X `7D X`7D X Xprt_msg(player_attack); +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-