/*************************************************************************** * combat.c added by Charles Marchant * Jan 12 1995 to replace old combat */ #include "mstruct.h" #include "mextern.h" #ifdef DMALLOC #include "/usr/local/include/dmalloc.h" #endif int update_combat(crt_ptr) creature *crt_ptr; { creature *att_ptr; room *rom_ptr; etag *ep; ctag *cp; char *enemy; int n = 0,rtn = 0,p = 0,fd,t = 0; rom_ptr = crt_ptr->parent_rom; ep = crt_ptr->first_enm; while(1) { enemy = ep->enemy; if(!enemy) ep = ep->next_tag; if(!ep) return 0; if(enemy) break; } att_ptr = find_crt(crt_ptr, rom_ptr->first_ply,enemy, 1); if(!att_ptr) att_ptr = find_crt(crt_ptr, rom_ptr->first_mon,enemy, 1); if(!att_ptr) { if(!find_who(enemy)) del_enm_crt(enemy, crt_ptr); else end_enm_crt(enemy, crt_ptr); return 0; } if(is_charm_crt(crt_ptr->name, att_ptr)&& F_ISSET(crt_ptr, MCHARM)) p = 1; crt_ptr->NUMHITS++; n=20; if(F_ISSET(crt_ptr, MMAGIO)) n=crt_ptr->proficiency[0]; if(F_ISSET(crt_ptr, MMAGIC) && mrand(1, 100) <= n && !p) { rtn = crt_spell(crt_ptr, att_ptr); if(rtn == 2) return 1; else if(rtn == 1) n = 21; else n = crt_ptr->thaco - att_ptr->armor/10; } else { n = crt_ptr->thaco - att_ptr->armor/10; n = MAX(n, 1); } if(mrand(1,20) >= n && !p) { fd = att_ptr->fd; ANSI(fd, RED); if(F_ISSET(crt_ptr, MBRETH) && mrand(1,30)<5) { if (F_ISSET(crt_ptr, MBRWP1) && !F_ISSET(crt_ptr, MBRWP2)) n = bw_spit_acid(crt_ptr,att_ptr); else if (F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2)) n = bw_poison(crt_ptr,att_ptr); else if (!F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2)) n = bw_cone_frost(crt_ptr,att_ptr); else n = bw_cone_fire(crt_ptr,att_ptr); } else if(F_ISSET(crt_ptr, MENEDR) && mrand(1,100)< 25) n = power_energy_drain(crt_ptr,att_ptr); else n = mdice(crt_ptr); att_ptr->hpcur -= n; print(fd, "%M hit you for %d damage.\n",crt_ptr, n); /* Output only when monster v. monster */ if (att_ptr->type == MONSTER && crt_ptr->type == MONSTER) { broadcast_rom2(fd,crt_ptr->fd,att_ptr->rom_num,"%M hits %m.", crt_ptr, att_ptr); add_enm_crt(crt_ptr->name, att_ptr); } add_enm_dmg(att_ptr->name, crt_ptr,n); if(F_ISSET(crt_ptr, MPOISS) && mrand(1,100) <= 15) { print(fd, "%M poisoned you.\n",crt_ptr); F_SET(att_ptr, PPOISN); } if(F_ISSET(crt_ptr, MDISEA) && mrand(1,100) <= 15) { print(fd, "%M infects you.\n",crt_ptr); F_SET(att_ptr, PDISEA); } if(F_ISSET(crt_ptr, MBLNDR) && mrand(1,100) <= 15) { print(fd, "%M blinds your eyes.\n",crt_ptr); F_SET(att_ptr, PBLIND); } if(F_ISSET(crt_ptr, MDISIT) && mrand(1,100) <= 15) dissolve_item(att_ptr,crt_ptr); ANSI(fd, WHITE); n = choose_item(att_ptr); if(n) { if(--att_ptr->ready[n-1]->shotscur<1) { print(fd,"Your %s fell apart.\n",att_ptr->ready[n-1]->name); broadcast_rom(fd,att_ptr->rom_num,"%M's %s fell apart.", att_ptr,att_ptr->ready[n-1]->name); add_obj_crt(att_ptr->ready[n-1],att_ptr); att_ptr->ready[n-1] = 0; compute_ac(att_ptr); } } if(att_ptr->type == PLAYER && !F_ISSET(att_ptr, PNOAAT) && !p) { rtn = attack_crt(att_ptr, crt_ptr); if(rtn) return 1; } else { if(LT(att_ptr,LT_ATTCK) < t) { rtn = attack_crt(att_ptr, crt_ptr); att_ptr->lasttime[LT_ATTCK].ltime = t; if(rtn) return 1; } } if(att_ptr->hpcur < 1) { ANSI(fd, MAGENTA); print(fd, "%M killed you.\n", crt_ptr); ANSI(fd, WHITE); if(att_ptr->type == MONSTER && crt_ptr->type == MONSTER) { broadcast_rom2(att_ptr->fd,crt_ptr->fd,att_ptr->rom_num,"%M killed %m.", crt_ptr, att_ptr); } die(att_ptr, crt_ptr); return 1; } else if(F_ISSET(att_ptr, PWIMPY)) { if(att_ptr->hpcur <= att_ptr->WIMPYVALUE) { flee(att_ptr); return 1; } } else if(F_ISSET(att_ptr, PFEARS)) { int ff; ff = 40 + (1- (att_ptr->hpcur/att_ptr->hpmax))*40 + bonus[att_ptr->constitution]*3 + (att_ptr->class == PALADIN) ? -10 : 0; if(ff < mrand(1,100)) { flee(att_ptr); } } } else if(n <= 20 && !p) { ANSI(att_ptr->fd, CYAN); print(att_ptr->fd, "%M missed you.\n", crt_ptr); /* Output only when monster v. monster */ if (att_ptr->type == MONSTER && crt_ptr->type == MONSTER) { broadcast_rom2(att_ptr->fd,crt_ptr->fd, att_ptr->rom_num,"%M misses %m.", crt_ptr, att_ptr); add_enm_crt(crt_ptr->name, att_ptr); } ANSI(att_ptr->fd, WHITE); if(att_ptr->type == PLAYER && !F_ISSET(att_ptr, PNOAAT)) { rtn = attack_crt(att_ptr, crt_ptr); if(rtn) return 1; } else { if(LT(att_ptr,LT_ATTCK) < t) { rtn = attack_crt(att_ptr, crt_ptr); att_ptr->lasttime[LT_ATTCK].ltime = t; if(rtn) return 1; } } } return 0; } /*************************************************************************** * breath weapons */ int bw_spit_acid(crt_ptr,vic_ptr) creature *crt_ptr; creature *vic_ptr; { int fd; int n; fd = vic_ptr->fd; print(fd, "%M spits acid on you!\n", crt_ptr); broadcast_rom(fd,vic_ptr->rom_num,"%M spits acid on %m!",crt_ptr,vic_ptr); n = dice(crt_ptr->level, 3, 0); return n; } int bw_poison(crt_ptr,vic_ptr) creature *crt_ptr; creature *vic_ptr; { int fd; int n; fd = vic_ptr->fd; print(fd, "%M breathes poisonous gas on you!\n", crt_ptr); broadcast_rom(fd, vic_ptr->rom_num, "%M breathes poisonous gas on %m!", crt_ptr, vic_ptr); n = dice(crt_ptr->level, 2, 1); print(fd, "%M poisoned you.\n", crt_ptr); F_SET(vic_ptr, PPOISN); return n; } int bw_cone_frost(crt_ptr,vic_ptr) creature *crt_ptr; creature *vic_ptr; { int fd; int n; fd = vic_ptr->fd; print(fd, "%M breathes frost on you!\n", crt_ptr); broadcast_rom(fd,vic_ptr->rom_num,"%M breathes frost on %m!", crt_ptr,vic_ptr); if(F_ISSET(vic_ptr, PRCOLD)) n = dice(crt_ptr->level, 2, 0); else n = dice(crt_ptr->level, 4, 0); return n; } int bw_cone_fire(crt_ptr,vic_ptr) creature *crt_ptr; creature *vic_ptr; { int fd; int n; fd = vic_ptr->fd; print(fd, "%M breathes fire on you!\n", crt_ptr); broadcast_rom(fd, vic_ptr->rom_num,"%M breathes fire on %m!", crt_ptr, vic_ptr); if(F_ISSET(vic_ptr, PRFIRE)) n = dice(crt_ptr->level, 2, 0); else n = dice(crt_ptr->level, 4, 0); return n; } int power_energy_drain(crt_ptr,vic_ptr) creature *crt_ptr; creature *vic_ptr; { int n; int fd; fd = vic_ptr->fd; n = dice(crt_ptr->level, 5, (crt_ptr->level)*5); n = MAX(0,MIN(n,vic_ptr->experience)); print(fd, "%M drains your experience!\n", crt_ptr); broadcast_rom2(crt_ptr->fd,vic_ptr->fd, vic_ptr->rom_num, "%M energy drains %m!", crt_ptr, vic_ptr); vic_ptr->experience -= n; lower_prof(vic_ptr,n); print(fd, "%M drains you for %d experience.\n",crt_ptr,n); return 0; }