// $Id: misc.cc,v 1.26.2.21 2000/05/13 19:42:59 greear Exp $
// $Revision: 1.26.2.21 $ $Author: greear $ $Date: 2000/05/13 19:42:59 $
//
//ScryMUD Server Code
//Copyright (C) 1998 Ben Greear
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// To contact the Author, Ben Greear: greear@cyberhighway.net, (preferred)
// greearb@agcs.com
//
#include "command4.h"
#include <time.h>
#include <iostream.h>
#include <fstream.h>
#include "commands.h"
#include "battle.h"
#include "misc.h"
#include "misc2.h"
#include <stdio.h>
#include "classes.h"
#include <sys/types.h>
#include <unistd.h>
#include "const.h"
#include "spells.h"
#include <PtrArray.h>
#include "vehicle.h"
#include "load_wld.h"
#include "command3.h"
#include "skills.h"
#include <time.h>
#include "Filters.h"
/** calculate the ratio between objects casting spell a spell and the
* number of players online. It will be fudged so that 1 will be
* considered a 'fair' amount. If > 1.0 then the spell should probably
* be weakened somewhat.
*/
float spell_objs_ratio(int spell_num) {
// Take potions & scrolls into affect, all 2 per person.
float cnt = SSCollection::instance().getSS(spell_num).getSpellCastingCount();
if (cnt == 0)
cnt = 1.0;
float pcnt = (((float)(MudStats::instance().getPlayerCount())
* 1.5 + 10.0) / cnt);
if (pcnt < 1.0)
pcnt = 1.0;
return pcnt;
}//spell_objs_ratio
const char* cstr(CSentryE e, critter& c) {
return CSHandler::getString(e, c.getLanguageChoice());
}
String& getCurTime() { //in the real world (tm) :)
static String retval(100);
long int cur_time;
time(&cur_time);
retval = ctime(&cur_time);
retval.Strip();
return retval;
}
int bound(int low, int high, int val) {
if (val < low)
val = low;
if (val > high)
val = high;
return val;
}
void critter::save() {
if (!pc) {
mudlog.log(ERROR, "ERROR: non PC sent to critter::save()\n");
return;
}
if (LEVEL == 0) {
mudlog << "ERROR: level 0 player trying to save, name: "
<< *(getName()) << endl;
return;
}
String buf(*(getName()));
buf.Tolower();
buf.Prepend("./Pfiles/");
ofstream ofile(buf);
if (!ofile) {
mudlog.log(ERROR, "ERROR: file not opened in save_pc.\n");
return;
}//if
Write(ofile);
}//save_pc
/** msg defaults to NULL if not entered explicitly.. */
short check_l_range(long i, long l, long h, critter& pc, short disp,
const char* msg) {
String buf(100);
if (i < l) {
if (disp) {
if (msg) {
Sprintf(buf, "%s: The number is too low.\n", msg);
pc.show(buf);
}
else
show("The number is too low.\n", pc);
return FALSE;
}//if
return FALSE;
}//if
else if (i > h) {
if (disp) {
if (msg) {
Sprintf(buf, "%s: The number is too high.\n", msg);
pc.show(buf);
}
else
show("The number is too high.\n", pc);
return FALSE;
}//if
return FALSE;
}//else
return TRUE;
}//check_l_range()
char* get_his_her(const critter& crit) {
if (crit.SEX == 0) {
return "her";
}//if
else if (crit.SEX == 1) {
return "his";
}//else
else {
return "its";
}//else
}//get_his_her
char* get_hisself_herself(const critter& crit) { //this is
//grammatically incorrect, the code is same as get_himself_herself.
if (crit.SEX == 0) {
return "herself";
}//if
else if (crit.SEX == 1) {
return "himself";
}//else
else {
return "itself";
}//else
}//get_hisself_herself
char* get_he_she(const critter& crit) {
if (crit.SEX == 0) {
return "she";
}//if
else if (crit.SEX == 1) {
return "he";
}//else
else {
return "it";
}//else
}//get_he_she
int d(const int num_rolls, const int dice_sides) {
int rtvalue = 0;
for (int i = 0; i<num_rolls; i++) {
rtvalue += 1 +(int)((rand() * (float)(dice_sides)) / (RAND_MAX + 1.0));
}//for
return rtvalue;
}//d()
/* in file parse.cc */
short isnum(String& word) {
int len = word.Strlen();
int i = 0;
if (len == 0)
return FALSE;
if ((word[0] == '-') || (word[0] == '+'))
i++;
for ( ; i<len; i++) {
if (!isdigit(word[i])) {
return FALSE;
}//if
}//for
return TRUE;
}//isnum
void join_in_battle(critter& agg, critter& vict) {
//log("In join_in_battle...\n");
if (mudlog.ofLevel(DBG)) {
mudlog << "join_in_battle: agg: " << &agg << " vict: " << &vict << endl;
}
if (agg.isMob()) {
mudlog.log(ERROR, "ERROR: join_in_battle called with agg as mob\n");
return;
}//if
if (vict.isMob()) {
mudlog.log(ERROR, "ERROR: join_in_battle called with vict as mob\n");
return;
}//if
if (&vict == &agg) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: vict == agg in join_in_battle, name: "
<< *(name_of_crit(agg, ~0)) << " address: " << &agg
<< endl;
}
return;
}//if
if (vict.isImmort() && vict.isNoHassle()
&& vict.getImmLevel() >= agg.getImmLevel()) {
if (mudlog.ofLevel(INF)) {
mudlog << "INFO: Not joining battle because of !hassle, agg: "
<< agg.getName() << " vict: " << vict.getName() << endl;
}//if
return;
}//if
//ensure only one copy (that's what gainData does)
if (agg.getCurRoomNum() == vict.getCurRoomNum()) {
embattled_rooms.gainData(&(room_list[agg.getCurRoomNum()]));
}
else {
embattled_rooms.gainData(&(room_list[agg.getCurRoomNum()]));
embattled_rooms.gainData(&(room_list[vict.getCurRoomNum()]));
}
/* make sure agg hits first */
if (room_list[agg.getCurRoomNum()].removeCritter(&agg)) {
room_list[vict.getCurRoomNum()].gainCritter(&agg);
}
else {
if (mudlog.ofLevel(DIS)) {
mudlog << "ERROR: could not 'LoseData' in join_in_battle, agg: "
<< *(name_of_crit(agg, ~0)) << " address: " << &agg
<< " getCurRoomNum(): " << agg.getCurRoomNum() << endl;
}
}
Put(&vict, agg.IS_FIGHTING);
Put(&agg, vict.IS_FIGHTING);
//Some mobs will remember....
if (vict.isNpc()) {
critter* virt_attacker = NULL;
if (agg.isPc()) {
virt_attacker = &agg;
}
else {
virt_attacker = agg.getFollowerOf();
}
if (virt_attacker) {
if ((((vict.getLevel() > 20) && vict.mob->getBadAssedness() > 0) ||
((vict.mob->getBadAssedness() > 3))) ||
(((vict.getLevel() > 20) && vict.getBenevolence() <= 0) ||
((vict.getBenevolence() < 0)))) {
vict.remember(*virt_attacker);
do_tell(vict, "I'll remember that!!", *virt_attacker, FALSE,
virt_attacker->getCurRoomNum());
}//if
if ((vict.getBenevolence() <= -4) ||
(vict.mob->getBadAssedness() >= 5)) {
vict.setTrackingTarget(*(virt_attacker->getShortName()));
}
}//if we found a PC responsible
}//if
agg.PAUSE += 1; //vict should get at least one hit in
}//join_in_battle
void do_tick() {
//gossip("An hour has passed in our fine land.", mob_list[2]);
/* do all decrementing */
decrease_timed_affecting_doors(); //takes care of affected_dors list
decrease_timed_affecting_lds(); //takes care of alllink deads
decrease_timed_affecting_pcs(); //takes care of all pc's
decrease_timed_affecting_smobs(); //takes care of affected_mobs list
decrease_timed_affecting_objects(); //takes care of affected_objects list
decrease_timed_affecting_rooms(); //takes care of affected_rooms
/* do all incrementing */
do_regeneration_pcs(); //takes care of all pc's
do_regeneration_smobs(); //takes care of affected_mobs list
do_regeneration_objects(); //takes care of affected_objects list
ZoneCollection::instance().doRegeneration(); //update mobs, objs, rooms if needed
/* time */
config.hour++;
if (config.hour >= 24) {
config.hour = 0;
config.day++;
}//if
if (config.day >= 365) {
config.year++;
config.day = 1;
}//if
config.writeDynamic("dynamic.cfg");
}//do_tick
void do_mini_tick() { // decrement pause count ect
Cell<critter*> cll;
pc_list.head(cll);
critter* crit_ptr;
Cell<stat_spell_cell*> scell;
stat_spell_cell* sc_ptr;
do_vehicle_moves(); //in misc2.cc
while ((crit_ptr = cll.next())) {
crit_ptr->spam_cnt = 0;
// Turn un-blocked, if not in battle.
if (!crit_ptr->isInBattle()) {
crit_ptr->crit_flags.turn_off(21);
}
/* Take care of round-by-round affects on other spells/skills. */
if ((sc_ptr = is_affected_by(EARTHMELD_SKILL_NUM, *crit_ptr))) {
if (crit_ptr->isFighting()) {
crit_ptr->MANA -= EARTHMELD_BATTLE_MANA_COST;
}
else {
crit_ptr->MANA -= EARTHMELD_NON_BATTLE_MANA_COST;
}
if (crit_ptr->MANA <= 0) {
crit_ptr->breakEarthMeld();
}//if
}//if
// Take care of other things...
if (crit_ptr->PAUSE > 0) {
crit_ptr->PAUSE--;
}//
crit_ptr->MINI_AFFECTED_BY.head(scell);
sc_ptr = scell.next();
while (sc_ptr) {
sc_ptr->bonus_duration--;
if (sc_ptr->bonus_duration == 0) {
rem_effects_crit(sc_ptr->stat_spell, *crit_ptr, TRUE);
delete sc_ptr;
sc_ptr = crit_ptr->MINI_AFFECTED_BY.lose(scell);
}//if
else
sc_ptr = scell.next();
}//while
}//while
affected_mobs.head(cll);
while ((crit_ptr = cll.next())) {
crit_ptr->spam_cnt = 0;
// Turn un-blocked, if not in battle.
if (!crit_ptr->isInBattle()) {
crit_ptr->crit_flags.turn_off(21);
}
if (crit_ptr->PAUSE > 0)
crit_ptr->PAUSE--;
crit_ptr->MINI_AFFECTED_BY.head(scell);
sc_ptr = scell.next();
while (sc_ptr) {
sc_ptr->bonus_duration--;
if (sc_ptr->bonus_duration == 0) {
rem_effects_crit(sc_ptr->stat_spell, *crit_ptr, TRUE);
delete sc_ptr;
sc_ptr = crit_ptr->MINI_AFFECTED_BY.lose(scell);
}//if
else
sc_ptr = scell.next();
}//while
}//while
// Decrease pause count for rooms that are running scripts.
room* rm_ptr;
for (int cnt = 0; cnt < proc_action_rooms.getCurLen(); cnt++) {
if (!(rm_ptr = proc_action_rooms.elementAt(cnt))) {
continue;
}//if
else {
rm_ptr->decrementPause();
}
}//for
// Decrease pause count for objects that are running scripts.
object* o_ptr;
for (int cnt = 0; cnt < proc_action_objs.getCurLen(); cnt++) {
if (!(o_ptr = proc_action_objs.elementAt(cnt))) {
continue;
}//if
else {
o_ptr->decrementPause();
}
}//for
}//do_mini_tick
void do_regeneration_pcs() {
float adj = 1.0, posn_mod;
Cell<critter*> crit_cell;
pc_list.head(crit_cell);
critter* crit_ptr;
//log("In do_regeneration_pcs\n");
while ((crit_ptr = crit_cell.next())) {
if ((crit_ptr->THIRST == 0) || (crit_ptr->HUNGER == 0)) {
adj = 0.2; // big penalty for being hungry
}
else {
adj = 1.0;
}
if ((crit_ptr->POS > POS_SIT) &&
room_list[crit_ptr->getCurRoomNum()].canCamp()) {
adj *= ((float)(200 + get_percent_lrnd(CAMPING_SKILL_NUM,
*crit_ptr))) / 200.0;
}//if camping is an issue
posn_mod = (2.0 + (float)(crit_ptr->POS)) / 4.0;
crit_ptr->HP += (int)((((float)(crit_ptr->CON) + 5.0) / 15.0) *
(((float)(crit_ptr->HP_MAX)) / 9.0) *
posn_mod * (((float)(crit_ptr->HP_REGEN)) / 100.0)
* adj + 10.0);
crit_ptr->MANA += (int)(((((float)(crit_ptr->INT)) + 5.0) / 16.0) *
posn_mod *
(((float)(crit_ptr->MA_MAX)) / 7.0) *
(((float)(crit_ptr->MA_REGEN)) / 100.0) *
adj + 4.0);
int tmp_mov;
tmp_mov = (int)(((((float)(crit_ptr->DEX)) + 5.0) / 16.0) *
posn_mod * adj *
(((float)(crit_ptr->MV_MAX)) / 3.0) *
(((float)(crit_ptr->MV_REGEN)) / 100.0) + 3.0);
crit_ptr->MOV += tmp_mov;
//if (tmp_mov < 0) {
// if (mudlog.ofLevel(DBG)) {
// mudlog << "WARNING: mov regen < 0 for PC: "
// << *(name_of_crit(*crit_ptr, ~0)) << " it was: "
// << tmp_mov << endl;
// }
//}
if (crit_ptr->HP > crit_ptr->HP_MAX)
crit_ptr->HP = crit_ptr->HP_MAX;
if (crit_ptr->MANA > crit_ptr->MA_MAX)
crit_ptr->MANA = crit_ptr->MA_MAX;
if (crit_ptr->MOV > crit_ptr->MV_MAX)
crit_ptr->MOV = crit_ptr->MV_MAX;
if (crit_ptr->HP < 0)
crit_ptr->HP = 0;
if (crit_ptr->MANA < 0)
crit_ptr->MANA = 0;
if (crit_ptr->MOV < 0)
crit_ptr->MOV = 0;
if ((((float)(crit_ptr->HP)) / (float)(crit_ptr->HP_MAX)) > 0.80) {
stat_spell_cell* ssptr =
is_affected_by(BIND_WOUND_SKILL_NUM, *crit_ptr);
if (ssptr) {
crit_ptr->affected_by.loseData(ssptr);
rem_effects_crit(BIND_WOUND_SKILL_NUM, *crit_ptr, TRUE);
}
}//if
}//while
}//do_regeneration_pcs
void do_regeneration_smobs() {
float posn_mod, adj = 1.0;
Cell<critter*> crit_cell;
affected_mobs.head(crit_cell);
critter* crit_ptr;
//log("In do_regeneration_smobs\n");
while ((crit_ptr = crit_cell.next())) {
posn_mod = (2.0 + crit_ptr->POS) / 4.0;
crit_ptr->HP +=
(int)(((crit_ptr->CON + 5.0) / 15.0) *
(crit_ptr->HP_MAX / 9.0) *
posn_mod * (crit_ptr->HP_REGEN / 100.0) * adj + 10.0);
crit_ptr->MANA +=
(int)(((crit_ptr->INT + 5.0) / 16.0) * posn_mod *
(crit_ptr->MA_MAX / 7.0) * (crit_ptr->MA_REGEN / 100.0) * adj + 4.0);
crit_ptr->MOV +=
(int)(((crit_ptr->DEX + 5.0) / 16.0) * posn_mod *
adj *
(crit_ptr->MV_MAX / 2.0) * (crit_ptr->MV_REGEN / 100.0) + 5.0);
if (crit_ptr->HP > crit_ptr->HP_MAX)
crit_ptr->HP = crit_ptr->HP_MAX;
if (crit_ptr->MANA > crit_ptr->MA_MAX)
crit_ptr->MANA = crit_ptr->MA_MAX;
if (crit_ptr->MOV > crit_ptr->MV_MAX)
crit_ptr->MOV = crit_ptr->MV_MAX;
if (((float)crit_ptr->HP / (float)crit_ptr->HP_MAX) > 0.80) {
stat_spell_cell* ssptr =
is_affected_by(BIND_WOUND_SKILL_NUM, *crit_ptr);
if (ssptr) {
crit_ptr->affected_by.loseData(ssptr);
rem_effects_crit(BIND_WOUND_SKILL_NUM, *crit_ptr, TRUE);
}
}//if
}//while
}//do_regeneration_smobs
void do_regeneration_objects() {
return;
}//do_regeneration_objects
int update_critters(int zone_num, short read_all) {
switch (config.useMySQL) {
#ifdef USEMYSQL
case true:
return db_update_critters(zone_num, read_all);
break;
#endif
case false:
return file_update_critters(zone_num, read_all);
break;
}
return -1;
}
#ifdef USEMYSQL
int db_update_critters(int zone_num, short read_all) {
critter tmp_mob;
MYSQL_RES* result;
MYSQL_ROW row;
String query="select * from Critters where FROM_ZONE=";
query+=zone_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In [function]:\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
}
return -1;
}
while ((row=mysql_fetch_row(result))) {
int k = atoi(row[CRITTBL_MOB_NUMBER]);
tmp_mob.dbRead(k, 0, read_all);
if (!(&mob_list[k])) {
if (mudlog.ofLevel(WRN)) {
mudlog << "WARNING: mob[" << k << "] is NULL.\n";
}
}
else {
if (mob_list[k].MOB_FLAGS.get(4)) {
Cell<object*> ocell;
object* obj_ptr;
tmp_mob.inv.head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(tmp_mob.inv, *obj_ptr) >
obj_count(mob_list[k].inv, *obj_ptr))
&& (obj_ptr->getCurInGame() < obj_ptr->getMaxInGame())) {
Put (&obj_list[obj_ptr->getIdNum()], mob_list[k].inv);
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}
}
for (int i = 1; i<MAX_EQ; i++) {
if ((tmp_mob.EQ[i] && !mob_list[k].EQ[i])
&& (tmp_mob.EQ[i]->getCurInGame()
< tmp_mob.EQ[i]->getMaxInGame())) {
mob_list[k].EQ[i] = &obj_list[tmp_mob.EQ[i]->getIdNum()];
recursive_init_loads(*(mob_list[k].EQ[i]), 0);
}
}
}
}
}
tmp_mob.CRITTER_TYPE = 1;
mysql_free_result(result);
}
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In [function]:\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
}
return -1;
}
return 0;
}
#endif
int file_update_critters(int zone_num, short read_all) {
Cell<object*> ocell;
critter tmp_mob;
int k, i;
object* obj_ptr;
char temp_str[81];
String buf(100);
//Sprintf(buf, "In update_critters, zone: %i.", zone_num);
//log(buf);
Sprintf(buf, "./World/critters_%i", zone_num);
ifstream mobfile(buf);
if (!mobfile) {
buf.Prepend("cp ./World/DEFAULT_CRITTERS ");
system(buf);
mudlog.log(ERROR, "WARNING: created CRITTER_FILE in update_critters");
tmp_mob.CRITTER_TYPE = 1; //make it a SMOB, so destructor fires correctly
return 0;
}//if
mobfile >> k;
mobfile.getline(temp_str, 80); //junk line
while (k != -1) {
Sprintf(buf, "About to read mob: %i, zone %i.", k, zone_num);
mudlog.log(DBG, buf);
if (!mobfile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: error reading critters for zone: " << zone_num
<< " trying to read mob# " << k << endl;
}//if
return -1;
}//if
tmp_mob.fileRead(mobfile, read_all);
if (!mob_list[k].mob) {
mudlog << "WARNING: mob[" << k
<< "] is NULL in update critters." << endl;
}//if
else {
if (mob_list[k].MOB_FLAGS.get(4)) {
//log("About to check if need to load more inv.\n");
tmp_mob.inv.head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(tmp_mob.inv, *obj_ptr) >
obj_count(mob_list[k].inv, *obj_ptr))
&& (obj_ptr->getCurInGame() < obj_ptr->getMaxInGame())) {
Put(&(obj_list[obj_ptr->getIdNum()]), mob_list[k].inv);
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}//if
}//while
for (i = 1; i<MAX_EQ; i++) {
if ((tmp_mob.EQ[i] && !mob_list[k].EQ[i])
&& (tmp_mob.EQ[i]->getCurInGame()
< tmp_mob.EQ[i]->getMaxInGame())) {
mob_list[k].EQ[i] = &(obj_list[tmp_mob.EQ[i]->getIdNum()]);
recursive_init_loads(*(mob_list[k].EQ[i]), 0);
}//if
}//for
}//if should update
}//else
mobfile >> k;
mobfile.getline(temp_str, 80);
}//while, the big loop, reads in a whole mob list
//log("Done w/update critters.\n");
tmp_mob.CRITTER_TYPE = 1; //make it a SMOB, so destructor fires correctly
return 0;
}//update_critters
int update_objects(int zone_num, short read_all) {
#ifdef USEMYSQL
if (config.useMySQL)
return db_update_objects(zone_num, read_all);
else
#endif
return file_update_objects(zone_num, read_all);
}
#ifdef USEMYSQL
int db_update_objects(int zone_num, short read_all) {
Cell<object *> ocell;
int k;
object temp_obj;
object* obj_ptr;
MYSQL_RES* result;
MYSQL_ROW row;
String query = "select distinct OBJ_NUM from ";
query += "RoomInv inner join Rooms on RoomInv.ROOM_NUM=Rooms.ROOM_NUM";
query += "where IN_ZONE=";
query += zone_num;
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In db_update_objects(int, short):\n";
mudlog << "Eror retrieving query results: " << mysql_error(database)
<< endl;
}
return -1;
}
while ((row=mysql_fetch_row(result))) {
k = atol(row[0]);
temp_obj.dbRead(k, -1, read_all);
if (obj_list[k].OBJ_FLAGS.get(OBJFLAG_NEEDS_RESETTING)) {
temp_obj.inv.head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(temp_obj.inv, *obj_ptr) >
obj_count(obj_list[k].inv, *obj_ptr)) &&
(obj_ptr->getCurInGame() < obj_ptr->getMaxInGame())) {
Put(&(obj_list[obj_ptr->getIdNum()]), obj_list[k].inv);
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}
}
}
}
mysql_free_result(result);
temp_obj.IN_LIST = room_list[0].getInv();
}
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In db_update_objects(int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
}
return -1;
}
return 0;
}
#endif
int file_update_objects(int zone_num, short read_all) {
Cell<object*> ocell;
int k;
object temp_obj;
object* obj_ptr;
char temp_str[81];
String buf(100);
// log("In update_objects.\n");
Sprintf(buf, "./World/objects_%i", zone_num);
ifstream objfile(buf);
if (!objfile) {
buf.Prepend("cp ./World/DEFAULT_OBJECTS ");
system(buf);
mudlog.log(ERROR, "WARNING: created new OBJECT_FILE in update_objects");
temp_obj.IN_LIST = room_list[0].getInv(); //hack to let destructor fire
//happily, turn it into a SOBJ
return 0;
}//if
objfile >> k;
objfile.getline(temp_str, 80); //junk line
while (k != -1) {
if (mudlog.ofLevel(DBG)) {
mudlog << "About to read obj: " << k
<< " zone: " << zone_num << endl;
}
temp_obj.fileRead(objfile, read_all);
if (!objfile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: error reading objects for zone: " << zone_num
<< " trying to read obj# " << k << endl;
}//if
return -1;
}//if
if (obj_list[k].OBJ_FLAGS.get(70)) {
//log("About to check if need to load more inv.\n");
temp_obj.inv.head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(temp_obj.inv, *obj_ptr) >
obj_count(obj_list[k].inv, *obj_ptr))
&& (obj_ptr->getCurInGame() < obj_ptr->getMaxInGame())) {
Put(&(obj_list[obj_ptr->getIdNum()]), obj_list[k].inv);
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}//if
}//while
}//if should update
objfile >> k;
objfile.getline(temp_str, 80);
}//while, the big loop, reads in a whole mob list
temp_obj.IN_LIST = room_list[0].getInv(); //hack to let destructor fire
//happily, turn it into a SOBJ
//log("Done w/update objects.\n");
return 0;
}//update_objects
int update_zone(int zone_num, short read_all) {
switch (config.useMySQL) {
#ifdef USEMYSQL
case true:
return db_update_zone(zone_num, read_all);
#endif
case false:
return file_update_zone(zone_num, read_all);
}
return -1;
}
#ifdef USEMYSQL
int db_update_zone(int zone_num, short read_all) {
int k;
room tmp_room;
vehicle tmp_veh;
object* obj_ptr;
Cell<object*> ocell;
critter* crit_ptr;
Cell<critter*> ccell;
MYSQL_RES* result;
MYSQL_ROW row;
String query="select ROOM_NUM from Rooms where IN_ZONE=";
query+=zone_num;
if (ZoneCollection::instance().elementAt(zone_num).isLocked() &&
(read_all == FALSE)) {
return 0;
}
if (mysql_real_query(database, query, strlen(query))==0) {
if ((result=mysql_store_result(database))==NULL) {
if (mudlog.ofLevel(WRN)) {
mudlog << "In db_update_zone(int, short):\n";
mudlog << "Error retrieving query results: "
<< mysql_error(database) << endl;
}
return -1;
}
while ((row=mysql_fetch_row(result))) {
room* room_ptr;
k=atoi(row[0]);
if (k & 0x01000000) {
tmp_veh.dbRead(k, read_all);
room_ptr = &tmp_veh;
k = (k & ~(0x01000000));
}
else {
tmp_room.dbRead(k, read_all);
room_ptr=&tmp_room;
}
if (read_all) {
room_list[k].setTotalLoaded(TRUE);
}
room_ptr->getInv()->head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(*(room_ptr->getInv()), *obj_ptr) >
obj_count(*(room_list[k].getInv()), *obj_ptr)) &&
(obj_ptr->getCurInGame() <
obj_list[obj_ptr->getIdNum()].getMaxInGame())) {
if (obj_ptr->isPlayerOwned()) {
object* pobox = load_player_box(obj_ptr->getIdNum());
if (pobox) {
pobox->IN_LIST = room_list[k].getInv();
pobox->setCurRoomNum(k, 0);
affected_objects.gainData(pobox);
room_list[k].gainObject(pobox);
}
else {
room_list[k].gainObject(&(obj_list[obj_ptr->getIdNum()]));
}
}
else {
room_list[k].gainObject(&(obj_list[obj_ptr->getIdNum()]));
}
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}
}
List<critter*> tmp_lst(room_ptr->getCrits());
tmp_lst.head(ccell);
int tmp_cc;
int ingame_cc;
while ((crit_ptr = ccell.next())) {
tmp_cc = room_ptr->getCritCount(*crit_ptr);
ingame_cc = room_list[k].getCritCount(*crit_ptr);
if ((tmp_cc > ingame_cc) && ((crit_ptr->getCurInGame() - tmp_cc) <
crit_ptr->getMaxInGame())) {
if (crit_ptr->isPlayerShopKeeper()) {
critter* shop_keeper =
load_player_shop_owner(crit_ptr->getIdNum());
if (shop_keeper) {
shop_keeper->setCurRoomNum(k);
room_list[k].gainCritter(shop_keeper);
}
}
else {
room_list[k].gainCritter(&(mob_list[crit_ptr->getIdNum()]));
}
recursive_init_loads(mob_list[crit_ptr->getIdNum()]);
}
}
}
tmp_room.Clear();
tmp_veh.Clear();
mysql_free_result(result);
}
else {
if (mudlog.ofLevel(WRN)) {
mudlog << "In db_update_zone(int, short):\n";
mudlog << "Error executing query: " << mysql_error(database) << endl;
}
return -1;
}
return 0;
}
#endif
int file_update_zone(int zone_num, short read_all) {
int k = 0;
room tmp_room;
vehicle tmp_veh;
object* obj_ptr;
Cell<object*> ocell;
critter* crit_ptr;
Cell<critter*> ccell;
char temp_str[100];
String buf(100);
//Sprintf(buf, "In update_zone: zone# = %i.\n", zone_num);
//log(buf);
//if it's locked, don't mess w/it
if (ZoneCollection::instance().elementAt(zone_num).isLocked() &&
(read_all == FALSE)) { //if locked and an automatic update
//log("Locked, returning...\n");
return 0; //don't do anything
}//if
Sprintf(buf, "./World/zone_%i", zone_num);
ifstream rfile(buf);
if (!rfile) {
buf.Prepend("cp ./World/DEFAULT_ZONE ");
system(buf);
mudlog.log(ERROR, "WARNING: zone file created in update_zone.");
mudlog.log(ERROR, buf);
return 0;
}//if
rfile >> k;
rfile.getline(temp_str, 80); //junk line
while (k != -1) {
room* room_ptr;
if (!rfile) {
if (mudlog.ofLevel(ERROR)) {
mudlog << "ERROR: error reading rooms for zone: " << zone_num
<< " trying to read room# " << k << endl;
}//if
return -1;
}//if
if (k & 0x01000000) { //it's a vehicle
k = (k & ~(0x01000000));
if (mudlog.ofLevel(DBG)) {
mudlog << "About to read vehicle: " << k
<< " zone: " << zone_num << endl;
}
tmp_veh.fileRead(rfile, read_all);
room_ptr = &tmp_veh;
}
else {
if (mudlog.ofLevel(DBG)) {
mudlog << "About to read room: " << k
<< " zone: " << zone_num << endl;
}
tmp_room.fileRead(rfile, read_all);
room_ptr = &tmp_room;
}
if (read_all) {
room_list[k].setTotalLoaded(TRUE); //total_loaded flag
}//if
//log("About to check if need to load more inv into the room.\n");
room_ptr->getInv()->head(ocell);
while ((obj_ptr = ocell.next())) {
if ((obj_count(*(room_ptr->getInv()), *obj_ptr) >
obj_count(*(room_list[k].getInv()), *obj_ptr)) &&
(obj_ptr->getCurInGame()
< obj_list[obj_ptr->getIdNum()].getMaxInGame())) {
if (obj_ptr->isPlayerOwned()) {
object* pobox = load_player_box(obj_ptr->getIdNum());
if (pobox) {
// Denote it as 'modified', (SMOB)
pobox->IN_LIST = room_list[k].getInv();
pobox->setCurRoomNum(k, 0);
affected_objects.gainData(pobox);
room_list[k].gainObject(pobox);
}
else {
//put a virgin copy in the room
room_list[k].gainObject(&(obj_list[obj_ptr->getIdNum()]));
}
}
else {
//points into object array
room_list[k].gainObject(&(obj_list[obj_ptr->getIdNum()]));
}
recursive_init_loads(obj_list[obj_ptr->getIdNum()], 0);
}//if
}//while
//log("Checking for load-more-critters?\n");
List<critter*> tmp_lst(room_ptr->getCrits());
tmp_lst.head(ccell);
int tmp_cc;
int ingame_cc;
while ((crit_ptr = ccell.next())) {
tmp_cc = room_ptr->getCritCount(*crit_ptr);
ingame_cc = room_list[k].getCritCount(*crit_ptr);
if ((tmp_cc > ingame_cc) &&
((crit_ptr->getCurInGame() - tmp_cc) <
crit_ptr->getMaxInGame())) {
//ptr into mob array
if (mudlog.ofLevel(DBG)) {
mudlog << "LOAD: Loading critter#: " << crit_ptr->getIdNum()
<< " in room: " << k << " curInGame: "
<< crit_ptr->getCurInGame() << " maxInGame: "
<< crit_ptr->getMaxInGame() << " tmp_cc: "
<< tmp_cc << " ingame_cc: " << ingame_cc << endl;
}
if (crit_ptr->isPlayerShopKeeper()) {
critter* shop_keeper = load_player_shop_owner(crit_ptr->getIdNum());
if (shop_keeper) {
shop_keeper->setCurRoomNum(k);
room_list[k].gainCritter(shop_keeper);
}//if
}//if
else {
room_list[k].gainCritter(&(mob_list[crit_ptr->getIdNum()]));
}
// Only does objects now.
recursive_init_loads(mob_list[crit_ptr->getIdNum()]);
}//if
}//while
rfile >> k;
rfile.getline(temp_str, 80);
}//while, the big loop, reads in a whole zone
tmp_room.Clear();
tmp_veh.Clear();
return 0;
}//update_zone
void decrease_timed_affecting_pcs() { //will decrease all
//timed affects by one time unit, if zero, it will
//delete them from the spells_affecting list, it
//will output all neccessary messages
//UNLESS THE SPELL IS PERMANENT (ie if time_left = -1)
// log("In decrease_timed_affecting_pcs\n");
Cell<critter*> crit_cell;
pc_list.head(crit_cell);
critter* crit_ptr;
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr;
String buf(100);
while ((crit_ptr = crit_cell.next())) {
if ((++(crit_ptr->pc->idle_ticks) > 30) &&
(!crit_ptr->pc->imm_data || (crit_ptr->IMM_LEVEL < 2))) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Logging off player in decrease_timed_affecting_pcs,"
<< " name: " << *(name_of_crit(*crit_ptr, ~0))
<< " address: " << crit_ptr << " ticks: "
<< crit_ptr->pc->idle_ticks << endl;
}
log_out(*crit_ptr);
}//if
if (TRUE /*crit_ptr->pc->mode == MODE_NORMAL*/) {
crit_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
if (sp_ptr->bonus_duration != -1)
sp_ptr->bonus_duration--;
if (sp_ptr->bonus_duration == 0) {
rem_effects_crit(sp_ptr->stat_spell, *crit_ptr, TRUE);
delete sp_ptr;
sp_ptr = crit_ptr->affected_by.lose(sp_cell);
}//if
else
sp_ptr = sp_cell.next();
}//while
if (crit_ptr->HUNGER > 0)
crit_ptr->HUNGER--; //food
if (crit_ptr->THIRST > 0)
crit_ptr->THIRST--; //drink
if (crit_ptr->DRUGGED > 0)
crit_ptr->DRUGGED--; //drugged
if (crit_ptr->MODE == MODE_NORMAL) {
if (crit_ptr->HUNGER == 0)
show("You are famished.\n", *crit_ptr);
if (crit_ptr->THIRST == 0)
show("You are thirsty.\n", *crit_ptr);
if (crit_ptr->DRUGGED == 0) {
show("You no longer feel drugged.\n", *crit_ptr);
crit_ptr->DRUGGED = -1;
}//if
}//if
/* check for lights about to go out */
if (crit_ptr->EQ[11]) {
if (!crit_ptr->EQ[11]->IN_LIST) {
crit_ptr->EQ[11] = obj_to_sobj(*(crit_ptr->EQ[11]),
&(crit_ptr->inv), crit_ptr->getCurRoomNum());
}//if
if (crit_ptr->EQ[11]->extras[0] == 1) {
Sprintf(buf, "%S flickers.\n",
long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
buf.Cap();
show(buf, *crit_ptr);
}//if
}//if
/* check for lights gone out */
if (crit_ptr->EQ[11]) {
if (crit_ptr->EQ[11]->extras[0] == 0) {
crit_ptr->EQ[11]->extras[0] = -2;
Sprintf(buf, "%S dims and glows its last.\n",
long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
buf.Cap();
show(buf, *crit_ptr);
crit_ptr->crit_flags.turn_off(USING_LIGHT_SOURCE);
room_list[crit_ptr->getCurRoomNum()].checkLight(FALSE);
crit_ptr->EQ[11]->short_desc += "(OUT)";
crit_ptr->EQ[11]->in_room_desc += "(OUT)";
}//if
}//if
}//if
}//while
}//decrease_timed_affecting_pcs
void decrease_timed_affecting_lds() {
// log("In decrease_timed_affecting_pcs\n");
Cell<critter*> crit_cell;
linkdead_list.head(crit_cell);
critter* crit_ptr;
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr;
String buf(100);
while ((crit_ptr = crit_cell.next())) {
if (++(crit_ptr->pc->idle_ticks) > 30) {
mudlog << "Logging off player in decrease_timed_affecting_lds,"
<< " name: " << *(name_of_crit(*crit_ptr, ~0))
<< " address: " << crit_ptr << endl;
log_out(*crit_ptr);
}//if
if (TRUE /*crit_ptr->pc->mode == MODE_NORMAL*/) {
crit_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
if (sp_ptr->bonus_duration != -1)
sp_ptr->bonus_duration--;
if (sp_ptr->bonus_duration == 0) {
rem_effects_crit(sp_ptr->stat_spell, *crit_ptr, TRUE);
delete sp_ptr;
sp_ptr = crit_ptr->affected_by.lose(sp_cell);
}//if
else
sp_ptr = sp_cell.next();
}//while
if (crit_ptr->HUNGER > 0)
crit_ptr->HUNGER--; //food
if (crit_ptr->THIRST > 0)
crit_ptr->THIRST--; //drink
if (crit_ptr->DRUGGED == 0)
crit_ptr->DRUGGED--; //food
if (crit_ptr->MODE == MODE_NORMAL) {
if (crit_ptr->HUNGER == 0)
show("You are famished.\n", *crit_ptr);
if (crit_ptr->THIRST == 0)
show("You are thirsty.\n", *crit_ptr);
if (crit_ptr->DRUGGED == 0) {
show("You no longer feel drugged.\n", *crit_ptr);
crit_ptr->DRUGGED = -1;
}//if
}//if
/* check for lights about to go out */
if (crit_ptr->EQ[11]) {
if (!crit_ptr->EQ[11]->IN_LIST) {
crit_ptr->EQ[11] = obj_to_sobj(*(crit_ptr->EQ[11]),
&(crit_ptr->inv), crit_ptr->getCurRoomNum());
}//if
if (crit_ptr->EQ[11]->extras[0] == 1) {
Sprintf(buf, "%S flickers.\n",
long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
buf.Cap();
show(buf, *crit_ptr);
}//if
}//if
/* check for lights gone out */
if (crit_ptr->EQ[11]) {
if (crit_ptr->EQ[11]->extras[0] == 0) {
crit_ptr->EQ[11]->extras[0] = -2;
Sprintf(buf, "%S dims and glows its last.\n",
long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
buf.Cap();
show(buf, *crit_ptr);
crit_ptr->crit_flags.turn_off(USING_LIGHT_SOURCE);
room_list[crit_ptr->getCurRoomNum()].checkLight(FALSE);
}//if
}//if
}//if
}//while
}//decrease_timed_affecting_lds
void decrease_timed_affecting_smobs() { //will decrease all
//timed affects by one time unit, if zero, it will
//delete them from the spells_affecting list, it
//will output all neccessary messages
//UNLESS THE SPELL IS PERMANENT (ie if time_left = -1)
// log("In decrease_timed_affecting_mobs\n");
Cell<critter*> crit_cell;
affected_mobs.head(crit_cell);
critter* crit_ptr;
critter* tmp_crit;
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr;
room* rm_ptr;
object* tmp_obj;
object* obj_ptr;
crit_ptr = crit_cell.next();
while (crit_ptr) {
if (!IsEmpty(crit_ptr->affected_by)) {
crit_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
if (sp_ptr->bonus_duration != -1)
sp_ptr->bonus_duration--;
if (sp_ptr->bonus_duration == 0) {
rem_effects_crit(sp_ptr->stat_spell, *crit_ptr, TRUE);
delete sp_ptr;
sp_ptr = crit_ptr->affected_by.lose(sp_cell);
}//if
else
sp_ptr = sp_cell.next();
}//while
}//else
// Check to see if the should, and can 'disolve'. This is used for
// summoned and other 'created' mobs.
crit_ptr->mob->incrementTicksOld();
// check to see if we can disolve it...
if (crit_ptr->mob->isDisolvable() && !crit_ptr->isFighting()) {
if (crit_ptr->mob->getTicksOld() > 60) {
if ((crit_ptr->follower_of == NULL) &&
(crit_ptr->master == NULL)) {
// check for hunting...
if (!crit_ptr->isTracking()) {
tmp_crit = crit_ptr;
crit_ptr = affected_mobs.lose(crit_cell);
tmp_crit->emote("wanders away...\n");
rm_ptr = tmp_crit->getCurRoom();
tmp_obj = rm_ptr->getInv()->peekFront();
agg_kills_vict(NULL, *tmp_crit, FALSE); //silently kill
// Now, clean up the corpse.
obj_ptr = rm_ptr->getInv()->peekFront();
if (obj_ptr && (obj_ptr != tmp_obj)) {
//ie if a corpse was placed in the room
// obj_ptr is it, and should be deleted.
rm_ptr->purgeObj(obj_ptr, NULL, FALSE);
}
continue;
}
}//if
}//if
}//if
crit_ptr->mob->decrementTicksTillFreedom();
if (crit_ptr->master) {
if (crit_ptr->mob->getTicksTillFreedom() <= 0) {
crit_ptr->doFollow(*crit_ptr); //follow self
}//if
}//if
crit_ptr = crit_cell.next();
}//while
}//decrease_timed_affecting_smobs
void decrease_timed_affecting_objects() {
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr;
Cell<object*> cell;
affected_objects.head(cell);
object* obj_ptr;
String buf(100);
//log("In decrease_timed_affecting_objects\n");
obj_ptr = cell.next();
while (obj_ptr) {
if (mudlog.ofLevel(DBG)) {
mudlog << "decrease_timed_affecting_objects, obj_number: "
<< obj_ptr->OBJ_NUM << " obj_ptr: " << obj_ptr << endl;
}
obj_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
if (sp_ptr->bonus_duration == 0) {
rem_effects_obj(sp_ptr->stat_spell, *obj_ptr);
delete sp_ptr;
sp_ptr = obj_ptr->affected_by.lose(sp_cell);
}//if
else {
if (sp_ptr->bonus_duration != -1)
sp_ptr->bonus_duration--;
sp_ptr = sp_cell.next();
}//else
}//while
if (mudlog.ofLevel(DBG)) {
mudlog << "About to look after lightts.." << endl;
}
/* take care of lights */
if (obj_ptr->OBJ_FLAGS.get(OBJ_LIGHT_SOURCE)) {
if (obj_ptr->extras[0] > -1) { //is not perm
obj_ptr->extras[0]--;
}//if
}//if
/* corpses */
if (mudlog.ofLevel(DBG)) {
mudlog << "About to look after corpses.." << endl;
}
// If we ever let more than this object disolve, see the normalize_obj
// method for notes on how not to crash the game!!
if (obj_ptr->OBJ_NUM == config.corpseObject) { //if is corpse
if (obj_ptr->bag &&
obj_ptr->bag->time_till_disolve == 0) { //disolve it!!
disolve_object(*obj_ptr);
obj_ptr = affected_objects.lose(cell);
}//if
else {
if (obj_ptr->bag->time_till_disolve != -1) {
obj_ptr->bag->time_till_disolve--;
obj_ptr = cell.next();
}//if
else {
obj_ptr = cell.next();
}
}//else
}//if is a corpse
else {
obj_ptr = cell.next(); //couldn't have disolved
}//else
if (mudlog.ofLevel(DBG)) {
mudlog << "At end of while loop." << endl;
}
}//while
while (!obj_to_be_disolved_list.isEmpty()) {
obj_ptr = obj_to_be_disolved_list.popFront();
if (mudlog.ofLevel(DBG)) {
mudlog << "About to disolve object: " << obj_ptr << endl;
}
do_disolve_object(*obj_ptr);
}//while
if (mudlog.ofLevel(DBG)) {
mudlog << "At end of decrease_timed_affecting_objects." << endl;
}
}//decrease_timed_affecting_objects
void decrease_timed_affecting_doors() {
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr;
Cell<door*> cell;
affected_doors.head(cell);
door* dr_ptr;
String buf(100);
//log("In decrease_timed_affecting_doors\n");
int take_me_off;
dr_ptr = cell.next();
while (dr_ptr) {
if (dr_ptr->ticks_till_disolve > 0) {
mudlog.log(DBG, "About to decrement a door's ticks_till_disolve.\n");
if (--(dr_ptr->ticks_till_disolve) <= 0) {
mudlog.log(DBG, "Gonna delete a door.\n");
room_list[dr_ptr->in_room].DOORS.loseData(dr_ptr);
Sprintf(buf, "%S closes up and vanishes.\n",
name_of_door(*dr_ptr, ~0));
buf.Cap();
room_list[dr_ptr->in_room].showAllCept(buf);
delete dr_ptr;
dr_ptr = affected_doors.lose(cell);
continue;
}//if
}//if
take_me_off = TRUE;
dr_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
take_me_off = FALSE;
if (sp_ptr->bonus_duration != -1)
sp_ptr->bonus_duration--;
if ((sp_ptr->bonus_duration == 0) || (sp_ptr->bonus_duration < -1)) {
rem_effects_door(sp_ptr->stat_spell, *dr_ptr,
room_list[abs(dr_ptr->destination)],
room_list[dr_ptr->in_room], TRUE);
delete sp_ptr;
sp_ptr = dr_ptr->affected_by.lose(sp_cell);
}//if
else {
sp_ptr = sp_cell.next();
}
}//while
if (take_me_off)
dr_ptr = affected_doors.lose(cell);
else
dr_ptr = cell.next();
}//while
}//decrease_timed_affecting_doors
void disolve_object(object& obj) {
obj_to_be_disolved_list.append(&obj);
}//disolve_object
void do_disolve_object(object& obj) {
Cell<object*> cell(obj.inv);
object *obj_ptr;
String buf(100);
if (mudlog.ofLevel(DBG)) {
mudlog << "do_disolve_obj, addr: " << &obj << endl;
}
if (!obj.in_list) {
core_dump("ERROR: disolve_object called on non-sobj.\n");
}//if
//log("Before while\n");
while ((obj_ptr = cell.next())) {
if (obj_ptr->in_list)
obj_ptr->in_list = obj.in_list;
obj.in_list->append(obj_ptr);
}//while
//log("Before Clear()\n");
obj.inv.clear();
if (obj.in_list->loseData(&obj)) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Successfully removed it from it's list.\n";
}
}
else {
Sprintf(buf, "Failed to remove object ptr: %i from it's list.",
(int)(&obj));
mudlog << "Failed to remove object ptr: " << &obj << " from it's list:"
<< obj.in_list << endl;
core_dump(buf);
}
//obj to be disolved
//log("Lost data.\n");
delete &obj; //should fire deconstructors
//log("Done.\n");
}//do_disolve_obj
void decrease_timed_affecting_rooms() { //will decrease all
//timed affects by one time unit, if zero, it will
//delete them from the spells_affecting list, it
//will output all neccessary messages
//UNLESS THE SPELL IS PERMANENT (ie if time_left = -1)
Cell<room*> cell;
affected_rooms.head(cell);
room* rm_ptr = NULL;
Cell<stat_spell_cell*> sp_cell;
stat_spell_cell* sp_ptr = NULL;
short take_it_off = FALSE;
if (mudlog.ofLevel(DBG)) {
mudlog << "In dta_rooms: affected_rooms.size() == "
<< affected_rooms.size() << endl;
}
rm_ptr = cell.next();
while (rm_ptr) {
take_it_off = TRUE;
if (mudlog.ofLevel(DBG)) {
mudlog << "dta_rooms, rm_ptr: " << rm_ptr << endl;
}
Cell<door*> dcll(rm_ptr->DOORS);
door* dptr, *tmp_dptr;
dptr = dcll.next();
while (dptr) {
if (dptr->ticks_till_disolve != -1) {
if ((--dptr->ticks_till_disolve) == 0) {
tmp_dptr = dptr;
dptr = rm_ptr->DOORS.lose(dcll);
delete tmp_dptr;
}//if
else {
take_it_off = FALSE;
dptr = dcll.next();
}//else
}//if
else
dptr = dcll.next();
}//while
rm_ptr->affected_by.head(sp_cell);
sp_ptr = sp_cell.next();
while (sp_ptr) {
if (sp_ptr->bonus_duration != -1) { //if not permanent
take_it_off = FALSE;
sp_ptr->bonus_duration--;
}//if
if (sp_ptr->bonus_duration == 0) {
rem_effects_room(sp_ptr->stat_spell, *rm_ptr, TRUE);
delete sp_ptr;
sp_ptr = rm_ptr->affected_by.lose(sp_cell);
}//if
else
sp_ptr = sp_cell.next();
}//while
if (take_it_off) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Taking it off...\n";
}
rm_ptr = affected_rooms.lose(cell);
}
else {
if (mudlog.ofLevel(DBG)) {
mudlog << "NOT Taking it off...\n";
}
rm_ptr = cell.next();
}
}//while
}//decrease_timed_affecting_rooms
void add_spell_affecting_critter(int spell, int duration, critter& vict) {
stat_spell_cell* spcell = new stat_spell_cell;
//log("In add_spell_affecting_critter");
spcell->stat_spell = spell;
spcell->bonus_duration = duration;
Put(spcell, vict.affected_by);
}//gain spell_affected_by
void add_spell_affecting_obj(int spell, int duration, object& vict) {
stat_spell_cell* spcell = new stat_spell_cell;
//log("In add_spell_affecting_obj\n");
spcell->stat_spell = spell;
spcell->bonus_duration = duration;
Put(spcell, vict.affected_by);
}//gain spell_affected_by
void show(const char* message, critter& pc) {
//log(message);
if (mudlog.ofLevel(XMT)) {
mudlog << "OUTPUT from -:" << *(pc.getName());
mudlog << ":- -:" << message << ":-\n" << endl;
}
if (pc.possessed_by) {
pc.possessed_by->show("[POSSESSED]: ");
pc.possessed_by->show(message);
}
if (pc.pc) {
critter* snooper;
if ((snooper = pc.SNOOPED_BY)) {
mudlog.log(TRC, "Within snoop if\n");
String buf2(100);
Sprintf(buf2, "SNOOP_OUT: -:%s:-\n", message);
snooper->show(buf2);
}//if snoop
pc.setDoPrompt(TRUE);
if (!message)
return;
if (pc.pc->output.Strlen() < OUTPUT_MAX_LEN) {
pc.pc->output.Append(message);
}//if
}//if
}//show
void show_all(const char* msg, const room& rm) {
rm.showAllCept(msg, NULL);
}
void show_all_but_2(critter& A, critter& B, const char* msg,
room& rm) {
Cell<critter*> cell(rm.getCrits());
critter* crit_ptr;
// log("In show_all_but_2\n");
while ((crit_ptr = cell.next())) {
if ((crit_ptr != &A) && (crit_ptr != &B))
if (crit_ptr->POS < POS_SLEEP)
show(msg, *crit_ptr);
}//while
Cell<object*> cll(*(rm.getInv()));
object* obj;
while ((obj = cll.next())) {
if (obj->obj_proc && (crit_ptr = obj->obj_proc->w_eye_owner)) {
if (crit_ptr->POS < POS_SLEEP) {
show("#####", *crit_ptr);
show(msg, *crit_ptr);
}//if
}//if
}//while
}//show_all_but_2
int doShowList(critter* pc, CSelectorColl& includes, CSelectorColl& denies,
List<critter*>& lst, CSentryE cs_entry, ...) {
va_list argp;
va_start(argp, cs_entry);
int retval = 0;
retval = vDoShowList(pc, includes, denies, lst, cs_entry, argp);
va_end(argp);
return retval;
}
int vDoShowList(critter* pc, CSelectorColl& includes, CSelectorColl& denies,
List<critter*>& lst, CSentryE cs_entry, va_list argp) {
Cell<critter*> cll(lst);
critter* ptr;
String buf(100);
String buf2(100);
while ((ptr = cll.next())) {
if (!(denies.matches(ptr, pc))) {
if (includes.matches(ptr, pc)) {
if (mudlog.ofLevel(DBG)) {
mudlog << "vDoShowList, includes matched." << endl;
mudlog << "cstr of " << (int)(cs_entry) << "-:"
<< cstr(cs_entry, *ptr) << ":-" << endl;
}
vSprintf(buf, cstr(cs_entry, *ptr), argp);
if (mudlog.ofLevel(DBG)) {
mudlog << endl << "buf -:" << buf << ":-" << endl << endl;
}
ptr->show(buf);
}//if
}//if
}//while
return 0;
}//voDoShowList
void show_all(const char* msg) {
Cell<critter*> cell(pc_list);
critter* crit_ptr;
while ((crit_ptr = cell.next())) {
if (crit_ptr->pc && crit_ptr->PC_FLAGS.get(14)) {
show(msg, *crit_ptr);
}//if
}//while
}//show_all_info
void out_str(const List<String*>& lst, critter& pc) {
Cell<String*> cell(lst);
String *string;
// log("In out_str.\n");
if (pc.pc) {
if (IsEmpty(lst)) {
show("You see nothing special.\n", pc);
return;
}//if
while ((string = cell.next())) {
show(*string, pc);
show("\n", pc);
}//while
}//if
}//out_str
/** Can over-ride the VIS/SEE bit stuff if you set see_all to true. */
void out_crit(const List<critter*>& lst, critter& pc, int see_all = FALSE) {
Cell<critter*> cell(lst);
Cell<stat_spell_cell*> cell2;
stat_spell_cell* sp;
critter* crit_ptr;
String buf(100);
// log("In out_crit\n");
int see_bits = pc.getSeeBit();
if (see_all) {
see_bits = ~0;
}
if (pc.isUsingClient())
show("<MOB_LIST>", pc);
else if (pc.isUsingColor()) {
pc.show(*(pc.getMobListColor()));
}
while ((crit_ptr = cell.next())) {
if (mudlog.ofLevel(DBG)) {
mudlog << "out_crit: got critter: " << *(crit_ptr->getName())
<< endl;
}
if (detect(see_bits, crit_ptr->VIS_BIT) &&
(crit_ptr != &pc)) { //can see it, not looker
if ((crit_ptr->isHiding()) && //if is hiding
(d(1, pc.LEVEL + 30) <
d(1, max(get_percent_lrnd(HIDE_SKILL_NUM, *crit_ptr) * 6,
get_percent_lrnd(BLEND_SKILL_NUM, *crit_ptr) * 6)))) {
continue; //successful hide
}//if
if (crit_ptr->pc) { //is a pc
if (mudlog.ofLevel(DBG)) {
mudlog << "Doing pc..." << endl;
}
if (crit_ptr->isParalyzed()) {
Sprintf(buf, " %S %S %s\n",
name_of_crit(*crit_ptr, see_bits),
&(crit_ptr->short_desc), cstr(CS_PARALYZED, pc));
}
else {
Sprintf(buf, " %S %S %s\n",
name_of_crit(*crit_ptr, see_bits),
&(crit_ptr->short_desc), crit_ptr->getPosnStr(pc));
}
buf.Cap();
if (crit_ptr->VIS_BIT & 2) {
buf.setCharAt(1, '*');
}//if
show(buf, pc);
crit_ptr->affected_by.head(cell2);
while ((sp = cell2.next())) {
if (sp->stat_spell == SANCTUARY_SKILL_NUM) {
Sprintf(buf, "\t\t%s glows brightly.\n",
get_he_she(*crit_ptr));
buf.Cap();
show(buf, pc);
break; //cause there are no others to display now
}//if
}//while
}//if
else if (crit_ptr->isSmob() &&
(crit_ptr->POS != mob_list[crit_ptr->getIdNum()].POS)) {
//is a SMOB with a different posn than corresponding MOB
if (mudlog.ofLevel(DBG)) {
mudlog << "Doing SMOB" << endl;
}
if (pc.shouldShowVnums()) {
if (crit_ptr->isParalyzed()) {
Sprintf(buf, " [%i]%P11 %S %s\n", crit_ptr->MOB_NUM,
name_of_crit(*crit_ptr, see_bits), cstr(CS_PARALYZED, pc));
}
else {
Sprintf(buf, " [%i]%P11 %S %s\n", crit_ptr->MOB_NUM,
name_of_crit(*crit_ptr, see_bits),
crit_ptr->getPosnStr(pc));
}
}
else {
if (crit_ptr->isParalyzed()) {
Sprintf(buf, " %S %s\n",
name_of_crit(*crit_ptr, see_bits),
cstr(CS_PARALYZED, pc));
}
else {
Sprintf(buf, " %S %s\n",
name_of_crit(*crit_ptr, see_bits),
crit_ptr->getPosnStr(pc));
}
}
buf.Cap();
if (crit_ptr->VIS_BIT & 2) {
buf.setCharAt(1, '*');
}//if
show(buf, pc);
crit_ptr->affected_by.head(cell2);
while ((sp = cell2.next())) {
if (sp->stat_spell == SANCTUARY_SKILL_NUM) {
Sprintf(buf, "\t\t%s glows brightly.\n",
get_he_she(*crit_ptr));
buf.Cap();
show(buf, pc);
break;
}//if
}//while
}//if
else if (crit_ptr->mob) { //then it is a mob, or SMOB w/same posn as MOB
if (mudlog.ofLevel(DBG)) {
mudlog << "Doing MOB" << endl;
}
if (pc.shouldShowVnums()) {
if (crit_ptr->isParalyzed()) {
Sprintf(buf, " [%i]%P11 %S %s\n", crit_ptr->MOB_NUM,
name_of_crit(*crit_ptr, see_bits), cstr(CS_PARALYZED, pc));
}
else {
Sprintf(buf, " [%i]%P11 %S\n", crit_ptr->MOB_NUM,
&(crit_ptr->in_room_desc));
}
}//if
else {
if (crit_ptr->isParalyzed()) {
Sprintf(buf, " %S %s\n",
name_of_crit(*crit_ptr, see_bits), cstr(CS_PARALYZED, pc));
}
else {
Sprintf(buf, " %S\n", &(crit_ptr->in_room_desc));
}
}
if (crit_ptr->VIS_BIT & 2) {
buf.setCharAt(1, '*');
}//if
buf.Cap();
show(buf, pc);
crit_ptr->affected_by.head(cell2);
while ((sp = cell2.next())) {
if (sp->stat_spell == SANCTUARY_SKILL_NUM) {
Sprintf(buf, "\t\t%s glows brightly.\n",
get_he_she(*crit_ptr));
buf.Cap();
show(buf, pc);
break;
}//if
}//while
}//else
else {
mudlog << __PRETTY_FUNCTION__ << "ERROR: crit_ptr is not sane: "
<< crit_ptr << endl;
}
}//if
}//while
if (pc.USING_CLIENT) {
show("</MOB_LIST>", pc);
}
else if (pc.isUsingColor()) {
pc.show(*(pc.getDefaultColor()));
}
}//out_crit
void out_inv(const List<object*>& lst, critter& pc,
const short type_of_list) {
//outs the names object*
Cell<object*> cell(lst);
object* obj_ptr;
String buf(100);
mudlog.log(TRC, "In out_inv.\n");
if (pc.isUsingClient()) {
show("<ITEM_LIST>", pc);
}
else if (pc.isUsingColor()) {
pc.show(*(pc.getObjListColor()));
}
if (IsEmpty(lst) && type_of_list == OBJ_INV) {
show(" [empty] \n", pc);
if (pc.isUsingClient()) {
show("</ITEM_LIST>", pc);
}
else if (pc.isUsingColor()) {
pc.show(*(pc.getDefaultColor()));
}
mudlog.log(DBG, "Done with out_inv (empty).\n");
return;
}//if
switch (type_of_list)
{
case ROOM_INV:
while ((obj_ptr = cell.next())) {
if (detect(pc.SEE_BIT, obj_ptr->OBJ_VIS_BIT)) {
if (pc.shouldShowVnums()) {
char tmp[50];
sprintf(tmp, "%p: ", obj_ptr);
Sprintf(buf, " %s [%i] %P11 %S", tmp, obj_ptr->OBJ_NUM,
&(obj_ptr->in_room_desc));
}
else {
Sprintf(buf, "\t%S", &(obj_ptr->in_room_desc));
}
buf.Cap();
if (obj_ptr->isHerb()) {
if (d(1, 100) <=
d(1, 2 * get_percent_lrnd(HERBALISM_SKILL_NUM, pc))) {
buf.Append("(herb)");
}//if
}//if
if (pc.canDetectMagic() &&
(!IsEmpty(obj_ptr->affected_by) ||
!IsEmpty(obj_ptr->stat_affects))) {
buf.Append(" {Blue Glow}\n");
}//if
else {
buf.Append("\n");
}
if (obj_ptr->OBJ_VIS_BIT & 2) {
buf.Prepend("*");
}//if
show(buf, pc);
}//if
}//while
break;
case OBJ_INV: case CRIT_INV:
while ((obj_ptr = cell.next())) {
if (detect(pc.SEE_BIT, obj_ptr->OBJ_VIS_BIT)) {
if (pc.shouldShowVnums()) {
char tmp[50];
sprintf(tmp, "%p: ", obj_ptr);
Sprintf(buf, " %s [%i] %P11 %S", tmp, obj_ptr->OBJ_NUM,
long_name_of_obj(*obj_ptr, ~0));
}
else {
Sprintf(buf, "\t%S", long_name_of_obj(*obj_ptr, ~0));
}
buf.Cap();
if (obj_ptr->isHerb()) {
if (d(1, 100) <=
d(1, 2 * get_percent_lrnd(HERBALISM_SKILL_NUM, pc))) {
buf.Append("(herb)");
}//if
}//if
if (pc.canDetectMagic() &&
(!IsEmpty(obj_ptr->affected_by) ||
!IsEmpty(obj_ptr->stat_affects))) {
buf.Append(" {Blue Glow}\n");
}//if
else {
buf.Append("\n");
}
if (obj_ptr->OBJ_VIS_BIT & 2) {
buf.Prepend("*");
}//if
show(buf, pc);
}//if
}//while
break;
default:
mudlog.log(ERROR, "ERROR: default called in out_inv.\n");
break;
}//switch type_of_list
if (pc.isUsingClient()) {
show("</ITEM_LIST>", pc);
}
else if (pc.isUsingColor()) {
pc.show(*(pc.getDefaultColor()));
}
mudlog.log(DBG, "Done with out_inv.\n");
}//out_inv
critter* have_crit_named(List<critter*>& lst, const int i_th,
const String* name, const int see_bit,
const room& rm, int do_exact = FALSE) {
int foo = 0;
return have_crit_named(lst, i_th, name, see_bit, foo, rm, do_exact);
}
critter* have_crit_named(List<critter*>& lst, const int i_th,
const String* name, const int see_bit,
int& count_sofar, const room& rm, int do_exact = FALSE) {
Cell<String*> char_cell;
Cell<critter*> cell(lst);
critter* crit_ptr;
int count = 0;
int ptr_v_bit, len;
String *string;
if (mudlog.ofLevel(DBG)) {
mudlog << "in have_crit_named, i_th: " << i_th << " name -:"
<< *name << ":- see_bit: " << see_bit << " rm# "
<< rm.getIdNum() << " do_exact: " << do_exact << endl;
}
if (!name) {
mudlog.log(ERROR, "ERROR: NULL name sent to have_crit_named.\n");
return NULL;
}//if
if ((len = name->Strlen()) == 0)
return NULL;
if (i_th <= 0)
return NULL;
int matched;
while ((crit_ptr = cell.next())) {
ptr_v_bit = (crit_ptr->VIS_BIT | rm.getVisBit());
if (detect(see_bit, ptr_v_bit)) {
crit_ptr->names.head(char_cell);
matched = FALSE;
while ((string = char_cell.next()) && !matched) {
if (do_exact) {
if (strcasecmp(*string, *name) == 0) {
matched = TRUE;
count++;
count_sofar++;
}//if
}//if exact
else {
if (strncasecmp(*string, *name, len) == 0) {
matched = TRUE;
count++;
count_sofar++;
}//if
}//else
if (count == i_th) {
return crit_ptr;
}//if
}//while
}//if
}//while
return NULL;
}//have_crit_named
int crit_sub_a_4_b(critter* a, List<critter*>& lst,
const int i_th, const String* name,
const int see_bit, room& rm) {
Cell<String*> char_cell;
Cell<critter*> cell(lst);
critter* crit_ptr;
int count = 0, ptr_v_bit;
String *string;
//log("In crit_sub_a_4_b.\n");
if (!name || !a) {
mudlog.log(ERROR, "ERROR: NULL(s) sent to crit_sub_a_4_b.\n");
return FALSE;
}//if
if (name->Strlen() == 0) {
mudlog.log(ERROR, "ERROR: name of zero length sent to crit_sub_a_4_b.\n");
return FALSE;
}//if
int matched;
while ((crit_ptr = cell.next())) {
ptr_v_bit = (crit_ptr->VIS_BIT | rm.getVisBit());
if (detect(see_bit, ptr_v_bit)) {
crit_ptr->names.head(char_cell);
matched = FALSE;
while ((string = char_cell.next()) && !matched) {
if (strncasecmp(*string, *name, name->Strlen()) == 0){
matched = TRUE;
count++;
if (count == i_th) { //found right one
lst.assign(cell, a);
return TRUE;
}//if
}//if
}//while
}//if
}//while
return FALSE;
}//crit_sub_a_4_b
int obj_sub_a_4_b(object* a, List<object*>& lst, const int i_th,
const String* name, const int see_bit, room& rm) {
Cell<String*> char_cell;
Cell<object*> cell(lst);
object* obj_ptr;
int count = 0, ptr_v_bit;
String *string;
//log("In obj_sub_a_4_b.\n");
if (!name || !a) {
mudlog.log(ERROR, "ERROR: NULL(s) sent to obj_sub_a_4_b.\n");
return FALSE;
}//if
if (name->Strlen() == 0) {
mudlog.log(ERROR, "ERROR: name of zero length sent to obj_sub_a_4_b.\n");
return FALSE;
}//if
int matched;
while ((obj_ptr = cell.next())) {
ptr_v_bit = (obj_ptr->OBJ_VIS_BIT | rm.getVisBit());
if (detect(see_bit, ptr_v_bit)) {
obj_ptr->names.head(char_cell);
matched = FALSE;
while ((string = char_cell.next()) && !matched) {
if (strncasecmp(*string, *name, name->Strlen()) == 0){
matched = TRUE;
count++;
if (count == i_th) { //found right one
//obj_ptr = Prev(cell); //back cell up one
lst.assign(cell, a);
return TRUE;
}//if
}//if
}//while
}//if
}//while
return FALSE;
}//obj_sub_a_4_b
object* have_obj_named(const List<object*>& lst, const int i_th,
const String* name, const int see_bit,
const room& rm) {
int foo = 0;
return have_obj_named(lst, i_th, name, see_bit, rm, foo);
}
object* have_obj_named(const List<object*>& lst, const int i_th,
const String* name, const int see_bit,
const room& rm, int& count_sofar) {
Cell<String*> char_cell;
Cell<object*> cell(lst);
object* obj_ptr;
int count = 0, ptr_v_bit;
String *string;
if (!name) {
mudlog.log(ERROR, "ERROR: Null sent to have_obj_named.k\n");
return NULL;
}//if
if (name->Strlen() == 0)
return NULL;
int matched;
while ((obj_ptr = cell.next())) {
ptr_v_bit = (obj_ptr->OBJ_VIS_BIT | rm.getVisBit());
if (detect(see_bit, ptr_v_bit)) {
obj_ptr->names.head(char_cell);
matched = FALSE;
while ((string = char_cell.next()) && !matched) {
if (strncasecmp(*string, *name, name->Strlen()) == 0){
matched = TRUE;
count++;
count_sofar++;
if (count == i_th) {
return obj_ptr;
}//if
}//if
}//while
}//if
}//while
return NULL;
}//have_obj_named
int obj_named_count(const List<object*>& lst, const String* name,
const int see_bit, const room& rm) {
Cell<String*> char_cell;
Cell<object*> cell(lst);
object* obj_ptr;
int count = 0, ptr_v_bit;
String *string;
if (name->Strlen() == 0)
return 0;
while ((obj_ptr = cell.next())) {
ptr_v_bit = (obj_ptr->OBJ_VIS_BIT | rm.getVisBit());
if (detect(see_bit, ptr_v_bit)) {
obj_ptr->names.head(char_cell);
while ((string = char_cell.next())) {
if (strncasecmp(*string, *name, name->Strlen()) == 0){
count++;
break; //out of the internal while loop
}//if
}//while
}//if
}//while
return count;
}//have_obj_named
int obj_is_named(const object& obj, const String& name) {
Cell<String*> char_cell(obj.names);
String *string;
int len;
//log("In obj_is_named\n");
if ((len = name.Strlen()) == 0)
return FALSE;
while ((string = char_cell.next())) {
if (strncasecmp(*string, name, len) == 0) {
return TRUE;
}//if
}//while
return FALSE;
}//obj_is_named
int door_is_named(const door_data& dr, const String& name) {
Cell<String*> char_cell(dr.names);
String *string;
int len;
//log("In obj_is_named\n");
if ((len = name.Strlen()) == 0)
return FALSE;
while ((string = char_cell.next())) {
if (strncasecmp(*string, name, len) == 0) {
return TRUE;
}//if
}//while
return FALSE;
}//door_is_named
//boolean functionality here...
int mob_is_named(const critter& pc, const String& name) {
return pc.isNamed(name);
}
const String* name_of_crit(critter& pc, int see_bit) {
return pc.getName(see_bit);
}
String* name_of_obj(const object& obj, int see_bit) {
if (!detect(see_bit, obj.OBJ_VIS_BIT)) {
return &SOMETHING;
}//if
else {
String* tmp = Top(obj.names);
if (tmp)
return tmp;
else
return &SOMETHING;
}//else
}//name_of_obj
String* long_name_of_obj(object& obj, int see_bit) {
if (obj.short_desc.Strlen() == 0 ||
!detect(see_bit, obj.OBJ_VIS_BIT)) {
return &SOMETHING;
}//if
else {
return &(obj.short_desc);
}//else
}//long name_of_obj
String* name_of_room(const room& rm, int see_bit) {
if ((IsEmpty(rm.names)) || !detect(see_bit, rm.getVisBit())) {
return &SOMEWHERE;
}//if
else {
return Top(rm.names);
}//else
}//name_of_room
String* name_of_door(const door& dr, int see_bit) {
return name_of_dr_data(*(dr.dr_data), see_bit, dr.destination);
}//name_of_door
String* name_of_dr_data(const door_data& dr, int see_bit, int dest) {
Cell<String*> cell(dr.names);
String *str, *str2;
if (!detect(see_bit, dr.vis_bit)) {
return &SOMETHING;
}//if
if (IsEmpty(dr.names))
return &UNKNOWN;
if (dest >= 0) {
str = cell.next();
str2 = cell.next();
if (str2)
if (*str2 != "#")
return str2;
else
return str;
else // no specific name, just the direction
return str;
}//if
else {
str = cell.prev();
str2 = cell.prev();
if (str2)
if (*(str2) != "#")
return str2;
else
return str;
else // no specific name, just the direction
return str;
}//else
}//name_of_dr_data
// Will be sent an IP with an optional N on the beginning,
// all, not just newbies
short is_banned(const String& ip) {
Cell<String*> cll(banned_hosts);
String* ptr;
while ((ptr = cll.next())) {
if (toupper(ptr->charAt(0)) == 'N') {
continue; //not interested in newbie bans here.
}//if
else {
if (strncmp(ip, *(ptr), min(ip.Strlen(), ptr->Strlen())) == 0)
return TRUE;
}
}//while
return FALSE;
}//is_banned
// Will be sent an IP with an optional N on the beginning,
// all, not just newbies
short is_newbie_banned(const String& ip) {
Cell<String*> cll(banned_hosts);
String* ptr;
while ((ptr = cll.next())) {
if (toupper(ptr->charAt(0)) == 'N') {
const char* str = *ptr; //convert to const char*
if (strncmp(ip, str + 1, max(ip.Strlen(), ptr->Strlen() - 1)) == 0)
return TRUE;
}//if
}//while
return FALSE;
}//is_newbie_banned
int detect(int see_bit, int vis_bit) {
return ((see_bit & vis_bit) == vis_bit);
}//detect