/* rob.c */

#include "copyright.h"
#include <ctype.h>

/* rob and kill */

#include "config.h"
#include "db.h"
#include "interface.h"
#include "match.h"
#include "externs.h"

void do_rob(player, what)
    dbref player;
    const char *what;
{
  dbref thing;
  init_match(player, what, TYPE_PLAYER);
  match_neighbor();
  match_me();
  if (Wizard(player)) {
    match_absolute();
    match_player();
  }
  thing = match_result();

  switch (thing) {
    case NOTHING:
      notify(player, "Rob whom?");
      break;
    case AMBIGUOUS:
      notify(player, "I don't know who you mean!");
      break;
    default:
      if (Typeof(thing) != TYPE_PLAYER) {
	notify(player, "Sorry, you can only rob other players.");
      } else if (Pennies(thing) < 1) {
	notify(player, tprintf("%s has no %s.", db[thing].name, MONIES));
	notify(thing,
	       tprintf("%s tried to rob you, but you have no %s to take.",
			db[player].name, MONIES));
      } else if (could_doit(player, thing)) {
	/* steal a penny */
	giveto(player, 1);
	giveto(thing, -1);
	notify(player, tprintf("You stole a %s.", MONEY));
	notify(thing, tprintf("%s stole one of your %s!", db[player].name,
			      MONIES));
	did_it(player, thing, "SUCCESS", NULL, "OSUCCESS", NULL, "ASUCCESS",
	       NOTHING);
      } else
	did_it(player, thing, "FAILURE", "Your conscience tells you not to.",
	       "OFAILURE", NULL, "AFAILURE", NOTHING);
      break;
  }
}

void do_kill(player, what, cost, slay)
    dbref player;
    const char *what;
    int cost;
    int slay;
{
  dbref victim;
  char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN];

  if(slay && !Wizard(player)) {
    notify(player,"You do not have such power.");
    return;
  }
  init_match(player, what, TYPE_PLAYER);
  match_neighbor();
  match_possession();
  match_me();
  match_here();
  if (Wizard(player)) {
    match_player();
    match_absolute();
  }
  victim = match_result();

  if(slay) {
    static char pl[BUFFER_LEN], vic[BUFFER_LEN];
    strcpy(pl, unparse_object(player, player));
    strcpy(vic, unparse_object(player, victim));
    fprintf(stderr, "SLAY [%s] %s\n", pl, vic);
  }
  switch (victim) {
    case NOTHING:
      notify(player, "I don't see that here.");
      break;
    case AMBIGUOUS:
      notify(player, "I don't know what you mean!");
      break;
    default:
      if (db[player].flags & PLAYER_SUSPECT)
	raw_broadcast(WIZARD, "Broadcast: Suspect %s tried to kill %s(#%d).",
		      db[player].name, db[victim].name, victim);
      if ((Typeof(victim) != TYPE_PLAYER) && (Typeof(victim) != TYPE_THING)) {
	notify(player, "Sorry, you can only kill players and objects.");
      } else if (((db[db[victim].location].flags & HAVEN) &&
		  !Wizard(player)) ||
		 (controls(victim, db[victim].location) &&
		  !controls(player, db[victim].location))) {
	notify(player, "Sorry.");
      } else if ((db[victim].flags & THING_IMMORTAL) &&
		 !Wizard(player) && (db[victim].owner != player)) {
	notify(player, "That object is immortal and cannot be killed.");
      } else {
	/* go for it */
	/* set cost */
	/* if this isn't called via slay */
        if(!slay) {
	  if (cost < KILL_MIN_COST)
	    cost = KILL_MIN_COST;

	    /* see if it works */
	    if (!payfor(player, cost)) {
	      notify(player, tprintf("You don't have enough %s.", MONIES));
	      break;
	    }
        }
	if ((((random() % KILL_BASE_COST) < cost) || slay) &&
	    !Wizard(victim)) {
	  /* you killed him */
	  sprintf(tbuf1, "You killed %s!", db[victim].name);
	  sprintf(tbuf2, "killed %s!", db[victim].name);
	  do_halt(victim, "");
	  did_it(player, victim,"DEATH",tbuf1,"ODEATH", tbuf2,"ADEATH",NOTHING);

	  /* notify victim */
	  notify(victim, tprintf("%s killed you!", db[player].name));

	  /* maybe pay off the bonus */
	  /* if we were not called via slay */
	  if(!slay) {
	    if (Pennies(db[victim].owner) < MAX_PENNIES) {
	      notify(victim, tprintf("Your insurance policy pays %d %s.",
		                     KILL_BONUS,
                                     ((KILL_BONUS == 1) ? MONEY : MONIES)));
	      giveto(db[victim].owner, KILL_BONUS);
	    } else {
	      notify(victim, "Your insurance policy has been revoked.");
	    }
          }
	  /* send him home */
	  safe_tel(victim, HOME);
	  /* if victim is object also dequeue all commands */
	} else {
	  /* notify player and victim only */
	  notify(player, "Your murder attempt failed.");
	  notify(victim, tprintf("%s tried to kill you!", db[player].name));
	}
	break;
      }
  }
}

