/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Envy Diku Mud, you must comply with * * the original Diku license in 'license.doc', the Merc license in * * 'license.txt', as well as the Envy license in 'license.nvy'. * * In particular, you may not remove either of these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * * * * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * * * * Code Adapted and Improved by Abandoned Realms Mud * * and Aabahran: The Forsaken Lands Mud by Virigoth * * * * Continued Production of this code is available at www.flcodebase.com * ***************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "jail.h" #include "bounty.h" #include "interp.h" #include "recycle.h" #include "cabal.h" #include "olc.h" /* Written by: Virigoth * returns: number of rares transfered * comments: takes a sorted group (highest to lowest level) of rares and * * transfers them to ch. Number of rare items taken is "number", ignores owner only items * * if fRandom then level is ignored and random rares are transfered */ int get_random_rares( CHAR_DATA* ch, CHAR_DATA* victim, int number, bool fRandom){ const int MAX_OBJ = 32; OBJ_DATA* bag; OBJ_DATA* rares[MAX_OBJ]; int max_rares = 0; int trans = 0; OBJ_DATA* obj, *obj_next; int i = 0; /* first cycle through the victim's items, and put limited pointers into "rares" */ for ( obj = victim->carrying; obj != NULL; obj = obj_next ){ obj_next = obj->next_content; if (obj->wear_loc == WEAR_TATTOO || !IS_LIMITED(obj) || IS_SET(obj->wear_flags, ITEM_HAS_OWNER) || is_affected_obj(obj, gen_malform) || is_affected_obj(obj, gen_hwep) || !can_take( ch, obj ) ) continue; rares[max_rares++] = obj; } if (max_rares < 1) return trans; /* sort the rares from highest level to lowest */ for (i = 1; i < max_rares; i++){ int j = 0; for (j = 0; j < max_rares - i; j ++ ){ obj = rares[j]; obj_next = rares[j + 1]; if (obj_next->level > obj->level){ rares[j + 1] = obj; rares[j] = obj_next; } } } /* create a bag */ if ( (bag = create_object(get_obj_index(OBJ_VNUM_JAILBAG), 0)) == NULL){ bug("get_random_rares: Could not create a jailbag", 0); return 0; } else{ char buf[MIL]; /* set the desc. and details */ sprintf( buf, bag->name, victim->name ); free_string( bag->name ); bag->name = str_dup( buf ); sprintf( buf, bag->short_descr, victim->name ); free_string( bag->short_descr ); bag->short_descr = str_dup( buf ); sprintf( buf, bag->description, victim->name ); free_string( bag->description ); bag->description = str_dup( buf ); } /* run through number of rares and either pull from top or select randomly */ if (fRandom){ for (i =0; i < number; i++){ int index = number_range(0, max_rares - 1); obj = rares[index]; REMOVE_BIT(obj->extra_flags,ITEM_INVENTORY); obj_from_char( obj ); if (ch == victim) extract_obj( obj ); else obj_to_obj( obj, bag ); trans ++; rares[index] = rares[max_rares--]; if (max_rares < 1) return trans; } } else{ for (i =0; i < number && i < max_rares; i++){ obj = rares[i]; REMOVE_BIT(obj->extra_flags,ITEM_INVENTORY); obj_from_char( obj ); if (ch == victim) extract_obj( obj ); else obj_to_obj( obj, bag ); trans++; } } if (trans > 0) obj_to_char( bag, ch ); else extract_obj( bag ); return trans; } /* Written by: Virigoth * returns: pointer to the bag * comments: Strips victim of all objects and deposits into OBJ_VNUM_JAILBAG * which is placed on ch. (fLimOnly = TRUE causes only limited items to be bagged) * * fAll causes all items on character to be put in the bag (minus tattoo) */ OBJ_DATA* create_jailbag(CHAR_DATA* ch, CHAR_DATA* victim, bool fLimOnly, bool fAll){ OBJ_DATA* bag = NULL; OBJ_DATA* obj, *obj_next; char buf[MIL]; int dur = 60; /* we run through all belongings and move to the bag. The bag should be made in OLC in such way as to prevent any other object frombeing put in there. */ if (ch->in_room == NULL) return NULL; /* PC only */ if (IS_NPC(victim)) return NULL; if (IS_IMMORTAL(victim)) return NULL; /* hard core cirminals get everything stripped */ if (victim->pcdata->flagged >= 5) fLimOnly = FALSE; /*Viri: new jail bag each death, was causing too much headache with incorrectly linked objects for ( obj = victim->carrying; obj != NULL; obj = obj_next ){ obj_next = obj->next_content; if (obj->pIndexData->vnum == OBJ_VNUM_JAILBAG && is_name(victim->name, obj->name)) bag = obj; } if (!bag){ for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; if (obj->pIndexData->vnum == OBJ_VNUM_JAILBAG && is_name(victim->name, obj->name)) bag = obj; } } */ if (!bag) { /* if no existin bag with victims name on victim or ch we make new one */ if ( (bag = create_object(get_obj_index(OBJ_VNUM_JAILBAG), 0)) == NULL){ bug("create_jailbag: Could not create a jailbag", 0); return NULL; } } /* set the desc. and details */ sprintf( buf, bag->name, victim->name ); free_string( bag->name ); bag->name = str_dup( buf ); sprintf( buf, bag->short_descr, victim->name ); free_string( bag->short_descr ); bag->short_descr = str_dup( buf ); sprintf( buf, bag->description, victim->name ); free_string( bag->description ); bag->description = str_dup( buf ); /* start transfer */ if (!fLimOnly && victim->gold > 0 ){ obj_to_obj(create_money(victim->gold), bag); victim->gold = 0; } if (!IS_IMMORTAL(victim)){ for ( obj = victim->carrying; obj != NULL; obj = obj_next ){ obj_next = obj->next_content; if (obj->wear_loc == WEAR_TATTOO) continue; if (!fAll){ if (fLimOnly && !IS_LIMITED(obj)) continue; if (IS_SET(obj->wear_flags, ITEM_HAS_OWNER)) continue; if( is_affected_obj(obj, gen_malform) || is_affected_obj(obj, gen_hwep)) continue; } REMOVE_BIT(obj->extra_flags,ITEM_INVENTORY); obj_from_char( obj ); obj_to_obj( obj, bag ); } } /* dont create a bag if empty or ch == victim */ if (!bag->contains || ch == victim){ extract_obj(bag); return NULL; } /* move the bag to ch automaticly */ obj_to_char(bag, ch); /* set the timer to prevent abuse */ bag->timer = dur; return bag; } /* finds a random justice and and jails the victim using that justice */ CHAR_DATA* surrender( CHAR_DATA* victim ){ const int max_justice = 16; CHAR_DATA* justice[max_justice]; int last_justice = 0; CHAR_DATA* vch; for (vch = player_list; vch; vch = vch->next_player ){ if (!IS_IMMORTAL(vch) && vch->pCabal && IS_CABAL(vch->pCabal, CABAL_JUSTICE)) justice[last_justice++] = vch; } if (last_justice < 1) return victim; else vch = justice[number_range(0, last_justice - 1)]; act("A guard drags $N towards you handing $M to you.", vch, NULL, victim, TO_CHAR ); act("A guard drags you towards $n handing you to $m.", vch, NULL, victim, TO_VICT ); return vch; } /* returns position in jail_table, based on current room vnum */ int jail_cell_lookup(int vnum){ int jail = 0; for (jail = 0; jail < MAX_HOMETOWN; jail ++){ int cell = 0; /* search through each hometown for matching vnum of room */ if (!jail_table[jail].name) break; /* check each cell */ for (cell = 0; cell < MAX_CELL; cell++){ if (!jail_table[jail].cell[cell]) continue; if (jail_table[jail].cell[cell] == vnum){ return jail; } }//END cell match }//END jail search return 0; } /* returns spot in execution_Table */ int jexecution_lookup(const char *name) { int e; for ( e = 0; execution_table[e].name != NULL; e++){ if (!execution_table[e].name[0]) continue; if (LOWER(name[0]) == LOWER(execution_table[e].name[0]) && !str_prefix( name, execution_table[e].name)) return e; } return 0; } /* Written by: Virigoth * * Returns: pointer to paf with gen_jail so name of justice can be set. * * Used: jail.c, effect.c * * Comment: Sets a current sentance based on "type" and "level". Type * * is JAIL_XXX from jail.h, level is severity which affects things based* * on type. Ch is the person to have gen_jail set/changed */ AFFECT_DATA* set_sentence(CHAR_DATA* ch, int type, int level){ AFFECT_DATA* paf, af; CHAR_DATA* wch; char buf[MIL]; char buf2[MIL]; int cur_dur = 0; /* poor man flag for change */ buf[0] = '\0'; /* set common things */ af.type = gen_jail; af.where = TO_AFFECTS; af.bitvector = 0; af.location = APPLY_NONE; /* check if there is existing duration/type */ if ( (paf = affect_find(ch->affected, gen_jail)) != NULL) cur_dur = paf->duration; switch(type){ default: bug("set_sentence: Unkown type.", 0); return NULL; /* NORMAL */ case JAIL_NORMAL: af.modifier = JAIL_NORMAL; af.duration = DUR_NORMAL; af.level = 0; sprintf(buf, "Normal for %d hours", af.duration); break; /* BAIL */ case JAIL_BAIL: af.modifier = JAIL_BAIL; af.duration = UMAX(DUR_BAIL, cur_dur); af.level = level; sprintf(buf, "Bail of %d gold for %d hours (Use \"bail\" to pay)", SEV_BAIL * level, af.duration); break; /* EXTENDED */ case JAIL_EXTENDED: af.modifier = JAIL_EXTENDED; af.duration = UMAX(5, DUR_EXTENDED + (SEV_EXTENDED * level) - (DUR_NORMAL - cur_dur)); af.level = level; sprintf(buf, "Extended for %d hours.", af.duration); break; /* EXECUTION */ case JAIL_EXECUTE: af.modifier = JAIL_EXECUTE; af.duration = DUR_EXECUTE; af.level = level; sprintf(buf, "Execution in %d hours.", af.duration); break; case JAIL_RELEASE: af.modifier = JAIL_RELEASE; af.duration = DUR_RELEASE; af.level = level; sprintf(buf, "Release in %d hours.", af.duration); break; } act_new("Your sentence has been set to $t.", ch, buf, NULL, TO_CHAR, POS_DEAD); sprintf(buf2, "%s's sentence has been set to %s.", PERS2(ch), buf); /* broadcast on justice channel */ for ( wch = char_list; wch != NULL; wch = wch->next ){ if ( IS_NPC(wch) && IS_SET(wch->off_flags,CABAL_GUARD) && wch->pIndexData->group == VNUM_JUSTICE ){ REMOVE_BIT(wch->comm,COMM_NOCHANNELS); REMOVE_BIT(wch->comm,COMM_NOCABAL); do_jcabaltalk(wch, buf2); SET_BIT(wch->comm,COMM_NOCABAL); SET_BIT(wch->comm,COMM_NOCHANNELS); break; } }//END CABAL CHANNEL TALK /* conclave gets reported when someone gets thrown injail */ if (type == JAIL_NORMAL){ sprintf(buf2, "Contacts report of %s's arrival in %s.", PERS2(ch), ch->in_room->area->name); for ( wch = char_list; wch != NULL; wch = wch->next ){ if ( IS_NPC(wch) && IS_SET(wch->off_flags,CABAL_GUARD) && wch->pIndexData->group == VNUM_LEGION ){ REMOVE_BIT(wch->comm,COMM_NOCHANNELS); REMOVE_BIT(wch->comm,COMM_NOCABAL); do_cabaltalk(wch, buf2); SET_BIT(wch->comm,COMM_NOCABAL); SET_BIT(wch->comm,COMM_NOCHANNELS); break; } } } /* decide between new paf, or current */ if (paf){ paf->modifier = af.modifier; paf->duration = af.duration; paf->level = level; return paf; } return affect_to_char(ch, &af); } /* Written by: Virigoth * * Returns: pointer of cell to put char. in, requires first cell in * * jail_table to contain cells and data to be used in case of no match * * found * * Used: jail.c, * * Comment: Jailcells stored in jail_table, cell is based on justice * * hometown, if no jail cells found there, it will search for first jail* * possible */ ROOM_INDEX_DATA* get_jailcell(int hometown){ int jail = jail_lookup(hometown_table[hometown].name); int small = 9999; int cell = 0; ROOM_INDEX_DATA* ret_cell = NULL; AREA_DATA* pArea; // first check if the hometown is lawful if ( (pArea = get_area_data_str(jail_table[jail].name)) != NULL && !IS_AREA(pArea, AREA_LAWFUL)){ /* check all jails pick first lawful city with jail */ int jaill; for ( jaill = 0; jail_table[jaill].name != NULL && jaill < MAX_HOMETOWN; jaill++){ if ( (pArea = get_area_data_str(jail_table[jaill].name)) != NULL && IS_AREA(pArea, AREA_LAWFUL)) jail = jaill; } } /* we need to traverse through the cells in the given city and select the one with lowest amount of characters */ for (cell = 0; cell < MAX_CELL; cell++){ ROOM_INDEX_DATA* room; CHAR_DATA* vch; int count = 0; /* skip 0 cells */ if (!jail_table[jail].cell[cell]) continue; /* get the room, check if exists */ if ( (room = get_room_index(jail_table[jail].cell[cell])) == NULL){ char buf[MIL]; sprintf(buf, "get_jailcell: cell %d does not exist.", jail_table[jail].cell[cell]); bug(buf, 0); return NULL; } /* count PC's in the room */ for (vch = room->people; vch; vch = vch->next_in_room){ if (!IS_NPC(vch) && (vch->pCabal == NULL || !IS_CABAL(vch->pCabal, CABAL_JUSTICE))) count++; } /* decide if this room is the one with least people */ if (count < small){ small = count; ret_cell = room; } /* continue the search */ } /* search over, make sure there is a room at all */ if (!ret_cell){ char buf[MIL]; sprintf(buf, "get_jailcell: No valid cell found for hometown %d.", hometown); bug(buf, 0); } return ret_cell; } /* Written by: Virigoth * * Returns: Void * * Used: jail.c, * * Comment: Causes the exe_mob as per jail_table to yell the string * * the mob is created at the "guardhouse" room, then destroyed */ void jail_announce(int jail, char* string){ CHAR_DATA* mob; ROOM_INDEX_DATA* room; /* safety */ if (!string) return; if (jail > MAX_HOMETOWN){ bug("jail_announce: jail was greater then MAX_HOMETOWN.", 0); return; } /* Grab the room to be yelled in*/ if ( (room = get_room_index(jail_table[jail].exe_room)) == NULL){ char buf[MIL]; sprintf(buf, "jail_announce: room %d does not exist.", jail_table[jail].exe_room); bug(buf, 0); return; } /* grab the mob to do the yelling */ if ( (mob = create_mobile( get_mob_index(jail_table[jail].exe_mob))) == NULL){ char buf[MIL]; sprintf(buf, "jail_announce: mob %d does not exist.", jail_table[jail].exe_mob); bug(buf, 0); return; } /* move mob to the right room, yell, and cleanup */ char_to_room(mob, room); REMOVE_BIT(mob->comm,COMM_NOYELL); REMOVE_BIT(mob->comm,COMM_NOCHANNELS); do_yell(mob, string); SET_BIT(mob->comm,COMM_NOYELL); SET_BIT(mob->comm,COMM_NOCHANNELS); /* just in case something did hit him */ stop_fighting(mob, FALSE); char_from_room(mob); extract_char(mob, TRUE); } /* Allows a criminal to surrender */ void do_surrender( CHAR_DATA* ch, char* argument ){ if (IS_OUTLAW( ch )){ send_to_char("Go fall on a sword instead.\n\r", ch); return; } else if (!IS_WANTED( ch )){ send_to_char("You have not been marked a criminal.\n\r", ch); return; } else if (is_affected(ch, gen_jail) || IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL)){ send_to_char("You're already in jail.\n\r", ch); return; } else if (is_fight_delay( ch, 180 )){ send_to_char("You cannot surrender after recent combat.\n\r", ch); return; } else if (IS_NULLSTR(argument)){ send_to_char("Are you sure you wish to surrender to forces of Law?\n\rUse \"surrender confirm\" to confirm.\n\r", ch ); return; } else{ char buf[MIL]; sprintf( buf, "%s has chosen to surrender to our judgement.", PERS2( ch )); cabal_echo_flag( CABAL_JUSTICE, buf ); jail_char( ch, ch ); } } /* Written by: Virigoth * * Returns: Void * * Used: fight.c, * * Comment: Checkes for wanted status, and transports victim to correct jail* * if needed. Sets gen_jail if needed. jail selected based on ch home */ void jail_char(CHAR_DATA* cha, CHAR_DATA* victim){ CHAR_DATA* ch = cha; ROOM_INDEX_DATA* cell; AFFECT_DATA* paf; AREA_DATA* pArea; char buf[MIL]; int max_pen = 0, crime = 0; /* check for problems */ if (!ch || !victim){ bug("jail_char: NULL ch or victim passed.", 0); return; } if (IS_NPC(victim)){ bug("jail_char: victim NPC passed.", 0); return; } /* check for wanted status */ if (!IS_SET(victim->act,PLR_WANTED)) return; /* check for charmies */ if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)){ if (ch->leader) ch = ch->leader; else if (ch->master) ch = ch->master; else{ bug("jail_char: NPC without master passed.", 0); return; } } /* check for mob apprehension */ else if (IS_NPC(ch) || ch == victim) ch = surrender( victim ); /* grab the jail cell to transport too */ if ( (cell = get_jailcell(ch->hometown)) == NULL){ char buf[MIL]; sprintf(buf, "jail_char: get_jailcell returned NULL for town of %s.", hometown_table[ch->hometown].name); bug(buf, 0); return; } /* stop the fight, make things all safe so victim doesnt die in cell */ stop_fighting( victim, TRUE ); if (IS_AFFECTED2(victim,AFF_RAGE)) { REMOVE_BIT(victim->affected2_by,AFF_RAGE); affect_strip(victim,gsn_rage); } affect_strip(victim,gsn_poison); affect_strip(victim,gsn_plague); affect_strip(victim,gen_bleed); affect_strip(victim,gsn_insect_swarm); affect_strip(victim, skill_lookup("visitation")); affect_strip(victim,skill_lookup("dysentery")); victim->pcdata->condition[COND_HUNGER]=45; victim->pcdata->condition[COND_THIRST]=45; victim->hit = UMAX(1, 25 * victim->max_hit / 100); victim->move = 25 * victim->max_move / 100; victim->mana = 0 * victim->max_mana / 100; victim->position = POS_RESTING; die_follower(victim, FALSE); /* get the belongings for die hard criminals, if ch and victim are same (surrender) items are poofed */ if (victim->pcdata->flagged > 11 ){ /* 10+ */ create_jailbag(ch, victim, TRUE, FALSE); } else if (victim->pcdata->flagged > 6 ){ /* 6 - 10 */ int num = get_random_rares( ch, victim, 6, FALSE ); sendf( ch, "You recive %d item%s from %s.\n\r", num, num == 1 ? "" : "s", PERS2( victim )); sendf( victim, "You lost %d item%s.\n\r", num, num == 1 ? "" : "s"); } else if (victim->pcdata->flagged > 3 ){ /* 3 - 5 */ int num = get_random_rares( ch, victim, 3, FALSE ); sendf( ch, "You recive %d item%s from %s.\n\r", num, num == 1 ? "" : "s", PERS2( victim )); sendf( victim, "You lost %d item%s.\n\r", num, num == 1 ? "" : "s"); } else if (victim->pcdata->flagged > 1 ){ /* 1 - 2 */ int num = get_random_rares( ch, victim, 1, TRUE ); sendf( ch, "You recive %d item%s from %s.\n\r", num, num == 1 ? "" : "s", PERS2( victim )); sendf( victim, "You lost %d item%s.\n\r", num, num == 1 ? "" : "s"); } /* Print some text and move the victim */ if (ch != victim ){ act("As you lose your consciousness you see a swarm of guards surround you quickly.", ch, NULL, victim, TO_VICT); act("As $N loses $S consciousness you call onto guards to capture $M.", ch, NULL, victim, TO_CHAR); act("As $N loses $S consciousness $n calls onto guards to capture $M.", ch, NULL, victim, TO_NOTVICT); } else{ act("The guards lead you away.\n\r", ch, NULL, victim, TO_CHAR ); } /* give credit */ if (ch != victim && IS_CABAL(ch->pCabal, CABAL_JUSTICE) && IS_SET(victim->act,PLR_WANTED) && !IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL) && !is_affected(ch, gen_jail)){ cp_event(ch, victim, NULL, CP_EVENT_CAPTURE); } /* boost the relations between the justice and royals of areas that this person commited crimes in */ for (paf = victim->affected; paf; paf = paf->next ){ if (paf->type == gsn_wanted && paf->bitvector){ /* crime found/wanted we increase the relations but need area first */ if ( (pArea = get_area_data( paf->location )) == NULL){ bug("jail_char: could not get area for vnum %d.", paf->location); continue; } else if (pArea->pCabal) affect_justice_relations(pArea->pCabal, 50); } } /* move the victim */ act("The guards quickly carry $N off to $S jailcell.", ch, NULL, victim, TO_NOTVICT); char_from_room(victim); char_to_room(victim, cell); act("A small squad of justice guards throws $n into the cell.", victim, NULL, NULL, TO_ROOM); do_look(victim, "auto"); /* get the maximum penalty based on "wanted" effect */ crime = show_crimes( victim, victim, TRUE, TRUE ); switch ( crime ){ case CRIME_LIGHT: max_pen = JAIL_BAIL; break; case CRIME_NORMAL: max_pen = JAIL_EXTENDED; break; case CRIME_HEAVY: max_pen = JAIL_EXECUTE; break; case CRIME_DEATH: max_pen = JAIL_EXECUTE; break; default: max_pen = JAIL_NORMAL; break; } /* outlaws always get the cut */ if (IS_OUTLAW(victim)){ crime = CRIME_DEATH; max_pen = JAIL_EXECUTE; } if ( crime == CRIME_DEATH || ch == victim){ if( (paf = set_sentence(victim, max_pen, number_range(1, 5))) == NULL) send_to_char("`!An error occured, contact an immortal.``\n\r", ch); else string_to_affect(paf, ch == victim ? "surrendered" : ch->name); } else if( (paf = set_sentence(victim, JAIL_NORMAL, 1)) == NULL) send_to_char("`!An error occured, contact an immortal.``\n\r", ch); else string_to_affect(paf, ch == victim ? "surrendered" : ch->name); /* Yell out the announcement */ if (ch == victim) sprintf(buf, "Justice be praised, %s has surrendered to Justice!", PERS2(victim)); else sprintf(buf, "Justice be praised, %s has been captured by %s!", PERS2(victim), PERS2(ch)); jail_announce(jail_cell_lookup(victim->in_room->vnum), buf); /* increase capture count if ch != victim */ if (ch != victim && ch->pCabal && IS_CABAL(ch->pCabal, CABAL_JUSTICE)){ ch->pcdata->member->kills++; } } /* Written by: Virigoth * * Returns: Void * * Used: effect.c, * * Comment: Transports the character out of the jail cell into the room * * dictated by "guardhouse" in jail_table */ void unjail_char(CHAR_DATA* ch){ ROOM_INDEX_DATA* room; CHAR_DATA* wch; AFFECT_DATA* paf; char buf[MIL]; int jail = 0; int exit = 0; /* check for problems */ if (!ch){ bug("unjail_char: NULL ch passed.", 0); return; } if (IS_NPC(ch)){ bug("unjail_char: ch NPC passed.", 0); return; } /* check that char. is in a cell */ if (!IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL)) bug("unjail_char: ch not in room marked ROOM_JAILCELL", 0); /* check for exit out of the jail */ jail = jail_cell_lookup(ch->in_room->vnum); exit = jail_table[jail].guardhouse; /* if exit is 0 we send to home temple */ if ( (room = get_room_index(exit)) == NULL){ char buf[MIL]; sprintf(buf, "unjail_char: room %d does not exist as an exit.", exit); bug(buf, 0); } if (!room) room = get_room_index(get_temple(ch)); if (room == NULL){ send_to_char("You are completely lost.\n\r",ch); return; } /* Yell out the announcement */ sprintf(buf, "The sentence served, %s is now free and innocent!", PERS2(ch)); jail_announce(jail, buf); /* move the char out of jail*/ char_from_room(ch); char_to_room(ch, room); act("The guards escort $n into the area and release $m.", ch, NULL, NULL, TO_ROOM); do_look(ch, "auto"); /* get rid of flag */ if (!IS_OUTLAW( ch )){ REMOVE_BIT(ch->act, PLR_WANTED); } /* broadcast on justice channel */ for ( wch = char_list; wch != NULL; wch = wch->next ){ if ( IS_NPC(wch) && IS_SET(wch->off_flags,CABAL_GUARD) && wch->pIndexData->group == VNUM_JUSTICE ){ REMOVE_BIT(wch->comm,COMM_NOCHANNELS); REMOVE_BIT(wch->comm,COMM_NOCABAL); do_jcabaltalk(wch, buf); SET_BIT(wch->comm,COMM_NOCABAL); SET_BIT(wch->comm,COMM_NOCHANNELS); break; } }//END CABAL CHANNEL TALK /* small check */ if ( (paf = affect_find(ch->affected, gen_jail)) != NULL){ paf->modifier = JAIL_NONE; affect_strip(ch, gen_jail); } //set wanted to expire for (paf = ch->affected; paf; paf = paf->next){ if (paf->type == gsn_wanted) paf->duration = 0; } // affect_strip( ch, gsn_wanted ); } /* Written by: Virigoth * * Returns: Void * * Used: effect.c, * * Comment: Command which lets the justice dictate fate of prisoner. * * only the justice matching the string passed in gen_jail can affect * * the prisoner, and only if prisoner is stillin a ROOM_JAILCELL room. */ void do_jail( CHAR_DATA *ch, char *argument ){ /* jail <criminal> <sentence> <severity/type of execution> SENTENCE FLOW: (NORMAL SET ON CAPTURE OR DEATH FOR ATTORICTY CRIMES) /-> JAIL_TRANSFER /--> JAIL_BAIL -> JAIL_EXTEND-> JAIL_RELEASE JAIL_NORMAL ---> JAIL_EXTEND -> JAIL_RELEASE \--> JAIL_EXECUTE \-> JAIL_RELEASE */ CHAR_DATA* victim; //criminal CHAR_DATA* justice; //Owner of criminal CHAR_DATA* vch; AFFECT_DATA* paf; //Info from gen_jail (if not found, abort) BUFFER *buffer; //For display of criminals char arg1[MIL]; //Target criminal char arg2[MIL]; //Sentence char buf[MIL]; int count = 0; int cur_sen = JAIL_NORMAL; int new_sen = JAIL_NORMAL; int new_sev = 1; int max_pen = JAIL_BAIL; bool fAllow = TRUE; //used tocheck if sentence flow is allowed if (!ch->pCabal || !IS_CABAL(ch->pCabal, CABAL_JUSTICE)) return; /* first check for null to show syntax mates */ if (argument[0] == '\0'){ sendf(ch, "Syntax: jail <criminal> <sentence> <severity (1-10)>\n\r"\ "for <sentence> of bail, amount is %d x severity gold with limit of %dh\n\r"\ "for <sentence> of extended, length is %d + (%d x severity) hours\n\r\n\r"\ "Following are all criminals with their jurisdictions:\n\r", SEV_BAIL, DUR_BAIL, DUR_EXTENDED, SEV_EXTENDED); /* run through players showing info */ buffer=new_buf(); for (vch = player_list; vch; vch = vch->next){ /* count only those in cells and still wanted*/ if (!IS_SET(vch->act, PLR_WANTED)|| !vch->in_room || !IS_SET(vch->in_room->room_flags2, ROOM_JAILCELL)) continue; /* check for gen_jail with justice name */ if ( (paf = affect_find(vch->affected, gen_jail)) == NULL || !paf->has_string) continue; /* add info to buffer */ sprintf(buf, "%d. %-5s %-15s in %-10s assigned to %-15s [%-2s (%dh)]\n\r",++count, PERS2(vch), vch->in_room->area->name, vch->in_room->name, paf->string, paf->modifier == JAIL_NONE ? "None" : paf->modifier == JAIL_NORMAL ? "Normal" : paf->modifier == JAIL_EXTENDED ? "Extended" : paf->modifier == JAIL_BAIL ? "Bail" : paf->modifier == JAIL_EXECUTE ? "Execution" : paf->modifier == JAIL_RELEASE ? "Release" : "Error", paf->duration); add_buf( buffer, buf ); } /* check if anything found */ if (!count) send_to_char("The jails are empty.\n\r", ch); else page_to_char(buf_string(buffer),ch); free_buf(buffer); return; } /* start testing the actual arguments */ argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if ( (victim = get_char(arg1)) == NULL || IS_NPC(victim)){ send_to_char("No such player found.\n\r", ch); return; } /* check they are criminal and justice have jurisdiction */ if ( (!IS_SET(victim->act, PLR_WANTED)|| !victim->in_room || !IS_SET(victim->in_room->room_flags2, ROOM_JAILCELL)) && !IS_IMMORTAL(ch)){ send_to_char("The target player must be [`1WANTED``] and be in a jailcell.\n\r", ch); return; } if ( (paf = affect_find(victim->affected, gen_jail)) == NULL){ send_to_char("That player is not affected by any type of incarceration.\n\r", ch); return; } else if (!paf->has_string || !is_name(paf->string, ch->name)){ if (!IS_IMMORTAL(ch)){ send_to_char("You do not have jurisdiction over that criminal.\n\r", ch); return; } } if (arg2[0] == '\0' || (str_cmp("bail", arg2) && str_cmp("extend", arg2) && str_cmp("execute", arg2) && str_cmp("release", arg2) && str_cmp("transfer", arg2))){ send_to_char("The sentence must be one of following:\n\r"\ "bail, extend, execute, release, transfer\n\r", ch); return; } /* get the maximum penalty based on "wanted" effect */ switch (show_crimes( ch, victim, FALSE, TRUE ) ){ case CRIME_LIGHT: max_pen = JAIL_BAIL; break; case CRIME_NORMAL: max_pen = JAIL_EXTENDED; break; case CRIME_HEAVY: max_pen = JAIL_EXECUTE; break; case CRIME_DEATH: max_pen = JAIL_EXECUTE; break; } /* select action and check over severities*/ if (!str_cmp("bail", arg2)){ new_sen = JAIL_BAIL; if (!(new_sev = atoi(argument)) || new_sev > 10){ send_to_char("Severity must be on scale 1-10", ch); return; } } else if (!str_cmp("extend", arg2)){ new_sen = JAIL_EXTENDED; if (!(new_sev = atoi(argument))){ send_to_char("Severity must be on scale 1-10", ch); return; } } else if (!str_cmp("execute", arg2)){ new_sen = JAIL_EXECUTE; if ( (new_sev = jexecution_lookup(argument)) == 0){ int i = 0; send_to_char("Following are valid executions:\n\r", ch); for (i = 0; execution_table[i].name != NULL; i++){ if (!execution_table[i].name[0]) continue; sendf(ch, "%s\n\r", execution_table[i].name); } return; } } else if (!str_cmp("release", arg2)) new_sen = JAIL_RELEASE; else if (!str_cmp("transfer", arg2)) new_sen = JAIL_TRANSFER; else{ sprintf(buf, "do_jail: Sentence %s not found or not valid.", arg2); bug(buf, 0); send_to_char(buf, ch); return; } /* check if the sentence selected is not over max */ if (new_sen > max_pen ){ act("That sentence is too severe based on the crimes $N has commited.", ch, NULL, victim, TO_CHAR); return; } /* All checks are clear, we now make sure that the SENTENCE flow is satisfied */ cur_sen = paf->modifier; switch (cur_sen){ default: case JAIL_RELEASE: case JAIL_TRANSFER: case JAIL_EXECUTE: fAllow = FALSE; break; case JAIL_EXTENDED: if (new_sen != JAIL_RELEASE && new_sen != JAIL_TRANSFER) fAllow = FALSE; break; case JAIL_BAIL: if (new_sen != JAIL_TRANSFER) fAllow = FALSE; break; case JAIL_NORMAL: break; } if (!fAllow){ send_to_char("This new verdict is not allowed due to criminals current sentence.\n\r", ch); return; } /* change verdict */ if (new_sen == JAIL_TRANSFER){ if ( (justice = get_char(argument)) == NULL){ send_to_char("No such player found.\n\r", ch); return; } if (justice == ch){ send_to_char("You already have jurisdiction over that criminal.\n\r", ch); return; } if (!justice->desc || ch->in_room->vnum == ROOM_VNUM_LIMBO){ send_to_char("Their soul seemed to vacate the body for now.\n\r", ch); return; } if (IS_NPC(justice) || justice->pCabal == NULL || !IS_CABAL(justice->pCabal, CABAL_JUSTICE)){ send_to_char("That person is not a Justice member.\n\r", ch); return; } /* change the name of Justice in charge */ string_to_affect(paf, justice->name); act("You have given $N jurisdiction over $t.", ch, PERS2(victim), justice, TO_CHAR); act("$n has given you jurisdiction over $t.", ch, PERS2(victim), justice, TO_VICT); act("Jurisdiction over your sentance has just been handed to $N.", victim, NULL, justice, TO_CHAR); return; } /* change sentance */ set_sentence(victim, new_sen, new_sev); act_new("$N's new sentence has been set.", ch, NULL, victim, TO_CHAR, POS_DEAD); } /* Written by: Virigoth * * Returns: Void * * Used: effect.c, * * Comment: Performs the actual execution and creates an object EXECUTION* * as a marker, which decays after "decay" ticks. The periodic yells are* * done by gen. Execution performed based on current Jailcell location */ void jail_execute(CHAR_DATA* ch, CHAR_DATA* mob, int exe_type, char* name){ ROOM_INDEX_DATA* room; AFFECT_DATA* crime; OBJ_DATA* obj, *bag, *tattoo; CHAR_DATA *vch, *vch_next; char crime_str[MIL], strsave[MIL]; int crimes = 0; char buf[MIL]; int jail = 0; int exit = 0; const int dur = 480; /* check for problems */ if (!ch){ bug("jail_execute: NULL ch passed.", 0); return; } if (IS_NPC(ch)){ bug("jail_execute: NPC ch passed.", 0); return; } /* check that char. is in a cell */ if (!IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL)) bug("jail_execute: ch not in room marked ROOM_JAILCELL", 0); jail = jail_cell_lookup(ch->in_room->vnum); exit = jail_table[jail].exe_room; /* if exit is 0 we send to home temple */ if ( (room = get_room_index(exit)) == NULL){ char buf[MIL]; sprintf(buf, "jail_execute: room %d does not exist as an exe_room.", exit); bug(buf, 0); } if (!room) room = get_room_index(get_temple(ch)); if (room == NULL){ send_to_char("You are completely lost.\n\r",ch); return; } /* move the char out of jail, announce */ char_from_room(ch); char_to_room(ch, room); act("The guards escort $n into the area.", ch, NULL, NULL, TO_ROOM); do_look(ch, "auto"); /* Announce one last time */ /* we make a bitvector of all the cimes the person has commited */ for (crime = ch->affected; crime != NULL; crime = crime->next){ if (crime->type == gsn_wanted && crime->bitvector != 0){ crimes |= crime->bitvector; } } sprintf( crime_str, "For the crimes of " ); if (IS_SET(crimes, CRIME_FLAG_S)){ strcat( crime_str, "Not sheathing" ); strcat( crime_str, ", "); } if (IS_SET(crimes, CRIME_FLAG_L)){ strcat( crime_str, crime_table[CRIME_LOOT].name ); strcat( crime_str, ", "); } if (IS_SET(crimes, CRIME_FLAG_T)){ strcat( crime_str, crime_table[CRIME_THEFT].name ); strcat( crime_str, ", "); } if (IS_SET(crimes, CRIME_FLAG_A)){ strcat( crime_str, crime_table[CRIME_ASSAULT].name ); strcat( crime_str, ", "); } if (IS_SET(crimes, CRIME_FLAG_M)){ strcat( crime_str, crime_table[CRIME_MURDER].name ); strcat( crime_str, ", "); } if (IS_SET(crimes, CRIME_FLAG_O)){ strcat( crime_str, crime_table[CRIME_OBSTRUCT].name ); strcat( crime_str, ", "); } sprintf(buf, "%sby the Law of Aabahran,\n\r"\ "%s has been sentenced by %s %s\n\r"\ "May Virigoth have mercy on your soul %s.", crime_str, PERS2(ch), IS_NULLSTR(name) ? "Justice" : name, execution_table[exe_type].announce, PERS2(ch)); jail_announce(jail, buf); /* show the TOVICT messages from the table*/ act(execution_table[exe_type].pre_act, mob, NULL, ch, TO_CHAR); act(execution_table[exe_type].on_act_r, mob, NULL, ch, TO_NOTVICT); act(execution_table[exe_type].on_act_c, mob, NULL, ch, TO_VICT); /* create bag with stuff (NULL if no bag, or no stuff to bag)*/ bag = create_jailbag(mob, ch, FALSE, TRUE); /* get rid of flag */ if (!IS_OUTLAW( ch )) REMOVE_BIT(ch->act, PLR_WANTED); affect_strip( ch, gsn_wanted ); /* give penalty */ if (!IS_OUTLAW( ch )) ch->exp -= UMIN(6000,UMIN(exp_per_level(ch,ch->level),ch->exp/10)); /* create the object */ obj = create_object( get_obj_index( OBJ_VNUM_EXECUTION ), 0); free_string(obj->description); sprintf(buf, execution_table[exe_type].room_desc, PERS2(ch)); obj->description = str_dup( buf ); obj->timer = dur; obj_to_room(obj, room); /* broadcast on justice channel */ sprintf(buf, "%s has been executed by %s as per %s's orders. The Justice prevails!", PERS2(ch), PERS2(mob), IS_NULLSTR(name) ? "Justice" : name); cabal_echo_flag( CABAL_JUSTICE, buf ); /* slay him */ sprintf( log_buf, "`&%s executed at %s [room %d]``", ch->name, ch->in_room->name, ch->in_room->vnum); nlogf( log_buf ); wiznet(log_buf,NULL,NULL,WIZ_DEATHS,0,0); ch->pcdata->dall++; ch->pcdata->dpc++; mud_data.deaths++; stop_fighting( ch, TRUE ); if (!IS_NPC(ch) && IS_SET(ch->act, PLR_DOOF)) REMOVE_BIT(ch->act, PLR_DOOF); death_cry( ch, mob ); for ( vch = char_list; vch != NULL; vch = vch_next ){ vch_next = vch->next; if (IS_NPC(vch) && vch->hunting != NULL && vch->hunting == ch ){ vch->hunting = NULL; if (IS_SET(vch->act,ACT_AGGRESSIVE)) { act( "$n slowly disappears.",vch,NULL,NULL,TO_ROOM ); extract_char( vch, TRUE ); } } } sendf(ch, "\n\rAs the cold chill of death descends upon you %s grants you yet another chance.\n\r"\ "You have been granted a temporary sanctuary as an invincible ghost.\n\rAs long as you don't attack"\ " anything.\n\r", (ch->pcdata->deity[0] == '\0' ? "The Creator" : ch->pcdata->deity)); tattoo = get_eq_char(ch, WEAR_TATTOO); if (tattoo != NULL) obj_from_char(tattoo); extract_char( ch, FALSE ); if (tattoo != NULL) { obj_to_char(tattoo, ch); equip_char(ch, tattoo, WEAR_TATTOO); } /* move the bag to ex-criminal */ if (bag){ obj_from_char(bag); obj_to_char(bag, ch); } /* Destory the mob */ char_from_room(mob); extract_char(mob, TRUE); ch->position = POS_STANDING; ch->hit = 1; ch->mana = 1; ch->move = UMAX( 100, ch->move ); ch->pcdata->ghost = time(NULL); ch->pcdata->fight_delay = time(NULL); ch->pcdata->pk_delay = time(NULL); ch->pcdata->condition[COND_HUNGER]=48; ch->pcdata->condition[COND_THIRST]=48; if (!IS_NPC(ch) && ch->pcdata->familiar != NULL){ extract_char( ch->pcdata->familiar, TRUE ); ch->pcdata->familiar=NULL; } if (ch->pcdata->dall > 60 && get_trust(ch) < MASTER){ send_to_char("You have died due to failing health.\n\r",ch); sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name ) ); wiznet("$N dies due to failing health.",ch,NULL,0,0,0); ch->pcdata->dall = 0; if (ch->level > 20) deny_record(ch); if (ch->pCabal){ CABAL_DATA* pCab = ch->pCabal; update_cabal_skills(ch, ch->pCabal, TRUE, TRUE); char_from_cabal( ch ); CHANGE_CABAL(pCab); save_cabals( TRUE, NULL ); } if (ch->pcdata->pbounty){ rem_bounty( ch->pcdata->pbounty ); free_bounty( ch->pcdata->pbounty ); } extract_char( ch, TRUE ); if ( ch->desc != NULL ) close_socket( ch->desc ); unlink(strsave); return; } if (ch->perm_stat[STAT_CON] > 3){ if (ch->pcdata->dall%5 == 0) { ch->perm_stat[STAT_CON]--; send_to_char("You feel less healthy.\n\r",ch); } } /* Cabal Requip */ save_char_obj( ch ); } /* Written by: Virigoth * * Returns: Void * * Used: jail.c,interp.c * * Comment: Allows to pay the bribe to current justice overseeing char. * if justice is not present, gold is deducted but not deposited anywhere */ void do_bail( CHAR_DATA *cha, char *argument ){ /* bail <target> <gold/cp>, if <target> is "gold" or "cp" is ignored */ AFFECT_DATA* paf; CHAR_DATA* justice; CHAR_DATA* ch = cha; char arg1[MIL]; int bail = 0; int assets = 0; bool fGold = FALSE; argument = one_argument(argument, arg1); /* select between paying for self, or other */ if (arg1[0] != '\0' && str_cmp("gold", arg1) && str_cmp("cp", arg1)){ if ( (ch = get_char_world(cha, arg1)) == NULL){ send_to_char("You cannot locate them.\n\r", cha); return; } if (IS_NPC(ch)){ send_to_char("Pay bail for a mob? What a grand idea!\n\r", cha); return; } } /* now "ch" is proper target */ /* check if affected by bail */ if ( (paf = affect_find(ch->affected, gen_jail)) == NULL || paf->modifier != JAIL_BAIL){ send_to_char("There is no need or no possibility of paying bail.\n\r", cha); return; } /* calculate bail */ bail = paf->level * SEV_BAIL; /* check for latter arguments (no gold/cp argument)*/ if (ch == cha){ if (arg1[0] == '\0'){ /* Cabaled char's get to pay with cp too */ if (!ch->pCabal) sendf(cha, "Your bail has been set at %d, use \"bail gold\" to pay.\n\r", bail); else sendf(cha, "Your bail has been set at %d Gp or %d Cp, use \"bail <gold/cp>\" to pay.\n\r", bail, bail / 100); return; } else if (!str_cmp("gold", arg1)){ assets = ch->in_bank + ch->gold; fGold = TRUE; } else if (!str_cmp("cp", arg1)){ assets = GET_CP(ch); bail /= 100; } else{ send_to_char("Bail <criminal> <gold/cp>\n\rBail <gold/cp>\n\r", cha); return; } } else{ if (argument[0] == '\0'){ /* Cabaled char's get to pay with cp too */ if (!ch->pCabal) sendf(cha, "Their bail has been set at %d, use \"bail gold\" to pay.\n\r", bail); else sendf(cha, "Their bail has been set at %d Gp or %d Cp, use \"bail <gold/cp>\" to pay.\n\r", bail, bail / 100); return; } else if (!str_cmp("gold", argument)){ assets = ch->in_bank + ch->gold; fGold = TRUE; } else if (!str_cmp("cp", argument)){ assets = GET_CP(ch); bail /= 100; } else{ send_to_char("Bail <criminal> <gold/cp>\n\rBail <gold/cp>\n\r", cha); return; } } /* check our account */ if (assets < bail){ sendf(cha ,"Your total assets are %d (%s) which is not enough to pay the bail of %d (%s).\n\r", assets, fGold ? "gold" : "cp" , bail, fGold ? "gold" : "cp"); return; } if (fGold){ /* start withdrawing */ cha->in_bank -= bail; if (cha->in_bank < 0){ cha->gold += cha->in_bank; cha->in_bank= 0; } sendf(cha, "Your bank balance is %d, you have %ld gold left on you.\n\r", cha->in_bank, cha->gold); } else CP_GAIN(cha, -bail, TRUE); if ( (justice = get_char(paf->string)) == NULL) return; unjail_char(ch); /* give justice gold */ if (fGold){ justice->in_bank += bail; sendf(justice, "%s has paid the bail. Your bank balance is: %d.\n\r", PERS2(ch), justice->in_bank); }else CP_GAIN(justice, bail, TRUE); } /* Written by: Virigoth * * Returns: TRUE if cells have power * * Used: jail.c, act_move.c * * Comment:Compares the vnum of room passed to jail_table for match of * * cell. If match is made, checks [].guardhouse for any mob marked * * "guild_guard", if found returns TRUE, if not, FALSE */ bool jail_check(ROOM_INDEX_DATA* room){ CHAR_DATA* vch; ROOM_INDEX_DATA* enter; int jail = jail_cell_lookup(room->vnum); /* try to get index to guardhouse */ if ( (enter = get_room_index(jail_table[jail].guardhouse)) == NULL){ char buf[MIL]; sprintf(buf ,"jail_check: Jail guardhouse %d could not be found.", jail_table[jail].guardhouse); bug(buf, 0); return FALSE; } /* all we do is check the guardhouse for cabal_guard */ for (vch = enter->people; vch; vch = vch->next_in_room){ if (IS_NPC(vch) && IS_SET(vch->off_flags, GUILD_GUARD)) return TRUE; } return FALSE; } /* Written by: Virigoth * * Returns: void * * Used: jail.c, act_move.c * * Comment: If ch is in powered jailcell and has no gen_jail, gsn_judge * * is applied with increasing modifier. Past certain point (max_mod) * * ch is teleported out of jail, and will not be able to pass jail fields* * if fGain == TRUE we only check gain the the affect (vtick) FALSE we * * check lowering of the affect (tick) * This is run once per 3 sec (10 x Tick). */ void jail_abuse_check(CHAR_DATA* ch, bool fGain){ AFFECT_DATA* paf, af; int mod = 0; const int ratio = ABUSE_RATIO; //ratio of time in CELL : OUTSIDE const int max_mod = ABUSE_KICK; //How many iterations before being kicked //if in a cell. (10 per tick) /* check if this is gain and we are in a cell */ if (fGain && !IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL)) return; /* check if this is an inmate */ if (IS_IMMORTAL(ch) || IS_NPC(ch) || IS_WANTED(ch) || is_affected(ch, gen_jail)) return; /* check if affect exists */ if ( (paf = affect_find(ch->affected, gsn_judge)) != NULL) mod = paf->modifier; /* check if in jailcell if its powered we add */ if (IS_SET(ch->in_room->room_flags2, ROOM_JAILCELL) && jail_check(ch->in_room)) mod += ratio; else if (!fGain) mod -= PULSE_TICK / PULSE_VIOLENCE; else mod --; /* safety */ mod = URANGE(-1, mod, 3000); /* add on or apply the mod */ if (!paf){ af.type = gsn_judge; af.level = 1; af.duration = -1; af.where = TO_NONE; af.bitvector = 0; af.location = APPLY_NONE; af.modifier = mod; if (mod > 0) affect_to_char(ch, &af); return; } else paf->modifier = mod; /* check if we should kick them out */ if (mod > max_mod){ AFFECT_DATA* paf; ROOM_INDEX_DATA* room; int jail = jail_cell_lookup(ch->in_room->vnum); int exit = jail_table[jail].guardhouse; /* if exit is 0 we send to home temple */ if ( (room = get_room_index(exit)) == NULL){ char buf[MIL]; sprintf(buf, "jail_abuse_check: room %d does not exist as an exit.", exit); bug(buf, 0); } if (!room) room = get_room_index(get_temple(ch)); if (room == NULL){ send_to_char("You are completely lost.\n\r",ch); return; } /* we have the room, so we move them */ act("A squad of guards surrounds the cell and quicly escort $n out.", ch, NULL, NULL, TO_ROOM); act("A squad of guards surrounds the cell and quicly escort you out.", ch, NULL, NULL, TO_CHAR); char_from_room(ch); char_to_room(ch, room); act("A squad of jail guards escort $n in and leave.", ch, NULL, NULL, TO_ROOM); do_look(ch, "auto"); /* decreae the modifier byone ratio at least so we dont get double transport */ if ( (paf = affect_find(ch->affected, gsn_judge)) != NULL) paf->modifier = UMAX(0, paf->modifier - ABUSE_RATIO); }//END kick out else if (mod < 1) affect_strip(ch, gsn_judge); } /* checks if a given crime in given room is a crime */ bool is_crime( ROOM_INDEX_DATA* room, int crime, CHAR_DATA* victim){ if (room == NULL || crime >= MAX_CRIME) return FALSE; else if (!IS_SET(room->area->area_flags, AREA_LAWFUL)) return FALSE; else if (victim && IS_NPC(victim) && IS_SET(victim->act, ACT_RAIDER)) return FALSE; else if (victim && victim->pCabal && IS_CABAL(victim->pCabal, CABAL_JUSTICE)) return TRUE; else if (room->area->crimes[crime] != 0) return TRUE; else return FALSE; } /* marks a given character for a given crime using the "Wanted" skill */ /* information is stored in a seperate wanted effect for each city crimes commited : bitvector city : location times flagged : modifier (if its none zero then the crime has not been flagged for yet) */ AFFECT_DATA* set_crime( CHAR_DATA* ch, CHAR_DATA* victim, AREA_DATA* area, int crime){ int dur = 1440; AFFECT_DATA* paf; CHAR_DATA* vch; int city = 0; bool fJustice = FALSE; if (ch == NULL || IS_NPC(ch) || area == NULL || crime >= MAX_CRIME) return NULL; else{ city = area->vnum; dur = URANGE(1, ch->pcdata->flagged, 10) * dur / 10; } if (area->pCabal != NULL && IS_AREA(area, AREA_CABAL) && IS_CABAL(area->pCabal, CABAL_JUSTICE)) fJustice = TRUE; /* don't bother if victim is wanted and attack is justice */ if (!fJustice && ch->pCabal && IS_CABAL(ch->pCabal, CABAL_JUSTICE) && victim && IS_WANTED(victim)) return NULL; //if in justice cabal we do not need to check /* run through the area checking if there are justice about */ for (vch = player_list; vch; vch = vch->next_player){ if (!IS_NPC(vch) && vch->desc && vch->in_room->area == area && vch->pCabal && (IS_CABAL(vch->pCabal, CABAL_JUSTICE) || IS_HIGHBORN(ch)) && !IS_AFFECTED(vch, AFF_INVISIBLE) && !IS_AFFECTED(vch, AFF_HIDE) && !IS_AFFECTED2(vch, AFF_CAMOUFLAGE)) break; } if (!fJustice && vch == NULL){ /* run through cabals check if justice parent cabal has any players in it */ CABAL_DATA* pCab; for (pCab = cabal_list; pCab; pCab = pCab->next){ if (!IS_CABAL(pCab, CABAL_JUSTICE) || pCab->parent) continue; if (pCab->present < 1) continue; else break; } /* the crime was not spotted, we affect the relation ships adversly */ if (area->pCabal && pCab) affect_justice_relations( area->pCabal, -5 ); return NULL; } /* we run through all the pafs on the character looking wanted with given city */ for (paf = ch->affected; paf; paf = paf->next){ if (paf->type == gsn_wanted && paf->location == city) break; } /* now we either have a paf or not */ if (paf == NULL){ AFFECT_DATA af; af.type = gsn_wanted; af.duration = dur; af.level = 60; af.where = TO_NONE; af.bitvector= 0; af.location = city; //new crime, will be put into bitvector when wanted. if (victim && victim->pCabal && IS_CABAL(victim->pCabal, CABAL_JUSTICE)) af.modifier = crime_table[CRIME_OBSTRUCT].bit; else af.modifier = crime_table[crime].bit; paf = affect_to_char( ch, &af); } else{ /* we update an existing crime info for a city */ paf->modifier |= crime_table[crime].bit; //add this crime to the ones waiting to be put in bitvector when wanted paf->duration = dur; } affect_strip(ch, gsn_timer ); return paf; } /* shows the crimes victim has been flagged for, and returns the maximum penalty */ int show_crimes( CHAR_DATA* ch, CHAR_DATA* victim, bool fPunish, bool fPenOnly ){ char buf[MSL]; char buf2[MIL]; AFFECT_DATA* paf; AREA_DATA* pArea; int max_pen = CRIME_ALLOW; buf[0] = '\0'; for (paf = victim->affected; paf; paf = paf->next){ if ( paf->type == gsn_wanted && paf->bitvector != 0 && (pArea = get_area_data( paf->location )) != NULL){ bool fFirst = TRUE; int i = 0; /* we run through all crimes making a list */ for (i = 0; i < MAX_CRIME; i++){ if (!IS_SET(paf->bitvector, crime_table[i].bit)) continue; if (fFirst){ sprintf(buf2, "%-15s (%2dd): %-10s %s%s%s\n\r", pArea->name, paf->duration / 24, crime_table[i].name, fPunish ? "(" : "", fPunish ? punish_table[pArea->crimes[i]].name : "", fPunish ? ")" : ""); fFirst = FALSE; } else{ sprintf(buf2, "%-20s : %-10s %s%s%s\n\r", "", crime_table[i].name, fPunish ? "(" : "", fPunish ? punish_table[pArea->crimes[i]].name : "", fPunish ? ")" : ""); } strcat( buf, buf2 ); /* select the highest penalty */ if (punish_table[pArea->crimes[i]].bit > max_pen) max_pen = punish_table[pArea->crimes[i]].bit; } } } if (IS_NULLSTR(buf) || fPenOnly) return max_pen; else if ( ch == victim ) send_to_char("You are wanted for following crimes:\n\r", ch); else sendf( ch, "%s is wanted for following crimes:\n\r", PERS2( victim )); send_to_char( buf, ch ); return max_pen; } /* returns an integer representing a crime or -1 */ int crime_lookup (const char *name ){ int crime; for (crime = 0; crime_table[crime].name != NULL; crime++){ if (LOWER(name[0]) == LOWER(crime_table[crime].name[0]) && !str_prefix(name, crime_table[crime].name)) return crime; } return -1; }