Floats and Ints question

  • Papaya Pete
  • Topic Author
  • Offline
  • Gold Boarder
  • Gold Boarder
More
4 years 10 months ago #4522 by Papaya Pete
Floats and Ints question was created by Papaya Pete
So I'm trying to figure out how to fix a bug in the item durability snippet. It's regarding buy and sell prices; I thought I had taken care of it, but I guess I didn't test it out enough. I'll stick to just selling things, for now.

So here's the problem; if an item has, say, 150 max durability, and the item is damaged at all, it will have a selling price (e.g. you get x coins!) of 0, even if it only has 1 point of durability damage. However, if the item has less than a max durability of 100, there is no issue; the code works fine as is.

I'm figuring it has something to do with how the percentage is figured out or something. I hate trying to work with int and float variables at the same time, but I don't really see any way around it. Here's the function for figuring out selling prices.
static int sell_price(struct obj_data *obj, int shop_nr, struct char_data *keeper, struct char_data *seller)
{
  float sell_cost_modifier = SHOP_SELLPROFIT(shop_nr) * (1 - (GET_CHA(keeper) - GET_CHA(seller)) / (float)70);
  float buy_cost_modifier = SHOP_BUYPROFIT(shop_nr) * (1 + (GET_CHA(keeper) - GET_CHA(seller)) / (float)70);
  int itemcond = (100 / GET_OBJ_MAX_DURAB(obj)) * GET_OBJ_DURABILITY(obj);
  float percent = 1, sellprice = 0;

    if ((GET_OBJ_MAX_DURAB(obj) != 0) && (GET_OBJ_MAX_DURAB(obj) > GET_OBJ_DURABILITY(obj))) {
        if (itemcond == 0)
            percent = 0;
          else if (itemcond <= 10)
            percent = 0.1;
          else if (itemcond <= 20)
            percent = 0.2;
          else if (itemcond <= 30)
            percent = 0.3;
          else if (itemcond <= 40)
            percent = 0.4;
          else if (itemcond <= 50)
            percent = 0.5;
          else if (itemcond <= 60)
            percent = 0.6;
          else if (itemcond <= 70)
            percent = 0.7;
          else if (itemcond <= 80)
            percent = 0.8;
          else if (itemcond <= 90)
            percent = 0.9;
          else if (itemcond <= 99)
            percent = 0.99;
    }

  sellprice = GET_OBJ_COST(obj) * sell_cost_modifier * percent;
  if (sell_cost_modifier > buy_cost_modifier)
    sell_cost_modifier = buy_cost_modifier;

  return (sellprice);
}

On a side note, been alpha testing out my mud and squashing quite a few bugs. Like regarding parry and dodge skills... turns out I messed that one up pretty bad. Oops! Anyways, any help on this would be greatly appreciated. :)

Please Log in or Create an account to join the conversation.

More
4 years 10 months ago #4523 by Krell
Replied by Krell on topic Floats and Ints question
You're declaring that the function will return an int, but at the end of the function you return a variable of type float. I think C automatically will convert the value to the correct type if it can. Maybe you should make your function of type float and see if that makes a difference?
The following user(s) said Thank You: Papaya Pete

Please Log in or Create an account to join the conversation.

More
4 years 10 months ago #4524 by thomas
Replied by thomas on topic Floats and Ints question
int itemcond = (100 / GET_OBJ_MAX_DURAB(obj)) * GET_OBJ_DURABILITY(obj);

should be the other way around, and a float:
float itemcond = GET_OBJ_DURABILITY(obj) / GET_OBJ_MAX_DURAB(obj);
And you should explicitly cast your price to int:
return (int) sellprice;
The following user(s) said Thank You: Papaya Pete

Please Log in or Create an account to join the conversation.

  • Papaya Pete
  • Topic Author
  • Offline
  • Gold Boarder
  • Gold Boarder
More
4 years 10 months ago #4527 by Papaya Pete
Replied by Papaya Pete on topic Floats and Ints question
Well, I thought I had gotten this fixed... but it turns out there's a problem with how C is handling this. The way I posted it above, it will work just fine if the item's max durability is 100 or less. If it's higher than that... it screws up the math, and just sets the buying price to 0. Very frustrating when my calculator does the math right but the program doesn't.

Please Log in or Create an account to join the conversation.

  • Papaya Pete
  • Topic Author
  • Offline
  • Gold Boarder
  • Gold Boarder
