/* ************************************************************************ * file: shop.c , Shop module. Part of DIKUMUD * * Usage: Procedures handling shops and shopkeepers. * * Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * ************************************************************************* */ #include "os.h" #include "structs.h" #include "comm.h" #include "handler.h" #include "db.h" #include "interpreter.h" #include "utils.h" #include "prototypes.h" #define SHOP_FILE "tinyworld.shp" #define MAX_TRADE 5 #define MAX_PROD 6 extern struct str_app_type str_app[]; extern struct index_data *mob_index; char *fread_string (FILE * fl); struct shop_data { int producing[MAX_PROD]; /* Which item to produce (virtual) */ float profit_buy; /* Factor to multiply cost with. */ float profit_sell; /* Factor to multiply cost with. */ byte type[MAX_TRADE]; /* Which item to trade. */ char *no_such_item1; /* Message if keeper hasn't got an item */ char *no_such_item2; /* Message if player hasn't got an item */ char *missing_cash1; /* Message if keeper hasn't got cash */ char *missing_cash2; /* Message if player hasn't got cash */ char *do_not_buy; /* If keeper dosn't buy such things. */ char *message_buy; /* Message when player buys item */ char *message_sell; /* Message when player sells item */ int temper1; /* How does keeper react if no money */ int temper2; /* How does keeper react when attacked */ int keeper; /* The mobil who owns the shop (virtual) */ int with_who; /* Who does the shop trade with? */ int in_room; /* Where is the shop? */ int open1, open2; /* When does the shop open? */ int close1, close2; /* When does the shop close? */ }; extern struct room_data *world; extern struct time_info_data time_info; struct shop_data *shop_index; int number_of_shops; int is_ok (struct char_data *keeper, struct char_data *ch, int shop_nr) { if (shop_index[shop_nr].open1 > time_info.hours) { do_say (keeper, "Come back later!", 17); return (FALSE); } else if (shop_index[shop_nr].close1 < time_info.hours) if (shop_index[shop_nr].open2 > time_info.hours) { do_say (keeper, "Sorry, we have closed, but come back later.", 17); return (FALSE); } else if (shop_index[shop_nr].close2 < time_info.hours) { do_say (keeper, "Sorry, come back tomorrow.", 17); return (FALSE); }; if (!(CAN_SEE (keeper, ch))) { do_say (keeper, "I don't trade with someone I can't see!", 17); return (FALSE); }; switch (shop_index[shop_nr].with_who) { case 0: return (TRUE); case 1: return (TRUE); default: return (TRUE); }; } int trade_with (struct obj_data *item, int shop_nr) { int counter; if (item->obj_flags.cost < 1) return (FALSE); for (counter = 0; counter < MAX_TRADE; counter++) if (shop_index[shop_nr].type[counter] == item->obj_flags.type_flag) return (TRUE); return (FALSE); } int shop_producing (struct obj_data *item, int shop_nr) { int counter; if (item->item_number < 0) return (FALSE); for (counter = 0; counter < MAX_PROD; counter++) if (shop_index[shop_nr].producing[counter] == item->item_number) return (TRUE); return (FALSE); } void shopping_buy (char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char argm[100], buf[MAX_STRING_LENGTH]; struct obj_data *temp1; struct char_data *temp_char; if (!(is_ok (keeper, ch, shop_nr))) return; one_argument (arg, argm); if (!(*argm)) { sprintf (buf, "%s what do you want to buy??", GET_NAME (ch)); do_tell (keeper, buf, 19); return; }; if (!(temp1 = get_obj_in_list_vis (ch, argm, keeper->carrying))) { sprintf (buf, shop_index[shop_nr].no_such_item1, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (temp1->obj_flags.cost <= 0) { sprintf (buf, shop_index[shop_nr].no_such_item1, GET_NAME (ch)); do_tell (keeper, buf, 19); extract_obj (temp1); return; } if (GET_GOLD (ch) < (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy) && GET_LEVEL (ch) < 22) { sprintf (buf, shop_index[shop_nr].missing_cash2, GET_NAME (ch)); do_tell (keeper, buf, 19); switch (shop_index[shop_nr].temper1) { case 0: do_action (keeper, GET_NAME (ch), 30); return; case 1: do_emote (keeper, "smokes on his joint", 36); return; default: return; } } if ((IS_CARRYING_N (ch) + 1 > CAN_CARRY_N (ch))) { sprintf (buf, "%s : You can't carry that many items.\n\r", fname (temp1->name)); send_to_char (buf, ch); return; } if ((IS_CARRYING_W (ch) + temp1->obj_flags.weight) > CAN_CARRY_W (ch)) { sprintf (buf, "%s : You can't carry that much weight.\n\r", fname (temp1->name)); send_to_char (buf, ch); return; } act ("$n buys $p.", FALSE, ch, temp1, 0, TO_ROOM); sprintf (buf, shop_index[shop_nr].message_buy, GET_NAME (ch), (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy)); do_tell (keeper, buf, 19); sprintf (buf, "You now have %s.\n\r", temp1->short_description); send_to_char (buf, ch); if (GET_LEVEL (ch) < 22) GET_GOLD (ch) -= (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy); GET_GOLD (keeper) += (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy); /* Test if producing shop ! */ if (shop_producing (temp1, shop_nr)) temp1 = read_object (temp1->item_number, REAL); else obj_from_char (temp1); obj_to_char (temp1, ch); return; } void shopping_sell (char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char argm[100], buf[MAX_STRING_LENGTH]; struct obj_data *temp1; struct char_data *temp_char; if (!(is_ok (keeper, ch, shop_nr))) return; one_argument (arg, argm); if (!(*argm)) { sprintf (buf, "%s What do you want to sell??", GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (!(temp1 = get_obj_in_list_vis (ch, argm, ch->carrying))) { sprintf (buf, shop_index[shop_nr].no_such_item2, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (!(trade_with (temp1, shop_nr)) || (temp1->obj_flags.cost < 1)) { sprintf (buf, shop_index[shop_nr].do_not_buy, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (GET_GOLD (keeper) < (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_sell)) { sprintf (buf, shop_index[shop_nr].missing_cash1, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } act ("$n sells $p.", FALSE, ch, temp1, 0, TO_ROOM); sprintf (buf, shop_index[shop_nr].message_sell, GET_NAME (ch), (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_sell)); do_tell (keeper, buf, 19); sprintf (buf, "The shopkeeper now has %s.\n\r", temp1->short_description); send_to_char (buf, ch); GET_GOLD (ch) += (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_sell); GET_GOLD (keeper) -= (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_sell); if ((get_obj_in_list (argm, keeper->carrying)) || (GET_ITEM_TYPE (temp1) == ITEM_TRASH)) extract_obj (temp1); else { obj_from_char (temp1); obj_to_char (temp1, keeper); } return; } void shopping_value (char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char argm[100], buf[MAX_STRING_LENGTH]; struct obj_data *temp1; if (!(is_ok (keeper, ch, shop_nr))) return; one_argument (arg, argm); if (!(*argm)) { sprintf (buf, "%s What do you want me to valuate??", GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (!(temp1 = get_obj_in_list_vis (ch, argm, ch->carrying))) { sprintf (buf, shop_index[shop_nr].no_such_item2, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } if (!(trade_with (temp1, shop_nr))) { sprintf (buf, shop_index[shop_nr].do_not_buy, GET_NAME (ch)); do_tell (keeper, buf, 19); return; } sprintf (buf, "%s I'll give you %d gold coins for that!", GET_NAME (ch), (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_sell)); do_tell (keeper, buf, 19); return; } void shopping_list (char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char buf[MAX_STRING_LENGTH], buf2[100], buf3[100]; struct obj_data *temp1; extern char *drinks[]; int found_obj; if (!(is_ok (keeper, ch, shop_nr))) return; strcpy (buf, "You can buy:\n\r"); found_obj = FALSE; if (keeper->carrying) for (temp1 = keeper->carrying; temp1; temp1 = temp1->next_content) if ((CAN_SEE_OBJ (ch, temp1)) && (temp1->obj_flags.cost > 0)) { found_obj = TRUE; if (temp1->obj_flags.type_flag != ITEM_DRINKCON) sprintf (buf2, "%s for %d gold coins.\n\r", (temp1->short_description) , (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy)); else { if (temp1->obj_flags.value[1]) sprintf (buf3, "%s of %s", (temp1->short_description) , drinks[temp1->obj_flags.value[2]]); else sprintf (buf3, "%s", (temp1->short_description)); sprintf (buf2, "%s for %d gold coins.\n\r", buf3, (int) (temp1->obj_flags.cost * shop_index[shop_nr].profit_buy)); } strcat (buf, CAP (buf2)); }; if (!found_obj) strcat (buf, "Nothing!\n\r"); send_to_char (buf, ch); return; } void shopping_kill (char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char buf[100]; switch (shop_index[shop_nr].temper2) { case 0: sprintf (buf, "%s Don't ever try that again!", GET_NAME (ch)); do_tell (keeper, buf, 19); return; case 1: sprintf (buf, "%s Scram - midget!", GET_NAME (ch)); do_tell (keeper, buf, 19); return; default: return; } } int shop_keeper (struct char_data *ch, int cmd, char *arg) { char argm[100], buf[MAX_STRING_LENGTH]; struct obj_data *temp1; struct char_data *temp_char; struct char_data *keeper; int shop_nr; keeper = 0; for (temp_char = world[ch->in_room].people; (!keeper) && (temp_char); temp_char = temp_char->next_in_room) if (IS_MOB (temp_char)) if (mob_index[temp_char->nr].func == shop_keeper) keeper = temp_char; for (shop_nr = 0; shop_index[shop_nr].keeper != keeper->nr; shop_nr++); if ((cmd == 56) && (ch->in_room == real_room (shop_index[shop_nr].in_room))) /* Buy */ { shopping_buy (arg, ch, keeper, shop_nr); return (TRUE); } if ((cmd == 57) && (ch->in_room == real_room (shop_index[shop_nr].in_room))) /* Sell */ { shopping_sell (arg, ch, keeper, shop_nr); return (TRUE); } if ((cmd == 58) && (ch->in_room == real_room (shop_index[shop_nr].in_room))) /* value */ { shopping_value (arg, ch, keeper, shop_nr); return (TRUE); } if ((cmd == 59) && (ch->in_room == real_room (shop_index[shop_nr].in_room))) /* List */ { shopping_list (arg, ch, keeper, shop_nr); return (TRUE); } /* if ((cmd == 25) || (cmd==70)) { one_argument(arg, argm); if (keeper == get_char_room(argm,ch->in_room)) { shopping_kill(arg,ch,keeper,shop_nr); return(TRUE); } } else if ((cmd==84) || (cmd==207) || (cmd==172)) { act("$N tells you 'No magic here - kid!'.", FALSE, ch, 0, keeper, TO_CHAR); return TRUE; } */ return (FALSE); } void boot_the_shops () { char *buf; int temp; int count; FILE *shop_f; if (!(shop_f = fopen (SHOP_FILE, "rb"))) { perror ("Error in boot shop\n"); WIN32CLEANUP exit (0); } number_of_shops = 0; for (;;) { buf = fread_string (shop_f); if (*buf == '#') { /* a new shop */ if (!number_of_shops) /* first shop */ CREATE (shop_index, struct shop_data, 1); else if (!(shop_index = (struct shop_data *) realloc (shop_index, (number_of_shops + 1) * sizeof (struct shop_data)))) { perror ("Error in boot shop\n"); WIN32CLEANUP exit (0); } for (count = 0; count < MAX_PROD; count++) { fscanf (shop_f, "%d \n", &temp); if (temp >= 0) shop_index[number_of_shops].producing[count] = real_object (temp); else shop_index[number_of_shops].producing[count] = temp; } fscanf (shop_f, "%f \n", &shop_index[number_of_shops].profit_buy); fscanf (shop_f, "%f \n", &shop_index[number_of_shops].profit_sell); for (count = 0; count < MAX_TRADE; count++) { fscanf (shop_f, "%d \n", &temp); shop_index[number_of_shops].type[count] = (byte) temp; } shop_index[number_of_shops].no_such_item1 = fread_string (shop_f); shop_index[number_of_shops].no_such_item2 = fread_string (shop_f); shop_index[number_of_shops].do_not_buy = fread_string (shop_f); shop_index[number_of_shops].missing_cash1 = fread_string (shop_f); shop_index[number_of_shops].missing_cash2 = fread_string (shop_f); shop_index[number_of_shops].message_buy = fread_string (shop_f); shop_index[number_of_shops].message_sell = fread_string (shop_f); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].temper1); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].temper2); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].keeper); shop_index[number_of_shops].keeper = real_mobile (shop_index[number_of_shops].keeper); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].with_who); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].in_room); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].open1); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].close1); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].open2); fscanf (shop_f, "%d \n", &shop_index[number_of_shops].close2); number_of_shops++; } else if (*buf == '$') /* EOF */ break; } fclose (shop_f); } void assign_the_shopkeepers () { int temp1; for (temp1 = 0; temp1 < number_of_shops; temp1++) mob_index[shop_index[temp1].keeper].func = shop_keeper; }