#include <stdio.h> #include <string.h> #include <stdlib.h> #include <malloc.h> #include "structs.h" #include "comm.h" #include "handler.h" #include "db.h" #include "interpreter.h" #include "utils.h" #define SHOP_FILE "tinyworld.shp" #define MAX_TRADE 5 #define MAX_PROD 5 #define MAX_SALE_ITEMS 100 #define MAXSHOPMESS 4 char *no_such_item1[]={ "%s Haven't got that on storage - try LIST.", "%s I don't have any of those.", "%s I don't sell those, try Home Depot.", "%s I don't deal in that kind crap.", "%s Do you see any of those around here? I don't." }; char *no_such_item2[]={ "%s You don't seem to have that.", "%s You don't have any.", "%s Where are you hiding it?", "%s I don't think you have any.", "%s Who are you trying to kid?" }; char *do_not_buy[]={ "%s I don't buy THAT. Try another shop.", "%s I don't want it.", "%s I don't need it.", "%s Looks like trash to me, no thanks.", "%s Go drop that in the dump." }; char *missing_cash[]={ "%s You seem a little short on coins, pal.", "%s Sorry, I don't give credit.", "%s Go stop at the bank first.", "%s On your budget? No chance.", "%s My price is too high for you. Scram." }; char *message_buy[]={ "%s That'll be %d coins, thank you.", "%s Yours for only %d coins.", "%s I'll take your %d coins, thanks.", "%s A shrewd investment for only %d coins.", "%s Here it is. I'll take %d coins." }; char *message_sell[]={ "%s You'd get %d coins for it.", "%s That's worth %d coins.", "%s That's worth %d coins.", "%s That's worth %d coins.", "%s I'd give you %d coins and not a penny more." }; struct sale_item { int n; int k; struct obj_data *p; } salelist[MAX_SALE_ITEMS]; /* extern struct str_app_type str_app[]; */ extern struct index_data *mob_index; extern struct index_data *obj_index; extern char *apply_types[]; char *fread_string(FILE *fl); void show_item_list(char buffer[], int shop_nr); int fill_item_list(struct obj_data *h); void object_identify_to_char(struct char_data *ch, struct obj_data *o); 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. */ 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); if(shop_index[shop_nr].type[0] == -2) return TRUE; 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_appraise( char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr) { char argm[100], buf[MAX_STRING_LENGTH]; struct obj_data *temp1; int k,n; if(!(is_ok(keeper,ch,shop_nr))) return; one_argument(arg, argm); if(!(*argm)) { sprintf(buf,"%s what do you want to appraise?",GET_NAME(ch)); do_tell(keeper,buf,19); return; } if(isdigit(*argm)){ n = fill_item_list(keeper->carrying); k = atoi(argm) - 1; if((k < 0)||(k >= n)){ sprintf(buf, no_such_item1[number(0,MAXSHOPMESS)],GET_NAME(ch)); do_tell(keeper,buf,19); return; } temp1 = salelist[k].p; } else if(!( temp1 = get_obj_in_list_vis(ch,argm,keeper->carrying))) { sprintf(buf, no_such_item1[number(0,MAXSHOPMESS)],GET_NAME(ch)); do_tell(keeper,buf,19); return; } object_identify_to_char(ch,temp1); return; } 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; int k,n; 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(isdigit(*argm)){ n = fill_item_list(keeper->carrying); k = atoi(argm) - 1; if((k < 0)||(k >= n)){ sprintf(buf, no_such_item1[number(0,MAXSHOPMESS)],GET_NAME(ch)); do_tell(keeper,buf,19); return; } temp1 = salelist[k].p; } else if(!( temp1 = get_obj_in_list_vis(ch,argm,keeper->carrying))) { sprintf(buf, no_such_item1[number(0,MAXSHOPMESS)],GET_NAME(ch)); do_tell(keeper,buf,19); return; } if(temp1->obj_flags.cost <= 0) { sprintf(buf, no_such_item1[number(0,MAXSHOPMESS)],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)<(IMO+1)) { sprintf(buf, missing_cash[number(0,MAXSHOPMESS)],GET_NAME(ch)); do_tell(keeper,buf,19); 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)) { strcpy(buf,"I guess it's too heavy for you.\n\r"); send_to_char(buf, ch); return; } act("$n buys $p.", FALSE, ch, temp1, 0, TO_ROOM); sprintf(buf, message_buy[number(0,MAXSHOPMESS)], 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) <= IMO) GET_GOLD(ch)-=(int)(temp1->obj_flags.cost* shop_index[shop_nr].profit_buy); 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, no_such_item2[number(0,MAXSHOPMESS)] ,GET_NAME(ch)); do_tell(keeper,buf,19); return; } if(!(trade_with(temp1,shop_nr))||(temp1->obj_flags.cost<1)) { sprintf(buf, do_not_buy[number(0,MAXSHOPMESS)], GET_NAME(ch)); do_tell(keeper,buf,19); return; } act("$n sells $p.", FALSE, ch, temp1, 0, TO_ROOM); sprintf(buf,message_sell[number(0,MAXSHOPMESS)], 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); 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,no_such_item2[number(0,MAXSHOPMESS)], GET_NAME(ch)); do_tell(keeper,buf,19); return; } if(!(trade_with(temp1,shop_nr))) { sprintf(buf, do_not_buy[number(0,MAXSHOPMESS)], GET_NAME(ch)); do_tell(keeper,buf,19); return; } sprintf(buf,message_sell[number(0,MAXSHOPMESS)], 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 buffer[8*MAX_STRING_LENGTH]; int n; if(!(is_ok(keeper,ch,shop_nr))) return; n = fill_item_list(keeper->carrying); if(n > 0){ show_item_list(buffer,shop_nr); page_string(ch->desc, buffer, 1); } else send_to_char("Nothing for sale.\n\r",ch); } 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,n; 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 == 298) && (ch->in_room == real_room(shop_index[shop_nr].in_room))) { shopping_appraise(arg,ch,keeper,shop_nr); return(TRUE); } if((cmd == 56) && (ch->in_room == real_room(shop_index[shop_nr].in_room))) { 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 == 156){ send_to_char("Oops.\n\r",ch); hit(keeper,ch,-1); return(TRUE); } if ((cmd==84) || (cmd==207) || (cmd==172)) { /* Cast, recite, use */ 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, "r"))) { perror("Error in boot shop\n"); exit(0); } number_of_shops = 0; for(;;) { buf = fread_string(shop_f); if(*buf == '#') { if(!number_of_shops) 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"); 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; } 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 == '$'){ break; } } fclose(shop_f); } void assign_the_shopkeepers() { int i; for(i=0 ; i<number_of_shops ; i++) mob_index[shop_index[i].keeper].func = shop_keeper; } int fill_item_list(struct obj_data *h) { struct obj_data *p; int f,i,j,k,n=0; for(p=h;p;p=p->next_content){ f = 0; k = p->item_number; for(i=0;i<n;i++) if(salelist[i].k == k){ f = 1; salelist[i].n++; break; } if(!f){ salelist[n].n = 1; salelist[n].k = k; salelist[n].p = p; n++; if(n==(MAX_SALE_ITEMS-1)) break; } } salelist[n].p = 0; return n; } void show_item_list(char buffer[], int shop_nr) { int i; char tbuf[256]; struct obj_data *p; strcpy(buffer,"You can buy:\n\r"); for(i=0;salelist[i].p;i++){ p = salelist[i].p; sprintf(tbuf,"%2d: %-30.30s%7d (%2d)\n\r", i+1, p->short_description, (int)(p->obj_flags.cost * shop_index[shop_nr].profit_buy), salelist[i].n); strcat(buffer,tbuf); } } void object_identify_to_char(struct char_data *ch, struct obj_data *j) { int i,virtual; char buf[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; extern char *item_types[]; extern char *wear_bits[]; extern char *extra_bits[]; extern char *drinks[]; virtual = (j->item_number >= 0) ? obj_index[j->item_number].virtual : 0; sprintf(buf,"%s: ",j->short_description); sprinttype(GET_ITEM_TYPE(j),item_types,buf2); strcat(buf,buf2); strcat(buf,"\n\r"); send_to_char(buf, ch); sprintf(buf,"Wgt: %d, Value: %d, Rent Lev: %d\n\r", j->obj_flags.weight,j->obj_flags.cost,j->obj_flags.rentlevel); send_to_char(buf, ch); send_to_char("Worn: ", ch); sprintbit(0x7ffffffe & j->obj_flags.wear_flags,wear_bits,buf); strcat(buf,"\n\r"); send_to_char(buf, ch); switch(GET_ITEM_TYPE(j)){ case ITEM_WEAPON: sprintf(buf,"Damage dice: %dd%d\n\r", j->obj_flags.value[1], j->obj_flags.value[2]); break; case ITEM_ARMOR: sprintf(buf,"Armor value: %d\n\r", j->obj_flags.value[0]); break; default: strcpy(buf,"More on this type of item later.\n\r"); break; } send_to_char(buf, ch); for (i=0;i<MAX_OBJ_AFFECT;++i) { if(!j->affected[i].location) continue; sprinttype(j->affected[i].location,apply_types,buf2); sprintf(buf," Affects: %s by %d\n\r",buf2,j->affected[i].modifier); send_to_char(buf, ch); } }