(RoF+) Implemented Armor Ornamentation using Hero's Forge Armor Models. To use, create an ornamentation augment and set the herosforgemodel field in the items table.

(RoF+) Added command #heromodel (#hm for short) - Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)
This commit is contained in:
Trevius
2014-12-13 13:53:55 -06:00
parent 80a67f9ebc
commit 9056008342
22 changed files with 457 additions and 393 deletions
+74 -9
View File
@@ -24,6 +24,7 @@
#include "races.h"
#include "shareddb.h"
#include "classes.h"
#include "rulesys.h"
#include <limits.h>
@@ -1125,10 +1126,12 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
m_trade[slot_id] = inst;
result = slot_id;
}
else {
else
{
// Slot must be within a bag
ItemInst* baginst = GetItem(Inventory::CalcSlotId(slot_id)); // Get parent bag
if (baginst && baginst->IsType(ItemClassContainer)) {
if (baginst && baginst->IsType(ItemClassContainer))
{
baginst->_PutItem(Inventory::CalcBagIdx(slot_id), inst);
result = slot_id;
}
@@ -1414,6 +1417,7 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) {
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
}
ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
@@ -1438,6 +1442,7 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
}
ItemInst::ItemInst(ItemInstTypes use_type) {
@@ -1457,6 +1462,7 @@ ItemInst::ItemInst(ItemInstTypes use_type) {
m_scaling = false;
m_ornamenticon = 0;
m_ornamentidfile = 0;
m_ornament_hero_model = 0;
}
// Make a copy of an ItemInst object
@@ -1509,6 +1515,7 @@ ItemInst::ItemInst(const ItemInst& copy)
m_scaling = copy.m_scaling;
m_ornamenticon = copy.m_ornamenticon;
m_ornamentidfile = copy.m_ornamentidfile;
m_ornament_hero_model = copy.m_ornament_hero_model;
}
// Clean up container contents
@@ -1782,21 +1789,79 @@ ItemInst* ItemInst::GetAugment(uint8 slot) const
return nullptr;
}
ItemInst* ItemInst::GetOrnamentationAug(int ornamentationAugtype) const
ItemInst* ItemInst::GetOrnamentationAug(int32 ornamentationAugtype) const
{
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype) {
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
if (strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0 || strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
continue;
if (ornamentationAugtype > 0)
{
for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++)
{
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
{
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
if (
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
)
{
continue;
}
return this->GetAugment(i);
}
}
}
return nullptr;
}
uint32 ItemInst::GetOrnamentHeroModel(int32 material_slot) const {
uint32 HeroModel = 0;
if (m_ornament_hero_model > 0)
{
HeroModel = m_ornament_hero_model;
if (material_slot >= 0)
{
HeroModel = (m_ornament_hero_model * 100) + material_slot;
}
}
return HeroModel;
}
bool ItemInst::UpdateOrnamentationInfo() {
bool ornamentSet = false;
if (IsType(ItemClassCommon))
{
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const Item_Struct* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
SetOrnamentIcon(ornamentItem->Icon);
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
if (strlen(ornamentItem->IDFile) > 2)
{
SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2]));
}
else
{
SetOrnamentationIDFile(0);
}
ornamentSet = true;
}
}
else
{
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
}
}
return ornamentSet;
}
bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll) {
if (!ItemToTry || !Container) return false;
+9 -5
View File
@@ -329,7 +329,8 @@ public:
void DeleteAugment(uint8 slot);
ItemInst* RemoveAugment(uint8 index);
bool IsAugmented();
ItemInst* GetOrnamentationAug(int ornamentationAugtype) const;
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll = false);
// Has attack/delay?
@@ -393,10 +394,12 @@ public:
void SetActivated(bool activated) { m_activated = activated; }
int8 GetEvolveLvl() const { return m_evolveLvl; }
void SetScaling(bool v) { m_scaling = v; }
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
void Initialize(SharedDatabase *db = nullptr);
void ScaleItem();
@@ -443,6 +446,7 @@ protected:
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_ornament_hero_model;
//
// Items inside of this item (augs or contents);
+20 -8
View File
@@ -3812,8 +3812,8 @@ namespace RoF
Equipment[k].material = emu->equipment[k].material;
Equipment[k].unknown1 = emu->equipment[k].unknown1;
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
Equipment[k].material2 = emu->equipment[k].heroforgemodel;
Equipment[k].elitematerial = emu->equipment[k].material2;
Equipment[k].heroforgemodel = emu->equipment[k].heroforgemodel;
Equipment[k].material2 = emu->equipment[k].material2;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -4847,7 +4847,6 @@ namespace RoF
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff;
hdr.unknown013 = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
//hdr.unknown013 = 0xffff;
hdr.price = inst->GetPrice();
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
//hdr.merchant_slot = (merchant_slot == 0) ? 1 : 0xffffffff;
@@ -4877,6 +4876,8 @@ namespace RoF
}
//ORNAMENT IDFILE / ICON
uint16 ornaIcon = 0;
int32 heroModel = 0;
/*
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
//Mainhand
@@ -4887,8 +4888,16 @@ namespace RoF
ss.write((const char*)&null_term, sizeof(uint8));
//Icon
ornaIcon = aug_weap->Icon;
if (aug_weap->HerosForgeModel > 0)
{
heroModel = (aug_weap->HerosForgeModel * 100) + Inventory::CalcMaterialFromSlot(slot_id_in);
}
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
else
*/
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
{
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand
ss.write(tmp, strlen(tmp));
@@ -4897,10 +4906,12 @@ namespace RoF
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = inst->GetOrnamentationIcon();
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
}
else {
ss.write((const char*)&null_term, sizeof(uint8)); //no mh
ss.write((const char*)&null_term, sizeof(uint8));//no of
else
{
ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
}
RoF::structs::ItemSerializationHeaderFinish hdrf;
@@ -4908,12 +4919,13 @@ namespace RoF
hdrf.unknown061 = 0;
hdrf.unknown062 = 0;
hdrf.unknowna1 = 0xffffffff;
hdrf.unknowna2 = 0;
hdrf.ornamentHeroModel = heroModel;
hdrf.unknown063 = 0;
hdrf.unknowna3 = 0;
hdrf.unknowna4 = 0xffffffff;
hdrf.unknowna5 = 0;
hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0)
+24 -11
View File
@@ -3816,8 +3816,8 @@ namespace RoF2
Equipment[k].material = emu->equipment[k].material;
Equipment[k].unknown1 = emu->equipment[k].unknown1;
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
Equipment[k].material2 = emu->equipment[k].heroforgemodel;
Equipment[k].elitematerial = emu->equipment[k].material2;
Equipment[k].heroforgemodel = emu->equipment[k].heroforgemodel;
Equipment[k].material2 = emu->equipment[k].material2;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -4851,7 +4851,6 @@ namespace RoF2
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff;
hdr.unknown013 = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
//hdr.unknown013 = 0xffff;
hdr.price = inst->GetPrice();
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
//hdr.merchant_slot = (merchant_slot == 0) ? 1 : 0xffffffff;
@@ -4862,8 +4861,8 @@ namespace RoF2
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
hdr.inst_nodrop = inst->IsInstNoDrop() ? 1 : 0;
hdr.unknown044 = 0;
hdr.unknown048 = 0;
hdr.unknown052 = 0;
hdr.unknown048 = 7300 + Inventory::CalcMaterialFromSlot(slot_id_in); //0;
hdr.unknown052 = 7300 + Inventory::CalcMaterialFromSlot(slot_id_in); //0;
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
@@ -4881,7 +4880,10 @@ namespace RoF2
}
//ORNAMENT IDFILE / ICON
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
int32 heroModel = 0;
/*
if (inst->GetOrnamentationAug(ornamentationAugtype))
{
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
//Mainhand
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
@@ -4891,8 +4893,16 @@ namespace RoF2
ss.write((const char*)&null_term, sizeof(uint8));
//Icon
ornaIcon = aug_weap->Icon;
if (aug_weap->HerosForgeModel > 0)
{
heroModel = (aug_weap->HerosForgeModel * 100) + Inventory::CalcMaterialFromSlot(slot_id_in);
}
}
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
else
*/
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
{
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand
ss.write(tmp, strlen(tmp));
@@ -4901,10 +4911,12 @@ namespace RoF2
ss.write(tmp, strlen(tmp));
ss.write((const char*)&null_term, sizeof(uint8));
ornaIcon = inst->GetOrnamentationIcon();
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
}
else {
ss.write((const char*)&null_term, sizeof(uint8)); //no mh
ss.write((const char*)&null_term, sizeof(uint8));//no of
else
{
ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
}
RoF2::structs::ItemSerializationHeaderFinish hdrf;
@@ -4912,12 +4924,13 @@ namespace RoF2
hdrf.unknown061 = 0;
hdrf.unknown062 = 0;
hdrf.unknowna1 = 0xffffffff;
hdrf.unknowna2 = 0;
hdrf.ornamentHeroModel = heroModel;
hdrf.unknown063 = 0;
hdrf.unknowna3 = 0;
hdrf.unknowna4 = 0xffffffff;
hdrf.unknowna5 = 0;
hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0)
+4 -4
View File
@@ -4425,14 +4425,14 @@ struct EvolvingItem {
struct ItemSerializationHeaderFinish
{
uint16 ornamentIcon;
/*079*/ uint16 ornamentIcon;
/*081*/ uint8 unknown061; // 0 - Add Evolving Item struct if this isn't set to 0?
/*082*/ uint8 unknown062; // 0
/*083*/ uint32 unknowna1; // 0xffffffff
/*087*/ uint32 unknowna2; // 0
/*083*/ int32 unknowna1; // 0xffffffff
/*087*/ uint32 ornamentHeroModel; // 0
/*091*/ uint8 unknown063; // 0
/*092*/ uint32 unknowna3; // 0
/*096*/ uint32 unknowna4; // 0xffffffff
/*096*/ int32 unknowna4; // 0xffffffff
/*100*/ uint32 unknowna5; // 0
/*104*/ uint8 ItemClass; //0, 1, or 2
/*105*/
+4 -4
View File
@@ -4422,14 +4422,14 @@ struct EvolvingItem {
struct ItemSerializationHeaderFinish
{
uint16 ornamentIcon;
/*079*/ uint16 ornamentIcon;
/*081*/ uint8 unknown061; // 0 - Add Evolving Item struct if this isn't set to 0?
/*082*/ uint8 unknown062; // 0
/*083*/ uint32 unknowna1; // 0xffffffff
/*087*/ uint32 unknowna2; // 0
/*083*/ int32 unknowna1; // 0xffffffff
/*087*/ uint32 ornamentHeroModel; // 0
/*091*/ uint8 unknown063; // 0
/*092*/ uint32 unknowna3; // 0
/*096*/ uint32 unknowna4; // 0xffffffff
/*096*/ int32 unknowna4; // 0xffffffff
/*100*/ uint32 unknowna5; // 0
/*104*/ uint8 ItemClass; //0, 1, or 2
/*105*/
+23 -33
View File
@@ -199,14 +199,15 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
// Update/Insert item
std::string query = StringFormat("REPLACE INTO inventory "
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
"augslot1, augslot2, augslot3, augslot4, augslot5, ornamenticon, ornamentidfile) "
"augslot1, augslot2, augslot3, augslot4, augslot5, ornamenticon, ornamentidfile, ornament_hero_model) "
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
"%lu, %lu, %lu, %lu, %lu, %lu, %lu)",
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
(unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID,
(unsigned long)charges, (unsigned long)(inst->IsInstNoDrop()? 1: 0),
inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(),
(unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2],
(unsigned long)augslot[3],(unsigned long)augslot[4], (unsigned long)inst->GetOrnamentationIcon(), (unsigned long)inst->GetOrnamentationIDFile());
(unsigned long)augslot[3],(unsigned long)augslot[4], (unsigned long)inst->GetOrnamentationIcon(),
(unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel());
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
@@ -488,7 +489,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
// Retrieve character inventory
std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model "
"FROM inventory WHERE charid = %i ORDER BY slotid", char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -515,6 +516,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
uint32 ornament_icon = (uint32)atoul(row[11]);
uint32 ornament_idfile = (uint32)atoul(row[12]);
uint32 ornament_hero_model = (uint32)atoul(row[13]);
const Item_Struct* item = GetItem(item_id);
@@ -552,11 +554,10 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
value.push_back(v);
}
}
if (ornament_icon > 0)
inst->SetOrnamentIcon(ornament_icon);
if (ornament_idfile > 0)
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
if (instnodrop || (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || slot_id == MainPowerSource) && inst->GetItem()->Attuneable))
inst->SetInstNoDrop(true);
@@ -599,7 +600,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) {
// Retrieve character inventory
std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile "
"augslot2, augslot3, augslot4, augslot5, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model "
"FROM inventory INNER JOIN character_data ch "
"ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid",
name, account_id);
@@ -627,6 +628,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false;
uint32 ornament_icon = (uint32)atoul(row[11]);
uint32 ornament_idfile = (uint32)atoul(row[12]);
uint32 ornament_hero_model = (uint32)atoul(row[13]);
const Item_Struct* item = GetItem(item_id);
int16 put_slot_id = INVALID_INDEX;
@@ -663,11 +665,9 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
}
}
if (ornament_icon > 0)
inst->SetOrnamentIcon(ornament_icon);
if (ornament_idfile > 0)
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
if (color > 0)
inst->SetColor(color);
@@ -854,23 +854,6 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
item.ItemType = (uint8)atoi(row[ItemField::itemtype]);
item.Material = (uint8)atoi(row[ItemField::material]);
item.HerosForgeModel = (uint32)atoi(row[ItemField::herosforgemodel]);
if (item.HerosForgeModel > 0)
{
item.HerosForgeModel *= 100;
uint32 HeroSlot = 0;
switch (item.Slots)
{
case 4: { HeroSlot = 0; break; } // Head
case 131072: { HeroSlot = 1; break; } // Chest
case 128: { HeroSlot = 2; break; } // Arms
case 1536: { HeroSlot = 3; break; } // Bracers
case 4096: { HeroSlot = 4; break; } // Hands
case 262144: { HeroSlot = 5; break; } // Legs
case 524288: { HeroSlot = 6; break; } // Feet
default: { HeroSlot = 1; break; } // Chest
}
item.HerosForgeModel += HeroSlot;
}
item.SellRate = (float)atof(row[ItemField::sellrate]);
item.CastTime = (uint32)atoul(row[ItemField::casttime]);
item.EliteMaterial = (uint32)atoul(row[ItemField::elitematerial]);
@@ -1024,11 +1007,18 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
if(!items_hash || id > items_hash->max_key()) {
if (id == 0)
{
return nullptr;
}
if(items_hash->exists(id)) {
if(!items_hash || id > items_hash->max_key())
{
return nullptr;
}
if(items_hash->exists(id))
{
return &(items_hash->at(id));
}
+1 -1
View File
@@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9060
#define CURRENT_BINARY_DATABASE_VERSION 9061
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32