18 Mar, 2010, triskaledia wrote in the 1st comment:
Votes: 0
In my fight.c I have a block of code that allows players to get hp/mana/move bonus's when certain criteria are met.
I had a long and very drawn out, if(ch->mkill == # || ch->mkill == #2 || etc || etc) { Give bonus'}.
I was then telling a friend about this a while back and he gave me a more simplistic version on how to run such a thing,
if (ch->mkill % # == 0) //my players know I post here often.
{
ch->hit = ch->max_hit;
ch->max_hit += 100;
ch->max_mana += 100;
ch->max_move += 100;
ch->pcdata->perm_hit += 100;
ch->pcdata->perm_mana +=100;
ch->pcdata->perm_move += 100;
ch->hit = ch->max_hit;
ch->mana = ch->max_mana;
ch->move = ch->max_move;
stc("{CYou{W'{Cve been awarded {D100 {Chitpoints{W, {Cmana{W, {Cmove and restored for your kills{W!{x\n\r", ch);
}

Now, I guess the question is how does this work? Im trying to use this in my convert command, so that
when players go to exchange their silver into gold, they are left that remainder (100silver = 1gold).
It didn't seem like their was a lot of loss, so I have it coded as:
x1 = ch->silver / 100;
sprintf(buf, "You've exchanged %ld silver for %d gold.\n\r", ch->silver, x1);
send_to_char(buf, ch);
ch->silver = 0;
ch->gold += x1;
x1 = 0;
:right now, and I had a player suggest that I break it up so that they can save that silver that they lose.

I tried to code it out, but since I don't really understand how that % value works, it didn't convert
any silver to gold, or deduct anything.
All I know is when the value is reached in fight.c that I had chosen, it does what I want it to.
18 Mar, 2010, Scandum wrote in the 2nd comment:
Votes: 0
18 Mar, 2010, Runter wrote in the 3rd comment:
Votes: 0
x1 = ch->silver / 100;
sprintf(buf, "You've exchanged %ld silver for %d gold.\n\r", x1*100, x1); // properly display how much silver traded in
send_to_char(buf, ch);
@@ ch->silver = ch->silver % 100; // modulus finds remainder.
ch->gold += x1;
x1 = 0;
18 Mar, 2010, Skol wrote in the 4th comment:
Votes: 0
sprintf(buf, "You've exchanged %ld silver for %ld gold.\r\n", ch->silver, ch->silver/100);
send_to_char (buf, ch);

int coins = ch->silver; // So we can read the code more easily, we'll use 'coins'
ch->gold += coins/100; // 100th conversion
ch->silver -= (coins/100) * 100; // 100 silver per gold then removed.

if (ch->silver > 0) // Only say we're giving change if we have silver left over.
{
sprintf(buf, "You get %d silver in change.\r\n", ch->silver);
send_to_char(buf, ch);
}

The modulo operator… well, see Scandum's link.

I generally use it for columns and other times I want a certain number of items per group.
ie:
// col is an int.
if (++col % 4 == 0)
strcat (buf1, "\r\n");

In this, I'm going 'does dividing 'col' by 4 leave no remainder?
If so, then I add the carriage return/line feed.
18 Mar, 2010, Runter wrote in the 5th comment:
Votes: 0
Quote
Now, I guess the question is how does this work?


There's a very simple way to look at it, and that is that it finds the remainder.

101 % 100 = 1
201 % 100 = 1
10001 % 100 = 1
21099 % 100 = 99
3 % 2 = 1
5 % 1 = 0
9 % 2 = 1

This is a good place to use it for finding your remainder in silver. In your example it uses the remainder to figure out when to trigger your bonus. You didn't post the actual number you're moding by but it finds the remainder and when it divides evenly into it, i.e. evaluates to 0, it fires. This could be every 100, 1000, or whatever number you actually use there.
18 Mar, 2010, KaVir wrote in the 6th comment:
Votes: 0
Runter said:
There's a very simple way to look at it, and that is that it finds the remainder.

Unless you're dealing with negative numbers. C99 mandates truncation toward zero, but C89 is implementation-defined, and I've used at least one compiler that implemented the % operator as modulus rather than remainder.
18 Mar, 2010, triskaledia wrote in the 7th comment:
Votes: 0
Thanks Scandum for the link for a full definition.
Thanks Runter and Skol for you code idea's (took Runters).
Thanks Runter for a brief explanation of how modulum's work.
Thanks Kavir for stating that negative numbers don't work the same as positive numbers when using the modulum.
18 Mar, 2010, Skol wrote in the 8th comment:
Votes: 0
Oh one last bit Trisk, if you use it to see if they've reached that plateau of X kills, also check that it != 0.

Unless it doesn't start with 0, or check anytime ON 0 (ie after each kill perhaps? If that's the case then it'd be fine). Otherwise if it's 0, it will yield valid. IE if (ch->mkill % 100 == 0). If that checks any time other than after incrementing ch->mkill, the first one would yield valid and give them the bonus. What I would do is in fight.c (assuming Rom? I forgot to check) when it kills the mob (where I'm assuming this check is?), have it do if (++ch->mpkill etc etc).

Hope that makes sense?
07 May, 2010, triskaledia wrote in the 9th comment:
Votes: 0
Damn it's been forever since I've been on here. Anyway, yeah. I have it set up so that ch->mkill auto increments and I've never ran into players getting a bonus from their first kill. If I do, I'll be changing it up so that the first kill won't count. Shouldn't ever run into that because players automatically start with 0 as their mkill/pkill/etc and I don't ever have it to decrease. Thanks though and I'll keep that in mind incase I ever need to add any more player information that starts as NULL.
07 May, 2010, quixadhal wrote in the 10th comment:
Votes: 0
One common gotcha when using modulo is to forget the zero case. :)

printf("Modulo stuff: ");
for(i = 0; i < 9; i++) {
printf("i = %d ", i);
if( ! i % 4 ) printf("\n");
}


Will happily output:
Modulo stuff: i = 0
i = 1 i = 2 i = 3 i = 4
i = 5 i = 6 i = 7 i = 8

because 0 mod anything is 0. :)

Also, I think using negative numbers is either an error, or usually implemented as (-3 % 4) == (int)((unsigned int)(-3) % 4)
But YMMV.
0.0/10