home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / mor4873s.lzh / STORE2.C < prev    next >
C/C++ Source or Header  |  1988-12-14  |  27KB  |  1,084 lines

  1. #include <stdio.h>
  2.  
  3. #include "constant.h"
  4. #include "config.h"
  5. #include "types.h"
  6. #include "externs.h"
  7.  
  8. #ifdef USG
  9. #include <string.h>
  10. #else
  11. #include <strings.h>
  12. #endif
  13.  
  14. #ifdef sun   /* correct SUN stupidity in the stdio.h file */
  15. char *sprintf();
  16. #endif
  17.  
  18. double chr_adj();
  19.  
  20. /* Comments vary...                    -RAK-    */
  21. /* Comment one : Finished haggling                */
  22. prt_comment1()
  23. {
  24.   msg_flag = FALSE;
  25.   switch(randint(14))
  26.     {
  27.     case 1: msg_print("Done!"); break;
  28.     case 2: msg_print("Accepted!"); break;
  29.     case 3: msg_print("Fine..."); break;
  30.     case 4: msg_print("Agreed!"); break;
  31.     case 5: msg_print("Okay..."); break;
  32.     case 6: msg_print("Taken!"); break;
  33.     case 7: msg_print("You drive a hard bargain, but taken..."); break;
  34.     case 8: msg_print("You'll force me bankrupt, but it's a deal..."); break;
  35.     case 9: msg_print("Sigh...  I'll take it..."); break;
  36.     case 10: msg_print("My poor sick children may starve, but done!"); break;
  37.     case 11: msg_print("Finally!  I accept..."); break;
  38.     case 12: msg_print("Robbed again..."); break;
  39.     case 13: msg_print("A pleasure to do business with you!"); break;
  40.     case 14: msg_print("My spouse will skin me, but accepted."); break;
  41.     }
  42. }
  43.  
  44.  
  45. /* %A1 is offer, %A2 is asking...        */
  46. prt_comment2(offer, asking, final)
  47. bigint_t offer, asking; int final;
  48. {
  49.   vtype comment;
  50.  
  51.   if (final > 0)
  52.     switch(randint(3))
  53.       {
  54.       case 1:
  55.     (void) strcpy(comment,"%A2 is my final offer; take it or leave it...");
  56.     break;
  57.       case 2:
  58.     (void) strcpy(comment, "I'll give you no more than %A2.");
  59.     break;
  60.       case 3:
  61.     (void) strcpy(comment, "My patience grows thin...  %A2 is final.");
  62.     break;
  63.       }
  64.   else
  65.     switch(randint(16))
  66.       {
  67.       case 1:
  68.     (void) strcpy(comment,
  69.               "%A1 for such a fine item?  HAH!  No less than %A2.");
  70.     break;
  71.       case 2:
  72.     (void) strcpy(comment, "%A1 is an insult!  Try %A2 gold pieces...");
  73.     break;
  74.       case 3:
  75.     (void) strcpy(comment,
  76.               "%A1???  Thou wouldst rob my poor starving children?");
  77.     break;
  78.       case 4:
  79.     (void) strcpy(comment, "Why, I'll take no less than %A2 gold pieces.");
  80.     break;
  81.       case 5:
  82.     (void) strcpy(comment, "Ha!  No less than %A2 gold pieces.");
  83.     break;
  84.       case 6:
  85.     (void) strcpy(comment,
  86.               "Thou knave!  No less than %A2 gold pieces.");
  87.     break;
  88.       case 7:
  89.     (void) strcpy(comment, "%A1 is far too little; how about %A2?");
  90.     break;
  91.       case 8:
  92.     (void) strcpy(comment, "I paid more than %A1 for it myself, try %A2.");
  93.     break;
  94.       case 9:
  95.     (void) strcpy(comment,
  96.               "%A1?  Are you mad???  How about %A2 gold pieces?");
  97.     break;
  98.       case 10:
  99.     (void) strcpy(comment,
  100.               "As scrap this would bring %A1.  Try %A2 in gold.");
  101.     break;
  102.       case 11:
  103.     (void) strcpy(comment,
  104.               "May the fleas of 1000 orcs molest you.  I want %A2.");
  105.     break;
  106.       case 12:
  107.     (void) strcpy(comment,
  108.               "My mother you can get for %A1, this costs %A2.");
  109.     break;
  110.       case 13:
  111.     (void) strcpy(comment,
  112.               "May your chickens grow lips.  I want %A2 in gold!");
  113.     break;
  114.       case 14:
  115.     (void) strcpy(comment,
  116.               "Sell this for such a pittance?  Give me %A2 gold.");
  117.     break;
  118.       case 15:
  119.     (void) strcpy(comment,
  120.               "May the Balrog find you tasty!  %A2 gold pieces?");
  121.     break;
  122.       case 16:
  123.     (void) strcpy(comment,"Your mother was a Troll!  %A2 or I'll tell...");
  124.     break;
  125.       }
  126.   insert_lnum(comment, "%A1", offer, FALSE);
  127.   insert_lnum(comment, "%A2", asking, FALSE);
  128.   msg_print(comment);
  129. }
  130.  
  131.  
  132. prt_comment3(offer, asking, final)
  133. bigint_t offer, asking; int final;
  134. {
  135.   vtype comment;
  136.  
  137.   if (final > 0)
  138.     switch(randint(3))
  139.       {
  140.       case 1:
  141.     (void) strcpy(comment,
  142.               "I'll pay no more than %A1; take it or leave it.");
  143.     break;
  144.       case 2:
  145.     (void) strcpy(comment, "You'll get no more than %A1 from me...");
  146.     break;
  147.       case 3:
  148.     (void) strcpy(comment, "%A1 and that's final.");
  149.     break;
  150.       }
  151.   else
  152.     switch(randint(15))
  153.       {
  154.       case 1:
  155.     (void) strcpy(comment,"%A2 for that piece of junk?  No more than %A1");
  156.     break;
  157.       case 2:
  158.     (void) strcpy(comment, "For %A2 I could own ten of those.  Try %A1.");
  159.     break;
  160.       case 3:
  161.     (void) strcpy(comment, "%A2?  NEVER!  %A1 is more like it...");
  162.     break;
  163.       case 4:
  164.     (void) strcpy(comment,
  165.               "Let's be reasonable... How about %A1 gold pieces?");
  166.     break;
  167.       case 5:
  168.     (void) strcpy(comment, "%A1 gold for that junk, no more...");
  169.     break;
  170.       case 6:
  171.     (void) strcpy(comment, "%A1 gold pieces and be thankful for it!");
  172.     break;
  173.       case 7:
  174.     (void) strcpy(comment, "%A1 gold pieces and not a copper more...");
  175.     break;
  176.       case 8:
  177.     (void) strcpy(comment, "%A2 gold?  HA!  %A1 is more like it...");
  178.     break;
  179.       case 9:
  180.     (void) strcpy(comment, "Try about %A1 gold...");
  181.     break;
  182.       case 10:
  183.     (void) strcpy(comment,
  184.               "I wouldn't pay %A2 for your children, try %A1.");
  185.     break;
  186.       case 11:
  187.     (void) strcpy(comment, "*CHOKE* For that!?  Let's say %A1.");
  188.     break;
  189.       case 12:
  190.     (void) strcpy(comment, "How about %A1?");
  191.     break;
  192.       case 13:
  193.     (void) strcpy(comment, "That looks war surplus!  Say %A1 gold.");
  194.     break;
  195.       case 14:
  196.     (void) strcpy(comment, "I'll buy it as scrap for %A1.");
  197.     break;
  198.       case 15:
  199.     (void) strcpy(comment, "%A2 is too much; let us say %A1 gold.");
  200.     break;
  201.       }
  202.   insert_lnum(comment, "%A1", offer, FALSE);
  203.   insert_lnum(comment, "%A2", asking, FALSE);
  204.   msg_print(comment);
  205. }
  206.  
  207.  
  208. /* Kick 'da bum out...                    -RAK-    */
  209. prt_comment4()
  210. {
  211.   msg_flag = FALSE;
  212.   switch(randint(5))
  213.     {
  214.     case 1:
  215.       msg_print("ENOUGH!  Thou hast abused me once too often!");
  216.       msg_print("Out of my place!");
  217.       break;
  218.     case 2:
  219.       msg_print("THAT DOES IT!  You shall waste my time no more!");
  220.       msg_print("out... Out... OUT!!!");
  221.       break;
  222.     case 3:
  223.       msg_print("This is getting nowhere...  I'm going home!");
  224.       msg_print("Come back tomorrow...");
  225.       break;
  226.     case 4:
  227.       msg_print("BAH!  No more shall you insult me!");
  228.       msg_print("Leave my place...  Begone!");
  229.       break;
  230.     case 5:
  231.       msg_print("Begone!  I have had enough abuse for one day.");
  232.       msg_print("Come back when thou art richer...");
  233.       break;
  234.     }
  235.   /* make sure player sees last message, before he is kicked out of store */
  236.   msg_print(" ");
  237.   msg_flag = FALSE;
  238. }
  239.  
  240.  
  241. prt_comment5()
  242. {
  243.   switch(randint(10))
  244.     {
  245.     case 1: msg_print("You will have to do better than that!"); break;
  246.     case 2: msg_print("That's an insult!"); break;
  247.     case 3: msg_print("Do you wish to do business or not?"); break;
  248.     case 4: msg_print("Hah!  Try again..."); break;
  249.     case 5: msg_print("Ridiculous!"); break;
  250.     case 6: msg_print("You've got to be kidding!"); break;
  251.     case 7: msg_print("You'd better be kidding!!"); break;
  252.     case 8: msg_print("You try my patience."); break;
  253.     case 9: msg_print("I don't hear you."); break;
  254.     case 10: msg_print("Hmmm, nice weather we're having..."); break;
  255.     }
  256. }
  257.  
  258.  
  259. prt_comment6()
  260. {
  261.   switch(randint(5))
  262.     {
  263.     case 1: msg_print("I must have heard you wrong..."); break;
  264.     case 2: msg_print("What was that?"); break;
  265.     case 3: msg_print("I'm sorry, say that again..."); break;
  266.     case 4: msg_print("What did you say?"); break;
  267.     case 5: msg_print("Sorry, what was that again?"); break;
  268.     }
  269. }
  270.  
  271.  
  272. /* Displays the set of commands                -RAK-    */
  273. display_commands()
  274. {
  275.   prt("You may:", 20, 0);
  276.   prt(" p) Purchase an item.           b) Browse store's inventory.", 21, 0);
  277.   prt(" s) Sell an item.               i) Inventory and Equipment Lists.",
  278.       22, 0);
  279.   prt("ESC) Exit from Building.       ^R) Redraw the screen.", 23, 0);
  280. }
  281.  
  282.  
  283. /* Displays the set of commands                -RAK-    */
  284. haggle_commands(typ)
  285. int typ;
  286. {
  287.   if (typ == -1)
  288.     prt("Specify an asking-price in gold pieces.", 21, 0);
  289.   else
  290.     prt("Specify an offer in gold pieces.", 21, 0);
  291.   prt("ESC) Quit Haggling.", 22, 0);
  292.   prt("", 23, 0);  /* clear last line */
  293. }
  294.  
  295.  
  296. /* Displays a store's inventory                -RAK-    */
  297. display_inventory(store_num, start)
  298. int store_num, start;
  299. {
  300.   register store_type *s_ptr;
  301.   register treasure_type *i_ptr;
  302.   register int i, j, stop;
  303.   bigvtype out_val1, out_val2;
  304.  
  305.   s_ptr = &store[store_num];
  306.   i = (start % 12);
  307.   stop = ((start / 12) + 1) * 12;
  308.   if (stop > s_ptr->store_ctr)  stop = s_ptr->store_ctr;
  309.   while (start < stop)
  310.     {
  311.       inventory[INVEN_MAX] = s_ptr->store_inven[start].sitem;
  312.       i_ptr = &inventory[INVEN_MAX];
  313.       if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
  314.     i_ptr->number = 1;
  315.       objdes(out_val1, INVEN_MAX, TRUE);
  316.       (void) sprintf(out_val2, "%c) %s", 97+i, out_val1);
  317.       prt(out_val2, i+5, 0);
  318.       if (s_ptr->store_inven[start].scost <= 0)
  319.     {
  320.       bigint_t value = - s_ptr->store_inven[start].scost;
  321.       value += (value * chr_adj());
  322.       if (value <= 0)
  323.         value = 1;
  324.       (void) sprintf(out_val2, "%9ld", value);
  325.     }
  326.       else
  327.     (void) sprintf(out_val2,"%9ld [Fixed]", s_ptr->store_inven[start].scost);
  328.       prt(out_val2, i+5, 59);
  329.       i++;
  330.       start++;
  331.     }
  332.   if (i < 12)
  333.     for (j = 0; j < (11 - i + 1); j++)
  334.       prt("", j+i+5, 0);  /* clear remaining lines */
  335.   if (s_ptr->store_ctr > 12)
  336.     prt("- cont. -", 17, 60);
  337.   else
  338.     prt("", 17, 60);  /* clear the line */
  339. }
  340.  
  341.  
  342. /* Re-displays only a single cost            -RAK-    */
  343. display_cost(store_num, pos)
  344. int store_num, pos;
  345. {
  346.   register int i; bigint_t j;
  347.   vtype out_val;
  348.   register store_type *s_ptr;
  349.  
  350.   s_ptr = &store[store_num];
  351.   i = (pos % 12);
  352.   if (s_ptr->store_inven[pos].scost < 0)
  353.     {
  354.       j = - s_ptr->store_inven[pos].scost;
  355.       j += (j*chr_adj());
  356.       (void) sprintf(out_val, "%ld", j);
  357.     }
  358.   else
  359.     (void) sprintf(out_val, "%9ld [Fixed]", s_ptr->store_inven[pos].scost);
  360.   prt(out_val, i+5, 59);
  361. }
  362.  
  363.  
  364. /* Displays players gold                    -RAK-    */
  365. store_prt_gold()
  366. {
  367.   vtype out_val;
  368.  
  369.   (void) sprintf(out_val, "Gold Remaining : %ld", py.misc.au);
  370.   prt(out_val, 18, 17);
  371. }
  372.  
  373.  
  374. /* Displays store                    -RAK-    */
  375. display_store(store_num, cur_top)
  376. int store_num, cur_top;
  377. {
  378.   register store_type *s_ptr;
  379.  
  380.   s_ptr = &store[store_num];
  381.   really_clear_screen();
  382.   prt(owners[s_ptr->owner].owner_name, 3, 9);
  383.   prt("   Item", 4, 0);
  384.   prt("Asking Price", 4, 60);
  385.   store_prt_gold();
  386.   display_commands();
  387.   display_inventory(store_num, cur_top);
  388. }
  389.  
  390.  
  391. /* Get the ID of a store item and return it's value    -RAK-    */
  392. int get_store_item(com_val, pmt, i, j)
  393. int *com_val;
  394. char *pmt;
  395. register int i, j;
  396. {
  397.   char command;
  398.   vtype out_val;
  399.   register int flag;
  400.  
  401.   *com_val = -1;
  402.   flag = TRUE;
  403.   (void) sprintf(out_val, "(Items %c-%c, ESC to exit) %s", i+97, j+97, pmt);
  404.   while (((*com_val < i) || (*com_val > j)) && (flag))
  405.     {
  406.       prt(out_val, 0, 0);
  407.       inkey(&command);
  408.       *com_val = (command);
  409.       switch(*com_val)
  410.     {
  411.     case 0: case 27: flag = FALSE; break;
  412.     default: *com_val = *com_val - 97; break;
  413.     }
  414.     }
  415.   msg_flag = FALSE;
  416.   erase_line(MSG_LINE, 0);
  417.   return(flag);
  418. }
  419.  
  420.  
  421. /* Increase the insult counter and get pissed if too many -RAK-    */
  422. int increase_insults(store_num)
  423. int store_num;
  424. {
  425.   register int increase;
  426.   register store_type *s_ptr;
  427.  
  428.   increase = FALSE;
  429.   s_ptr = &store[store_num];
  430.   s_ptr->insult_cur++;
  431.   if (s_ptr->insult_cur > owners[s_ptr->owner].insult_max)
  432.     {
  433.       prt_comment4();
  434.       s_ptr->insult_cur = 0;
  435.       s_ptr->store_open = turn + 2500 + randint(2500);
  436.       increase = TRUE;
  437.     }
  438.   return(increase);
  439. }
  440.  
  441.  
  442. /* Decrease insults                    -RAK-    */
  443. decrease_insults(store_num)
  444. int store_num;
  445. {
  446.   register store_type *s_ptr;
  447.  
  448.   s_ptr = &store[store_num];
  449.   s_ptr->insult_cur -= 2;
  450.   if (s_ptr->insult_cur < 0)  s_ptr->insult_cur = 0;
  451. }
  452.  
  453.  
  454. /* Have insulted while haggling                -RAK-    */
  455. int haggle_insults(store_num)
  456. int store_num;
  457. {
  458.   register int haggle;
  459.  
  460.   haggle = FALSE;
  461.   if (increase_insults(store_num))
  462.     haggle = TRUE;
  463.   else
  464.     prt_comment5();
  465.   return(haggle);
  466. }
  467.  
  468.  
  469. int get_haggle(comment, num)
  470. char *comment;
  471. bigint_t *num;
  472. {
  473.   bigint_t i;
  474.   vtype out_val;
  475.   register int flag, clen;
  476.  
  477.   flag = TRUE;
  478.   i = 0;
  479.   clen = strlen(comment);
  480.   do
  481.     {
  482.       msg_print(comment);
  483.       msg_flag = FALSE;
  484.       if (!get_string(out_val, 0, clen, 40))
  485.     {
  486.       flag = FALSE;
  487.       erase_line(MSG_LINE, 0);
  488.     }
  489.       (void) sscanf(out_val, "%ld", &i);
  490.     }
  491.   while ((i <= 0) && (flag));
  492.   if (flag)  *num = i;
  493.   return(flag);
  494. }
  495.  
  496.  
  497. int receive_offer(store_num, comment, new_offer, last_offer, factor)
  498. int store_num;
  499. char *comment;
  500. bigint_t *new_offer;
  501. bigint_t last_offer; int factor;
  502. {
  503.   register int flag;
  504.   register int receive;
  505.  
  506.   receive = 0;
  507.   flag = FALSE;
  508.   do
  509.     {
  510.       if (get_haggle(comment, new_offer))
  511.     {
  512.       if (*new_offer*factor >= last_offer*factor)
  513.         flag = TRUE;
  514.       else if (haggle_insults(store_num))
  515.         {
  516.           receive = 2;
  517.           flag = TRUE;
  518.         }
  519.     }
  520.       else
  521.     {
  522.       receive = 1;
  523.       flag = TRUE;
  524.     }
  525.     }
  526.   while (!flag);
  527.   return(receive);
  528. }
  529.  
  530.  
  531. /* Haggling routine                    -RAK-    */
  532. int purchase_haggle(store_num, price, item)
  533. int store_num;
  534. bigint_t *price;
  535. treasure_type item;
  536. {
  537.   bigint_t max_sell, min_sell, max_buy;
  538.   bigint_t cost, cur_ask, final_ask, min_offer;
  539.   bigint_t last_offer, new_offer; int final_flag; bigint_t x3;
  540.   double x1, x2;
  541.   double min_per, max_per;
  542.   register int flag, loop_flag;
  543.   vtype out_val, comment;
  544.   int purchase;
  545.   register store_type *s_ptr;
  546.   register owner_type *o_ptr;
  547.  
  548.   flag = FALSE;
  549.   purchase = 0;
  550.   *price = 0;
  551.   final_flag = 0;
  552.   msg_flag = FALSE;
  553.   s_ptr = &store[store_num];
  554.   o_ptr = &owners[s_ptr->owner];
  555.   cost = sell_price(store_num, &max_sell, &min_sell, item);
  556.   max_sell = max_sell + (max_sell*chr_adj());
  557.   if (max_sell <= 0)  max_sell = 1;
  558.   min_sell = min_sell + (min_sell*chr_adj());
  559.   if (min_sell <= 0)  min_sell = 1;
  560.   max_buy  = (cost*(1-o_ptr->max_inflate));
  561.   min_per  = o_ptr->haggle_per;
  562.   max_per  = min_per*3.0;
  563.   haggle_commands(1);
  564.   cur_ask   = max_sell;
  565.   final_ask = min_sell;
  566.   min_offer = max_buy;
  567.   last_offer = min_offer;
  568.   (void) strcpy(comment, "Asking : ");
  569.   do
  570.     {
  571.       do
  572.     {
  573.       loop_flag = TRUE;
  574.       (void) sprintf(out_val, "%s %ld", comment, cur_ask);
  575.       put_buffer(out_val, 1, 0);
  576.       switch(receive_offer(store_num, "What do you offer? ",
  577.                  &new_offer, last_offer, 1))
  578.         {
  579.         case 1:
  580.           purchase = 1;
  581.           flag   = TRUE;
  582.           break;
  583.         case 2:
  584.           purchase = 2;
  585.           flag   = TRUE;
  586.           break;
  587.         default:
  588.           if (new_offer > cur_ask)
  589.         {
  590.           prt_comment6();
  591.         }
  592.           else if (new_offer == cur_ask)
  593.         {
  594.           flag = TRUE;
  595.           *price = new_offer;
  596.         }
  597.           else
  598.         loop_flag = FALSE;
  599.         }
  600.     }
  601.       while (!flag && loop_flag);
  602.       if (!flag)
  603.     {
  604.       x1 = (double)(new_offer - last_offer)/(double)(cur_ask - last_offer);
  605.       if (x1 < min_per)
  606.         {
  607.           flag = haggle_insults(store_num);
  608.           if (flag)  purchase = 2;
  609.         }
  610.       else
  611.         {
  612.           if (x1 > max_per)
  613.         {
  614.           x1 = x1*0.75;
  615.           if (x1 < max_per)  x1 = max_per;
  616.         }
  617.         }
  618.       x2 = (x1 + (randint(5) - 3)/100.0);
  619.       x3 = ((cur_ask-new_offer)*x2) + 1;
  620.       /* don't let the price go up */
  621.       if (x3 < 0)
  622.         x3 = 0;
  623.       cur_ask -= x3;
  624.       if (cur_ask < final_ask)
  625.         {
  626.           cur_ask = final_ask;
  627.           (void) strcpy(comment, "Final Offer : ");
  628.           final_flag++;
  629.           if (final_flag > 3)
  630.         {
  631.           if (increase_insults(store_num))
  632.             purchase = 2;
  633.           else
  634.             purchase = 1;
  635.           flag = TRUE;
  636.         }
  637.         }
  638.       else if (new_offer >= cur_ask)
  639.         {
  640.           flag = TRUE;
  641.           *price = new_offer;
  642.         }
  643.       if (!flag)
  644.         {
  645.           last_offer = new_offer;
  646.           prt("", 1, 0);  /* clear the line */
  647.           (void) sprintf(out_val, "Your last offer : %ld", last_offer);
  648.           put_buffer(out_val, 1, 39);
  649.           prt_comment2(last_offer, cur_ask, final_flag);
  650.         }
  651.     }
  652.     }
  653.   while (!flag);
  654.   prt("", 1, 0);  /* clear the line */
  655.   display_commands();
  656.   return(purchase);
  657. }
  658.  
  659.  
  660. /* Haggling routine                    -RAK-    */
  661. int sell_haggle(store_num, price, item)
  662. int store_num;
  663. bigint_t *price;
  664. treasure_type item;
  665. {
  666.   bigint_t max_sell, max_buy, min_buy;
  667.   bigint_t cost, cur_ask, final_ask, min_offer;
  668.   bigint_t last_offer, new_offer; int final_flag, x3;
  669.   bigint_t max_gold;
  670.   double x1, x2;
  671.   double min_per, max_per;
  672.   register int flag, loop_flag;
  673.   vtype comment, out_val;
  674.   register store_type *s_ptr;
  675.   register owner_type *o_ptr;
  676.   int sell;
  677.  
  678.   flag = FALSE;
  679.   sell = 0;
  680.   *price = 0;
  681.   final_flag = 0;
  682.   msg_flag = FALSE;
  683.   s_ptr = &store[store_num];
  684.   cost = item_value(item);
  685.   if (cost < 1)
  686.     {
  687.       sell = 3;
  688.       flag = TRUE;
  689.     }
  690.   else
  691.     {
  692.       o_ptr = &owners[s_ptr->owner];
  693.       cost += -(cost*chr_adj()) -
  694.            (cost*rgold_adj[o_ptr->owner_race][py.misc.prace]);
  695.       if (cost < 1)  cost = 1;
  696.       max_sell = (cost*(1+o_ptr->max_inflate));
  697.       max_buy  = (cost*(1-o_ptr->max_inflate));
  698.       min_buy  = (cost*(1-o_ptr->min_inflate));
  699.       if (min_buy < 1) min_buy = 1;
  700.       if (max_buy < 1) max_buy = 1;
  701.       if (min_buy < max_buy)  min_buy = max_buy;
  702.       min_per  = o_ptr->haggle_per;
  703.       max_per  = min_per*3.0;
  704.       max_gold = o_ptr->max_cost;
  705.     }
  706.   if (!flag)
  707.     {
  708.       haggle_commands(-1);
  709.       if (max_buy > max_gold)
  710.     {
  711.       final_flag= 1;
  712.       (void) strcpy(comment, "Final offer : ");
  713.       cur_ask   = max_gold;
  714.       final_ask = max_gold;
  715.  msg_print("I am sorry, but I have not the money to afford such a fine item.");
  716.       /* make sure player see the message */
  717.       msg_print(" ");
  718.     }
  719.       else
  720.     {
  721.       cur_ask   = max_buy;
  722.       final_ask = min_buy;
  723.       if (final_ask > max_gold)
  724.         final_ask = max_gold;
  725.       (void) strcpy(comment, "Offer : ");
  726.     }
  727.       min_offer = max_sell;
  728.       last_offer = min_offer;
  729.       if (cur_ask < 1)  cur_ask = 1;
  730.       do
  731.     {
  732.       do
  733.         {
  734.           loop_flag = TRUE;
  735.           (void) sprintf(out_val, "%s %ld", comment, cur_ask);
  736.           put_buffer(out_val, 1, 0);
  737.           switch(receive_offer(store_num, "What price do you ask? ",
  738.                  &new_offer, last_offer, -1))
  739.         {
  740.         case 1:
  741.           sell = 1;
  742.           flag   = TRUE;
  743.           break;
  744.         case 2:
  745.           sell = 2;
  746.           flag   = TRUE;
  747.           break;
  748.         default:
  749.           if (new_offer < cur_ask)
  750.             {
  751.               prt_comment6();
  752.             }
  753.           else if (new_offer == cur_ask)
  754.             {
  755.               flag = TRUE;
  756.               *price = new_offer;
  757.             }
  758.           else
  759.             loop_flag = FALSE;
  760.             }
  761.         }
  762.       while (!flag && loop_flag);
  763.       if (!flag)
  764.         {
  765.           msg_flag = FALSE;
  766.           x1 = (double)(last_offer - new_offer)/
  767.         (double)(last_offer - cur_ask);
  768.           if (x1 < min_per)
  769.         {
  770.           flag = haggle_insults(store_num);
  771.           if (flag)  sell = 2;
  772.         }
  773.           else
  774.         {
  775.           if (x1 > max_per)
  776.             {
  777.               x1 = x1 * 0.75;
  778.               if (x1 < max_per)  x1 = max_per;
  779.             }
  780.         }
  781.           x2 = (x1 + (randint(5) - 3)/100.0);
  782.           x3 = ((new_offer-cur_ask)*x2) + 1;
  783.           /* don't let the price go down */
  784.           if (x3 < 0)
  785.         x3 = 0;
  786.           cur_ask += x3;
  787.           if (cur_ask > final_ask)
  788.         {
  789.           cur_ask = final_ask;
  790.           (void) strcpy(comment, "Final Offer : ");
  791.           final_flag++;
  792.           if (final_flag > 3)
  793.             {
  794.               if (increase_insults(store_num))
  795.             sell = 2;
  796.               else
  797.             sell = 1;
  798.               flag = TRUE;
  799.             }
  800.         }
  801.           else if (new_offer <= cur_ask)
  802.         {
  803.           flag = TRUE;
  804.           *price = new_offer;
  805.         }
  806.           if (!flag)
  807.         {
  808.           last_offer = new_offer;
  809.           prt("", 1, 0);  /* clear the line */
  810.           (void) sprintf(out_val, "Your last bid %ld", last_offer);
  811.           put_buffer(out_val, 1, 39);
  812.           prt_comment3(cur_ask, last_offer, final_flag);
  813.         }
  814.         }
  815.     }
  816.       while (!flag);
  817.       prt("", 1, 0);  /* clear the line */
  818.       display_commands();
  819.     }
  820.   return(sell);
  821. }
  822.  
  823.  
  824. /* Buy an item from a store                -RAK-    */
  825. int store_purchase(store_num, cur_top)
  826. int store_num;
  827. int *cur_top;
  828. {
  829.   int i, item_val; bigint_t price;
  830.   int item_new, choice;
  831.   int save_number;
  832.   bigvtype out_val, tmp_str;
  833.   register store_type *s_ptr;
  834.   register treasure_type *i_ptr;
  835.   register inven_record *r_ptr;
  836.   int purchase;
  837.  
  838.   purchase = FALSE;
  839.   s_ptr = &store[store_num];
  840.   /* i == number of objects shown on screen    */
  841.   if (*cur_top == 12)
  842.     i = s_ptr->store_ctr - 1 - 12;
  843.   else if (s_ptr->store_ctr > 11)
  844.     i = 11;
  845.   else
  846.     i = s_ptr->store_ctr - 1;
  847.   if (s_ptr->store_ctr < 1)
  848.     msg_print("I am currently out of stock.");
  849.       /* Get the item number to be bought        */
  850.   else if (get_store_item(&item_val,
  851.               "Which item are you interested in? ", 0, i))
  852.     {
  853.       item_val = item_val + *cur_top;    /* TRUE item_val    */
  854.       inventory[INVEN_MAX] = s_ptr->store_inven[item_val].sitem;
  855.       i_ptr = &inventory[INVEN_MAX];
  856.       if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
  857.     {
  858.       save_number = i_ptr->number;
  859.       i_ptr->number = 1;
  860.     }
  861.       else
  862.     save_number = 1;
  863.       if (inven_check_weight())
  864.     if (inven_check_num())
  865.       {
  866.         if (s_ptr->store_inven[item_val].scost > 0)
  867.           {
  868.         price = s_ptr->store_inven[item_val].scost;
  869.         choice = 0;
  870.           }
  871.         else
  872.           choice = purchase_haggle(store_num, &price,
  873.                        inventory[INVEN_MAX]);
  874.         switch(choice)
  875.           {
  876.           case 0:
  877.         if (py.misc.au >= price)
  878.           {
  879.             prt_comment1();
  880.             decrease_insults(store_num);
  881.             py.misc.au -= price;
  882.             store_destroy(store_num, item_val, TRUE);
  883.             inven_carry(&item_new);
  884.             objdes(tmp_str, item_new, TRUE);
  885.             (void) sprintf(out_val, "You have %s (%c)",
  886.                    tmp_str, item_new+97);
  887.             msg_print(out_val);
  888.             if (*cur_top >= s_ptr->store_ctr)
  889.               {
  890.             *cur_top = 0;
  891.             display_inventory(store_num, *cur_top);
  892.               }
  893.             else
  894.               {
  895.             r_ptr = &s_ptr->store_inven[item_val];
  896.             if (save_number > 1)
  897.               {
  898.                 if (r_ptr->scost < 0)
  899.                   {
  900.                 r_ptr->scost = price;
  901.                 display_cost(store_num, item_val);
  902.                   }
  903.               }
  904.             else
  905.               display_inventory(store_num, item_val);
  906.             store_prt_gold();
  907.               }
  908.           }
  909.         else
  910.           {
  911.             if (increase_insults(store_num))
  912.               purchase = TRUE;
  913.             else
  914.               {
  915.             prt_comment1();
  916.             msg_print("Liar!  You have not the gold!");
  917.               }
  918.           }
  919.         break;
  920.           case 2:
  921.         purchase = TRUE;
  922.         break;
  923.           default:
  924.         break;
  925.           }
  926.         prt("", 1, 0);  /* clear the line */
  927.       }
  928.     else
  929.       prt("You cannot carry that many different items.", 0, 0);
  930.       else
  931.     prt("You can not carry that much weight.", 0, 0);
  932.     }
  933.   return(purchase);
  934. }
  935.  
  936.  
  937. /* Sell an item to the store                -RAK-    */
  938. int store_sell(store_num, cur_top)
  939. int store_num, cur_top;
  940. {
  941.   int item_val;
  942.   int item_pos; bigint_t price;
  943.   int redraw;
  944.   bigvtype out_val, tmp_str;
  945.   register treasure_type *i_ptr;
  946.   register int sell;
  947.  
  948.   sell = FALSE;
  949.   redraw = FALSE;
  950.   if (get_item(&item_val, "Which one? ", &redraw, 0, inven_ctr-1))
  951.     {
  952.       if (redraw)  display_store(store_num, cur_top);
  953.       inventory[INVEN_MAX] = inventory[item_val];
  954.       i_ptr = &inventory[INVEN_MAX];
  955.       if ((i_ptr->subval > 255) && (i_ptr->subval < 512))
  956.     i_ptr->number = 1;
  957.       objdes(tmp_str, INVEN_MAX, TRUE);
  958.       (void) sprintf(out_val, "Selling %s (%c)", tmp_str, item_val+97);
  959.       msg_print(out_val);
  960.       /* make sure player sees the message */
  961.       msg_print(" ");
  962.       if ((*store_buy[store_num])(inventory[INVEN_MAX].tval))
  963.     if (store_check_num(store_num))
  964.       switch(sell_haggle(store_num, &price, inventory[INVEN_MAX]))
  965.         {
  966.         case 0:
  967.           prt_comment1();
  968.           py.misc.au += price;
  969.           inven_destroy(item_val);
  970.           store_carry(store_num, &item_pos);
  971.           if (item_pos >= 0)
  972.         if (item_pos < 12)
  973.           if (cur_top < 12)
  974.             display_inventory(store_num, item_pos);
  975.           else
  976.             display_inventory(store_num, cur_top);
  977.         else if (cur_top > 11)
  978.           display_inventory(store_num, item_pos);
  979.           store_prt_gold();
  980.           break;
  981.         case 2:
  982.           sell = TRUE;
  983.           break;
  984.         case 3:
  985.           msg_print("How dare you!");
  986.           msg_print("I will not buy that!");
  987.           sell = increase_insults(store_num);
  988.           break;
  989.         default:
  990.           break;
  991.         }
  992.     else
  993.       prt("I have not the room in my store to keep it...", 0, 0);
  994.       else
  995.     prt("I do not buy such items.", 0, 0);
  996.     }
  997.   else if (redraw)
  998.     display_store(store_num, cur_top);
  999.   return(sell);
  1000. }
  1001.  
  1002.  
  1003. /* Entering a store                    -RAK-    */
  1004. enter_store(store_num)
  1005. int store_num;
  1006. {
  1007.   int com_val, cur_top;
  1008.   char command;
  1009.   register int exit_flag;
  1010.   register store_type *s_ptr;
  1011.  
  1012.   s_ptr = &store[store_num];
  1013.   if (s_ptr->store_open < turn)
  1014.     {
  1015.       exit_flag = FALSE;
  1016.       cur_top = 0;
  1017.       display_store(store_num, cur_top);
  1018.       do
  1019.     {
  1020.       if (get_com("", &command))
  1021.         {
  1022.           msg_flag = FALSE;
  1023.           com_val = (command);
  1024.           switch(com_val)
  1025.         {
  1026.         case 18:
  1027.           display_store(store_num, cur_top);
  1028.           break;
  1029.         case 98:
  1030.           if (cur_top == 0)
  1031.             if (s_ptr->store_ctr > 12)
  1032.               {
  1033.             cur_top = 12;
  1034.             display_inventory(store_num, cur_top);
  1035.               }
  1036.             else
  1037.               prt("Entire inventory is shown.", 0, 0);
  1038.           else
  1039.             {
  1040.               cur_top = 0;
  1041.               display_inventory(store_num, cur_top);
  1042.             }
  1043.           break;
  1044.         case 101:      /* Equipment List    */
  1045.           if (inven_command('e', 0, 0))
  1046.             display_store(store_num, cur_top);
  1047.           break;
  1048.         case 105:      /* Inventory        */
  1049.           if (inven_command('i', 0, 0))
  1050.             display_store(store_num, cur_top);
  1051.           break;
  1052.         case 116:      /* Take off        */
  1053.           if (inven_command('t', 0, 0))
  1054.             display_store(store_num, cur_top);
  1055.           break;
  1056.         case 119:    /* Wear            */
  1057.           if (inven_command('w', 0, 0))
  1058.             display_store(store_num, cur_top);
  1059.           break;
  1060.         case 120:     /* Switch weapon        */
  1061.           if (inven_command('x', 0, 0))
  1062.             display_store(store_num, cur_top);
  1063.           break;
  1064.         case 112:
  1065.           exit_flag = store_purchase(store_num, &cur_top);
  1066.           break;
  1067.         case 115:
  1068.           exit_flag = store_sell(store_num, cur_top);
  1069.           break;
  1070.         default:
  1071.           prt("Invalid Command.", 0, 0);
  1072.           break;
  1073.         }
  1074.         }
  1075.       else
  1076.         exit_flag = TRUE;
  1077.     }
  1078.       while (!exit_flag);
  1079.       draw_cave();
  1080.     }
  1081.   else
  1082.     msg_print("The doors are locked.");
  1083. }
  1084.