// $Id: command3.cc,v 1.24.2.27 2000/06/27 05:54:09 greear Exp $
// $Revision: 1.24.2.27 $ $Author: greear $ $Date: 2000/06/27 05:54:09 $
//
//ScryMUD Server Code
//Copyright (C) 1998 Ben Greear
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// To contact the Author, Ben Greear: greear@cyberhighway.net, (preferred)
// greearb@agcs.com
//
///********************** command3.cc ****************************///
#include "commands.h"
#include "command2.h"
#include "command3.h"
#include "command4.h"
#include "misc.h"
#include "misc2.h"
#include <stdio.h>
#include "classes.h"
#include "battle.h"
#include "spec_prc.h"
#include "spells.h"
#include "skills.h"
#include "command5.h"
#include <PtrArray.h>
#include "load_wld.h"
// Logs things generated by the 'bug' or 'typo' command.
ofstream bug_log("./log/bug_log");
int use(int i_th, String* wand_name, int j_th, String* target,
critter& pc) { //for wands
critter* targ;
object* wand = NULL;
String buf(100);
if (mudlog.ofLevel(DBG)) {
mudlog << __FUNCTION__ << " i_th: " << i_th << " target -:"
<< *target << ":-" << endl;
}
if (!ok_to_do_action(NULL, "mSNFP", 0, pc)) {
return -1;
}//if
if (ROOM.isNoWand()) {
show("This room is not conducive to the use of your wand.\n", pc);
return -1;
}//if
/* check if holding wand, has charges ect */
int cnt = 0;
int i;
for (i = 0; i<MAX_EQ; i++) {
if (pc.EQ[i]) { //if holding ANY object
if (pc.EQ[i]->isNamed(*wand_name)) {
cnt++;
if (cnt == i_th) {
wand = pc.EQ[i];
break;
}//if
}//if
}//if
}//for
if (!wand) {
if (pc.EQ[10]) {
if (pc.EQ[10]->OBJ_FLAGS.get(51) &&
pc.EQ[10]->obj_proc) { //if a wand
i = 10;
wand = pc.EQ[i];
}//if
}//if
if (!wand && pc.EQ[9]) {
if (pc.EQ[9]->OBJ_FLAGS.get(51) &&
pc.EQ[9]->obj_proc) { //if a wand
i = 9;
wand = pc.EQ[i];
}//if
}//if
}//if
if (!wand) {
show("You must be holding a wand in your hands in order to use it.\n",
pc);
return -1;
}//if
if (wand->CHARGES <= 0) {
Sprintf(buf, "Your %S seems quite devoid of energies.\n",
single_obj_name(*wand, pc.SEE_BIT));
show(buf, pc);
return -1;
}//if
if (!(wand->OBJ_FLAGS.get(51) && wand->obj_proc)) {
pc.show("That is not a wand!\n");
return -1;
}
if (!wand->IN_LIST) {
pc.EQ[i] = wand = obj_to_sobj(*(pc.EQ[i]), &(pc.inv), pc.getCurRoomNum());
}//if
/* wand is ready, check for target */
Sprintf(buf, "You clench %S and try to remember how to trigger it.\n",
long_name_of_obj(*wand, pc.SEE_BIT));
show(buf, pc);
short found_proc = TRUE;
short do_dec = FALSE;
Cell<stat_spell_cell*> cll(wand->obj_proc->casts_these_spells);
stat_spell_cell* ptr;
// Take care of case where they didn't specify a wand.
if (target->Strlen() == 0) {
*target = *wand_name;
}
while ((ptr = cll.next())) {
switch (ptr->stat_spell)
{
//First, those requiring a MOB for target
case 1: case 10: case 11: case 30:
case 38: case 39: case 136: case 139: case 140:
case 151: case 152: case 155: case 160:
case 162: case 163: case 164: case 171:
case 172: case 174: case 175: case 176:
case 177: case 178: case 179: case 180: case 189:
case 191: case 192: case 193: case 194: case 195: case 197:
case 199: case 201: case 202: case 203: case 204:
case 205: case 206: case 208: case 217: case 219:
case 221: case 222: case 224: case 225: case 226:
case 227: case 228: case 233:
{
found_proc = TRUE;
if (target->Strlen() == 0) {
targ = Top(pc.IS_FIGHTING);
}//if
else {
targ = ROOM.haveCritNamed(j_th, target, pc.SEE_BIT);
}//else
if (targ) {
if (targ->isMob()) { //if its a MOB
targ = mob_to_smob(*targ, pc.getCurRoomNum(), TRUE, j_th,
target, pc.SEE_BIT);
}//if
}//if
if (!targ) {
pc.show("Use it on who?\n");
//targ = &pc;
}
else {
do_dec = TRUE;
do_wand_scroll_proc(targ, ptr->stat_spell, pc, ptr->bonus_duration);
}
break;
}//case for mob targets
// now for doors
case 21: case 181: case 6:
{
door* dr_ptr;
if ((dr_ptr = door::findDoor(ROOM.DOORS, j_th, target,
pc.SEE_BIT, ROOM))) {
if (dr_ptr->isSecret()) {
if (!name_is_secret(target, *dr_ptr)) {
show("You don't see that exit.\n", pc);
return -1;
}//if
}//if
do_wand_scroll_proc(dr_ptr, ptr->stat_spell, pc,
ptr->bonus_duration);
do_dec = TRUE;
}//if
else {
pc.show("You need to specify a door on which to use your scroll.\n");
}//else
break;
}//door case statement
// spells requiring no target
case 12:
case 22: case 25: case 145: case 146:
case 147: case 149: case 150: case 153: case 200:
case 210: case 211: case 218:
// spells requiring room targs, always use current room
case 4: case 14: case 17: case 18: case 20:
case 198: case 215: case 220:
{
do_wand_scroll_proc(ptr->stat_spell, pc,
ptr->bonus_duration);
do_dec = TRUE;
break;
}//case
case 159: //special case, gate spell (portal too?)
{
targ = have_crit_named(pc_list, j_th, target, pc.SEE_BIT,
ROOM);
if (!targ) {
show("That person isn't logged on.\n", pc);
}//if
else {
do_wand_scroll_proc(targ, ptr->stat_spell, pc,
ptr->bonus_duration);
do_dec = TRUE;
}
break;
}
//object targets
case 124: case 156:
case 165: case 182: case 183: case 184: case 185:
case 186: case 196: case 213:
{
object* ob_ptr;
ob_ptr = have_obj_named(pc.inv, j_th, target,
pc.SEE_BIT, ROOM);
if (ob_ptr) {
if (!ob_ptr->IN_LIST) {
ob_ptr = obj_to_sobj(*ob_ptr, &(pc.inv), TRUE,
j_th, target, pc.SEE_BIT, ROOM);
}
}
else {
ob_ptr = ROOM.haveObjNamed(j_th, target, pc.SEE_BIT);
if (ob_ptr && !ob_ptr->IN_LIST) {
ob_ptr = obj_to_sobj(*ob_ptr, ROOM.getInv(), TRUE,
j_th, target, pc.SEE_BIT, ROOM);
}
}//else
if (ob_ptr) {
pc.show("Which object shall the scroll be used on?\n");
}
else {
do_wand_scroll_proc(ob_ptr, ptr->stat_spell, pc,
ptr->bonus_duration);
do_dec = TRUE;
}
break;
}//case
default:
{
mudlog << "ERROR: found default case in use (wand), spell_num: "
<< ptr->stat_spell << " on object#: "
<< wand->getIdNum() << endl;
pc.show("You call upon forces unavailable at this time!\n");
found_proc = FALSE;
}
}//switch
}//while
if (!found_proc) {
show("Nothing seems to happen.\n", pc);
Sprintf(buf, "ERROR: wand# %i has no spells defined.\n", wand->OBJ_NUM);
mudlog.log(ERROR, buf);
return -1;
}//if
if (do_dec) {
wand->CHARGES--;
}//if
return 0;
}//use
int quaff(int i_th, const String* item, critter& pc) { //for wands
object* potion = NULL;
String buf(100);
int posn = 0;
if (!ok_to_do_action(NULL, "mFP", 0, pc)) {
return -1;
}//if
if (ROOM.isNoPotion()) {
show("Open potions are not allowed here!!\n", pc);
return -1;
}//if
if (item->Strlen() == 0) { //then must be holding
for (int i = 9; i<11; i++) {
if (pc.EQ[i]) { //if holding ANY object
if (pc.EQ[i]->OBJ_FLAGS.get(52)) { //if a potion
potion = pc.EQ[i];
posn = i;
break;
}//if
}//if
}//for
}//if
else {
potion = have_obj_named(pc.inv, i_th, item, pc.SEE_BIT,
ROOM);
}//if
if (!potion) {
show("Quaff what?\n", pc);
return -1;
}//if
if (!potion->isPotion()) {
show("That isn't a potion.\n", pc);
return -1;
}//if
Sprintf(buf, "You quaff %S.\n",
long_name_of_obj(*potion, pc.SEE_BIT));
show(buf, pc);
short found_proc = TRUE;
Cell<stat_spell_cell*> cll(potion->CASTS_THESE_SPELLS);
stat_spell_cell* ptr;
while ((ptr = cll.next())) {
switch (ptr->stat_spell)
{
//First, those requiring a MOB for target
case 1: case 10: case 11: case 30:
case 38: case 39: case 136: case 139: case 140:
case 151: case 152: case 155: case 160:
case 162: case 163: case 164: case 171:
case 172: case 174: case 175: case 176:
case 177: case 178: case 179: case 180: case 188: case 189:
case 191: case 192: case 193: case 195: case 197:
case 199: case 201: case 202: case 203: case 204:
case 205: case 206: case 208: case 217: case 219:
case 221: case 222: case 224: case 225: case 226:
case 227: case 228:
{
do_wand_scroll_proc(&pc, ptr->stat_spell, pc, ptr->bonus_duration);
break;
}//case for mob targets
// spells requiring no target
case 12:
case 22: case 25: case 145: case 146:
case 147: case 149: case 150: case 153: case 200:
case 210: case 211: case 218:
// spells requiring room targs, always use current room
case 4: case 14: case 17: case 18: case 20:
case 159: case 198: case 215: case 220:
{
do_wand_scroll_proc(ptr->stat_spell, pc, ptr->bonus_duration);
break;
}//case
default:
{
mudlog << "ERROR: found default case in quaff, spell_num: "
<< ptr->stat_spell << " on object#: "
<< potion->getIdNum() << endl;
pc.show("You call upon forces unavailable at this time!\n");
found_proc = FALSE;
}
}//switch
}//while
if (!found_proc) {
show("You feel slightly refreshed!\n", pc);
Sprintf(buf, "ERROR: item# %i casts no spells (quaff)\n",
potion->OBJ_NUM);
mudlog.log(ERROR, buf);
}//if
if (posn) {
if (pc.EQ[posn]->IN_LIST) { //if a SOBJ
delete pc.EQ[posn];
}//if
pc.EQ[posn] = NULL;
}//if
else {
pc.loseInv(potion);
if (potion->IN_LIST) {
delete potion;
potion = NULL;
}//if
}//else
if (found_proc)
return 0;
return -1;
}//quaf
int recite(int i_th, const String* item, int j_th, const String* vict,
critter& pc) { //for scrolls
critter* targ = NULL;
object* scroll = NULL;
String buf(100);
short posn = 0;
int junk_scroll = FALSE;
if (!ok_to_do_action(NULL, "mSNPF", -1, pc)) {
return -1;
}//if
/* check if holding scroll */
for (int i = 9; i<11; i++) {
if (pc.EQ[i]) { //if holding ANY object
if (pc.EQ[i]->OBJ_FLAGS.get(53) &&
pc.EQ[i]->obj_proc) { //if a scroll
if (obj_is_named(*(pc.EQ[i]), *item)) {
if (detect(pc.SEE_BIT,
pc.EQ[i]->OBJ_VIS_BIT & ROOM.getVisBit())) {
scroll = pc.EQ[i];
posn = i;
break;
}//if
}//if
}//if
}//if
}//while
if (!scroll) {
scroll = have_obj_named(pc.inv, i_th, item, pc.SEE_BIT, ROOM);
}//else
if (!scroll) {
show("Recite what??\n", pc);
return -1;
}//if
if (!scroll->obj_proc) {
mudlog << "ERROR: Scroll: " << scroll
<< " does not have an obj_proc, scroll# " << scroll->getIdNum()
<< nl;
pc.show("Looks like a bug, please tell an imm about that scroll.\n");
return -1;
}
Sprintf(buf, "You unroll %S and begin to read...\n",
long_name_of_obj(*scroll, pc.SEE_BIT));
show(buf, pc);
short found_proc = TRUE;
Cell<stat_spell_cell*> cll(scroll->CASTS_THESE_SPELLS);
stat_spell_cell* ptr;
while ((ptr = cll.next())) {
if (mudlog.ofLevel(DBG)) {
mudlog << "In while loop, spell: " << ptr->toString() << endl;
}
switch (ptr->stat_spell)
{
//First, those requiring a MOB for target
case 1: case 10: case 11: case 30:
case 38: case 39: case 136: case 139: case 140:
case 151: case 152: case 155: case 160:
case 162: case 163: case 164: case 171:
case 172: case 174: case 175: case 176:
case 177: case 178: case 179: case 180: case 189:
case 191: case 192: case 193: case 194: case 195: case 197:
case 199: case 201: case 202: case 203: case 204:
case 205: case 206: case 208: case 217: case 219:
case 221: case 222: case 224: case 225: case 226:
case 227: case 228:
{
mudlog.dbg("Requires mob for target.\n");
found_proc = TRUE;
if (vict->Strlen() == 0) {
targ = Top(pc.IS_FIGHTING);
}//if
else {
targ = ROOM.haveCritNamed(j_th, vict, pc.SEE_BIT);
}//else
if (targ) {
if (targ->isMob()) { //if its a MOB
targ = mob_to_smob(*targ, pc.getCurRoomNum(), TRUE, j_th,
vict, pc.SEE_BIT);
}//if
}//if
if (!targ) {
targ = &pc;
}
if (do_wand_scroll_proc(targ, ptr->stat_spell, pc,
ptr->bonus_duration) >= 0) {
junk_scroll = TRUE;
}
break;
}//case for mob targets
case 159: //special case, gate spell (portal too?)
{
mudlog.dbg("gate/portal case.\n");
targ = have_crit_named(pc_list, j_th, vict, pc.SEE_BIT,
ROOM);
if (!targ) {
show("That person isn't logged on.\n", pc);
}//if
else {
if (do_wand_scroll_proc(targ, ptr->stat_spell, pc,
ptr->bonus_duration) >= 0) {
junk_scroll = TRUE;
}
}
break;
}
// now for doors
case 21: case 181: case 6:
{
mudlog.dbg("Doors case.\n");
door* dr_ptr;
if ((dr_ptr = door::findDoor(ROOM.DOORS, j_th, vict,
pc.SEE_BIT, ROOM))) {
if (dr_ptr->isSecret()) {
if (!name_is_secret(vict, *dr_ptr)) {
show("You don't see that exit.\n", pc);
return -1;
}//if
}//if
if (do_wand_scroll_proc(dr_ptr, ptr->stat_spell, pc,
ptr->bonus_duration) >= 0) {
junk_scroll = TRUE;
}
}//if
else {
pc.show("You need to specify a door on which to use your scroll.\n");
}//else
break;
}//door case statement
// spells requiring no target
case 12:
case 22: case 25: case 145: case 146:
case 147: case 149: case 150: case 153: case 200:
case 210: case 211: case 218:
// spells requiring room targs, always use current room
case 4: case 14: case 17: case 18: case 20:
case 198: case 215: case 220:
{
mudlog.dbg("No target needed.\n");
if (do_wand_scroll_proc(ptr->stat_spell, pc,
ptr->bonus_duration) >= 0) {
junk_scroll = TRUE;
}
break;
}//case
//object targets
case 124: case 156:
case 165: case 182: case 183: case 184: case 185:
case 186: case 196: case 213:
{
mudlog.dbg("Object for target...\n");
object* ob_ptr;
ob_ptr = have_obj_named(pc.inv, j_th, vict,
pc.SEE_BIT, ROOM);
if (ob_ptr) {
if (!ob_ptr->IN_LIST) {
ob_ptr = obj_to_sobj(*ob_ptr, &(pc.inv), TRUE,
j_th, vict, pc.SEE_BIT, ROOM);
}
}
else {
ob_ptr = ROOM.haveObjNamed(j_th, vict, pc.SEE_BIT);
if (ob_ptr && !ob_ptr->IN_LIST) {
ob_ptr = obj_to_sobj(*ob_ptr, ROOM.getInv(), TRUE,
j_th, vict, pc.SEE_BIT, ROOM);
}
}//else
if (!ob_ptr) {
pc.show("Which object shall the scroll be used on?\n");
}
else {
if (do_wand_scroll_proc(ob_ptr, ptr->stat_spell, pc,
ptr->bonus_duration) >= 0) {
junk_scroll = TRUE;
}
}
break;
}//case
default:
{
mudlog << "ERROR: found default case in recite, spell_num: "
<< ptr->stat_spell << " on object#: "
<< scroll->getIdNum() << endl;
pc.show("You call upon forces unavailable at this time!\n");
found_proc = FALSE;
}
}//switch
}//while
if (!found_proc) {
show("Nothing seems to happen.\n", pc);
Sprintf(buf, "ERROR: object# %i has no spells in recite.\n",
scroll->OBJ_NUM);
mudlog.log(ERROR, buf);
}//if
if (junk_scroll) {
if (posn) {
recursive_init_unload(obj_list[pc.EQ[posn]->OBJ_NUM], 0);
if (pc.EQ[posn]->IN_LIST) { //if a SOBJ
delete pc.EQ[posn];
}//if
pc.EQ[posn] = NULL;
}//if
else {
pc.loseInv(scroll);
recursive_init_unload(*scroll, 0);
if (scroll->IN_LIST) {
delete scroll;
}//if
}//else
}//if should get rid of it
if (found_proc)
return 0;
return -1;
}//recite
ofstream idea_log("./log/idea_log");
int idea(const String& str, critter& pc) {
String buf(300);
if (!pc.isPc()) {
return -1;
}
if (str.Strlen() == 0) {
show("Usage: idea <text of idea>.\n", pc);
return -1;
}//if
Sprintf(buf, "%S %S, room %i: %S\n\n", &(getCurTime()), name_of_crit(pc, ~0),
pc.getCurRoomNum(), &str);
idea_log << buf << flush;
bl_ideas.addBug(getCurTime(), pc.getCurRoomNum(), *(pc.getName()), str);
show("Idea logged, thanks a heap.\n", pc);
return 0;
}//idea
int bug(String& str, critter& pc) {
String buf(300);
if (!pc.isPc()) {
return -1;
}
if (str.Strlen() == 0) {
show("Usage: bug <text of bug description>.\n", pc);
return -1;
}//if
parse_for_max_80(str);
Sprintf(buf, "%S %S, room %i: %S\n\n", &(getCurTime()), name_of_crit(pc, ~0),
pc.getCurRoomNum(), &str);
bug_log << buf << flush;
bl_bugs.addBug(getCurTime(), pc.getCurRoomNum(), *(pc.getName()), str);
show("Bug logged, thanks.\n", pc);
return 0;
}//bug
/** Uses:
* buglist # List all bugs in all states.
* buglist [state] # Lists bugs in that state.
* buglist stat [bug#] # List a particular bug
* buglist chstate [bug#] [new state] # Change the state of a bug.
* buglist assign [new assignee] # Assign someone to be responsible.
* buglist comment [bug#] # Puts you into a state in which
* # you can add a comment to the bug.
* buglist purge [bug#] # Remove a bug from the list entirely.
*/
int buglist(BugTypeE bt, int i, String& cmd, int j, const String& mod,
const String& notes, critter& pc) {
if (!pc.isPc()) {
i = notes.Strlen(); //using notes here stops compiler warnings.
return -1;
}
if ((cmd.Strlen() == 0) ||
(strcasecmp(cmd, "open") == 0) ||
(strcasecmp(cmd, "closed") == 0) ||
(strcasecmp(cmd, "assigned") == 0) ||
(strcasecmp(cmd, "retest") == 0) ||
(strcasecmp(cmd, "all") == 0)) {
// Default now is open
if (cmd.Strlen() == 0) {
cmd = "open";
}
else if (strcasecmp(cmd, "all") == 0) {
cmd = "";
}
if (bt == BT_BUGS) {
pc.show("Bug Listing:\n");
pc.show(bl_bugs.toStringBrief(cmd)); // FALSE == No Hegemon Tagging
}
else if (bt == BT_IDEAS) {
pc.show("Idea Listing:\n");
pc.show(bl_ideas.toStringBrief(cmd));
}
return 0;
}//if just want a listing
if (strncasecmp(cmd, "chstate", cmd.Strlen()) == 0) {
if (bt == BT_BUGS) {
if (bl_bugs.changeState(j, mod, pc.getImmLevel(),
*(pc.getName())) < 0) {
pc.show("Could not make that state transition.\n");
return -1;
}
else {
pc.show("State transition for bug accomplished.\n");
return 0;
}
}
else if (bt == BT_IDEAS) {
if (bl_ideas.changeState(j, mod, pc.getImmLevel(), *(pc.getName())) < 0) {
pc.show("Could not make that state transition.\n");
return -1;
}
else {
pc.show("State transition for idea accomplished.\n");
return 0;
}
}
}
else if (strncasecmp(cmd, "purge", cmd.Strlen()) == 0) {
if (pc.getImmLevel() < 9) {
pc.show("You must be level 9 IMMORT or higher to purge bug/idea postings.\n");
return -1;
}
if (bt == BT_BUGS) {
if (bl_bugs.purgeBug(j) < 0) {
pc.show("Could not purge that bug.\n");
return -1;
}
else {
pc.show("Purged the bug from the listing.\n");
return 0;
}
}
else if (bt == BT_IDEAS) {
if (bl_ideas.purgeBug(j) < 0) {
pc.show("Could not purge that idea.\n");
return -1;
}
else {
pc.show("Purged the idea from the listing.\n");
return 0;
}
}
}
else if (strncasecmp("comment", cmd, cmd.Strlen()) == 0) {
if (bt == BT_BUGS) {
if (bl_bugs.canComment(j, pc.getImmLevel(), *(pc.getName()))) {
pc.show("Enter text for your description. Terminate with a ~\n");
pc.show("on a line BY ITSELF.\n");
pc.pc->bug_num = j;
pc.pc->bug_comment = "";
pc.setMode(MODE_ADD_BUG_COMMENT);
return 0;
}
else {
pc.show("You can't add a comment to that bug.\n");
return 0;
}
}
else if (bt == BT_IDEAS) {
if (bl_ideas.canComment(j, pc.getImmLevel(), *(pc.getName()))) {
pc.show("Enter text for your description. Terminate with a ~\n");
pc.show("on a line BY ITSELF.\n");
pc.pc->bug_num = j;
pc.pc->bug_comment = "";
pc.setMode(MODE_ADD_IDEA_COMMENT);
return 0;
}
else {
pc.show("You can't add a comment to that idea.\n");
return 0;
}
}
}//comment
else if (strncasecmp("assign", cmd, cmd.Strlen()) == 0) {
if (bt == BT_BUGS) {
if (bl_bugs.reAssign(j, mod, pc.getImmLevel(), *(pc.getName())) < 0) {
pc.show("Could not re-assign that bug.\n");
return -1;
}
else {
pc.show("Bug re-assigned.\n");
return 0;
}
}
else if (bt == BT_IDEAS) {
if (bl_ideas.reAssign(j, mod, pc.getImmLevel(), *(pc.getName())) < 0) {
pc.show("Could not re-assign that idea.\n");
return -1;
}
else {
pc.show("Idea re-assigned.\n");
return 0;
}
}
}//if assign
else if (strncasecmp("stat", cmd, cmd.Strlen()) == 0) {
BugEntry* be;
const char* ct;
if (bt == BT_BUGS) {
be = bl_bugs.getBugEntry(j);
ct = bl_bugs.getColTypeName();
}
else {
be = bl_ideas.getBugEntry(j);
ct = bl_ideas.getColTypeName();
}
if (be) {
if (pc.isUsingClient()) {
pc.show(be->toStringHeg(ct));
}
pc.show(be->toString());
return 0;
}//if
else {
pc.show("Could not find that bug in the buglist.\n");
return -1;
}
}//if assign
pc.show("Bug/Idea list command not recognized, see help for buglist.\n");
return -1;
}//buglist
int do_add_idea_comment(critter& pc) {
return do_add_comment(BT_IDEAS, pc);
}//do_add_idea_comment
int do_add_bug_comment(critter& pc) {
return do_add_comment(BT_BUGS, pc);
}//do_add_idea_comment
int do_add_comment(BugTypeE bt, critter& pc) {
String buf = pc.pc->input.Get_Rest();
while (TRUE) {
if (buf.Strlen() == 0) {
return 0;
}//if
if (buf == "~") {
show("Comment added.\n", pc);
pc.setMode(MODE_NORMAL);
parse_for_max_80(pc.pc->bug_comment);
CommentEntry re(getCurTime(), *(pc.getName()), pc.pc->bug_comment);
if (bt == BT_BUGS) {
bl_bugs.addComment(pc.pc->bug_num, re, pc.getImmLevel(),
*(pc.getName()));
}
else if (bt == BT_IDEAS) {
bl_ideas.addComment(pc.pc->bug_num, re, pc.getImmLevel(),
*(pc.getName()));
}
pc.pc->bug_comment = "";
return 0;
}//if
pc.pc->bug_comment += buf; //append the line to desc
pc.pc->bug_comment += "\n";
buf = pc.pc->input.Get_Rest();
}//while
return 0;
}//do_add_comment
int oclone(int i_th, const String* item, critter& pc) {
String buf(100);
object* obj_ptr;
if (!ok_to_do_action(NULL, "IFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (item->Strlen() == 0) {
if (check_l_range(i_th, 0, NUMBER_OF_ITEMS, pc, TRUE)) {
obj_ptr = &(obj_list[i_th]);
if (!obj_ptr->OBJ_FLAGS.get(10)) {
show("That object has not been defined yet.\n", pc);
return -1;
}//if
}//if
else {
return -1;
}//else
}//if
else {
obj_ptr = have_obj_named(pc.inv, i_th, item, pc.SEE_BIT,
ROOM);
if (!obj_ptr) {
obj_ptr = ROOM.haveObjNamed(i_th, item, pc.SEE_BIT);
}//if
}//else
if (!obj_ptr) {
show("You don't see that object.\n", pc);
}//if
else { //got one!
int new_obj = get_next_obj();
if (!check_l_range(new_obj, 2, NUMBER_OF_ITEMS, pc, FALSE)) {
show("OOPS, seems the object database is FULL, talk at your IMP.\n",
pc);
return -1;
}//if
if ((pc.getImmLevel() <= 4) && !pc.doesOwnObject(*obj_ptr)) {
pc.show("You don't own that object, must be level 5 or greater.\n");
return -1;
}
obj_list[new_obj] = obj_list[obj_ptr->OBJ_NUM];
Sprintf(buf, "CLONE OF: %S.", Top(obj_ptr->names));
obj_list[new_obj].in_room_desc = buf;
obj_list[new_obj].short_desc = buf;
obj_list[new_obj].OBJ_NUM = new_obj;
obj_list[new_obj].cur_stats[3] = ROOM.getZoneNum();
obj_list[new_obj].IN_LIST = NULL;
pc.gainInv(&(obj_list[new_obj]));
}//else
show("Okay, CLONE of object now in your inventory.\n", pc);
return 0;
}//oclone
int sacrifice(const String* cmd, critter& pc) {
String buf(100);
if (pc.EXP < (levels[30] - 1)) {
pc.show("You need more experience in order to sacrifice.\n");
return -1;
}
pc.show("NOTE: Only equipment in inventory counts.\n");
int do_it = FALSE;
if (strcasecmp(*cmd, "DO_IT") == 0) {
do_it = TRUE;
pc.show("Doing a true sacrifice.\n");
}
else {
pc.show("Calculating current sacrifice amount.\n");
}
// Now, make them sacrifice a certain amount of equipment!
// Currently, +100 to any/all stats. No duplicates allowed.
List<object*> sac_list;
Cell<object*> cll(pc.getInv());
object* ptr;
int total = 0;
while ((ptr = cll.next())) {
total += ptr->getSacPoints(sac_list, 0);
}
if (do_it) {
if (total >= config.sacPointsNeeded) {
//clear out all inventory
while (!pc.getInv().isEmpty()) {
ptr = pc.getInv().popFront();
drop_eq_effects(*ptr, pc, FALSE);
recursive_init_unload(*ptr, 0);
if (ptr->isModified()) {
delete ptr;
}
}//while
pc.show("You have successfully sacrificed, you may now become a re-mort.\n");
pc.setHasSacrificed(TRUE);
}//if there was enough
else {
pc.show("You need more points in order to sacrifice.\n");
return -1;
}
}//if
else {
Sprintf(buf, "You have %i of %i points needed to sacrifice. If you\n",
total, config.sacPointsNeeded);
pc.show(buf);
pc.show("really want to sacrifice, use the: 'sacrifice DO_IT' command.\n");
pc.show("NOTE: YOU WILL LOSE ALL OF YOUR CURRENT INVENTORY if you SACRIFICE!!!\n");
}//else
return 0;
}//sacrifice
int remort(int i_th, const String* v, const String* new_race,
const String* new_class, critter& pc) {
String buf(100);
if (pc.isImmort() && (pc.getImmLevel() >= 9)) {
if (pc.isFrozen()) {
show("You are too frozen to do anything.\n", pc);
return -1;
}//if
critter* vict = ROOM.haveCritNamed(i_th, v, pc);
if (!vict) {
pc.show("Remort who??\n");
return -1;
}
if (vict->EXP < (levels[30] - 1)) {
pc.show("That person doesn't have enough experience.\n");
return -1;
}
if (!vict->hasSacrificed()) {
pc.show("That person has not 'sacrificed' yet.\n");
return -1;
}
for (int i = 1; i<MAX_EQ; i++) {
if (vict->eq[i]) {
pc.show("The mortal must not be wearing anything.\n");
return -1;
}//if
}//for
if (!vict->getInv().isEmpty()) {
pc.show("The mortal must have NO inventory.\n");
return -1;
}
if (vict->isRemort()) { //may do a new race
int race = get_race_num(*new_race);
switch (race) {
case HUMAN: case ANITRE: case AVINTRE: case DARKLING: case DROW:
case DRAGON: case DWARF: case IRONCLAD: case OGRUE: case ROCKTROLL:
case ELF: case FAERIE: case ENTITY: case SOMBRIAN: {
if (race == vict->getRace()) {
pc.show("INFO: That person is already of that race, continuing.\n");
}
vict->setRace(race);
Sprintf(buf, "Your race has been changed to: %S.\n", new_race);
vict->show(buf);
Sprintf(buf, "%S's race has been changed to: %S.\n",
vict->getName(pc), new_race);
pc.show(buf);
break;
}
default: {
pc.show("That race is unknown.\n");
return -1;
}
}//switch
}//if already a remort
int cls = get_class_num(*new_class);
switch (cls) {
case WARRIOR: case SAGE: case WIZARD: case RANGER: case THIEF: case ALCHEMIST:
case CLERIC: case BARD: {
if (vict->getClass() == cls) {
pc.show("INFO: That person is already that class, continuing.\n");
}
else {
vict->setClass(cls);
}
break;
}//
default: {
pc.show("That class is unknown.\n");
return -1;
}
}//switch
// Ok then, lets re-set the mana/HP/MOV levels.
vict->setHP_MAX(30);
vict->setManaMax(100);
vict->setMovMax(100);
vict->setLevel(1);
vict->setHasSacrificed(FALSE); //used that one up!!
vict->setIsRemort(TRUE);
vict->EXP = 1;
// Make sure they have the right base skills
switch (vict->getClass()) {
case WARRIOR:
vict->SKILLS_KNOWN.Insert(WEAPON_MASTERY_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHYSICAL_ARTS_SKILL_NUM, 25);
break;
case SAGE:
vict->SKILLS_KNOWN.Insert(HERBALISM_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHILOSOPHY_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(BLACKSMITHING_SKILL_NUM, 10);
break;
case WIZARD:
vict->SKILLS_KNOWN.Insert(LITERACY_SKILL_NUM, 10);
vict->SKILLS_KNOWN.Insert(CHANNELLING_SKILL_NUM, 10);
break;
case RANGER:
vict->SKILLS_KNOWN.Insert(FORESTRY_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHYSICAL_ARTS_SKILL_NUM, 25);
break;
case THIEF:
vict->SKILLS_KNOWN.Insert(ACROBATICS_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHYSICAL_ARTS_SKILL_NUM, 10);
break;
case BARD:
vict->SKILLS_KNOWN.Insert(HONOR_CODE_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHYSICAL_ARTS_SKILL_NUM, 10);
break;
case CLERIC:
vict->SKILLS_KNOWN.Insert(PHILOSOPHY_SKILL_NUM, 25);
vict->SKILLS_KNOWN.Insert(PHYSIK_SKILL_NUM, 25);
break;
default: {
mudlog.log(ERROR, "ERROR: In default of class modifiers in remort.\n");
break;
}
}//switch
vict->SKILLS_KNOWN.Insert(TAMMUZ_SKILL_NUM, 1);
// Now, re-set all skills to 25% if they are higher than that.
int key;
int retval = 0;
if (vict->SKILLS_KNOWN.Min(key)) {
vict->SKILLS_KNOWN.Find(key, retval);
vict->SKILLS_KNOWN.Insert(key, min(retval, 25));
while (vict->SKILLS_KNOWN.Next(key)) {
vict->SKILLS_KNOWN.Find(key, retval);
vict->SKILLS_KNOWN.Insert(key, min(retval, 25));
}//while
}//if
pc.show("Remort process completed. You can now give the player +3 (TOTAL)\n");
pc.show("to whatever stat(s) they desire.\n");
vict->show("Remort process completed. You can now chose how to spend your\n");
vict->show("+3 (TOTAL) stat bonuses. They can be added to: STRength,\n");
vict->show("INTeligence, DEXterity, or CHArisma.\n");
}//if an immort of high level
else {
show("Eh??\n", pc);
return -1;
}//if
return 0;
}//remort
int oload(int i_th, const String* item, critter& pc) {
object* obj_ptr;
// mudlog.log(TRC, "In oclone.\n");
if (pc.isImmort() || (pc.isSmob() && !pc.isCharmed())) {
if (pc.isFrozen()) {
show("You are too frozen to do anything.\n", pc);
return -1;
}//if
if (item->Strlen() == 0) {
if (check_l_range(i_th, 0, NUMBER_OF_ITEMS, pc, TRUE)) {
obj_ptr = &(obj_list[i_th]);
if (!obj_ptr->OBJ_FLAGS.get(10)) {
show("That object has not been defined yet.\n", pc);
return -1;
}//if
}//if
else {
return -1;
}//else
}//if
else {
obj_ptr = have_obj_named(pc.inv, i_th, item, pc.SEE_BIT,
ROOM);
if (!obj_ptr) {
obj_ptr = ROOM.haveObjNamed(i_th, item, pc.SEE_BIT);
}//if
}//else
if (!obj_ptr) {
show("You don't see that object.\n", pc);
}//if
else { //got one!
if (pc.isPc() && (pc.getImmLevel() <= 4) && !pc.doesOwnObject(*obj_ptr)) {
pc.show("You don't own that object, must be level 5 or greater.\n");
return -1;
}
if (!obj_ptr->isBulletinBoard()) {
recursive_init_loads(*obj_ptr, 0);
}
else {
obj_ptr->incrementCurInGame();
}
pc.gainInv(&(obj_list[obj_ptr->OBJ_NUM]));
}//else
show("Okay, loaded object now in your inventory.\n", pc);
}//if
else {
show("Eh??\n", pc);
return -1;
}//if
return 0;
}//oload
int rclone(int src_room, const String* direction, int dist, critter& pc) {
//mudlog.log(TRC, "In rclone.\n");
dist--;
if (!check_l_range(dist, -3, 10, pc, FALSE)) {
show("The distance must be between -3 and 10.\n", pc);
return -1;
}//if
if (!ok_to_do_action(NULL, "RIFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (direction->Strlen() == 0) {
show("Usage: rclone <room_number> <direction>\n", pc);
return -1;
}//if
int zone_num = ROOM.getZoneNum();
room* new_rm = get_next_room(zone_num);
if (!new_rm) {
show("Ack, there are no more available room slots in this zone.\n",
pc);
return -1;
}//if
int new_room_num = new_rm->getIdNum();
if (mudlog.ofLevel(DBG))
mudlog << "Rclone: New room num: " << new_room_num << endl;
if (src_room == 1) {
src_room = ROOM.getIdNum();
}
if (!check_l_range(src_room, 1, NUMBER_OF_ROOMS, pc, TRUE))
return -1;
if (room_list[src_room].isVehicle()) {
pc.show("Vehicle cloning not supported at this time.");
return -1;
}
if (!room_list[src_room].isInUse()) {
pc.show("Source room is not in use!\n");
return -1;
}
if ((pc.getImmLevel() <= 4) && !pc.doesOwnRoom(room_list[src_room])) {
pc.show("You don't own that room, must be level 5 or greater.\n");
return -1;
}
*new_rm = room_list[src_room];
// We coppied over it when assigning it...
new_rm->setRoomNum(new_room_num);
clear_ptr_list(new_rm->doors); //don't want to start w/any doors
clear_ptr_list(new_rm->keywords); //or keywords
if (mudlog.ofLevel(DBG))
mudlog << "Rclone: New room num, before door_to: "
<< new_room_num << endl;
door_to(new_room_num, dist, direction, pc);
return 0;
}//rclone
int rinit(int src_rm, int dest_rm, critter& pc) {
//mudlog.log(TRC, "In rclone.\n");
if (dest_rm == 1) {
dest_rm = src_rm;
src_rm = ROOM.getIdNum();
}
if (!check_l_range(dest_rm, 2, NUMBER_OF_ROOMS, pc, TRUE)) {
return -1;
}//if
if (!check_l_range(src_rm, 2, NUMBER_OF_ROOMS, pc, TRUE)) {
return -1;
}//if
if (!ok_to_do_action(NULL, "IFPR", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
int dest_z = room_list[dest_rm].getZoneNum();
int z = ROOM.getZoneNum();
if (z != dest_z) {
pc.show("Your destinatio room must be in this zone.\n");
return -1;
}
if (room_list[dest_rm].isInUse()) {
pc.show("That room is already in use, maybe you want rclear?\n");
return -1;
}
if (!room_list[src_rm].isInUse()) {
pc.show("Source room is not in use!\n");
return -1;
}
if (room_list[src_rm].isVehicle()) {
pc.show("Can't init with a vehicle as a source.\n");
return -1;
}
room_list[dest_rm] = room_list[src_rm];
room_list[dest_rm].setRoomNum(dest_rm); //just in case
clear_ptr_list(room_list[dest_rm].DOORS);//don't want to start w/any doors
return 0;
}//rinit
int mclone(int i_th, const String* item, critter& pc) {
critter* crit_ptr;
String buf(100);
if (!ok_to_do_action(NULL, "RIFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (item->Strlen() == 0) {
if (check_l_range(i_th, 0, NUMBER_OF_MOBS, pc, TRUE)) {
crit_ptr = &(mob_list[i_th]);
if (!crit_ptr->isInUse()) {
show("That mobile has not been defined yet.\n", pc);
return -1;
}//if
}//if
else {
return -1;
}//else
}//if
else {
crit_ptr = ROOM.haveCritNamed(i_th, item, pc.SEE_BIT);
}//else
if (!crit_ptr) {
show("You don't see that person.\n", pc);
return -1;
}//if
if (crit_ptr->pc || !crit_ptr->mob) {
show("You can't clone a pc.\n", pc);
return -1;
}//if
if ((pc.getImmLevel() <= 4) && !pc.doesOwnCritter(*crit_ptr)) {
pc.show("You don't own that mobile, must be level 5 or greater.\n");
return -1;
}
/* do it then */
int new_num = get_next_mob();
if (!check_l_range(new_num, 2, NUMBER_OF_MOBS, pc, FALSE)) {
show("OOPS, seems we are out of room in the database, tell an IMP!\n",
pc);
return -1;
}//if
mob_list[new_num] = mob_list[crit_ptr->MOB_NUM]; //make a copy
Sprintf(buf, "CLONE OF: %S.", Top(crit_ptr->names));
mob_list[new_num].in_room_desc = buf;
mob_list[new_num].short_desc = buf;
mob_list[new_num].setIdNum(new_num);
mob_list[new_num].setNativeZoneNum(ROOM.getZoneNum());
mob_list[new_num].CRITTER_TYPE = 2;
ROOM.gainCritter(&(mob_list[new_num]));
show("Okay, critter CLONED, its now in your room.\n", pc);
return 0;
}//mclone
int mload(int i_th, const String* item, critter& pc) {
critter* crit_ptr;
if (!ok_to_do_action(NULL, "IFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (item->Strlen() == 0) {
if (check_l_range(i_th, 0, NUMBER_OF_MOBS, pc, TRUE)) {
crit_ptr = &(mob_list[i_th]);
if (!crit_ptr->CRIT_FLAGS.get(18)) {
show("That mobile has not been defined yet.\n", pc);
return -1;
}//if
}//if
else {
return -1;
}//else
}//if
else {
crit_ptr = ROOM.haveCritNamed(i_th, item, pc.SEE_BIT);
}//else
if (!crit_ptr) {
show("You don't see that person.\n", pc);
return -1;
}//if
if (crit_ptr->pc || !crit_ptr->mob) {
show("You can't load a pc.\n", pc);
return -1;
}//if
if (pc.isPc() && ((pc.getImmLevel() <= 4) && !pc.doesOwnCritter(*crit_ptr)) ||
(pc.isPc() && (pc.getImmLevel() < 8) && !pc.doesOwnRoom(ROOM))) {
pc.show("You don't own that critter, or this room, must be level 5\n");
pc.show("or level 8 if you don't even own the room.\n");
return -1;
}
/* do it then */
if (crit_ptr->isPlayerShopKeeper()) {
critter* shop_keeper = load_player_shop_owner(crit_ptr->getIdNum());
if (shop_keeper) {
ROOM.gainCritter(shop_keeper);
}//if
}//if
else {
ROOM.gainCritter(&(mob_list[crit_ptr->getIdNum()]));
}
recursive_init_loads(*crit_ptr);
show("Okay, critter LOADED in this room.\n", pc);
return 0;
}//mload
int wield(int i_th, const String* item, critter& pc) {
String buf("wield");
return wear(i_th, item, 1, &buf, pc);
}//wield
int hold(int i_th, const String* item, critter& pc) {
String buf("hold");
return wear(i_th, item, 1, &buf, pc);
}//hold
int light(int i_th, const String* item, critter& pc) {
String buf("light");
return wear(i_th, item, 1, &buf, pc);
}//hold
int flee_to_safety(critter& pc, int& is_dead) {
/* this is a semi-inteligent flee used by mobs to escape aggressors */
/* it attempts to escape to havens, !magic, or rough terrain */
if (!ok_to_do_action(NULL, "mFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
Cell<door*> cll(ROOM.DOORS);
door* ptr;
while ((ptr = cll.next())) {
if (room_list[abs(ptr->destination)].isHaven() || //haven
room_list[abs(ptr->destination)].isNoMagic() || //!magic
room_list[abs(ptr->destination)].isSwamp()) { //swamp
/* quit battle */
Cell<critter*> cll(pc.IS_FIGHTING);
critter* tmp_ptr;
while ((tmp_ptr = cll.next())) {
tmp_ptr->IS_FIGHTING.loseData(&pc);
}//while
pc.IS_FIGHTING.clear();
if (move(pc, 1, *(direction_of_door(*ptr)), TRUE, ROOM, is_dead) >= 0) {
return 0;
}//if
else {
return flee(pc, is_dead);
}//else
}//if
}//while
return flee(pc, is_dead); //any is as good as the rest
}//flee_to_safety
int flee(critter& pc, int& is_dead) {
int flee_chance;
critter* crit_ptr;
String buf(100);
short have_exit = FALSE;
door* dr_ptr = NULL;
door* valid_dr_ptr = NULL;
// mudlog.log(TRC, "In flee.\n");
if (!ok_to_do_action(NULL, "mFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (pc.POS != POS_STAND) { //if not standing
show("You can't flee sitting on your butt!\n", pc);
}//if
else { //lets try it
if ((crit_ptr = Top(pc.IS_FIGHTING))) { //ie in battle
if (crit_ptr->mob) { //if its a mob
if (crit_ptr->MOB_FLAGS.get(1) && (d(1,100) > 12)) { //if !flee
Sprintf(buf, "%S prevents you from fleeing.\n",
name_of_crit(*crit_ptr, pc.SEE_BIT));
buf.Cap();
show(buf, pc);
Sprintf(buf, "prevents %S from fleeing!!\n",
name_of_crit(pc, ~0));
emote(buf, *crit_ptr, ROOM, TRUE, &pc);
pc.PAUSE += 1;
return -1;
}//if
}//if
flee_chance = pc.DEX * 5 + ROOM.doors.size() * 3;
if (flee_chance > d(1,100)) { //will try at least
Cell<door*> dr_cll(ROOM.doors);
while ((dr_ptr = dr_cll.next())) {
if (!(dr_ptr->isClosed())) {
valid_dr_ptr = dr_ptr;
have_exit = TRUE;
break;
}//if
}//while
if (!have_exit) {
show("Death may be your only exit!\n", pc);
pc.PAUSE += 1;
return -1;
}//if
/* now move pc outa room */
/* quit battle */
Cell<critter*> cll(pc.IS_FIGHTING);
critter* tmp_ptr;
while ((tmp_ptr = cll.next())) {
tmp_ptr->IS_FIGHTING.loseData(&pc);
}//while
pc.IS_FIGHTING.clear();
/* we know we have an exit, lets find it */
int sanity = 0;
while (TRUE) {
if (sanity++ > 20) {
dr_ptr = valid_dr_ptr;
break;
}
if ((dr_ptr = door::findDoor(ROOM.doors, 1,
Top(door_list[d(1,10)].names), ~0, ROOM))) {
if (dr_ptr->isOpen()) {
break; //weee hoooo, found a good one!
}//if
}//if
}//while
show("You try to flee the scene!\n", pc);
Sprintf(buf, "tries to flee %S!",
direction_of_door(*dr_ptr));
emote(buf, pc, ROOM, FALSE);
if (pc.isUsingClient()) {
pc.show("</BATTLE>");
}
else if (pc.isUsingColor()) {
pc.show(*(pc.getDefaultColor()));
}
move(pc, 1, *(direction_of_door(*dr_ptr)), FALSE, ROOM, is_dead);
if (is_dead)
return 0;
pc.PAUSE += 1;
pc.MOV -= 25;
return 0;
}//if
else { //didn't even beat the odds...
show("You can't elude your foe.\n", pc);
pc.PAUSE += 1;
}//else
}//if in battle
else {
Cell<door*> dr_cll(ROOM.doors);
while ((dr_ptr = dr_cll.next())) {
if (!(dr_ptr->dr_data->door_data_flags.get(2))) {
have_exit = TRUE;
valid_dr_ptr = dr_ptr;
break;
}//if
}//while
if (!have_exit) {
show("You can't find an exit.\n", pc);
}//if
else {
int sanity = 0;
while (TRUE) {
if (sanity++ > 20) {
dr_ptr = valid_dr_ptr;
break;
}
if ((dr_ptr = door::findDoor(ROOM.doors, 1,
Top(door_list[d(1,10)].names), ~0, ROOM))) {
if (!(dr_ptr->dr_data->door_data_flags.get(2))) {
break; //weee hoooo, found a good one!
}//if
}//if
}//while
show("You try to flee the scene!\n", pc);
Sprintf(buf, "tries to flee %S!",
direction_of_door(*dr_ptr));
emote(buf, pc, ROOM, FALSE);
move(pc, 1, *(Top(dr_ptr->dr_data->names)), FALSE, ROOM, is_dead);
if (is_dead)
return 0;
pc.PAUSE += 1;
pc.MOV -= 25;
return 0;
}//else
}//else, not in battle
}//else, past little checks
return 0;
}//flee
int slay(int i_th, const String* vict, critter& pc) {
String buf(100);
critter* ptr;
if (!ok_to_do_action(NULL, "IFV", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
ptr = ROOM.haveCritNamed(i_th, vict, pc.SEE_BIT);
if (!ptr) {
show("You detect not that being.\n", pc);
return -1;
}//if
if (ptr->isMob()) {
ptr = mob_to_smob(*ptr, pc.getCurRoomNum(), TRUE, i_th, vict, pc.SEE_BIT);
}//if
if (ptr->pc && ptr->pc->imm_data &&
(ptr->IMM_LEVEL > pc.IMM_LEVEL)) {
show("RESPECT THY ELDERS!!\n", pc);
pc.setHP(1); //that'll teach em!!
return -1;
}//if
Sprintf(buf, "You slay %S.\n", name_of_crit(*ptr, pc.SEE_BIT));
show(buf, pc);
Sprintf(buf, "%S slays you!!\n", name_of_crit(pc, ptr->SEE_BIT));
show(buf, *ptr);
Sprintf(buf, "%S slays %S!\n", name_of_crit(pc, ~0),
name_of_crit(*ptr, ~0));
show_all_but_2(pc, *ptr, buf, ROOM);
agg_kills_vict(&pc, *ptr);
return 0;
}//slay
int time(critter& pc) {
if (pc.isSleeping()) {
pc.show("Time moves in funny ways when you are asleep!!\n");
return -1;
}
String buf(50);
Sprintf(buf, "It is %s.\n", military_to_am(config.hour));
show(buf, pc);
return 0;
}//time
int date(critter& pc) {
String buf(100);
Sprintf(buf, "The date is %s %i, %i.\n", get_month(config.day),
get_day_of_month(config.day), config.year);
show(buf, pc);
return 0;
}//date
int tail(int i_th, const String* vict, critter& pc, int do_smob = FALSE) {
String buf(100);
critter* ptr;
if (pc.isMob())
return -1;
if (!pc.pc && !do_smob)
return -1;
if (!ok_to_do_action(NULL, "FP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (get_percent_lrnd(TAIL_SKILL_NUM, pc) < 1) {
show("You wiggle your bottom!?!!!\n", pc);
Sprintf(buf, "wiggles %s bottom!?!!!\n", get_his_her(pc));
emote(buf, pc, ROOM, FALSE);
return -1;
}//if
if (vict->Strlen() == 0) {
ptr = &pc;
}//if
else {
ptr = ROOM.haveCritNamed(i_th, vict, pc.SEE_BIT);
}//if
if (!ptr) {
show("You can't detect that being.\n", pc);
return -1;
}//if
pc.CRIT_FLAGS.turn_on(23);
pc.doFollow(*ptr, TRUE);
return 0;
}//tail
int follow(int i_th, const String* vict, critter& pc, int do_msg = TRUE) {
critter* ptr;
String buf(100);
if (!ok_to_do_action(NULL, "mFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (vict->Strlen() == 0) {
ptr = &pc;
}//if
else {
ptr = ROOM.haveCritNamed(i_th, vict, pc);
}//if
if (!ptr) {
show("You can't detect that being.\n", pc);
return -1;
}//if
return pc.doFollow(*ptr, do_msg);
}//follow
/* pc follows vict */
int critter::doFollow(critter& vict, int do_msg = TRUE) {
String buf(100);
if (vict.isMob() || isMob()) {
mudlog.log(ERROR, "ERROR: MOB's in do_follow.\n");
return -1;
}//if
if (&vict == this) { //if follow self
if (!FOLLOWER_OF) {
show("You already follow yourself.\n");
doBecomeNonPet(); //no longer a pet
return 0;
}//if
else {
doUngroup(1, &NULL_STRING); //no longer part of a group
doBecomeNonPet(); //no longer a pet
}//else
}//if
else { //follow some other
if (vict.isInGroupWith(this)) {
show("You are already in a group with this person!\n");
return -1;
}
if (master && master!= &vict && (vict.PETS.size() < (vict.CHA/6 +1))) {
// the new owner of a pet can push him around
doBecomeNonPet();
Put(this, vict.PETS);
MASTER=&vict;
}
else if (FOLLOWER_OF) { // if possibly part of a group
doUngroup(1, &NULL_STRING); //pets will still be pets....for now
show("You are now removed from your old group.\n");
}//if
if (FOLLOWER_OF) {
FOLLOWER_OF->FOLLOWERS.loseData(this);
}
FOLLOWER_OF = NULL;
FOLLOWER_OF = &vict;
vict.FOLLOWERS.gainData(this);
if (do_msg) {
Sprintf(buf, "%S now follows you.\n", getName(vict.SEE_BIT));
buf.Cap();
vict.show(buf);
}//if do_msg
Sprintf(buf, "You now follow %S.\n", vict.getName(SEE_BIT));
show(buf);
String cmd = "follow";
getCurRoom()->checkForProc(cmd, NULL_STRING, *this, vict.MOB_NUM);
}//else, follow some other
return 0;
}//doFollow
int group(int i_th, const String* vict, critter& pc) {
Cell<critter*> cll;
critter* ptr;
String buf(100);
if (pc.isMob()) {
mudlog.log(ERROR, "ERROR: mob sent to group, needs to be a smob or pc.\n");
return -1;
}//if
if (vict->Strlen() == 0) { //display group
if (IsEmpty(pc.GROUPEES)) {
show("You are a party of one!\n", pc);
return -1;
}//if
Sprintf(buf, "Name %P30 Class%P45 Hp %P55Mana %P68Mov\n\n");
show(buf, pc);
pc.GROUPEES.head(cll);
while ((ptr = cll.next())) {
Sprintf(buf, "%S%P30 %s(%i)%P45 %i/%i %P54 %i/%i %P66 %i/%i\n",
name_of_crit(*ptr, pc.SEE_BIT), class_of_crit(*ptr),
ptr->LEVEL, ptr->HP, ptr->HP_MAX,
ptr->MANA, ptr->MA_MAX, ptr->MOV, ptr->MV_MAX);
buf.Cap();
show(buf, pc);
}//while
}//if displaying group
//******************* group all *****************************//
else if (strcasecmp("all", *vict) == 0) {
if (! pc.isGroupLeader() && !pc.GROUPEES.isEmpty()) {
show("You have to be the leader in order to enroll groupees.\n",
pc);
return -1;
}//if
if (IsEmpty(pc.FOLLOWERS)) {
show("You need followers in order to form a group!\n", pc);
return -1;
}//if
pc.GROUPEES.gainData(&pc); //enroll self fer sure
pc.FOLLOWERS.head(cll);
while ((ptr = cll.next())) {
if (ptr->isTailing() || pc.isNoHassle()) {
Sprintf(buf, "Attempt to group you by %S failed because you are tailing or !hassle.\n",
ptr->getName());
ptr->show(buf);
continue; //fail silently
}//if !hassle or tailing, can't be grouped
if (! ptr->GROUPEES.isEmpty()) {
Sprintf(buf, "You can't enroll %S because they are already in a group.\n", ptr->getName(pc));
pc.show(buf);
}
else {
if (! pc.GROUPEES.haveData(ptr)) {
pc.GROUPEES.gainData(ptr);
show("You are now part of the group.\n", *ptr);
Sprintf(buf, "%S is now part of the group.\n", ptr->getName(pc));
buf.Cap();
show(buf, pc);
pc.makeGroupSane();
String cmd = "group";
ROOM.checkForProc(cmd, NULL_STRING, pc, ptr->MOB_NUM);
}
}
}//while
}// if group all
//***************** group an individual ************************//
else { //group some individual
if (! pc.isGroupLeader() && !pc.GROUPEES.isEmpty()) {
show("You have to be the leader in order to enroll groupees.\n", pc);
return -1;
}//if
ptr = have_crit_named(pc.FOLLOWERS, i_th, vict, pc.SEE_BIT, ROOM);
if (!ptr) {
show("That person is not following you.\n", pc);
return -1;
}//
if (pc.GROUPEES.haveData(ptr)) {
Sprintf(buf, "%S is already in your group.\n", ptr->getName());
buf.Cap();
pc.show(buf);
return 0;
}
pc.GROUPEES.gainData(&pc); //make sure self is in
pc.GROUPEES.gainData(ptr);
show("You are now part of the group.\n", *ptr);
Sprintf(buf, "%S joins your group.\n", ptr->getName());
buf.Cap();
pc.show(buf);
pc.makeGroupSane();
String cmd = "group";
ROOM.checkForProc(cmd, NULL_STRING, pc, ptr->MOB_NUM);
}//else
return 0;
}//group
/* some parsing is done by this function */
int order(String* str, critter& pc) {
Cell<critter*> cll;
critter* ptr;
short eos = FALSE, term_by_period = FALSE;
String str1, str2;
String name, buf(100);
int i = 1;
if (!ok_to_do_action(NULL, "mrFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
str1 = str->Get_Command(eos, term_by_period);
if (str1.Strlen() != 0) {
if (isnum(str1)) {
i = atoi(str1);
name = str->Get_Command(eos, term_by_period);
}//if
else {
if (strncasecmp(str1, "followers", str1.Strlen()) == 0) {
i = -1;
}//if
else {
name = str1;
}//else
}//else
if (str->Strlen() == 0) {
show("Order them to do what??\n", pc);
return -1;
}//if
if (i == -1) { //if order fol <cmd_string>
if (IsEmpty(pc.PETS)) {
show("But, you have no pets!\n", pc);
return -1;
}//if
List<critter*> tmp_lst;
ROOM.getPetsFor(pc, tmp_lst);
if (mudlog.ofLevel(DBG)) {
mudlog << "order: tmp_list.size(): " << tmp_lst.size() << endl;
}
/* this list will be static, the other can change according to what
the mob was ordered to do */
tmp_lst.head(cll);
while ((ptr = cll.next())) {
if (ROOM.haveCritter(ptr)) {
String tmp(*str); //Must pass in a copy, it will be modified.
ptr->processInput(tmp, TRUE, FALSE, NULL, NULL, TRUE);
}//if
else {
if (mudlog.ofLevel(DBG)) {
mudlog << "ROOM didn't have critter." << endl;
}
}//else
}//while
pc.show(CS_OK);
}//if
else {
ptr = ROOM.haveCritNamed(i, &name, pc.SEE_BIT);
if (ptr) {
if (HaveData(ptr, pc.PETS)) {
String cmd = "order";
ROOM.checkForProc(cmd, *str, pc, ptr->MOB_NUM);
ptr->processInput(*str, TRUE, FALSE, NULL, NULL, TRUE);
show("Ok.\n", pc);
}//if
else {
Sprintf(buf, "%S looks at you and smirks at your suggestion.\n",
name_of_crit(*ptr, pc.SEE_BIT));
buf.Cap();
show(buf, pc);
}//else
}//if ptr
else {
show("You don't see that person here.\n", pc);
}//else
}//else, order <targ> <cmd_string>
}//if valid string gotten
else {
show("Order who to do what???\n", pc);
return -1;
}//else
return 0;
}//order
/* some parsing is done by this function */
int force(String* str, critter& pc) {
critter* ptr;
short eos = FALSE, term_by_period = FALSE;
String str1, str2;
String name, buf(100);
int i = 1;
if (!pc.isImmort()) {
// I'll give you a hint: Little dude with pointy ears living in
// a swamp!! --BLG
show("He knew there was another, but you are not the one!\n", pc);
return -1;
}//if
if (!ok_to_do_action(NULL, "FP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
str1 = str->Get_Command(eos, term_by_period);
if (str1.Strlen() != 0) {
if (isnum(str1)) {
i = atoi(str1);
name = str->Get_Command(eos, term_by_period);
}//if
else {
name = str1;
}//else
if (str->Strlen() == 0) {
show("Force them to do what??\n", pc);
return -1;
}//if
ptr = have_crit_named(pc_list, i, &name, pc.SEE_BIT, ROOM);
if (!ptr) {
ptr = have_crit_named(linkdead_list, i, &name,
pc.SEE_BIT, ROOM);
}//if
if (!ptr) {
ptr = ROOM.haveCritNamed(i, &name, pc.SEE_BIT);
}//if
if (ptr) {
if (ptr->isMob()) {
ptr = mob_to_smob(*ptr, pc.getCurRoomNum(), TRUE, i, &name, pc.SEE_BIT);
}//if
if ((pc.IMM_LEVEL < 5) && (!pc.doesOwnCritter(*ptr))) {
show("You are not yet worthy of the force.\n", pc);
return -1;
}//if
if (ptr->pc && ptr->pc->imm_data &&
ptr->IMM_LEVEL >= pc.IMM_LEVEL) {
show("Heh, don't you WISH you could force them!!\n", pc);
return -1;
}//if
Sprintf(buf, "%S has forced you to: %S\n",
name_of_crit(pc, ptr->SEE_BIT), str);
show(buf, *ptr);
ptr->processInput(*str, TRUE, TRUE);
show("Ok\n", pc);
}//if
else {
show("That person is neither playing nor linkdead, or not\n", pc);
show("visible to you.\n", pc);
}//else
}//if valid string gotten
else {
show("Force who to do what???\n", pc);
return -1;
}//else
return 0;
}//force
/* some parsing is done by this function */
int force_all(String* str, critter& pc) {
critter* ptr;
String buf(100);
mudlog.log(TRC, "In force_all.\n");
if (!ok_to_do_action(NULL, "IFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (pc.IMM_LEVEL < 5) {
show("You are not yet worthy of the force.\n", pc);
return -1;
}//if
if (str->Strlen() == 0) {
show("Force all to do what??\n", pc);
return -1;
}//if
if (mudlog.ofLevel(DBG)) {
mudlog << "Passed tests in force_all, str: " << *str << endl;
}
Cell<critter*> cll(pc_list);
while ((ptr = cll.next())) {
if (ptr->MODE == MODE_NORMAL) {
if (!(ptr->pc->imm_data && (ptr->IMM_LEVEL >= pc.IMM_LEVEL))) {
Sprintf(buf, "%S has forced you to: %S\n",
name_of_crit(pc, ptr->SEE_BIT), str);
show(buf, *ptr);
ptr->processInput(*str, FALSE, TRUE);
}//if
}//if in normal mode
}//while
show("Ok\n", pc);
return 0;
}//force_all
int enslave(int i_th, const String* vict, critter& pc) {
critter* ptr;
String buf(100);
if(pc.isPc() || (pc.isSmob() && pc.isCharmed())) {
if (!ok_to_do_action(NULL, "IFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
}
ptr = ROOM.haveCritNamed(i_th, vict, pc.SEE_BIT);
if (!ptr) {
show("You can't detect that being.\n", pc);
return -1;
}//if
///******************* have a valid ptr now ***********************///
if (ptr->isMob()) {
ptr = mob_to_smob(*ptr, pc.getCurRoomNum(), TRUE, i_th, vict,
pc.SEE_BIT);
}//if
if (ptr->pc && ptr->pc->imm_data) { //if vict is an IMM
if (ptr->IMM_LEVEL >= pc.IMM_LEVEL) {
show("You cannot enslave one so powerful, fool!!\n", pc);
pc.PAUSE += 10;
return -1;
}//if
}//if
Put(ptr, pc.PETS);
ptr->MASTER = &pc;
ptr->doFollow(pc);
return 0;
}//enslave
int do_tell(critter& pc, const char* message, critter& targ,
short show_teller, int targs_room_num) {
targs_room_num = targs_room_num; // get rid of un-used variable warning
if (pc.isSleeping() || pc.isParalyzed()) {
pc.show("You mutter in your unconcious state...\n");
return -1;
}
else if (targ.isSleeping() || (targ.pc && (targ.getMode() != MODE_NORMAL))) {
pc.show("They can't hear you right now.\n");
return -1;
}
String buf(200);
String msg;
msg = message;
if (msg.Strlen() == 0) {
pc.show(CS_SAY_WHAT);
return -1;
}
pc.drunkifyMsg(msg);
String tag;
String untag;
if (targ.isUsingClient()) {
tag = "<TELL>";
untag = "</TELL>";
}
else if (targ.isUsingColor()) {
tag = *(targ.getTellColor());
untag = *(targ.getDefaultColor());
}
Sprintf(buf, "%S%S tells you, '%S'\n%S",
&tag, name_of_crit(pc, targ.SEE_BIT), &msg, &untag);
buf.setCharAt(tag.Strlen(), toupper(buf[tag.Strlen()]));
show(buf, targ);
if (targ.pc) {
targ.pc->rep_to = *(name_of_crit(pc, targ.SEE_BIT));
}
if (show_teller) {
if (pc.isUsingClient()) {
tag = "<TELL>";
untag = "</TELL>";
}
else if (pc.isUsingColor()) {
tag = *(pc.getTellColor());
untag = *(pc.getDefaultColor());
}
else {
tag = "";
untag = "";
}
Sprintf(buf, "%SYou tell %S, '%S'\n%S",
&tag, name_of_crit(targ, pc.SEE_BIT), &msg, &untag);
show(buf, pc);
}//if
String cmd = "tell";
String mmsg = msg;
ROOM.checkForProc(cmd, mmsg, pc, targ.MOB_NUM);
return 0;
}//do_tell
int showZones(critter& pc) {
if (pc.isImmort()) {
pc.show(ZoneList::instance().toString());
return 0;
}
else {
pc.show("Eh?\n");
return -1;
}
}//showZones
// to active zones.
int addZone(int i, critter& pc) {
if (check_l_range(i, 0, NUMBER_OF_ZONES, pc, TRUE)) {
if (pc.isImmort() && (pc.getImmLevel() > 8)) {
ZoneList::instance().add(i);
ZoneList::instance().writeSelf();
ZoneCollection::instance().zunlock(i);
pc.show("Ok.\n");
return 0;
}
else {
pc.show("Eh??\n");
}
}
return -1;
}//addZone
// from active zones
int remZone(int i, critter& pc) {
if (pc.isImmort() && (pc.getImmLevel() > 8)) {
if ((i == 1) && (pc.getCurZoneNum() != 1)) {
pc.show("You have to be in zone 1 to remove it.\n");
return -1;
}
ZoneList::instance().remove(i);
ZoneList::instance().writeSelf();
ZoneCollection::instance().zlock(i);
pc.show("Ok.\n");
return 0;
}
else {
pc.show("Eh??\n");
}
return -1;
}
int junk(int i_th, const String* str1, const String* str2, critter& pc) {
return do_junk(TRUE, i_th, str1, str2, pc);
}
int silent_junk(int i_th, const String* str1, const String* str2,
critter& pc) {
if (pc.isPc() && !pc.isImmort()) {
pc.show("Eh??");
return -1;
}
else {
return do_junk(FALSE, i_th, str1, str2, pc);
}
}//silent_junk
int do_junk(int do_msg, int i_th, const String* str1,
const String* str2, critter& pc) {
String buf(100);
String targ;
Cell<object*> cll(pc.inv);
object* obj_ptr;
short did_msg = FALSE;
if (!ok_to_do_action(NULL, "FP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if ((*str1 == "all") && (str2->Strlen() == 0)) {
show("If you want to junk EVERYTHING, go to a dump.\n", pc);
return -1;
}//if
/* check for junk all.roadkill */
if ((*str1 == "all") && (str2->Strlen() != 0)) {
targ = *str2;
i_th = -1;
}//if
else if (i_th == -1) {
targ = *str1;
}//if
if (i_th == -1) {
//mudlog.log(TRC, "i_th is/was -1.\n");
obj_ptr = cll.next();
while(obj_ptr) {
if (detect(pc.SEE_BIT, obj_ptr->OBJ_VIS_BIT)) {
if (obj_is_named(*obj_ptr, targ)) {
did_msg = TRUE;
if (obj_ptr->OBJ_FLAGS.get(5) && !(pc.pc &&
pc.pc->imm_data && (pc.IMM_LEVEL > 1))) {
if (do_msg) {
Sprintf(buf, "You can't junk %S.\n",
long_name_of_obj(*obj_ptr,
pc.SEE_BIT));
show(buf, pc);
}//if
obj_ptr = cll.next();
}//if
else { //can junk
drop_eq_effects(*obj_ptr, pc, FALSE, TRUE);
if (do_msg) {
Sprintf(buf, "You junk %S.\n",
&(obj_ptr->short_desc));
show(buf, pc);
}//if
pc.GOLD += obj_ptr->PRICE / 50;
recursive_init_unload(*obj_ptr, 0);
if (obj_list[obj_ptr->OBJ_NUM].getCurInGame() < 0) {
if (mudlog.ofLevel(DBG)) {
mudlog << "ERROR: junk: obj_cur_in_game: "
<< obj_list[obj_ptr->OBJ_NUM].getCurInGame()
<< " object_number: " << obj_ptr->OBJ_NUM
<< endl;
}
obj_list[obj_ptr->OBJ_NUM].setCurInGame(0);
}//if
if (obj_ptr->isModified()) {
delete obj_ptr;
}//if is a SOBJ
obj_ptr = pc.inv.lose(cll);
}//else
}// if obj is named...
else {
obj_ptr = cll.next();
}//else
}//if can detect
else {
obj_ptr = cll.next();
}//else
}//while
if (!did_msg) {
show("You don't have anything like that.\n", pc);
}//if
else {
show("The gods reward you.\n", pc);
}//else
}//if
else {
obj_ptr = have_obj_named(pc.inv, i_th, str1, pc.SEE_BIT, ROOM);
if (!obj_ptr) {
show("You don't have that.\n", pc);
}//if
else {
if (obj_ptr->OBJ_FLAGS.get(5) && !(pc.pc &&
pc.pc->imm_data && pc.IMM_LEVEL > 1)) {
if (do_msg) {
Sprintf(buf, "You can't junk %S.\n", name_of_obj(*obj_ptr,
pc.SEE_BIT));
show(buf, pc);
}//if
}//if
else {
drop_eq_effects(*obj_ptr, pc, FALSE, TRUE);
pc.loseInv(obj_ptr);
if (do_msg) {
Sprintf(buf, "You junk %S.\n",
&(obj_ptr->short_desc));
show(buf, pc);
show("The gods reward you for your sacrifice.\n", pc);
}//if
pc.GOLD += ((obj_ptr->PRICE / 50) + 1);
if (!obj_ptr->isBulletinBoard()) {
recursive_init_unload(*obj_ptr, 0);
}
else {
obj_ptr->decrementCurInGame();
}
if (obj_list[obj_ptr->OBJ_NUM].getCurInGame() < 0) {
if (mudlog.ofLevel(DBG)) {
mudlog << "ERROR: jnk(), obj_cur_in_game: "
<< obj_list[obj_ptr->OBJ_NUM].getCurInGame()
<< " object_num: " << obj_ptr->OBJ_NUM << endl;
}
obj_list[obj_ptr->OBJ_NUM].setCurInGame(0);
}//if
if (obj_ptr->isModified()) {
delete obj_ptr;
}//if is a SOBJ
}//else
}//else
}//else, not junk all.sumpin
return 0;
}//do_junk
int tell(int i_th, const String* targ, const char* msg, critter& pc) {
critter* crit_ptr;
int count = 0, z;
if (i_th > 100) {
show("I won't search above 100, too many cycles.\n", pc);
return 0;
}//if
if (!ok_to_do_action(NULL, "GFP", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
if (i_th == 1) {
crit_ptr = have_crit_named(pc_list, i_th, targ,
pc.SEE_BIT, ROOM);
if (crit_ptr) {
do_tell(pc, msg, *crit_ptr, TRUE, crit_ptr->getCurRoomNum());
return 0;
}//if
}//if
// Only can tell mobs in your own zone
int begin = ZoneCollection::instance().elementAt(pc.getCurZoneNum()).getBeginRoomNum();
int end = ZoneCollection::instance().elementAt(pc.getCurZoneNum()).getEndRoomNum();
for (int i = begin; i<=end; i++) {
z = 1;
if (room_list.elementAtNoCreate(i)) {
while ((crit_ptr = room_list[i].haveCritNamed(z, targ, pc.SEE_BIT))) {
count++;
if (count == i_th) {
do_tell(pc, msg, *crit_ptr, TRUE, i);
return 0;
}
z++;
}//while
}//if
}//for
pc.show("That person is not around!\n");
return -1;
}//tell
int who(critter& pc) {
Cell<critter*> cll(pc_list);
critter* ptr;
String buf(100);
mudlog.log(TRC, "In who..\n");
show("These people are actively playing:\n", pc);
while ((ptr = cll.next())) {
if ((!detect(pc.SEE_BIT, ptr->VIS_BIT)) &&
(ptr->isImmort())) {
continue;
}//if
if ((ptr->getMode() == MODE_LOGGING_IN) && (!pc.isImmort())) {
continue;
}
String class_str;
String lvl_str;
int can_detect = FALSE;
if (ptr->isImmort()) {
if (pc.isImmort() && (pc.getImmLevel() >= ptr->getImmLevel())) {
can_detect = TRUE;
}
else {
can_detect = FALSE;
}
}//
else if (pc.isImmort()) {
can_detect = TRUE;
}
else {
//neither are immorts
can_detect = FALSE;
}
if (ptr->isCloaked() && !can_detect && (ptr != &pc)) {
class_str = "Cloaked";
lvl_str = "??";
}
else {
class_str = get_class_name(ptr->CLASS);
if (ptr->isImmort()) {
Sprintf(lvl_str, "IMM-%i", ptr->getImmLevel());
}
else if (ptr->isRemort()) {
Sprintf(lvl_str, "RMT-%i", ptr->LEVEL);
}
else {
lvl_str = ptr->LEVEL;
}
}//else
Sprintf(buf, "%S %S %P45%S(%S)%P25\n",
ptr->getName(pc.SEE_BIT), &(ptr->short_desc),
&class_str, &lvl_str);
show(buf, pc);
}//while
Sprintf(buf, "\nThere are currently %i people actively playing.\n",
pc_list.size());
pc.show(buf);
mudlog.log(TRC, "Done with who.\n");
return 0;
}//who
int sockets(critter& pc) {
Cell<critter*> cll(pc_list);
critter* ptr;
String buf(100);
mudlog.log(TRC, "In sockets..\n");
if (!ok_to_do_action(NULL, "IF", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
show("Verbose list of players:\n", pc);
while ((ptr = cll.next())) {
Sprintf(buf, "%S(%i)%P15 %S%P35 %S\n", name_of_crit(*ptr, pc.SEE_BIT),
ptr->LEVEL, &(ptr->pc->host), &(ptr->short_desc));
pc.show(buf);
}//while
return 0;
}//sockets
int ldwho(critter& pc) {
Cell<critter*> cll(linkdead_list);
critter* ptr;
String buf(100);
if (!ok_to_do_action(NULL, "IF", 0, pc, pc.getCurRoom(), NULL, TRUE)) {
return -1;
}
show("These people are link dead.\n", pc);
while ((ptr = cll.next())) {
Sprintf(buf, "%S%P20%s(%i)%P35%S Last IP: %S\n", name_of_crit(*ptr, ~0),
get_class_name(ptr->CLASS), ptr->LEVEL,
&(ptr->short_desc), ptr->getHostName());
show(buf, pc);
}//while
return 0;
}//ldwho