/************************************************************************
Realms of Aurealis James Rhone aka Vall of RoA
handler.c Vital code related to char and object
moving. Other miscellaneous mud handler
functions.
******** Heavily modified and expanded ********
*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
******** Heavily modified and expanded ********
All rights reserved henceforth.
Please note that no guarantees are associated with any code from
Realms of Aurealis. All code which has been released to the general
public has been done so with an 'as is' pretense. RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license. *** Read, Learn, Understand, Improve ***
*************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structures.h"
#include "utils.h"
#include "comm.h"
#include "db.h"
#include "handler.h"
#include "interpreter.h"
#include "acmd.h"
#include "mudlimits.h"
#include "magic.h"
#include "affect.h"
#include "lists.h"
#include "fight.h"
#include "global.h"
#include "plshop.h"
#include "objsave.h"
#include "clicomm.h"
#include "darkenelf.h"
#include "descmenu.h"
/* external vars */
extern chdata *combat_list;
extern char *wv_bits[];
/* external functions */
void free_char(chdata *ch);
void stop_fighting(chdata *ch);
void remove_follower(chdata *ch);
void clearMemory(chdata *ch);
void float_sink_char(chdata *ch);
void float_sink_object(obdata *ob, int room);
void reload_zone(int zone);
int unidle_reset_zone(int zone);
void null_char_room_affects(chdata *ch);
void remove_song_from_world(chdata *ch, sh_int song);
void send_aff1_mesg(chdata *ch, int j, BOOL flag);
void send_aff2_mesg(chdata *ch, int j, BOOL flag);
int apply_ac(chdata *ch, int pos);
int can_see(chdata *ch, chdata *i);
int num_remorts(chdata *ch);
void update_client_eq(dsdata *d);
void update_client_inv(dsdata *d);
void die_follower(chdata *ch);
char *fname(char *namelist)
{
static char holder[30];
register char *point;
for (point = holder; isalpha(*namelist); namelist++, point++)
*point = *namelist;
*point = '\0';
return(holder);
}
int isname(char *str, char *namelist)
{
register char *curname, *curstr;
if (!namelist || !*namelist)
return FALSE;
curname = namelist;
for (; ; )
{
for (curstr = str; ; curstr++, curname++)
{
if (!*curstr && !isalpha(*curname))
return TRUE;
if (!*curname)
return FALSE;
if (!*curstr || *curname == ' ')
break;
if (LOWER(*curstr) != LOWER(*curname))
break;
}
// skip to next name
for (; isalpha(*curname); curname++)
;
if (!*curname)
return FALSE;
curname++; /* first char of new name */
}
}
/* move a player out of a room */
void char_from_room(chdata *ch)
{
chdata *temp;
int room = ch->in_room;
if (IN_NOWHERE(ch))
{
sprintf(buf, "SYSERR: NOWHERE chfromroom (%s)",GET_NAME(ch));
log(buf);
exit(1);
}
if (EQ(ch, W_HOLD) && OBJ_LIGHT(EQ(ch, W_HOLD)) && LIT(EQ(ch, W_HOLD)))
world[room].light--;
if (IS_AFFECTED2(ch, AFF2_LIGHT))
world[room].light--;
world[room].light = MAX(0, world[room].light);
REMOVE_FROM_LIST(ch, world[room].people, next_in_room);
if (IS_NPC(ch))
world[room].num_present--; /* -1 to the room for MOBS for now*/
else
if (!IS_IMMORTAL(ch))
{
if (GET_RACE(ch) == RACE_DRAGON)
world[room].num_present -= 4; /* dragon size 4 */
if (GET_RACE(ch) == RACE_OGRE || GET_RACE(ch) == RACE_ORC)
world[room].num_present -= 3; /* these guys are 3 */
if (GET_RACE(ch) == RACE_PIXIE || GET_RACE(ch) == RACE_NIXIE)
world[room].num_present -= 1; /* small size 1 */
else
world[room].num_present -= 2; /* normal size 2 */
}
ch->in_room = NOWHERE;
ch->next_in_room = NULL;
}
// give newbie eq to ch if <= level 1 and they enter newbie eq room
void give_newbie_eq(chdata *ch)
{
obdata *ob = NULL;
int i;
// torch
ob = read_object(172, VIRTUAL);
obj_to_char(ob, ch);
// bag
ob = read_object(173, VIRTUAL);
obj_to_char(ob, ch);
// waterskin i think
ob = read_object(175, VIRTUAL);
obj_to_char(ob, ch);
// 4 breads
for (i = 0; i < 4; i++)
{
ob = read_object(174, VIRTUAL);
obj_to_char(ob, ch);
}
switch (GET_CLASS(ch)) {
case CLASS_WARRIOR:
ob = read_object(153, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(162, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(171, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_MAGE:
case CLASS_MADEPT:
ob = read_object(151, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(160, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(169, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_CLERIC:
case CLASS_DRUID:
ob = read_object(152, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(161, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(171, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_THIEF:
ob = read_object(154, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(163, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(171, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_RANGER:
ob = read_object(156, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(165, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(171, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_BARD:
ob = read_object(157, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(166, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(170, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_SHAMAN:
ob = read_object(155, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(164, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(171, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_MONK:
ob = read_object(159, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(168, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(169, VIRTUAL);
obj_to_char(ob, ch);
break;
case CLASS_WARLOCK:
ob = read_object(158, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(167, VIRTUAL);
obj_to_char(ob, ch);
ob = read_object(170, VIRTUAL);
obj_to_char(ob, ch);
break;
};
GET_GOLD(ch) = 500;
send_to_char("%B%6You've been given some equipment and currency!%0\n\r",ch);
}
// if this room has a sound file... if ch has client connection... send it..
// also, after that, if mob in room has a sound.. send that
void check_room_soundsend(chdata *ch)
{
void send_soundfile_to_client(dsdata *d, char *sound_file);
chdata *m;
if (INVALID_ROOM(ch->in_room))
return;
if (!ch->desc || !HAS_CLIENT(ch->desc))
return;
// first, check the room they're in...
if (world[ch->in_room].sound_file)
{
send_soundfile_to_client(ch->desc, world[ch->in_room].sound_file);
ch->desc->room_stimer = world[ch->in_room].music_timer;
ch->desc->music_room = world[ch->in_room].number;
}
// ALSO have to check if a mob in the room with them is makin noise...
for (m=world[ch->in_room].people; m; m=m->next_in_room)
if (IS_NPC(m) && m->npc_specials.sound_file)
{
send_soundfile_to_client(ch->desc, m->npc_specials.sound_file);
ch->desc->mob_stimer = m->npc_specials.music_timer;
ch->desc->music_room = GET_MOB_VNUM(m);
break;
}
}
/* place a character in a room */
void char_to_room(chdata *ch, int room)
{
int zone;
void reset_roazone(int zone);
int purge_zone(int zone);
ch->next_in_room = world[room].people;
world[room].people = ch;
zone = world[room].zone;
/* CHECK FOR FREENESS, IF SO LOAD ROOMS AND ZONE COMLIST!!! */
/* even an immortal will trigger this one */
if (REAL_ZONE(zone) && ZONE_FREED(zone))
reload_zone(zone);
if (IS_NPC(ch))
world[room].num_present++; /* add one to the room for MOBS for now*/
else
if (IS_PC(ch) && !IS_IMMORTAL(ch))
{
if (GET_RACE(ch) == RACE_DRAGON)
world[room].num_present += 4; /* dragon size 4 */
if (GET_RACE(ch) == RACE_OGRE || GET_RACE(ch) == RACE_ORC)
world[room].num_present += 3; /* these guys are 3 */
if (GET_RACE(ch) == RACE_PIXIE || GET_RACE(ch) == RACE_NIXIE)
world[room].num_present += 1; /* small size 1 */
else
world[room].num_present += 2; /* normal size 2 */
/* CHECK FOR IDLENESS, IF SO RESET THE ZONE!!! */
if (REAL_ZONE(zone) && ZONE_IDLE(zone))
unidle_reset_zone(zone);
}
ch->in_room = room;
if ((room == real_room(1904)) && (GET_LEVEL(ch) <= 1))
give_newbie_eq(ch);
if (EQ(ch, W_HOLD) && OBJ_LIGHT(EQ(ch, W_HOLD)) && LIT(EQ(ch, W_HOLD)) )
world[room].light++;
if (IS_AFFECTED2(ch, AFF2_LIGHT))
world[room].light++;
// if light isnt waterproof, extinguish it -roa
if (ROOM_FLAGGED(room, UWATER) && EQ(ch, W_HOLD) &&
LIT(EQ(ch, W_HOLD)) && !OBJ_FLAGGED(EQ(ch, W_HOLD), ITEM_WATERPROOF))
do_extinguish(ch, "", 0, 0);
// if they were eavesdroppin, pull them from it now... 4/17/98 -jtrhone
if (CHAR_FLAGGED(ch, CH_EAVESDROPPING) && ch->desc && !INVALID_ROOM(ch->desc->room_snooping))
{
remove_room_snooper(&world[ch->desc->room_snooping], ch->desc);
REMOVE_BIT(CHAR_FLAGS(ch), CH_EAVESDROPPING);
}
check_room_soundsend(ch);
}
/* give an object to a char */
void obj_to_char(obdata *object, chdata *ch)
{
object->next_content = ch->carrying;
ch->carrying = object;
object->carried_by = ch;
object->in_room = NOWHERE;
IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(object);
IS_CARRYING_N(ch)++;
if ((IS_PC(ch) && !IS_IMMORTAL(ch)) || (SPC_FLAGGED(ch, SPC_SHOPKEEP) || SPC_FLAGGED(ch, SPC_FIXER)))
object->touched = TRUE;
/* set flag for crash-save system */
if (IS_PC(ch))
SET_BIT(PLR_FLAGS(ch), PLR_CRASH);
// update client inv list... 6/17/98 -jtrhone
if (ch->desc && D_CHECK(ch->desc) && HAS_CLIENT(ch->desc) && PLR2_FLAGGED(ch, PLR2_CLIENTINV))
update_client_inv(ch->desc);
}
/* take an object from a char */
void obj_from_char(obdata *object)
{
obdata *temp = NULL;
chdata *ch = object->carried_by;
REMOVE_FROM_LIST(object, ch->carrying, next_content);
/* this object has been touched by mortals */
if (IS_PC(ch) && !IS_IMMORTAL(ch))
object->touched = TRUE;
/* player gets flagged crash for next autosave */
if (IS_PC(ch))
SET_BIT(PLR_FLAGS(ch), PLR_CRASH);
IS_CARRYING_W(object->carried_by) -= GET_OBJ_WEIGHT(object);
IS_CARRYING_N(object->carried_by)--;
object->carried_by = NULL;
object->next_content = NULL;
// update client inv list... 6/17/98 -jtrhone
if (ch->desc && D_CHECK(ch->desc) && HAS_CLIENT(ch->desc) && PLR2_FLAGGED(ch, PLR2_CLIENTINV))
update_client_inv(ch->desc);
}
// object - character restrictions, return true if any
// remort only eq update 5/29/98 -jtrhone
BOOL object_restricts(chdata *ch, obdata *obj)
{
if ((OBJ_FLAGGED(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) )
{
if (!IN_NOWHERE(ch))
{
act("You, being evil, are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch))
{
if (!IN_NOWHERE(ch))
{
act("You, being good, are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))
{
if (!IN_NOWHERE(ch))
{
act("You, being neutral, are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_MAGE) && IS_NAT_MAGE(ch))
{
if (!IN_NOWHERE(ch))
{
act("Mages are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_CLERIC) && IS_NAT_CLERIC(ch))
{
if (!IN_NOWHERE(ch))
{
act("Clerics are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_WARRIOR) && IS_NAT_WARRIOR(ch))
{
if (!IN_NOWHERE(ch))
{
act("Warriors are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_THIEF) && IS_NAT_THIEF(ch))
{
if (!IN_NOWHERE(ch))
{
act("Thieves are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_SHAMAN) && IS_NAT_SHAMAN(ch))
{
if (!IN_NOWHERE(ch))
{
act("Shaman are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_BARD) && IS_NAT_BARD(ch))
{
if (!IN_NOWHERE(ch))
{
act("Bards are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_RANGER) && IS_NAT_RANGER(ch))
{
if (!IN_NOWHERE(ch))
{
act("Rangers are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_WARLOCK) && IS_NAT_WARLOCK(ch))
{
if (!IN_NOWHERE(ch))
{
act("Warlocks are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED(obj, ITEM_ANTI_MONK) && IS_NAT_MONK(ch))
{
if (!IN_NOWHERE(ch))
{
act("Monshai are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_HUMAN) && IS_HUMAN(ch))
{
if (!IN_NOWHERE(ch))
{
act("Humans are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_ELF) && IS_ELF(ch))
{
if (!IN_NOWHERE(ch))
{
act("Elves are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_HALF_ELF) && IS_HALF_ELF(ch))
{
if (!IN_NOWHERE(ch))
{
act("Half-elves are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_ORC) && IS_ORC(ch))
{
if (!IN_NOWHERE(ch))
{
act("Orcs are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_OGRE) && IS_OGRE(ch))
{
if (!IN_NOWHERE(ch))
{
act("Ogres are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_DROW) && IS_DROW(ch))
{
if (!IN_NOWHERE(ch))
{
act("Drow are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_DWARF) && IS_DWARF(ch))
{
if (!IN_NOWHERE(ch))
{
act("Dwarves are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_PIXIE) && IS_PIXIE(ch))
{
if (!IN_NOWHERE(ch))
{
act("Pixies are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_NIXIE) && IS_NIXIE(ch))
{
if (!IN_NOWHERE(ch))
{
act("Nixies are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_MADEPT) && IS_NAT_MADEPT(ch))
{
if (!IN_NOWHERE(ch))
{
act("Madept are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_DRUID) && IS_NAT_DRUID(ch))
{
if (!IN_NOWHERE(ch))
{
act("Druids are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_DRAGON) && IS_DRAGON(ch))
{
if (!IN_NOWHERE(ch))
{
act("Drakyn are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_ASSASSIN) && IS_ASSASSIN(ch))
{
if (!IN_NOWHERE(ch))
{
act("Assassins are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ANTI_ASSASSIN) && MOB2_FLAGGED(ch, MOB2_ASSASSIN))
{
if (!IN_NOWHERE(ch))
{
act("Assassins are unable to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
if (OBJ_FLAGGED2(obj, ITEM_ASSASSIN_ONLY) && (!MOB2_FLAGGED(ch, MOB2_ASSASSIN) && !IS_ASSASSIN(ch)))
{
if (!IN_NOWHERE(ch))
{
act("Only assassins are able to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
// let NPCs/Immortals get remort waver 6/24/98 -jtrhone
if (OBJ_FLAGGED2(obj, ITEM_REMORT_ONLY) && IS_PC(ch) && !IS_IMMORTAL(ch) && !num_remorts(ch))
{
if (!IN_NOWHERE(ch))
{
act("Only remorts are able to use $p.", FALSE, ch, obj, 0, TO_CHAR);
act("$n is unable to use $p.", FALSE, ch, obj, 0, TO_ROOM);
}
else
log("SYSERR: ch->in_room = NOWHERE when equipping char.");
return TRUE;
}
// else, all is good, return ok...
return FALSE;
}
/* RoA ... we MUST know if equip was successful! */
// updated to support wvectors 5/28/98 -jtrhone
// if anything fails, give obj to char, do not make it disappear 6/4/98 -jtrhone
BOOL equip_char(chdata *ch, obdata *obj, int pos, BOOL mode)
{
int i, j;
long oldbitv1, newbitv1;
long oldbitv2, newbitv2;
assert(pos >= 0 && pos < MAX_WEAR);
if (EQ(ch, pos) || WV_FLAGGED(ch, ((1 << pos)) ))
{
sprintf(buf, "SYSERR: Char already equipped: %s, %s (%d), pos: %d", GET_NAME(ch), obj->shdesc, GET_OBJ_VNUM(obj), pos);
mudlog(buf, BRF, LEV_IMM, TRUE);
obj_to_char(obj, ch);
return FALSE;
}
if (obj->carried_by)
{
sprintf(buf, "SYSERR: EQUIP: Obj(%d: %s) carried_by %s", GET_OBJ_VNUM(obj), obj->shdesc, GET_NAME(obj->carried_by));
mudlog(buf, BRF, LEV_IMM, TRUE);
obj_to_char(obj, ch);
return FALSE;
}
if (obj->in_room != NOWHERE)
{
log("SYSERR: EQUIP: Obj is in_room when equip.");
obj_to_char(obj, ch);
return FALSE;
}
if (IS_AFFECTED2(ch, AFF2_CLAWS) && (pos == W_WIELD || pos == W_HOLD))
{
if (!IN_NOWHERE(ch))
act("Your claws prevent you from wielding or holding anything.", FALSE, ch, 0, 0, TO_CHAR);
obj_to_char(obj, ch);
return FALSE;
}
// object_restricts now sends tailored failure messages
if (!IS_IMMORTAL(ch) && object_restricts(ch, obj))
{
obj_to_char(obj, ch);
return FALSE;
}
obj->in_room = NOWHERE;
EQ(ch, pos) = obj;
if (ITEM_TYPE(obj) == ITEM_ARMOR)
GET_AC(ch) -= apply_ac(ch, pos);
oldbitv1 = AFF_FLAGS(ch);
oldbitv2 = AFF2_FLAGS(ch);
for (j = 0; j < MAX_OBJ_AFFECT; j++)
affect_modify(ch, obj->affected[j].location, obj->affected[j].modifier,
obj->eqaffbit, obj->eqaff2bit, TRUE);
newbitv1 = AFF_FLAGS(ch);
newbitv2 = AFF2_FLAGS(ch);
for(j = 1, i = 0; i < MAX_AFFECT; i++, j *= 2)
if(IS_SET(newbitv1, j) && !IS_SET(oldbitv1, j) && mode)
send_aff1_mesg(ch, j, TRUE);
for(j = 1, i = 0; i < MAX_AFFECT; i++, j *= 2)
if(IS_SET(newbitv2, j) && !IS_SET(oldbitv2, j) && mode)
send_aff2_mesg(ch, j, TRUE);
affect_total(ch);
// now, set wvector flags from object's wvflags and send messages 5/28/98 -jtrhone
if (WV_FLAGS(obj))
{
SET_BIT(WV_FLAGS(ch), WV_FLAGS(obj));
if (mode)
{
act("$p also occupies the following positions:", FALSE, ch, obj, 0, TO_CHAR);
sprintbit(WV_FLAGS(obj), wv_bits, buf2);
sprintf(buf, "%%B%%6%s%%0\n", buf2);
S2C();
}
}
// update client eq list... 6/17/98 -jtrhone
if (mode && ch->desc && D_CHECK(ch->desc) && HAS_CLIENT(ch->desc) && PLR2_FLAGGED(ch, PLR2_CLIENTEQ))
update_client_eq(ch->desc);
return TRUE;
}
// updated to support slot revamp, 5/26/98 -jtrhone
// updated to support wvectors 5/28/98 -jtrhone
obdata *unequip_char(chdata *ch, int pos, BOOL mode)
{
int i, j;
obdata *obj;
long oldbitv1, newbitv1;
long oldbitv2, newbitv2;
assert(pos >= 0 && pos < MAX_WEAR);
assert(EQ(ch, pos));
obj = EQ(ch, pos);
if (ITEM_TYPE(obj) == ITEM_ARMOR)
GET_AC(ch) += apply_ac(ch, pos);
// this supports new slot revamp 5/26/98 -jtrhone
if (OBJ_LIGHT(obj) && LIT(obj) && mode)
do_extinguish(ch, "", 0, 0);
EQ(ch, pos) = NULL;
oldbitv1 = AFF_FLAGS(ch);
oldbitv2 = AFF2_FLAGS(ch);
for (j = 0; j < MAX_OBJ_AFFECT; j++)
affect_modify(ch, obj->affected[j].location, obj->affected[j].modifier,
obj->eqaffbit, obj->eqaff2bit, FALSE);
affect_total(ch);
newbitv1 = AFF_FLAGS(ch);
newbitv2 = AFF2_FLAGS(ch);
for(j = 1, i = 0; i < MAX_AFFECT;i++, j *= 2)
if(!IS_SET(newbitv1, j) && IS_SET(oldbitv1, j) && mode)
send_aff1_mesg(ch, j, FALSE);
for(j = 1, i = 0; i < MAX_AFFECT;i++, j *= 2)
if(!IS_SET(newbitv2, j) && IS_SET(oldbitv2, j) && mode)
send_aff2_mesg(ch, j, FALSE);
EQ(ch, pos) = NULL;
// now, remove wvector flags from object's wvflags and send messages 5/28/98 -jtrhone
if (WV_FLAGS(obj))
{
REMOVE_BIT(WV_FLAGS(ch), WV_FLAGS(obj));
if (mode)
{
act("Removing $p has freed up the following positions:", FALSE, ch, obj, 0, TO_CHAR);
sprintbit(WV_FLAGS(obj), wv_bits, buf2);
sprintf(buf, "%%B%%6%s%%0\n", buf2);
S2C();
}
}
// update client eq list... 6/17/98 -jtrhone
if (mode && ch->desc && D_CHECK(ch->desc) && HAS_CLIENT(ch->desc) && PLR2_FLAGGED(ch, PLR2_CLIENTEQ))
update_client_eq(ch->desc);
return(obj);
}
// yank a piece of eq out of equip list, place it into inventory -roa
BOOL eq_to_inv(chdata *ch, int pos, BOOL tellem)
{
obdata *ob;
assert(pos >= 0 && pos < MAX_WEAR);
ob = unequip_char(ch, pos, tellem);
obj_to_char(ob, ch);
return TRUE;
}
// yank a piece of inv out of inv list, wield/wear it -roa
BOOL inv_to_eq(chdata *ch, obdata *ob, int pos, BOOL tellem)
{
assert(pos >= 0 && pos < MAX_WEAR);
obj_from_char(ob);
return equip_char(ch, ob, pos, tellem);
}
int get_number(char **name)
{
int i;
char *ppos;
char number[MAX_INPUT_LENGTH];
*number = '\0';
if ((ppos = strchr(*name, '.')))
{
*ppos++ = '\0';
strcpy(number, *name);
strcpy(*name, ppos);
for (i = 0; *(number + i); i++)
if (!isdigit(*(number + i)))
return 0;
return(atoi(number));
}
return 1;
}
/* Search a given list for an object, and return a pointer to that object */
obdata *get_obj_in_list(char *name, obdata *list)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj_in_list");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return NULL;
for (i = list, j = 1; i && (j <= number); i = i->next_content)
if (isname(tmp, i->name))
{
if (j == number)
return(i);
j++;
}
return NULL;
}
/* Search a given list for an object number, and return a ptr to that obj */
obdata *get_obj_in_list_num(int num, obdata *list)
{
obdata *i;
for (i = list; i; i = i->next_content)
if (i->item_number == num)
return(i);
return NULL;
}
/*search the entire world for an object, and return a pointer */
obdata *get_obj(char *name)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return NULL;
for (i = object_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->name))
{
if (j == number)
return(i);
j++;
}
return NULL;
}
/*search the entire world for an object number, and return a pointer */
obdata *get_obj_num(int nr)
{
obdata *i;
for (i = object_list; i; i = i->next)
if (i->item_number == nr)
return(i);
return NULL;
}
/* search a room for a char, and return a pointer if found.. */
chdata *get_char_room(char *name, int room)
{
chdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_char_room");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return NULL;
for (i = world[room].people, j = 1; i && (j <= number); i = i->next_in_room)
if (isname(tmp, i->player.name))
{
if (j == number)
return(i);
j++;
}
return NULL;
}
/* search all over the world for a char, and return a pointer if found */
chdata *get_char(char *name)
{
chdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
if (!name || !*name) return NULL;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_char");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return NULL;
for (i = character_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->player.name))
{
if (j == number)
return(i);
j++;
}
return NULL;
}
/* search all over the world for a char num, and return a pointer if found */
chdata *get_char_num(int nr)
{
chdata *i;
for (i = character_list; i; i = i->next)
if (i->nr == nr)
return(i);
return NULL;
}
/* put an object in a room */
void obj_to_room(obdata *object, int room)
{
object->next_content = world[room].contents;
world[room].contents = object;
object->in_room = room;
object->carried_by = NULL;
if (ROOM_FLAGGED2(room, HOUSE))
SET_BIT(ROOM_FLAGS2(room), HOUSE_CRASH);
else
if (ROOM_FLAGGED2(room, SAVE_ROOM))
SET_BIT(ROOM_FLAGS2(room), ROOM_CRASH);
}
/* Take an object from a room */
void obj_from_room(obdata *object)
{
obdata *temp;
if (object->in_room == NOWHERE)
{
sprintf(buf, "SYSERR: Obj in NOWHERE, placed in void.(%d)", GET_OBJ_VNUM(object));
mudlog(buf, BRF, LEV_IMM, TRUE);
obj_to_room(object, 0);
return;
}
REMOVE_FROM_LIST(object, world[object->in_room].contents, next_content);
if (ROOM_FLAGGED2(object->in_room, HOUSE))
SET_BIT(ROOM_FLAGS2(object->in_room), HOUSE_CRASH);
else
if (ROOM_FLAGGED2(object->in_room, SAVE_ROOM))
SET_BIT(ROOM_FLAGS2(object->in_room), ROOM_CRASH);
object->in_room = NOWHERE;
object->next_content = NULL;
}
// place an object inside another object
void obj_to_obj(obdata *obj, obdata *obj_to)
{
obdata *tmp_obj;
if (!obj || !obj_to) return;
obj->next_content = obj_to->contains;
obj_to->contains = obj;
obj->in_obj = obj_to;
for (tmp_obj = obj->in_obj; tmp_obj->in_obj; tmp_obj = tmp_obj->in_obj)
GET_OBJ_WEIGHT(tmp_obj) += GET_OBJ_WEIGHT(obj);
/* top level object. Subtract weight from inventory if necessary. */
GET_OBJ_WEIGHT(tmp_obj) += GET_OBJ_WEIGHT(obj);
if (tmp_obj->carried_by)
IS_CARRYING_W(tmp_obj->carried_by) += GET_OBJ_WEIGHT(obj);
}
/* remove an object from an object */
void obj_from_obj(obdata *obj)
{
obdata *temp, *obj_from;
if (obj->in_obj == NULL) {
log("SYSERR: (handler.c): trying to illegally extract obj from obj");
return;
}
obj_from = obj->in_obj;
REMOVE_FROM_LIST(obj, obj_from->contains, next_content);
/* Subtract weight from containers container */
for (temp = obj->in_obj; temp->in_obj; temp = temp->in_obj)
GET_OBJ_WEIGHT(temp) -= GET_OBJ_WEIGHT(obj);
/* Subtract weight from char that carries the object */
GET_OBJ_WEIGHT(temp) -= GET_OBJ_WEIGHT(obj);
if (temp->carried_by)
IS_CARRYING_W(temp->carried_by) -= GET_OBJ_WEIGHT(obj);
obj->in_obj = NULL;
obj->next_content = NULL;
}
/* Set all carried_by to point to new owner */
void object_list_new_owner(obdata *list, chdata *ch)
{
if (list)
{
object_list_new_owner(list->contains, ch);
object_list_new_owner(list->next_content, ch);
list->carried_by = ch;
}
}
/* Extract an object from the world */
void extract_obj(obdata *obj)
{
obdata *temp;
if (!INVALID_ROOM(obj->in_room))
obj_from_room(obj);
else if (obj->carried_by)
obj_from_char(obj);
else if (obj->in_obj)
obj_from_obj(obj);
/* leave nothing behind */
while(obj->contains)
extract_obj(obj->contains);
obj->contains = NULL;
REMOVE_FROM_LIST(obj, object_list, next);
if (GET_OBJ_RNUM(obj) >= 0)
obj_index[GET_OBJ_RNUM(obj)].number--;
free_obj(obj);
}
// update object just decrements the timers on this obj and all within it/after it in list
void update_object(obdata *obj, int use)
{
if (!obj)
{
mudlog("SYSERR: NO OBJECT in update_object, handler.c", BRF, LEV_IMM, TRUE);
return;
}
if (obj->timer > 0)
obj->timer -= use;
if (obj->contains)
update_object(obj->contains, use);
if (obj->next_content)
update_object(obj->next_content, use);
}
// updated to support pure poisons and brewing and the like... 4/17/98 -jtrhone
// updated to check hold slot for light objs rather than light slot
// i.e. to support slot revamp 5/26/98 -jtrhone
// todo: should move light updates to update_obj and add inv scanning
void update_char_objects( chdata *ch )
{
int i;
BOOL waslit = FALSE;
if (EQ(ch, W_HOLD) && OBJ_LIGHT(EQ(ch, W_HOLD)) &&
LIGHT_TIME(EQ(ch, W_HOLD)) > 0)
{
LIGHT_TIME(EQ(ch, W_HOLD))--;
waslit = TRUE;
}
if (EQ(ch, W_HOLD) && OBJ_LIGHT(EQ(ch, W_HOLD)) &&
!LIGHT_TIME(EQ(ch, W_HOLD)) && waslit && !IN_NOWHERE(ch))
{
EQ(ch, W_HOLD)->lit = FALSE;
act("Your light source has burnt out!",FALSE,ch,0,0,TO_CHAR);
if (world[ch->in_room].light > 0)
{
if ((world[ch->in_room].light--) > 0)
{
act("The area surrounding you gets slightly darker.",FALSE,ch,0,0,TO_CHAR);
act("The area surrounding you gets slightly darker.",FALSE,ch,0,0,TO_ROOM);
}
else
{
act("The area surrounding you suddenly gets dark!",FALSE,ch,0,0,TO_CHAR);
act("The area surrounding you suddenly gets dark!",FALSE,ch,0,0,TO_ROOM);
}
}
}
/* update all but light objects */
// apparently, objs in EQ list time out faster
for (i = 0; i < MAX_WEAR; i++)
if (EQ(ch, i) && !OBJ_LIGHT(EQ(ch, i)))
update_object(EQ(ch, i), 2);
// than objs in inventory (why... i dunno.. ) 4/17/98 -jtrhone
if (ch->carrying)
update_object(ch->carrying, 1);
// now, update the poison if ch is brewing and is holding the right stuff
// 4/17/98 -jtrhone
if (affected_by_spell(ch, SKILL_BREW))
{
obdata *o;
if (!(o = EQ(ch, W_HOLD)) || (!IS_LIQCONT(o)) || (DRINKS_LEFT(o) && DRINK_TYPE(o) != LIQ_POISON))
affect_from_char(ch, SKILL_BREW);
else
if (!DRINKS_LEFT(o) || IS_PUREPOISON(o))
{
act("You continue to brew your poison.", FALSE,ch,0,0,TO_CHAR);
DRINK_TYPE(o) = LIQ_POISON;
DRINKS_LEFT(o)++;
POISON_LEVEL(o)++;
}
}
}
// for NPC - extract mob from real world and free_char as well...
// for PCs - extract character from real world, leave char at menu...
void extract_char(chdata *ch)
{
obdata *obj;
chdata *k, *temp;
dsdata *d;
int l;
BOOL zap = FALSE;
void update_client_who(void);
if (CHAR_FLAGGED(ch, CH_RECORD))
fclose(ch->fp);
if (IS_PC(ch))
{
global_forget(ch);
if (SINGING(ch))
remove_song_from_world(ch, SINGING(ch));
if (PLAYING(ch))
remove_song_from_world(ch, PLAYING(ch));
remove_char_plshops(ch);
// if they have any clpids, we wanna not point to this char anymore
// 3/1/98 -jtrhone
null_char_clpids(ch);
}
if (IS_PC(ch) && !ch->desc)
for (d = descriptor_list; d; d = d->next)
if (d->original == ch)
do_return(d->character, "", 0, 0);
if (IN_NOWHERE(ch))
{
log("SYSERR: NOWHERE extracting char. (handler.c, extract_char)");
log(GET_NAME(ch)); /* just to see if mob or player next time */
exit(1);
}
/* if player in void or nowehere, wipe the objects RoA */
if (!ch->in_room)
zap = TRUE;
if (ch->followers || ch->master)
die_follower(ch);
if (ch->desc)
{
if (ch->desc->snooping)
ch->desc->snooping->snoop_by = 0;
if (ch->desc->snoop_by)
{
if (ch->desc->snoop_by->character)
send_to_char("Your victim is no longer among us.\n\r", ch->desc->snoop_by->character);
ch->desc->snoop_by->snooping = 0;
}
ch->desc->snooping = ch->desc->snoop_by = 0;
// now for room snooping
if (ch->desc->room_snooping)
remove_room_snooper(&world[ch->desc->room_snooping], ch->desc);
}
if (MOB_FLAGGED(ch, MOB_PLSHOPKEEP))
{
save_plshopkeep_objs(ch);
extract_objects(ch->carrying);
}
else
while (ch->carrying)
{
obj = ch->carrying;
obj_from_char(obj);
if (zap)
{
obj_to_room(obj, ch->in_room);
extract_obj(obj);
}
else
float_sink_object(obj, ch->in_room);
}
/* clear equipment_list */
for (l = 0; l < MAX_WEAR; l++)
if (EQ(ch, l))
{
obj = unequip_char(ch, l, FALSE);
if (zap)
{
obj_to_room(obj, ch->in_room);
extract_obj(obj);
}
else
float_sink_object(obj, ch->in_room);
}
if (FIGHTING(ch))
stop_fighting(ch);
for (k = combat_list; k ; k = temp)
{
temp = k->next_fighting;
if (FIGHTING(k) == ch)
stop_fighting(k);
}
null_char_room_affects(ch);
/* in case they's a shaman and they be in a rite */
DELAY_TYPE(ch) = 0;
char_from_room(ch);
/* pull the char from the list */
REMOVE_FROM_LIST(ch, character_list, next);
if (ch->desc && ch->desc->original)
do_return(ch, "", 0, 0);
if (IS_NPC(ch))
{
if (GET_MOB_RNUM(ch) > -1)
mob_index[GET_MOB_RNUM(ch)].number--;
clearMemory(ch);
free_char(ch); /* note, ch is invalid after this call */
}
else
if (ch->desc)
{
/* if they hit a dt, have them press return to go to menu */
if (CHAR_FLAGGED(ch, CH_HIT_DT))
{
CHAR_FLAGS(ch) = 0;
save_char(ch, NOWHERE);
STATE(ch->desc) = CON_DESCMENU;
descmenu_next(ch->desc, mainmenu);
descmenu_push_jump(ch->desc, genericreturn);
}
else
{
CHAR_FLAGS(ch) = 0;
save_char(ch, NOWHERE);
STATE(ch->desc) = CON_DESCMENU;
if (VT100(ch))
{
resetscr(ch);
send_to_q(VTMENU, ch->desc);
}
else
send_to_q(MENU, ch->desc);
descmenu_next(ch->desc, mainmenu);
}
// now, update the client who lists 6/15/98 -jtrhone
update_client_who();
}
}
// unlike the previous function, this one does not leave a PC at main menu, but rather
// flings him/her from the game, also does not rely on there being a descriptor
// also, it's assumed all equipment has already been removed before this point...
// usually called on PCs that have been force-saved -roa
int eject_char(chdata *ch)
{
chdata *k, *temp;
dsdata *d;
int l;
// if char is switched, return em now
if (IS_PC(ch))
for (d = descriptor_list; d; d = d->next)
if (d->original == ch)
do_return(d->character, "", 0, 0);
if (ch->followers || ch->master)
die_follower(ch);
// shouldn't have eq or inventory here, but hey...
for (l = 0; l < MAX_WEAR; l++)
if (EQ(ch, l) || ch->carrying)
{
sprintf(buf, "SYSERR: Ejected char had equipment/inventory (%s).", GET_NAME(ch));
mudlog(buf, BRF, LEV_IMM, TRUE);
break;
}
// shouldn't be fighting, but just in case...
if (FIGHTING(ch))
stop_fighting(ch);
for (k = combat_list; k ; k = temp)
{
temp = k->next_fighting;
if (FIGHTING(k) == ch)
stop_fighting(k);
}
// remove any song affects and set room affects by this char to NULL
if (IS_PC(ch))
{
if (SINGING(ch))
remove_song_from_world(ch, SINGING(ch));
if (PLAYING(ch))
remove_song_from_world(ch, PLAYING(ch));
}
null_char_room_affects(ch);
/* in case they's a shaman and they be in a rite */
DELAY_TYPE(ch) = CHAR_FLAGS(ch) = 0;
char_from_room(ch);
// yank character from list now
REMOVE_FROM_LIST(ch, character_list, next);
if (IS_PC(ch))
save_char(ch, NOWHERE);
else
if (IS_NPC(ch))
{
if (GET_MOB_RNUM(ch) > -1)
mob_index[GET_MOB_RNUM(ch)].number--;
clearMemory(ch);
}
free_char(ch); /* note, ch is invalid after this call */
return CHAR_DIED;
}
/* ***********************************************************************
Here follows high-level versions of some earlier routines, ie functions
which incorporate the actual player-data.
*********************************************************************** */
// Changed this to allow 0.<name> for PCs and add "me" and "self" support
// ala Circle 3.0... 03/22/98 -callahan
CharData *get_char_room_vis(CharData *ch, char *name)
{
CharData *i;
int j = 0, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp = tmpname;
if (IN_NOWHERE(ch))
return (NULL);
if (!str_cmp(name, "self") || !str_cmp(name, "me"))
return ch;
// 0.<name> means PC with name
str_cpy(tmp, name, MAX_INPUT_LENGTH, "get_char_room_vis");
if (!(number = get_number(&tmp)))
return get_player_vis(ch, tmp, TRUE);
for (i = Adjacents(ch); i && j <= number; i = i->next_in_room)
if (isname(tmp, PName(i)))
if (can_see(ch, i))
if (++j == number)
return i;
return NULL;
}
// Added int inroom check so 0.playername only works within a room.
// 03/22/98 -callahan
chdata *get_player_vis(chdata *ch, char *name, int inroom)
{
chdata *i;
for (i = character_list; i; i = i->next)
if (IS_PC(i) && !str_cmp(i->player.name, name) && can_see(ch, i) &&
(!inroom || (InRoom(ch) == InRoom(i))))
return i;
return 0;
}
chdata *get_char_zone_vis(chdata *ch, char *name)
{
chdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
/* check location */
if ((i = get_char_room_vis(ch, name)))
return(i);
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_char_zone_vis");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
for (i = character_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->player.name) && can_see(ch, i) && !INVALID_ROOM(i->in_room) &&
world[i->in_room].zone == world[ch->in_room].zone)
{
if (j == number)
return(i);
j++;
}
return(0);
}
chdata *get_char_zone(int zone, char *name)
{
chdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_char_zone");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
for (i = character_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->player.name) && !INVALID_ROOM(i->in_room) &&
world[i->in_room].zone == zone)
{
if (j == number)
return(i);
j++;
}
return(0);
}
chdata *get_char_vis(chdata *ch, char *name)
{
chdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
/* check location */
if ((i = get_char_room_vis(ch, name)))
return(i);
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_char_vis");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
for (i = character_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->player.name) && can_see(ch, i))
{
if (j == number)
return(i);
j++;
}
return(0);
}
obdata *get_obj_in_list_vis(chdata *ch, char *name, obdata *list)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj_in_list_vis");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
for (i = list, j = 1; i && (j <= number); i = i->next_content)
if (isname(tmp, i->name))
if (CAN_SEE_OBJ(ch, i)) {
if (j == number)
return(i);
j++;
}
return(0);
}
// same as get_obj_vis, but with a zone check
obdata *get_obj_zone_vis(chdata *ch, char *name)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
/* scan room */
if ((i = get_obj_in_list_vis(ch, name, world[ch->in_room].contents)))
return(i);
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj_zone_vis");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
/* ok.. no luck yet. scan the entire obj list */
for (i = object_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->name))
if (CAN_SEE_OBJ(ch, i) && !INVALID_ROOM(i->in_room) &&
world[i->in_room].zone == world[ch->in_room].zone)
{
if (j == number)
return(i);
j++;
}
return(0);
}
obdata *get_object_zone(int zone, char *name)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj_zone");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
for (i = object_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->name))
if (!INVALID_ROOM(i->in_room) && world[i->in_room].zone == zone)
{
if (j == number)
return(i);
j++;
}
return NULL;
}
/*search the entire world for an object, and return a pointer */
obdata *get_obj_vis(chdata *ch, char *name)
{
obdata *i;
int j, number;
char tmpname[MAX_INPUT_LENGTH];
char *tmp;
/* scan items carried */
if ((i = get_obj_in_list_vis(ch, name, ch->carrying)))
return(i);
/* scan room */
if ((i = get_obj_in_list_vis(ch, name, world[ch->in_room].contents)))
return(i);
str_cpy(tmpname, name, MAX_INPUT_LENGTH, "get_obj_vis");
tmp = tmpname;
if (!(number = get_number(&tmp)))
return(0);
/* ok.. no luck yet. scan the entire obj list */
for (i = object_list, j = 1; i && (j <= number); i = i->next)
if (isname(tmp, i->name))
if (CAN_SEE_OBJ(ch, i)) {
if (j == number)
return(i);
j++;
}
return(0);
}
obdata *get_object_in_equip_vis(chdata *ch, char *arg, obdata *equipment[], int *j)
{
for ((*j) = 0; (*j) < MAX_WEAR ; (*j)++)
if (equipment[(*j)])
if (CAN_SEE_OBJ(ch, equipment[(*j)]))
if (isname(arg, equipment[(*j)]->name))
return(equipment[(*j)]);
return (0);
}
// no longer create an exdesc on money objs, now use obj ldesc 11/28/97 -jtrhone
obdata *create_money(int amount)
{
char buf[200];
obdata *obj;
if (amount <= 0)
{
log("SYSERR: Try to create negative or 0 currency.");
exit(1);
}
CREATE(obj, obdata, 1);
clear_object(obj);
if (amount == 1)
{
sprintf(buf, "%s %s", currency_name, currency_name_plural);
obj->name = str_dup(buf);
sprintf(buf, "a %s", currency_name);
obj->shdesc = str_dup(buf);
sprintf(buf, "One miserable %s is lying here.", currency_name);
obj->description = str_dup(buf);
sprintf(buf, "One miserable %s.", currency_name);
obj->actdesc = str_dup(buf);
}
else
{
sprintf(buf, "%s %s", currency_name_plural, currency_name);
obj->name = str_dup(buf);
if (amount <= 100)
{
sprintf(buf, "a small pile of %s", currency_name_plural);
obj->shdesc = str_dup(buf);
sprintf(buf, "A small pile of %s is lying here.", currency_name_plural);
obj->description = str_dup(buf);
} else if (amount <= 1000) {
sprintf(buf, "a pile of %s", currency_name_plural);
obj->shdesc = str_dup(buf);
sprintf(buf, "A pile of %s is lying here.", currency_name_plural);
obj->description = str_dup(buf);
} else if (amount <= 25000) {
sprintf(buf, "a large heap of %s", currency_name_plural);
obj->shdesc = str_dup(buf);
sprintf(buf, "A large heap of %s is lying here.", currency_name_plural);
obj->description = str_dup(buf);
} else if (amount <= 500000) {
sprintf(buf, "a huge mound of %s", currency_name_plural);
obj->shdesc = str_dup(buf);
sprintf(buf, "A huge mound of %s is lying here.", currency_name_plural);
obj->description = str_dup(buf);
} else {
sprintf(buf, "an enormous mountain of %s", currency_name_plural);
obj->shdesc = str_dup(buf);
sprintf(buf, "An enormous mountain of %s is lying here.", currency_name_plural);
obj->description = str_dup(buf);
}
if (amount < 10) {
sprintf(buf, "There are %d %s.", amount, currency_name_plural);
obj->actdesc = str_dup(buf);
} else if (amount < 100) {
sprintf(buf, "There are about %d %s.", 10 * (amount / 10), currency_name_plural);
obj->actdesc = str_dup(buf);
} else if (amount < 1000) {
sprintf(buf, "There looks to be about %d %s.", 100 * (amount / 100), currency_name_plural);
obj->actdesc = str_dup(buf);
} else if (amount < 100000) {
sprintf(buf, "You guess there are, maybe, %d %s.",
1000 * ((amount / 1000) + number(0, (amount / 1000))), currency_name_plural);
obj->actdesc = str_dup(buf);
}
else
{
sprintf(buf, "There are a LOT of %s.", currency_name_plural);
obj->actdesc = str_dup(buf);
}
}
obj->type_flag = ITEM_MONEY;
OBJ_WEARS(obj) = ITEM_TAKE;
obj->value[0] = amount;
obj->cost = amount;
obj->item_number = -1;
obj->next = object_list;
object_list = obj;
return(obj);
}
/* Generic Find, designed to find any object/character */
/* Calling : */
/* *arg is the sting containing the string to be searched for. */
/* This string doesn't have to be a single word, the routine */
/* extracts the next word itself. */
/* bitv.. All those bits that you want to "search through". */
/* Bit found will be result of the function */
/* *ch This is the person that is trying to "find" */
/* **tar_ch Will be NULL if no character was found, otherwise points */
/* **tar_obj Will be NULL if no object was found, otherwise points */
/* */
/* The routine returns a pointer to the next word in *arg (just like the */
/* one_argument routine). */
int generic_find(char *arg, int bitvector, chdata *ch, chdata **tar_ch,
obdata **tar_obj)
{
static char *ignore[] = {
"the",
"in",
"on",
"at",
"\n"
};
int i;
char name[256];
BOOL found = FALSE;
/* Eliminate spaces and "ignore" words */
while (*arg && !found) {
for (; *arg == ' '; arg++)
;
for (i = 0; (name[i] = *(arg + i)) && (name[i] != ' '); i++)
;
name[i] = 0;
arg += i;
if (search_block(name, ignore, TRUE) > -1)
found = TRUE;
}
if (!name[0])
return(0);
*tar_ch = 0;
*tar_obj = 0;
if (IS_SET(bitvector, FIND_CHAR_ROOM)) { /* Find person in room */
if ((*tar_ch = get_char_room_vis(ch, name))) {
return(FIND_CHAR_ROOM);
}
}
if (IS_SET(bitvector, FIND_CHAR_WORLD)) {
if ((*tar_ch = get_char_vis(ch, name))) {
return(FIND_CHAR_WORLD);
}
}
if (IS_SET(bitvector, FIND_OBJ_EQUIP))
{
for (found = FALSE, i = 0; i < MAX_WEAR && !found; i++)
if (EQ(ch, i) && isname(name, EQ(ch, i)->name))
{
*tar_obj = EQ(ch, i);
found = TRUE;
}
if (found)
return(FIND_OBJ_EQUIP);
}
if (IS_SET(bitvector, FIND_OBJ_INV)) {
if ((*tar_obj = get_obj_in_list_vis(ch, name, ch->carrying))) {
return(FIND_OBJ_INV);
}
}
if (IS_SET(bitvector, FIND_OBJ_ROOM)) {
if ((*tar_obj = get_obj_in_list_vis(ch, name, world[ch->in_room].contents))) {
return(FIND_OBJ_ROOM);
}
}
if (IS_SET(bitvector, FIND_OBJ_WORLD)) {
if ((*tar_obj = get_obj_vis(ch, name))) {
return(FIND_OBJ_WORLD);
}
}
return(0);
}
/* a function to scan for "all" or "all.x" */
int find_all_dots(char *arg)
{
if (!str_cmp(arg, "all"))
return FIND_ALL;
else if (!strncmp(arg, "all.", 4)) {
strcpy(arg, arg+4);
return FIND_ALLDOT;
} else
return FIND_INDIV;
}
// Function to manipulate multiple objects. 08/10/98 -callahan
int ManyObjs(char *arg, char *ptr)
{
int amount = 0;
char buff[MAX_INPUT_LENGTH];
buff[0] = 0;
sscanf(arg, "%d*%s", &amount, buff);
if (buff[0] == '\0')
return 0;
if (amount < 1)
return 0;
if (amount > 20)
amount = 20;
while (*arg != '*')
arg++;
arg++;
for (; (*ptr = *arg); arg++, ptr++);
return amount;
}