/* ************************************************************************
* file: spec_generic.c , Special module. Part of DIKUMUD *
* Usage: Procedures handling special procedures for object/room/mobile *
* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
************************************************************************* */
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "limits.h"
/* external vars */
extern struct room_data *world;
extern int top_of_world;
extern struct zone_data *zone_table;
extern struct char_data *character_list;
extern struct descriptor_data *descriptor_list;
extern struct index_data *obj_index;
extern struct time_info_data time_info;
extern struct title_type titles[4][28];
/* extern procedures */
void hit(struct char_data *ch, struct char_data *victim, int type);
void gain_exp(struct char_data *ch, int gain);
char *strdup(char *source);
struct char_data *get_char_room_vis(struct char_data *ch,char *name);
void do_say(struct char_data *ch, char *argument, int cmd);
void do_tell(struct char_data *ch, char *argument, int cmd);
/* Data declarations */
struct social_type {
char *cmd;
int next_line;
};
#define LAW_ENFORCER(x) (((x)->nr==real_mobile(3081) || \
(x)->nr==real_mobile(3082) || (x)->nr==real_mobile(12581) \
|| (x)->nr==real_mobile(12582)))
/* ********************************************************************
* Special procedures for rooms *
******************************************************************** */
char *how_good(int percent)
{
static char buf[256];
if (percent == 0)
strcpy(buf, " (not learned)");
else if (percent <= 10)
strcpy(buf, " (awful)");
else if (percent <= 20)
strcpy(buf, " (bad)");
else if (percent <= 40)
strcpy(buf, " (poor)");
else if (percent <= 55)
strcpy(buf, " (average)");
else if (percent <= 70)
strcpy(buf, " (fair)");
else if (percent <= 80)
strcpy(buf, " (good)");
else if (percent <= 85)
strcpy(buf, " (very good)");
else
strcpy(buf, " (Superb)");
return (buf);
}
/* NOT a room proc, folks... */
int guild(struct char_data *ch, struct char_data *pl, int cmd, char *arg) {
char arg1[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
int number, i, percent;
extern char *spells[];
extern struct spell_info_type spell_info[MAX_SPL_LIST];
extern struct int_app_type int_app[26];
static char *w_skills[] = {
"kick", /* No. 50 */
"bash",
"rescue",
"\n"
};
static char *t_skills[] = {
"sneak", /* No. 45 */
"hide",
"steal",
"backstab",
"pick",
"\n"
};
if ((cmd != 164) && (cmd != 170)) return(FALSE);
for(; *arg==' '; arg++);
/* Keep people from practicing at the wrong guild -Sman */
if(ISNPC(ch) && GET_CLASS(pl) != GET_NPCCLASS(ch) &&
(!(pl->specials.act&PLR_ISMULTIWA) || !(ch->specials.act&ACT_HAS_WA)) &&
(!(pl->specials.act&PLR_ISMULTIMU) || !(ch->specials.act&ACT_HAS_MU)) &&
(!(pl->specials.act&PLR_ISMULTITH) || !(ch->specials.act&ACT_HAS_TH)) &&
(!(pl->specials.act&PLR_ISMULTICL) || !(ch->specials.act&ACT_HAS_CL)) &&
*arg && ch!=pl) {
if(CAN_SEE(ch,pl)) {
sprintf(buf,"%s Hey! This isn't your guild!",GET_NAME(pl));
do_tell(ch,buf,0);
} else
do_say(ch,"Whoever you are, this isn't your guild!",0);
return(TRUE);
}
/* This is setup to go off of the ACT_HAS_xx bits of the guildmaster */
/* -- be sure the guildmaster has only one set, for general sanity */
switch (IS_NPC(ch) ? GET_NPCCLASS(ch) : GET_CLASS(ch)) {
case CLASS_MAGIC_USER :{
if (!*arg) {
sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn);
send_to_char(buf, pl);
send_to_char("You can practise any of these spells:\n\r", pl);
for(i=0; *spells[i] != '\n'; i++) {
if (spell_info[i+1].spell_pointer &&
(spell_info[i+1].min_level_magic <= GET_LEVEL(pl))) {
send_to_char(spells[i], pl);
send_to_char(how_good(pl->skills[i+1].learned), pl);
send_to_char("\n\r", pl);
}
}
return(TRUE);
}
number = old_search_block(arg,0,strlen(arg),spells,FALSE);
if(number == -1) {
send_to_char("You do not know of this spell...\n\r", pl);
return(TRUE);
}
if (GET_LEVEL(pl) < spell_info[number].min_level_magic) {
send_to_char("You do not know of this spell...\n\r", pl);
return(TRUE);
}
if (pl->specials.spells_to_learn <= 0) {
send_to_char("You do not seem to be able to practice now.\n\r", pl);
return(TRUE);
}
if (pl->skills[number].learned >= 95) {
send_to_char("You are already learned in this area.\n\r", pl);
return(TRUE);
}
send_to_char("You Practice for a while...\n\r", pl);
pl->specials.spells_to_learn--;
percent = pl->skills[number].learned+MAX(25,int_app[GET_INT(pl)].learn);
pl->skills[number].learned = MIN(95, percent);
if (pl->skills[number].learned >= 95) {
send_to_char("You are now learned in this area.\n\r", pl);
return(TRUE);
}
} break;
case CLASS_THIEF: {
if (!*arg) {
sprintf(buf,"You have got %d practice sessions left.\n\r", pl->specials.spells_to_learn);
send_to_char(buf, pl);
send_to_char("You can practise any of these skills:\n\r", pl);
for(i=0; *t_skills[i] != '\n';i++) {
send_to_char(t_skills[i], pl);
send_to_char(how_good(pl->skills[i+45].learned), pl);
send_to_char("\n\r", pl);
}
return(TRUE);
}
number = search_block(arg,t_skills,FALSE);
if(number == -1) {
send_to_char("You do not know of this spell...\n\r", pl);
return(TRUE);
}
if (pl->specials.spells_to_learn <= 0) {
send_to_char("You do not seem to be able to practice now.\n\r", pl);
return(TRUE);
}
if (pl->skills[number+SKILL_SNEAK].learned >= 85) {
send_to_char("You are already learned in this area.\n\r", pl);
return(TRUE);
}
send_to_char("You Practice for a while...\n\r", pl);
pl->specials.spells_to_learn--;
percent = pl->skills[number+SKILL_SNEAK].learned +
MIN(int_app[GET_INT(pl)].learn, 12);
pl->skills[number+SKILL_SNEAK].learned = MIN(85, percent);
if (pl->skills[number+SKILL_SNEAK].learned >= 85) {
send_to_char("You are now learned in this area.\n\r", pl);
return(TRUE);
}
} break;
case CLASS_CLERIC :{
if (!*arg) {
sprintf(buf,"You have got %d practice sessions left.\n\r", pl->specials.spells_to_learn);
send_to_char(buf, pl);
send_to_char("You can practise any of these spells:\n\r", pl);
for(i=0; *spells[i] != '\n'; i++)
if (spell_info[i+1].spell_pointer &&
(spell_info[i+1].min_level_cleric <= GET_LEVEL(pl))) {
send_to_char(spells[i], pl);
send_to_char(how_good(pl->skills[i+1].learned), pl);
send_to_char("\n\r", pl);
}
return(TRUE);
}
number = old_search_block(arg,0,strlen(arg),spells,FALSE);
if(number == -1) {
send_to_char("You do not know of this spell...\n\r", pl);
return(TRUE);
}
if (GET_LEVEL(pl) < spell_info[number].min_level_cleric) {
send_to_char("You do not know of this spell...\n\r", pl);
return(TRUE);
}
if (pl->specials.spells_to_learn <= 0) {
send_to_char("You do not seem to be able to practice now.\n\r", pl);
return(TRUE);
}
if (pl->skills[number].learned >= 95) {
send_to_char("You are already learned in this area.\n\r", pl);
return(TRUE);
}
send_to_char("You Practice for a while...\n\r", pl);
pl->specials.spells_to_learn--;
percent = pl->skills[number].learned+MAX(25,int_app[GET_INT(pl)].learn);
pl->skills[number].learned = MIN(95, percent);
if (pl->skills[number].learned >= 95) {
send_to_char("You are now learned in this area.\n\r", pl);
return(TRUE);
}
} break;
case CLASS_WARRIOR: {
if (!*arg) {
sprintf(buf,"You have got %d practice sessions left.\n\r", pl->specials.spells_to_learn);
send_to_char(buf, pl);
send_to_char("You can practise any of these skills:\n\r", pl);
for(i=0; *w_skills[i] != '\n';i++) {
send_to_char(w_skills[i], pl);
send_to_char(how_good(pl->skills[i+SKILL_KICK].learned), pl);
send_to_char("\n\r", pl);
}
return(TRUE);
}
number = search_block(arg, w_skills, FALSE);
if(number == -1) {
send_to_char("You do not have ability to practise this skill!\n\r", pl);
return(TRUE);
}
if (pl->specials.spells_to_learn <= 0) {
send_to_char("You do not seem to be able to practice now.\n\r", pl);
return(TRUE);
}
if (pl->skills[number+SKILL_KICK].learned >= 80) {
send_to_char("You are already learned in this area.\n\r", pl);
return(TRUE);
}
send_to_char("You Practice for a while...\n\r", pl);
pl->specials.spells_to_learn--;
percent = pl->skills[number+SKILL_KICK].learned +
MIN(12, int_app[GET_INT(pl)].learn);
pl->skills[number+SKILL_KICK].learned = MIN(80, percent);
if (pl->skills[number+SKILL_KICK].learned >= 80) {
send_to_char("You are now learned in this area.\n\r", pl);
return(TRUE);
}
} break;
}
}
/* A room proc */
int dump(int room, struct char_data *ch, int cmd, char *arg)
{
struct obj_data *k;
char buf[MAX_INPUT_LENGTH];
struct char_data *tmp_char;
int value=0;
void do_drop(struct char_data *ch, char *argument, int cmd);
char *fname(char *namelist);
if(!ch)
return(FALSE);
for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
{
sprintf(buf, "The %s vanish in a puff of smoke.\n\r" ,fname(k->name));
for(tmp_char = world[ch->in_room].people; tmp_char;
tmp_char = tmp_char->next_in_room)
if (CAN_SEE_OBJ(tmp_char, k))
send_to_char(buf,tmp_char);
extract_obj(k);
}
if(cmd!=60) return(FALSE);
do_drop(ch, arg, cmd);
value = 0;
for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
{
sprintf(buf, "The %s vanishes in a puff of smoke.\n\r",fname(k->name));
for(tmp_char = world[ch->in_room].people; tmp_char;
tmp_char = tmp_char->next_in_room)
if (CAN_SEE_OBJ(tmp_char, k))
send_to_char(buf,tmp_char);
value += MAX(1, MIN(50, k->obj_flags.cost/10));
extract_obj(k);
}
if (value)
{
act("You are awarded for outstanding performance.", FALSE, ch, 0, 0, TO_CHAR);
act("$n has been awarded for being a good citizen.", TRUE, ch, 0,0, TO_ROOM);
if (GET_LEVEL(ch) < 3)
gain_exp(ch, value);
else
GET_GOLD(ch) += value;
}
}
int mayor(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
static char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
static char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
/*
const struct social_type open_path[] = {
{"G",0}
};
static void *thingy = 0;
static int cur_line = 0;
for (i=0; i < 1; i++)
{
if (*(open_path[cur_line].cmd) == '!') {
i++;
exec_social(ch, (open_path[cur_line].cmd)+1,
open_path[cur_line].next_line, &cur_line, &thingy);
} else {
exec_social(ch, open_path[cur_line].cmd,
open_path[cur_line].next_line, &cur_line, &thingy);
}
*/
static char *path;
static int index;
static bool move = FALSE;
void do_move(struct char_data *ch, char *argument, int cmd);
void do_open(struct char_data *ch, char *argument, int cmd);
void do_lock(struct char_data *ch, char *argument, int cmd);
void do_unlock(struct char_data *ch, char *argument, int cmd);
void do_close(struct char_data *ch, char *argument, int cmd);
if (!move) {
if (time_info.hours == 6) {
move = TRUE;
path = open_path;
index = 0;
} else if (time_info.hours == 20) {
move = TRUE;
path = close_path;
index = 0;
}
}
if (cmd || !move || (GET_POS(ch) < POSITION_SLEEPING) ||
(GET_POS(ch) == POSITION_FIGHTING))
return FALSE;
switch (path[index]) {
case '0' :
case '1' :
case '2' :
case '3' :
do_move(ch,"",path[index]-'0'+1);
break;
case 'W' :
GET_POS(ch) = POSITION_STANDING;
act("$n awakens and groans loudly.",FALSE,ch,0,0,TO_ROOM);
break;
case 'S' :
GET_POS(ch) = POSITION_SLEEPING;
act("$n lies down and instantly falls asleep.",FALSE,ch,0,0,TO_ROOM);
break;
case 'a' :
act("$n says 'Hello Honey!'",FALSE,ch,0,0,TO_ROOM);
act("$n smirks.",FALSE,ch,0,0,TO_ROOM);
break;
case 'b' :
act("$n says 'What a view! I must get something done about that dump!'",
FALSE,ch,0,0,TO_ROOM);
break;
case 'c' :
act("$n says 'Vandals! Youngsters nowadays have no respect for anything!'",
FALSE,ch,0,0,TO_ROOM);
break;
case 'd' :
act("$n says 'Good day, citizens!'", FALSE, ch, 0,0,TO_ROOM);
break;
case 'e' :
act("$n says 'I hereby declare the bazaar open!'",FALSE,ch,0,0,TO_ROOM);
break;
case 'E' :
act("$n says 'I hereby declare Midgaard closed!'",FALSE,ch,0,0,TO_ROOM);
break;
case 'O' :
do_unlock(ch, "gate", 0);
do_open(ch, "gate", 0);
break;
case 'C' :
do_close(ch, "gate", 0);
do_lock(ch, "gate", 0);
break;
case '.' :
move = FALSE;
break;
}
index++;
return FALSE;
}
/* ********************************************************************
* General special procedures for mobiles *
******************************************************************** */
/* SOCIAL GENERAL PROCEDURES
If first letter of the command is '!' this will mean that the following
command will be executed immediately.
"G",n : Sets next line to n
"g",n : Sets next line relative to n, fx. line+=n
"m<dir>",n : move to <dir>, <dir> is 0,1,2,3,4 or 5
"w",n : Wake up and set standing (if possible)
"c<txt>",n : Look for a person named <txt> in the room
"o<txt>",n : Look for an object named <txt> in the room
"r<int>",n : Test if the npc in room number <int>?
"s",n : Go to sleep, return false if can't go sleep
"e<txt>",n : echo <txt> to the room, can use $o/$p/$N depending on
contents of the **thing
"E<txt>",n : Send <txt> to person pointed to by thing
"B<txt>",n : Send <txt> to room, except to thing
"?<num>",n : <num> in [1..99]. A random chance of <num>% success rate.
Will as usual advance one line upon sucess, and change
relative n lines upon failure.
"O<txt>",n : Open <txt> if in sight.
"C<txt>",n : Close <txt> if in sight.
"L<txt>",n : Lock <txt> if in sight.
"U<txt>",n : Unlock <txt> if in sight. */
/* Execute a social command. */
void exec_social(struct char_data *npc, char *cmd, int next_line,
int *cur_line, void **thing)
{
bool ok;
void do_move(struct char_data *ch, char *argument, int cmd);
void do_open(struct char_data *ch, char *argument, int cmd);
void do_lock(struct char_data *ch, char *argument, int cmd);
void do_unlock(struct char_data *ch, char *argument, int cmd);
void do_close(struct char_data *ch, char *argument, int cmd);
if (GET_POS(npc) == POSITION_FIGHTING)
return;
ok = TRUE;
switch (*cmd) {
case 'G' :
*cur_line = next_line;
return;
case 'g' :
*cur_line += next_line;
return;
case 'e' :
act(cmd+1, FALSE, npc, *thing, *thing, TO_ROOM);
break;
case 'E' :
act(cmd+1, FALSE, npc, 0, *thing, TO_VICT);
break;
case 'B' :
act(cmd+1, FALSE, npc, 0, *thing, TO_NOTVICT);
break;
case 'm' :
do_move(npc, "", *(cmd+1)-'0'+1);
break;
case 'w' :
if (GET_POS(npc) != POSITION_SLEEPING)
ok = FALSE;
else
GET_POS(npc) = POSITION_STANDING;
break;
case 's' :
if (GET_POS(npc) <= POSITION_SLEEPING)
ok = FALSE;
else
GET_POS(npc) = POSITION_SLEEPING;
break;
case 'c' : /* Find char in room */
*thing = get_char_room_vis(npc, cmd+1);
ok = (*thing != 0);
break;
case 'o' : /* Find object in room */
*thing = get_obj_in_list_vis(npc, cmd+1, world[npc->in_room].contents);
ok = (*thing != 0);
break;
case 'r' : /* Test if in a certain room */
ok = (npc->in_room == atoi(cmd+1));
break;
case 'O' : /* Open something */
do_open(npc, cmd+1, 0);
break;
case 'C' : /* Close something */
do_close(npc, cmd+1, 0);
break;
case 'L' : /* Lock something */
do_lock(npc, cmd+1, 0);
break;
case 'U' : /* UnLock something */
do_unlock(npc, cmd+1, 0);
break;
case '?' : /* Test a random number */
if (atoi(cmd+1) <= number(1,100))
ok = FALSE;
break;
default:
break;
} /* End Switch */
if (ok)
(*cur_line)++;
else
(*cur_line) += next_line;
}
void npc_steal(struct char_data *ch,struct char_data *victim)
{
int gold;
if(IS_NPC(victim)) return;
if(IS_TRUSTED(victim)) return;
if(world[ch->in_room].room_flags & SAFE) return;
if (AWAKE(victim) && (number(0,GET_LEVEL(ch)) == 0)) {
act("You discover that $n has $s hands in your wallet.",FALSE,ch,0,victim,TO_VICT);
act("$n tries to steal gold from $N.",TRUE, ch, 0, victim, TO_NOTVICT);
} else {
/* Steal some gold coins */
gold = (int) ((GET_GOLD(victim)*number(1,10))/100);
if (gold > 0) {
GET_GOLD(ch) += gold;
GET_GOLD(victim) -= gold;
}
}
}
int poison(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
void cast_poison( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(ch->specials.fighting &&
(ch->specials.fighting->in_room == ch->in_room) &&
(number(0,32-GET_LEVEL(ch))==0))
{
act("$n bites $N!", 1, ch, 0, ch->specials.fighting, TO_NOTVICT);
act("$n bites you!", 1, ch, 0, ch->specials.fighting, TO_VICT);
cast_poison( GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL,
ch->specials.fighting, 0);
return TRUE;
}
return FALSE;
}
int thief(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
struct char_data *cons;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_STANDING)return FALSE;
for(cons = world[ch->in_room].people; cons; cons = cons->next_in_room )
if(!IS_NPC(cons) && !IS_TRUSTED(cons) && (number(1,5)==1))
npc_steal(ch,cons);
return TRUE;
}
int magic_user(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
struct char_data *vict;
void cast_burning_hands( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_chill_touch( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_energy_drain( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_fireball( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_magic_missile( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_blindness( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_curse( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_sleep( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to to evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch)
break;
if (!vict)
return FALSE;
if( (vict!=ch->specials.fighting) && (GET_LEVEL(ch)>13) && (number(0,7)==0) )
{
act("$n utters the words 'dilan oso'.", 1, ch, 0, 0, TO_ROOM);
cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,6)==0) )
{
act("$n utters the words 'gharia miwi'.", 1, ch, 0, 0, TO_ROOM);
cast_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>7) && (number(0,5)==0) )
{
act("$n utters the words 'koholian dia'.", 1, ch, 0, 0, TO_ROOM);
cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,8)==0) && IS_EVIL(ch))
{
act("$n utters the words 'ib er dranker'.", 1, ch, 0, 0, TO_ROOM);
cast_energy_drain(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
switch (GET_LEVEL(ch)) {
case 1:
case 2:
case 3:
case 4:
act("$n utters the words 'hahili duvini'.", 1, ch, 0, 0, TO_ROOM);
cast_magic_missile(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 5:
case 6:
case 7:
case 8:
act("$n utters the words 'grynt oef'.", 1, ch, 0, 0, TO_ROOM);
cast_burning_hands(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 9:
case 10:
act("$n utters the words 'sjulk divi'.", 1, ch, 0, 0, TO_ROOM);
cast_lightning_bolt(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 11:
case 12:
case 13:
case 14:
act("$n utters the words 'nasson hof'.", 1, ch, 0, 0, TO_ROOM);
cast_colour_spray(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
default:
act("$n utters the words 'tuborg'.", 1, ch, 0, 0, TO_ROOM);
cast_fireball(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
}
return TRUE;
}
/* ********************************************************************
* Special procedures for mobiles *
******************************************************************** */
int guild_guard(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
char buf[256], buf2[256];
if (cmd>6 || cmd<1)
return(witness(ch,pl,cmd,arg));
if (IS_TRUSTED(ch)){
return FALSE;
}
strcpy(buf, "The guard humiliates you, and block your way.\n\r");
strcpy(buf2, "The guard humiliates $n, and blocks $s way.");
if ((ch->in_room == real_room(3017)) && (cmd == 3)) {
if ((GET_CLASS(pl) != CLASS_MAGIC_USER)&&
(!IS_SET(pl->specials.act,PLR_ISMULTIMU))) {
act(buf2, FALSE, pl, 0, 0, TO_ROOM);
send_to_char(buf, pl);
return TRUE;
}
} else if ((ch->in_room == real_room(3004)) && (cmd == 1)) {
if ((GET_CLASS(pl) != CLASS_CLERIC)&&
(!IS_SET(pl->specials.act,PLR_ISMULTICL))) {
act(buf2, FALSE, pl, 0, 0, TO_ROOM);
send_to_char(buf, pl);
return TRUE;
}
} else if ((ch->in_room == real_room(3027)) && (cmd == 2)) {
if ((GET_CLASS(pl) != CLASS_THIEF)&&
(!IS_SET(pl->specials.act,PLR_ISMULTITH))) {
act(buf2, FALSE, pl, 0, 0, TO_ROOM);
send_to_char(buf, pl);
return TRUE;
}
} else if ((ch->in_room == real_room(3021)) && (cmd == 2)) {
if ((GET_CLASS(pl) != CLASS_WARRIOR)&&
(!IS_SET(pl->specials.act,PLR_ISMULTIWA))) {
act(buf2, FALSE, pl, 0, 0, TO_ROOM);
send_to_char(buf, pl);
return TRUE;
}
}
return FALSE;
}
int remove_team(int room,struct char_data *ch, int cmd, char *arg)
{
char buf[256], buf2[256];
if (cmd!=4)
return FALSE;
strcpy(buf, "The Arena Gods bid you farewell.\n\r");
strcpy(buf2, "The Arena Gods bid $n farewell.\n\r");
if ((ch->in_room == real_room(3751)) && (cmd == 4)) {/*EXIT room*/
act(buf2, FALSE, ch, 0, 0, TO_ROOM);
send_to_char(buf, ch);
if(ch->specials.arena > ARENA_NOTPLAYING){
ch->specials.arena=ARENA_NOTPLAYING;
GET_MOVE(ch)=ch->specials.arena_move;
GET_MANA(ch)=ch->specials.arena_mana;
GET_HIT(ch)=ch->specials.arena_hits;
while(ch->affected)
affect_remove(ch,ch->affected);
ch->affected=ch->tmp_affected;
ch->tmp_affected=NULL;
ch->specials.affected_by=ch->specials.arena_affvector;
}
}
return FALSE;
}
int devour(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
struct obj_data *i, *temp, *next_obj;
if (cmd || !AWAKE(ch))
return(FALSE);
for (i = world[ch->in_room].contents; i; i = i->next_content) {
if ((GET_ITEM_TYPE(i)==ITEM_CONTAINER && i->obj_flags.value[3])
|| GET_ITEM_TYPE(i)==ITEM_FOOD) {
act("$n savagely devours $o.", FALSE,ch,i,0,TO_ROOM);
if(GET_ITEM_TYPE(i)==ITEM_CONTAINER)
for(temp = i->contains; temp; temp=next_obj) {
next_obj = temp->next_content;
obj_from_obj(temp);
obj_to_room(temp,ch->in_room);
}
extract_obj(i);
return(TRUE);
}
}
return(FALSE);
}
int pet_shops(int room, struct char_data *ch, int cmd, char *arg)
{
char buf[MAX_STRING_LENGTH], pet_name[256];
int pet_room;
struct char_data *pet;
struct char_data *tmp_ch;
struct follow_type *fol;
int count;
if(!ch)
return(FALSE);
pet_room = ch->in_room+1;
if (cmd==59) { /* List */
send_to_char("Available pets are:\n\r", ch);
for(pet = world[pet_room].people; pet; pet = pet->next_in_room) {
sprintf(buf, "%8d - %s\n\r", 3*GET_EXP(pet), pet->player.short_descr);
send_to_char(buf, ch);
}
return(TRUE);
} else if (cmd==56) { /* Buy */
arg = one_argument(arg, buf);
arg = one_argument(arg, pet_name);
/* Pet_Name is for later use when I feel like it */
if (!(pet = get_char_room(buf, pet_room))) {
send_to_char("There is no such pet!\n\r", ch);
return(TRUE);
}
for(count=0, fol=ch->followers; fol; fol=fol->next){
if(IS_NPC(fol->follower) &&
IS_AFFECTED(fol->follower, AFF_CHARM)){
count++;
}
}
if(count>=2){
send_to_char("You may only have 2 pets\n\r",ch);
return(TRUE);
}
if (GET_GOLD(ch) < (GET_EXP(pet)*3)) {
send_to_char("You don't have enough gold!\n\r", ch);
return(TRUE);
}
GET_GOLD(ch) -= GET_EXP(pet)*3;
pet = read_mobile(pet->nr, REAL);
GET_EXP(pet) = 0;
SET_BIT(pet->specials.affected_by, AFF_CHARM);
if (*pet_name) {
sprintf(buf,"%s %s", pet->player.name, pet_name);
free(pet->player.name);
pet->player.name = strdup(buf);
sprintf(buf,"%sA small sign on a chain around the neck says 'My Name is %s'\n\r",
pet->player.description, pet_name);
free(pet->player.description);
pet->player.description = strdup(buf);
}
char_to_room(pet, ch->in_room,0);
add_follower(pet, ch);
/* Be certain that pet's can't get/carry/use/weild/wear items */
IS_CARRYING_W(pet) = 1000;
IS_CARRYING_N(pet) = 100;
send_to_char("May you enjoy your pet.\n\r", ch);
act("$n bought $N as a pet.",FALSE,ch,0,pet,TO_ROOM);
return(TRUE);
}
/* All commands except list and buy */
return(FALSE);
}
void new_class(struct char_data *ch, int newclass)
{
char oldclass[80];
char sendbuf[80];
char buf[80];
switch(GET_CLASS(ch)){
case CLASS_THIEF:
SET_BIT(ch->specials.act,PLR_ISMULTITH);
strcpy(oldclass,"Thief"); break;
case CLASS_MAGIC_USER:
SET_BIT(ch->specials.act,PLR_ISMULTIMU);
strcpy(oldclass,"Magic User"); break;
case CLASS_CLERIC:
SET_BIT(ch->specials.act,PLR_ISMULTICL);
strcpy(oldclass,"Cleric"); break;
case CLASS_WARRIOR:
SET_BIT(ch->specials.act,PLR_ISMULTIWA);
strcpy(oldclass,"Warrior"); break;
default:
send_to_char("Invalid class!\n\r",ch);
return;
}
GET_CLASS(ch)=newclass;
switch(GET_CLASS(ch)){
case CLASS_WARRIOR:
sprintf(buf,"Warrior/%s",oldclass);break;
case CLASS_THIEF:
sprintf(buf,"Thief/%s",oldclass);break;
case CLASS_CLERIC:
sprintf(buf,"Cleric/%s",oldclass);break;
case CLASS_MAGIC_USER:
sprintf(buf,"Magic User/%s",oldclass);break;
default:
send_to_char("Serious error in new class!\n\r",ch);
return;
}
sprintf(sendbuf,"You are now a %s!\n\r",buf);
send_to_char(sendbuf,ch);
}
#define MULTI_MIN_LEV 5 /* minimum level to change class*/
#define MULTI_COST_PER_LEV 100000 /* 100k per level to change */
int do_multiclass(int room, struct char_data *ch, int cmd, char *arg)
{
char buf[300];
long cost;
if (cmd!=233){
return(FALSE);
}
if (IS_NPC(ch)) {
send_to_char("Monsters have no class, go away!\n\r",ch);
return(TRUE);
}
arg = one_argument(arg, buf);
if(strcmp(buf,"cleric")&&strcmp(buf,"mu")&&
strcmp(buf,"thief")&&strcmp(buf,"warrior")) {
send_to_char("You can only switch to a THIEF, CLERIC, MU, or WARRIOR.\n\r",ch);
return(TRUE);
}
if(IS_SET(ch->specials.act,PLR_ISMULTITH)||
IS_SET(ch->specials.act,PLR_ISMULTIWA)||
IS_SET(ch->specials.act,PLR_ISMULTIMU)||
IS_SET(ch->specials.act,PLR_ISMULTICL)){
send_to_char("You can't switch more than once (yet).\n\r",ch);
return(TRUE);
}
if (GET_LEVEL(ch)<MULTI_MIN_LEV){
send_to_char("You need more levels first!\n\r",ch);
return(TRUE);
}
if (GET_LEVEL(ch)>LV_IMMORTAL || IS_TRUSTED(ch)){
send_to_char("Gods may not multiclass!\n\r",ch);
return(TRUE);
}
cost=GET_LEVEL(ch)*MULTI_COST_PER_LEV;
if(GET_GOLD(ch)<cost){
sprintf(buf,"You need %d coins to change class at your level.\n\r",cost);
send_to_char(buf,ch);
return(TRUE);
}
if(GET_EXP(ch)<titles[GET_CLASS(ch)-1][GET_LEVEL(ch)].exp){
sprintf(buf,"You need %d experience points to multiclass at your level.\n\r",titles[GET_CLASS(ch)-1][GET_LEVEL(ch)].exp);
send_to_char(buf,ch);
return(TRUE);
}
if(!strcmp(buf,"cleric")&&(GET_CLASS(ch)!=CLASS_CLERIC)){
new_class(ch,CLASS_CLERIC);
} else if (!strcmp(buf,"mu")&&(GET_CLASS(ch)!=CLASS_MAGIC_USER)){
new_class(ch,CLASS_MAGIC_USER);
} else if (!strcmp(buf,"thief")&&(GET_CLASS(ch)!=CLASS_THIEF)){
new_class(ch,CLASS_THIEF);
} else if (!strcmp(buf,"warrior")&&(GET_CLASS(ch)!=CLASS_WARRIOR)){
new_class(ch,CLASS_WARRIOR);
} else {
send_to_char("You are already that class!\n\r",ch);
return(TRUE);
}
GET_GOLD(ch) -= cost;
sprintf(buf,"It costs you %d coins to switch class.\n\r",cost);
send_to_char(buf,ch);
/* Change class. Set player's level at 1. Zero experience. Give
necessary stats to new class.*/
GET_LEVEL(ch) = 1;
GET_EXP(ch) = 1;
ch->specials.spells_to_learn = 0;
set_title(ch);
switch (GET_CLASS(ch)) {
case CLASS_THIEF : {
ch->skills[SKILL_SNEAK].learned = 10;
ch->skills[SKILL_HIDE].learned = 5;
ch->skills[SKILL_STEAL].learned = 15;
ch->skills[SKILL_BACKSTAB].learned = 10;
ch->skills[SKILL_PICK_LOCK].learned = 10;
} break;
}
send_to_char("You feel awesome power surge coarse through your veins.\n\r",ch);
send_to_char("You feel like a new person!\n\r",ch);
}
int offensive(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
struct char_data *vict;
void cast_burning_hands( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_chill_touch( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_energy_drain( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_fireball( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_magic_missile( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_blindness( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_curse( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_sleep( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
if(cmd) return FALSE;
if(!AWAKE(ch)) return FALSE;
/* Find a pc-killer or a thief to do battle with */
if(GET_POS(ch)!=POSITION_FIGHTING || !ch->specials.fighting) {
for(vict=world[ch->in_room].people; vict; vict=vict->next_in_room){
if(!IS_NPC(vict) && CAN_SEE(ch, vict) &&
(IS_SET(vict->specials.act, PLR_ISKILLER) ||
IS_SET(vict->specials.act, PLR_ISTHIEF))){
act("$n screams 'Outlaw! Fresh blood! Kill!'", FALSE, ch, 0, 0, TO_ROOM);
hit(ch, vict, TYPE_UNDEFINED);
return(TRUE);
}
}
return (FALSE);
}
/* We're fighting someone, so
* Find a dude to to evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch)
break;
if (!vict)
return FALSE;
if( (vict!=ch->specials.fighting) && (GET_LEVEL(ch)>13) && (number(0,4)==0) )
{
act("$n utters the words 'dilan oso'.", 1, ch, 0, 0, TO_ROOM);
cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,4)==0) )
{
act("$n utters the words 'gharia miwi'.", 1, ch, 0, 0, TO_ROOM);
cast_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>7) && (number(0,3)==0) )
{
act("$n utters the words 'kholian dia'.", 1, ch, 0, 0, TO_ROOM);
cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,5)==0) && IS_EVIL(ch))
{
act("$n utters the words 'ib er dranker'.", 1, ch, 0, 0, TO_ROOM);
cast_energy_drain(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
switch (number(0,16)) {
case 0: break; /* do nothing */
case 1:
case 2:
case 3:
case 4:
act("$n utters the words 'hahili duvini'.", 1, ch, 0, 0, TO_ROOM);
cast_magic_missile(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 5:
case 6:
case 7:
case 8:
act("$n utters the words 'grynt oef'.", 1, ch, 0, 0, TO_ROOM);
cast_burning_hands(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 9:
case 10:
act("$n utters the words 'sjulk divi'.", 1, ch, 0, 0, TO_ROOM);
cast_lightning_bolt(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 11:
case 12:
case 13:
case 14:
act("$n utters the words 'nasson hof'.", 1, ch, 0, 0, TO_ROOM);
cast_colour_spray(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
default:
act("$n utters the words 'tuborg'.", 1, ch, 0, 0, TO_ROOM);
cast_fireball(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
}
return TRUE;
}
bool transact(struct char_data *from,struct obj_data *merchandise,
struct char_data *to,int value)
{
char buf[MAX_STRING_LENGTH];
if (to->points.gold >= value && from->in_room == to->in_room) {
to->points.gold -= value;
from->points.gold += value;
if(merchandise) {
obj_from_char(merchandise);
obj_to_char(merchandise,to);
sprintf(buf,"You buy %s for %d coins.\n\r\n\r",merchandise->short_description, value);
send_to_char(buf,to);
sprintf(buf,"%s gives you %d coins for %s.\n\r\n\r",to->player.name,value,
merchandise->short_description);
send_to_char(buf,from);
sprintf(buf,"%s sells %s to %s.\n\r\n\r",from->player.name,
merchandise->short_description, to->player.name);
send_to_room_except_two(buf,from->in_room,from,to);
return TRUE;
} else {
sprintf(buf,"You give %s %d coins.\n\r\n\r",GET_NAME(from),value);
send_to_char(buf,to);
act("$n gives $N some money.",TRUE,to,0,from,TO_NOTVICT);
act("$N pays your price.",FALSE,from,0,to,TO_CHAR);
return TRUE;
}
} else {
sprintf(buf,"%s doesn't have the funds for the exchange.\n\r\n\r",GET_NAME(to));
send_to_char(buf,from);
send_to_char(buf,to);
return FALSE;
}
}
int citizenship(struct char_data *ch, struct char_data *pl, int cmd, char *arg)
{
struct char_data *c_obj;
char arg1[MAX_STRING_LENGTH],arg2[MAX_STRING_LENGTH],buf[MAX_STRING_LENGTH];
bool reject_bad_item=FALSE;
if(pl) {
if(cmd==56) { /* Buy */
argument_interpreter(arg,arg1,arg2);
if (!*arg1)
return(FALSE);
if(*arg2) {
c_obj=get_char_room(arg1,ch->in_room);
if(c_obj!=ch)
return(FALSE);
reject_bad_item=TRUE;
}
if(!strcmp(arg1,"midgaard")) {
if(GET_HOME(pl)==1) {
if(CAN_SEE(ch,pl)) {
sprintf(buf,"%s Hey, that's already your hometown!",GET_NAME(pl));
do_tell(ch,buf,0);
} else
do_say(ch,"Hey someone, that's already your hometown!",0);
return(TRUE);
}
if(transact(ch,NULL,pl,20000)) {
GET_HOME(pl)=1;
send_to_char("Your hometown has been changed!\n\r\n\r",pl);
return(TRUE);
}
} else if(!strcmp(arg1,"anapest")) {
if(GET_HOME(pl)==2) {
if(CAN_SEE(ch,pl)) {
sprintf(buf,"%s Hey, that's already your hometown!",GET_NAME(pl));
do_tell(ch,buf,0);
} else
do_say(ch,"Hey someone, that's already your hometown!",0);
return(TRUE);
}
if(transact(ch,NULL,pl,20000)) {
GET_HOME(pl)=2;
send_to_char("Your hometown has been changed!\n\r\n\r",pl);
return(TRUE);
}
} else if(reject_bad_item) {
if(CAN_SEE(ch,pl)) {
sprintf(buf,"%s I don't know that place.",GET_NAME(pl));
do_tell(ch,buf,0);
} else
do_say(ch,"Where?",0);
return(TRUE);
}
}
}
return(FALSE);
}
/* Here are the routines governing the jail system */
/* some flags for the apprehender, in spec[2] */
#define APPR_PRISONERS 1
#define APPR_RHETORICAL 2
#define APPR_RETURN 4
int apprehender(struct char_data *ch,struct char_data *pl,int cmd,char *arg)
{
struct char_data *tch,*temp,*temp2;
char name[MAX_INPUT_LENGTH],message[MAX_INPUT_LENGTH],buf[MAX_STRING_LENGTH];
bool action_made=FALSE,pause=FALSE,found_one;
int to_room,temp_room;
if (!AWAKE(ch) || (GET_POS(ch) == POSITION_FIGHTING))
return (FALSE);
if(pl) {
if(pl->specials.arrest_by!=ch || GET_POS(pl)<POSITION_SLEEPING)
return(FALSE);
switch(cmd) {
case 19: /* tell-> make sure it is tell <chname> */
if(ch->specials.spec[2] & APPR_RHETORICAL) {
half_chop(arg,name,message);
if(ch!=get_char_room_vis(pl,name))
return(FALSE);
strcpy(arg,message);
if(strstr(arg,"yes"))
do_say(ch,"That was a rhetorical question, bub.",0);
else if(strstr("no",arg))
do_say(ch,"I hope that's the case.",0);
}
break;
case 17: /* say */
case 169: /* short (') version of say */
if(ch->specials.spec[2] & APPR_RHETORICAL) {
do_say(pl,arg,0);
if(strstr(arg,"yes"))
do_say(ch,"That was a rhetorical question.",0);
else if(strstr("no",arg))
do_say(ch,"I hope that's the case.",0);
}
break;
case 25: /* Kill */
case 70: /* Hit */
case 84: /* Cast */
case 152: /* Sneak */
case 153: /* Hide */
case 154: /* Backstab */
case 157: /* Bash */
case 159: /* Kick */
message[0]=0;
strcat(message,GET_NAME(pl));
strcat(message," None of that while you're in my custody!");
do_tell(ch,message,0);
return(TRUE);
break;
case 156: /* pl should have a chance of success */
break;
default:
break;
}
} else if(GET_POS(ch)==POSITION_FIGHTING) {
if(!number(0,4))
do_say(ch,"Resistance is stupid!",0);
} else {
ch->specials.spec[2]&=~APPR_RHETORICAL;
if(IS_SET(ch->specials.act,NPC_OUTLAW)) {
/* Release arrested people? */
switch(number(1,15)) {
case 1:
act("$n fidgets.",TRUE,ch,0,0,TO_ROOM);
break;
case 2:
do_say(ch,"Ack! I don't know what to do with myself.",0);
break;
case 3:
do_action(ch,"",53); /* cry */
break;
default:
break;
}
/* Get rid of the arrested people to avoid the */
/* possibility of strange loops and the like */
for(tch=ch->specials.arrest_link;tch;tch=ch->specials.arrest_link) {
tch->specials.arrest_by=NULL;
ch->specials.arrest_link=tch->specials.arrest_link;
tch->specials.arrest_link=NULL;
}
return(FALSE);
}
if(!ch->specials.fighting)
for(tch=world[ch->in_room].people; tch; tch=tch->next_in_room)
if (IS_HUMANOID(tch) && CAN_SEE(ch, tch) && tch !=ch &&
tch->specials.fighting) {
if(IS_HUMANOID(tch->specials.fighting) &&
!LAW_ENFORCER(tch) &&
!LAW_ENFORCER(tch->specials.fighting)) {
stop_fighting(tch);
action_made=TRUE;
} else if(LAW_ENFORCER(tch) && !action_made) {
do_action(ch,"",26);
hit(ch,tch->specials.fighting,TYPE_UNDEFINED);
break;
}
}
if(action_made) {
do_say(ch,"Break it up! Break it up!",0);
act("$n stops the fight.",TRUE,ch,0,0,TO_ROOM);
do_say(ch,"Now, do I have to take you people in?",0);
ch->specials.spec[2]|=APPR_RHETORICAL;
return(TRUE);
}
if(!(ch->specials.spec[2] & APPR_RETURN)) {
found_one=FALSE;
for(tch=world[ch->in_room].people; tch; tch=tch->next_in_room) {
if(IS_OUTLAW(tch) && !tch->specials.arrest_by && GET_POS(ch)>=POSITION_SLEEPING){
if(!AWAKE(tch)) {
do_wake(ch,GET_NAME(tch),0);
do_say(ch,"Wake up, Outlaw!",0);
} else if(GET_POS(tch)>POSITION_SLEEPING) {
if(!found_one) {
sprintf(buf,"You're coming with me, %s!",fname(GET_NAME(tch)));
do_say(ch,buf,0);
found_one=TRUE;
} else {
sprintf(buf,"You too, %s!",fname(GET_NAME(tch)));
do_say(ch,buf,0);
}
if(GET_POS(tch)<POSITION_STANDING) {
GET_POS(tch)=POSITION_STANDING;
act("$n forces $N on $S feet.",
TRUE,ch,0,tch,TO_NOTVICT);
act("$n forces you on your feet.",
FALSE,ch,0,tch,TO_VICT);
}
tch->specials.arrest_by=ch;
tch->specials.arrest_link=ch->specials.arrest_link;
ch->specials.arrest_link=tch;
ch->specials.spec[2]|=APPR_PRISONERS;
pause=TRUE;
}
}
}
}
if((ch->specials.spec[2] & APPR_PRISONERS) && !pause) {
/* Headed to jail */
/* Will need a routing method. Probably static */
/*if(route method fails...)*/
to_room=real_room(jail_hometown(ch->player.hometown));
if(to_room==-1) {
do_say(ch,"Eek! I can't find the jail!",0);
ch->specials.spec[2]=0;/*
for(k=ch->specials.arrest_link;k=*/
teleport_to(ch,NOWHERE);
return(FALSE);
}
do_say(ch,"Shoot! I'm a little lost.",0);
act("$n snaps $s fingers.",FALSE,ch,0,0,TO_ROOM);
temp_room=ch->in_room;
teleport_to(ch,to_room);
/* To follow the in-room list of chars, we need */
/* to save the next guy ahead of us before we */
/* teleport, so we don't teleport people in the */
/* place we're teleporting to... */
for(temp=ch->specials.arrest_link;temp;temp=ch->specials.arrest_link) {
if(temp->in_room!=temp_room) {
sprintf(buf,"%s You can't get away that easily, bub!",GET_NAME(temp));
do_tell(ch,buf,0);
}
teleport_to(temp,to_room);
temp->specials.arrest_by=NULL;
ch->specials.arrest_link=temp->specials.arrest_link;
temp->specials.arrest_link=NULL;
}
ch->specials.spec[2]|=APPR_RETURN;
ch->specials.spec[2]&=~APPR_PRISONERS;
ch->specials.spec[3]=temp_room;
} else if(ch->specials.spec[2] & APPR_RETURN) {
do_say(ch,"Sorry I can't stay, but I have work to do!",0);
teleport_to(ch,ch->specials.spec[3]);
act("$n smiles inwardly at a job well done.",TRUE,ch,0,0,TO_ROOM);
ch->specials.spec[2]=0; /* change for extra flags */
}
}
return(FALSE);
}
int witness(struct char_data *ch,struct char_data *pl,int cmd,char *arg)
{
struct char_data *vict=NULL;
char buf[MAX_STRING_LENGTH],arg1[MAX_STRING_LENGTH],arg2[MAX_STRING_LENGTH];
if(GET_POS(ch)<POSITION_SLEEPING)
return(FALSE);
if(!(zone_table[world[ch->in_room].zone].flags & ZONE_HOMETOWN))
return(FALSE);
if(pl) {
if(!IS_HUMANOID(pl) || !CAN_SEE(ch,pl))
return(FALSE);
switch(cmd) {
case 84: /*cast*/
/* if(!..is_offensive..) return(FALSE); */
case 25: /* kill */
case 70: /* hit */
case 154: /* backstab */
case 156: /* steal -should have a different treatment*/
case 157: /* bash */
case 159: /* kick */
case 236: /* murder */
one_argument(arg,arg1);
if(!(vict=get_char_room_vis(pl,arg1)))
return(FALSE);
if(!IS_HUMANOID(vict))
return(FALSE);
if(vict->specials.fighting==pl)
return(FALSE);
argument_interpreter(arg,arg1,arg2);
if(vict->specials.fighting==ch || ch->specials.fighting==vict) {
sprintf(buf,"%s Hey, thanks!",fname(GET_NAME(pl)));
do_tell(ch,buf,0);
return(FALSE);
}
if(!ch->specials.witnessing) {
ch->specials.witnessing=pl;
ch->specials.witness_vict=vict;
ch->specials.witness_cmd=cmd;
}
break;
}
} else {
if(ch->specials.witnessing) {
if(ch->specials.witnessing->specials.fighting==
ch->specials.witness_vict) {
if(ch->specials.witness_vict==ch)
sprintf(buf,"%s is an Outlaw! %s %s me!",
PERS(ch->specials.witnessing,ch),
HSSH(ch->specials.witnessing),
(ch->specials.witness_cmd==156 ?
"stole from" : "attacked"));
else
sprintf(buf,"%s is an Outlaw! I saw %s %s %s!",
PERS(ch->specials.witnessing,ch),
HMHR(ch->specials.witnessing),
(ch->specials.witness_cmd==156 ?
"steal from" : "attack"),
fname(GET_NAME(ch->specials.witness_vict)));
do_yell(ch,buf,0);
if(IS_NPC(ch->specials.witnessing))
SET_BIT(ch->specials.witnessing->specials.act,NPC_OUTLAW);
else
SET_BIT(ch->specials.witnessing->specials.act,PLR_OUTLAW);
}
ch->specials.witnessing=NULL;
ch->specials.witness_vict=NULL;
ch->specials.witness_cmd=0;
}
}
return(FALSE);
}
int judge(struct char_data *ch,struct char_data *pl,int cmd,char *arg)
{
return(FALSE);
}
int jailtally(struct obj_data *obj, struct char_data *ch,int cmd, char *arg)
{
struct obj_data *t_obj;
struct char_data *k;
char buf[MAX_STRING_LENGTH];
int room;
if(!ch)
return(FALSE);
if(cmd==63 && ch && GET_POS(ch) >= POSITION_RESTING) {
while(isspace(*arg))
arg++;
t_obj=get_obj_in_list_vis(ch,arg,world[ch->in_room].contents);
if(t_obj==obj) {
if(IS_SET(world[ch->in_room].room_flags,JAIL))
room=ch->in_room;
else if(IS_SET(world[ch->in_room+1].room_flags,JAIL))
room=ch->in_room+1;
else
return(FALSE);
send_to_char("The tally sheet lists the following inmates:\n\r",ch);
for(k=world[room].people;k;k=k->next_in_room) {
if(IS_OUTLAW(k) && k->specials.jail_time) {
sprintf(buf,"$N - %d more ticks",k->specials.jail_time);
act(buf,FALSE,ch,0,k,TO_CHAR);
}
}
return(TRUE);
}
}
return(FALSE);
}
int jailkeeper(struct char_data *ch,struct char_data *pl,int cmd,char *arg)
{
/* This relies on the jail room being one number higher than the */
/* room in which the jailkeeper resides... */
struct char_data *k,*temp_ch;
struct obj_data *obj;
int room;
bool change_room,feeding=FALSE;
char buf[MAX_STRING_LENGTH],arg1[MAX_INPUT_LENGTH];
extern struct time_info_data time_info;
if(room == top_of_world - 1 ||
!IS_SET(world[ch->in_room+1].room_flags,JAIL)) {
return(FALSE); /* temporary solution */
}
if(GET_POS(ch)<=POSITION_FIGHTING)
return(FALSE);
if(pl) {
switch(cmd) {/*
case 1: /* movement commands * /
case 2:
case 3:
case 4:
case 5:
case 6:
if(
case ...unlock..:
case ...open..:
break;*/
case 156: /* steal */
argument_interpreter(arg,arg1,buf);
if(ch==get_char_room_vis(pl,buf) && !IS_TRUSTED(pl)) {
do_action(ch,pl->player.name,130);
return(TRUE);
}
break;
default:
break;
}
} else {
if(GET_POS(ch)==POSITION_SLEEPING) {
do_wake(ch,"",0);
return(FALSE);
}
if(GET_POS(ch)==POSITION_RESTING ||
GET_POS(ch)==POSITION_SITTING) {
do_stand(ch,"",0);
return(FALSE);
}
change_room=FALSE;
/* Check the current room for outlaws */
for(k=world[ch->in_room].people;k;k=k->next_in_room) {
if(k!=ch && IS_OUTLAW(k) && !IS_TRUSTED(k))
change_room=TRUE;
}
/* Check the jail room for various things */
for(k=world[ch->in_room+1].people;k;k=k->next_in_room) {
if(LAW_ENFORCER(k)&&(k->specials.spec[2] & APPR_RETURN))
continue;
if(IS_OUTLAW(k) && !IS_TRUSTED(k))
k->specials.jail_time--;
if((!IS_OUTLAW(k) || !k->specials.jail_time ||
k->specials.jail_time<=-1) && !IS_TRUSTED(k))
change_room=TRUE;
}
if(!time_info.hours%8) {
if(!ch->specials.spec[0]) {
feeding=TRUE;
change_room=TRUE;
ch->specials.spec[0]=1;
}
} else
ch->specials.spec[0]=0;
if(!change_room) {
do_close(ch,"door",0);
do_lock(ch,"door",0);
return(FALSE);
}
room=ch->in_room;
/* Open a passage, if possible */
do_unlock(ch,"door",0);
do_open(ch,"door",0);
/* Throw in any outlaws */
for(k=world[ch->in_room].people;k;k=temp_ch) {
temp_ch = k->next_in_room;
if(k!=ch && IS_OUTLAW(k) && !IS_TRUSTED(k)) {
if(k->specials.jail_time) {
do_say(ch,"Laws are laws, buddy.",0);
k->specials.jail_time += 50;
} else {
do_say(ch,"Turning yourelf in, eh?",0);
k->specials.jail_time = 120;
}
act("$N throws you in the cell.",FALSE,k,0,ch,TO_CHAR);
act("$N throws $n in the cell.",FALSE,k,0,ch,TO_NOTVICT);
char_from_room(k);
char_to_room(k,room+1,0);
act("$n is thrown into the room.",FALSE,k,0,0,TO_ROOM);
}
}
act("$n enters the cell.",TRUE,ch,0,0,TO_ROOM);
char_from_room(ch);
char_to_room(ch,room+1,0);
act("$n enters the cell.",TRUE,ch,0,0,TO_ROOM);
for(k=world[ch->in_room].people;k;k=temp_ch) {
temp_ch=k->next_in_room;
if(IS_TRUSTED(k) || ch==k)
continue;
if(!IS_OUTLAW(k)) {
if(!(LAW_ENFORCER(k)&&(k->specials.spec[2] & APPR_RETURN))) {
sprintf(buf,"What are you doing in here, %s?", fname(GET_NAME(k)));
do_say(ch,buf,0);
act("$n tosses $N out of the cell.",TRUE,ch,0,k,TO_NOTVICT);
act("$n tosses you out of the cell.",FALSE,ch,0,k,TO_VICT);
char_from_room(k);
char_to_room(k,room,0);
act("$n is tossed from the cell.",TRUE,k,0,0,TO_ROOM);
do_look(k,"",0);
}
} else if(!k->specials.jail_time) {
do_action(ch,GET_NAME(k),23);
sprintf(buf,"You are free to go, %s.",
fname(GET_NAME(k)));
do_say(ch,buf,0);
act("$n lets $N out of the cell.",TRUE,ch,0,k,TO_NOTVICT);
act("$n lets you out of the cell.",FALSE,ch,0,k,TO_VICT);
char_from_room(k);
char_to_room(k,room,0);
act("$n has arrived.",FALSE,k,0,0,TO_ROOM);
REMOVE_BIT(k->specials.act, (IS_NPC(k) ?
NPC_OUTLAW : PLR_OUTLAW));
} else if(k->specials.jail_time<=-1) {
k->specials.jail_time=150; /* ought to #define*/
act("$n points a finger at $N.",TRUE,ch,0,k,TO_NOTVICT);
act("$n points a finger at you.",TRUE,ch,0,k,TO_VICT);
sprintf(buf,"I hope you enjoy your stay, %s.",
fname(GET_NAME(k)));
do_say(ch,buf,0);
}
}
if(feeding) {
for(k=world[ch->in_room].people;k;k=k->next_in_room)
if(!IS_TRUSTED(k) && ch!=k) {
obj=read_object(3010,VIRTUAL);
obj_to_char(obj,ch);
sprintf(buf,"%s to %s",fname(obj->name),
GET_NAME(k));
do_give(ch,buf,0);
/* if(obj->carried_by==ch) {
obj_from_ch(*/
obj=read_object(3100,VIRTUAL);
obj_to_char(obj,ch);
sprintf(buf,"%s to %s",fname(obj->name),
GET_NAME(k));
do_give(ch,buf,0);
}
}
act("$n leaves the cell.",TRUE,ch,0,0,TO_ROOM);
char_from_room(ch);
char_to_room(ch,room,0);
act("$n has arrived.",TRUE,ch,0,0,TO_ROOM);
do_close(ch,"door",0);
do_lock(ch,"door",0);
}
return(FALSE);
}