home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / steal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  9.3 KB  |  386 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)steal.c    3.1    93/05/30    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. STATIC_DCL int NDECL(stealarm);
  8.  
  9. #ifdef OVLB
  10. static const char * FDECL(equipname, (struct obj *));
  11.  
  12. static const char *
  13. equipname(otmp)
  14. register struct obj *otmp;
  15. {
  16.     return (
  17. #ifdef TOURIST
  18.         (otmp == uarmu) ? "shirt" :
  19. #endif
  20.         (otmp == uarmf) ? "boots" :
  21.         (otmp == uarms) ? "shield" :
  22.         (otmp == uarmg) ? "gloves" :
  23.         (otmp == uarmc) ? "cloak" :
  24.         (otmp == uarmh) ? "helmet" : "armor");
  25. }
  26.  
  27. long        /* actually returns something that fits in an int */
  28. somegold()
  29. {
  30. #ifdef LINT    /* long conv. ok */
  31.     return(0L);
  32. #else
  33.     return (long)( (u.ugold < 100) ? u.ugold :
  34.         (u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
  35. #endif
  36. }
  37.  
  38. void
  39. stealgold(mtmp)
  40. register struct monst *mtmp;
  41. {
  42.     register struct obj *gold = g_at(u.ux, u.uy);
  43.     register long tmp;
  44.  
  45.     if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) {
  46.         mtmp->mgold += gold->quan;
  47.         delobj(gold);
  48.         newsym(u.ux, u.uy);
  49.         pline("%s quickly snatches some gold from between your %s!",
  50.             Monnam(mtmp), makeplural(body_part(FOOT)));
  51.         if(!u.ugold || !rn2(5)) {
  52.         if (!tele_restrict(mtmp)) rloc(mtmp);
  53.         mtmp->mflee = 1;
  54.         }
  55.     } else if(u.ugold) {
  56.         u.ugold -= (tmp = somegold());
  57.         Your("purse feels lighter.");
  58.         mtmp->mgold += tmp;
  59.         if (!tele_restrict(mtmp)) rloc(mtmp);
  60.         mtmp->mflee = 1;
  61.         flags.botl = 1;
  62.     }
  63. }
  64.  
  65. /* steal armor after you finish taking it off */
  66. unsigned int stealoid;        /* object to be stolen */
  67. unsigned int stealmid;        /* monster doing the stealing */
  68.  
  69. STATIC_OVL int
  70. stealarm()
  71. {
  72.     register struct monst *mtmp;
  73.     register struct obj *otmp;
  74.  
  75.     for(otmp = invent; otmp; otmp = otmp->nobj)
  76.       if(otmp->o_id == stealoid) {
  77.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  78.           if(mtmp->m_id == stealmid) {
  79.           if(otmp->unpaid) 
  80.                subfrombill(otmp, shop_keeper(*u.ushops));
  81.           freeinv(otmp);
  82.           pline("%s steals %s!", Monnam(mtmp), doname(otmp));
  83.           mpickobj(mtmp,otmp);
  84.           mtmp->mflee = 1;
  85.           if (!tele_restrict(mtmp)) rloc(mtmp);
  86.         break;
  87.           }
  88.         break;
  89.       }
  90.     stealoid = 0;
  91.     return 0;
  92. }
  93.  
  94. /* Returns 1 when something was stolen (or at least, when N should flee now)
  95.  * Returns -1 if the monster died in the attempt
  96.  * Avoid stealing the object stealoid
  97.  */
  98. int
  99. steal(mtmp)
  100. struct monst *mtmp;
  101. {
  102.     register struct obj *otmp;
  103.     register int tmp;
  104.     register int named = 0;
  105.  
  106.     /* the following is true if successful on first of two attacks. */
  107.     if(!monnear(mtmp, u.ux, u.uy)) return(0);
  108.  
  109.     if(!invent
  110. #ifdef POLYSELF
  111.            || (inv_cnt() == 1 && uskin)
  112. #endif
  113.                         ){
  114.         /* Not even a thousand men in armor can strip a naked man. */
  115.         if(Blind)
  116.           pline("Somebody tries to rob you, but finds nothing to steal.");
  117.         else
  118.           pline("%s tries to rob you, but she finds nothing to steal!",
  119.         Monnam(mtmp));
  120.         return(1);    /* let her flee */
  121.     }
  122.  
  123.     if(Adornment & LEFT_RING) {
  124.         otmp = uleft;
  125.         goto gotobj;
  126.     } else if(Adornment & RIGHT_RING) {
  127.         otmp = uright;
  128.         goto gotobj;
  129.     }
  130.  
  131.     tmp = 0;
  132.     for(otmp = invent; otmp; otmp = otmp->nobj)
  133.         if((!uarm || otmp != uarmc)
  134. #ifdef POLYSELF
  135.                     && otmp != uskin
  136. #endif
  137.                             )
  138.         tmp += ((otmp->owornmask &
  139.             (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
  140.     tmp = rn2(tmp);
  141.     for(otmp = invent; otmp; otmp = otmp->nobj)
  142.         if((!uarm || otmp != uarmc)
  143. #ifdef POLYSELF
  144.                     && otmp != uskin
  145. #endif
  146.                             )
  147.         if((tmp -= ((otmp->owornmask &
  148.             (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0)
  149.             break;
  150.     if(!otmp) {
  151.         impossible("Steal fails!");
  152.         return(0);
  153.     }
  154.     /* can't steal gloves while wielding - so steal the wielded item. */
  155.     if (otmp == uarmg && uwep)
  156.         otmp = uwep;
  157.     /* can't steal armor while wearing cloak - so steal the cloak. */
  158.     else if(otmp == uarm && uarmc) otmp = uarmc;
  159. #ifdef TOURIST
  160.     else if(otmp == uarmu && uarmc) otmp = uarmc;
  161.     else if(otmp == uarmu && uarm) otmp = uarm;
  162. #endif
  163. gotobj:
  164.     if(otmp->o_id == stealoid) return(0);
  165.  
  166. #ifdef WALKIES
  167.     if(otmp->otyp == LEASH && otmp->leashmon) o_unleash(otmp);
  168. #endif
  169.  
  170.     if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
  171.         switch(otmp->oclass) {
  172.         case TOOL_CLASS:
  173.             Blindf_off(otmp);
  174.             break;
  175.         case AMULET_CLASS:
  176.             Amulet_off();
  177.             break;
  178.         case RING_CLASS:
  179.             Ring_gone(otmp);
  180.             break;
  181.         case ARMOR_CLASS:
  182.             /* Stop putting on armor which has been stolen. */
  183.             if (donning(otmp)) {
  184.               cancel_don();
  185.               if (otmp == uarm)  (void) Armor_off();
  186.               /* else if (otmp == uarmc) (void) Cloak_off(); */
  187.               else if (otmp == uarmf) (void) Boots_off();
  188.               else if (otmp == uarmg) (void) Gloves_off();
  189.               else if (otmp == uarmh) (void) Helmet_off();
  190.               /* else if (otmp == uarms) (void) Shield_off(); */
  191.               else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  192.               break;
  193.             }
  194.             { int curssv = otmp->cursed;
  195.             otmp->cursed = 0;
  196.             stop_occupation();
  197.             if(flags.female)
  198.                 pline("%s charms you.  You gladly %s your %s.",
  199.                   Blind ? "She" : Monnam(mtmp),
  200.                   curssv ? "let her take" : "hand over",
  201.                   equipname(otmp));
  202.             else
  203.                 pline("%s seduces you and %s off your %s.",
  204.                   Blind ? "It" : Adjmonnam(mtmp, "beautiful"),
  205.                   curssv ? "helps you to take" : "you start taking",
  206.                   equipname(otmp));
  207.             named++;
  208.             /* the following is to set multi for later on */
  209.             nomul(-objects[otmp->otyp].oc_delay);
  210.  
  211.             if (otmp == uarm)  (void) Armor_off();
  212.             else if (otmp == uarmc) (void) Cloak_off();
  213.             else if (otmp == uarmf) (void) Boots_off();
  214.             else if (otmp == uarmg) (void) Gloves_off();
  215.             else if (otmp == uarmh) (void) Helmet_off();
  216.             else if (otmp == uarms) (void) Shield_off();
  217.             else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  218.             otmp->cursed = curssv;
  219.             if(multi < 0){
  220.                 /*
  221.                 multi = 0;
  222.                 nomovemsg = 0;
  223.                 afternmv = 0;
  224.                 */
  225.                 stealoid = otmp->o_id;
  226.                 stealmid = mtmp->m_id;
  227.                 afternmv = stealarm;
  228.                 return(0);
  229.             }
  230.             break;
  231.             }
  232.         default:
  233.             impossible("Tried to steal a strange worn thing.");
  234.         }
  235.     }
  236.     else if(otmp == uwep) uwepgone();
  237.  
  238.     if(otmp == uball) unpunish();
  239.  
  240.     freeinv(otmp);
  241.     pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
  242.     (void) snuff_candle(otmp);
  243.     mpickobj(mtmp,otmp);
  244.     if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  245.         && !resists_ston(mtmp->data)
  246. #ifdef MUSE
  247.         && !(mtmp->misc_worn_check & W_ARMG)
  248. #endif
  249.         ) {
  250.         pline("%s turns to stone.", Monnam(mtmp));
  251.         stoned = TRUE;
  252.         xkilled(mtmp, 0);
  253.         return -1;
  254.     }
  255.     return((multi < 0) ? 0 : 1);
  256. }
  257.  
  258. #endif /* OVLB */
  259. #ifdef OVL1
  260.  
  261. void
  262. mpickobj(mtmp,otmp)
  263. register struct monst *mtmp;
  264. register struct obj *otmp;
  265. {
  266.     if (otmp->otyp == GOLD_PIECE) {    /* from floor etc. -- not inventory */
  267.     mtmp->mgold += otmp->quan;
  268.     obfree(otmp, (struct obj *)0);
  269.     } else {
  270.     otmp->nobj = mtmp->minvent;
  271.     mtmp->minvent = otmp;
  272.     }
  273. }
  274.  
  275. #endif /* OVL1 */
  276. #ifdef OVLB
  277.  
  278. void
  279. stealamulet(mtmp)
  280. register struct monst *mtmp;
  281. {
  282.     register struct obj *otmp;
  283.     register int    real, fake;
  284.  
  285.     /* select the artifact to steal */
  286.     if(u.uhave.amulet) {
  287.         real = AMULET_OF_YENDOR ;
  288.         fake = FAKE_AMULET_OF_YENDOR ;
  289. #ifdef MULDGN
  290.     } else if(u.uhave.questart) {
  291.         real = fake = 0;        /* gcc -Wall lint */
  292.         for(otmp = invent; otmp; otmp = otmp->nobj)
  293.             if(is_quest_artifact(otmp)) goto snatch_it;
  294. #endif
  295.     } else if(u.uhave.bell) {
  296.         real = BELL_OF_OPENING;
  297.         fake = BELL;
  298.     } else if(u.uhave.book) {
  299.         real = SPE_BOOK_OF_THE_DEAD;
  300.         fake = 0;
  301.     } else if(u.uhave.menorah) {
  302.         real = CANDELABRUM_OF_INVOCATION;
  303.         fake = 0;
  304.     } else return;    /* you have nothing of special interest */
  305.  
  306. /*    If we get here, real and fake have been set up. */
  307.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  308.         if(otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz)) {
  309.         /* might be an imitation one */
  310. snatch_it:
  311. #ifdef MULDGN
  312.         if (otmp->oclass == ARMOR_CLASS) adj_abon(otmp, -(otmp->spe));
  313. #endif
  314.         setnotworn(otmp);
  315.         freeinv(otmp);
  316.         mpickobj(mtmp,otmp);
  317.         pline("%s stole %s!", Monnam(mtmp), doname(otmp));
  318.         if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
  319.             rloc(mtmp);
  320.         return;
  321.         }
  322.     }
  323. }
  324.  
  325. #endif /* OVLB */
  326. #ifdef OVL0
  327.  
  328. /* release the objects the creature is carrying */
  329. void
  330. relobj(mtmp,show,is_pet)
  331. register struct monst *mtmp;
  332. register int show;
  333. boolean is_pet;        /* If true, pet should keep wielded/worn items */
  334. {
  335.     register struct obj *otmp, *otmp2;
  336.     register int omx = mtmp->mx, omy = mtmp->my;
  337. #ifdef MUSE
  338.     struct obj *backobj = 0;
  339.     struct obj *wep = MON_WEP(mtmp);
  340. #endif
  341.  
  342.     otmp = mtmp->minvent;
  343.     mtmp->minvent = 0;
  344.     for (; otmp; otmp = otmp2) {
  345.         otmp2 = otmp->nobj;
  346. #ifdef MUSE
  347.         if (otmp->owornmask || otmp == wep) {
  348.             if (is_pet) { /* skip worn/wielded item */
  349.                 if (!backobj) {
  350.                     mtmp->minvent = backobj = otmp;
  351.                 } else {
  352.                     backobj->nobj = otmp;
  353.                     backobj = backobj->nobj;
  354.                 }
  355.                 continue;
  356.             }
  357.             mtmp->misc_worn_check &= ~(otmp->owornmask);
  358.             otmp->owornmask = 0L;
  359.         }
  360.         if (backobj) backobj->nobj = otmp->nobj;
  361. #endif
  362.         if (is_pet && cansee(omx, omy) && flags.verbose)
  363.             pline("%s drops %s.", Monnam(mtmp),
  364.                     distant_name(otmp, doname));
  365.         if (flooreffects(otmp, omx, omy, "fall")) continue;
  366.         place_object(otmp, omx, omy);
  367.         otmp->nobj = fobj;
  368.         fobj = otmp;
  369.         stackobj(fobj);
  370.     }
  371.     if (mtmp->mgold) {
  372.         register long g = mtmp->mgold;
  373.         mkgold(g, omx, omy);
  374.         if (is_pet && cansee(omx, omy) && flags.verbose)
  375.             pline("%s drops %ld gold piece%s.", Monnam(mtmp),
  376.                 g, plur(g));
  377.         mtmp->mgold = 0L;
  378.     }
  379.     if (show & cansee(omx, omy))
  380.         newsym(omx, omy);
  381. }
  382.  
  383. #endif /* OVL0 */
  384.  
  385. /*steal.c*/
  386.