/*************************************************************************** * Emud 2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem. * * * * MrMud 1.4 by David Bills and Dug Michael. * * * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe. * ***************************************************************************/ #include "emud.h" /* Scandum 20-05-2002 */ void send_bounty_message(char *message) { NOTE_DATA *pnote; FILE *fp; push_call("send_bounty_message(%p)",message); ALLOCMEM( pnote, NOTE_DATA, 1); pnote->next = NULL; pnote->sender = STRALLOC("Bounty Office"); pnote->date = STRALLOC(get_time_string(mud->current_time)); pnote->time = mud->current_time; pnote->to_list = STRALLOC("All"); pnote->subject = STRALLOC("New Contract!"); pnote->room_vnum = 30961; pnote->text = STRALLOC(message); LINK(pnote, mud->f_note, mud->l_note, next, prev); close_reserve(); fp = my_fopen (NOTE_FILE, "a",FALSE); if (fp == NULL) { perror (NOTE_FILE); } else { fprintf (fp, "Sender %s~\nDate %s~\nTime %d\nTo %s~\nSubject %s~\nTopic %d\nText\n%s~\nRoom %u\n\n", pnote->sender, pnote->date, pnote->time, pnote->to_list, pnote->subject, pnote->topic, fixer(pnote->text), pnote->room_vnum); fflush (fp); } my_fclose(fp); open_reserve(); pop_call(); return; } void do_bounty( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH]; int amount = 0; CHAR_DATA *victim; BOUNTY_DATA *bounty; bool loaded = FALSE; push_call("do_bounty(%p,%p)",ch,argument); argument = one_argument(argument, arg); if (IS_NPC(ch)) { pop_call(); return; } if (tolower(*arg) == 'p') { argument = one_argument(argument, arg); amount = atoi(arg); if (amount <= 0) { send_to_char("You can't post a bounty of 0 gold.\n\r", ch); pop_call(); return; } if (amount < 1000000) { ch_printf(ch, "The minimum bounty is 1,000,000 gold coins.\n\r"); pop_call(); return; } argument = one_argument(argument, arg); if (*arg == '\0' || *arg == ' ') { send_to_char("Usage: bounty <post/list/info> [amount] [target]\n\r", ch); pop_call(); return; } if ((victim = lookup_char(arg)) == NULL) { if ((victim = start_partial_load(ch, arg)) == NULL) { pop_call(); return; } loaded = TRUE; } if (IS_IMMORTAL(victim)) { send_to_char("You may not post bounties on Immortals.\n\r", ch); if (loaded) { clear_partial_load(victim); } pop_call(); return; } if (!IS_SET(victim->act, PLR_KILLER) && !IS_SET(victim->act, PLR_THIEF)) { send_to_char("You may only bounty killers and thieves.\n\r", ch); if (loaded) { clear_partial_load(victim); } pop_call(); return; } if (which_god(ch) == GOD_NEUTRAL) { send_to_char("You would not want to risk the wrath of their God.\n\r", ch); if (loaded) { clear_partial_load(victim); } pop_call(); return; } if (which_god(ch) == which_god(victim)) { send_to_char("You would not want to risk the wrath of your God.\n\r", ch); if (loaded) { clear_partial_load(victim); } pop_call(); return; } if (!gold_transaction(ch, 0 - amount)) { send_to_char("You don't have that much gold.\n\r", ch); if (loaded) { clear_partial_load(victim); } pop_call(); return; } post_bounty(arg, amount); save_bounties(); send_to_char("The bounty has been posted.\n\r", ch); if (!IS_IMMORTAL(ch)) { bounty = get_bounty(victim->name); strftime(arg, 12, "%2e %b %Y", gmtime( (const time_t *) &bounty->expires)); sprintf(buf, "\n\r{128}A bounty of %s gold has been posted on %s's head by %s.\n\r", tomoney(bounty->amount), victim->name, ch->name); send_bounty_message(buf); } if (loaded) { clear_partial_load(victim); } } else if (tolower(*arg) == 'i') { argument = one_argument(argument, arg); if ((bounty = get_bounty(arg)) == NULL) { ch_printf(ch, "There is no bounty posted on '%s'.\n\r", arg); pop_call(); return; } if (bounty->expires < mud->current_time) { send_to_char("That bounty has just expired.\n\r", ch); remove_bounty(bounty); save_bounties(); pop_call(); return; } ch_printf(ch, "Expiration date for the bounty on %s: %s\n\r", bounty->name, get_time_string(bounty->expires)); } else { sprintf(buf, "{138} %12s %13s %11s %12s %13s %11s\n\r", "Player", "Bounty", "Expiration", "Player", "Bounty", "Expiration"); cat_sprintf(buf, "{818}--------------------------------------------------------------------------------\n\r"); for (amount = 0, bounty = mud->f_bounty ; bounty ; bounty = bounty->next, amount++) { strftime(arg, 12, "%2e %b %Y", gmtime( (const time_t *) &bounty->expires)); switch (amount % 2) { case 0: cat_sprintf(buf, " {848}%12s {828}%13s {878}%11s ", bounty->name, tomoney(bounty->amount), arg); break; case 1: cat_sprintf(buf, " {848}%12s {828}%13s {878}%11s\n\r", bounty->name, tomoney(bounty->amount), arg); break; } } if (str_suffix("\n\r", buf)) { strncat(buf, "\n\r", MAX_STRING_LENGTH); } send_to_char_color(buf, ch); } pop_call(); return; } void post_bounty(char *name, int amount) { BOUNTY_DATA *bounty; push_call("post_bounty(%p,%p)",name,amount); /* Increase the value of a current bounty */ for (bounty = mud->f_bounty ; bounty ; bounty = bounty->next) { if (!strcasecmp(bounty->name, name)) { bounty->amount = UMIN(1000000000, bounty->amount + amount); bounty->expires = mud->current_time + 2592000 + bounty->amount / 1000000 * 86400; pop_call(); return; } } ALLOCMEM(bounty, BOUNTY_DATA, 1); bounty->name = STRALLOC(capitalize(name)); bounty->amount = amount; bounty->expires = mud->current_time + 2592000 + bounty->amount / 1000000 * 86400; sort_bounty(bounty); pop_call(); return; } void sort_bounty(BOUNTY_DATA *bounty) { BOUNTY_DATA *temp_bounty; push_call("sort_bounty(%p)",bounty); for (temp_bounty = mud->f_bounty ; temp_bounty ; temp_bounty = temp_bounty->next) { if (strcmp(bounty->name, temp_bounty->name) < 0) { INSERT_LEFT(bounty, temp_bounty, mud->f_bounty, next, prev); break; } } if (temp_bounty == NULL) { LINK(bounty, mud->f_bounty, mud->l_bounty, next, prev); } pop_call(); return; } void remove_bounty(BOUNTY_DATA *bounty) { push_call("remove_bounty(%p)",bounty); UNLINK(bounty, mud->f_bounty, mud->l_bounty, next, prev); STRFREE(bounty->name); FREEMEM(bounty); pop_call(); return; } BOUNTY_DATA *get_bounty( char *name ) { BOUNTY_DATA *bounty; push_call("get_bounty(%p)",name); for (bounty = mud->f_bounty ; bounty ; bounty = bounty->next) { if (!strcasecmp(bounty->name, name)) { pop_call(); return(bounty); } } pop_call(); return NULL; } int gold_transaction(CHAR_DATA *ch, int amount) { int max_account, max_pocket; push_call("gold_transaction(%p)",ch,amount); if (IS_NPC(ch)) { pop_call(); return FALSE; } if (amount < 0) { amount = 0 - amount; if (ch->gold >= amount) { ch->gold -= amount; pop_call(); return TRUE; } else if (ch->gold + ch->pcdata->account >= amount) { amount -= ch->gold; ch->gold = 0; ch->pcdata->account -= amount; pop_call(); return TRUE; } else { pop_call(); return FALSE; } } else { max_pocket = ch->level * 1000000 - ch->gold; max_account = (ch->level + 5 + ch->pcdata->reincarnation * 5) * 2000000; if (amount <= max_pocket) { ch->gold += amount; } else { amount -= max_pocket; ch->gold = ch->level * 1000000; ch->pcdata->account += amount; if (ch->pcdata->account > max_account) { ch->pcdata->account = max_account; } } pop_call(); return TRUE; } } void collect_bounty( CHAR_DATA *ch, CHAR_DATA *victim ) { BOUNTY_DATA *bounty; OBJ_DATA *head; char buf[MAX_INPUT_LENGTH]; AFFECT_DATA af; int stat_bonus[5] = {0}; int dam_plus, hit_plus, ac_plus, hp_plus, mana_plus, level_plus; push_call("collect_bounty(%p,%p)",ch,victim); bounty = get_bounty(victim->name); if (bounty == NULL) { pop_call(); return; } act("You sever $N's head to collect the bounty on it.", ch, NULL, victim, TO_CHAR); act("$n severs $N's head to collect the bounty on it.", ch, NULL, victim, TO_NOTVICT); head = create_object(get_obj_index(OBJ_VNUM_BOUNTY_HEAD), 0); head->level = victim->level; head->cost = bounty->amount; head->weight = 1 + race_table[victim->race].weight / 30; head->value[0] = mud->current_time + 60 * 60 * 24 * 30 * 12 + bounty->amount / 1000000 * 86400; SET_BIT(head->extra_flags, ITEM_MODIFIED); if (!IS_EVIL(victim)) { SET_BIT(head->extra_flags, ITEM_ANTI_EVIL); } if (!IS_GOOD(victim)) { SET_BIT(head->extra_flags, ITEM_ANTI_GOOD); } if (!IS_NEUTRAL(victim)) { SET_BIT(head->extra_flags, ITEM_ANTI_NEUTRAL); } sprintf(buf, head->name, victim->name); RESTRING(head->name, buf); sprintf(buf, head->short_descr, get_name(victim)); RESTRING(head->short_descr, buf); sprintf(buf, head->long_descr, get_name(victim)); RESTRING(head->long_descr, buf); sprintf(buf, head->description, get_name(victim), bounty->amount); RESTRING(head->description, justify(buf, 80)); stat_bonus[0] = race_table[victim->race].race_mod[0] + victim->pcdata->reincarnation / 2; stat_bonus[1] = race_table[victim->race].race_mod[1] + victim->pcdata->reincarnation / 2; stat_bonus[2] = race_table[victim->race].race_mod[2] + victim->pcdata->reincarnation / 2; stat_bonus[3] = race_table[victim->race].race_mod[3] + victim->pcdata->reincarnation / 2; stat_bonus[4] = race_table[victim->race].race_mod[4] + victim->pcdata->reincarnation / 2; stat_bonus[class_table[victim->class].attr_prime -1] += class_table[victim->class].prime_mod; stat_bonus[class_table[victim->class].attr_second -1] += class_table[victim->class].sec_mod; dam_plus = hit_plus = ac_plus = hp_plus = mana_plus = 0; level_plus = UMAX(1, victim->pcdata->history[HISTORY_KILL_EN] - victim->pcdata->history[HISTORY_KILL_BY_EN]); dam_plus = hit_plus = UMIN(level_plus * 1, victim->level / 6); hp_plus = mana_plus = UMIN(level_plus * 12, victim->level * 2); ac_plus = UMAX(level_plus * -2, -victim->level / 3); af.type = gsn_object_rape; af.duration = -1; af.bitvector = 0; if (stat_bonus[0]) { af.modifier = stat_bonus[0]; af.location = 1; affect_to_obj(head, &af); } if (stat_bonus[1]) { af.modifier = stat_bonus[1]; af.location = 2; affect_to_obj(head, &af); } if (stat_bonus[2]) { af.modifier = stat_bonus[2]; af.location = 3; affect_to_obj(head, &af); } if (stat_bonus[3]) { af.modifier = stat_bonus[3]; af.location = 4; affect_to_obj(head, &af); } if (stat_bonus[4]) { af.modifier = stat_bonus[4]; af.location = 5; affect_to_obj(head, &af); } if (ac_plus) { af.modifier = ac_plus; af.location = APPLY_AC; affect_to_obj(head, &af); } if (victim->pcdata->mclass[CLASS_WARRIOR] || victim->pcdata->mclass[CLASS_GLADIATOR] || victim->pcdata->mclass[CLASS_MARAUDER] || victim->pcdata->mclass[CLASS_NINJA]) { if (dam_plus) { af.modifier = dam_plus; af.location = APPLY_DAMROLL; affect_to_obj(head, &af); } if (hit_plus) { af.modifier = hit_plus; af.location = APPLY_HITROLL; affect_to_obj(head, &af); } } else { if (hp_plus) { af.modifier = hp_plus; af.location = APPLY_HIT; affect_to_obj(head, &af); } if (mana_plus) { af.modifier = mana_plus; af.location = APPLY_MANA; affect_to_obj(head, &af); } } obj_to_char(head, ch); remove_bounty(bounty); save_bounties(); pop_call(); return; }