// $Id: door.cc,v 1.3.2.11 2000/05/03 02:25:12 justin Exp $ // $Revision: 1.3.2.11 $ $Author: justin $ $Date: 2000/05/03 02:25:12 $ // //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 // //*********************************************************************// ///************************** struct door data ********************/// #include "door.h" #include "misc.h" #include "misc2.h" #include "commands.h" #include "room.h" #include <PtrArray.h> int door_data::_cnt = 0; door_data::door_data () { //default constructor _cnt++; Clear(); }//door_data constructor door_data::door_data (const door_data& source) { _cnt++; *this = source; }//door door_data::~door_data () { _cnt--; Clear(); } //destructor door_data& door_data::operator= (const door_data& source) { if (this == &source) return *this; String* st_ptr; Cell<String*> st_cell(source.names); vis_bit = source.vis_bit; door_num = source.door_num; token_num = source.token_num; key_num = source.token_num; in_zone = source.in_zone; door_data_flags = source.door_data_flags; //bitfield overloaded = clear_ptr_list(names); while ((st_ptr = st_cell.next())) { names.append(new String(*st_ptr)); }//while long_desc = source.long_desc; return *this; }//operator= void door_data::Clear() { vis_bit = door_num = key_num = token_num = in_zone = 0; clear_ptr_list(names); long_desc.Clear(); door_data_flags.off_all(); }//clear #ifdef USEMYSQL void door_data::dbRead(int door_num) { MYSQL_RES* result; MYSQL_ROW row; String query="select * from Doors where DOOR_NUM="; query += door_num; if (mysql_real_query(database, query, strlen(query))==0) { if ((result=mysql_store_result(database))==NULL) { if (mudlog.ofLevel(WRN)) { mudlog << "In door_data::dbRead(int):\n"; mudlog << "Error retrieving query results: " << mysql_error(database) << endl; } return; } row=mysql_fetch_row(result); vis_bit = atoi(row[DOORTBL_VIS_BIT]); door_num = atoi(row[DOORTBL_DOOR_NUM]); token_num = atoi(row[DOORTBL_TOKEN_NUM]); in_zone = atoi(row[DOORTBL_IN_ZONE]); vis_bit |= 1024; door_data_flags.set(DDFLAG_OPEN_EXIT, atoi(row[DOORTBL_OPEN_EXIT])); door_data_flags.set(DDFLAG_MAGIC_LOCKABLE, atoi(row[DOORTBL_MAGIC_LOCKABLE])); door_data_flags.set(DDFLAG_CLOSED, atoi(row[DOORTBL_CLOSED])); door_data_flags.set(DDFLAG_LOCKED, atoi(row[DOORTBL_LOCKED])); door_data_flags.set(DDFLAG_PICKABLE, atoi(row[DOORTBL_PICKABLE])); door_data_flags.set(DDFLAG_LOCKABLE, atoi(row[DOORTBL_LOCKABLE])); door_data_flags.set(DDFLAG_MAG_LOCKED, atoi(row[DOORTBL_MAG_LOCKED])); door_data_flags.set(DDFLAG_DESTRUCTABLE, atoi(row[DOORTBL_DESTRUCTABLE])); door_data_flags.set(DDFLAG_CLOSABLE, atoi(row[DOORTBL_CLOSABLE])); door_data_flags.set(DDFLAG_FLIPPABLE, atoi(row[DOORTBL_FLIPPABLE])); door_data_flags.set(DDFLAG_PC_CANT_OPEN, atoi(row[DOORTBL_PC_CANT_OPEN])); door_data_flags.set(DDFLAG_VEHICLE_EXIT, atoi(row[DOORTBL_VEHICLE_EXIT])); door_data_flags.set(DDFLAG_SECRET, atoi(row[DOORTBL_SECRET])); door_data_flags.set(DDFLAG_BLOCKED, atoi(row[DOORTBL_BLOCKED])); door_data_flags.set(DDFLAG_SECRET_WHEN_OPEN, atoi(row[DOORTBL_SECRET_WHEN_OPEN])); door_data_flags.set(DDFLAG_CONSUMES_KEY, atoi(row[DOORTBL_CONSUMES_KEY])); door_data_flags.set(DDFLAG_NO_PASSDOOR, atoi(row[DOORTBL_NO_PASSDOOR])); door_data_flags.turn_on(DDFLAG_IN_USE); setComplete(); mysql_free_result(result); } else { if (mudlog.ofLevel(WRN)) { mudlog << "In door_data::dbRead(int):\n"; mudlog << "Error executing query: " << mysql_error(database) << endl; } return; } // names query = "select NAME from DoorNames where DOOR_NUM="; query += door_num; if (mysql_real_query(database, query, strlen(query))==0) { if ((result=mysql_store_result(database))==NULL) { if (mudlog.ofLevel(WRN)) { mudlog << "In door_data::dbRead(int):\n"; mudlog << "Error retrieving query results: " << mysql_error(database) << endl; } return; } while ((row=mysql_fetch_row(result))) { Put(new String(row[0]), names); } mysql_free_result(result); } else { if (mudlog.ofLevel(WRN)) { mudlog << "In door_data::dbRead(int):\n"; mudlog << "Error executing query: " << mysql_error(database) << endl; } return; } } #endif void door_data::fileRead(ifstream& da_file) { char tmp[81]; String tmp_str(80); String* string; int test = TRUE; Clear(); if (!da_file) { if (mudlog.ofLevel(ERROR)) { mudlog << "ERROR: da_file FALSE in door_data read." << endl; } return; } da_file >> vis_bit >> door_num >> token_num >> key_num >> in_zone; da_file.getline(tmp, 80); vis_bit |= 1024; //hack, forgot blindness bit :P door_data_flags.Read(da_file); door_data_flags.turn_on(10); //set in use flag no matter what setComplete(); //if we can read it, it's complete! test = TRUE; while (test) { if (!da_file) { if (mudlog.ofLevel(ERROR)) { mudlog << "ERROR: da_file FALSE in door_data read." << endl; } return; } da_file >> tmp_str; if (strcmp(tmp_str, "~") == 0) { test = FALSE; }//if else { string = new String(tmp_str); Put(string, names); }//else }//while da_file.getline(tmp, 80); long_desc.Termed_Read(da_file); }//Read void door_data::Write(ofstream& da_file) { Cell<String*> cll(names); String* ptr; da_file << vis_bit << " " << door_num << " " << token_num << " " << key_num << " " << in_zone << "\tvbit, door#, token#, key#\n"; door_data_flags.Write(da_file); int len = 0; while ((ptr = cll.next())) { len += ptr->Strlen() + 1; if (len > 79) { da_file << endl; len = 0; }//if da_file << *ptr << " "; }//while da_file << "~" << "\tnames\n"; parse_for_max_80(long_desc); da_file << long_desc << endl << "~" << endl; }//Write //*******************************************************// //*********************** door **************************// int door::_cnt = 0; door::door() { _cnt++; dr_data = NULL; crit_blocking = NULL; destination = in_room = 0; distance = 0; /* number of battle rounds it takes to move can be used to slow ppl/vehicles down when logical */ ticks_till_disolve = -1; // don't disolve }//door constructor door::door(const door& source) { _cnt++; dr_data = NULL; crit_blocking = NULL; *this = source; ticks_till_disolve = -1; }//door copy constructor door::~door() { _cnt--; affected_doors.loseData(this); Clear(); }//destructor void door::Clear() { dr_data = NULL; //do not delete data pointed too, its in static arrays crit_blocking = NULL; destination = in_room = 0; distance = 0; clear_ptr_list(affected_by); ticks_till_disolve = -1; }//Clear() door& door::operator= (const door& source) { if (this == &source) return *this; Clear(); if (!source.dr_data) { mudlog.log(ERROR, "ERROR: assigning with empty door as source.\n"); return *this; }//if if (!dr_data) { dr_data = new door_data(*(source.dr_data)); }//if else { *dr_data = *(source.dr_data); }//else destination = source.destination; distance = source.distance; Cell<stat_spell_cell*> cll(source.affected_by); stat_spell_cell* ptr; while ((ptr = cll.next())) { Put(new stat_spell_cell(*ptr), affected_by); }//while crit_blocking = source.crit_blocking; ticks_till_disolve = source.ticks_till_disolve; in_room = source.in_room; return *this; }//operator= void door::Read(ifstream& da_file) { int data_index; int i, tmp; char buf[82]; Clear(); if (!da_file) { if (mudlog.ofLevel(ERROR)) { mudlog << "ERROR: da_file FALSE in door read." << endl; } return; } da_file >> data_index; if (!check_l_range(data_index, 0, NUMBER_OF_DOORS, mob_list[0], FALSE)) { mudlog.log(ERROR, "ERROR: door_index is out of range.\n"); data_index = 1; //at least it won't crash this way }//if /* ok, got good data_index */ dr_data = &(door_list[data_index]); da_file >> destination; da_file >> distance; /* comment this out for reading original, DB_UPGRADE */ da_file.getline(buf, 80); da_file >> i; int is_affected = FALSE; while (i != -1) { //affected by if (!da_file) { if (mudlog.ofLevel(ERROR)) { mudlog << "ERROR: da_file FALSE in door read." << endl; } return; } is_affected = TRUE; da_file >> tmp; Put(new stat_spell_cell(i, tmp), affected_by); da_file >> i; }//while if (is_affected) { affected_doors.gainData(this); } da_file.getline(buf, 80); }// Read() void door::Write(ofstream& da_file) { int count = 0; da_file << dr_data->door_num << " " << destination << " " << distance << " door# dest# distance\n"; Cell<stat_spell_cell*> cll(affected_by); stat_spell_cell* ptr; while ((ptr = cll.next())) { da_file << ptr->stat_spell << " " << ptr->bonus_duration << " "; if (++count > 20) { da_file << endl; count = 0; }//if }//while da_file << -1 << "\tdoor Affected_Bye (end of door)\n"; }//Write() ///****************** Static Functions ***************************/// /* static */ door* door::findDoor(const List<door*> &lst, const int i_th, const String* name, const int see_bit, const room& rm) { int foo = 0; return findDoor(lst, i_th, name, see_bit, rm, foo); } door* door::findDoor(const List<door*> &lst, const int i_th, const String* name, const int see_bit, const room& rm, int& count_sofar) { return door::findDoor(lst, i_th, name, see_bit, rm.getVisBit(), count_sofar); } door* door::findDoor(const List<door*> &lst, const int i_th, const String* name, const int see_bit, const int rm_vis_bit) { int foo = 0; return findDoor(lst, i_th, name, see_bit, rm_vis_bit, foo); } /* static */ door* door::findDoor(const List<door*> &lst, const int i_th, const String* name, const int see_bit, const int rm_vis_bit, int& count_sofar) { Cell<String*> char_cell; Cell<door*> cell(lst); door* door_ptr; int count = 0, ptr_v_bit, len; String *string; if ((len = name->Strlen()) == 0) { //mudlog.log(WRN, "WARNING: len was zero in have_door_named.\n"); return NULL; }//if while ((door_ptr = cell.next())) { ptr_v_bit = (door_ptr->DOOR_VIS_BIT | rm_vis_bit); if (detect(see_bit, ptr_v_bit)) { door_ptr->dr_data->names.head(char_cell); if (door_ptr->destination < 0) { string = char_cell.prev(); if (string) { while (*string != "#") { if (strncasecmp(*string, *name, len) == 0) { count++; count_sofar++; if (count == i_th) { return door_ptr; }//if break; }//if string = char_cell.prev(); }//while } }//if else { while ((string = char_cell.next())) { if (*string == "#") { break; }//if else { if (strncasecmp(*string, *name, name->Strlen()) == 0) { count++; count_sofar++; if (count == i_th) { return door_ptr; }//if break; }//if }//else }//while }//if }//if }//while return NULL; }//haveDoor door* door::findDoorByDest(const List<door*>& lst, int dest_room) { Cell<door*> cll(lst); door* ptr; while ((ptr = cll.next())) { if (abs(ptr->destination) == dest_room) { return ptr; }//if }//while return ptr; } room* door::getDestRoom() { return room_list.elementAtNoCreate(bound(0, NUMBER_OF_ROOMS, abs(destination))); }//getDestRoom String* door::getDirection() { return direction_of_door(*this); } stat_spell_cell* door::isAffectedBy(int spell_num) { Cell<stat_spell_cell*> cll(affected_by); stat_spell_cell* sp; while ((sp = cll.next())) { if (sp->stat_spell == spell_num) { return sp; } }//while return NULL; }