void do_give(player, recipient, amnt)
    dbref player;
    char *recipient;
    char *amnt;
{
  dbref who;
  int amount;
  char *s;
  char tbuf1[BUFFER_LEN];

  /* check recipient */
  init_match(player, recipient, TYPE_PLAYER);
  match_neighbor();
  match_me();
  if (Wizard(player)) {
    match_player();
    match_absolute();
  }
  switch (who = match_result()) {
    case NOTHING:
      notify(player, "Give to whom?");
      return;
    case AMBIGUOUS:
      notify(player, "I don't know who you mean!");
      return;
  }

  /* make sure amount is all digits */
  for (s = amnt; *s && ((isdigit(*s)) || (*s == '-')); s++) ;
  /* must be giving object */
  if (*s) {
    dbref thing;
    init_match(player, amnt, TYPE_THING);
    match_possession();
    match_me();
    switch (thing = match_result()) {
      case NOTHING:
	notify(player, "You don't have that!");
	return;
      case AMBIGUOUS:
	notify(player, "I don't know which you mean!");
	return;
      default:
	if (((Typeof(thing) == TYPE_THING) || (Typeof(thing) == TYPE_PLAYER)) &&
	    ((db[who].flags & ENTER_OK) || controls(player, who))) {
	  moveto(thing, who);
	  notify(who,
	       tprintf("%s gave you %s.", db[player].name, db[thing].name));
	  notify(player, "Given.");
	  notify(thing, tprintf("%s gave you to %s.", db[player].name,
				db[who].name));
	  did_it(who,thing, "SUCCESS", NULL, "OSUCCES", NULL, "ASUCCSS",
		 NOTHING);
	} else
	  notify(player, "Permission denied.");
    }
    return;
  }
  amount = atoi(amnt);
  /* do amount consistency check */
  if (amount < 0 && !Wizard(player)) {
    notify(player, "Try using the \"rob\" command.");
    return;
  } else if (amount == 0) {
    notify(player,tprintf("You must specify a positive number of %s.",MONIES));
    return;
  }
  if (!Wizard(player)) {
    if (Pennies(who) + amount > MAX_PENNIES) {
      notify(player, tprintf("That player doesn't need that many %s!",MONIES));
      return;
    }
  }
  /* try to do the give */
  if (!payfor(player, amount)) {
    notify(player, tprintf("You don't have that many %s to give!", MONIES));
  } else {
    /* objects work differently */
    if (Typeof(who) == TYPE_THING) {
      int cost = 0;
      ATTR *a;
      a = atr_get(who, "COST");
      if (a && (amount < (cost = atoi(uncompress(a->value))))) {
	notify(player, "Feeling poor today?");
	giveto(player, amount);
	return;
      }
      if (cost < 0)
	return;
      if ((amount - cost) > 0) {
	sprintf(tbuf1, "You get %d in change.", amount - cost);
      } else {
	sprintf(tbuf1, "You paid %d %s.", amount,
		((amount == 1)? MONEY : MONIES));
      }
      notify(player, tbuf1);
      giveto(player, amount - cost);
      giveto(who, cost);
      did_it(player, who, "PAYMENT", NULL, "OPAYMENT", NULL, "APAYMENT",
	     NOTHING);
      return;
    } else {
      /* he can do it */
      if(amount > 0) {
        notify(player,
	       tprintf("You give %d %s to %s.", amount,
                       ((amount == 1) ? MONEY : MONIES),  db[who].name));
      } else {
	notify(player, tprintf("You took %d %s from %s!", abs(amount),
			       ((abs(amount) == 1) ? MONEY : MONIES), 
			       db[who].name));
      }
      if (Typeof(who) == TYPE_PLAYER) {
	if(amount > 0) {
	  notify(who, tprintf("%s gives you %d %s.", db[player].name, 
                              amount, ((amount == 1) ? MONEY : MONIES)));
	} else {
	  notify(who, tprintf("%s took %d %s from you!", db[player].name,
			      abs(amount),
			      ((abs(amount) == 1) ? MONEY : MONIES)));
	}
      }
      giveto(who, amount);
      did_it(player, who, "PAYMENT", NULL, "OPAYMENT", NULL, "APAYMENT",
	     NOTHING);
    }
  }
}