Creating exp from nothing

From: Apua Cesar de Miranda Paquola (apua@dcc.unicamp.br)
Date: 04/02/96


	Hi,

	We have found a bug in circle30bpl10 that allows a group to
gain exp points by killing its own members in rounds.

	Because there is a limit on maximum exp loss and there is no
limit on the total exp gain of the group, the group (if big enough)
receives all the exp(victim)/3 while the victim loses only
max_exp_loss. Note that it has advantage only when exp(victim) >
3*max_exp_loss.

	Between begin(apua) and end(apua) are the changes we have made
to fight.c to correct this problem. In this code, if the the victim is
a PC, the total group gain is at most 2/3 max_exp_loss.  This makes
the total exp gain be 2/3 of the victim's exp loss in every kill.


	Apua~        (apua@dcc.unicamp.br)
	Dirani       (spharion@dcc.unicamp.br)	


/* begin(apua) */
extern int max_exp_loss;	/* see config.c */
/* end(apua) */

void group_gain(struct char_data * ch, struct char_data * victim)
{
  int tot_members, base;
  /* begin(apua) */
  int tot_gain;
  /* end(apua) */
  struct char_data *k;
  struct follow_type *f;

  if (!(k = ch->master))
    k = ch;

  if (IS_AFFECTED(k, AFF_GROUP) && (k->in_room == ch->in_room))
    tot_members = 1;
  else
    tot_members = 0;

  for (f = k->followers; f; f = f->next)
    if (IS_AFFECTED(f->follower, AFF_GROUP) && f->follower->in_room == ch->in_room)
      tot_members++;

  /* round up to the next highest tot_members */
  /* begin(apua) */
  /*   base = (GET_EXP(victim) / 3) + tot_members - 1; */
  tot_gain = (GET_EXP(victim) / 3) + tot_members - 1;
  /* end(apua) */
  
  /* begin(apua) */
  /* prevent illegal xp creation when killing players */
  if (!IS_NPC(victim))
    tot_gain = MIN(max_exp_loss * 2 / 3, tot_gain);
  /* end(apua) */

  if (tot_members >= 1)
    /* begin(apua) */
    /*     base = MAX(1, GET_EXP(victim) / (3 * tot_members)); */
    base = MAX(1, tot_gain / tot_members);
    /* end(apua) */
  else
    base = 0;

  if (IS_AFFECTED(k, AFF_GROUP) && k->in_room == ch->in_room)
    perform_group_gain(k, base, victim);

  for (f = k->followers; f; f = f->next)
    if (IS_AFFECTED(f->follower, AFF_GROUP) && f->follower->in_room == ch->in_room)
      perform_group_gain(f->follower, base, victim);
}



This archive was generated by hypermail 2b30 : 12/18/00 PST