void killed(struct monst *mtmp) { #define NEW_SCORING int tmp; int tmp2; int nk; int x; int y; struct permonst *mdat = mtmp->data; if(mtmp->cham != 0) { mdat = PM_CHAM; } if(Blind != 0) { pline("You destroy it!"); } else { if(mtmp->mtame != 0) { pline("You destroy %s!", amonnam(mtmp, "poor")); } else { pline("You destroy %s!", monnam(mtmp)); } } if(u.umconf != 0) { if(Blind == 0) { pline("Your hands stop clowing blue."); u.umconf = 0; } } /* Count killed monsters */ #define MAXMONNO 100 /* In case we cannot find it in mons */ nk = 1; /* Index in mons array (if not 'd', '@', ...) */ tmp = mdat - mons; if((tmp >= 0) && (tmp < (CMNUM + 2))) { extern char fut_geno[]; ++u.nr_killed[tmp]; nk = u.nr_killed[tmp]; if((nk > MAXMONNO) && (index(fut_geno, mdat->mlet) == 0)) { charcat(fut_geno, mdat->mlet); } } /* Punish bad behaviour */ if(mdat->mlet == '@') { Telepat = 0; u.uluck -= 2; } if((mtmp->mpeaceful != 0) || (mtmp->mtame != 0)) { --u.uluck; } if(mdat->mlet == 'u') { u.uluck -= 5; } /* 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) != 0) { tmp += (2 * mdat->mlevel); } if(index("DeV&P", mdat->mlet) != 0) { tmp += (7 * mdat->mlevel); } if(mdat->mlevel > 6) { tmp += 50; } #ifdef NEW_SCORING /* * ------- Recent addition: make number of points decrease * when this is not the first of this kind */ int ul = u.ulevel; int ml = mdat->mlevel; /* Points are given based on present and future level */ if(ul < 14) { for(tmp2 = 0; (tmp2 == 0) || ((ul + tmp2) <= ml); ++tmp2) { if(tmp <= 0) { if(((u.uexp + 1) + ((tmp + (0)) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) { ++ul; if(ul == 14) { break; } } } else { if(((u.uexp + 1) + ((tmp + (4 << (tmp2 - 1))) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) { ++ul; if(ul == 14) { break; } } } } } tmp2 = (ml - ul) - 1; if(tmp2 < 0) { tmp = (tmp + (0)) / nk; } else { tmp = (tmp + (4 << tmp2)) / nk; } if(tmp == 0) { tmp = 1; } /* * Note: ul is not necessarily the future value of u.ulevel * ------- End of recent valuation change ------- */ #endif u.uexp += tmp; u.urexp += (4 * tmp); flags.botl = 1; while((u.ulevel < 14) && (u.uexp >= (10 * pow(2, u.ulevel - 1)))) { ++u.ulevel; pline("Welcome to level %d.", u.ulevel); tmp = rnd(30); 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(WAND_SYM, WAN_DIGGING, x, y); /* * if(cansee(x, y) != 0) { * atl(x, y, fobj->olet); * } */ stackobj(fobj); } #ifndef NOWORM else if(tmp == 'w') { mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y); stackobj(fobj); } #endif else { if((letter(tmp) == 0) || (rn2(3) == 0)) { tmp = 0; } if(levl[x][y].typ >= DOOR) { /* Might be a mimic in wall */ if((x != u.ux) || (y != u.uy)) { /* Might be here after swallowed */ if((index("NTVm&", mdat->mlet) != NULL) || (rn2(5) != 0)) { mkobj_at(tmp, x, y); if(cansee(x, y) != 0) { atl(x, y, fobj->olet); } stackobj(fobj); } } } } }
int dopay(void) { long ltmp; struct bill_x *bp; struct monst *shkp; int pass, tmp; multi = 0; inshop(); for (shkp = fmon; shkp; shkp = shkp->nmon) if (shkp->isshk && dist(shkp->mx, shkp->my) < 3) break; if (!shkp && u.uinshop && inroom(shopkeeper->mx, shopkeeper->my) == ESHK(shopkeeper)->shoproom) shkp = shopkeeper; if (!shkp) { pline("There is nobody here to receive your payment."); return (0); } ltmp = ESHK(shkp)->robbed; if (shkp != shopkeeper && NOTANGRY(shkp)) { if (!ltmp) pline("You do not owe %s anything.", monnam(shkp)); else if (!u.ugold) pline("You have no money."); else { long ugold = u.ugold; if (u.ugold > ltmp) { pline("You give %s the %ld gold pieces he asked for.", monnam(shkp), ltmp); pay(ltmp, shkp); } else { pline("You give %s all your gold.", monnam(shkp)); pay(u.ugold, shkp); } if (ugold < ltmp / 2) pline("Unfortunately, he doesn't look satisfied."); else { ESHK(shkp)->robbed = 0; ESHK(shkp)->following = 0; if (ESHK(shkp)->shoplevel != dlevel) { /* For convenience's sake, let him disappear */ shkp->minvent = 0; /* %% */ shkp->mgold = 0; mondead(shkp); } } } return (1); } if (!ESHK(shkp)->billct) { pline("You do not owe %s anything.", monnam(shkp)); if (!u.ugold) { pline("Moreover, you have no money."); return (1); } if (ESHK(shkp)->robbed) { #define min(a, b) ((a < b) ? a : b) pline("But since his shop has been robbed recently,"); pline("you %srepay %s's expenses.", (u.ugold < ESHK(shkp)->robbed) ? "partially " : "", monnam(shkp)); pay(min(u.ugold, ESHK(shkp)->robbed), shkp); ESHK(shkp)->robbed = 0; return (1); } if (ANGRY(shkp)) { pline("But in order to appease %s,", amonnam(shkp, "angry")); if (u.ugold >= 1000) { ltmp = 1000; pline(" you give him 1000 gold pieces."); } else { ltmp = u.ugold; pline(" you give him all your money."); } pay(ltmp, shkp); if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ) || rn2(3)) { pline("%s calms down.", Monnam(shkp)); NOTANGRY(shkp) = 1; } else pline("%s is as angry as ever.", Monnam(shkp)); } return (1); } if (shkp != shopkeeper) { impossible("dopay: not to shopkeeper?"); if (shopkeeper) setpaid(); return (0); } for (pass = 0; pass <= 1; pass++) { tmp = 0; while (tmp < ESHK(shopkeeper)->billct) { bp = &bill[tmp]; if (!pass && !bp->useup) { tmp++; continue; } if (!dopayobj(bp)) return (1); bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } pline("Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); NOTANGRY(shopkeeper) = 1; return (1); }
// What does the return value indicate?? Boolean dopay() { Long ltmp; bill_t *bp; monst_t *shkp; Short pass, tmp; multi = 0; inshop(); for (shkp = fmon ; shkp ; shkp = shkp->nmon) if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3) break; if (!shkp && you.uinshop && inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom) shkp = shopkeeper; if (!shkp) { message("There is nobody here to receive your payment."); return false; } ltmp = ESHK(shkp)->robbed; if (shkp != shopkeeper && NOTANGRY(shkp)) { if (!ltmp) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); } else if (!you.ugold) { message("You have no money."); } else { Long ugold = you.ugold; if (you.ugold > ltmp) { StrPrintF(ScratchBuffer, "You give %s the %ld gold pieces he asked for.", monnam(shkp), ltmp); message(ScratchBuffer); pay(ltmp, shkp); } else { StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp)); message(ScratchBuffer); pay(you.ugold, shkp); } if (ugold < ltmp/2) { message("Unfortunately, he doesn't look satisfied."); } else { ESHK(shkp)->robbed = 0; ESHK(shkp)->following = false; if (ESHK(shkp)->shoplevel != dlevel) { /* For convenience's sake, let him disappear */ shkp->minvent = NULL; /* %% */ // xxx leak? shkp->mgold = 0; mondead(shkp); } } } return true; } if (!ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); if (!you.ugold) { message("Moreover, you have no money."); return true; } if (ESHK(shkp)->robbed) { message("But since his shop has been robbed recently,"); StrPrintF(ScratchBuffer, "you%srepay %s's expenses.", (you.ugold < ESHK(shkp)->robbed) ? " partially " : " ", monnam(shkp)); message(ScratchBuffer); pay(min(you.ugold, ESHK(shkp)->robbed), shkp); ESHK(shkp)->robbed = 0; return true; } if (ANGRY(shkp)) { StrPrintF(ScratchBuffer, "But in order to appease %s,", amonnam(shkp, "angry")); message(ScratchBuffer); if (you.ugold >= 1000) { ltmp = 1000; message(" you give him 1000 gold pieces."); } else { ltmp = you.ugold; message(" you give him all your money."); } pay(ltmp, shkp); if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ) || rund(3)){ StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp)); message(ScratchBuffer); shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } else { StrPrintF(ScratchBuffer, "%s is as angry as ever.", Monnam(shkp)); message(ScratchBuffer); } } return true; } if (shkp != shopkeeper) { message("BUG: dopay: not to shopkeeper?"); if (shopkeeper) setpaid(); return false; } for (pass = 0 ; pass <= 1 ; pass++) { tmp = 0; while (tmp < ESHK(shopkeeper)->billct) { bp = &bill[tmp]; if (!pass && !bp->useup) { tmp++; continue; } if (!dopayobj(bp)) return true; bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; return true; }