More
4 years 10 months ago #4528 by Papaya Pete
Replied by Papaya Pete on topic Floats and Ints question
Ok, I figured out what was going on. For some reason, when using GET_OBJ_DURABILITY and GET_OBJ_MAX_DURAB directly when computing itemcond, it was (I'm guessing) rounding it to the nearest integer (so in the case of a max durability of 110... when trying to perform 100 / 110, it would give a value of 0). Testing it out, it looks like now it works...

... I hope!
static int buy_price(struct obj_data *obj, int shop_nr, struct char_data *keeper, struct char_data *buyer)
{
  float itemcond = 0;
  float percent = 1, maxdurab = 0, durab = 0;
  float buyprice = 0, reduceprice = 0;

  maxdurab = GET_OBJ_MAX_DURAB(obj);
  durab = GET_OBJ_DURABILITY(obj);
  itemcond = (100 / maxdurab) * durab;
    if ((GET_OBJ_MAX_DURAB(obj) != 0) && (GET_OBJ_MAX_DURAB(obj) > GET_OBJ_DURABILITY(obj))) {
        if (itemcond == 0)
            percent = 0;
          else if (itemcond < 10)
            percent = 0.05;
          else if (itemcond < 20)
            percent = 0.1;
          else if (itemcond < 30)
            percent = 0.2;
          else if (itemcond < 40)
            percent = 0.3;
          else if (itemcond < 50)
            percent = 0.4;
          else if (itemcond < 60)
            percent = 0.5;
          else if (itemcond < 70)
            percent = 0.6;
          else if (itemcond < 80)
            percent = 0.7;
          else if (itemcond < 90)
            percent = 0.8;
          else if (itemcond <= 99)
            percent = 0.9;
    }

  if (GET_OBJ_DURABILITY(obj) < GET_OBJ_MAX_DURAB(obj))
    reduceprice = GET_OBJ_COST(obj) - (GET_OBJ_COST(obj) * percent);

    buyprice = (GET_OBJ_COST(obj) * SHOP_BUYPROFIT(shop_nr) * (1 + (GET_CHA(keeper) - GET_CHA(buyer)) / (float)70));
	buyprice -= reduceprice;
  return (int) buyprice;
}

/* When the shopkeeper is buying, we reverse the discount. Also make sure
   we don't buy for more than we sell for, to prevent infinite money-making. */
static int sell_price(struct obj_data *obj, int shop_nr, struct char_data *keeper, struct char_data *seller)
{
  float sell_cost_modifier = SHOP_SELLPROFIT(shop_nr) * (1 - (GET_CHA(keeper) - GET_CHA(seller)) / (float)70);
  float buy_cost_modifier = SHOP_BUYPROFIT(shop_nr) * (1 + (GET_CHA(keeper) - GET_CHA(seller)) / (float)70);
  float itemcond = 0;
  float percent = 1, sellprice = 0, reduceprice = 0, maxdurab, durab;

  maxdurab = GET_OBJ_MAX_DURAB(obj);
  durab = GET_OBJ_DURABILITY(obj);
  itemcond = (100 / maxdurab) * durab;
    if ((GET_OBJ_MAX_DURAB(obj) != 0) && (GET_OBJ_MAX_DURAB(obj) > GET_OBJ_DURABILITY(obj))) {
        if (itemcond == 0)
            percent = 0;
          else if (itemcond < 10)
            percent = 0.05;
          else if (itemcond < 20)
            percent = 0.1;
          else if (itemcond < 30)
            percent = 0.2;
          else if (itemcond < 40)
            percent = 0.3;
          else if (itemcond < 50)
            percent = 0.4;
          else if (itemcond < 60)
            percent = 0.5;
          else if (itemcond < 70)
            percent = 0.6;
          else if (itemcond < 80)
            percent = 0.7;
          else if (itemcond < 90)
            percent = 0.8;
          else if (itemcond <= 99)
            percent = 0.9;
    }

  if (GET_OBJ_DURABILITY(obj) < GET_OBJ_MAX_DURAB(obj))
    reduceprice = GET_OBJ_COST(obj) - (GET_OBJ_COST(obj) * percent);
  if (sell_cost_modifier > buy_cost_modifier)
    sell_cost_modifier = buy_cost_modifier;
  sellprice = (GET_OBJ_COST(obj) * sell_cost_modifier) - reduceprice;

  return (int) sellprice;
}

Please Log in or Create an account to join the conversation.

Time to create page: 1.114 seconds