Add the following functions prototypes to zone.h
public:
int GetZoneObjectStatus(char);
void AddOpenedZoneObject(char, uint32);
void CloseZoneObject(char);
void CheckZoneObjects();
int GetZoneObjects(char *, ZoneObject_Struct*&

;
ZoneObject *GetZoneObject(char);
private:
int numzoneobjects;
LinkedList<ZoneObject*> ZoneObjects;
LinkedList<ZoneObject*> opened_zone_object_list;
And also add the following include to zone.h
#include "zoneobject.h"
Add the following line to the Zone constructor
numzoneobjects=GetZoneObjectsFromDB();
Add the following function definitions to zone.cpp
int Zone::GetZoneObjectsFromDB() {
char *query = 0;
int buf_len = 256;
int chars = -1;
MYSQL_RES *result;
MYSQL_ROW row;
int numzoneobjects;
while (chars == -1 || chars >= buf_len)
{
if (query != 0)
{
delete[] query;
query = 0;
buf_len *= 2;
}
query = new char[buf_len];
chars = snprintf(query, buf_len, "SELECT * FROM zoneobjects WHERE zonename='%s'", short_name);
}
if (!mysql_query(&database.mysql, query))
{
delete[] query;
result = mysql_store_result(&database.mysql);
if (result)
{
numzoneobjects=int(mysql_num_rows(result));
for(int i=0; i< numzoneobjects; i++)
{
row = mysql_fetch_row(result);
ZoneObject *newzoneobject=new ZoneObject;
strcpy(newzoneobject->zoneobjectstruct.name, row[1]);
newzoneobject->zoneobjectstruct.x=atof(row[2]);
newzoneobject->zoneobjectstruct.y=atof(row[3]);
newzoneobject->zoneobjectstruct.z=atof(row[4]);
newzoneobject->zoneobjectstruct.heading=atof(row[5]);
newzoneobject->zoneobjectstruct.unknown1=atof(row[6]);
newzoneobject->zoneobjectstruct.unknown2=atof(row[7]);
newzoneobject->zoneobjectstruct.zoneobject_id=atoi(row[8]);
newzoneobject->zoneobjectstruct.type=atoi(row[9]);
newzoneobject->zoneobjectstruct.initialstate=atoi(row[10]);
newzoneobject->zoneobjectstruct.holdstateforever=atoi(row[11]);
newzoneobject->zoneobjectstruct.unknown3=atof(row[12]);
newzoneobject->zoneobjectstruct.unknown4=atof(row[13]);
newzoneobject->zoneobjectstruct.unknown5=atof(row[14]);
newzoneobject->zoneobjectstruct.unknown6=atof(row[15]);
newzoneobject->item_nr=atoi(row[16]);
newzoneobject->trigger_id=atoi(row[17]);
newzoneobject->opentimer=atoi(row[18]);
ZoneObjects.Append(newzoneobject);
}
cout << numzoneobjects << " Zone Objects Loaded" << endl;
}
mysql_free_result(result);
}
else
{
cerr << "Error in GetZoneObjects query '" << query << "' " << mysql_error(&database.mysql) << endl;
delete[] query;
}
return numzoneobjects;
}
int Zone::GetZoneObjects(ZoneObject_Struct* &zos)
{
LinkedListIterator<ZoneObject*> iterator(ZoneObjects);
zos = new ZoneObject_Struct[numzoneobjects];
int i=0;
iterator.Reset();
while (iterator.MoreElements())
{
zos[i]=iterator.GetData()->zoneobjectstruct;
iterator.Advance();
i++;
}
return numzoneobjects;
}
int Zone::GetZoneObjectStatus(char zoneobject_id) // Is it open?
{
LinkedListIterator<ZoneObject*> iterator(opened_zone_object_list);
iterator.Reset();
while (iterator.MoreElements())
{
if(iterator.GetData()->GetZoneObjectID()==zoneobject_id)
return 1;
iterator.Advance();
}
return 0;
}
void Zone::CheckZoneObjects() // If timer has run out, close it
{
LinkedListIterator<ZoneObject*> iterator(opened_zone_object_list);
iterator.Reset();
while (iterator.MoreElements())
{
if(iterator.GetData()->timer->Check())
{
ZoneObject *pzo;
pzo=GetZoneObject(iterator.GetData()->GetZoneObjectID());
if(!pzo->zoneobjectstruct.holdstateforever)
pzo->zoneobjectstruct.initialstate=0;
iterator.RemoveCurrent();
}
iterator.Advance();
}
}
ZoneObject *Zone::GetZoneObject(char zoneobject_id)
{
LinkedListIterator<ZoneObject*> iterator(ZoneObjects);
iterator.Reset();
while (iterator.MoreElements())
{
if(iterator.GetData()->GetZoneObjectID()==zoneobject_id)
return iterator.GetData();
iterator.Advance();
}
return 0;
}
void Zone::AddOpenedZoneObject(char zoneobject_id, uint32 opentimer)
{
ZoneObject *newzoneobject=new ZoneObject;
newzoneobject->SetZoneObjectID(zoneobject_id);
newzoneobject->timer=new Timer(opentimer);
opened_zone_object_list.Append(newzoneobject);
}
void Zone::CloseZoneObject(char zoneobject_id)
{
LinkedListIterator<ZoneObject*> iterator(opened_zone_object_list);
iterator.Reset();
while (iterator.MoreElements())
{
if(iterator.GetData()->GetZoneObjectID()==zoneobject_id)
{
iterator.RemoveCurrent();
return;
}
iterator.Advance();
}
}
Add the Following 2 lines to eq_opcodes.h
#define OP_ZoneObjectOpenRequest 0x8d20
#define OP_ZoneObjectOpen 0x8e20
Add the Following structs to eq_packet_structs.h
struct ZoneObject_Struct
{
char name[16]; // Filename of object? Determines what the object looks like
float x;
float y;
float z;
float heading;
float unknown1;
float unknown2;
char zoneobject_id; // uniquely identifies the object within the zone
char type; // determines animation (can do cool things with this)
char initialstate; // is it initially open,spinniing etc.
char holdstateforever; // stay open forever, or return to "closed" after 11 seconds
char unknown3;
char unknown4;
char unknown5;
char unknown6;
};
struct CompressedZoneObject_Struct
{
uint16 count; // number of objects
struct ZoneObject_Struct *zoneobjects;
};
struct ZoneObjectOpen_Struct
{
char zoneobject_id; // id within the zone of the door
char action; // 01
char placeholder[2];
uint16 item_nr; // unique item number player is holding(key)
char placeholder2[2];
char unknown[2];
char placeholder3[2];
};