/*! \file rob.cpp * \brief Commands dealing with giving/taking/killing things or money. * */ #include "copyright.h" #include "autoconf.h" #include "config.h" #include "externs.h" void do_kill ( dbref executor, dbref caller, dbref enactor, int eval, int key, int nargs, UTF8 *what, UTF8 *costchar, const UTF8 *cargs[], int ncargs ) { UNUSED_PARAMETER(caller); UNUSED_PARAMETER(enactor); UNUSED_PARAMETER(eval); UNUSED_PARAMETER(nargs); UNUSED_PARAMETER(cargs); UNUSED_PARAMETER(ncargs); init_match(executor, what, TYPE_PLAYER); match_neighbor(); match_me(); match_here(); if (Long_Fingers(executor)) { match_player(); match_absolute(); } dbref victim = match_result(); switch (victim) { case NOTHING: notify(executor, M_("I don’t see that player here.")); break; case AMBIGUOUS: notify(executor, M_("I don’t know who you mean!")); break; default: if ( !isPlayer(victim) && !isThing(victim)) { notify(executor, M_("Sorry, you can only kill players and things.")); break; } if ( ( Haven(Location(victim)) && !Wizard(executor)) || ( Controls(victim, Location(victim)) && !Controls(executor, Location(victim))) || Unkillable(victim)) { notify(executor, M_("Sorry.")); break; } // Go for it. // int cost = 0; if (key == KILL_KILL) { cost = mux_atoi64(costchar); if (cost < mudconf.killmin) { cost = mudconf.killmin; } if (cost > mudconf.killmax) { cost = mudconf.killmax; } // See if it works. // if (!payfor(executor, cost)) { notify(executor, tprintf(M_("You don’t have enough %s."), mudconf.many_coins)); return; } } if ( RealWizard(victim) || ( 0 < mudconf.killguarantee && !( RandomINT32(0, mudconf.killguarantee-1) < cost || key == KILL_SLAY))) { // Failure: notify player and victim only. // notify(executor, M_("Your murder attempt failed.")); { LBuf buf1 = LBuf_Src("do_kill.failed"); mux_sprintf(buf1, LBUF_SIZE, M_("%s tried to kill you!"), Moniker(executor)); notify_with_cause_ooc(victim, executor, buf1, MSG_SRC_KILL); if (Suspect(executor)) { mux_strncpy(buf1, Moniker(executor), LBUF_SIZE-1); if (executor == Owner(executor)) { raw_broadcast(WIZARD, M_("[Suspect] %s tried to kill %s(#%d)."), buf1.get(), Moniker(victim), victim); } else { LBuf buf2 = LBuf_Src("do_kill.SUSP.failed"); mux_strncpy(buf2, Moniker(Owner(executor)), LBUF_SIZE-1); raw_broadcast(WIZARD, M_("[Suspect] %s tried to kill %s(#%d)."), buf2.get(), buf1.get(), executor, Moniker(victim), victim); } } } break; } // Success! You killed him // { LBuf buf1 = LBuf_Src("do_kill.succ.1"); LBuf buf2 = LBuf_Src("do_kill.succ.2"); if (Suspect(executor)) { mux_strncpy(buf1, Moniker(executor), LBUF_SIZE-1); if (executor == Owner(executor)) { raw_broadcast(WIZARD, M_("[Suspect] %s killed %s(#%d)."), buf1.get(), Moniker(victim), victim); } else { mux_strncpy(buf2, Moniker(Owner(executor)), LBUF_SIZE-1); raw_broadcast(WIZARD, M_("[Suspect] %s killed %s(#%d)."), buf2.get(), buf1.get(), executor, Moniker(victim), victim); } } mux_sprintf(buf1, LBUF_SIZE, M_("You killed %s!"), Moniker(victim)); mux_sprintf(buf2, LBUF_SIZE, M_("killed %s!"), Moniker(victim)); if (!isPlayer(victim)) { if (halt_que(NOTHING, victim) > 0) { if (!Quiet(victim)) { notify(Owner(victim), M_("Halted.")); } } } did_it(executor, victim, A_KILL, buf1, A_OKILL, buf2, A_AKILL, 0, nullptr, 0); // notify victim // mux_sprintf(buf1, LBUF_SIZE, M_("%s killed you!"), Moniker(executor)); notify_with_cause_ooc(victim, executor, buf1, MSG_SRC_KILL); // Pay off the bonus. // if (key == KILL_KILL) { cost /= 2; // Victim gets half. if (Pennies(Owner(victim)) < mudconf.paylimit) { mux_sprintf(buf1, LBUF_SIZE, M_("Your insurance policy pays %d %s."), cost, mudconf.many_coins); notify(victim, buf1); giveto(Owner(victim), cost); } else { notify(victim, M_("Your insurance policy has been revoked.")); } } } // Send him home. // move_via_generic(victim, HOME, NOTHING, 0); divest_object(victim); break; } } /* * --------------------------------------------------------------------------- * * give_thing, give_money, do_give: Give away money or things. */ static void give_thing(dbref giver, dbref recipient, int key, UTF8 *what) { init_match(giver, what, TYPE_THING); match_possession(); match_me(); dbref thing = match_result(); switch (thing) { case NOTHING: notify(giver, M_("You don’t have that!")); return; case AMBIGUOUS: notify(giver, M_("I don’t know which you mean!")); return; } if (thing == giver) { notify(giver, M_("You can’t give yourself away!")); return; } if (thing == recipient) { notify(giver, M_("You can’t give an object to itself.")); return; } if ( (!isThing(thing) && !isPlayer(thing)) || !( Enter_ok(recipient) || Controls(giver, recipient)) || isGarbage(recipient)) { notify(giver, NOPERM_MESSAGE); return; } if (!could_doit(giver, thing, A_LGIVE)) { LBuf str = LBuf_Src("do_give.gfail"); UTF8 *sp = str.get(); safe_str(T("You can’t give "), str, &sp); safe_str(Moniker(thing), str, &sp); safe_str(T(" away."), str, &sp); *sp = '\0'; did_it(giver, thing, A_GFAIL, str, A_OGFAIL, nullptr, A_AGFAIL, 0, nullptr, 0); return; } if (!could_doit(thing, recipient, A_LRECEIVE)) { LBuf str = LBuf_Src("do_give.rfail"); UTF8 *sp = str.get(); safe_str(Moniker(recipient), str, &sp); safe_str(T(" doesn’t want "), str, &sp); safe_str(Moniker(thing), str, &sp); safe_chr('.', str, &sp); *sp = '\0'; did_it(giver, recipient, A_RFAIL, str, A_ORFAIL, nullptr, A_ARFAIL, 0, nullptr, 0); return; } move_via_generic(thing, recipient, giver, 0); divest_object(thing); if (!(key & GIVE_QUIET)) { LBuf str = LBuf_Src("do_give.thing.ok"); mux_strncpy(str, Moniker(giver), LBUF_SIZE-1); notify_with_cause_ooc(recipient, giver, tprintf(M_("%s gave you %s."), str.get(), Moniker(thing)), MSG_SRC_GIVE); notify(giver, M_("Given.")); notify_with_cause_ooc(thing, giver, tprintf(M_("%s gave you to %s."), str.get(), Moniker(recipient)), MSG_SRC_GIVE); } did_it(giver, thing, A_DROP, nullptr, A_ODROP, nullptr, A_ADROP, 0, nullptr, 0); did_it(recipient, thing, A_SUCC, nullptr, A_OSUCC, nullptr, A_ASUCC, 0, nullptr, 0); } static void give_money(dbref giver, dbref recipient, int key, int amount) { // Do amount consistency check. // if ( amount < 0 && !Steal(giver)) { notify(giver, tprintf(M_("You look through your pockets. Nope, no negative %s."), mudconf.many_coins)); return; } if (!amount) { notify(giver, tprintf(M_("You must specify a positive number of %s."), mudconf.many_coins)); return; } if (!Wizard(giver)) { if ( isPlayer(recipient) && (Pennies(recipient) + amount > mudconf.paylimit)) { notify(giver, tprintf(M_("That player doesn’t need that many %s!"), mudconf.many_coins)); return; } if (!could_doit(giver, recipient, A_LUSE)) { notify(giver, tprintf(M_("%s won’t take your money."), Moniker(recipient))); return; } } // Try to do the give. // if (!payfor(giver, amount)) { notify(giver, tprintf(M_("You don’t have that many %s to give!"), mudconf.many_coins)); return; } // Find out cost if an object. // int cost; if (isThing(recipient)) { dbref aowner; int aflags; LBuf str = LBuf_Adopt(atr_pget(recipient, A_COST, &aowner, &aflags)); cost = mux_atoi64(str); // Can't afford it? // if (amount < cost) { notify(giver, M_("Feeling poor today?")); giveto(giver, amount); return; } // Negative cost // if (cost < 0) { return; } } else { cost = amount; } if (!(key & GIVE_QUIET)) { if (amount == 1) { notify(giver, tprintf(M_("You give a %s to %s."), mudconf.one_coin, Moniker(recipient))); notify_with_cause_ooc(recipient, giver, tprintf(M_("%s gives you a %s."), Moniker(giver), mudconf.one_coin), MSG_SRC_GIVE); } else { notify(giver, tprintf(M_("You give %d %s to %s."), amount, mudconf.many_coins, Moniker(recipient))); notify_with_cause_ooc(recipient, giver, tprintf(M_("%s gives you %d %s."), Moniker(giver), amount, mudconf.many_coins), MSG_SRC_GIVE); } } // Report change given // if ((amount - cost) == 1) { notify(giver, tprintf(M_("You get 1 %s in change."), mudconf.one_coin)); giveto(giver, 1); } else if (amount != cost) { notify(giver, tprintf(M_("You get %d %s in change."), (amount - cost), mudconf.many_coins)); giveto(giver, (amount - cost)); } // Transfer the money and run PAY attributes // giveto(recipient, cost); did_it(giver, recipient, A_PAY, nullptr, A_OPAY, nullptr, A_APAY, 0, nullptr, 0); return; } void do_give ( dbref executor, dbref caller, dbref enactor, int eval, int key, int nargs, UTF8 *who, UTF8 *amnt, const UTF8 *cargs[], int ncargs ) { UNUSED_PARAMETER(caller); UNUSED_PARAMETER(enactor); UNUSED_PARAMETER(eval); UNUSED_PARAMETER(nargs); UNUSED_PARAMETER(cargs); UNUSED_PARAMETER(ncargs); // Check recipient. // init_match(executor, who, TYPE_PLAYER); match_neighbor(); match_possession(); match_me(); if (Long_Fingers(executor)) { match_player(); match_absolute(); } dbref recipient = match_result(); switch (recipient) { case NOTHING: notify(executor, M_("Give to whom?")); return; case AMBIGUOUS: notify(executor, M_("I don’t know who you mean!")); return; } if (isExit(recipient)) { notify(executor, M_("You can’t give anything to an exit.")); return; } if (Guest(recipient)) { notify(executor, M_("Guests really don’t need money or anything.")); return; } if (is_rational(amnt)) { give_money(executor, recipient, key, mux_atoi64(amnt)); } else { give_thing(executor, recipient, key, amnt); } }