// $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