-+-+-+-+-+-+-+-+ START OF PART 68 -+-+-+-+-+-+-+-+
X`09(void) sprintf(out_val2,"%9ld `5BFixed`5D", x);
X      prt(out_val2, i+5, 59);
X      i++;
X      start++;
X    `7D
X  if (i < 12)
X    for (j = 0; j < (11 - i + 1); j++)
X      erase_line (j+i+5, 0); /* clear remaining lines */
X  if (s_ptr->store_ctr > 12)
X    put_buffer("- cont. -", 17, 60);
X  else
X    erase_line (17, 60);
X`7D
X
X
X/* Re-displays only a single cost`09`09`09-RAK-`09*/
Xstatic void display_cost(store_num, pos)
Xint store_num, pos;
X`7B
X  register int i;
X  register int32 j;
X  vtype out_val;
X  register store_type *s_ptr;
X
X  s_ptr = &store`5Bstore_num`5D;
X  i = (pos % 12);
X  if (s_ptr->store_inven`5Bpos`5D.scost < 0)
X    `7B
X      j = - s_ptr->store_inven`5Bpos`5D.scost;
X      j = j * chr_adj() / 100;
X      (void) sprintf(out_val, "%ld", j);
X    `7D
X  else
X    (void) sprintf(out_val, "%9ld `5BFixed`5D", s_ptr->store_inven`5Bpos`5D.
Vscost);
X  prt(out_val, i+5, 59);
X`7D
X
X
X/* Displays players gold`09`09`09`09`09-RAK-`09*/
Xstatic void store_prt_gold()
X`7B
X  vtype out_val;
X
X  (void) sprintf(out_val, "Gold Remaining : %ld", py.misc.au);
X  prt(out_val, 18, 17);
X`7D
X
X
X/* Displays store`09`09`09`09`09-RAK-`09*/
Xstatic void display_store(store_num, cur_top)
Xint store_num, cur_top;
X`7B
X  register store_type *s_ptr;
X
X  s_ptr = &store`5Bstore_num`5D;
X  clear_screen();
X  put_buffer(owners`5Bs_ptr->owner`5D.owner_name, 3, 9);
X  put_buffer("Item", 4, 3);
X  put_buffer("Asking Price", 4, 60);
X  store_prt_gold();
X  display_commands();
X  display_inventory(store_num, cur_top);
X`7D
X
X
X/* Get the ID of a store item and return it's value`09-RAK-`09*/
Xstatic int get_store_item(com_val, pmt, i, j)
Xint *com_val;
Xchar *pmt;
Xregister int i, j;
X`7B
X  char command;
X  vtype out_val;
X  register int flag;
X
X  *com_val = -1;
X  flag = FALSE;
X  (void) sprintf(out_val, "(Items %c-%c, ESC to exit) %s", i+'a', j+'a', pmt
V);
X  while (get_com(out_val, &command))
X    `7B
X      command -= 'a';
X      if (command >= i && command <= j)
X`09`7B
X`09  flag = TRUE;
X`09  *com_val = command;
X`09  break;
X`09`7D
X      bell();
X    `7D
X  erase_line(MSG_LINE, 0);
X  return(flag);
X`7D
X
X
X/* Increase the insult counter and get angry if too many -RAK-`09*/
Xstatic int increase_insults(store_num)
Xint store_num;
X`7B
X  register int increase;
X  register store_type *s_ptr;
X
X  increase = FALSE;
X  s_ptr = &store`5Bstore_num`5D;
X  s_ptr->insult_cur++;
X  if (s_ptr->insult_cur > owners`5Bs_ptr->owner`5D.insult_max)
X    `7B
X      prt_comment4();
X      s_ptr->insult_cur = 0;
X      s_ptr->good_buy = 0;
X      s_ptr->bad_buy = 0;
X      s_ptr->store_open = turn + 2500 + randint(2500);
X      increase = TRUE;
X    `7D
X  return(increase);
X`7D
X
X
X/* Decrease insults`09`09`09`09`09-RAK-`09*/
Xstatic void decrease_insults(store_num)
Xint store_num;
X`7B
X  register store_type *s_ptr;
X
X  s_ptr = &store`5Bstore_num`5D;
X  if (s_ptr->insult_cur != 0)
X    s_ptr->insult_cur--;
X`7D
X
X
X/* Have insulted while haggling`09`09`09`09-RAK-`09*/
Xstatic int haggle_insults(store_num)
Xint store_num;
X`7B
X  register int haggle;
X
X  haggle = FALSE;
X  if (increase_insults(store_num))
X    haggle = TRUE;
X  else
X    `7B
X      prt_comment5();
X      msg_print (CNIL); /* keep insult separate from rest of haggle */
X    `7D
X  return(haggle);
X`7D
X
X
Xstatic int get_haggle(comment, new_offer, num_offer)
Xchar *comment;
Xint32 *new_offer;
Xint num_offer;
X`7B
X  register int32 i;
X  vtype out_val, default_offer;
X  register int flag, clen;
X  int orig_clen;
X  register char *p;
X  int increment;
X
X  flag = TRUE;
X  increment = FALSE;
X  clen = strlen(comment);
X  orig_clen = clen;
X  if (num_offer == 0)
X    last_store_inc = 0;
X  i = 0;
X  do
X    `7B
X      prt(comment, 0, 0);
X      if (num_offer && last_store_inc != 0)
X`09`7B
X`09  (void) sprintf (default_offer, "`5B%c%d`5D ",
X`09`09`09  (last_store_inc < 0) ? '-' : '+',
X`09`09`09  abs (last_store_inc));
X`09  prt (default_offer, 0, orig_clen);
X`09  clen = orig_clen + strlen (default_offer);
X`09`7D
X      if (!get_string(out_val, 0, clen, 40))
X`09flag = FALSE;
X      for (p = out_val; *p == ' '; p++)
X`09;
X      if (*p == '+' `7C`7C *p == '-')
X`09increment = TRUE;
X      if (num_offer && increment)
X`09`7B
X`09  i = atol (out_val);
X`09  /* Don't accept a zero here.  Turn off increment if it was zero
X`09     because a zero will not exit.  This can be zero if the user
X`09     did not type a number after the +/- sign.  */
X`09  if (i == 0)
X`09    increment = FALSE;
X`09  else
X`09    last_store_inc = i;
X`09`7D
X      else if (num_offer && *out_val == '\0')
X`09`7B
X`09  i = last_store_inc;
X`09  increment = TRUE;
X`09`7D
X      else
X`09i = atol (out_val);
X
X      /* don't allow incremental haggling, if player has not made an offer
X`09 yet */
X      if (flag && num_offer == 0 && increment)
X`09`7B
X`09  msg_print("You haven't even made your first offer yet!");
X`09  i = 0;
X`09  increment = FALSE;
X`09`7D
X    `7D
X  while (flag && (i == 0));
X  if (flag)
X    `7B
X      if (increment)
X`09*new_offer += i;
X      else
X`09*new_offer = i;
X    `7D
X  else
X    erase_line (0, 0);
X  return(flag);
X`7D
X
X
Xstatic int receive_offer(store_num, comment, new_offer, last_offer,
X`09`09`09 num_offer, factor)
Xint store_num;
Xchar *comment;
Xregister int32 *new_offer, last_offer;
Xint num_offer, factor;
X`7B
X  register int flag;
X  register int receive;
X
X  receive = 0;
X  flag = FALSE;
X  do
X    `7B
X      if (get_haggle(comment, new_offer, num_offer))
X`09`7B
X`09  if (*new_offer*factor >= last_offer*factor)
X`09    flag = TRUE;
X`09  else if (haggle_insults(store_num))
X`09    `7B
X`09      receive = 2;
X`09      flag = TRUE;
X`09    `7D
X`09  else
X`09    /* new_offer rejected, reset new_offer so that incremental
X`09       haggling works correctly */
X`09    *new_offer = last_offer;
X`09`7D
X      else
X`09`7B
X`09  receive = 1;
X`09  flag = TRUE;
X`09`7D
X    `7D
X  while (!flag);
X  return(receive);
X`7D
X
X
X/* Haggling routine`09`09`09`09`09-RAK-`09*/
Xstatic int purchase_haggle(store_num, price, item)
Xint store_num;
Xint32 *price;
Xinven_type *item;
X`7B
X  int32 max_sell, min_sell, max_buy;
X  int32 cost, cur_ask, final_ask, min_offer;
X  int32 last_offer, new_offer;
X  int32 x1, x2, x3;
X  int32 min_per, max_per;
X  register int flag, loop_flag;
X  char *comment;
X  vtype out_val;
X  int purchase, num_offer, final_flag, didnt_haggle;
X  register store_type *s_ptr;
X  register owner_type *o_ptr;
X
X  flag = FALSE;
X  purchase = 0;
X  *price = 0;
X  final_flag = 0;
X  didnt_haggle = FALSE;
X  s_ptr = &store`5Bstore_num`5D;
X  o_ptr = &owners`5Bs_ptr->owner`5D;
X  cost = sell_price(store_num, &max_sell, &min_sell, item);
X  max_sell = max_sell * chr_adj() / 100;
X  if (max_sell <= 0)  max_sell = 1;
X  min_sell = min_sell * chr_adj() / 100;
X  if (min_sell <= 0)  min_sell = 1;
X  /* cast max_inflate to signed so that subtraction works correctly */
X  max_buy  = cost * (200 - (int)o_ptr->max_inflate) / 100;
X  if (max_buy <= 0) max_buy = 1;
X  min_per  = o_ptr->haggle_per;
X  max_per  = min_per * 3;
X  haggle_commands(1);
X  cur_ask   = max_sell;
X  final_ask = min_sell;
X  min_offer = max_buy;
X  last_offer = min_offer;
X  new_offer = 0;
X  num_offer = 0; /* this prevents incremental haggling on first try */
X  comment = "Asking";
X
X  /* go right to final price if player has bargained well */
X  if (noneedtobargain(store_num, final_ask))
X    `7B
X      msg_print("After a long bargaining session, you agree upon the price."
V);
X      cur_ask = min_sell;
X      comment = "Final offer";
X      didnt_haggle = TRUE;
X
X      /* Set up automatic increment, so that a return will accept the
X`09 final price.  */
X      last_store_inc = min_sell;
X      num_offer = 1;
X    `7D
X
X  do
X    `7B
X      do
X`09`7B
X`09  loop_flag = TRUE;
X`09  (void) sprintf(out_val, "%s :  %ld", comment, cur_ask);
X`09  put_buffer(out_val, 1, 0);
X`09  purchase = receive_offer(store_num, "What do you offer? ",
X`09`09`09`09   &new_offer, last_offer, num_offer, 1);
X`09  if (purchase != 0)
X`09    flag = TRUE;
X`09  else
X`09    `7B
X`09      if (new_offer > cur_ask)
X`09`09`7B
X`09`09  prt_comment6();
X`09`09  /* rejected, reset new_offer for incremental haggling */
X`09`09  new_offer = last_offer;
X
X`09`09  /* If the automatic increment is large enough to overflow,
X`09`09     then the player must have made a mistake.  Clear it
X`09`09     because it is useless.  */
X`09`09  if (last_offer + last_store_inc > cur_ask)
X`09`09    last_store_inc = 0;
X`09`09`7D
X`09      else if (new_offer == cur_ask)
X`09`09`7B
X`09`09  flag = TRUE;
X`09`09  *price = new_offer;
X`09`09`7D
X`09      else
X`09`09loop_flag = FALSE;
X`09    `7D
X`09`7D
X      while (!flag && loop_flag);
X      if (!flag)
X`09`7B
X`09  x1 = (new_offer - last_offer) * 100 / (cur_ask - last_offer);
X`09  if (x1 < min_per)
X`09    `7B
X`09      flag = haggle_insults(store_num);
X`09      if (flag)`09 purchase = 2;
X`09    `7D
X`09  else if (x1 > max_per)
X`09    `7B
X`09      x1 = x1 * 75 / 100;
X`09      if (x1 < max_per)`09 x1 = max_per;
X`09    `7D
X`09  x2 = x1 + randint(5) - 3;
X`09  x3 = ((cur_ask - new_offer) * x2 / 100) + 1;
X`09  /* don't let the price go up */
X`09  if (x3 < 0)
X`09    x3 = 0;
X`09  cur_ask -= x3;
X`09  if (cur_ask < final_ask)
X`09    `7B
X`09      cur_ask = final_ask;
X`09      comment = "Final Offer";
X`09      /* Set the automatic haggle increment so that RET will give
X`09`09 a new_offer equal to the final_ask price.  */
X`09      last_store_inc = final_ask - new_offer;
X`09      final_flag++;
X`09      if (final_flag > 3)
X`09`09`7B
X`09`09  if (increase_insults(store_num))
X`09`09    purchase = 2;
X`09`09  else
X`09`09    purchase = 1;
X`09`09  flag = TRUE;
X`09`09`7D
X`09    `7D
X`09  else if (new_offer >= cur_ask)
X`09    `7B
X`09      flag = TRUE;
X`09      *price = new_offer;
X`09    `7D
X`09  if (!flag)
X`09    `7B
X`09      last_offer = new_offer;
X`09      num_offer++; /* enable incremental haggling */
X`09      erase_line (1, 0);
X`09      (void) sprintf(out_val, "Your last offer : %ld", last_offer);
X`09      put_buffer(out_val, 1, 39);
X`09      prt_comment2(last_offer, cur_ask, final_flag);
X
X`09      /* If the current increment would take you over the store's
X`09`09 price, then decrease it to an exact match.  */
X`09      if (cur_ask - last_offer < last_store_inc)
X`09`09last_store_inc = cur_ask - last_offer;
X`09    `7D
X`09`7D
X    `7D
X  while (!flag);
X
X  /* update bargaining info */
X  if ((purchase == 0) && (!didnt_haggle))
X    updatebargain(store_num, *price, final_ask);
X
X  return(purchase);
X`7D
X
X
X/* Haggling routine`09`09`09`09`09-RAK-`09*/
Xstatic int sell_haggle(store_num, price, item)
Xint store_num;
Xint32 *price;
Xinven_type *item;
X`7B
X  int32 max_sell, max_buy, min_buy;
X  int32 cost, cur_ask, final_ask, min_offer;
X  int32 last_offer, new_offer;
X  int32 max_gold;
X  int32 x1, x2, x3;
X  int32 min_per, max_per;
X  register int flag, loop_flag;
X  char *comment;
X  vtype out_val;
X  register store_type *s_ptr;
X  register owner_type *o_ptr;
X  int sell, num_offer, final_flag, didnt_haggle;
X
X  flag = FALSE;
X  sell = 0;
X  *price = 0;
X  final_flag = 0;
X  didnt_haggle = FALSE;
X  s_ptr = &store`5Bstore_num`5D;
X  cost = item_value(item);
X  if (cost < 1)
X    `7B
X      sell = 3;
X      flag = TRUE;
X    `7D
X  else
X    `7B
X      o_ptr = &owners`5Bs_ptr->owner`5D;
X      cost = cost * (200 - chr_adj()) / 100;
X      cost = cost * (200 - rgold_adj`5Bo_ptr->owner_race`5D`5Bpy.misc.prace`
V5D) / 100;
X      if (cost < 1)  cost = 1;
X      max_sell = cost * o_ptr->max_inflate / 100;
X      /* cast max_inflate to signed so that subtraction works correctly */
X      max_buy  = cost * (200 - (int)o_ptr->max_inflate) / 100;
X      min_buy  = cost * (200 - o_ptr->min_inflate) / 100;
X      if (min_buy < 1) min_buy = 1;
X      if (max_buy < 1) max_buy = 1;
X      if (min_buy < max_buy)  min_buy = max_buy;
X      min_per  = o_ptr->haggle_per;
X      max_per  = min_per * 3;
X      max_gold = o_ptr->max_cost;
X    `7D
X  if (!flag)
X    `7B
X      haggle_commands(-1);
X      num_offer = 0; /* this prevents incremental haggling on first try */
X      if (max_buy > max_gold)
X`09`7B
X`09  final_flag= 1;
X`09  comment = "Final Offer";
X`09  /* Disable the automatic haggle increment on RET.  */
X`09  last_store_inc = 0;
X`09  cur_ask   = max_gold;
X`09  final_ask = max_gold;
X`09  msg_print("I am sorry, but I have not the money to afford such \
Xa fine item.");
X`09  didnt_haggle = TRUE;
X`09`7D
X      else
X`09`7B
X`09  cur_ask   = max_buy;
X`09  final_ask = min_buy;
X`09  if (final_ask > max_gold)
X`09    final_ask = max_gold;
X`09  comment = "Offer";
X
X`09  /* go right to final price if player has bargained well */
X          if (noneedtobargain(store_num, final_ask))
X`09    `7B
X`09      msg_print("After a long bargaining session, you agree upon \
Xthe price.");
X              cur_ask = final_ask;
X`09      comment = "Final offer";
X`09      didnt_haggle = TRUE;
X
X`09      /* Set up automatic increment, so that a return will accept the
X`09`09 final price.  */
X`09      last_store_inc = final_ask;
X`09      num_offer = 1;
X            `7D
X`09`7D
X      min_offer = max_sell;
X      last_offer = min_offer;
X      new_offer = 0;
X      if (cur_ask < 1)`09cur_ask = 1;
X      do
X`09`7B
X`09  do
X`09    `7B
X`09      loop_flag = TRUE;
X`09      (void) sprintf(out_val, "%s :  %ld", comment, cur_ask);
X`09      put_buffer(out_val, 1, 0);
X`09      sell = receive_offer(store_num, "What price do you ask? ",
X`09`09`09`09 &new_offer, last_offer, num_offer, -1);
X`09      if (sell != 0)
X`09`09flag   = TRUE;
X`09      else
X`09`09`7B
X`09`09  if (new_offer < cur_ask)
X`09`09    `7B
X`09`09      prt_comment6();
X`09`09      /* rejected, reset new_offer for incremental haggling */
X`09`09      new_offer = last_offer;
X
X`09`09      /* If the automatic increment is large enough to
X`09`09`09 overflow, then the player must have made a mistake.
+-+-+-+-+-+-+-+-  END  OF PART 68 +-+-+-+-+-+-+-+-
