[crossfire] Shop prices overhaul

2014-11-30 Thread Kevin Zheng
Hi all,

At the moment, Crossfire's shops aren't particularly useful. For
medium-level players, prices seem unreasonable, while new players can't
afford to buy from shops at all. Old players with high charisma and
bargaining, on the other hand, don't notice a huge discrepancy.

The attached patch attempts to fix some of these issues:

Charisma and bargaining now only affect the shop buy price, with
multipliers ranging from 2x for new players to 0.5x for very advanced
players. This is consistent with rogue-style shopkeeper greed but still
better than the existing situation. Bargaining is now significantly less
useful; the hope is that in the near future it is replaced with
interactive haggling.

The sell price is clamped down to 0.5x base price, subject to additional
shop specialization and greed. This sell price is mostly better than the
existing prices, and at the very least prevents high level players from
buying and selling for a profit.

Comments, questions, clarifications, or hate mail?

Thanks,
Kevin Zheng

-- 
Kevin Zheng
kevinz5...@gmail.com | kev...@kd0lgh.mooo.com | PGP: 0xC22E1090
From 57871a24be5dd89f0c3778fd01472f4bae1523c2 Mon Sep 17 00:00:00 2001
From: Kevin Zheng kevinz5...@gmail.com
Date: Fri, 28 Nov 2014 18:57:03 -0600
Subject: [PATCH 1/6] Overhaul shop prices

Adjust charisma and bargaining price multipliers and apply them only to
buy prices, capped at 50% base value. Fix sell multiplier at 50% base
value, subject to additional shop specialization and greed.
---
 server/shop.c | 122 --
 1 file changed, 68 insertions(+), 54 deletions(-)

diff --git a/server/shop.c b/server/shop.c
index b817bc4..776b248 100644
--- a/server/shop.c
+++ b/server/shop.c
@@ -75,17 +75,17 @@ static const char *const coins[] = {
  * @param flag
  * @return
  */
-uint64_t price_base(const object *tmp, const int flag) {
+static uint64_t price_base(const object *tmp, const int flag) {
 const char *key;// Temporary place to hold key values
 
 // When there are zero objects, there is really one.
 int number = (tmp-nrof == 0) ? 1 : tmp-nrof;
 uint64_t val = (uint64_t)tmp-value * number;
 
-bool is_ident = (flag  BS_IDENTIFIED) || QUERY_FLAG(tmp, FLAG_IDENTIFIED)
-|| !need_identify(tmp);
-bool is_cursed = !(flag  BS_NOT_CURSED)  (QUERY_FLAG(tmp, FLAG_CURSED)
-|| QUERY_FLAG(tmp, FLAG_DAMNED));
+const bool is_ident = (flag  BS_IDENTIFIED)
+|| QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp);
+const bool is_cursed = !(flag  BS_NOT_CURSED)
+ (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED));
 
 // Objects with price adjustments skip the rest of the calculations.
 if ((key = object_get_value(tmp, price_adjustment)) != NULL) {
@@ -162,6 +162,33 @@ uint64_t price_base(const object *tmp, const int flag) {
 }
 
 /**
+ * Calculate the buy price multiplier based on a player's charisma.
+ * @param charisma Player's charisma
+ * @return Buy multiplier between 2 and 0.5
+ */
+static float shop_buy_multiplier(int charisma) {
+float multiplier = 1 / (0.38 * pow(1.06, charisma));
+
+if (multiplier  2) {
+return 2;
+} else if (multiplier  0.5) {
+return 0.5;
+} else {
+return multiplier;
+}
+}
+
+/**
+ * Calculate the buy price multiplier based on a player's bargaining skill.
+ * The reciprocal of this result can be used as a sell multiplier.
+ * @param lev_bargain Player's bargaining level
+ * @return Buy multiplier between 1 and 0.5
+ */
+static float shop_bargain_multiplier(int lev_bargain) {
+return 1 - 0.5 * lev_bargain / settings.max_level;
+}
+
+/**
  * Adjust the value of an item based on the player's bargaining skill and
  * charisma. This should only be used if the player is in a shop.
  * @param val Base item value
@@ -170,52 +197,29 @@ uint64_t price_base(const object *tmp, const int flag) {
  * @param flag Additional flags to use while determining value
  * @return Adjusted value of item
  */
-uint64_t price_adjust(uint64_t val, const object *tmp, object *who, const int flag) {
-float diff;
-int lev_bargain = 0;
-int lev_identify = 0;
-int idskill1 = 0;
-int idskill2 = 0;
-bool approximate = flag  BS_APPROX;
-bool no_bargain = flag  BS_NO_BARGAIN;
-
-/* ratio determines how much of the price modification
- * will come from the basic stat charisma
- * the rest will come from the level in bargaining skill
- */
-const float ratio = 0.5;
-const typedata *tmptype = get_typedata(tmp-type);
+static uint64_t shop_price_adjust(uint64_t val, const object *tmp, object *who, const int flag) {
+const bool approximate = flag  BS_APPROX;
+const bool no_bargain = flag  BS_NO_BARGAIN;
+int lev_bargain;
+float multiplier;
 
 if (find_skill_by_number(who, SK_BARGAINING)) {
 lev_bargain = find_skill_by_number(who, SK_BARGAINING)-level;
 }
-if 

Re: [crossfire] Shop prices overhaul

2014-11-30 Thread Steven Lembark

 Comments, questions, clarifications, or hate mail?

Nice idea.

-- 
Steven Lembark 3646 Flora Pl
Workhorse Computing   St Louis, MO 63110
lemb...@wrkhors.com  +1 888 359 3508
___
crossfire mailing list
crossfire@metalforge.org
http://mailman.metalforge.org/mailman/listinfo/crossfire