📄 hack.mon.c
字号:
if(mtmp->wormno) worm_move(mtmp);#endif NOWORM } else { if(msym == 'u' && rn2(2)){ rloc(mtmp); return(0); }#ifndef NOWORM if(mtmp->wormno) worm_nomove(mtmp);#endif NOWORM }postmov: if(mmoved == 1) { if(mintrap(mtmp) == 2) /* he died */ return(2); if(likegold) mpickgold(mtmp); if(likegems) mpickgems(mtmp); if(mtmp->mhide) mtmp->mundetected = 1; } pmon(mtmp); return(mmoved);}mpickgold(mtmp) register struct monst *mtmp; {register struct gold *gold; while(gold = g_at(mtmp->mx, mtmp->my)){ mtmp->mgold += gold->amount; freegold(gold); if(levl[mtmp->mx][mtmp->my].scrsym == '$') newsym(mtmp->mx, mtmp->my); }}mpickgems(mtmp) register struct monst *mtmp; {register struct obj *otmp; for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp->olet == GEM_SYM) if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){ freeobj(otmp); mpickobj(mtmp, otmp); if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM) newsym(mtmp->mx, mtmp->my); /* %% */ return; /* pick only one object */ }}/* return number of acceptable neighbour positions */mfndpos(mon,poss,info,flag)register struct monst *mon;coord poss[9];int info[9], flag;{ register int x,y,nx,ny,cnt = 0,ntyp; register struct monst *mtmp; int nowtyp; boolean pool; x = mon->mx; y = mon->my; nowtyp = levl[x][y].typ; pool = (mon->data->mlet == ';');nexttry: /* eels prefer the water, but if there is no water nearby, they will crawl over land */ if(mon->mconf) { flag |= ALLOW_ALL; flag &= ~NOTONL; } for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) if(nx != x || ny != y) if(isok(nx,ny)) if(!IS_ROCK(ntyp = levl[nx][ny].typ)) if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR))) if((ntyp == POOL) == pool) { info[cnt] = 0; if(nx == u.ux && ny == u.uy){ if(!(flag & ALLOW_U)) continue; info[cnt] = ALLOW_U; } else if(mtmp = m_at(nx,ny)){ if(!(flag & ALLOW_M)) continue; info[cnt] = ALLOW_M; if(mtmp->mtame){ if(!(flag & ALLOW_TM)) continue; info[cnt] |= ALLOW_TM; } } if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { if(flag & NOGARLIC) continue; info[cnt] |= NOGARLIC; } if(sobj_at(SCR_SCARE_MONSTER, nx, ny) || (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { if(!(flag & ALLOW_SSM)) continue; info[cnt] |= ALLOW_SSM; } if(sobj_at(ENORMOUS_ROCK, nx, ny)) { if(!(flag & ALLOW_ROCK)) continue; info[cnt] |= ALLOW_ROCK; } if(!Invis && online(nx,ny)){ if(flag & NOTONL) continue; info[cnt] |= NOTONL; } /* we cannot avoid traps of an unknown kind */ { register struct trap *ttmp = t_at(nx, ny); register int tt; if(ttmp) { tt = 1 << ttmp->ttyp; if(mon->mtrapseen & tt){ if(!(flag & tt)) continue; info[cnt] |= tt; } } } poss[cnt].x = nx; poss[cnt].y = ny; cnt++; } if(!cnt && pool && nowtyp != POOL) { pool = FALSE; goto nexttry; } return(cnt);}dist(x,y) int x,y; { return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy));}poisoned(string, pname)register char *string, *pname;{ register int i; if(Blind) pline("It was poisoned."); else pline("The %s was poisoned!",string); if(Poison_resistance) { pline("The poison doesn't seem to affect you."); return; } i = rn2(10); if(i == 0) { u.uhp = -1; pline("I am afraid the poison was deadly ..."); } else if(i <= 5) { losestr(rn1(3,3)); } else { losehp(rn1(10,6), pname); } if(u.uhp < 1) { killer = pname; done("died"); }}mondead(mtmp)register struct monst *mtmp;{ relobj(mtmp,1); unpmon(mtmp); relmon(mtmp); unstuck(mtmp); if(mtmp->isshk) shkdead(mtmp); if(mtmp->isgd) gddead();#ifndef NOWORM if(mtmp->wormno) wormdead(mtmp);#endif NOWORM monfree(mtmp);}/* called when monster is moved to larger structure */replmon(mtmp,mtmp2)register struct monst *mtmp, *mtmp2;{ relmon(mtmp); monfree(mtmp); mtmp2->nmon = fmon; fmon = mtmp2; if(u.ustuck == mtmp) u.ustuck = mtmp2; if(mtmp2->isshk) replshk(mtmp,mtmp2); if(mtmp2->isgd) replgd(mtmp,mtmp2);}relmon(mon)register struct monst *mon;{ register struct monst *mtmp; if(mon == fmon) fmon = fmon->nmon; else { for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ; mtmp->nmon = mon->nmon; }}/* we do not free monsters immediately, in order to have their name available shortly after their demise */struct monst *fdmon; /* chain of dead monsters, need not to be saved */monfree(mtmp) register struct monst *mtmp; { mtmp->nmon = fdmon; fdmon = mtmp;}dmonsfree(){register struct monst *mtmp; while(mtmp = fdmon){ fdmon = mtmp->nmon; free((char *) mtmp); }}unstuck(mtmp)register struct monst *mtmp;{ if(u.ustuck == mtmp) { if(u.uswallow){ u.ux = mtmp->mx; u.uy = mtmp->my; u.uswallow = 0; setsee(); docrt(); } u.ustuck = 0; }}killed(mtmp)register struct monst *mtmp;{#ifdef lint#define NEW_SCORING#endif lint register int tmp,tmp2,nk,x,y; register struct permonst *mdat; extern long newuexp(); if(mtmp->cham) mtmp->data = PM_CHAMELEON; mdat = mtmp->data; if(Blind) pline("You destroy it!"); else { pline("You destroy %s!", mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); } if(u.umconf) { if(!Blind) pline("Your hands stop glowing blue."); u.umconf = 0; } /* count killed monsters */#define MAXMONNO 100 nk = 1; /* in case we cannot find it in mons */ tmp = mdat - mons; /* index in mons array (if not 'd', '@', ...) */ if(tmp >= 0 && tmp < CMNUM+2) { extern char fut_geno[]; u.nr_killed[tmp]++; if((nk = u.nr_killed[tmp]) > MAXMONNO && !index(fut_geno, mdat->mlet)) charcat(fut_geno, mdat->mlet); } /* punish bad behaviour */ if(mdat->mlet == '@') Telepat = 0, u.uluck -= 2; if(mtmp->mpeaceful || mtmp->mtame) u.uluck--; if(mdat->mlet == 'u') u.uluck -= 5; if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN; /* give experience points */ tmp = 1 + mdat->mlevel * mdat->mlevel; if(mdat->ac < 3) tmp += 2*(7 - mdat->ac); if(index("AcsSDXaeRTVWU&In:P", mdat->mlet)) tmp += 2*mdat->mlevel; if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel); if(mdat->mlevel > 6) tmp += 50; if(mdat->mlet == ';') tmp += 1000;#ifdef NEW_SCORING /* ------- recent addition: make nr of points decrease when this is not the first of this kind */ { int ul = u.ulevel; int ml = mdat->mlevel; if(ul < 14) /* points are given based on present and future level */ for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk >= 10*pow((unsigned)(ul-1))) if(++ul == 14) break; tmp2 = ml - ul -1; tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk; if(!tmp) tmp = 1; } /* note: ul is not necessarily the future value of u.ulevel */ /* ------- end of recent valuation change ------- */#endif NEW_SCORING more_experienced(tmp,0); flags.botl = 1; while(u.ulevel < 14 && u.uexp >= newuexp()){ pline("Welcome to experience level %u.", ++u.ulevel); tmp = rnd(10); if(tmp < 3) tmp = rnd(10); u.uhpmax += tmp; u.uhp += tmp; flags.botl = 1; } /* dispose of monster and make cadaver */ x = mtmp->mx; y = mtmp->my; mondead(mtmp); tmp = mdat->mlet; if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */ /* note: the dead minotaur will be on top of it! */ mksobj_at(WAN_DIGGING, x, y); /* if(cansee(x,y)) atl(x,y,fobj->olet); */ stackobj(fobj); } else#ifndef NOWORM if(tmp == 'w') { mksobj_at(WORM_TOOTH, x, y); stackobj(fobj); } else#endif NOWORM if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0; if(ACCESSIBLE(levl[x][y].typ)) /* might be mimic in wall or dead eel*/ if(x != u.ux || y != u.uy) /* might be here after swallowed */ if(index("NTVm&",mdat->mlet) || rn2(5)) { register struct obj *obj2 = mkobj_at(tmp,x,y); if(cansee(x,y)) atl(x,y,obj2->olet); stackobj(obj2); }}kludge(str,arg)register char *str,*arg;{ if(Blind) { if(*str == '%') pline(str,"It"); else pline(str,"it"); } else pline(str,arg);}rescham() /* force all chameleons to become normal */{ register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->cham) { mtmp->cham = 0; (void) newcham(mtmp, PM_CHAMELEON); }}newcham(mtmp,mdat) /* make a chameleon look like a new monster */ /* returns 1 if the monster actually changed */register struct monst *mtmp;register struct permonst *mdat;{ register mhp, hpn, hpd; if(mdat == mtmp->data) return(0); /* still the same monster */#ifndef NOWORM if(mtmp->wormno) wormdead(mtmp); /* throw tail away */#endif NOWORM if (u.ustuck == mtmp) { if (u.uswallow) { u.uswallow = 0; u.uswldtim = 0; mnexto (mtmp); docrt (); prme (); } u.ustuck = 0; } hpn = mtmp->mhp; hpd = (mtmp->data->mlevel)*8; if(!hpd) hpd = 4; mtmp->data = mdat; mhp = (mdat->mlevel)*8; /* new hp: same fraction of max as before */ mtmp->mhp = 2 + (hpn*mhp)/hpd; hpn = mtmp->mhpmax; mtmp->mhpmax = 2 + (hpn*mhp)/hpd; mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;#ifndef NOWORM if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp); /* perhaps we should clear mtmp->mtame here? */#endif NOWORM unpmon(mtmp); /* necessary for 'I' and to force pmon */ pmon(mtmp); return(1);}mnexto(mtmp) /* Make monster mtmp next to you (if possible) */struct monst *mtmp;{ extern coord enexto(); coord mm; mm = enexto(u.ux, u.uy); mtmp->mx = mm.x; mtmp->my = mm.y; pmon(mtmp);}ishuman(mtmp) register struct monst *mtmp; { return(mtmp->data->mlet == '@');}setmangry(mtmp) register struct monst *mtmp; { if(!mtmp->mpeaceful) return; if(mtmp->mtame) return; mtmp->mpeaceful = 0; if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp));}/* not one hundred procent correct: now a snake may hide under an invisible object */canseemon(mtmp)register struct monst *mtmp;{ return((!mtmp->minvis || See_invisible) && (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my)) && cansee(mtmp->mx, mtmp->my));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -