home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / shop.c < prev    next >
C/C++ Source or Header  |  1991-03-01  |  14KB  |  576 lines

  1. /* ************************************************************************
  2. *  file: shop.c , Shop module.                            Part of DIKUMUD *
  3. *  Usage: Procedures handling shops and shopkeepers.                      *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ************************************************************************* */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #include "structs.h"
  11. #include "comm.h"
  12. #include "handler.h"
  13. #include "db.h"
  14. #include "interpreter.h"
  15. #include "utils.h"
  16.  
  17. #define SHOP_FILE "tinyworld.shp"
  18. #define MAX_TRADE 5
  19. #define MAX_PROD 5
  20.  
  21. extern struct str_app_type str_app[];
  22. extern struct index_data *mob_index;
  23.  
  24. char *fread_string(FILE *fl);
  25.  
  26. struct shop_data
  27. {
  28.     int producing[MAX_PROD];/* Which item to produce (virtual)      */
  29.     float profit_buy;       /* Factor to multiply cost with.        */
  30.     float profit_sell;      /* Factor to multiply cost with.        */
  31.     byte type[MAX_TRADE];   /* Which item to trade.                 */
  32.     char *no_such_item1;    /* Message if keeper hasn't got an item */
  33.     char *no_such_item2;    /* Message if player hasn't got an item */
  34.     char *missing_cash1;    /* Message if keeper hasn't got cash    */
  35.     char *missing_cash2;    /* Message if player hasn't got cash    */
  36.     char *do_not_buy;            /* If keeper dosn't buy such things.     */
  37.     char *message_buy;      /* Message when player buys item        */
  38.     char *message_sell;     /* Message when player sells item       */
  39.     int temper1;               /* How does keeper react if no money    */
  40.     int temper2;               /* How does keeper react when attacked  */
  41.     int keeper;             /* The mobil who owns the shop (virtual)*/
  42.     int with_who;        /* Who does the shop trade with?    */
  43.     int in_room;        /* Where is the shop?            */
  44.     int open1,open2;    /* When does the shop open?        */
  45.     int close1,close2;    /* When does the shop close?        */
  46. };
  47.  
  48.  
  49. extern struct room_data *world;
  50. extern struct time_info_data time_info;
  51.  
  52. struct shop_data *shop_index;
  53. int number_of_shops;
  54.  
  55. int is_ok(struct char_data *keeper, struct char_data *ch, int shop_nr)
  56. {
  57.     if (shop_index[shop_nr].open1>time_info.hours){
  58.         do_say(keeper,
  59.         "Come back later!",17);
  60.         return(FALSE);
  61.     } else if (shop_index[shop_nr].close1<time_info.hours)
  62.         if (shop_index[shop_nr].open2>time_info.hours){
  63.             do_say(keeper,
  64.             "Sorry, we have closed, but come back later.",17);
  65.             return(FALSE);
  66.         } else if (shop_index[shop_nr].close2<time_info.hours){
  67.             do_say(keeper,
  68.             "Sorry, come back tomorrow.",17);
  69.             return(FALSE);
  70.         };
  71.  
  72.     if(!(CAN_SEE(keeper,ch)))
  73.     {
  74.         do_say(keeper,
  75.         "I don't trade with someone I can't see!",17);
  76.         return(FALSE);
  77.     };
  78.  
  79.     switch(shop_index[shop_nr].with_who){
  80.         case 0 : return(TRUE);
  81.         case 1 : return(TRUE);
  82.         default : return(TRUE);
  83.     };
  84. }
  85.  
  86. int trade_with(struct obj_data *item, int shop_nr)
  87. {
  88.     int counter;
  89.  
  90.    if(item->obj_flags.cost < 1) return(FALSE);
  91.  
  92.     for(counter=0;counter<MAX_TRADE;counter++)
  93.         if(shop_index[shop_nr].type[counter]==item->obj_flags.type_flag)
  94.             return(TRUE);
  95.     return(FALSE);
  96. }
  97.  
  98. int shop_producing(struct obj_data *item, int shop_nr)
  99. {
  100.     int counter;
  101.  
  102.     if(item->item_number<0) return(FALSE);
  103.  
  104.     for(counter=0;counter<MAX_PROD;counter++)
  105.         if (shop_index[shop_nr].producing[counter] == item->item_number)
  106.             return(TRUE);
  107.     return(FALSE);
  108. }
  109.  
  110. void shopping_buy( char *arg, struct char_data *ch,
  111.      struct char_data *keeper, int shop_nr)
  112. {
  113.     char argm[100], buf[MAX_STRING_LENGTH];
  114.     struct obj_data *temp1;
  115.     struct char_data *temp_char;
  116.  
  117.     if(!(is_ok(keeper,ch,shop_nr)))
  118.         return;
  119.     
  120.  
  121.     one_argument(arg, argm);
  122.     if(!(*argm))
  123.     {
  124.         sprintf(buf,
  125.         "%s what do you want to buy??"
  126.         ,GET_NAME(ch));
  127.         do_tell(keeper,buf,19);
  128.         return;
  129.     };
  130.     if(!( temp1 = 
  131.         get_obj_in_list_vis(ch,argm,keeper->carrying)))
  132.     {
  133.         sprintf(buf,
  134.         shop_index[shop_nr].no_such_item1
  135.         ,GET_NAME(ch));
  136.         do_tell(keeper,buf,19);
  137.         return;
  138.     }
  139.  
  140.     if(temp1->obj_flags.cost <= 0)
  141.     {
  142.         sprintf(buf,
  143.         shop_index[shop_nr].no_such_item1
  144.         ,GET_NAME(ch));
  145.         do_tell(keeper,buf,19);
  146.         extract_obj(temp1);
  147.         return;
  148.     }
  149.  
  150.     if(GET_GOLD(ch) < (int) (temp1->obj_flags.cost*
  151.         shop_index[shop_nr].profit_buy) && GET_LEVEL(ch)<22)
  152.     {
  153.         sprintf(buf,
  154.         shop_index[shop_nr].missing_cash2,
  155.         GET_NAME(ch));
  156.         do_tell(keeper,buf,19);
  157.  
  158.         switch(shop_index[shop_nr].temper1)
  159.         {
  160.             case 0:
  161.                 do_action(keeper,GET_NAME(ch),30);
  162.                 return;
  163.             case 1:
  164.                 do_emote(keeper,"smokes on his joint",36);
  165.                 return;
  166.             default:
  167.                 return;
  168.         }
  169.     }
  170.     
  171.     if ((IS_CARRYING_N(ch) + 1 > CAN_CARRY_N(ch)))
  172.     {
  173.         sprintf(buf,"%s : You can't carry that many items.\n\r", 
  174.             fname(temp1->name));
  175.         send_to_char(buf, ch);
  176.         return;
  177.     }
  178.  
  179.     if ((IS_CARRYING_W(ch) + temp1->obj_flags.weight) > CAN_CARRY_W(ch))
  180.     {
  181.         sprintf(buf,"%s : You can't carry that much weight.\n\r", 
  182.             fname(temp1->name));
  183.         send_to_char(buf, ch);
  184.         return;
  185.     }
  186.  
  187.  
  188.     act("$n buys $p.", FALSE, ch, temp1, 0, TO_ROOM);
  189.  
  190.     sprintf(buf,
  191.         shop_index[shop_nr].message_buy,
  192.         GET_NAME(ch),
  193.         (int) (temp1->obj_flags.cost*
  194.             shop_index[shop_nr].profit_buy));
  195.     do_tell(keeper,buf,19);
  196.     sprintf(buf,"You now have %s.\n\r",
  197.         temp1->short_description);
  198.     send_to_char(buf,ch);
  199.    if(GET_LEVEL(ch)<22)
  200.         GET_GOLD(ch) -= (int)(temp1->obj_flags.cost*
  201.             shop_index[shop_nr].profit_buy);
  202.  
  203.    GET_GOLD(keeper) += (int)(temp1->obj_flags.cost*
  204.       shop_index[shop_nr].profit_buy);
  205.  
  206.     /* Test if producing shop ! */
  207.     if(shop_producing(temp1,shop_nr))
  208.         temp1 = read_object(temp1->item_number, REAL);
  209.     else
  210.         obj_from_char(temp1);
  211.  
  212.     obj_to_char(temp1,ch);
  213.  
  214.     return; 
  215. }
  216.  
  217. void shopping_sell( char *arg, struct char_data *ch,
  218.      struct char_data *keeper,int shop_nr)
  219. {
  220.     char argm[100], buf[MAX_STRING_LENGTH];
  221.     struct obj_data *temp1;
  222.     struct char_data *temp_char;
  223.  
  224.     if(!(is_ok(keeper,ch,shop_nr)))
  225.         return;
  226.  
  227.     one_argument(arg, argm);
  228.  
  229.     if(!(*argm))
  230.     {
  231.         sprintf(buf,
  232.         "%s What do you want to sell??"
  233.         ,GET_NAME(ch));
  234.         do_tell(keeper,buf,19);
  235.         return;
  236.     }
  237.  
  238.     if(!( temp1 = get_obj_in_list_vis(ch,argm,ch->carrying)))
  239.     {
  240.         sprintf(buf,
  241.         shop_index[shop_nr].no_such_item2
  242.         ,GET_NAME(ch));
  243.         do_tell(keeper,buf,19);
  244.         return;
  245.     }
  246.  
  247.     if(!(trade_with(temp1,shop_nr))||(temp1->obj_flags.cost<1))
  248.     {
  249.         sprintf(buf,
  250.         shop_index[shop_nr].do_not_buy,
  251.         GET_NAME(ch));
  252.         do_tell(keeper,buf,19);
  253.         return;
  254.     }
  255.  
  256.     if (GET_GOLD(keeper)<(int) (temp1->obj_flags.cost*
  257.         shop_index[shop_nr].profit_sell)) {
  258.         sprintf(buf,shop_index[shop_nr].missing_cash1
  259.         ,GET_NAME(ch));
  260.         do_tell(keeper,buf,19);
  261.         return;
  262.     }
  263.  
  264.     act("$n sells $p.", FALSE, ch, temp1, 0, TO_ROOM);
  265.  
  266.     sprintf(buf,shop_index[shop_nr].message_sell,
  267.         GET_NAME(ch),(int) (temp1->obj_flags.cost*
  268.             shop_index[shop_nr].profit_sell));
  269.     do_tell(keeper,buf,19);
  270.     sprintf(buf,"The shopkeeper now has %s.\n\r",
  271.         temp1->short_description);
  272.     send_to_char(buf,ch);
  273.     GET_GOLD(ch) += (int) (temp1->obj_flags.cost*
  274.         shop_index[shop_nr].profit_sell);
  275.     GET_GOLD(keeper) -= (int) (temp1->obj_flags.cost*
  276.         shop_index[shop_nr].profit_sell);
  277.  
  278.     if((get_obj_in_list(argm,keeper->carrying)) || 
  279.    (GET_ITEM_TYPE(temp1) == ITEM_TRASH))
  280.         extract_obj(temp1);
  281.     else
  282.     {
  283.         obj_from_char(temp1);
  284.         obj_to_char(temp1,keeper);
  285.     }
  286.  
  287.     return;
  288. }
  289.  
  290. void shopping_value( char *arg, struct char_data *ch, 
  291.     struct char_data *keeper, int shop_nr)
  292. {
  293.     char argm[100], buf[MAX_STRING_LENGTH];
  294.     struct obj_data *temp1;
  295.  
  296.     if(!(is_ok(keeper,ch,shop_nr)))
  297.         return;
  298.  
  299.     one_argument(arg, argm);
  300.  
  301.     if(!(*argm))
  302.     {
  303.         sprintf(buf,"%s What do you want me to valuate??",
  304.             GET_NAME(ch));
  305.         do_tell(keeper,buf,19);
  306.         return;
  307.     }
  308.  
  309.     if(!( temp1 = get_obj_in_list_vis(ch,argm,ch->carrying)))
  310.     {
  311.         sprintf(buf,shop_index[shop_nr].no_such_item2,
  312.             GET_NAME(ch));
  313.         do_tell(keeper,buf,19);
  314.         return;
  315.     }
  316.  
  317.     if(!(trade_with(temp1,shop_nr)))
  318.     {
  319.         sprintf(buf,
  320.         shop_index[shop_nr].do_not_buy,
  321.         GET_NAME(ch));
  322.         do_tell(keeper,buf,19);
  323.         return;
  324.     }
  325.  
  326.     sprintf(buf,"%s I'll give you %d gold coins for that!",
  327.         GET_NAME(ch),(int) (temp1->obj_flags.cost*
  328.             shop_index[shop_nr].profit_sell));
  329.     do_tell(keeper,buf,19);
  330.  
  331.     return;
  332. }
  333.  
  334. void shopping_list( char *arg, struct char_data *ch,
  335.      struct char_data *keeper, int shop_nr)
  336. {
  337.     char buf[MAX_STRING_LENGTH], buf2[100],buf3[100];
  338.     struct obj_data *temp1;
  339.     extern char *drinks[];
  340.     int found_obj;
  341.  
  342.     if(!(is_ok(keeper,ch,shop_nr)))
  343.         return;
  344.  
  345.     strcpy(buf,"You can buy:\n\r");
  346.     found_obj = FALSE;
  347.         if(keeper->carrying)
  348.     for(temp1=keeper->carrying;
  349.         temp1; 
  350.         temp1 = temp1->next_content)
  351.             if((CAN_SEE_OBJ(ch,temp1)) && (temp1->obj_flags.cost>0))
  352.         {
  353.             found_obj = TRUE; 
  354.             if(temp1->obj_flags.type_flag != ITEM_DRINKCON) 
  355.                 sprintf(buf2,"%s for %d gold coins.\n\r"
  356.                 ,(temp1->short_description)
  357.                 ,(int)(temp1->obj_flags.cost*
  358.                 shop_index[shop_nr].profit_buy));
  359.             else {
  360.                 if (temp1->obj_flags.value[1])
  361.                     sprintf(buf3,"%s of %s",(temp1->short_description)
  362.                     ,drinks[temp1->obj_flags.value[2]]);
  363.                 else
  364.                     sprintf(buf3,"%s",(temp1->short_description));
  365.                 sprintf(buf2,"%s for %d gold coins.\n\r",buf3,
  366.                 (int)(temp1->obj_flags.cost*shop_index[shop_nr].profit_buy));
  367.             }
  368.             strcat(buf,CAP(buf2));
  369.         };
  370.  
  371.     if(!found_obj)
  372.         strcat(buf,"Nothing!\n\r");
  373.  
  374.     send_to_char(buf,ch);
  375.     return;
  376. }
  377.  
  378. void shopping_kill( char *arg, struct char_data *ch,
  379.     struct char_data *keeper, int shop_nr)
  380. {
  381.     char buf[100];
  382.  
  383.     switch(shop_index[shop_nr].temper2)
  384.     {
  385.         case 0:
  386.             sprintf(buf,"%s Don't ever try that again!",
  387.                 GET_NAME(ch));
  388.             do_tell(keeper,buf,19);
  389.             return;
  390.  
  391.         case 1:
  392.             sprintf(buf,"%s Scram - midget!",
  393.                 GET_NAME(ch));
  394.             do_tell(keeper,buf,19);
  395.             return;
  396.  
  397.         default :
  398.             return;
  399.     }
  400. }
  401.  
  402.  
  403. int shop_keeper(struct char_data *ch, int cmd, char *arg)
  404. {
  405.     char argm[100], buf[MAX_STRING_LENGTH];
  406.     struct obj_data *temp1;
  407.     struct char_data *temp_char;
  408.     struct char_data *keeper;
  409.     int shop_nr;
  410.  
  411.     keeper = 0;
  412.  
  413.     for (temp_char = world[ch->in_room].people; (!keeper) && (temp_char) ; 
  414.         temp_char = temp_char->next_in_room)
  415.     if (IS_MOB(temp_char))
  416.         if (mob_index[temp_char->nr].func == shop_keeper)
  417.             keeper = temp_char;
  418.  
  419.     for(shop_nr=0 ; shop_index[shop_nr].keeper != keeper->nr; shop_nr++);
  420.  
  421.     if((cmd == 56) && (ch->in_room == 
  422.        real_room(shop_index[shop_nr].in_room)))
  423.      /* Buy */
  424.     {
  425.         shopping_buy(arg,ch,keeper,shop_nr);
  426.         return(TRUE);
  427.     }
  428.  
  429.     if((cmd ==57 ) && (ch->in_room == 
  430.        real_room(shop_index[shop_nr].in_room)))
  431.      /* Sell */
  432.     {
  433.         shopping_sell(arg,ch,keeper,shop_nr);
  434.         return(TRUE);
  435.     }
  436.  
  437.     if((cmd == 58) && (ch->in_room == 
  438.        real_room(shop_index[shop_nr].in_room)))
  439.      /* value */
  440.     {
  441.         shopping_value(arg,ch,keeper,shop_nr);
  442.         return(TRUE);
  443.     }
  444.  
  445.     if((cmd == 59) && (ch->in_room == 
  446.        real_room(shop_index[shop_nr].in_room)))
  447.      /* List */
  448.     {
  449.         shopping_list(arg,ch,keeper,shop_nr);
  450.         return(TRUE);
  451.     }
  452.  
  453.     if ((cmd == 25) || (cmd==70))   /* Kill or Hit */
  454.     {
  455.         one_argument(arg, argm);
  456.  
  457.         if (keeper == get_char_room(argm,ch->in_room))
  458.         {
  459.             shopping_kill(arg,ch,keeper,shop_nr);
  460.             return(TRUE);
  461.         }
  462.     } else if ((cmd==84) || (cmd==207) || (cmd==172)) {   /* Cast, recite, use */
  463.         act("$N tells you 'No magic here - kid!'.", FALSE, ch, 0, keeper, TO_CHAR);
  464.     return TRUE;
  465.     }
  466.  
  467.     return(FALSE);
  468. }
  469.  
  470. void boot_the_shops()
  471. {
  472.     char *buf;
  473.     int temp;
  474.     int count;
  475.     FILE *shop_f;
  476.  
  477.     if (!(shop_f = fopen(SHOP_FILE, "r")))
  478.     {
  479.         perror("Error in boot shop\n");
  480.         exit(0);
  481.     }
  482.  
  483.     number_of_shops = 0;
  484.  
  485.     for(;;)
  486.     {
  487.         buf = fread_string(shop_f);
  488.         if(*buf == '#')    /* a new shop */
  489.         {
  490.             if(!number_of_shops)    /* first shop */
  491.                 CREATE(shop_index, struct shop_data, 1);
  492.             else
  493.               if(!(shop_index=
  494.                 (struct shop_data*) realloc(
  495.                 shop_index,(number_of_shops + 1)*
  496.                 sizeof(struct shop_data))))
  497.                 {
  498.                     perror("Error in boot shop\n");
  499.                     exit(0);
  500.                 }
  501.  
  502.             for(count=0;count<MAX_PROD;count++)
  503.                 {
  504.                     fscanf(shop_f,"%d \n", &temp);
  505.                     if (temp >= 0)
  506.                         shop_index[number_of_shops].producing[count]=
  507.                             real_object(temp);
  508.                     else
  509.                         shop_index[number_of_shops].producing[count]= temp;
  510.                 }
  511.             fscanf(shop_f,"%f \n",
  512.                 &shop_index[number_of_shops].profit_buy);
  513.             fscanf(shop_f,"%f \n",
  514.                 &shop_index[number_of_shops].profit_sell);
  515.             for(count=0;count<MAX_TRADE;count++)
  516.                 {
  517.                     fscanf(shop_f,"%d \n", &temp);
  518.                     shop_index[number_of_shops].type[count] =
  519.                     (byte) temp;
  520.                 }
  521.             shop_index[number_of_shops].no_such_item1 =
  522.                 fread_string(shop_f);
  523.             shop_index[number_of_shops].no_such_item2 =
  524.                 fread_string(shop_f);
  525.             shop_index[number_of_shops].do_not_buy =
  526.                 fread_string(shop_f);
  527.             shop_index[number_of_shops].missing_cash1 =
  528.                 fread_string(shop_f);
  529.             shop_index[number_of_shops].missing_cash2 =
  530.                 fread_string(shop_f);
  531.             shop_index[number_of_shops].message_buy =
  532.                 fread_string(shop_f);
  533.             shop_index[number_of_shops].message_sell =
  534.                 fread_string(shop_f);
  535.             fscanf(shop_f,"%d \n",
  536.                 &shop_index[number_of_shops].temper1);
  537.             fscanf(shop_f,"%d \n",
  538.                 &shop_index[number_of_shops].temper2);
  539.             fscanf(shop_f,"%d \n",
  540.                 &shop_index[number_of_shops].keeper);
  541.  
  542.             shop_index[number_of_shops].keeper =
  543.               real_mobile(shop_index[number_of_shops].keeper);
  544.  
  545.             fscanf(shop_f,"%d \n",
  546.                 &shop_index[number_of_shops].with_who);
  547.             fscanf(shop_f,"%d \n",
  548.                 &shop_index[number_of_shops].in_room);
  549.             fscanf(shop_f,"%d \n",
  550.                 &shop_index[number_of_shops].open1);
  551.             fscanf(shop_f,"%d \n",
  552.                 &shop_index[number_of_shops].close1);
  553.             fscanf(shop_f,"%d \n",
  554.                 &shop_index[number_of_shops].open2);
  555.             fscanf(shop_f,"%d \n",
  556.                 &shop_index[number_of_shops].close2);
  557.  
  558.             number_of_shops++;
  559.         }
  560.         else 
  561.             if(*buf == '$')    /* EOF */
  562.                 break;
  563.     }
  564.  
  565.     fclose(shop_f);
  566. }
  567.  
  568. void assign_the_shopkeepers()
  569. {
  570.     int temp1;
  571.  
  572.     for(temp1=0 ; temp1<number_of_shops ; temp1++)
  573.         mob_index[shop_index[temp1].keeper].func = shop_keeper;
  574.  
  575. }
  576.