// $Id: critter.cc,v 1.35.2.26 2000/06/27 05:54:09 greear Exp $
// $Revision: 1.35.2.26 $ $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
//
//***********************************************************//
//************************ mob data **********************///
#include "script.h"
#include "critter.h"
#include "misc.h"
#include "misc2.h"
#include <PtrArray.h>
#include "room.h"
#include "const.h"
#include "commands.h"
#include "command2.h"
#include "command3.h"
#include "command5.h"
#include "batl_prc.h"
#include "battle.h"
#include <stdarg.h>
#include "clients.h"
const char* PcPositionStrings[] = {"stand", "sit", "rest", "sleep", "meditate",
"stun", "dead", "prone"};
//**********************************************************//
///*********************** immort data ********************///
int immort_data::_cnt = 0;
immort_data::immort_data() {
_cnt++;
olc_counter = temp_olc_int = imm_level = 0;
olc_mob = NULL;
olc_room = NULL;
olc_obj = NULL;
olc_door = NULL;
edit_string = NULL;
tmp_proc_script = NULL;
} // constructor
immort_data::immort_data(const immort_data& source) {
_cnt++;
olc_counter = source.olc_counter;
temp_olc_int = source.temp_olc_int;
olc_mob = source.olc_mob;
olc_room = source.olc_room;
olc_obj = source.olc_obj;
olc_door = source.olc_door;
imm_level = source.imm_level;
edit_string = source.edit_string;
tmp_proc_script = NULL;
} // constructor
immort_data::~immort_data() {
_cnt--;
Clear();
}//deconstructor
void immort_data::Clear() {
if (olc_mob) {
olc_mob->Clear();
olc_mob = NULL;
}//if
if (olc_room) {
olc_room->Clear();
olc_room = NULL;
}//if
if (olc_obj) {
olc_obj->Clear();
olc_obj = NULL;
}//if
if (olc_door) {
olc_door->Clear();
olc_door = NULL;
}//if
clear_ptr_list(tmplist);
olc_counter = temp_olc_int = imm_level = 0;
edit_string = NULL; //clearing it probably not the right solution
delete tmp_proc_script;
tmp_proc_script = NULL;
} // Clear
void immort_data::Read(ifstream& dafile) {
char buf[82];
dafile >> imm_level;
dafile.getline(buf, 80); //junk end of line
}//Read
void immort_data::Write(ofstream& dafile) {
dafile << imm_level << "\tImm level\n";
}//Write
//**********************************************************//
///********************* teacher_data ********************///
int teacher_data::_cnt = 0;
teacher_data::teacher_data() {
_cnt++;
}//constructor
teacher_data::teacher_data(const teacher_data& source) {
_cnt++;
teach_data_flags = source.teach_data_flags;
}//constructor
void teacher_data::Read(ifstream& da_file) {
teach_data_flags.Read(da_file);
}//Read
void teacher_data::Write(ofstream& da_file) const {
teach_data_flags.Write(da_file);
}//Write
//****************************************************************//
///********************* Player Shop Data *********************///
int PlayerShopData::_cnt = 0; // Instance Count
int PlayerShopData::read(ifstream& da_file) {
int sentinel;
char tmp[81];
da_file >> sentinel;
if (sentinel == -1) {
da_file.getline(tmp, 80);
return 0;
}
else {
da_file >> object_num;
da_file >> sell_price;
da_file >> buy_price;
da_file.getline(tmp, 80);
return object_num;
}//else
}//read
void PlayerShopData::write(ofstream& da_file) const {
da_file << 1 << " " << object_num << " "
<< sell_price << " " << buy_price << " PlayerShopData \n";
}//write
//**********************************************************//
///********************* shop data ***********************///
int shop_data::_cnt = 0;
shop_data::shop_data() {
_cnt++;
markup = buy_percentage = open_time = close_time = 0;
}//constructor;
shop_data::shop_data(const shop_data& source) {
_cnt++;
*this = source;
}//constructor;
shop_data::~shop_data() {
_cnt--;
Clear();
}
shop_data& shop_data::operator=(const shop_data& source) {
if (this == &source)
return *this;
clear_obj_list(perm_inv);
markup = source.markup;
buy_percentage = source.buy_percentage;
open_time = source.open_time;
close_time = source.close_time;
Cell<object*> cll(source.perm_inv);
object* ptr;
while ((ptr = cll.next())) {
if (!ptr->IN_LIST) {
perm_inv.append(ptr);
}//if
}//while
// Deep copy here...
Cell<PlayerShopData*> pcll(source.ps_data_list);
PlayerShopData* pptr;
while ((pptr = pcll.next())) {
ps_data_list.pushBack(new PlayerShopData(*pptr));
}
perm_inv = source.perm_inv;
shop_data_flags = source.shop_data_flags;
return *this;
}//operator=;
void shop_data::Clear() {
markup = buy_percentage = close_time = open_time = 0;
clear_obj_list(perm_inv);
shop_data_flags.Clear();
clear_ptr_list(ps_data_list);
}//Clear
void shop_data::Read(ifstream& da_file, short read_all) {
int i;
String buf(100);
char tmp[81];
Clear();
if (!da_file) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in shop_data read." << endl;
}
return;
}
da_file >> markup >> buy_percentage >> open_time >> close_time;
da_file.getline(tmp, 80);
shop_data_flags.Read(da_file);
/* Inventory */
da_file >> i;
while (i != -1) {
if (i == -2) { //assume its gonna load fer sure
object* new_obj = new object;
da_file.getline(tmp, 80); //junk message
new_obj->fileRead(da_file, read_all);
new_obj->IN_LIST = &(perm_inv); //make sure its a SOBJ
perm_inv.append(new_obj); //add it to inventory
}//if
else {
if (obj_list[i].OBJ_FLAGS.get(10)) {
if (read_all ||
((obj_list[i].OBJ_PRCNT_LOAD*config.currentLoadModifier)/100) >
d(1,100)) {
perm_inv.append(&(obj_list[i])); //add it to inventory
}//if
}//if
else {
Sprintf(buf,
"ERROR: trying to load non_exist. obj: %i in perm_inv.\n",
i);
mudlog.log(ERROR, buf);
}//else
}//else
da_file >> i;
}//while
da_file.getline(tmp, 80);
if (isPlayerRun()) {
PlayerShopData* ps_data = new PlayerShopData();
while (ps_data->read(da_file)) {
ps_data_list.pushBack(ps_data);
ps_data = new PlayerShopData();
}//while
// Delete the last one, was not added to the list.
delete ps_data;
ps_data = NULL;
da_file >> manager;
da_file.getline(tmp, 80);
}//if is a Player Run Shopkeeper
}//Read
void shop_data::Write(ofstream& da_file) const {
Cell<object*> ob_cell(perm_inv);
object* ob_ptr;
int i = 0;
da_file << " " << markup << " " << buy_percentage << " "
<< open_time << " " << close_time
<< "\tshop_data shorts\n";
shop_data_flags.Write(da_file);
/* Inventory */
i = 0;
while ((ob_ptr = ob_cell.next())) {
if (ob_ptr->IN_LIST) {
da_file << -2 << "\t Start of SOBJ\n";
ob_ptr->Write(da_file);
}//if
else {
if (obj_list[ob_ptr->OBJ_NUM].OBJ_FLAGS.get(10)) {
da_file << ob_ptr->OBJ_NUM << " ";
if ((++i % 20) == 0)
da_file << endl;
}//if it exists
}//else
}//while
da_file << "-1 End of perm_inv\n";
if (isPlayerRun()) {
Cell<PlayerShopData*> pcll(ps_data_list);
PlayerShopData* pptr;
while ((pptr = pcll.next())) {
pptr->write(da_file);
}
da_file << "-1 End of PlayerShopData list\n";
if (manager.Strlen() == 0) {
da_file << "Grock" << " Manager\n"; //default value...
}
else {
da_file << manager << " Manager\n";
}
}//if
}//Write
void shop_data::valueRem(int idx, critter& manager) {
PlayerShopData* psd = ps_data_list.elementAt(idx);
if (psd) {
ps_data_list.loseData(psd);
delete psd;
manager.show("Ok, removed it.\n");
}//if
else {
manager.show("That index does not exist.\n");
}//else
}//valueRem
void shop_data::valueAdd(object& obj, critter& manager) {
if (getPsdFor(obj)) {
manager.show("That object has already been added.\n");
}
else {
ps_data_list.pushBack(new PlayerShopData(obj.getIdNum(),
obj.getDefaultPrice() * 3 / 2,
obj.getDefaultPrice() * 2 / 3));
manager.show("Value added, you will probably want to set it next.\n");
}//else
}//valueAdd
int shop_data::findItemSalePrice(object& obj) {
PlayerShopData* ptr = getPsdFor(obj);
if (ptr) {
return ptr->getSellPrice();
}
return -1;
}//findItemSalePrice
int shop_data::findItemBuyPrice(object& obj) {
PlayerShopData* ptr = getPsdFor(obj);
if (ptr) {
return ptr->getBuyPrice();
}
return -1;
}//findItemBuyPrice
PlayerShopData* shop_data::getPsdFor(object& obj) {
Cell<PlayerShopData*> cll(ps_data_list);
PlayerShopData* ptr;
while ((ptr = cll.next())) {
if (ptr->getObjNum() == obj.getIdNum()) {
return ptr;
}//if
}//while
return NULL;
}//getPsdFor
void shop_data::valueList(int i_th, const String* targ, critter& keeper,
critter& manager) {
String normal(500);
String client(500);
String buf(100);
int idx = 0;
Cell<PlayerShopData*> cll(ps_data_list);
PlayerShopData* ptr;
if (keeper.isManagedBy(manager)) {
Sprintf(client, "<VALUE_LIST %i %S %i> ", i_th, targ, keeper.GOLD);
Sprintf(normal, "Value listing for %i.%S, register: %i\n", i_th,
targ, keeper.GOLD);
}
else {
Sprintf(client, "<VALUE_LIST %i %S ??> ", i_th, targ);
Sprintf(normal, "Value listing for %i.%S:\n", i_th, targ);
}
while ((ptr = cll.next())) {
if (manager.isUsingClient()) {
Sprintf(buf, "<VALUE_ITEM %i %i %i %i> ", idx,
ptr->getObjNum(), ptr->getSellPrice(),
ptr->getBuyPrice());
client.Append(buf);
Sprintf(buf, "<VALUE_INAME %i %S> ", idx,
obj_list[ptr->getObjNum()].getLongName());
client.Append(buf);
}//if
Sprintf(buf, " [%i] Sell: %i %P20 Buy: %i %P30 Item: %S(%i)\n", idx,
ptr->getSellPrice(),
ptr->getBuyPrice(),
obj_list[ptr->getObjNum()].getLongName(),
ptr->getObjNum());
normal.Append(buf);
idx++;
}//while
if (manager.isUsingClient()) {
manager.show(client);
}
manager.show(normal);
}//valueList
void shop_data::valueSet(int val_idx, int sell_val, int buy_val,
critter& manager) {
PlayerShopData* psd = ps_data_list.elementAt(val_idx);
if (psd) {
psd->setSellPrice(sell_val);
psd->setBuyPrice(buy_val);
manager.show("Ok, new values set.\n");
}//if
else {
manager.show("That index is not valid.\n");
}//else
}//valueSet
///***************************************************************///
///*************** temp proc data ***********************///
int temp_proc_data::_cnt = 0;
temp_proc_data::temp_proc_data() {
_cnt++;
}//constructor
temp_proc_data::temp_proc_data(const temp_proc_data& source) {
_cnt++;
*this = source;
}//copy constructor
temp_proc_data::~temp_proc_data() {
_cnt--;
clear_ptr_list(hunting);
}//destructor
void temp_proc_data::Clear() {
clear_ptr_list(hunting);
tracking.Clear();
}//clear
temp_proc_data& temp_proc_data::operator= (const temp_proc_data& source) {
if (this == &source)
return *this;
String* sp;
Cell<String*> cll(source.hunting);
String* ptr;
Clear();
while ((ptr = cll.next())) {
sp = new String(*ptr);
hunting.append(sp);
}//while
tracking = source.tracking;
return *this;
}//operator= overload
///*******************************************************************///
///********************** say proc cell ***************************///
int say_proc_cell::_cnt = 0;
say_proc_cell::say_proc_cell() {
_cnt++;
obj_num = 0; //one to be given
trans_to_room = 0;
}//constructor
say_proc_cell::say_proc_cell(const say_proc_cell& source) {
_cnt++;
*this = source;
}//copy constructor
void say_proc_cell::Clear() {
topic.Clear();
msg.Clear();
skill_name.Clear();
obj_num = 0;
trans_to_room = 0;
}//Clear
void say_proc_cell::Read(ifstream& da_file) {
char buf[82];
if (!da_file) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in say_proc_cell read." << endl;
}
return;
}
da_file.getline(buf, 80);
topic = buf;
msg.Termed_Read(da_file);
da_file.getline(buf, 80);
skill_name = buf;
da_file >> obj_num >> trans_to_room;
da_file.getline(buf, 80);
}//read()
void say_proc_cell::Write(ofstream& da_file) {
da_file << topic << endl;
parse_for_max_80(msg);
da_file << msg << endl << "~" << endl;
da_file << skill_name << endl;
da_file << obj_num << " " << trans_to_room << "\t end of say_proc_cell\n";
}//write()
///*******************************************************************///
///********************** action proc data ***************************///
int action_proc_data::_cnt = 0;
action_proc_data::action_proc_data() {
_cnt++;
test_num = 0;
obj_num = 0; //one to be given
trans_to_room = 0;
}//constructor
action_proc_data::action_proc_data(const action_proc_data& source) {
_cnt++;
*this = source;
}//copy constructor
action_proc_data::~action_proc_data() {
_cnt--;
}//destructor
action_proc_data& action_proc_data::operator=(const action_proc_data& source) {
if (this == &source)
return *this;
test_num = source.test_num;
correct_msg = source.correct_msg;
skill_name = source.skill_name;
obj_num = source.obj_num;
trans_to_room = source.trans_to_room;
wrong_gift_msg = source.wrong_gift_msg;
return *this;
}//operator = overload
void action_proc_data::Clear() {
test_num = 0;
correct_msg.Clear();
skill_name.Clear();
obj_num = 0;
trans_to_room = 0;
wrong_gift_msg.Clear();
}//Clear
void action_proc_data::Read(ifstream& da_file) {
char buf[82];
if (!da_file) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in action_proc_data read." << endl;
}
return;
}
//mudlog.log(DBG, "Reading action_proc.\n");
da_file >> test_num;
da_file.getline(buf, 80);
//mudlog.log(DBG, "got test_num.\n");
correct_msg.Termed_Read(da_file);
//mudlog.log(DBG, "got correct_msg:");
//mudlog.log(DBG, correct_msg);
da_file.getline(buf, 80);
skill_name = buf;
//mudlog.log(DBG, "Got skillname: ");
//mudlog.log(DBG, skill_name);
da_file >> obj_num >> trans_to_room;
da_file.getline(buf, 80);
//mudlog.log(DBG, "Getting wrong_gift_msg:");
wrong_gift_msg.Termed_Read(da_file);
da_file.getline(buf, 80);
//mudlog.log(DBG, wrong_gift_msg);
}//read()
void action_proc_data::Write(ofstream& da_file){
da_file << test_num << "\t test_num, valid for give_proc mostly\n";
parse_for_max_80(correct_msg);
da_file << correct_msg << endl << "~" << endl;
da_file << skill_name << endl;
da_file << obj_num << " " << trans_to_room << "\tobj_num, trans_room#\n";
parse_for_max_80(wrong_gift_msg);
da_file << wrong_gift_msg << endl << "~" << endl;
da_file << "end action_proc_data\n";
}//write()
//************************************************************//
///********************* spec data *************************///
int spec_data::_cnt = 0;
spec_data::spec_data() {
_cnt++;
int1 = 0;
skill_violence = benevolence = defensiveness = bad_assedness =
social_awareness = 0;
sh_data = NULL;
teach_data = NULL;
temp_proc = NULL;
give_proc = NULL;
bow_proc = NULL;
curse_proc = NULL;
}//constructor
spec_data::spec_data(const spec_data& source) {
_cnt++;
sh_data = NULL;
teach_data = NULL;
temp_proc = NULL;
give_proc = NULL;
bow_proc = NULL;
curse_proc = NULL;
*this = source; //overloaded =
}//constructor
spec_data::~spec_data() {
_cnt--;
delete sh_data;
sh_data = NULL;
delete teach_data;
teach_data = NULL;
delete temp_proc;
temp_proc = NULL;
delete give_proc;
give_proc = NULL;
delete bow_proc;
bow_proc = NULL;
delete curse_proc;
curse_proc = NULL;
clear_ptr_list(topics);
}//destructor
void spec_data::Clear() {
delete sh_data;
sh_data = NULL;
delete teach_data;
teach_data = NULL;
delete temp_proc;
temp_proc = NULL;
delete give_proc;
give_proc = NULL;
delete bow_proc;
bow_proc = NULL;
delete curse_proc;
curse_proc = NULL;
flag1.Clear();
int1 = 0;
clear_ptr_list(topics);
wrong_align_msg.Clear();
wrong_class_msg.Clear();
wrong_race_msg.Clear();
skill_violence = benevolence = defensiveness = bad_assedness =
social_awareness = 0;
}//Clear
void spec_data::auditAI() {
if (!skill_violence || !benevolence || !defensiveness ||
!bad_assedness || !social_awareness) {
flag1.turn_on(13);
}//if
else {
flag1.turn_off(13);
}
}//auditAI
spec_data& spec_data::operator=(const spec_data& source) {
if (this == &source)
return *this;
Clear();
flag1 = source.flag1;
int1 = source.int1;
if (source.sh_data)
sh_data = new shop_data(*(source.sh_data));
if (source.teach_data)
teach_data = new teacher_data(*(source.teach_data));
if (source.temp_proc)
temp_proc = new temp_proc_data(*(source.temp_proc));
if (source.give_proc)
give_proc = new action_proc_data(*(source.give_proc));
if (source.bow_proc)
bow_proc = new action_proc_data(*(source.bow_proc));
if (source.curse_proc)
curse_proc = new action_proc_data(*(source.curse_proc));
Cell<say_proc_cell*> cll(source.topics);
say_proc_cell* ptr;
while ((ptr = cll.next())) {
topics.append(new say_proc_cell(*ptr));
}//while
wrong_align_msg = source.wrong_align_msg;
wrong_class_msg = source.wrong_class_msg;
wrong_race_msg = source.wrong_race_msg;
skill_violence = source.skill_violence;
benevolence = source.benevolence;
defensiveness = source.defensiveness;
bad_assedness = source.bad_assedness;
social_awareness = source.social_awareness;
return *this;
}//op = overload
void spec_data::Read(ifstream& da_file, short read_all) {
char tmp[81];
int test;
Clear();
if (!da_file) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in spec_data read." << endl;
}
return;
}
flag1.Read(da_file);
flag1.turn_off(12); //hack, get rid of this flag
da_file >> int1;
da_file.getline(tmp, 80);
if (flag1.get(1)) { // shopkeeper
sh_data = new shop_data;
sh_data->Read(da_file, read_all);
}//if
if (flag1.get(2)) { // teacher
teach_data = new teacher_data;
teach_data->Read(da_file);
}//if
if (flag1.get(5)) { //give_proc
give_proc = new action_proc_data;
give_proc->Read(da_file);
}//if
if (flag1.get(7)) { //bow_proc
bow_proc = new action_proc_data;
bow_proc->Read(da_file);
}//if
if (flag1.get(8)) { //curse_proc
curse_proc = new action_proc_data;
curse_proc->Read(da_file);
}//if
if (flag1.get(6)) { //say_proc
da_file >> test;
da_file.getline(tmp, 80);
say_proc_cell* ptr;
while (test != -1) {
ptr = new say_proc_cell;
ptr->Read(da_file);
topics.append(ptr);
da_file >> test;
da_file.getline(tmp, 80);
}//while
}//if
if (flag1.get(5) || flag1.get(6) || flag1.get(7) || flag1.get(8)) {
// then assume messages are there, ignore otherwise
wrong_align_msg.Termed_Read(da_file);
wrong_class_msg.Termed_Read(da_file);
wrong_race_msg.Termed_Read(da_file);
}//if
if (flag1.get(13)) { //if HAS_MOB_AI
da_file >> skill_violence >> benevolence >> defensiveness
>> bad_assedness >> social_awareness;
da_file.getline(tmp, 80);
}//if
}//Read
void spec_data::Write(ofstream& da_file){
if (skill_violence || benevolence || defensiveness || bad_assedness) {
flag1.turn_on(13); //make sure
}//if
flag1.Write(da_file);
da_file << int1 << "\tint1, above bitfield started spec_data\n";
if (flag1.get(1)) { // shopkeeper
if (!sh_data) {
mudlog.log(ERROR, "ERROR: trying to write sh_data, but it's NULL\n");
return;
}//if
sh_data->Write(da_file);
}//if
if (flag1.get(2)) { // teacher
if (!teach_data) {
mudlog.log(ERROR,
"ERROR: trying to write teach_data, but it's NULL\n");
return;
}//if
teach_data->Write(da_file);
}//if
if (flag1.get(5)) { //give_proc
give_proc->Write(da_file);
}//if
if (flag1.get(7)) { //bow_proc
bow_proc->Write(da_file);
}//if
if (flag1.get(8)) { //curse_proc
curse_proc->Write(da_file);
}//if
if (flag1.get(6)) { //say_proc
Cell<say_proc_cell*> cll(topics);
say_proc_cell* ptr;
while ((ptr = cll.next())) {
da_file << "1 here starts a valid say_proc_cell.\n";
ptr->Write(da_file);
}//while
da_file << "-1 end of say_proc_cells\n";
}//if
if (flag1.get(5) || flag1.get(6) || flag1.get(7) || flag1.get(8)) {
parse_for_max_80(wrong_align_msg);
da_file << wrong_align_msg << "\n~\n";
parse_for_max_80(wrong_class_msg);
da_file << wrong_class_msg << "\n~\n";
parse_for_max_80(wrong_race_msg);
da_file << wrong_race_msg << "\n~\n";
}//if
if (flag1.get(13)) {
da_file << skill_violence << " " << benevolence << " "
<< defensiveness << " " << bad_assedness << " "
<< social_awareness
<< " sk_viol, benev, def, bad_assed, soc_aware\n";
}//if
}//Write
///*********************************************************************///
////*********************** temp_crit_data ****************************///
///*********************************************************************///
int temp_crit_data::_cnt = 0;
temp_crit_data::temp_crit_data() {
guarded_by = guarding = shielded_by = shielding = NULL;
_cnt++;
}//constructor
temp_crit_data::temp_crit_data(const temp_crit_data& source) {
_cnt++;
guarded_by = source.guarded_by;
guarding = source.guarding;
shielded_by = source.shielding;
shielding = source.shielding;
}//copy constructor
temp_crit_data::~temp_crit_data() {
_cnt--;
Clear();
}//destructor
int temp_crit_data::doUnShield() {
if (shielding) {
if (shielding->temp_crit &&
shielding->temp_crit->shielded_by) {
shielding->temp_crit->shielded_by = NULL;
}//if
shielding = NULL;
return 0;
}//if
return -1;
}//doUnShield
void temp_crit_data::Clear() {
if (guarded_by) {
if (guarded_by->temp_crit && guarded_by->temp_crit->guarding) {
guarded_by->temp_crit->guarding = NULL;
}//if
guarded_by = NULL;
}//if
if (guarding) {
if (guarding->temp_crit && guarding->temp_crit->guarded_by) {
guarding->temp_crit->guarded_by = NULL;
}//if
guarding = NULL;
}//if
if (shielded_by) {
if (shielded_by->temp_crit &&
shielded_by->temp_crit->shielding) {
shielded_by->temp_crit->shielding = NULL;
}//if
shielded_by = NULL;
}//if
doUnShield();
}//Clear
///******************************* mob data **************************///
int mob_data::_cnt = 0;
mob_data::mob_data() {
_cnt++;
mob_num = tmp_num = cur_in_game = max_in_game = 0;
proc_data = NULL;
cur_script = NULL;
skin_num = 0;
home_room = 0;
ticks_old = ticks_till_freedom = 0;
}//constructor
mob_data::mob_data(mob_data& source) {
_cnt++;
proc_data = NULL;
cur_script = NULL;
*this = source;
}//constructor
mob_data::~mob_data() {
_cnt--;
delete proc_data; //if doesn't exist, then its NULL, still no prob :)
clear_ptr_list(mob_proc_scripts);
proc_data = NULL;
cur_script = NULL; //it was held in the mob_proc_scripts
}//destructor
void mob_data::Clear() {
mob_num = tmp_num = cur_in_game = max_in_game = 0;
delete proc_data;
proc_data = NULL;
mob_data_flags.Clear();
skin_num = 0;
clear_ptr_list(mob_proc_scripts);
clear_ptr_list(pending_scripts);
cur_script = NULL; //its held in the mob_proc_scripts
home_room = 0;
ticks_old = ticks_till_freedom = 0;
}//Clear, mob_data
void mob_data::finishedMobProc() {
if (cur_script) {
pending_scripts.loseData(cur_script);
delete cur_script;
}
cur_script = pending_scripts.peekFront();
}//finishedMobProc
void mob_data::addProcScript(const String& txt, MobScript* script_data) {
//similar to reading it in...
//first, see if we are over-writing one...
if (mudlog.ofLevel(DBG)) {
mudlog << "In mob_data::addProcScript, txt: \n" << txt
<< "\nscript data: "
<< script_data->toStringBrief(0, 0, ENTITY_CRITTER, 0)
<< endl;
}
mob_data_flags.turn_on(17); //now it has procs for sure!!
Cell<MobScript*> cll;
MobScript* ptr;
mob_proc_scripts.head(cll);
while ((ptr = cll.next())) {
if (ptr->matches(*script_data)) {
//got a match.
mudlog.log("mob_data::addProcScript, they match.");
*ptr = *script_data;
ptr->setScript(txt);
delete script_data;
return;
}//if
}//while
mudlog.log(DBG, "About to setScript.");
script_data->setScript(txt);
mudlog.log(DBG, "done with setScript.");
if (!script_data) {
mudlog.log(ERROR, "script_data is NULL, mob_data::addProcScript.");
return;
}
mob_proc_scripts.append(script_data);
}//addProcScript
mob_data& mob_data::operator= (mob_data& source) {
if (this == &source)
return *this;
Clear();
mob_num = source.mob_num;
tmp_num = source.tmp_num;
cur_in_game = source.cur_in_game;
max_in_game = source.max_in_game;
mob_data_flags = source.mob_data_flags; //bitfield's overloaded =
if (source.proc_data) {
proc_data = new spec_data(*(source.proc_data));
}//if
skin_num = source.skin_num;
home_room = source.home_room;
ticks_old = source.ticks_old;
ticks_till_freedom = source.ticks_till_freedom;
Cell<MobScript*> cll;
source.mob_proc_scripts.head(cll);
MobScript* ptr;
while ((ptr = cll.next())) {
Put(new MobScript(*ptr), mob_proc_scripts);
}
return *this;
}//mob_data operator=
void mob_data::Write(ofstream& ofile) {
ofile << " " << mob_num << " " << tmp_num << " "
<< max_in_game << "\tmob#, tmp_num, max_n_game\n";
mob_data_flags.Write(ofile);
if (mob_data_flags.get(0)) { //does it have spec_data?
if (!(proc_data)) {
mudlog.log(ERROR, "ERROR: told to write proc_data, but is NULL!\n");
return;
}//if
proc_data->Write(ofile);
}//if
if (mob_data_flags.get(16)) {
ofile << skin_num << " skin number\n";
}//if
if (mob_data_flags.get(17)) {
Cell<MobScript*> cll;
mob_proc_scripts.head(cll);
MobScript* ptr;
int i = 1;
while ((ptr = cll.next())) {
ofile << i++ << " Start of a mob proc script\n";
ptr->write(ofile);
}
ofile << "-1 End of mob proc scripts" << endl;
}
}//Write()
void mob_data::doScriptJump(int abs_offset) {
if (cur_script)
cur_script->doScriptJump(abs_offset);
}
void mob_data::Read(ifstream& ofile, short read_all) {
char tmp[81];
Clear();
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in mob_data read." << endl;
}
return;
}
ofile >> mob_num >> tmp_num >> max_in_game;
ofile.getline(tmp, 80);
if (mudlog.ofLevel(DBG))
mudlog << "Mob number: " << mob_num << endl;
tmp_num = 0; //since it isn't used..should be zero
mob_data_flags.Read(ofile);
if (mob_data_flags.get(0)) { //does it have spec_data?
proc_data = new spec_data;
proc_data->Read(ofile, read_all);
}//if
if (mob_data_flags.get(16)) {
ofile >> skin_num;
ofile.getline(tmp, 80);
}//if
if (mob_data_flags.get(17)) {
//mudlog.log("Mob has proc scripts...");
int sent_;
MobScript* ptr;
ofile >> sent_;
ofile.getline(tmp, 80);
if (mudlog.ofLevel(DB))
mudlog << "Tmp, after script#: " << sent_ << " -:" << tmp
<< ":-\n";
while (sent_ != -1) {
if (mudlog.ofLevel(DB))
mudlog << "\nReading script# " << sent_ << endl;
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: mob_data reading script da_file FALSE." << endl;
}
return;
}
ptr = new MobScript();
ptr->read(ofile);
Put(ptr, mob_proc_scripts);
ofile >> sent_;
ofile.getline(tmp, 80);
if (mudlog.ofLevel(DB))
mudlog << "Got rest of line -:" << tmp << ":-" << endl;
}
}//if using mob proc scripts
}//Read()
int mob_data::getBenevolence() const {
if (proc_data)
return proc_data->getBenevolence();
return 0;
}
void mob_data::auditAI() {
if (proc_data)
proc_data->auditAI();
}
int mob_data::getBadAssedness() const {
if (proc_data)
return proc_data->getBadAssedness();
return 0;
}
int mob_data::getSocialAwareness() const {
if (proc_data)
return proc_data->getSocialAwareness();
return 0;
}
int mob_data::getSkillViolence() const {
if (proc_data)
return proc_data->getSkillViolence();
return 0;
}
int mob_data::getDefensiveness() const {
if (proc_data)
return proc_data->getDefensiveness();
return 0;
}
int mob_data::isSentinel() const {
if (proc_data)
return proc_data->isSentinel();
return FALSE;
}
void mob_data::setBenevolence(int i) {
if (!proc_data)
addProcData();
proc_data->setBenevolence(i);
}
void mob_data::setBadAssedness(int i) {
if (!proc_data)
addProcData();
proc_data->setBadAssedness(i);
}
void mob_data::setSocialAwareness(int i) {
if (!proc_data)
addProcData();
proc_data->setSocialAwareness(i);
}
void mob_data::setSkillViolence(int i) {
if (!proc_data)
addProcData();
proc_data->setSkillViolence(i);
}
void mob_data::setDefensiveness(int i) {
if (!proc_data)
addProcData();
proc_data->setDefensiveness(i);
}
void mob_data::addProcData() {
if (!proc_data) {
mob_data_flags.turn_on(0);
proc_data = new spec_data;
}//if
}//addProcData
//*************************************************************//
///*********************** pc data ***************************///
int pc_data::_cnt = 0;
pc_data::pc_data() {
_cnt++;
post_msg = NULL;
snoop_by = NULL;
snooping = NULL;
imm_data = NULL;
w_eye_obj = NULL;
Clear();
}//constructor
pc_data::pc_data(const pc_data& source) {
_cnt++;
post_msg = NULL;
snoop_by = NULL;
snooping = NULL;
imm_data = NULL;
w_eye_obj = NULL;
*this = source;
}//constructor
pc_data::~pc_data() {
_cnt--;
delete imm_data;
imm_data = NULL;
if (post_msg) {
delete post_msg;
post_msg = NULL;
}
snoop_by = NULL;
snooping = NULL;
if (w_eye_obj) {
w_eye_obj->obj_proc->w_eye_owner = NULL;
w_eye_obj = NULL;
}//if
}//destructor
void pc_data::Clear() {
delete post_msg;
post_msg = NULL;
password.Clear();
input.Clear();
output.Clear();
last_input.Clear();
host.Clear();
mode = MODE_NORMAL;
descriptor = age = index = hunger = thirst = drugged = 0;
birth_year = birth_day = rent_day = rent_year = pk_count =
died_count = quest_points = idle_ticks = 0;
link_condition = CON_LOGGING_IN;
delete imm_data;
imm_data = NULL;
snoop_by = NULL;
snooping = NULL;
pc_data_flags.Clear();
skills_spells_known.Clear();
prompt.Clear();
poofout.Clear();
poofin.Clear();
gos_str = ANSI_BLACK;
say_str = ANSI_BLACK;
yell_str = ANSI_BLACK;
tell_str = ANSI_BLACK;
desc_str = ANSI_BLACK;
obj_list_str = ANSI_BLACK;
mob_list_str = ANSI_BLACK;
dflt_str = ANSI_BLACK;
bk_str = ANSI_BWHITE;
battle_str = ANSI_BLACK;
user1_str = ANSI_BLACK;
user2_str = ANSI_BLACK;
user3_str = ANSI_BLACK;
preferred_language = English;
last_login_time = 0; //in seconds, since 1970 etc...
total_time_online = 0; //in seconds
lines_on_page = 20;
if (w_eye_obj) {
w_eye_obj->obj_proc->w_eye_owner = NULL;
w_eye_obj = NULL;
}//if
// Volatile members (not saved to disk).
bug_num = 0;
bug_comment.Clear();
}//Clear, pc_data
pc_data& pc_data::operator=(const pc_data& source) {
if (this == &source)
return *this;
Clear();
password = source.password;
input = source.input;
output = source.output;
last_input = source.last_input;
descriptor = source.descriptor;
pc_data_flags = source.pc_data_flags;
age = source.age;
birth_day = source.birth_day;
birth_year = source.birth_year;
rent_day = source.rent_day;
rent_year = source.rent_year;
host = source.host;
link_condition = source.link_condition;
snoop_by = source.snoop_by;
snooping = source.snooping;
imm_data = new immort_data(*(source.imm_data));
mode = source.mode;
lines_on_page = source.lines_on_page;
index = source.index;
hunger = source.hunger;
thirst = source.thirst;
drugged = source.drugged;
pk_count = source.pk_count;
died_count = source.died_count;
quest_points = source.quest_points;
idle_ticks = source.idle_ticks;
skills_spells_known = source.skills_spells_known; //overload operator
prompt = source.prompt;
w_eye_obj = source.w_eye_obj;
last_login_time = source.last_login_time;
total_time_online = source.total_time_online;
poofin = source.poofin;
poofout = source.poofout;
gos_str = source.gos_str;
say_str = source.say_str;
yell_str = source.yell_str;
tell_str = source.tell_str;
desc_str = source.desc_str;
obj_list_str = source.obj_list_str;
mob_list_str = source.mob_list_str;
dflt_str = source.dflt_str;
bk_str = source.bk_str;
battle_str = source.battle_str;
user1_str = source.user1_str;
user2_str = source.user2_str;
user3_str = source.user3_str;
preferred_language = source.preferred_language;
return *this;
}//operator=, pc_data
void pc_data::Write(ofstream& ofile) {
int i;
ofile << password << "\tpasswd\n";
pc_data_flags.Write(ofile);
if (pc_data_flags.get(22)) {
ofile << lines_on_page << " ";
}
ofile << birth_day << " " << birth_year
<< " " << rent_year << " " << rent_day << " "
<< last_login_time << " " << total_time_online
<< "\t\tbday, byr, ryr, rday, llt, tto\n";
ofile << age << " " << hunger << " " << thirst << " " << drugged
<< " " << pk_count << " " << died_count << " " << quest_points
<< " age hgr thr drg pk died qp\n";
int key;
i = 1;
int retval = 0;
if (skills_spells_known.Min(key)) {//if it isn't empty
ofile << key << " ";
skills_spells_known.Find(key, retval);
ofile << retval << " ";
while (skills_spells_known.Next(key)) {
ofile << key << " ";
skills_spells_known.Find(key, retval);
ofile << retval << " ";
if (++i > 9) {
ofile << endl;
i = 0;
}//if
}//while
}//if
ofile << -1 << "\tss_known\n";
ofile << prompt << endl;
if (pc_data_flags.get(21)) {
ofile << poofin << endl;
ofile << poofout << endl;
}
if (pc_data_flags.get(2) || pc_data_flags.get(11)) { //has imm_data
if (imm_data) {
imm_data->Write(ofile);
}//if
else {
mudlog.log(ERROR, "ERROR: flagged imm, but no imm_data file!\n");
}//else
}//if
if (pc_data_flags.get(25)) {
ofile << gos_str << " Gos color" << endl;
ofile << say_str << " Say color" << endl;
ofile << yell_str << " Yell color" << endl;
ofile << tell_str << " Tell color" << endl;
ofile << desc_str << " Desc color" << endl;
ofile << obj_list_str << " Obj List color" << endl;
ofile << mob_list_str << " Mob List Color" << endl;
ofile << dflt_str << " Default Color" << endl;
ofile << bk_str << " Background Color" << endl;
ofile << battle_str << " Battle Color" << endl;
ofile << user1_str << " User1 color" << endl;
ofile << user2_str << " User2 Color" << endl;
ofile << user3_str << " User3 color" << endl;
}//if
if (pc_data_flags.get(27)) {
ofile << (int)(preferred_language) << " -1 preferred_language\n" << endl;
}
ofile << "*** end of pc data ***\n";
}//Write()
void pc_data::Read(ifstream& ofile) {
int i;
char tmp[81];
Clear();
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in pc_data read." << endl;
}
return;
}
ofile >> password;
ofile.getline(tmp, 80);
pc_data_flags.Read(ofile);
pc_data_flags.turn_off(23); //don't log in with page break on
if (pc_data_flags.get(22)) {
ofile >> lines_on_page;
}
ofile >> birth_day >> birth_year >> rent_year >> rent_day
>> last_login_time >> total_time_online;
ofile.getline(tmp, 80);
ofile >> age >> hunger >> thirst >> drugged >> pk_count >> died_count
>> quest_points;
ofile.getline(tmp, 80);
/* skills spells known */
ofile >> i;
int tmp_int;
while (i != -1) {
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in pc_data read." << endl;
}
return;
}
ofile >> tmp_int;
skills_spells_known.Insert(i, tmp_int);
ofile >> i;
}//while
ofile.getline(tmp, 80);
ofile.getline(tmp, 80); //grabs prompt
prompt = tmp;
if (pc_data_flags.get(21)) {
ofile.getline(tmp, 80);
poofin = tmp;
ofile.getline(tmp, 80);
poofout = tmp;
}
if (pc_data_flags.get(11)) {
pc_data_flags.turn_on(2);
}//if
if (pc_data_flags.get(2)) {
imm_data = new immort_data;
imm_data->Read(ofile);
}//if
if (pc_data_flags.get(25)) {
ofile >> gos_str;
ofile.getline(tmp, 80);
ofile >> say_str;
ofile.getline(tmp, 80);
ofile >> yell_str;
ofile.getline(tmp, 80);
ofile >> tell_str;
ofile.getline(tmp, 80);
ofile >> desc_str;
ofile.getline(tmp, 80);
ofile >> obj_list_str;
ofile.getline(tmp, 80);
ofile >> mob_list_str;
ofile.getline(tmp, 80);
ofile >> dflt_str;
ofile.getline(tmp, 80);
ofile >> bk_str;
ofile.getline(tmp, 80);
ofile >> battle_str;
ofile.getline(tmp, 80);
ofile >> user1_str;
ofile.getline(tmp, 80);
ofile >> user2_str;
ofile.getline(tmp, 80);
ofile >> user3_str;
ofile.getline(tmp, 80);
}//if
if (pc_data_flags.get(27)) {
int t;
ofile >> t;
if ((t < 0) || (t > LastLanguage)) {
t = English;
}
preferred_language = (LanguageE)(t);
ofile.getline(tmp, 80);
}
ofile.getline(tmp, 80); //grabs extra line/comment
}//Read()
//*************************************************************//
///********************* critter ***************************///
int critter::_cnt = 0;
critter::critter() {
// if (mudlog.ofLevel(DBG)) {
// mudlog << "MEMORY: creating crit: " << this << endl;
// }
_cnt++;
obj_ptr_log << "CRI_CON 0 " << this << "\n";
pc = NULL;
mob = NULL;
possessed_by = NULL;
possessing = NULL;
temp_crit = NULL;
Clear();
} // crit constructor
critter::critter(critter& source) {
// if (mudlog.ofLevel(DBG)) {
// mudlog << "MEMORY: copy constructing crit: " << this << endl;
// }
_cnt++;
pc = NULL;
mob = NULL;
possessed_by = NULL;
possessing = NULL;
temp_crit = NULL;
*this = source; //utilize overloaded =
obj_ptr_log << "CRI_CC " << getIdNum() << " " << this << "\n";
} // crit constructor
critter::~critter() {
// if (mudlog.ofLevel(DBG)) {
// mudlog << "MEMORY: deleting critter: " << this << endl;
// }
_cnt--;
obj_ptr_log << "CRI_DES " << getIdNum() << " " << this << "\n";
if (isMob() && (!do_shutdown)) {
core_dump("ERROR: trying to delete a MOB before shutdown.\n");
}//if
if (! do_shutdown) {
/* Eventually, could take these checks out. --BEN */
if (affected_mobs.haveData(this)) {
mudlog << "ERROR: deleting critter, but it's in affected_mobs: "
<< this << " mob num: " << *(names.peekFront()) << endl;
}//if
if (affected_mobs.haveData(this)) {
mudlog << "ERROR: deleting critter, but it's in affected_mobs: "
<< this << " mob num: " << *(names.peekFront()) << endl;
}//if
if (linkdead_list.haveData(this)) {
mudlog << "ERROR: deleting critter, but it's in linkdead_list: "
<< this << " mob num: " << *(names.peekFront()) << endl;
}//if
if (pc_list.haveData(this)) {
mudlog << "ERROR: deleting critter, but it's in pc_list: "
<< this << " mob num: " << *(names.peekFront()) << endl;
}//if
if (proc_action_mobs.haveData(this)) {
mudlog << "ERROR: deleting critter, but it's in proc_action_mobs: "
<< this << " mob num: " << *(names.peekFront()) << endl;
}//if
if (room_list[IN_ROOM].haveCritter(this)) {
mudlog << "ERROR: deleting critter, but it's in ROOM::CRITTERS: "
<< this << " mob num: " << *(names.peekFront())
<< " room num: " << IN_ROOM << endl;
}//if
}//if
Clear();
}//destructor
critter& critter::operator=(critter& source) { //automagically makes SMOB
if (this == &source)
return *this;
Cell<stat_spell_cell*> cell;
stat_spell_cell *tmp_stat, *tmp_stat2;
Cell<object*> cll;
object* obj_ptr;
int i;
//mudlog.log(DBG, "In crit operator= overload.\n");
Clear();
Cell<String*> scll(source.names);
String* sptr;
while ((sptr = scll.next())) {
Put((new String(*sptr)), names);
}//while
short_desc = source.short_desc;
in_room_desc = source.in_room_desc;
long_desc = source.long_desc;
if (source.pc) {
pc = new pc_data(*(source.pc));
}//if
if (source.mob) {
mob = new mob_data(*(source.mob));
}//if
crit_flags = source.crit_flags; //bitfields
for (i = 0; i<MOB_LONG_DATA; i++)
long_data[i] = source.long_data[i];
for (i = 0; i<MOB_SHORT_CUR_STATS; i++)
short_cur_stats[i] = source.short_cur_stats[i];
for (i = 0; i<MOB_CUR_STATS; i++)
cur_stats[i] = source.cur_stats[i];
for (i = 0; i<MAX_EQ; i++) {
if (source.eq[i]) {
if (!(source.eq[i]->IN_LIST)) { //don't need multiple ptrs to SOBJ's
eq[i] = source.eq[i];
}//if
else {
eq[i] = new object(*(source.eq[i]));
if (eq[i]) // if had the memory
eq[i]->IN_LIST = &(this->inv);
}//else
}//if
else {
eq[i] = NULL;
}//else
}//for
source.affected_by.head(cell);
while ((tmp_stat = cell.next())) {
tmp_stat2 = new stat_spell_cell;
*tmp_stat2 = *tmp_stat; //shallow copy should work
affected_by.append(tmp_stat2);
}//while
source.mini_affected_by.head(cell);
while ((tmp_stat = cell.next())) {
tmp_stat2 = new stat_spell_cell;
*tmp_stat2 = *tmp_stat; //shallow copy should work
Put(tmp_stat2, mini_affected_by);
}//while
source.inv.head(cll);
while ((obj_ptr = cll.next())) {
if (!obj_ptr->IN_LIST) { //no multiple ptrs to SOBJ's
Put(obj_ptr, inv);
}//if
}//while
follower_of = source.follower_of;
if (source.temp_crit) {
temp_crit = new temp_crit_data(*(source.temp_crit));
}//if
else {
temp_crit = NULL;
}//else
master = source.master;
//pets = source.pets; //these can cause multiple ptrs
//followers = source.followers; //to SMOB's, a definate SEGV
//groupees = source.groupees;
//is_fighting = source.is_fighting;
if (source.short_cur_stats[26] == 0)
short_cur_stats[26] = 0; //Stays a pc
else
short_cur_stats[26] = 1; //it IS a SMOB now!
mirrors = source.mirrors;
possessing = source.possessing;
possessed_by = source.possessed_by;
return *this;
}//crit::operator= overload
/** NOTE: This may normalize the real value.
*/
int critter::getDamRecMod() {
int min_val = 25;
if (is_affected_by(FLESH_TO_STONE_SKILL_NUM, *this)) {
min_val = 1;
}
return (max(min_val, DAM_REC_MOD));
}
int critter::isInGroupWith(critter* v) {
return GROUPEES.haveData(v);
}
/** Make sure that everyone in THIS critter's group list is in all the other
* member's lists.
*/
int critter::makeGroupSane() {
Cell<critter*> cll(GROUPEES);
Cell<critter*> cll2;
critter* ptr, *ptr2;
// For every one in the group....
while ((ptr = cll.next())) {
// Make sure that they know about all the others.
GROUPEES.head(cll2);
while ((ptr2 = cll2.next())) {
ptr->GROUPEES.gainData(ptr2); //Will not insert duplicates, btw.
}
}
return 0;
}
void critter::split(int amt, int do_msg) {
int d = GROUPEES.size();
String buf(100);
if (d > 0) {
Cell<critter*> cll(GROUPEES);
critter* ptr;
while ((ptr = cll.next())) {
ptr->GOLD += amt / d;
if (do_msg) {
Sprintf(buf, "%S splits %i coins, your share is: %i\n", getName(*ptr), amt, amt/d);
ptr->show(buf);
}
}
}
else {
GOLD += amt;
Sprintf(buf, "You split %i coins with yourself!\n", amt);
show(buf);
}
}
int critter::isGroupLeader() {
if (GROUPEES.isEmpty()) {
return FALSE;
}
else {
// We have groupees...
if (!FOLLOWER_OF || (FOLLOWER_OF == this)) {
// following self, so must be the leader.
return TRUE;
}
else {
// Is following someone other than self
if (FOLLOWER_OF && FOLLOWER_OF->GROUPEES.haveData(this)) {
//in follower's group
return FALSE;
}
else {
// Not in follower_of's group, but has a group of it's own...
return TRUE;
}
}
}
}
void critter::Clear() {
int i;
critter* ptr;
//mudlog.log(DBG, "In crit Clear().\n");
clear_ptr_list(names);
short_desc.Clear();
in_room_desc.Clear();
long_desc.Clear();
crit_flags.Clear();
spam_cnt = 0;
delete pc;
delete mob;
pc = NULL;
mob = NULL;
for (i = 0; i<MOB_LONG_DATA; i++)
long_data[i] = 0;
for (i = 0; i<MOB_SHORT_CUR_STATS; i++)
short_cur_stats[i] = 0;
for (i = 0; i<MOB_CUR_STATS; i++)
cur_stats[i] = 0;
for (i = 0; i<MAX_EQ; i++) {
eq[i] = NULL;
}//for
short_cur_stats[26] = 2; // slight hack, default it to MOB
clear_ptr_list(affected_by);
clear_ptr_list(mini_affected_by);
clear_obj_list(inv);
follower_of = master = NULL;
delete temp_crit;
temp_crit = NULL;
/* just get rid of ptrs, clean up SMOBs before clear is called */
pets.clear();
groupees.clear();
/* This should always be empty, I would think. */
while (!followers.isEmpty()) {
ptr = followers.popFront();
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: followers not empty in Clear, for mob: "
<< *(getName()) << " follower: " << *(ptr->getName()) << endl;
}//if
ptr->FOLLOWER_OF = NULL;
}//while
is_fighting.clear();
mirrors = 0;
if (possessing) {
unPossess();
}
if (possessed_by) {
possessed_by->unPossess();
}
//mudlog.log(DBG, "Done w/clear.\n");
}//crit Clear
int critter::doUnShield() {
if (temp_crit) {
return temp_crit->doUnShield();
}
return -1;
}
const char* critter::getPosnStr(critter& for_this_pc) {
switch (getPosn())
{
case POS_STAND:
return cstr(CS_STANDING, for_this_pc);
case POS_SIT:
return cstr(CS_SITTING, for_this_pc);
case POS_PRONE:
return cstr(CS_PRONE, for_this_pc);
case POS_REST:
return cstr(CS_RESTING, for_this_pc);
case POS_SLEEP:
return cstr(CS_SLEEPING, for_this_pc);
case POS_MED:
return cstr(CS_MEDITATING, for_this_pc);
case POS_STUN:
return cstr(CS_STUNNED, for_this_pc);
case POS_DEAD:
return cstr(CS_DEAD, for_this_pc);
default:
return cstr(CS_UNKNOWN, for_this_pc);
}//switch
}//getPosnStr
int critter::travelToRoom(int targ_room_num, int num_steps, int& is_dead) {
List<int> path;
if (!isStanding()) {
//Try to get up...
wake(*this);
stand(*this);
}
path_from_a_to_b(getCurRoomNum(), targ_room_num, path);
if (mudlog.ofLevel(DBG)) {
mudlog << "travelToRoom: targ_room: " << targ_room_num << " num_steps: "
<< num_steps << " from_room: " << getCurRoomNum() << endl;
Cell<int> cll(path);
int foo;
mudlog << "Path: ";
while ((foo = cll.next())) {
mudlog << " [" << foo << "] ";
}//while
mudlog << "\n\n";
}//if
if (path.isEmpty()) {
return -1; //couldn't find it
}//if
else { //got a valid path
// First, get rid of the first step, that is the current room.
path.popFront();
int iter = min(path.size(), num_steps);
for (int i = 0; ((i < iter) && (IsEmpty(IS_FIGHTING))); i++) {
int next_room = path.popFront();
String* dir = dir_of_room(*(getCurRoom()), next_room);
if (!dir) {
if (mudlog.ofLevel(WRN)) {
mudlog << "WARNING: Could not find door to room: "
<< next_room << " from room: " << getCurRoomNum()
<< " critter: " << *(getName()) << " targ_room_num: "
<< targ_room_num << " num_steps: " << num_steps << endl;
}//if
return -1;
}//if
else {
if (mudlog.ofLevel(DBG)) {
mudlog << "\ttravelToRoom, dir: " << *dir << endl;
}
}
door* dptr = door::findDoor(getCurRoom()->DOORS, 1, dir, ~0,
*(getCurRoom()));
if (!dptr) {
if (mudlog.ofLevel(WRN)) {
mudlog << "WARNING: Could not find door: " << *dir
<< " to room: "
<< next_room << " from room: " << getCurRoomNum()
<< endl;
}//if
return -1;
}//if
if (dptr->isClosed()) {
if (!open(1, dir, *this)) {
if (mudlog.ofLevel(DBG)) {
mudlog << "WARNING: Could not open door: " << *dir
<< " to room: " << next_room << " from room: "
<< getCurRoomNum() << endl;
}//if
return -1; //cant get there from here
}//if
}//if
//move will take care of attack
if (move(*this, 1, *dir, TRUE, *(getCurRoom()), is_dead) < 0) {
if (mudlog.ofLevel(DBG)) {
if (!is_dead) {
mudlog << "INFO: failed to move in travelToRoom, next_room: "
<< next_room << " from room: " << getCurRoomNum()
<< " critter: " << *(getName()) << " targ_room_num: "
<< targ_room_num << " num_steps: " << num_steps << endl;
}
else {
mudlog << "INFO: failed to move in travelToRoom, next_room: "
<< next_room << " targ_room_num: " << targ_room_num
<< " num_steps: " << num_steps << endl;
}
}//if
return -1;
}//if
if (is_dead) {
return -1;
}
}//for
}//else
return 0;
}//travelToRoom
int critter::getNakedWeight() const {
if (short_cur_stats[41] == 0) {
return 150;
}
return short_cur_stats[41];
}//getNakedWeight
int critter::getCurWeight() {// of inv...eq not taken into account here
Cell<object*> cll(inv);
object* tmp_obj;
int retval = 0;
while ((tmp_obj = cll.next())) {
retval += tmp_obj->getCurWeight();
}//while
for (int i = 1; i<MAX_EQ; i++) {
if (EQ[i]) {
retval += EQ[i]->getCurWeight() / 2;
}//if
}//for
retval += GOLD / config.goldPerLb; //gold weighs a little..though not much
return retval + getNakedWeight();
} // cur_weight
int critter::getMaxWeight() {
return (short_cur_stats[1] * 10 + getNakedWeight()); // 10 times their str
}//max_weight
int critter::getCurRoomNum() {
return IN_ROOM;
}
void critter::checkForBattle(room& rm) {
List<critter*> tmp_crits(rm.getCrits()); //just do shallow copy
Cell<critter*> cll(tmp_crits);
critter* ptr;
while ((ptr = cll.next())) {
if (!rm.haveCritter(this)) {
return;
}
if (rm.haveCritter(ptr)) {
if (ptr->doesRemember(*this) && ptr->canDetect(*this)) {
say("There you are!!", *ptr, *(ptr->getCurRoom()));
try_hit(*this, *ptr);
}//if
}//if
if (!rm.haveCritter(this)) {
return;
}
if (rm.haveCritter(ptr)) { //make sure we're still there
if (doesRemember(*ptr) && canDetect(*ptr)) {
say("I've found you now!!", *this, *(getCurRoom()));
try_hit(*ptr, *this);
}//if
}//if
}//while
}//checkForBattle
int critter::canDetect(const critter& other) const {
return detect(getSeeBit(), other.getVisBit());
}
void critter::Write(ofstream& ofile) {
int i, num_written;
Cell<stat_spell_cell*> ss_cell;
stat_spell_cell* ss_ptr;
Cell<object*> ob_cell;
object* ob_ptr;
Cell<String*> st_cell(names);
String* st_ptr;
String tmp_str(100);
int len = 0;
while ((st_ptr = st_cell.next())) {
len += st_ptr->Strlen();
if (len > 79) {
ofile << endl;
len = 0;
}//if
ofile << *st_ptr << " ";
}//while
ofile << "~" << "\tnames";
if (pc) {
ofile << " " << pc->host << " __LEVEL__ " << getLevel();
}
ofile << "\n";
parse_for_max_80(short_desc);
ofile << (short_desc) << endl << "~" << endl;
parse_for_max_80(in_room_desc);
ofile << (in_room_desc) << endl << "~" << endl;
parse_for_max_80(long_desc);
ofile << (long_desc) << endl << "~" << endl;
crit_flags.Write(ofile);
for (i = 0; i<MOB_LONG_DATA; i++)
ofile << long_data[i] << " ";
ofile << "\tlong_data\n";
for (i = 0; i<MOB_SHORT_CUR_STATS; i++) {
if ((i + 1) % 20 == 0)
ofile << endl;
ofile << short_cur_stats[i] << " ";
}//for
ofile << "\tshrt_cur_stats\n";
for (i = 0; i<MOB_CUR_STATS; i++)
ofile << cur_stats[i] << " ";
ofile << "\tcur_stats\n";
/* EQ, write out item_num, posn */
num_written = 0;
for (i = 0; i < MAX_EQ; i++) {
if (eq[i]) {
if (!eq[i]->IN_LIST) {
ofile << eq[i]->OBJ_NUM << " " << i << " ";
if ((++num_written % 20) == 0)
ofile << endl;
}//if
else { //then its a SOBJ
ofile << -2 << " " << i << "\t Start of SOBJ\n";
eq[i]->Write(ofile);
}//else
}//if
}//for
ofile << -1 << "\teq: num, posn\n";
/* Affected By */
num_written = 0;
affected_by.head(ss_cell);
while ((ss_ptr = ss_cell.next())) {
ofile << ss_ptr->stat_spell << " " << ss_ptr->bonus_duration << " ";
if ((++num_written % 20) == 0)
ofile << endl;
}//while
ofile << -1 << "\taffected_by\n";
/* Inventory */
num_written = 0;
inv.head(ob_cell);
while ((ob_ptr = ob_cell.next())) {
if (ob_ptr->IN_LIST) {
ofile << -2 << "\t Start of SOBJ\n";
ob_ptr->Write(ofile);
}//if
else {
ofile << ob_ptr->OBJ_NUM << " ";
if ((++num_written % 20) == 0)
ofile << endl;
}//else
}//while
ofile << -1 << "\tinv\n";
/* Do PC, MOB */
if (short_cur_stats[26] == 0) { // If its a pc
if (!pc) {
mudlog.log(ERROR, "ERROR: trying to write out pc_data when pc is NULL.\n");
return;
}//if
pc->Write(ofile); //write it out
}//if
else { //its a mob/smob
if (!mob) {
mudlog.log(ERROR, "ERROR: trying to write out mob_data when mob is NULL.\n");
return;
}//if
mob->Write(ofile); //write it out
}//else
ofile << "\tend_of_crit\n"; //done
}//Write....crit
#ifdef USEMYSQL
void critter::dbRead(int mob_num, int pc_num, short read_all) {
String wrong_a, wrong_c, wrong_r;
MYSQL_RES* result;
MYSQL_ROW row;
String query="select * from Critters where PC_NUM=";
query+=pc_num;
query+=" and MOB_NUM=";
query+=mob_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
row=mysql_fetch_row(result);
short_desc = row[CRITTBL_SHORT_DESC];
in_room_desc = row[CRITTBL_IN_ROOM_DESC];
long_desc = row[CRITTBL_LONG_DESC];
// might not be needed, but this saves re-querying when we actually do
wrong_a = row[CRITTBL_WRONG_ALIGN_MSG];
wrong_c = row[CRITTBL_WRONG_CLASS_MSG];
wrong_r = row[CRITTBL_WRONG_RACE_MSG];
long_data[0] = atol(row[CRITTBL_GOLD]);
long_data[1] = atol(row[CRITTBL_EXP_WORTH]);
long_data[2] = atol(row[CRITTBL_BANK_GOLD]);
short_cur_stats[0] = atoi(row[CRITTBL_POSITION]);
short_cur_stats[1] = atoi(row[CRITTBL_STR]);
short_cur_stats[2] = atoi(row[CRITTBL_INTELLIGENCE]);
short_cur_stats[3] = atoi(row[CRITTBL_CON]);
short_cur_stats[4] = atoi(row[CRITTBL_CHA]);
short_cur_stats[5] = atoi(row[CRITTBL_WIS]);
short_cur_stats[6] = atoi(row[CRITTBL_DEX]);
short_cur_stats[7] = atoi(row[CRITTBL_HIT]);
short_cur_stats[8] = atoi(row[CRITTBL_DAM]);
short_cur_stats[9] = atoi(row[CRITTBL_AC]);
short_cur_stats[10] = atoi(row[CRITTBL_ATTACKS]);
short_cur_stats[11] = atoi(row[CRITTBL_PAUSE_COUNT]);
short_cur_stats[12] = atoi(row[CRITTBL_SEX]);
short_cur_stats[13] = atoi(row[CRITTBL_CLASS]);
short_cur_stats[14] = atoi(row[CRITTBL_RACE]);
short_cur_stats[15] = atoi(row[CRITTBL_HP]);
short_cur_stats[16] = atoi(row[CRITTBL_MANA]);
short_cur_stats[17] = atoi(row[CRITTBL_MOV]);
short_cur_stats[18] = atoi(row[CRITTBL_ALIGNMENT]);
short_cur_stats[19] = atoi(row[CRITTBL_LEVEL]);
short_cur_stats[20] = atoi(row[CRITTBL_HOMETOWN]);
short_cur_stats[21] = atoi(row[CRITTBL_WIMPY]);
short_cur_stats[22] = atoi(row[CRITTBL_PRACTICES]);
short_cur_stats[23] = atoi(row[CRITTBL_HP_MAX]);
short_cur_stats[24] = atoi(row[CRITTBL_MANA_MAX]);
short_cur_stats[25] = atoi(row[CRITTBL_MOV_MAX]);
short_cur_stats[26] = atoi(row[CRITTBL_MOB_TYPE]);
short_cur_stats[27] = atoi(row[CRITTBL_DAM_REC_MOD]);
short_cur_stats[28] = atoi(row[CRITTBL_DAM_GIV_MOD]);
short_cur_stats[29] = atoi(row[CRITTBL_HEAT_RESIS]);
short_cur_stats[30] = atoi(row[CRITTBL_COLD_RESIS]);
short_cur_stats[31] = atoi(row[CRITTBL_ELECT_RESIS]);
short_cur_stats[32] = atoi(row[CRITTBL_SPELL_RESIS]);
short_cur_stats[33] = atoi(row[CRITTBL_RELIGION]);
short_cur_stats[34] = atoi(row[CRITTBL_FROM_ZONE]);
short_cur_stats[35] = atoi(row[CRITTBL_BHD_COUNT]);
short_cur_stats[36] = atoi(row[CRITTBL_BHD_SIDES]);
short_cur_stats[37] = atoi(row[CRITTBL_HP_REGEN]);
short_cur_stats[38] = atoi(row[CRITTBL_MANA_REGEN]);
short_cur_stats[39] = atoi(row[CRITTBL_MOV_REGEN]);
short_cur_stats[40] = atoi(row[CRITTBL_GUILD]);
short_cur_stats[41] = atoi(row[CRITTBL_WEIGHT]);
cur_stats[0] = atoi(row[CRITTBL_VIS_BITS]);
cur_stats[1] = atoi(row[CRITTBL_SEE_BITS]);
cur_stats[2] = atoi(row[CRITTBL_IN_ROOM]);
crit_flags.set(CRITFLAG_CAN_SEE_INV, atoi(row[CRITTBL_CAN_SEE_INVENTORY]));
crit_flags.set(CRITFLAG_USING_LIGHT, atoi(row[CRITTBL_USING_LIGHT_SOURCE]));
crit_flags.set(CRITFLAG_IS_FLYING, atoi(row[CRITTBL_IS_FLYING]));
crit_flags.set(CRITFLAG_HAS_BOAT, atoi(row[CRITTBL_HAS_BOAT]));
crit_flags.set(CRITFLAG_CAN_CLIMB, atoi(row[CRITTBL_CAN_CLIMB]));
crit_flags.set(CRITFLAG_GOSSIPS, atoi(row[CRITTBL_GOSSIPS]));
crit_flags.set(CRITFLAG_YELLS, atoi(row[CRITTBL_YELLS]));
crit_flags.set(CRITFLAG_GRATZ, atoi(row[CRITTBL_GRATZ]));
crit_flags.set(CRITFLAG_AUCTIONS, atoi(row[CRITTBL_AUCTIONS]));
crit_flags.set(CRITFLAG_SHOUTS, atoi(row[CRITTBL_SHOUTS]));
crit_flags.set(CRITFLAG_SAYS, atoi(row[CRITTBL_SAYS]));
crit_flags.set(CRITFLAG_TELLS, atoi(row[CRITTBL_TELLS]));
crit_flags.set(CRITFLAG_WIZNETS, atoi(row[CRITTBL_WIZNETS]));
crit_flags.set(CRITFLAG_IS_PARALYZED, atoi(row[CRITTBL_IS_PARALYZED]));
crit_flags.set(CRITFLAG_IS_PERM_SLEEPED, atoi(row[CRITTBL_IS_PERM_SLEEPED]));
crit_flags.set(CRITFLAG_IS_DUAL_WIELDING, atoi(row[CRITTBL_IS_DUAL_WIELDING]));
crit_flags.set(CRITFLAG_IS_SNEAK, atoi(row[CRITTBL_IS_SNEAKING]));
crit_flags.set(CRITFLAG_IN_USE, atoi(row[CRITTBL_IN_USE]));
crit_flags.set(CRITFLAG_CAN_DIVE, atoi(row[CRITTBL_CAN_DIVE]));
crit_flags.set(CRITFLAG_IS_HIDE, atoi(row[CRITTBL_IS_HIDE]));
if (short_cur_stats[26] == 0) {
if (!pc) {
pc = new pc_data;
} // if
pc->pc_data_flags.set(PCFLAG_FROZEN, atoi(row[CRITTBL_IS_FROZEN]));
pc->pc_data_flags.set(PCFLAG_GAGGED, atoi(row[CRITTBL_IS_GAGGED]));
pc->pc_data_flags.set(PCFLAG_HAS_IMM_DATA, atoi(row[CRITTBL_HAS_IMM_DATA]));
pc->pc_data_flags.set(PCFLAG_CLOAKED, atoi(row[CRITTBL_CLOAKED]));
pc->pc_data_flags.set(PCFLAG_TANK_GRAPH, atoi(row[CRITTBL_TANK_GRAPH]));
pc->pc_data_flags.set(PCFLAG_USING_CLIENT, atoi(row[CRITTBL_USING_CLIENT]));
pc->pc_data_flags.set(PCFLAG_AUTOEXIT, atoi(row[CRITTBL_AUTO_EXIT]));
pc->pc_data_flags.set(PCFLAG_NO_HASSLE, atoi(row[CRITTBL_NO_HASSLE]));
pc->pc_data_flags.set(PCLFAG_BRIEF, atoi(row[CRITTBL_BRIEF]));
pc->pc_data_flags.set(PCFLAG_AUTOSPLIT, atoi(row[CRITTBL_AUTOSPLIT]));
pc->pc_data_flags.set(PCFLAG_IS_BUILDER, atoi(row[CRITTBL_IS_BUILDER]));
pc->pc_data_flags.set(PCFLAG_AUTOLOOT, atoi(row[CRITTBL_AUTOLOOT]));
pc->pc_data_flags.set(PCFLAG_EXTRA_INFO, atoi(row[CRITTBL_EXTRA_INFO]));
pc->pc_data_flags.set(PCFLAG_CR_BEHIND, atoi(row[CRITTBL_CR_BEHIND]));
pc->pc_data_flags.set(PCFLAG_DO_CARRIAGE_RETURN, atoi(row[CRITTBL_DO_CARRIAGE_RETURN]));
pc->pc_data_flags.set(PCFLAG_CAN_DET_MAGIC, atoi(row[CRITTBL_CAN_DETECT_MAGIC]));
pc->pc_data_flags.set(PCFLAG_DETECT_INVENTORY, atoi(row[CRITTBL_DETECT_INVENTORY]));
pc->pc_data_flags.set(PCFLAG_SHOW_VNUMS, atoi(row[CRITTBL_SHOW_VNUMS]));
pc->pc_data_flags.set(PCFLAG_HAS_POOFIN_POOFOUT_MSG, atoi(row[CRITTBL_HAS_POOFIN_POOFOUT_MSG]));
pc->pc_data_flags.set(PCFLAG_PAGE_OUTPUT, atoi(row[CRITTBL_PAGE_OUTPUT]));
pc->pc_data_flags.set(PCFLAG_NO_WIZCHAT, atoi(row[CRITTBL_NO_WIZCHAT]));
pc->pc_data_flags.set(PCFLAG_HAS_COLORS, atoi(row[CRITTBL_HAS_COLORS]));
pc->pc_data_flags.set(PCFLAG_USE_COLOR, atoi(row[CRITTBL_USE_COLOR]));
pc->pc_data_flags.set(PCFLAG_HAS_LANGUAGE_CHOICE, atoi(row[CRITTBL_HAS_LANGUAGE_CHOICE]));
pc->pc_data_flags.set(PCFLAG_NO_SHOW_MOB_ENTRY, atoi(row[CRITTBL_NO_SHOW_NPC_ENTRY]));
pc->pc_data_flags.set(PCFLAG_NO_BEEP, atoi(row[CRITTBL_NO_BEEP]));
pc->pc_data_flags.set(PCFLAG_IS_REMORT, atoi(row[CRITTBL_IS_REMORT]));
pc->pc_data_flags.set(PCFLAG_HAS_SACRIFICED, atoi(row[CRITTBL_HAS_SACRIFICED]));
pc->password = row[CRITTBL_PASSWORD];
pc->birth_day = atoi(row[CRITTBL_BIRTH_DAY]);
pc->birth_year = atoi(row[CRITTBL_BIRTH_YEAR]);
pc->rent_day = atoi(row[CRITTBL_RENT_DAY]);
pc->rent_year = atoi(row[CRITTBL_RENT_YEAR]);
pc->last_login_time = atoi(row[CRITTBL_LAST_LOGIN_TIME]);
pc->total_time_online = atoi(row[CRITTBL_TOTAL_TIME_ONLINE]);
pc->age = atoi(row[CRITTBL_AGE]);
pc->hunger = atoi(row[CRITTBL_HUNGER]);
pc->thirst = atoi(row[CRITTBL_THIRST]);
pc->drugged = atoi(row[CRITTBL_DRUGGEDNESS]);
pc->pk_count = atoi(row[CRITTBL_PKILLS]);
pc->died_count = atoi(row[CRITTBL_DEATHS]);
pc->quest_points = atoi(row[CRITTBL_QUEST_POINTS]);
pc->lines_on_page = atoi(row[CRITTBL_LINES_ON_PAGE]);
pc->prompt = row[CRITTBL_PROMPT];
if (pc->pc_data_flags.get(PCFLAG_HAS_POOFIN_POOFOUT_MSG)) {
pc->poofin = row[CRITTBL_POOFIN_MSG];
pc->poofout = row[CRITTBL_POOFOUT_MSG];
} // if
if (pc->pc_data_flags.get(PCFLAG_IS_BUILDER))
pc->pc_data_flags.turn_on(PCFLAG_HAS_IMM_DATA);
if (pc->pc_data_flags.get(PCFLAG_HAS_IMM_DATA)) {
pc->imm_data = new immort_data;
pc->imm_data->imm_level = atoi(row[CRITTBL_IMM_LEVEL]);
} // if
if (pc->pc_data_flags.get(PCFLAG_HAS_COLORS)) {
pc->gos_str = row[CRITTBL_GOS_COLOR];
pc->say_str = row[CRITTBL_SAY_COLOR];
pc->yell_str = row[CRITTBL_YELL_COLOR];
pc->tell_str = row[CRITTBL_TELL_COLOR];
pc->desc_str = row[CRITTBL_DESC_COLOR];
pc->obj_list_str = row[CRITTBL_OBJ_LIST_COLOR];
pc->mob_list_str = row[CRITTBL_MOB_LIST_COLOR];
pc->dflt_str = row[CRITTBL_DEFAULT_COLOR];
pc->bk_str = row[CRITTBL_BACKGROUND_COLOR];
pc->battle_str = row[CRITTBL_BATTLE_COLOR];
pc->user1_str = row[CRITTBL_USER1_COLOR];
pc->user2_str = row[CRITTBL_USER2_COLOR];
pc->user3_str = row[CRITTBL_USER3_COLOR];
} // if
if (pc->pc_data_flags.get(PCFLAG_HAS_LANGUAGE_CHOICE))
pc->preferred_language = (LanguageE)(atoi(row[CRITTBL_PREFERRED_LANGUAGE]));
} // if
else {
if (!mob)
mob = new mob_data;
mob->mob_num = mob_num;
mob->setMaxInGame(atoi(row[CRITTBL_MAX_IN_GAME]));
mob->mob_data_flags.set(MOBFLAG_HAS_PROC_DATA, atoi(row[CRITTBL_HAS_PROC_DATA]));
mob->mob_data_flags.set(MOBFLAG_SCAVENGE, atoi(row[CRITTBL_SCAVENGE]));
mob->mob_data_flags.set(MOBFLAG_WANDER, atoi(row[CRITTBL_WANDER]));
mob->mob_data_flags.set(MOBFLAG_SHOULD_DO_PROCS, atoi(row[CRITTBL_SHOULD_DO_PROCS]));
mob->mob_data_flags.set(MOBFLAG_EDIBLE_CORPSE, atoi(row[CRITTBL_EDIBLE]));
mob->mob_data_flags.set(MOBFLAG_IS_BANKER, atoi(row[CRITTBL_IS_BANKER]));
mob->mob_data_flags.set(MOBFLAG_SESSILE, atoi(row[CRITTBL_IS_SESSILE]));
mob->mob_data_flags.set(MOBFLAG_NOT_HOMING, atoi(row[CRITTBL_NO_HOMING]));
mob->mob_data_flags.set(MOBFLAG_DISOLVABLE, atoi(row[CRITTBL_DISOLVABLE]));
mob->mob_data_flags.set(MOBFLAG_HAS_SKIN, atoi(row[CRITTBL_HAS_SKIN]));
mob->mob_data_flags.set(MOBFLAG_HAS_MOB_SCRIPT, atoi(row[CRITTBL_HAS_MOB_SCRIPTS]));
if (mob->mob_data_flags.get(CRITTBL_HAS_PROC_DATA)) {
mob->proc_data = new spec_data;
mob->proc_data->flag1.set(SPECFLAG_SHOPKEEPER,
atoi(row[CRITTBL_IS_SHOPKEEPER]));
mob->proc_data->flag1.set(SPECFLAG_TEACHER,
atoi(row[CRITTBL_IS_TEACHER]));
mob->proc_data->flag1.set(SPECFLAG_LET_SAME_CLASS_PASS,
atoi(row[CRITTBL_LET_SAME_CLASS_PASS]));
mob->proc_data->flag1.set(SPECFLAG_LET_SAME_RACE_PASS,
atoi(row[CRITTBL_LET_SAME_RACE_PASS]));
mob->proc_data->flag1.set(SPECFLAG_HAS_MOB_GIVE_PROC,
atoi(row[CRITTBL_HAS_MOB_GIV_PROC]));
mob->proc_data->flag1.set(SPECFLAG_HAS_MOB_SAY_PROC,
atoi(row[CRITTBL_HAS_MOB_SAY_PROC]));
mob->proc_data->flag1.set(SPECFLAG_HAS_MOB_BOW_PROC,
atoi(row[CRITTBL_HAS_MOB_BOW_PROC]));
mob->proc_data->flag1.set(SPECFLAG_HAS_MOB_CURSE_PROC,
atoi(row[CRITTBL_HAS_MOB_CURSE_PROC]));
mob->proc_data->flag1.set(SPECFLAG_PROC_WITH_SAME_RACE,
atoi(row[CRITTBL_PROC_WITH_SAME_RACE]));
mob->proc_data->flag1.set(SPECFLAG_PROC_WITH_SAME_ALIGN,
atoi(row[CRITTBL_PROC_WITH_SAME_ALIGN]));
mob->proc_data->flag1.set(SPECFLAG_PROC_WITH_SAME_CLASS,
atoi(row[CRITTBL_PROC_WITH_SAME_CLASS]));
mob->proc_data->flag1.set(SPECFLAG_HAS_AI,
atoi(row[CRITTBL_HAS_AI]));
if (mob->proc_data->flag1.get(SPECFLAG_SHOPKEEPER)) {
mob->proc_data->sh_data = new shop_data;
mob->proc_data->sh_data->markup = atoi(row[CRITTBL_MARKUP]);
mob->proc_data->sh_data->buy_percentage = atoi(row[CRITTBL_BUY_PERCENTAGE]);
mob->proc_data->sh_data->open_time = atoi(row[CRITTBL_OPEN_TIME]);
mob->proc_data->sh_data->close_time = atoi(row[CRITTBL_CLOSE_TIME]);
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_BUY0,
atoi(row[CRITTBL_BUY_0]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_SELL0,
atoi(row[CRITTBL_SELL_0]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_OFFER0,
atoi(row[CRITTBL_OFFER_0]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_PLAYER_OWNED,
atoi(row[CRITTBL_IS_PLAYER_OWNED]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_NON_WEAPON,
atoi(row[CRITTBL_BUYS_NON_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_SLASH,
atoi(row[CRITTBL_BUYS_SLASHING_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_SMASH,
atoi(row[CRITTBL_BUYS_SMASHING_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_PIERCE,
atoi(row[CRITTBL_BUYS_PIERCING_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_WHIP,
atoi(row[CRITTBL_BUYS_WHIPS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_NEEDS_AMMO,
atoi(row[CRITTBL_BUYS_AMMO_NEEDING_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_DART_THROWER,
atoi(row[CRITTBL_BUYS_DART_THROWERS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_BOW,
atoi(row[CRITTBL_BUYS_BOWS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_DART,
atoi(row[CRITTBL_BUYS_DARTS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_ARROW,
atoi(row[CRITTBL_BUYS_ARROWS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_JUNK,
atoi(row[CRITTBL_BUYS_JUNK]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_WAND,
atoi(row[CRITTBL_BUYS_WANDS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_POTION,
atoi(row[CRITTBL_BUYS_POTIONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_SCROLL,
atoi(row[CRITTBL_BUYS_SCROLLS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_CONTAINER,
atoi(row[CRITTBL_BUYS_CONTAINERS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_COINS,
atoi(row[CRITTBL_BUYS_COINS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_ARMOR,
atoi(row[CRITTBL_BUYS_ARMOR]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_WEAPON,
atoi(row[CRITTBL_BUYS_WEAPONS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_LIGHT_SOURCE,
atoi(row[CRITTBL_BUYS_LIGHTS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_CANTEEN,
atoi(row[CRITTBL_BUYS_CANTEENS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_LIQUID,
atoi(row[CRITTBL_BUYS_LIQUIDS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_FOOD,
atoi(row[CRITTBL_BUYS_FOOD]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_BOAT,
atoi(row[CRITTBL_BUYS_BOATS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_TOOLBOX,
atoi(row[CRITTBL_BUYS_TOOLBOXES]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_CAULDRON,
atoi(row[CRITTBL_BUYS_CAULDRENS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_PEN,
atoi(row[CRITTBL_BUYS_PENS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_CONSTRUCT_COMPONENT,
atoi(row[CRITTBL_BUYS_CONSTRUCT_COMPONENTS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_CONCOCT_COMPONENT,
atoi(row[CRITTBL_BUYS_CONCOCT_COMPONENTS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_PARCHMENT,
atoi(row[CRITTBL_BUYS_PARCHMENTS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_HERB,
atoi(row[CRITTBL_BUYS_HERBS]));
mob->proc_data->sh_data->shop_data_flags.set(
SHOPFLAG_VEND_MACHINE,
atoi(row[CRITTBL_BUYS_VENDING_MACHINES]));
} // if
if (mob->proc_data->flag1.get(SPECFLAG_TEACHER)) {
mob->proc_data->teach_data = new teacher_data;
mob->proc_data->teach_data->teach_data_flags.set(1,
CRITTBL_TEACHES_WARRIORS);
mob->proc_data->teach_data->teach_data_flags.set(2,
CRITTBL_TEACHES_SAGES);
mob->proc_data->teach_data->teach_data_flags.set(3,
CRITTBL_TEACHES_WIZARDS);
mob->proc_data->teach_data->teach_data_flags.set(4,
CRITTBL_TEACHES_RANGERS);
mob->proc_data->teach_data->teach_data_flags.set(5,
CRITTBL_TEACHES_THIEVES);
mob->proc_data->teach_data->teach_data_flags.set(6,
CRITTBL_TEACHES_ALCHEMISTS);
mob->proc_data->teach_data->teach_data_flags.set(7,
CRITTBL_TEACHES_CLERICS);
mob->proc_data->teach_data->teach_data_flags.set(8,
CRITTBL_TEACHES_BARDS);
} // if
if (mob->proc_data->flag1.get(SPECFLAG_HAS_AI)) {
mob->proc_data->setSkillViolence(
atoi(row[CRITTBL_SKILL_VIOLENCE]));
mob->proc_data->setBenevolence(atoi(row[CRITTBL_BENEVOLENCE]));
mob->proc_data->setDefensiveness(
atoi(row[CRITTBL_DEFENSIVENESS]));
mob->proc_data->setBadAssedness(
atoi(row[CRITTBL_BAD_ASSEDNESS]));
mob->proc_data->setSocialAwareness(
atoi(row[CRITTBL_SOCIAL_AWARENESS]));
} // if
} // if
if (mob->mob_data_flags.get(MOBFLAG_HAS_SKIN))
mob->skin_num = atoi(row[CRITTBL_SKIN]);
} // else
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
// names
query="select NAME from CritNames where MOB_NUMBER=";
query+=mob_num;
query+=" and PC_NUMBER=";
query+=pc_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
while ((row=mysql_fetch_row(result))) {
Put(new String(row[0]), names);
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
// equipment
query = "select POSITION, OBJ_NUM, SOBJ_NUM from CritEq where MOB_NUMBER=";
query+=mob_num;
query+=" and PC_NUMBER=";
query+=pc_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
int obj_num, sobj_num, pos;
while ((row=mysql_fetch_row(result))) {
pos = atoi(row[0]);
obj_num = atoi(row[1]);
sobj_num = atoi(row[2]);
if (check_l_range(pos, 1, MAX_EQ, mob_list[0], FALSE)) {
if (sobj_num != 0) {
object* new_obj = new object;
new_obj->dbRead(obj_num, sobj_num, read_all);
new_obj->IN_LIST = &(inv);
eq[pos] = new_obj;
} // if
else {
if (obj_list[obj_num].isInUse()) {
if (read_all || ((obj_list[obj_num].OBJ_PRCNT_LOAD *
config.currentLoadModifier)/100) > d(1,100)) {
eq[pos]=&obj_list[obj_num];
} // if
} // if
} // else
} // if
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
// affected by
query="select SPELL_NUMBER, DURATION from CritSpells where MOB_NUMBER=";
query+=mob_num;
query+=" and PC_NUM=";
query+=pc_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
stat_spell_cell* ss_ptr;
while ((row=mysql_fetch_row(result))) {
ss_ptr = new stat_spell_cell;
ss_ptr->stat_spell = atoi(row[0]);
ss_ptr->bonus_duration = atoi(row[1]);
Put(ss_ptr, affected_by);
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
// inventory
query="select OBJ_NUM, SOBJ_NUM, QUANTITY from CritInv where MOB_NUMBER=";
query+=mob_num;
query+=" and PC_NUMBER=";
query+=pc_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
int quantity, obj_num, sobj_num;
while ((row=mysql_fetch_row(result))) {
obj_num = atoi(row[0]);
sobj_num = atoi(row[1]);
quantity = atoi(row[2]);
for (;quantity > 0; quantity--) {
if (sobj_num != 0) {
object* new_obj = new object;
new_obj->dbRead(obj_num, sobj_num, read_all);
new_obj->IN_LIST = &inv;
Put(new_obj, inv);
affected_objects.append(new_obj);
} // if
else {
if (obj_list[obj_num].OBJ_FLAGS.get(OBJFLAG_IN_USE)) {
if (read_all || ((obj_list[obj_num].OBJ_PRCNT_LOAD *
config.currentLoadModifier)/100) > d(1, 100)) {
Put(&obj_list[obj_num], inv);
} // if
} // if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: trying to load non-existant object: "
<< obj_num << " in critter named: " << *(getName())
<< endl;
} // if
} // else
} // else
} // for
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
// known skills (pc's only)
if (pc) {
String query="select SKILL_NUMBER, PERCENT_LEARNED from CritLrnd where PC_NUM=";
query+=pc_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
while((row=mysql_fetch_row(result))) {
pc->skills_spells_known.Insert(atoi(row[0]), atoi(row[1]));
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
} // if
// procs (mobs only)
if (mob && mob->proc_data) {
if (mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_GIVE_PROC)) {
mob->proc_data->give_proc = new action_proc_data;
query="select * from CritProcs where MOB_NUMBER=";
query+=mob_num;
query+=" and PROC_TYPE=";
query+=PROCTYPE_GIVE;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
row=mysql_fetch_row(result);
mob->proc_data->give_proc->test_num = atoi(row[CRPTBL_TEST_ONUM]);
mob->proc_data->give_proc->correct_msg = row[CRPTBL_CORRECT_MSG];
mob->proc_data->give_proc->skill_name = row[CRPTBL_SKILL_NAME];
mob->proc_data->give_proc->trans_to_room = atoi(row[CRPTBL_TRANS_ROOM]);
mob->proc_data->give_proc->wrong_gift_msg = row[CRPTBL_INCORRECT_MSG];
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
if (mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_BOW_PROC)) {
mob->proc_data->bow_proc = new action_proc_data;
query="select * from CritProcs where MOB_NUMBER=";
query+=mob_num;
query+=" and PROC_TYPE=";
query+=PROCTYPE_BOW;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
row=mysql_fetch_row(result);
mob->proc_data->bow_proc->test_num = atoi(row[CRPTBL_TEST_ONUM]);
mob->proc_data->bow_proc->correct_msg = row[CRPTBL_CORRECT_MSG];
mob->proc_data->bow_proc->skill_name = row[CRPTBL_SKILL_NAME];
mob->proc_data->bow_proc->trans_to_room = atoi(row[CRPTBL_TRANS_ROOM]);
mob->proc_data->bow_proc->wrong_gift_msg = row[CRPTBL_INCORRECT_MSG];
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
if (mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_CURSE_PROC)) {
mob->proc_data->curse_proc = new action_proc_data;
query="select * from CritProcs where MOB_NUMBER=";
query+=mob_num;
query+=" and PROC_TYPE=";
query+=PROCTYPE_CURSE;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
row=mysql_fetch_row(result);
mob->proc_data->curse_proc->test_num = atoi(row[CRPTBL_TEST_ONUM]);
mob->proc_data->curse_proc->correct_msg = row[CRPTBL_CORRECT_MSG];
mob->proc_data->curse_proc->skill_name = row[CRPTBL_SKILL_NAME];
mob->proc_data->curse_proc->trans_to_room = atoi(row[CRPTBL_TRANS_ROOM]);
mob->proc_data->curse_proc->wrong_gift_msg = row[CRPTBL_INCORRECT_MSG];
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
if (mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_SAY_PROC)) {
// say proc
say_proc_cell* ptr;
query="select * from CritProcs where MOB_NUMBER=";
query+=mob_num;
query+=" and PROC_TYPE=";
query+=PROCTYPE_SAY;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
while ((row=mysql_fetch_row(result))) {
ptr = new say_proc_cell;
ptr->topic = row[CRPTBL_PROC_TOPIC];
ptr->msg = row[CRPTBL_CORRECT_MSG];
ptr->skill_name = row[CRPTBL_SKILL_NAME];
ptr->obj_num = atoi(row[CRPTBL_TEST_ONUM]);
ptr->trans_to_room = atoi(row[CRPTBL_TRANS_ROOM]);
mob->proc_data->topics.append(ptr);
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
if (mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_GIVE_PROC) ||
mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_SAY_PROC) ||
mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_BOW_PROC) ||
mob->proc_data->flag1.get(SPECFLAG_HAS_MOB_CURSE_PROC)) {
mob->proc_data->wrong_align_msg = wrong_a;
mob->proc_data->wrong_class_msg = wrong_c;
mob->proc_data->wrong_race_msg = wrong_r;
} // if
else {
delete wrong_a;
delete wrong_c;
delete wrong_r;
} // else
// scripts
if (mob->mob_data_flags.get(MOBFLAG_HAS_MOB_SCRIPT)) {
query="select * from CritScripts where MOB_NUMBER=";
query+=mob_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
MobScript* ptr;
while ((row=mysql_fetch_row(result))) {
String* tmp_disc = new String(row[CRSTBL_DISCRIMINATOR]);
tmp_disc->Strip();
tmp_disc->Prepend(" ");
tmp_disc->Append(" ");
ptr = new MobScript(*(new String[CRSTBL_TRIGGER_CMD]),
atoi(row[CRSTBL_TARGET]),
atoi(row[CRSTBL_ACTOR]),
*tmp_disc,
atoi(row[CRSTBL_PRECEDENCE]));
String sbuf, *tmp_str;
sbuf=row[CRSTBL_SCRIPT_COMMANDS];
while ((tmp_str = sbuf.getUntil(';'))) {
ptr->appendCmd(*tmp_str);
delete tmp_str;
} // while
Put(ptr, mob->mob_proc_scripts);
ptr->compile();
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
} // if
return;
} // else
} // if
} // if
// shop inventory
if (mob && mob->proc_data && mob->proc_data->sh_data) {
query="select OBJECT_NUMBER, SOBJ_NUMBER, QUANTITY from CritPermInv where MOB_NUMBER=";
query+=mob_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
int quantity, obj_num, sobj_num;
while ((row=mysql_fetch_row(result))) {
obj_num = atoi(row[0]);
sobj_num = atoi(row[1]);
quantity = atoi(row[2]);
for (;quantity>0;quantity--) {
if (sobj_num != 0) {
object* new_obj = new object;
new_obj->dbRead(obj_num, sobj_num, read_all);
new_obj->IN_LIST = &mob->proc_data->sh_data->perm_inv;
mob->proc_data->sh_data->perm_inv.append(new_obj);
} // if
else {
if (obj_list[obj_num].OBJ_FLAGS.get(OBJFLAG_IN_USE)) {
if (read_all || ((obj_list[obj_num].OBJ_PRCNT_LOAD*
config.currentLoadModifier)/100) > d(1,100)) {
mob->proc_data->sh_data->perm_inv.append(&obj_list[obj_num]);
} // if
} // if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: Trying to load non-existant object: "
<< obj_num << " on shopkeeper " << mob_num;
} // if
} // else
} // else
} // for
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
// player shop inventory
if (mob && mob->proc_data && mob->proc_data->sh_data &&
mob->proc_data->sh_data->isPlayerRun()) {
query="select OBJECT_NUMBER, SELL_AT, BUY_AT where MOB_NUMBER=";
query+=mob_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
} // if
return;
} // if
PlayerShopData* ps_data;
while ((row=mysql_fetch_row(result))) {
ps_data = new PlayerShopData(atoi(row[0]), atoi(row[1]),
atoi(row[2]));
mob->proc_data->sh_data->ps_data_list.pushBack(ps_data);
} // while
mysql_free_result(result);
} // if
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In critter::dbRead(int, int, short):\n";
mudlog << "Error executing query: " << mysql_error(database)
<< endl;
} // if
return;
} // else
} // if
if (!is_affected_by(BLINDNESS_SKILL_NUM, *this)) {
SEE_BIT |= 1024;
} // if
} // critter::dbRead()
#endif
void critter::fileRead(ifstream& ofile, short read_all) {
int i, test = TRUE, z;
stat_spell_cell* ss_ptr;
char tmp[81];
String tmp_str(80);
String* string;
Clear();
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in crit read." << endl;
}
return;
}
test = TRUE;
while (test) {
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in crit read." << endl;
}
return;
}
ofile >> tmp_str;
if (strcmp(tmp_str, "~") == 0) {
test = FALSE;
}//if
else {
string = new String(tmp_str);
Put(string, names);
}//else
}//while
ofile.getline(tmp, 80);
short_desc.Termed_Read(ofile);
in_room_desc.Termed_Read(ofile);
long_desc.Termed_Read(ofile);
crit_flags.Read(ofile);
crit_flags.turn_on(18); //always in use
crit_flags.turn_off(25); // Never been hurled before.
setComplete(); //if we can read it, it's complete enough!
for (i = 0; i<MOB_LONG_DATA; i++)
ofile >> long_data[i];
ofile.getline(tmp, 80);
for (i = 0; i<MOB_SHORT_CUR_STATS; i++) {
ofile >> short_cur_stats[i];
}
ofile.getline(tmp, 80);
for (i = 0; i<MOB_CUR_STATS; i++) {
ofile >> cur_stats[i];
}
ofile.getline(tmp, 80);
/* EQ, read in item_num, posn */
ofile >> i;
while (i != -1) {
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in crit read." << endl;
}
return;
}
ofile >> z;
if (!check_l_range(z, 1, MAX_EQ, mob_list[0], FALSE)) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: wear_posn out of range, crit.Read(): " << z
<< " short desc: " << short_desc << endl;
}
ofile >> i;
continue;
}//if
if (i == -2) { //gonna load fer sure
object* new_obj = new object;
ofile.getline(tmp, 80); //junk message
new_obj->fileRead(ofile, TRUE);
new_obj->IN_LIST = &(inv); //make sure its a SOBJ
eq[z] = new_obj; //now it wears it
affected_objects.append(new_obj);
}//if
else {
if (obj_list[i].isInUse()) { //exists?
if (read_all ||
((obj_list[i].OBJ_PRCNT_LOAD * config.currentLoadModifier)/
100) > d(1,100)) {
eq[z] = &(obj_list[i]); //now it wears it
}//if
}//
else {
Sprintf(tmp_str,
"ERROR: trying to load non-existant obj: %i,
in critter's: %S eq.\n", i, &short_desc);
mudlog.log(ERROR, tmp_str);
}//else
}//else
ofile >> i;
}//while
ofile.getline(tmp, 80);
/* Affected By */
ofile >> i;
while (i != -1) {
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in crit read." << endl;
}
return;
}
ss_ptr = new stat_spell_cell;
ss_ptr->stat_spell = i;
ofile >> ss_ptr->bonus_duration;
Put(ss_ptr, affected_by);
ofile >> i;
}//while
ofile.getline(tmp, 80);
/* Inventory */
ofile >> i;
while (i != -1) {
if (!ofile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: da_file FALSE in crit read." << endl;
}
return;
}
if (i == -2) { //gonna load fer sure
object* new_obj = new object;
ofile.getline(tmp, 80); //junk message
new_obj->fileRead(ofile, TRUE);
new_obj->IN_LIST = &(inv); //make sure its a SOBJ
Put(new_obj, inv); //add it to inventory
affected_objects.append(new_obj);
}//if
else {
if (obj_list[i].OBJ_FLAGS.get(10)) {
if (read_all ||
((obj_list[i].OBJ_PRCNT_LOAD * config.currentLoadModifier)/100) >
d(1,100)) {
Put(&(obj_list[i]), inv); //add it to inventory
}//if
}//if
else {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: trying to load non-existant object: " << i
<< " in critter named: " << *(getName()) << endl;
}
}//else
}//else
ofile >> i;
}//while
ofile.getline(tmp, 80);
/* Do PC, MOB */
if (short_cur_stats[26] == 0) { // If its a pc
if (!(pc)) {
pc = new pc_data;
}//if
pc->Read(ofile);
}//if
else { //its a mob
if (!(mob)) {
mob = new mob_data;
}//if
mob->Read(ofile, read_all);
}//else
ofile.getline(tmp, 80);
//mudlog.log(DBG, "Done w/read crit.\n");
if (!is_affected_by(BLINDNESS_SKILL_NUM, *this))
SEE_BIT |= 1024; //another bletcherous kludge
}//Read....crit
void critter::notifyHasBeenHurled() {
if ((getLevel() > 10) || (INT > 14)) { //experienced and smart folks remember
CRIT_FLAGS.turn_on(25);
}
}
int critter::shouldBeHoming() {
return (mob && isSmob() && !mob->isNoHoming() && !isTracking() &&
(getHomeRoom() != getCurRoomNum()));
}
int critter::canBeHurled() {
if (!isPc()) {
return !(CRIT_FLAGS.get(25));
}
return TRUE; //Pc's can always be hurled.
}
int critter::haveObjNumbered(int cnt, int obj_num) {
Cell<object*> cll(inv);
object* ptr;
int count = 0;
if (mudlog.ofLevel(DBG)) {
mudlog << "haveObjNumbered: cnt: " << cnt << " obj_num: "
<< obj_num << endl;
}
if (cnt == 0)
return FALSE;
while ((ptr = cll.next())) {
count += ptr->getObjCountByNumber(obj_num, 0);
if (ptr->getIdNum() == obj_num) {
count++;
}//if obj nums agree
if (count >= cnt) {
return TRUE;
}//if
}//while
for (int i = 0; i<MAX_EQ; i++) {
if ((ptr = eq[i])) {
count += ptr->getObjCountByNumber(obj_num, 0);
if (ptr->OBJ_NUM == obj_num) {
count++;
}//if obj nums agree
if (count >= cnt) {
return TRUE;
}//if
}//if
}//for
return FALSE;
}//haveObjectNumbered
void critter::setIdNum(int i) {
if (mob)
mob->mob_num = i;
}
void critter::setNoClient() {
if (!pc) return;
PC_FLAGS.turn_off(5);
setClient(NO_CLIENT);
}
void critter::setImmLevel(int i) {
if (pc && pc->imm_data) {
if (i < 0)
i = 0;
if (i > 10)
i = 10;
pc->imm_data->imm_level = i;
}//if
}
int critter::getIdNum() const {
if (mob) {
return mob->mob_num;
}
return 0;
}
// NOTE: The script owner is *this. It is likely, but not necessary
// that targ is also *this. Looks through all the objects the critter
// is wearing.
void critter::checkForProc(String& cmd, String& arg1, critter& actor,
int targ, room& rm) {
if (mudlog.ofLevel(DBG)) {
mudlog << "In critter::checkForProc, this#: " << getIdNum()
<< " actor#: " << actor.getIdNum() << " cmd -:"
<< cmd << ":- arg1 -:" << arg1 << ":- targ: "
<< targ << " room#: " << rm.getIdNum() << endl;
}
String buf(100);
if (mob) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Was a mob, mob#: " << MOB_NUM << endl;
}
Cell<MobScript*> cll;
MobScript* ptr;
mob->mob_proc_scripts.head(cll);
while ((ptr = cll.next())) {
//mudlog.log("In while.");
//mudlog.log(ptr->toStringBrief(0, 0));
if (ptr->matches(cmd, arg1, actor, targ)) {
//mudlog.log("Matches..");
if (mob->pending_scripts.size() >= 10) { //only queue 10 scripts
break; //do nothing, don't want to get too much backlog.
}
else {
// add it to the pending scripts.
ptr->generateScript(cmd, arg1, actor, targ, rm, this);
insertNewScript(new MobScript(*ptr));
if (mob->cur_script) {
if (mob->cur_script->getPrecedence() <
mob->pending_scripts.peekFront()->getPrecedence()) {
mob->pending_scripts.loseData(mob->cur_script); //take it out of queue
delete mob->cur_script; //junk it!
mob->cur_script = mob->pending_scripts.peekFront();
mob->cur_script->resetStackPtr(); //get ready to start
}//if
if (!proc_action_mobs.haveData(this)) {
int idx = proc_action_mobs.gainData(this);
mudlog << "ERROR: had to add mob to proc_action_mobs....but"
<< " should have already been in there, idx: " << idx
<< " me: " << *(getName()) << endl;
Sprintf(buf, "ERROR: Just had to add you to the proc_action_mobs, idx: %i\n",
idx);
this->show(buf);
}
// else, it just goes into the queue
}//if we currently have a script.
else { //there was none, so grab the first one.
mob->cur_script = mob->pending_scripts.peekFront();
int idx = proc_action_mobs.gainData(this);
Sprintf(buf, "Just added you to the proc_action_mobs, idx: %i\n",
idx);
this->show(buf);
mob->cur_script->resetStackPtr(); //get ready to start
}
break;
}//else
}//if matches
}//while
}//if
// Look through all objects the person is using.
for (int i = 1; i < MAX_EQ; i++) {
if (mudlog.ofLevel(DBG2)) {
mudlog << "Critter [" << getIdNum() << "] " << *(getName())
<< ": Checking EQ[" << i << "] == " << EQ[i] << ", in rm: "
<< rm.getIdNum() << endl;
}
if (EQ[i] && (EQ[i]->hasScript())) {
if (mudlog.ofLevel(DBG2))
mudlog << "Found an object with a script: EQ[" << i << "]\n";
// make it modified, if it is not already so.
if (!(EQ[i]->isModified())) {
EQ[i] = obj_to_sobj(*(EQ[i]), &inv, rm.getIdNum());
}
EQ[i]->checkForProc(cmd, arg1, actor, targ, rm);
}//if
}//for
// Look through all inventory (recursively)
Cell<object*> cll(inv);
object* ptr;
while ((ptr = cll.next())) {
if (ptr->hasScript()) {
if (!ptr->isModified()) {
object* tmp = ptr;
ptr = obj_to_sobj(*ptr, &inv, getCurRoomNum());
if (!inv.substituteData(tmp, ptr, 1)) {
mudlog.log(ERROR, "ERROR: critter::checkForProc: substituteData failed after obj_to_sobj.\n");
}//if
}
ptr->checkForProc(cmd, arg1, actor, targ, rm);
}//if
}//while
}//checkForProcAction
int critter::insertNewScript(MobScript* script) {
if (!mob)
return -1;
// Don't append scripts that have a zero precedence, if there
// are other scripts in the queue.
if ((script->getPrecedence() == 0) && (!mob->pending_scripts.isEmpty())) {
delete script;
return 0;
}
MobScript* ptr;
Cell<MobScript*> cll(mob->pending_scripts);
while ((ptr = cll.next())) {
if (ptr->getPrecedence() < script->getPrecedence()) {
// Then insert it
mob->pending_scripts.insertBefore(cll, script);
return 0;
}//if
}//while
// If here, then we need to place it at the end.
mob->pending_scripts.append(script);
return 0;
}
void critter::trackToKill(critter& vict, int& is_dead) {
if ((isMob()) || (vict.isMob())) {
mudlog.log(ERROR, "ERROR: MOB's in trackToKill.\n");
return;
}//f
if (!mob) {
mudlog.log(ERROR, "ERROR: pc trying to track_to_kill.\n");
return;
}//if
// Not going to track non-player characters, don't move if sessile
if (vict.isNpc() || isSessile())
return;
remember(vict);
if (isSentinel())
return;
setTrackingTarget(*(vict.getShortName()));
doHuntProc(5, is_dead);
}//track_to_kill
void critter::setTrackingTarget(const String& targ_name) {
if (!mob)
return;
if (!mob->proc_data)
mob->proc_data = new spec_data();
if (!mob->proc_data->temp_proc)
mob->proc_data->temp_proc = new temp_proc_data();
TRACKING = targ_name;
}
int critter::getBenevolence() const {
if (isPc() || !mob) {
return 0;
}
else {
return mob->getBenevolence();
}
}//getAggressiveness
int critter::isSentinel() const {
if (isPc() || !mob) {
return FALSE;
}
else {
return mob->isSentinel();
}
}//isSentinel
void critter::doRemoveFromBattle() {
if (!IS_FIGHTING.isEmpty()) {
Cell<critter*> cll(IS_FIGHTING);
critter* crit_ptr;
while ((crit_ptr = cll.next())) {
crit_ptr->IS_FIGHTING.loseData(this);
}//while
IS_FIGHTING.clear();
}//if
}//doRemoveFromBattle
void critter::doGoToRoom(int dest_room, const char* from_dir, door* by_door,
int& is_dead, int cur_room, int sanity, int do_msgs) {
if (mudlog.ofLevel(DBG)) {
mudlog << "In doGoToRoom, dest_room: " << dest_room
<< " cur_room: " << cur_room
<< " by_door: " << by_door << endl;
}
doRemoveFromBattle();
leave_room_effects(room_list[cur_room], *this);
// If we are in earth-meld, break it.
breakEarthMeld();
room_list[cur_room].removeCritter(this);
room_list[dest_room].gainCritter(this);
// This can cause us to delete ourselves btw...not very good coding
// but..maybe it will work!
do_entered_room_procs(*this, by_door, from_dir, room_list[dest_room],
is_dead, sanity);
if (!is_dead && do_msgs) {
look(1, &NULL_STRING, *this, FALSE); //don't ignore brief
}
}//doGoToRoom
stat_spell_cell* critter::isAffectedBy(int spell_num) {
return is_affected_by(spell_num, *this);
}
void critter::breakEarthMeld() {
stat_spell_cell* sp;
if ((sp = is_affected_by(EARTHMELD_SKILL_NUM, *this))) {
show("Your meld with the earth has been severed.\n");
affected_by.loseData(sp);
delete sp;
}//if
}//breakEarthMeld
int critter::isNamed(const String& name) const {
Cell<String*> char_cell(names);
String *string;
if (name.Strlen() == 0)
return FALSE;
int len = name.Strlen();
while ((string = char_cell.next())) {
if (strncasecmp(*string, name, len) == 0) {
return TRUE;
}//if
}//while
return FALSE;
}//mob_is_named
object* critter::loseInv(object* obj) {
return inv.loseData(obj);
}
void critter::loseObjectFromGame(object* obj) {
// first, check EQ
if (mudlog.ofLevel(DBG)) {
mudlog << "loseObjectFromGame, obj num: " << obj->getIdNum()
<< " pc's name: " << getName() << endl;
}
for (int i =1; i<MAX_EQ; i++) {
if (EQ[i] && (EQ[i]->getIdNum() == obj->getIdNum())) {
remove_eq_effects(*obj, *this, FALSE, FALSE, i);
if (EQ[i]->IN_LIST) {
delete EQ[i];
}
EQ[i] = NULL;
}//if
}//for
Cell<object*> cll(inv);
object* ptr;
ptr = cll.next();
while (ptr) {
if (ptr->getIdNum() == obj->getIdNum()) {
if (ptr->IN_LIST) {
delete ptr;
}
ptr = inv.lose(cll);
}//if
else {
ptr = cll.next();
}
}//while
}//loseObjectFromGame
void critter::gainInv(object* obj) {
inv.prepend(obj);
if (obj->IN_LIST) {
obj->IN_LIST = &inv;
obj->setCurRoomNum(getCurRoomNum(), 0);
}
}
void critter::setHP(int i) {
if (i < 0)
i = 0;
if (i > 32000)
i = 32000;
HP = i;
}
void critter::setMana(int i) {
if (i > 32000)
i = 32000;
MANA = i;
}
void critter::setMov(int i) {
if (i > 32000)
i = 32000;
MOV = i;
}
void critter::show(const char* msg) {
::show(msg, *this);
}
void critter::show(CSentryE which_string) {
show(CSHandler::getString(which_string, getLanguageChoice()));
}
LanguageE critter::getLanguageChoice() const {
if (pc) {
return pc->preferred_language;
}
return English;
}
void critter::setHP_MAX(int i) {
if (i < 0)
i = 0;
if (i > 32000)
i = 32000;
short_cur_stats[23] = i; //MAX_HP of course...
}
void critter::setManaMax(int i) {
if (i < 0)
i = 0;
if (i > 32000)
i = 32000;
short_cur_stats[24] = i;
}
void critter::setMovMax(int i) {
if (i < 0)
i = 0;
if (i > 32000)
i = 32000;
short_cur_stats[25] = i;
}
// set in_room to zero
void critter::doLeaveRoom() {
room_list[IN_ROOM].removeCritter(this);
IN_ROOM = 0;
}//doLeaveRoom
room* critter::getCurRoom() {
return &(room_list[IN_ROOM]);
}
void critter::doSuicide() {
if (!isPc())
return;
String buf(100);
if (mudlog.ofLevel(DBG)) {
mudlog << "In doSuicide, pc: " << *(getName()) << endl;
}
buf = *(Top(names));
buf.Tolower();
buf.Prepend("rm ./Pfiles/");
system(buf);
Sprintf(buf, "leaves this world forever by %s own hand!\n",
get_his_her(*this));
::emote(buf, *this, *(getCurRoom()), TRUE);
setMode(MODE_QUIT_ME_PLEASE);
}//doSuicide
void critter::setMode(PcMode val) {
mudlog << "Setting mode to: " << (int)val << endl;
pc->mode = val;
}
void critter::emote(const char* msg) {
::emote(msg, *this, room_list[getCurRoomNum()], TRUE);
}
void critter::pemote(const char* msg) {
::pemote(msg, *this, room_list[getCurRoomNum()], TRUE);
}
void critter::emote(CSelectorColl& includes, CSelectorColl& denies,
CSentryE cs_entry, .../*Sprintf args*/) {
va_list argp;
va_start(argp, cs_entry);
getCurRoom()->vDoEmote(*this, includes, denies, cs_entry, argp);
va_end(argp);
}//emote
void critter::doPrompt() {
if (!pc) {
return;
}
int i;
String targ(200);
int source_len = PROMPT_STRING.Strlen();
for (i = 0; i < source_len; ) {
if (PROMPT_STRING[i] == '%') {
i++;
if (i >= source_len) {
break;
}
if (PROMPT_STRING[i] != '%') {
switch (PROMPT_STRING[i]) {
case 'N': /* newline */
targ.Append("\n");
break;
case 'h': /* cur hp */
targ.Append(HP);
break;
case 'H': /* max hp */
targ.Append(HP_MAX);
break;
case 'v': /* cur mov */
targ.Append(MOV);
break;
case 'V': /* max mov */
targ.Append(MV_MAX);
break;
case 'm': /* cur mana */
targ.Append(MANA);
break;
case 'M': /* max mana */
targ.Append(MA_MAX);
break;
default:
targ.Append(PROMPT_STRING[i]);
}//switch
i++;
}//if
else { //
i++;
targ.Append("%");
}//else
}//if
else {
targ.Append(PROMPT_STRING[i]);
i++;
}//else
}//for
targ.Append(pc->input);
show(targ);
if (isUsingClient()) {
// HP, HP-MAX, MANA, MANA-MAX, MOV, MOV-MAX
Sprintf(targ, "<PROMPT %i %i %i %i %i %i> ", // the trailing space is important.
getHP(), getHP_MAX(), getMana(), getManaMax(),
getMov(), getMovMax());
show(targ);
}
}//doPrompt
critter* critter::getFirstFighting() {
return IS_FIGHTING.peekFront();
}
int critter::getCurZoneNum() {
return getCurRoom()->getZoneNum();
}
int critter::shouldSeeInventory() {
return ((pc && PC_FLAGS.get(19)) ||
(possessed_by && possessed_by->pc && possessed_by->PC_FLAGS.get(19)));
}
int critter::shouldShowVnums() {
return ((pc && pc->imm_data && !PC_FLAGS.get(20)) ||
(possessed_by && possessed_by->pc
&& possessed_by->pc->imm_data && !possessed_by->PC_FLAGS.get(20)));
}
int critter::shouldDoAutoExits() {
return ((pc && PC_FLAGS.get(6)) ||
(possessed_by && possessed_by->pc && possessed_by->PC_FLAGS.get(6)));
}
int critter::getImmLevel() {
if (pc && pc->imm_data)
return pc->imm_data->imm_level;
return 0;
}
void critter::setCurRoomNum(int i) {
if (i < 0)
i = 0;
if (i >= NUMBER_OF_ROOMS)
i = 0;
IN_ROOM = i;
// The first time we are placed in a room, lets remember it
// so we can get home once we've tracked down anybody that is
// bothering us!!
if (mob && (mob->home_room == 0)) {
mob->home_room = i;
}
// So now I want to know the current room for all Objects that
// may be scripting. If they are scripting, then we know they
// have an IN_LIST (ie they are a SOBJ (more antiquity)).
// First, check all equipment. Remember to check inside containers
// too.
for (int z = 1; z < MAX_EQ; z++) {
if (EQ[z] && EQ[z]->isModified()) {
EQ[z]->setCurRoomNum(i, 0); //will recurse if needed
}
}
Cell<object*> cll(inv);
object* ptr;
while ((ptr = cll.next())) {
if (ptr->isModified()) {
ptr->setCurRoomNum(i, 0); //is recursive if needed
}
}//while
}//setCurRoomNum
void critter::addProcScript(const String& txt, MobScript* script_data) {
if (mob)
mob->addProcScript(txt, script_data);
}//addProcScript
/** If return is > 0, self is more powerful, if less than 0,
* b is more powerful... The larger/smaller the value, the more
* extreme the difference.
*/
int critter::compareTo(critter& b) { //is a weaker than b
int str_a = 0;
int str_b = 0;
str_a += HP * 3 + MANA + DAM * 15 + HIT * 5 + LEVEL * 4 + STR;
str_b += b.HP * 3 + b.MANA + b.DAM * 15 + b.HIT * 5 + b.LEVEL * 4 + b.STR;
if (pc)
str_a += 20;
if (b.pc)
str_b += 20;
str_a *= ATTACKS;
str_b *= b.ATTACKS;
return (str_a - str_b);
}//compareTo
String* critter::getTrackingTarget() {
if (mob && mob->proc_data && mob->proc_data->temp_proc)
return &(TRACKING);
return &NULL_STRING;
}
void critter::unPossess() {
if (possessing) {
possessing->possessed_by = NULL;
possessing = NULL;
}
}//unpossess
int critter::isUsingClient() const {
return ((pc && pc->pc_data_flags.get(5)) ||
(possessed_by && possessed_by->pc->pc_data_flags.get(5)));
}//isUsingClient
int critter::whichClient() {
if (pc)
return pc->client;
else
return 0;
}//whichClient
bool critter::setClient(int which) {
if (NUM_CLIENTS < which)
return false;
if(!pc->pc_data_flags.get(5))
return false;
pc->client = which;
return true;
}
int critter::isBrief() {
return ((pc && pc->pc_data_flags.get(8)) ||
(possessed_by && possessed_by->pc->pc_data_flags.get(8)));
}//isBrief
int critter::isGagged() {
return (pc && PC_FLAGS.get(1));
}
int critter::isFrozen() {
return (pc && PC_FLAGS.get(0));
}
int critter::isWizchat() const {
return (pc && PC_FLAGS.get(24));
}
int critter::isImmort() {
return (pc && pc->imm_data);
}
int critter::isFlying() {
return (crit_flags.get(3));
}
int critter::isParalyzed() {
return (crit_flags.get(14));
}
int critter::canClimb() {
return (crit_flags.get(5) ||
(d(1, 100) < d(1,
get_percent_lrnd(CLIMBING_SKILL_NUM, *this)
* 4 + 10)));
}//canClimb
void critter::drunkifyMsg(String& msg) {
char ch;
if (pc && (pc->drugged > 0)) {
for (int i = 0; i<msg.Strlen(); i++) {
if ((msg.charAt(i) != '<') && (d(1, 15) < d(1, pc->drugged))) {
ch = (char)(d(1, 52) + 41);
// Don't want to translate < in case of hegemon markup messups.
if (ch == '<') {
ch = '!';
}
msg.setCharAt(i, ch);
}//if
}//for
}//if
}//drunkifyMsg
int critter::shouldDoPoofin() {
return (pc && PC_FLAGS.get(21));
}
int critter::shouldDoPoofout() {
return (pc && PC_FLAGS.get(21));
}
String& critter::getPoofin() {
if (pc)
return pc->poofin;
return NULL_STRING;
}
String& critter::getPoofout() {
if (pc)
return pc->poofout;
return NULL_STRING;
}
int critter::isInUse() const {
return CRIT_FLAGS.get(18);
}
void critter::setComplete() {
CRIT_FLAGS.turn_off(24);
}
void critter::setNotComplete() {
CRIT_FLAGS.turn_on(24);
}
int critter::isNotComplete() const {
return CRIT_FLAGS.get(24);
}
void critter::setPoofin(const char* pin) {
if (pc) {
pc->poofin = pin;
pc->poofin.Strip();
PC_FLAGS.turn_on(21);
}
}
void critter::setPoofout(const char* pout) {
if (pc) {
pc->poofout = pout;
pc->poofout.Strip();
PC_FLAGS.turn_on(21);
}
}
int critter::doesOwnRoom(room& rm) {
return (ZoneCollection::instance().elementAt(rm.getZoneNum()).isOwnedBy(*this));
}
int critter::doesOwnObject(object& obj) {
return (ZoneCollection::instance().elementAt(obj.getZoneNum()).isOwnedBy(*this));
}
int critter::doesOwnCritter(critter& mobile) {
return (mobile.isNpc() &&
ZoneCollection::instance().elementAt(mobile.getNativeZoneNum()).isOwnedBy(*this));
}
int critter::doesOwnDoor(door& dr) {
return (dr.dr_data && doesOwnDoor(*dr.dr_data));
}
int critter::doesOwnDoor(door_data& dd) {
return (ZoneCollection::instance().elementAt(dd.getZoneNum()).isOwnedBy(*this));
}
const String* critter::getName(int see_bit) const {
if (!detect(see_bit, VIS_BIT)) {
return &SOMEONE; //global string
}
if (isPc()) { //is a pc
const String* tmp = names.peekFront();
if (tmp) {
return tmp;
}
else {
return &SOMEONE;
}
}//if
else {
return &(short_desc);
}//else
}//name_of_crit
const String* critter::getShortName(int see_bit) const {
if (!detect(see_bit, VIS_BIT)) {
return &SOMEONE; //global string
}
const String* tmp = names.peekFront();
if (tmp) {
return tmp;
}
else {
return &SOMEONE;
}
}//getShortName
// return current value of cur_in_game after operation
int critter::getCurInGame() {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->getCurInGame();
}
mudlog << "ERROR: could not get curInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
// return current value of cur_in_game after operation
int critter::getMaxInGame() {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->getMaxInGame();
}
mudlog << "ERROR: could not get maxInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
int critter::setCurInGame(int i) {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->setCurInGame(i);
}
mudlog << "ERROR: could not set curInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
int critter::setMaxInGame(int i) {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->setMaxInGame(i);
}
mudlog << "ERROR: could not set maxInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
int critter::decrementCurInGame() {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->decrementCurInGame();
}
mudlog << "ERROR: could not decrementCurInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
int critter::incrementCurInGame() {
if (mob && mob_list[getIdNum()].mob) {
return mob_list[getIdNum()].mob->incrementCurInGame();
}
mudlog << "ERROR: could not incrementCurInGame for critter: "
<< *(getName()) << " id: " << getIdNum() << endl;
return 0;
}
int critter::isNoHassle() {
return (pc && PC_FLAGS.get(7));
}
int critter::isSneaking() const {
return crit_flags.get(17);
}
int critter::isHiding() const {
return crit_flags.get(22);
}
int critter::hasAI() {
return (mob && mob->proc_data && FLAG1.get(13));
}
int critter::getLinesOnPage() {
if (pc) {
return pc->lines_on_page;
}
return 40; //default, probably never used
}
void critter::setLinesOnPage(int lines) {
if (pc) {
pc->lines_on_page = lines;
}
}
/** Assume we are removing this object at this posn. */
void critter::checkLight(object* obj, int posn) {
//check all EQ for a burning light...
crit_flags.turn_off(1); //not using light
for (int i = 1; i<MAX_EQ; i++) {
if (i == posn && (EQ[i] == obj)) {
continue;
}
else {
if (EQ[i] && EQ[i]->isLit()) {
crit_flags.turn_on(1);
return;
}//if
}
}//for
}//checkLight
object* critter::findObjInEq(int i_th, const String& name,
int see_bit, room& rm, int& posn,
int& count_sofar) {
int count = 0;
for (int i = 1; i<MAX_EQ; i++) {
if (EQ[i] &&
detect(see_bit, rm.getVisBit() | EQ[i]->OBJ_VIS_BIT) &&
obj_is_named(*(EQ[i]), name)) {
count++;
count_sofar++;
if (count == i_th) {
posn = i;
return EQ[i];
}//if
}//if
}//for
posn = 0;
return NULL;
}//findObjInEq
String* critter::getHostName() const {
if (pc) {
return &(pc->host);
}
return &UNKNOWN;
}
String* critter::getSayColor() {
if (pc) {
return &(pc->say_str);
}
return &NULL_STRING;
}
String* critter::getYellColor() {
if (pc) {
return &(pc->yell_str);
}
return &NULL_STRING;
}
String* critter::getTellColor() {
if (pc) {
return &(pc->tell_str);
}
return &NULL_STRING;
}
String* critter::getGossipColor() {
if (pc) {
return &(pc->gos_str);
}
return &NULL_STRING;
}
String* critter::getDescColor() {
if (pc) {
return &(pc->desc_str);
}
return &NULL_STRING;
}
String* critter::getObjListColor() {
if (pc) {
return &(pc->obj_list_str);
}
return &NULL_STRING;
}
String* critter::getMobListColor() {
if (pc) {
return &(pc->mob_list_str);
}
return &NULL_STRING;
}
String* critter::getDefaultColor() { //for foreground
if (pc) {
return &(pc->dflt_str);
}
return &NULL_STRING;
}
String* critter::getBackGroundColor() {
if (pc) {
return &(pc->bk_str);
}
return &NULL_STRING;
}
String* critter::getBattleColor() {
if (pc) {
return &(pc->battle_str);
}
return &NULL_STRING;
}
int critter::isUsingColor() {
return pc && pc->pc_data_flags.get(26);
}
int critter::getAge() const {
int age = 18;
if (pc) {
if (config.day >= BIRTH_DAY) {
age++;
}//if
age += config.year - BIRTH_YEAR;
}//if
return age;
}//get_age
int critter::getXpToNextLevel() const {
int lvl = bound(0, MAX_LEVEL -1, LEVEL);
return levels[lvl] - EXP;
}//getXpToNextLevel
void critter::doScriptJump(int abs_index) {
if (mob)
mob->doScriptJump(abs_index);
}
void critter::remember(critter& targ) {
if (isPc() || targ.isNpc())
return;
if (doesRemember(targ))
return; //already remembering this fellow
if (!mob->proc_data) {
mob->proc_data = new spec_data;
}//if
if (!mob->proc_data->temp_proc) {
mob->proc_data->temp_proc = new temp_proc_data;
}//if
HUNTING.prepend(new String(*(targ.getShortName())));
}//remember
int critter::doesRemember(critter& targ) {
if (isPc())
return FALSE;
if (!mob->proc_data || !mob->proc_data->temp_proc) {
return FALSE;
}//if
Cell<String*> cll(HUNTING);
String* ptr;
while ((ptr = cll.next())) {
if (targ.isNamed(*ptr)) {
return TRUE;
}//if
}//while
return FALSE;
}//doesRemember
void critter::doHuntProc(int num_steps, int& is_dead) {
int targ_room_num;
if (!mob || !mob->proc_data ||
!mob->proc_data->temp_proc) {
mudlog.log(ERROR, "ERROR: bad pc sent to do_hunt_proc.\n");
return;
}//if
// If yer sessile, then you can't hunt!
if (isSessile()) {
return;
}
critter* targ = have_crit_named(pc_list, 1, getTrackingTarget(),
~0, *(getCurRoom()));
// No longer hunt MOBS
//if (!targ) {
// targ = have_crit_named(affected_mobs, 1,
// getTrackingTarget(), ~0, *(getCurRoom()));
//}//if
if (!targ) { //quit hunting that person (maybe)
Cell<String*> cll(HUNTING);
String* sp, *stp;
setTrackingTarget(NULL_STRING);
sp = cll.next();
while (sp) {
/* There is a chance we will forget if the target is not
* logged on currently.
*/
if ((strcasecmp(*sp, TRACKING) == 0) && (d(1,100) == 5)) {
stp = sp;
sp = HUNTING.lose(cll);
delete stp;
stp = NULL;
}//if
else {
TRACKING = *sp;
break;
}//if
}//while
}//if can't find target
else { //go get em!
if (targ->isMob()) {
mudlog.log(ERROR, "ERROR: targ is MOB in do_hunt_proc.\n");
return;
}//if
targ_room_num = targ->getCurRoomNum();
if (targ_room_num == getCurRoomNum()) {
checkForBattle(*(getCurRoom()));
}
else {
//mudlog << "WARNING: travelToRoom from doHuntProc" << endl;
travelToRoom(targ_room_num, num_steps, is_dead);
}
}//else go get em
}//doHuntProc
int critter::isTeacher() {
return (mob && mob->proc_data && FLAG1.get(2));
}
int critter::isShopKeeper() {
return (mob && mob->proc_data && FLAG1.get(1));
}
int critter::isPlayerShopKeeper() {
return (mob && mob->proc_data && mob->proc_data->sh_data
&& mob->proc_data->sh_data->shop_data_flags.get(3));
}//isPlayerShopKeeper
// Price this keeper will sell the object for.
int critter::findItemSalePrice(object& item, critter& pc) {
int price = 0;
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
return 0;
}
if (isPlayerShopKeeper()) {
price = mob->proc_data->sh_data->findItemSalePrice(item);
}//if
else { // automagically figure it out
price = (int)((float)(item.PRICE) *
((float)(MARKUP) / 100.0));
if (pc.getHomeTown() != (getHomeTown())) {
price = (int)((float)(price) * config.outOfTownModifier);
}//if
if (pc.pc && (d(1, 100) <
get_percent_lrnd(COMMERCE_SKILL_NUM, pc))) {
price = (int)((float)price * config.commerceSkillBuyEffect);
}//if
}//else
return price;
}//findItemSalePrice
// Price this keeper will buy the object for.
int critter::findItemBuyPrice(object& item, critter& pc) {
int price = 0;
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
return 0;
}
if (isPlayerShopKeeper()) {
price = mob->proc_data->sh_data->findItemBuyPrice(item);
}//if
else { // automagically figure it out
price = (int)((float)(item.PRICE) *
((float)(BUY_PERCENTAGE) / 100.0));
if (pc.getHomeTown() != getHomeTown())
price = (int)(((float)(price)) * (1.0 / config.outOfTownModifier));
if (pc.pc && (d(1, 100) <
get_percent_lrnd(COMMERCE_SKILL_NUM, pc))) {
price = (int)((float)price * config.commerceSkillSellEffect);
}//if
}//else
return price;
}//findItemBuyPrice
void critter::transferShopDataTo(critter& sink) {
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
mudlog << "ERROR: transferShopDataTo, this does not have sh_data"
<< endl;
return;
}
if (!sink.mob || !sink.mob->proc_data || !sink.mob->proc_data->sh_data) {
mudlog << "ERROR: transferShopDataTo, sink does not have sh_data"
<< endl;
return;
}
clear_ptr_list(sink.mob->proc_data->sh_data->ps_data_list);
Cell<PlayerShopData*> cll(mob->proc_data->sh_data->ps_data_list);
PlayerShopData* ptr;
while ((ptr = cll.next())) {
sink.mob->proc_data->sh_data->ps_data_list.pushBack(new PlayerShopData(*ptr));
}//while
}//transferShopDataTo
void critter::valueRem(int idx, critter& manager) {
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
mudlog << "ERROR: valueRem, this does not have sh_data"
<< endl;
return;
}
mob->proc_data->sh_data->valueRem(idx, manager);
}//valueRem
void critter::valueAdd(object& obj, critter& manager) {
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
mudlog << "ERROR: valueAdd, this does not have sh_data"
<< endl;
return;
}
mob->proc_data->sh_data->valueAdd(obj, manager);
}//valueAdd
void critter::valueList(int i_th, const String* targ, critter& manager) {
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
mudlog << "ERROR: valueList, this does not have sh_data"
<< endl;
return;
}
mob->proc_data->sh_data->valueList(i_th, targ, *this, manager);
}//valueList
void critter::valueSet(int val_idx, int sell_val, int buy_val,
critter& manager) {
if (!mob || !mob->proc_data || !mob->proc_data->sh_data) {
mudlog << "ERROR: valueSet, this does not have sh_data"
<< endl;
return;
}
mob->proc_data->sh_data->valueSet(val_idx, sell_val, buy_val, manager);
}//valueSet
int critter::isManagedBy(critter& pc) {
return (isPlayerShopKeeper() &&
(strcasecmp(mob->proc_data->sh_data->manager, *(pc.getName())) == 0));
}//isManagedBy
int critter::withdrawCoins(int count, critter& banker) { //do messages
String buf(100);
if (long_data[2] >= count) {
long_data[2] -= count;
long_data[0] += count;
Sprintf(buf, "%S gives you %i coins.\n", banker.getName(), count);
show(buf);
Sprintf(buf, "Your balance is now %i coins.", long_data[2]);
do_tell(banker, buf, *this, FALSE, getCurRoomNum());
return 0;
}
Sprintf(buf, "Your balance is only %i coins.", long_data[2]);
do_tell(banker, buf, *this, FALSE, getCurRoomNum());
return -1;
}
int critter::balanceCoins(critter& banker) {
String buf(100);
Sprintf(buf, "Your balance is %i coins.", long_data[2]);
do_tell(banker, buf, *this, FALSE, getCurRoomNum());
return 0;
}
int critter::depositCoins(int count, critter& banker) { //do messages
String buf(100);
if (long_data[0] >= count) {
long_data[0] -= count;
long_data[2] += count;
Sprintf(buf, "%S puts %i coins into your account.\n", banker.getName(),
count);
show(buf);
Sprintf(buf, "Your balance is now %i coins.", long_data[2]);
do_tell(banker, buf, *this, FALSE, getCurRoomNum());
return 0;
}
Sprintf(buf, "Your have only %i coins.", long_data[0]);
do_tell(banker, buf, *this, FALSE, getCurRoomNum());
return -1;
}
/** Translates an asci string (like HP, MANA, MOV, ALIGN, etc)
* and returns the integer value. Returns 0 if it can't
* resolve the field.
*/
int critter::getFieldValue(const char* field) const {
if (strcasecmp(field, "HP") == 0) {
return getHP();
}
else if (strcasecmp(field, "MANA") == 0) {
return getMana();
}
else if (strcasecmp(field, "MOV") == 0) {
return getMov();
}
else if (strcasecmp(field, "ALIGN") == 0) {
return getAlignment();
}
else if (strcasecmp(field, "BENEVOLENCE") == 0) {
return getBenevolence();
}
else if (strcasecmp(field, "HOMETOWN") == 0) {
return getHomeTown();
}
else if (strcasecmp(field, "NATIVEZONE") == 0) {
return getNativeZoneNum();
}
else if (strcasecmp(field, "AGE") == 0) {
return getAge();
}
else if (strcasecmp(field, "VISBIT") == 0) {
return getVisBit();
}
else if (strcasecmp(field, "SEEBIT") == 0) {
return getSeeBit();
}
else if (strcasecmp(field, "NAKED_WEIGHT") == 0) {
return getNakedWeight();
}
else if (strcasecmp(field, "CHARISMA") == 0) {
return getCharisma();
}
else if (strcasecmp(field, "HP_MAX") == 0) {
return getHP_MAX();
}
else if (strcasecmp(field, "MANA_MAX") == 0) {
return getManaMax();
}
else if (strcasecmp(field, "MOV_MAX") == 0) {
return getMovMax();
}
else if (strcasecmp(field, "WIMPY") == 0) {
return getWimpy();
}
else if (strcasecmp(field, "LEVEL") == 0) {
return getLevel();
}
else if (strcasecmp(field, "CLASS") == 0) {
return getClass();
}
else if (strcasecmp(field, "GOLD") == 0) {
return GOLD;
}
else if (strcasecmp(field, "RACE") == 0) {
return RACE;
}
else {
return 0;
}
}
/** Only valid for shop owners. */
int critter::isOpen(int cmt, int do_msg, critter& pc) const {
if (mob && mob->proc_data && mob->proc_data->sh_data) {
// 9 AM to 4 PM (9 - 16)
if (OPEN_TIME <= CLOSE_TIME) {
if ((cmt >= OPEN_TIME) && (cmt <= CLOSE_TIME)) {
return TRUE;
}
}
// 4 PM to 9 AM (16(open) - 9(close))
else if (CLOSE_TIME <= OPEN_TIME) {
if (!((cmt > CLOSE_TIME) && (cmt < OPEN_TIME))) {
return TRUE;
}
}
}//if
if (do_msg) {
String buf(100);
Sprintf(buf, cstr(CS_HOURS_FROM, pc),
military_to_am(OPEN_TIME),
military_to_am(CLOSE_TIME));
pc.show(buf);
}
return FALSE;
}//isOpen
/** Can fail if cnt is bad, does all messages. */
int critter::doDropCoins(int cnt) {
if (GOLD < cnt) {
show(CS_TOO_LITTLE_GOLD);
return -1;
}
else if (cnt <= 0) {
show(CS_MUST_DROP_MORE_GOLD);
return -1;
}
else {
String buf(100);
Sprintf(buf, cstr(CS_DROP_I_COINS, *this), cnt);
show(buf);
object* gold;
gold = obj_to_sobj(obj_list[config.goldCoinsObject], getCurRoom()->getInv(),
getCurRoomNum());
obj_list[config.goldCoinsObject].incrementCurInGame();
gold->cur_stats[1] = cnt;
GOLD -= cnt;
getCurRoom()->gainObject(gold);
return 0;
}//all is well
}//doDropCoins