// $Id: misc2.cc,v 1.24.2.19 2000/05/13 19:42:59 greear Exp $
// $Revision: 1.24.2.19 $ $Author: greear $ $Date: 2000/05/13 19:42:59 $
//
//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
//
///*************************** misc2.cc ****************************///
///******** Headers for this file are found in misc2.h ************///
///******** Bitfield masks defined here as well. ************///
#include "misc.h"
#include "misc2.h"
#include <stdio.h>
#include <string.h>
#include "classes.h"
#include "commands.h"
#include "command2.h"
#include "command3.h"
#include "spec_prc.h"
#include "batl_prc.h"
#include "spells.h"
#include "skills.h"
#include <PtrArray.h>
#include "vehicle.h"
#include <sys/types.h>
#include <signal.h>
#include <LogStream.h>
#include "SkillSpell.h"
// Attempt to load the player-run shop owner of that number.
// Returns a newly allocated SMOB, or NULL if a problem is
// encountered.
critter* load_player_shop_owner(int mob_num) {
switch (config.useMySQL) {
#ifdef USEMYSQL
case true:
return db_load_player_shop_owner(mob_num);
break;
#endif
case false:
return file_load_player_shop_owner(mob_num);
break;
}
return NULL;
}
#ifdef USEMYSQL
critter* db_load_player_shop_owner(int mob_num) {
critter* sk = new critter();
sk->dbRead(mob_num, 0, true);
sk->short_cur_stats[26] = 1;
affected_mobs.append(sk);
return sk;
}
#endif
critter* file_load_player_shop_owner(int mob_num) {
String buf(100);
if (mob_list[mob_num].isInUse()) {
// Find the file name of our shopkeeper.
Sprintf(buf, "./PlayerShops/%S_%i", mob_list[mob_num].getShortName(),
mob_num);
ifstream dafile(buf);
if (dafile) {
critter* sk = new critter();
sk->fileRead(dafile, TRUE); //read all inventory.
// Make sure it's labeled as a SMOB
sk->short_cur_stats[26] = 1; /* make it a SMOB */
affected_mobs.append(sk);
return sk;
}//if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: Could not open Player Shop Keeper -:"
<< buf << ":- for reading." << endl;
}//if
return NULL;
}//else
}//if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: load_player_shop_owner, mob_num: "
<< mob_num << " is not in use." << endl;
}//if
return NULL;
}//else
}//load_player_shop_owner
int save_player_shop_owner(critter& pc) {
String buf(100);
if (!pc.isPlayerShopKeeper()) {
mudlog << "ERROR: save_player_shop_owner, mob: "
<< pc.getName() << " id_num: " << pc.getIdNum()
<< " is not a shop keeper." << endl;
return FALSE;
}
if (mob_list[pc.getIdNum()].isInUse()) {
// Find the file name of our shopkeeper.
Sprintf(buf, "./PlayerShops/%S_%i", mob_list[pc.getIdNum()].getShortName(),
pc.getIdNum());
ofstream dafile(buf);
if (dafile) {
pc.Write(dafile);
return TRUE;
}//if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: Could not open Player Shop Keeper -:"
<< buf << ":- for writing." << endl;
}//if
return FALSE;
}//else
}//if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: save_player_shop_owner, mob_num: "
<< pc.getIdNum() << " is not in use." << endl;
}//if
return FALSE;
}//else
}//save_player_shop_owner
object* load_player_box(int box_num) {
#ifdef USEMYSQL
if (config.useMySQL)
return db_load_player_box(box_num);
else
#endif
return file_load_player_box(box_num);
}
#ifdef USEMYSQL
object* db_load_player_box(int box_num) {
object* box = new object();
box->dbRead(box_num, -1, true);
return box;
}
#endif
object* file_load_player_box(int box_num) {
String buf(100);
if (obj_list[box_num].isInUse()) {
Sprintf(buf, "./PlayerSacks/%i", box_num);
ifstream dafile(buf);
if (dafile) {
object* box = new object();
box->fileRead(dafile, TRUE);
return box;
}
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: Could not open Player Box -:"
<< buf << ":- for reading." << endl;
}
return NULL;
}
}
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: load_player_box, box_num: "
<< box_num << " is not in use." << endl;
}
return NULL;
}
}
int save_player_box(object& box) {
String buf(100);
if(obj_list[box.getIdNum()].isInUse()) {
Sprintf(buf, "./PlayerSacks/%i", box.getIdNum());
ofstream dafile(buf);
if(dafile) {
box.Write(dafile);
return TRUE;
}
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: Could not open Player Owned Box -:"
<< box.getIdNum() << ":- for writing." << endl;
}
return FALSE;
}
}
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: save_player_box, obj_num: "
<< box.getIdNum() << " is not in use." << endl;
}
return FALSE;
}
}
int core_dump(const char* msg) {
cerr << "In my_assert, msg: " << msg << endl;
mudlog << "ERROR: Dumping core on purpose..." << endl
<< flush;
//From the great Katrina McClelan!
//TODO: Add waidpid etc...
kill(getpid(),SIGSEGV); /* this'll dump core */
sleep(10); /* make sure it stops here */
return TRUE;
// if (!fork()) {
// /* child copy starts here */
// /* dead by here */
// kill(getpid(),SIGSEGV); /* this'll dump core */
// sleep(10); /* make sure it stops here */
// }
// else {
// cerr << "fork failed: " << strerror(errno) << endl;
// }
// return TRUE;
}//core_dump
/* parent continues unaware */
short a_will_help_b_against_c(critter& a, critter& b, critter& c) {
if (!a.mob || !a.mob->proc_data || a.INT1)
return FALSE;
if (a.mob->getSocialAwareness() < 2)
return FALSE;
int should = a.mob->getSocialAwareness() * 10 + 5;
/* should a like b? */
if (a.CLASS == b.CLASS)
should += 50;
if (a.RACE == b.RACE)
should += 75;
if (abs(abs(a.ALIGN) - (abs(b.ALIGN))) < 300)
should += 90;
if (a.ALIGN > 300)
should += 35;
/* now figure out why a should like c */
if (a.CLASS == c.CLASS)
should -= 50;
if (a.RACE == c.RACE)
should -= 75;
if (abs(abs(a.ALIGN) - (abs(b.ALIGN))) < 300)
should -= 90;
should -= d(1, (40 - a.LEVEL) * 4); //generally don't wanna help out..
if (should > 0)
return TRUE;
else
return FALSE;
}//a_helps_b_against_c
void lose_fly(critter& pc, short do_msg = FALSE) {
int is_dead;
if (do_msg) {
show("You glance down just in time to see the ground rushing up to meet you.\n", pc);
pc.emote("suddenly falls out of the sky.\n");
}
if (ROOM.needsFly() && (ROOM.getFallTo() != 0)) {
pc.doGoToRoom(ROOM.getFallTo(), "from the sky", NULL, is_dead,
pc.getCurRoomNum(), 1, TRUE);
}
if (!is_dead)
look(1, &NULL_STRING, pc, TRUE);
}//lose_fly
void unpetrify(critter& pc, short do_msg = FALSE) {
if (do_msg)
show("Your skin returns to its origional rubbery texture.\n", pc);
pc.CRIT_FLAGS.turn_off(14);
}//unpetrify
void show_stat_affects(object& obj, critter& pc) {
Cell<stat_spell_cell*> cll(obj.stat_affects);
stat_spell_cell* ptr;
String buf(100);
if (obj.stat_affects.isEmpty()) {
pc.show("NONE\n");
}
while ((ptr = cll.next())) {
if (ptr->stat_spell == 1) {
Sprintf(buf, "Strength[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 2) {
Sprintf(buf, "Inteligence[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 3) {
Sprintf(buf, "Constitution[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 4) {
Sprintf(buf, "Charisma[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 5) {
Sprintf(buf, "Wisdom[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 6) {
Sprintf(buf, "Dexterity[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 7) {
Sprintf(buf, "Hit (chance)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 8) {
Sprintf(buf, "Damage[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 9) {
Sprintf(buf, "AC (armor)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 10) {
Sprintf(buf, "Attacks[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 15) {
Sprintf(buf, "HP (current)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 16) {
Sprintf(buf, "Mana (current)[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 17) {
Sprintf(buf, "Movement (current)[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 18) {
Sprintf(buf, "Alignment[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 22) {
Sprintf(buf, "Practices[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 23) {
Sprintf(buf, "HP (max)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 24) {
Sprintf(buf, "Mana (max)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 25) {
Sprintf(buf, "Movement (max)[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 27) {
Sprintf(buf, "Damage Recieved Modifier[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 28) {
Sprintf(buf, "Damage Given Modifier[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 29) {
Sprintf(buf, "Heat Resistance[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 30) {
Sprintf(buf, "Cold Resistance[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 31) {
Sprintf(buf, "Electrical Resistance[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 32) {
Sprintf(buf, "Spell Resistance[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 35) {
Sprintf(buf, "Bare Hand Dice Count[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 36) {
Sprintf(buf, "Bare Hand Dice Sides[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 37) {
Sprintf(buf, "HP Regeneration[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 38) {
Sprintf(buf, "Mana Regeneration[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 39) {
Sprintf(buf, "Movement Regeneration[%i]:%P25 %i\n",
ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 100) {
Sprintf(buf, "Hunger[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 101) {
Sprintf(buf, "Thirst[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else if (ptr->stat_spell == 102) {
Sprintf(buf, "Drugged[%i]:%P25 %i\n", ptr->stat_spell, ptr->bonus_duration);
show(buf, pc);
}//if
else {
Sprintf(buf, "Unknown [%i]:, value: [%i]\n", ptr->stat_spell,
ptr->bonus_duration);
show(buf, pc);
}//if
}//while
}//show_stat_affects
/** Tests this performs: A(!animal)
* B(!pc in_battle) b (! in mob room)
* C(owns aux_crit) F(frozen)
* G(!gagged) I(is immort) K(know spell), M(has mana),
* m(!mob, smob ok), N(!magic),
* P(paralyzed), R(owns aux_rm), r(resting or standing)
* S(is_standing), V(!violence), Z(room is zlocked)
* Syntax is: If test is TRUE, then action can be done. Note that some
* of the conditions are negative logic. Thus, 'A' will be TRUE if
* the critter is NOT an ANIMAL.
*
* Case matters.
*/
int ok_to_do_action(critter* vict, const char* flags, int spell_num,
critter& pc, room* aux_rm = NULL, critter* aux_crit = NULL,
int do_msg = TRUE) {
String buf(100);
int len = strlen(flags);
char chr;
int mana_cost = 0;
// mana_cost = SSCollection::instance().getSS(spell_num).getManaCost();
mana_cost = get_mana_cost(spell_num, pc);
if (pc.isMob()) {
Sprintf(buf, "ERROR: mob casting spell# %i.\n", spell_num);
mudlog.log(ERROR, buf);
return FALSE;
}//if
for (int i = 0; i<len; i++) {
chr = flags[i];
if (chr == 'M') {
if (mana_cost > pc.MANA) {
if (do_msg) {
show("You don't have enough energy to cast this spell!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'A') {
if (pc.getClass() == ANIMAL) {
if (do_msg) {
show("Animals can't do that!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'K') {
if (get_percent_lrnd(spell_num, pc) <= 0) {
if (do_msg) {
show("You don't know where to begin!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'm') {
if (pc.isMob()) {
if (do_msg) {
mudlog << "ERROR: ok_to_do_action, got a MOB (not SMOB).\n";
pc.show("ERROR: mob trying to do an action.\n");
}//if
return FALSE;
}//if
}//if
else if (chr == 'G') {
if (pc.isGagged()) {
if (do_msg) {
show("You have been gagged.\n", pc);
return FALSE;
}//if
}
}
else if (chr == 'P') {
if (pc.CRIT_FLAGS.get(14)) {
if (do_msg) {
show("You are paralyzed!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'F') {
if (pc.pc && pc.PC_FLAGS.get(0)) {
if (do_msg) {
show("You are frozen!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'r') {
if (pc.POS > POS_REST) {
if (do_msg) {
show("You must be in a more lively position!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'B') {
if (!pc.IS_FIGHTING.isEmpty()) {
if (do_msg) {
show("You can't concentrate enough in battle!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'b') {
if (ROOM.isNoMob()) {
if (do_msg) {
show("NPC's cannot be here.\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'N') {
if (ROOM.isNoMagic()) {
if (do_msg) {
show("Magic cannot function here!\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'S') {
if (pc.POS != POS_STAND) {
if (do_msg) {
show("You must be standing in order to do this.\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'R') {
if (!aux_rm || !pc.doesOwnRoom(*aux_rm)) {
if (do_msg) {
pc.show("You do not own that room.\n");
}//if
return FALSE;
}//if
}//if
else if (chr == 'Z') {
if (!aux_rm || !aux_rm->isZlocked()) {
if (do_msg) {
show("You cannot edit a room that is not locked.\n", pc);
}//if
return FALSE;
}//if
}//if
else if (chr == 'C') {
if (!pc.doesOwnCritter(*aux_crit)) {
if (do_msg) {
pc.show("You do not own that critter.\n");
}//if
return FALSE;
}//if
}//if
else if (chr == 'I') {
if (!pc.isImmort()) {
if (do_msg) {
pc.show("Ehh??\n");
}//if
return FALSE;
}//if
}//if
else if (chr == 'V') {
if (ROOM.isZlocked() && !(pc.doesOwnRoom(ROOM) || pc.getImmLevel() > 8)) {
if (do_msg) {
pc.show("You don't own this room, and the zone is locked.\n");
}
return FALSE;
}
if (!pc.isImmort()) {
if (ROOM.isHaven() && (&pc != vict)) {
if (do_msg) {
show("Violence is not permitted here.\n", pc);
}//if
return FALSE;
}//if
else if (ROOM.isNoPK() && vict && vict->pc && (&pc != vict)) {
if (do_msg) {
show("Player killing is not allowed here.\n", pc);
}//if
return FALSE;
}//if
}//if
}//if
}//for
return TRUE;
}//ok_to_do_action
critter* check_for_diversions(critter& pc, char* tests, critter& agg) {
char chr;
int i;
String buf(100);
if (!tests)
return &pc;
for (i = 0; (chr = tests[i]); i++) {
if (chr == 'S') {
if (pc.temp_crit && pc.SHIELDED_BY) {
if (d(1, 175) > pc.SHIELDED_BY->DEX +
get_percent_lrnd(SHIELD_SKILL_NUM, *(pc.SHIELDED_BY))) {
if (ROOM.haveCritter(pc.SHIELDED_BY)) {
return pc.SHIELDED_BY;
}//if
}//if
}//if
}//if
else if (chr == 'G') {
if (pc.temp_crit) {
if (pc.GUARDED_BY) {
if (d(1, 175) > pc.GUARDED_BY->DEX +
get_percent_lrnd(GUARD_SKILL_NUM, *(pc.GUARDED_BY))) {
if (ROOM.haveCritter(pc.GUARDED_BY)) {
return pc.GUARDED_BY;
}
}//if
}//if
}//if
}//if Guard
else if (chr == 'M') {
if (pc.mirrors > 0) {
if (d(1, pc.mirrors) > 1) {
pc.mirrors--;
Sprintf(buf, "%S shatters a mirror image of you.\n",
name_of_crit(agg, pc.SEE_BIT));
buf.Cap();
show(buf, pc);
Sprintf(buf, "breaks a mirror image of %S.",
name_of_crit(pc, ~0));
emote(buf, agg, room_list[agg.getCurRoomNum()], TRUE, &pc);
return NULL;
}//if hit a mirror
}//if has mirrors
}//if mirror check
}//for
return &pc;
}//check_for_diversions
stat_spell_cell* is_affected_by(int spell_num, critter& pc) {
Cell<stat_spell_cell*> cll(pc.affected_by);
stat_spell_cell* ptr;
while ((ptr = cll.next())) {
if (ptr->stat_spell == spell_num)
return ptr;
}//while
return NULL;
}//is_affected_by
stat_spell_cell* is_affected_by(int spell_num, object& obj) {
Cell<stat_spell_cell*> cll(obj.affected_by);
stat_spell_cell* ptr;
while ((ptr = cll.next())) {
if (ptr->stat_spell == spell_num)
return ptr;
}//while
return NULL;
}//is_affected_by (obj)
stat_spell_cell* has_stat_affect(int stat_num, object& obj) {
Cell<stat_spell_cell*> cll(obj.stat_affects);
stat_spell_cell* ptr;
while ((ptr = cll.next())) {
if (ptr->stat_spell == stat_num)
return ptr;
}//while
return NULL;
}//has_stat_affect
const char* get_opposite_dir(const char* dir) {
int i = strlen(dir);
if (strncasecmp(dir, "north", i) == 0)
return "south";
else if (strncasecmp(dir, "east", i) == 0)
return "west";
else if (strncasecmp(dir, "south", i) == 0)
return "north";
else if (strncasecmp(dir, "west", i) == 0)
return "east";
else if (strncasecmp(dir, "northeast", i) == 0)
return "southwest";
else if (strncasecmp(dir, "southeast", i) == 0)
return "northwest";
else if (strncasecmp(dir, "southwest", i) == 0)
return "northeast";
else if (strncasecmp(dir, "northwest", i) == 0)
return "southeast";
else if (strncasecmp(dir, "up", i) == 0)
return "down";
else if (strncasecmp(dir, "down", i) == 0)
return "up";
else
return "UNKNOWN";
}//get_opposite_dir
void leave_room_effects(room& rm, critter& pc) {
Cell<door*> cll(rm.DOORS);
door* ptr;
while ((ptr = cll.next())) {
if (ptr->crit_blocking == &pc) {
ptr->dr_data->door_data_flags.turn_off(14); //no longer blocked
ptr->crit_blocking = NULL;
}//if
}//while
pc.CRIT_FLAGS.turn_off(22); //no longer hiding or melding
if (pc.pc) {
pc.PC_FLAGS.turn_off(17);
}//if
rm.checkLight(FALSE);
String cmd = "exit";
rm.checkForProc(cmd, NULL_STRING, pc, -1);
}//leave_room_effects
void leave_room_effects(room& rm, object& obj) {
rm.checkLight(FALSE);
//String cmd = "exit";
//rm.checkForProc(cmd, NULL_STRING, pc, -1);
}//leave_room_effects (Objects)
const String* single_obj_name(object& obj, int see_bit) {
if (detect(see_bit, obj.OBJ_VIS_BIT))
return Top(obj.names);
else
return &SOMETHING; //global 'someone' String
}//single_obj_name
const char* get_himself_herself(critter& pc) {
if (pc.SEX == 0)
return "herself";
else if (pc.SEX == 1)
return "himself";
else return "itself";
}//
const char* get_dude_chic(critter& pc) {
if (pc.SEX == 0)
return "chic";
else if (pc.SEX == 1)
return "dude";
else return "being";
}//
const char* get_fellow_lady(critter& pc) {
if (pc.SEX == 0)
return "lady";
else if (pc.SEX == 1)
return "fellow";
else return "being";
}//
const char* get_him_her(critter& pc) {
if (pc.SEX == 0)
return "her";
else if (pc.SEX == 1)
return "him";
else return "it";
}//
int is_grouped(critter& crit, critter& pc) {
Cell<critter*> cll(pc.GROUPEES);
critter* ptr;
while ((ptr = cll.next())) {
if (ptr == &crit)
return TRUE;
}//while
crit.GROUPEES.head(cll);
while ((ptr = cll.next())) {
if (ptr == &pc)
return TRUE;
}//while
return FALSE;
}//is_grouped
int get_race_num(const char* name) {
if (strcasecmp(name, "undead") == 0)
return UNDEAD;
if (strcasecmp(name, "animal") == 0)
return ANIMAL;
if (strcasecmp(name, "monster") == 0)
return MONSTER;
if (strcasecmp(name, "human") == 0)
return HUMAN;
if (strcasecmp(name, "anitre") == 0)
return ANITRE;
if (strcasecmp(name, "avintre") == 0)
return AVINTRE;
if (strcasecmp(name, "darkling") == 0)
return DARKLING;
if (strcasecmp(name, "drow") == 0)
return DROW;
if (strcasecmp(name, "dragon") == 0)
return DRAGON;
if (strcasecmp(name, "dwarf") == 0)
return DWARF;
if (strcasecmp(name, "ironclad") == 0)
return IRONCLAD;
if (strcasecmp(name, "orgue") == 0)
return OGRUE;
if (strcasecmp(name, "rocktroll") == 0)
return ROCKTROLL;
if (strcasecmp(name, "elf") == 0)
return ELF;
if (strcasecmp(name, "faerie") == 0)
return FAERIE;
if (strcasecmp(name, "entity") == 0)
return ENTITY;
if (strcasecmp(name, "sombrian") == 0)
return SOMBRIAN;
if (strcasecmp(name, "avian") == 0)
return AVIAN;
return OTHER_RACE;
}//get race_num
int get_class_num(const char* name) {
if (strcasecmp(name, "warrior") == 0)
return WARRIOR;
if (strcasecmp(name, "sage") == 0)
return SAGE;
if (strcasecmp(name, "wizard") == 0)
return WIZARD;
if (strcasecmp(name, "ranger") == 0)
return RANGER;
if (strcasecmp(name, "thief") == 0)
return THIEF;
if (strcasecmp(name, "alchemist") == 0)
return ALCHEMIST;
if (strcasecmp(name, "cleric") == 0)
return CLERIC;
if (strcasecmp(name, "bard") == 0)
return BARD;
return OTHER_CLASS;
}//get class num
const char* get_race_name(int num) {
if (num == OTHER_RACE)
return "other";
if (num == UNDEAD)
return "undead";
if (num == ANIMAL)
return "animal";
if (num == MONSTER)
return "monster";
if (num == HUMAN)
return "human";
if (num == ANITRE)
return "anitre";
if (num == AVINTRE)
return "avintre";
if (num == DARKLING)
return "darkling";
if (num == DROW)
return "drow";
if (num == DRAGON)
return "dragon";
if (num == DWARF)
return "dwarf";
if (num == IRONCLAD)
return "ironclad";
if (num == OGRUE)
return "ogrue";
if (num == ROCKTROLL)
return "rocktroll";
if (num == ELF)
return "elf";
if (num == FAERIE)
return "faerie";
if (num == ENTITY)
return "entity";
if (num == SOMBRIAN)
return "sombrian";
if (num == AVIAN)
return "avian";
return "UNKNOWN";
}//get race name
const char* get_class_name(int num) {
if (num == OTHER_CLASS)
return "other";
if (num == WARRIOR)
return "warrior";
if (num == SAGE)
return "sage";
if (num == WIZARD)
return "wizard";
if (num == RANGER)
return "ranger";
if (num == THIEF)
return "thief";
if (num == ALCHEMIST)
return "alchemist";
if (num == CLERIC)
return "cleric";
if (num == BARD)
return "bard";
return "UNKNOWN";
}//get class name
int max(int i, int j) {
if (i > j)
return i;
return j;
}
int min(int i, int j) {
if (i < j)
return i;
return j;
}
void save_all() {
Cell<critter*> cll(pc_list);
critter* ptr;
//log("In save_all.\n");
while ((ptr = cll.next())) {
if (ptr->MODE == MODE_NORMAL) {
if (mudlog.ofLevel(DBG)) {
mudlog << "save_all: Name of crit -:" << *(name_of_crit(*ptr, ~0))
<< ":-" << endl;
}
ptr->save();
}//if
}//while
}//save all
say_proc_cell* have_topic_named(List<say_proc_cell*> lst, const String& msg) {
Cell<say_proc_cell*> cll(lst);
say_proc_cell* ptr;
while ((ptr = cll.next())) {
if (strcasecmp(ptr->topic, msg) == 0) {
return ptr;
}//if
}//while
return NULL;
}//have_topic_named
void strip_hegemon_tags(String& str) {
// If we find a tag, delete it. Maybe do more interesting things
// later.
int len = str.Strlen();
String retval(len);
char ch;
int in_tag = false;
int prev_was_lt = false;
for (int i = 0; i<len; i++) {
ch = str[i];
if (ch == '<') {
if (in_tag) {
continue;
}
else {
if (prev_was_lt) {
prev_was_lt = FALSE;
retval += ch;
}
else {
prev_was_lt = TRUE;
}
}//else
}//if
else {
if (prev_was_lt) {
in_tag = TRUE;
}
if (ch == '>') {
prev_was_lt = FALSE;
if (in_tag) {
in_tag = FALSE;
}
else {
retval += ch;
}
}
else {
prev_was_lt = FALSE;
if (in_tag) {
continue;
}
else {
retval += ch;
}
}//else
}//else
}//for
str = retval;
}//strip_hegemon_tags
void parse_communication(String& str) {
int sofar = 0;
int len = str.Strlen();
char ch;
int max_len = 380;
// First, check for censored strings. This is a lot of work
// for the computer, and I hate censoring, but experience has
// shown it to be needed. Edit the CensoredStrings in const.cc
// to modify this...
String tmp(str);
tmp.Tolower(); //make it all lower-case
//const char* incoming = tmp; //will cast to char*
// Skip censorship for now. --BEN
//const char* censored;
//for (int i = 0; (censored = CensoredStrings[i]); i++) {
// if (strstr(incoming, censored)) {
// str = "CENSORED";
// return;
// }
//}
String retval(len + 5);
for (int i = 0; i<len; i++) {
ch = str[i];
if (++sofar > max_len) {
// retval needs to have a newline inserted before the current
// spot. (retval.Strlen())
int retval_len = retval.Strlen();
for (int j = retval_len; j > (retval_len - max_len); j--) {
if (isspace(retval[j])) {
retval.setCharAt(j, '\n');
max_len = 380;
sofar = 0;
break;
}//if
}//for
if (sofar > 0) { //didn't find a space
retval += '\n';
max_len = 380;
sofar = 0;
}
}//if
if (ch == '<') {
retval += "<<";
}
else {
if (ch == '\n') {
max_len = 380;
sofar = 0;
}
retval += ch;
}
}//for
str = retval;
}//parse_communication
void parse_for_max_80(String& str) {
int start = 0;
int sofar = 0;
int len = str.Strlen();
int i;
short found_it;
while (TRUE) {
found_it = FALSE;
i = start;
if ((i + 79) >= len) {
break;//done
}//if
while ((i < len) && (str[i] != '\n') && (i < (start + 80))) {
i++;
}//while
sofar = i;
if ((sofar - start) > 79) { //gotta fix it
while (i > start) {
i--;
if (str[i] == ' ') {
str.setCharAt(i, '\n');
i++; //move past newline
start = i;
found_it = TRUE;
break;
}//if
}//while
if (!found_it) { //there wasn't a space
str.setCharAt((i + 78), '\n');
start = i + 79;
}//if
}//if need fixing
else {
start = sofar + 1;
}//else
}//while true
if (len == 0)
return; //hack
for (i = 0; i < (len - 1); i++) {
if ((str[i] == '~') && (isspace(str[i+1]))) {
str.setCharAt(i, ' ');
}//if
}//for
if (str[len - 1] == '~')
str.setCharAt((len - 1), ' ');
}//parse_for_max_80()
short name_is_secret(const String* name, door& dr) {
Cell<String*> cll(dr.dr_data->names);
String* ptr;
int len = name->Strlen();
if (len == 0)
return FALSE;
if (dr.destination >= 0) { //if positive, go from top
ptr = cll.next();
while ((ptr = cll.next())) {
if (*ptr == "#")
break; // didn't find it
if (strncasecmp(*name, *ptr, len) == 0)
return TRUE;
}//while
return FALSE;
}//if
else {
ptr = cll.prev();
while ((ptr = cll.prev())) {
if (*ptr == "#")
break; // didn't find it
if (strncasecmp(*name, *ptr, len) == 0)
return TRUE;
}//while
return FALSE;
}//else
}//name_is_secret
// May return a NULL!
String* dir_of_room(room& rm, int dest_rm_num) {
Cell<door*> cll(rm.DOORS);
door* ptr;
while ((ptr = cll.next())) {
if (abs(ptr->destination) == abs(dest_rm_num)) {
return direction_of_door(*ptr);
}//if
}//while
return NULL;
}//dir_of_room
int get_next_msg_num(object& board) {
Cell<object*> cll(board.inv);
object* ptr;
int sofar = 0;
int i;
while ((ptr = cll.next())) {
i = atoi(*(ptr->names.peekFront()));
if (i > sofar)
sofar = i;
}//while
return sofar + 1;
}//get_next_msg_num
String owner_of_zone(int rm_num) {
int znum = room_list[rm_num].getZoneNum();
return ZoneCollection::instance().elementAt(znum).getFirstOwner();
}//owner_of_zone
void do_vehicle_moves() {
Cell<room*> cll;
pulsed_proc_rooms.head(cll); //declared in grrmud.cc
room* rm_ptr;
if (mudlog.ofLevel(DBG)) {
mudlog << "In do_vehicle_moves, pulsed_proc_rooms.Size(): "
<< pulsed_proc_rooms.size() << endl;
}
while ((rm_ptr = cll.next())) {
//if (mudlog.ofLevel()) {
// mudlog << "Checking on room/vehicle number: "
// << rm_ptr->getRoomNum() << endl;
//}
if (rm_ptr->isVehicle() && rm_ptr->isInUse() && !rm_ptr->isZlocked()) {
vehicle* veh_ptr = (vehicle*)(rm_ptr);
if (veh_ptr->isSelfGuided()) { //its not pc-guided
veh_ptr->decrementTicksTillNextStop();
if (veh_ptr->getTicksTillNextStop() <= 0) {
veh_ptr->move();
}//if
}//if
}//if
}//while
}//do_vehicle_moves()
int mob_can_enter(critter& pc, room& rm, short do_msg, int check_no_wander = FALSE) {
int retval = FALSE;
if (!rm.isInUse()) { //if not used
if (do_msg)
show("That room doesn't really exist!!\n", pc);
}//if
else if ((rm.isNoMortal() && !pc.isImmort())) {
if (do_msg) {
pc.show("Mortals are not allowed there!!\n");
}
}
else if ((rm.needsBoat()) && //need boat
(!(pc.CRIT_FLAGS.get(4) || pc.CRIT_FLAGS.get(3)))) {
if (do_msg)
show("You need a boat to go there.\n", pc);
}//if
else if ((rm.needsDive()) && //need underwater ability
(!pc.canDive())) {
if (do_msg)
show("You must be able to dive to go there.\n", pc);
}//if
else if ((rm.needsClimb()) && //need climb
(!(pc.isFlying() || pc.canClimb()))) {
if (do_msg) {
show("You lose your footing and almost fall!!\n", pc);
emote("slips and almost falls!!\n", pc, ROOM, TRUE);
pc.PAUSE++; //punish them a bit
}//if
}//if
else if ((rm.needsFly()) && //need fly
(!(pc.CRIT_FLAGS.get(3)))) {
if (do_msg)
show("You have to be flying to go there.\n", pc);
}//if
else if ((rm.isNoMob()) && // !mob?
(!pc.isPc())) {
if (do_msg)
show("Mobs are not allowed to move there.\n", pc); //never see prob.
}//if !mob
else if (!pc.isPc() && check_no_wander &&
(rm.isNoWanderMob() ||
(rm.isNoWanderForeignMob() && (pc.getHomeTown() != rm.getZoneNum())))) {
if (do_msg)
show("Mobs are not allowed to wander there.\n", pc); //never see prob.
}//if !mob
else if (rm.isZlocked()) {
if (pc.isImmort()) {
if (rm.getZoneNum() != 0) {
if ((pc.getImmLevel() <= 2) &&
(!ZoneCollection::instance().elementAt(rm.getZoneNum()).isOwnedBy(pc))) {
if (do_msg) {
pc.show("Immorts may no longer visit other areas that are\n");
pc.show("locked. If you have a legit reason, ask a higher\n");
pc.show("builder or coder for permission.\n");
}//if
return FALSE;
}//if
else {
return TRUE;
}
}//if
else {
return TRUE;
}
}//if is Immort
else {
if (do_msg)
show("That direction has been locked to your kind.\n", pc);
return FALSE;
}
}//if
else
retval = TRUE;
return retval;
}//mob_can_enter
void out_stat_list(const List<stat_spell_cell*>& lst, critter& pc,
const BitfieldNames& names) {
Cell<stat_spell_cell*> cll(lst);
stat_spell_cell* ptr;
String buf(100);
String buf2(100);
if (lst.isEmpty()) {
pc.show("NONE\n");
return;
}
while ((ptr = cll.next())) {
Sprintf(buf, "(%s %i) ", names.getName(ptr->stat_spell),
ptr->bonus_duration);
buf2.Append(buf);
}//while
buf2.Append("\n");
pc.show(buf2);
}//out_stat_list
void out_spell_list(const List<stat_spell_cell*>& lst, critter& pc) {
Cell<stat_spell_cell*> cll(lst);
stat_spell_cell* ptr;
String buf(100);
String buf2(100);
if (lst.isEmpty()) {
pc.show("NONE\n");
return;
}
while ((ptr = cll.next())) {
Sprintf(buf, "(%s %i) ",
SSCollection::instance().getNameForNum(ptr->stat_spell),
ptr->bonus_duration);
buf2.Append(buf);
}//while
buf2.Append("\n");
pc.show(buf2);
}//out_spell_list
object* have_obj_numbered(const List<object*>& lst, const int i_th,
const int obj_num, const int see_bit,
const room& rm) {
Cell<object*> cll(lst);
object* ptr;
int count = 0;
while ((ptr = cll.next())) {
if (ptr->OBJ_NUM == obj_num) {
if (detect(see_bit, (ptr->OBJ_VIS_BIT | rm.getVisBit()))) {
count++;
if (count == i_th) {
return ptr;
}//if
}//if detect
}//if obj nums agree
}//while
return NULL;
}//have_obj_numbered
int get_game_time() {
return config.hour;
}//get_game_time
const char* get_month(int day) {
if (day <= 31)
return "January";
else if (day <= 60)
return "February";
else if (day <= 91)
return "March";
else if (day <= 120)
return "April";
else if (day <= 150)
return "May";
else if (day <= 181)
return "June";
else if (day <= 211)
return "July";
else if (day <= 242)
return "August";
else if (day <= 273)
return "September";
else if (day <= 303)
return "October";
else if (day <= 334)
return "November";
else if (day <= 365)
return "December";
else {
mudlog.log(ERROR, "ERROR: day is > 365, in get_month.\n");
return "Leap Month";
}//else
}//get_month
const int get_day_of_month(int day) { //day of the year that is
if (day <= 31)
return day;
else if (day <= 60)
return day - 31;
else if (day <= 91)
return day - 60;
else if (day <= 120)
return day - 91;
else if (day <= 150)
return day - 120;
else if (day <= 181)
return day - 150;
else if (day <= 211)
return day - 181;
else if (day <= 242)
return day - 211;
else if (day <= 273)
return day - 242;
else if (day <= 303)
return day - 273;
else if (day <= 334)
return day - 303;
else if (day <= 365)
return day - 334;
else {
mudlog.log(ERROR, "ERROR: day is > 365, get_day_of_month.\n");
return 32;
}//else
}//get_day_of_month
const char* military_to_am(int m_time) {
if (m_time == 0)
return "1 am";
else if (m_time == 1)
return "2 am";
else if (m_time == 2)
return "3 am";
else if (m_time == 3)
return "4 am";
else if (m_time == 4)
return "5 am";
else if (m_time == 5)
return "6 am";
else if (m_time == 6)
return "7 am";
else if (m_time == 7)
return "8 am";
else if (m_time == 8)
return "9 am";
else if (m_time == 9)
return "10 am";
else if (m_time == 10)
return "11 am";
else if (m_time == 11)
return "12 pm";
else if (m_time == 12)
return "1 pm";
else if (m_time == 13)
return "2 pm";
else if (m_time == 14)
return "3 pm";
else if (m_time == 15)
return "4 pm";
else if (m_time == 16)
return "5 pm";
else if (m_time == 17)
return "6 pm";
else if (m_time == 18)
return "7 pm";
else if (m_time == 19)
return "8 pm";
else if (m_time == 20)
return "9 pm";
else if (m_time == 21)
return "10 pm";
else if (m_time == 22)
return "11 pm";
else if (m_time == 23)
return "12 am";
else {
mudlog.log(ERROR, "ERROR: m_time out of range, military_to_am.\n");
return "0 am";
}//else
}//military_to_am
room* get_next_room(int zone_num) {
for (int i = ZoneCollection::instance().elementAt(zone_num).getBeginRoomNum();
i <= ZoneCollection::instance().elementAt(zone_num).getEndRoomNum();
i++) {
if (!room_list[i].isInUse()) { //if room is not used
room_list[i].setRoomNum(i); //This really shouldn't be needed!
return &(room_list[i]); //ptr to that room
}//if
}//for
return NULL; //there was no free room
}//get_next_room()
int get_next_obj() {
for (int i = 10; i<NUMBER_OF_ITEMS; i++) {
if (!(obj_list[i].OBJ_FLAGS.get(10))) {
return i;
}//if
}//for
return -1; //there was no free room
}//get_next_obj()
int get_next_door() {
for (int i = 10; i<NUMBER_OF_DOORS; i++) {
if (!(door_list[i].door_data_flags.get(10))) {
return i;
}//if
}//for
return -1; //there was no free door
}//get_next_door()
int get_next_mob() {
for (int i = 10; i<NUMBER_OF_MOBS; i++) {
if (!(mob_list[i].CRIT_FLAGS.get(18))) {
return i;
}//if
}//for
return -1; //there was no free mob
}//get_next_obj()
int get_percent_lrnd(int skill_num, const critter& pc, short automatic = FALSE) {
if (!pc.pc) {
if (automatic && pc.mob && pc.mob->proc_data) {
if (pc.FLAG1.get(12)) { //evasive maneuvers flag
if (skill_num == DODGE_SKILL_NUM)
return (70 + pc.LEVEL);
if (skill_num == PARRY_SKILL_NUM)
return (70 + pc.LEVEL);
}//if
}//if automatic (ie should search)
return (70 + pc.LEVEL);
}//if not a pc
int retval;
if (pc.SKILLS_KNOWN.Find(skill_num, retval)) {
return retval;
}//if
return -1;
}//%lrnd_skill
void increment_percent_lrnd(int skill_num, critter& pc) {
if (!pc.pc)
return;
float inc;
int dif = SSCollection::instance().getSS(skill_num).getDifficulty();
inc = (33.0/(float)dif) * (((float)(pc.INT)/4.0) * ((float)(pc.INT)/4.0) +
(float)(pc.INT)/2.0);
inc = max((int)(inc), 1);
int p_lrnt;
if (pc.SKILLS_KNOWN.Find(skill_num, p_lrnt)) {
p_lrnt += (int)inc;
if (p_lrnt > 100)
p_lrnt = 100;
pc.SKILLS_KNOWN.Insert(skill_num, p_lrnt); //update value
return;
}//if
mudlog.log(ERROR,
"ERROR: tried to increment_%_lrnd on a skill unknown by pc.\n");
}//inc_skill
void init_masks() {
/* OBJ_WEAR_FLAGS */
int i;
for (i = 22; i < (21 + MAX_EQ); i++) {
Obj_Wear_Flags_Mask.turn_on(i);
}
/* OBJ_CONSUME_PROCS_FLAGS */
Obj_Consume_Procs_Mask.turn_on(0); //teleport
Obj_Consume_Procs_Mask.turn_on(3); //poison
/* OBJ_WEAR_PROCS */
//Obj_Wear_Procs_Mask.turn_on(??); //no special ones coded yet
/* OBJ_REMOVE_PROCS */
//Obj_Remove_Procs_Mask.turn_on(??); //no special ones coded yet
//Shop_Data_Buy_Procs_Mask.turn_on(0); //buy_proc_0
//Shop_Data_Sell_Procs_Mask.turn_on(1); //sell_proc_0
//Shop_Data_Offer_Procs_Mask.turn_on(2); //offer_proc_0
}//init masks
String* direction_of_door(const door& drr) {
String* ptr = NULL;
if (drr.destination < 0)
ptr = drr.dr_data->names.peekRear();
else
ptr = drr.dr_data->names.peekFront();
if (ptr)
return ptr;
else
return &UNKNOWN;
}//direction_of_door
const char* abbrev_dir_of_door(const door& drr) {
String* dir;
if (drr.destination < 0)
dir = drr.dr_data->names.peekRear();
else
dir = drr.dr_data->names.peekFront();
if (dir == NULL) {
return "??";
}//if
if (strcasecmp(*dir, "north") == 0)
return "N";
else if (strcasecmp(*dir, "northwest") == 0)
return "NW";
else if (strcasecmp(*dir, "northeast") == 0)
return "NE";
else if (strcasecmp(*dir, "east") == 0)
return "E";
else if (strcasecmp(*dir, "south") == 0)
return "S";
else if (strcasecmp(*dir, "southeast") == 0)
return "SE";
else if (strcasecmp(*dir, "southwest") == 0)
return "SW";
else if (strcasecmp(*dir, "west") == 0)
return "W";
else if (strcasecmp(*dir, "up") == 0)
return "U";
else if (strcasecmp(*dir, "down") == 0)
return "D";
else return "??";
}//abbrev_dir_of_door
int obj_count(List<object*>& lst, object& src) {
int retval = 0;
Cell<object*> cll(lst);
object* ptr;
while ((ptr = cll.next())) {
if (ptr->OBJ_NUM == src.OBJ_NUM) {
retval++;
}//if
}//while
return retval;
}//obj_count
int crit_count(List<critter*>& lst, critter& src) {
int retval = 0;
Cell<critter*> cll(lst);
critter* ptr;
if (!src.mob) {
return retval;
}//if
while ((ptr = cll.next())) {
if (ptr->mob) {
if (ptr->MOB_NUM == src.MOB_NUM) {
retval++;
}//if
}//if
}//while
return retval;
}//crit_count
void clear_crit_list(List<critter*>& lst) {
Cell<critter*> cll(lst);
critter* ptr;
//log("In clear_crit_list.\n");
ptr = cll.next();
while (ptr) {
if ((ptr->pc) || (ptr->isSmob())) { //if smob/pc
delete ptr; //delete it for sure
}//if
ptr = lst.lose(cll);
}//while
}//clear_crit_list
void clear_obj_list(List<object*>& lst) {
Cell<object*> cll(lst);
object* ptr;
//log("In clear_obj_list.\n");
ptr = cll.next();
while (ptr) {
//log("In while loop.\n");
if (ptr->in_list) { //if its a SOBJ
delete ptr; //delete it for sure
}//if
ptr = lst.lose(cll);
}//while
}//clear_obj_list
void out_field(const bitfield& field, critter& pc, const BitfieldNames& names) {
int k = field.max_bit();
String buf(100);
String tmp(50);
int sofar = 0;
Sprintf(buf, "%S (SET)\n\t", &(names.getHeader()));
pc.show(buf);
buf = "";
for (int i = 0; i <= k; i++) {
if (field.get(i)) {
Sprintf(tmp, "[%i] %s, ", i, names.getName(i));
if ((sofar + tmp.Strlen()) > 80) {
buf += "\n\t";
sofar = tmp.Strlen();
}
else {
sofar += tmp.Strlen();
}
buf += tmp;
}//if
}//for
buf.Append("\n");
show(buf, pc);
}//out_field
int critter::doBecomeNonPet() {
String buf(100);
if (isMob()) {
mudlog.log(ERROR, "ERROR: mob sent to unpet.\n");
return -1;
}//if
if (!MASTER) {
return -1;
}//if
MASTER->PETS.loseData(this); //master no longer has pc as pet...
MASTER = NULL; // slave of none
return doUngroup(1, &NULL_STRING);
}//unpet
const char* class_of_crit(critter& pc) {
return get_class_name(pc.CLASS);
}//class_of_crit
int find_and_delete_obj(object* obj_to_find, int room_num) {
// Find an object in the rooms current inventory, also look in containers' and
// critters' inventories.
// Returns FALSE on error (room doesn't exist, removed wasn't found)
// TRUE when an object has been removed
object* obj = NULL;
critter* crit = NULL;
if (mudlog.ofLevel(DBG)) {
mudlog << "DEBUG: in find_and_remove_obj(object* obj_to_find = " << obj_to_find
<< ", int rm_num = " << room_num << ")\n";
}
// Sanity checks, make sure this is a valid room
if ((0 > room_num > NUMBER_OF_ROOMS) || !room_list[room_num].isInUse()) {
mudlog.log(DBG, "DEBUG: Room is invalid.\n");
return FALSE;
}
Cell<object *> obj_cll(*(room_list[room_num].getInv()));
Cell<critter*> crit_cll(room_list[room_num].getCrits());
// Try to find obj_to_find in the room's inventory
mudlog.log(DBG, "DEBUG: checking objects in the room.\n");
while((obj = obj_cll.next())) {
if (obj == obj_to_find) {
// Found it, so delete it
mudlog.log(DBG, "DEBUG: Found object in the room.\n");
room_list[room_num].loseInv(obj_to_find);
if (obj_to_find->isModified()) {
delete obj_to_find;
}
return TRUE;
}
else if (find_and_delete_obj(obj_to_find, obj)) {
mudlog.log(DBG, "DEBUG: Found object in a container.\n");
return TRUE;
}
}
// Check the critters in the room
mudlog.log(DBG, "DEBUG: checking on critters in the room.\n");
while((crit = crit_cll.next())) {
if (find_and_delete_obj(obj_to_find, crit)) {
mudlog.log(DBG, "DEBUG: Found object on a critter.\n");
return TRUE;
}
}
// Guess we didn't find it
mudlog.log(DBG, "DEBUG: Didn't find object in room.\n");
return FALSE;
}
int find_and_delete_obj(object* obj_to_find, critter* crit_ptr) {
// Find an object in a critter's current inventory, also look in containers the
// critter owns, and at the critter's equipment list
// Returns FALSE on error (crit_ptr is bad, didn't find obj_to_find)
// TRUE when an object has been removed
object* obj = NULL;
if (mudlog.ofLevel(DBG)) {
mudlog << "DEBUG: in find_and_remove_obj(object* obj_to_find = " << obj_to_find
<< ", crit_ptr = " << crit_ptr << ")\n";
}
if (!crit_ptr) {
mudlog.log(DBG, "DEBUG: bad crit_ptr.\n");
return FALSE;
}
Cell<object*> obj_cll(crit_ptr->inv);
// Try to find obj_to_find in the critter's inventory
mudlog.log(DBG, "DEBUG: checking critter's inventory.\n");
obj = obj_cll.next();
while (obj) {
if (obj == obj_to_find) {
// Found it, so delete it
mudlog.log(DBG, "DEBUG: found object in critter's inventory.\n");
crit_ptr->loseInv(obj_to_find);
if (obj_to_find->isModified()) {
delete obj_to_find;
}
return TRUE;
}
else {
if (find_and_delete_obj(obj_to_find, obj)) {
mudlog.log(DBG, "DEBUG: Found object in a container (2).");
return TRUE;
}
}//else
obj = obj_cll.next();
}
// Check the critter's equipped items
mudlog.log(DBG, "DEBUG: checking critter's equipment.");
for (int i=1; i < MAX_EQ; i++) {
if (crit_ptr->EQ[i] == obj_to_find) {
// Found it, so delete it
mudlog.log(DBG, "DEBUG: found object in critter's EQ[].");
remove_eq_effects(*crit_ptr->EQ[i], *crit_ptr, FALSE, FALSE, i);
crit_ptr->EQ[i] = NULL;
if (obj_to_find->isModified()) {
delete obj_to_find;
}
return TRUE;
}
else {
if (crit_ptr->EQ[i] && find_and_delete_obj(obj_to_find, crit_ptr->EQ[i])) {
mudlog.log(DBG, "DEBUG: Found object in a container.\n");
return TRUE;
}
}
}
// Guess we didn't find it
mudlog.log(DBG, "DEBUG: didn't find object on critter.\n");
return FALSE;
}
int find_and_delete_obj(object* obj_to_find, object* find_in) {
// Find an object in another object's inventory - infinately recursive
// Returns FALSE on error (find_in isn't a container, obj_to_find isn't in find_in)
// TRUE when an object has been removed
object* obj = NULL;
if (mudlog.ofLevel(DBG)) {
mudlog << "DEBUG: in find_and_remove_obj(object* obj_to_find = " << obj_to_find
<< ", object* find_in = " << find_in << ")\n";
}
Cell<object *> cll(find_in->inv);
// Try to find obj_to_find in find_in's inventory
mudlog.log(DBG, "DEBUG: checking object's inventory.\n");
obj = cll.next();
while (obj) {
if (obj == obj_to_find) {
// Found it, so, delete it
mudlog.log(DBG, "DEBUG: Found object in container.\n");
find_in->loseInv(obj_to_find);
if (obj_to_find->isModified()) {
delete obj_to_find;
}
return TRUE;
}
else {
if (find_and_delete_obj(obj_to_find, obj)) {
mudlog.log(DBG, "DEBUG: Found object in container in container.\n");
return TRUE;
}
}
obj = cll.next();
}
// Guess we didn't find it
mudlog.log(DBG, "DEBUG: Couldn't find object in container.\n");
return FALSE;
}