mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-03 17:46:36 +00:00
Merge branch 'master' into web_interface
This commit is contained in:
@@ -63,6 +63,7 @@ public:
|
||||
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
|
||||
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
|
||||
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
|
||||
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
|
||||
|
||||
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
|
||||
uint8 ReadUInt8(uint32 Offset) const { uint8 value = *(uint8 *)(pBuffer + Offset); return value; }
|
||||
|
||||
+88
-12
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CLIENTVERSIONS_H
|
||||
#define CLIENTVERSIONS_H
|
||||
|
||||
@@ -46,32 +67,87 @@ static const char* ClientVersionName(ClientVersion version)
|
||||
switch (version)
|
||||
{
|
||||
case ClientVersion::Unknown:
|
||||
return "ClientVersion::Unknown";
|
||||
return "Unknown";
|
||||
case ClientVersion::Client62:
|
||||
return "ClientVersion::Client62";
|
||||
return "Client62";
|
||||
case ClientVersion::Titanium:
|
||||
return "ClientVersion::Titanium";
|
||||
return "Titanium";
|
||||
case ClientVersion::SoF:
|
||||
return "ClientVersion::SoF";
|
||||
return "SoF";
|
||||
case ClientVersion::SoD:
|
||||
return "ClientVersion::SoD";
|
||||
return "SoD";
|
||||
case ClientVersion::UF:
|
||||
return "ClientVersion::UF";
|
||||
return "UF";
|
||||
case ClientVersion::RoF:
|
||||
return "ClientVersion::RoF";
|
||||
return "RoF";
|
||||
case ClientVersion::RoF2:
|
||||
return "ClientVersion::RoF2";
|
||||
return "RoF2";
|
||||
case ClientVersion::MobNPC:
|
||||
return "ClientVersion::MobNPC";
|
||||
return "MobNPC";
|
||||
case ClientVersion::MobMerc:
|
||||
return "ClientVersion::MobMerc";
|
||||
return "MobMerc";
|
||||
case ClientVersion::MobBot:
|
||||
return "ClientVersion::MobBot";
|
||||
return "MobBot";
|
||||
case ClientVersion::MobPet:
|
||||
return "ClientVersion::MobPet";
|
||||
return "MobPet";
|
||||
default:
|
||||
return "<ERROR> Invalid ClientVersion";
|
||||
};
|
||||
}
|
||||
|
||||
static uint32 ClientBitFromVersion(ClientVersion clientVersion)
|
||||
{
|
||||
switch (clientVersion)
|
||||
{
|
||||
case ClientVersion::Unknown:
|
||||
case ClientVersion::Client62:
|
||||
return 0;
|
||||
case ClientVersion::Titanium:
|
||||
case ClientVersion::SoF:
|
||||
case ClientVersion::SoD:
|
||||
case ClientVersion::UF:
|
||||
case ClientVersion::RoF:
|
||||
case ClientVersion::RoF2:
|
||||
case ClientVersion::MobNPC:
|
||||
case ClientVersion::MobMerc:
|
||||
case ClientVersion::MobBot:
|
||||
case ClientVersion::MobPet:
|
||||
return ((uint32)1 << (static_cast<unsigned int>(clientVersion) - 1));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static ClientVersion ClientVersionFromBit(uint32 clientVersionBit)
|
||||
{
|
||||
switch (clientVersionBit)
|
||||
{
|
||||
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown):
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)):
|
||||
return ClientVersion::Unknown;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)):
|
||||
return ClientVersion::Titanium;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)):
|
||||
return ClientVersion::SoF;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoD) - 1)):
|
||||
return ClientVersion::SoD;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::UF) - 1)):
|
||||
return ClientVersion::UF;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF) - 1)):
|
||||
return ClientVersion::RoF;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)):
|
||||
return ClientVersion::RoF2;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobNPC) - 1)):
|
||||
return ClientVersion::MobNPC;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobMerc) - 1)):
|
||||
return ClientVersion::MobMerc;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobBot) - 1)):
|
||||
return ClientVersion::MobBot;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobPet) - 1)):
|
||||
return ClientVersion::MobPet;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CLIENTVERSIONS_H */
|
||||
|
||||
+2
-2
@@ -1984,7 +1984,7 @@ void Database::GetRaidLeadershipInfo(uint32 rid, char *maintank,
|
||||
|
||||
void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid)
|
||||
{
|
||||
std::string query = StringFormat("UPDATE raid_leaders SET leadershipaa = '', WHERE gid = %lu AND rid = %lu",
|
||||
std::string query = StringFormat("UPDATE raid_leaders SET leadershipaa = '' WHERE gid = %lu AND rid = %lu",
|
||||
(unsigned long)gid, (unsigned long)rid);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
@@ -2172,4 +2172,4 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings)
|
||||
Log.file_logs_enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,18 +157,29 @@ namespace Convert {
|
||||
/*84*/ uint32 Points;
|
||||
/*88*/
|
||||
} PVPStatsEntry_Struct;
|
||||
|
||||
static const size_t BANDOLIERS_SIZE = 4;
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4;
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
|
||||
char Name[32];
|
||||
Convert::BandolierItem_Struct Items[Convert::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 4;
|
||||
struct PotionBeltItem_Struct {
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
|
||||
Convert::PotionBeltItem_Struct Items[Convert::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct SuspendedMinion_Struct
|
||||
{
|
||||
/*000*/ uint16 SpellID;
|
||||
@@ -346,7 +357,7 @@ namespace Convert {
|
||||
/*12800*/ uint32 expAA;
|
||||
/*12804*/ uint32 aapoints; //avaliable, unspent
|
||||
/*12808*/ uint8 unknown12844[36];
|
||||
/*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
|
||||
/*12844*/ Convert::Bandolier_Struct bandoliers[Convert::BANDOLIERS_SIZE];
|
||||
/*14124*/ uint8 unknown14160[4506];
|
||||
/*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use
|
||||
/*19240*/ uint32 timeentitledonaccount;
|
||||
@@ -1430,15 +1441,15 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Bandolier Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){
|
||||
if (strlen(pp->bandoliers[i].name) < 32) {
|
||||
for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){
|
||||
if (pp->bandoliers[i].items[si].item_id > 0){
|
||||
for (i = 0; i < Convert::BANDOLIERS_SIZE; i++){
|
||||
if (strlen(pp->bandoliers[i].Name) < 32) {
|
||||
for (int si = 0; si < Convert::BANDOLIER_ITEM_COUNT; si++){
|
||||
if (pp->bandoliers[i].Items[si].ID > 0){
|
||||
if (first_entry != 1) {
|
||||
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
|
||||
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
|
||||
first_entry = 1;
|
||||
}
|
||||
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
|
||||
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1446,13 +1457,13 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Potion Belt Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){
|
||||
if (pp->potionbelt.items[i].item_id > 0){
|
||||
for (i = 0; i < Convert::POTION_BELT_ITEM_COUNT; i++){
|
||||
if (pp->potionbelt.Items[i].ID > 0){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
|
||||
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
|
||||
first_entry = 1;
|
||||
}
|
||||
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
|
||||
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+48
-1
@@ -21,6 +21,53 @@
|
||||
#include "skills.h"
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
** Light Types
|
||||
**
|
||||
*/
|
||||
enum LightTypes
|
||||
{
|
||||
lightTypeNone = 0,
|
||||
lightTypeCandle,
|
||||
lightTypeTorch,
|
||||
lightTypeTinyGlowingSkull,
|
||||
lightTypeSmallLantern,
|
||||
lightTypeSteinOfMoggok,
|
||||
lightTypeLargeLantern,
|
||||
lightTypeFlamelessLantern,
|
||||
lightTypeGlobeOfStars,
|
||||
lightTypeLightGlobe,
|
||||
lightTypeLightstone,
|
||||
lightTypeGreaterLightstone,
|
||||
lightTypeFireBeetleEye,
|
||||
lightTypeColdlight,
|
||||
lightTypeUnknown1,
|
||||
lightTypeUnknown2
|
||||
};
|
||||
|
||||
#define LIGHT_TYPES_COUNT 16
|
||||
|
||||
/*
|
||||
** Light Levels
|
||||
**
|
||||
*/
|
||||
enum LightLevels
|
||||
{
|
||||
lightLevelUnlit = 0,
|
||||
lightLevelCandle,
|
||||
lightLevelTorch,
|
||||
lightLevelSmallMagic,
|
||||
lightLevelRedLight,
|
||||
lightLevelBlueLight,
|
||||
lightLevelSmallLantern,
|
||||
lightLevelMagicLantern,
|
||||
lightLevelLargeLantern,
|
||||
lightLevelLargeMagic,
|
||||
lightLevelBrilliant
|
||||
};
|
||||
|
||||
#define LIGHT_LEVELS_COUNT 11
|
||||
|
||||
/*
|
||||
** Item attributes
|
||||
**
|
||||
@@ -55,7 +102,7 @@ enum ItemClassTypes
|
||||
**
|
||||
** (ref: database and eqstr_us.txt)
|
||||
**
|
||||
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013] -U)
|
||||
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013])
|
||||
*/
|
||||
enum ItemUseTypes : uint8
|
||||
{
|
||||
|
||||
+102
-115
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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
|
||||
@@ -25,8 +25,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// class EmuConstants
|
||||
//
|
||||
uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
|
||||
switch (indexMap) {
|
||||
uint16 EmuConstants::InventoryMapSize(int16 indexMap)
|
||||
{
|
||||
switch (indexMap)
|
||||
{
|
||||
case MapPossessions:
|
||||
return MAP_POSSESSIONS_SIZE;
|
||||
case MapBank:
|
||||
@@ -83,7 +85,8 @@ uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
|
||||
}
|
||||
|
||||
/*
|
||||
std::string EmuConstants::InventoryLocationName(Location_Struct location) {
|
||||
std::string EmuConstants::InventoryLocationName(Location_Struct location)
|
||||
{
|
||||
// not ready for implementation...
|
||||
std::string ret_str;
|
||||
StringFormat(ret_str, "%s, %s, %s, %s", InventoryMapName(location.map), InventoryMainName(location.main), InventorySubName(location.sub), InventoryAugName(location.aug));
|
||||
@@ -91,8 +94,10 @@ std::string EmuConstants::InventoryLocationName(Location_Struct location) {
|
||||
}
|
||||
*/
|
||||
|
||||
std::string EmuConstants::InventoryMapName(int16 indexMap) {
|
||||
switch (indexMap) {
|
||||
std::string EmuConstants::InventoryMapName(int16 indexMap)
|
||||
{
|
||||
switch (indexMap)
|
||||
{
|
||||
case INVALID_INDEX:
|
||||
return "Invalid Map";
|
||||
case MapPossessions:
|
||||
@@ -100,7 +105,7 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
|
||||
case MapBank:
|
||||
return "Bank";
|
||||
case MapSharedBank:
|
||||
return "Shared Bank";
|
||||
return "SharedBank";
|
||||
case MapTrade:
|
||||
return "Trade";
|
||||
case MapWorld:
|
||||
@@ -110,9 +115,9 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
|
||||
case MapTribute:
|
||||
return "Tribute";
|
||||
case MapTrophyTribute:
|
||||
return "Trophy Tribute";
|
||||
return "TrophyTribute";
|
||||
case MapGuildTribute:
|
||||
return "Guild Tribute";
|
||||
return "GuildTribute";
|
||||
case MapMerchant:
|
||||
return "Merchant";
|
||||
case MapDeleted:
|
||||
@@ -124,23 +129,23 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
|
||||
case MapInspect:
|
||||
return "Inspect";
|
||||
case MapRealEstate:
|
||||
return "Real Estate";
|
||||
return "RealEstate";
|
||||
case MapViewMODPC:
|
||||
return "View MOD PC";
|
||||
return "ViewMODPC";
|
||||
case MapViewMODBank:
|
||||
return "View MOD Bank";
|
||||
return "ViewMODBank";
|
||||
case MapViewMODSharedBank:
|
||||
return "View MOD Shared Bank";
|
||||
return "ViewMODSharedBank";
|
||||
case MapViewMODLimbo:
|
||||
return "View MOD Limbo";
|
||||
return "ViewMODLimbo";
|
||||
case MapAltStorage:
|
||||
return "Alt Storage";
|
||||
return "AltStorage";
|
||||
case MapArchived:
|
||||
return "Archived";
|
||||
case MapMail:
|
||||
return "Mail";
|
||||
case MapGuildTrophyTribute:
|
||||
return "Guild Trophy Tribute";
|
||||
return "GuildTrophyTribute";
|
||||
case MapKrono:
|
||||
return "Krono";
|
||||
case MapOther:
|
||||
@@ -150,20 +155,22 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string EmuConstants::InventoryMainName(int16 indexMain) {
|
||||
switch (indexMain) {
|
||||
std::string EmuConstants::InventoryMainName(int16 indexMain)
|
||||
{
|
||||
switch (indexMain)
|
||||
{
|
||||
case INVALID_INDEX:
|
||||
return "Invalid Main";
|
||||
case MainCharm:
|
||||
return "Charm";
|
||||
case MainEar1:
|
||||
return "Ear 1";
|
||||
return "Ear1";
|
||||
case MainHead:
|
||||
return "Head";
|
||||
case MainFace:
|
||||
return "Face";
|
||||
case MainEar2:
|
||||
return "Ear 2";
|
||||
return "Ear2";
|
||||
case MainNeck:
|
||||
return "Neck";
|
||||
case MainShoulders:
|
||||
@@ -173,9 +180,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
|
||||
case MainBack:
|
||||
return "Back";
|
||||
case MainWrist1:
|
||||
return "Wrist 1";
|
||||
return "Wrist1";
|
||||
case MainWrist2:
|
||||
return "Wrist 2";
|
||||
return "Wrist2";
|
||||
case MainRange:
|
||||
return "Range";
|
||||
case MainHands:
|
||||
@@ -185,9 +192,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
|
||||
case MainSecondary:
|
||||
return "Secondary";
|
||||
case MainFinger1:
|
||||
return "Finger 1";
|
||||
return "Finger1";
|
||||
case MainFinger2:
|
||||
return "Finger 2";
|
||||
return "Finger2";
|
||||
case MainChest:
|
||||
return "Chest";
|
||||
case MainLegs:
|
||||
@@ -197,30 +204,30 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
|
||||
case MainWaist:
|
||||
return "Waist";
|
||||
case MainPowerSource:
|
||||
return "Power Source";
|
||||
return "PowerSource";
|
||||
case MainAmmo:
|
||||
return "Ammo";
|
||||
case MainGeneral1:
|
||||
return "General 1";
|
||||
return "General1";
|
||||
case MainGeneral2:
|
||||
return "General 2";
|
||||
return "General2";
|
||||
case MainGeneral3:
|
||||
return "General 3";
|
||||
return "General3";
|
||||
case MainGeneral4:
|
||||
return "General 4";
|
||||
return "General4";
|
||||
case MainGeneral5:
|
||||
return "General 5";
|
||||
return "General5";
|
||||
case MainGeneral6:
|
||||
return "General 6";
|
||||
return "General6";
|
||||
case MainGeneral7:
|
||||
return "General 7";
|
||||
return "General7";
|
||||
case MainGeneral8:
|
||||
return "General 8";
|
||||
return "General8";
|
||||
/*
|
||||
case MainGeneral9:
|
||||
return "General 9";
|
||||
return "General9";
|
||||
case MainGeneral10:
|
||||
return "General 10";
|
||||
return "General10";
|
||||
*/
|
||||
case MainCursor:
|
||||
return "Cursor";
|
||||
@@ -229,7 +236,8 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string EmuConstants::InventorySubName(int16 indexSub) {
|
||||
std::string EmuConstants::InventorySubName(int16 indexSub)
|
||||
{
|
||||
if (indexSub == INVALID_INDEX)
|
||||
return "Invalid Sub";
|
||||
|
||||
@@ -237,12 +245,13 @@ std::string EmuConstants::InventorySubName(int16 indexSub) {
|
||||
return "Unknown Sub";
|
||||
|
||||
std::string ret_str;
|
||||
ret_str = StringFormat("Container %i", (indexSub + 1)); // zero-based index..but, count starts at one
|
||||
ret_str = StringFormat("Container%i", (indexSub + 1)); // zero-based index..but, count starts at one
|
||||
|
||||
return ret_str;
|
||||
}
|
||||
|
||||
std::string EmuConstants::InventoryAugName(int16 indexAug) {
|
||||
std::string EmuConstants::InventoryAugName(int16 indexAug)
|
||||
{
|
||||
if (indexAug == INVALID_INDEX)
|
||||
return "Invalid Aug";
|
||||
|
||||
@@ -250,7 +259,7 @@ std::string EmuConstants::InventoryAugName(int16 indexAug) {
|
||||
return "Unknown Aug";
|
||||
|
||||
std::string ret_str;
|
||||
ret_str = StringFormat("Augment %i", (indexAug + 1)); // zero-based index..but, count starts at one
|
||||
ret_str = StringFormat("Augment%i", (indexAug + 1)); // zero-based index..but, count starts at one
|
||||
|
||||
return ret_str;
|
||||
}
|
||||
@@ -260,14 +269,16 @@ std::string EmuConstants::InventoryAugName(int16 indexAug) {
|
||||
// class EQLimits
|
||||
//
|
||||
// client validation
|
||||
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) {
|
||||
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
|
||||
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
|
||||
return clientVersion;
|
||||
|
||||
@@ -275,14 +286,16 @@ ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
|
||||
}
|
||||
|
||||
// npc validation
|
||||
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) {
|
||||
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
|
||||
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
|
||||
return clientVersion;
|
||||
|
||||
@@ -290,22 +303,47 @@ ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
|
||||
}
|
||||
|
||||
// mob validation
|
||||
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) {
|
||||
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) {
|
||||
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion)
|
||||
{
|
||||
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
|
||||
return clientVersion;
|
||||
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
|
||||
// database
|
||||
size_t EQLimits::CharacterCreationLimit(ClientVersion clientVersion)
|
||||
{
|
||||
static const size_t local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*Client62*/ NOT_USED,
|
||||
/*Titanium*/ Titanium::consts::CHARACTER_CREATION_LIMIT,
|
||||
/*SoF*/ SoF::consts::CHARACTER_CREATION_LIMIT,
|
||||
/*SoD*/ SoD::consts::CHARACTER_CREATION_LIMIT,
|
||||
/*UF*/ UF::consts::CHARACTER_CREATION_LIMIT,
|
||||
/*RoF*/ RoF::consts::CHARACTER_CREATION_LIMIT,
|
||||
/*RoF2*/ RoF2::consts::CHARACTER_CREATION_LIMIT,
|
||||
|
||||
/*MobNPC*/ NOT_USED,
|
||||
/*MobMerc*/ NOT_USED,
|
||||
/*MobBot*/ NOT_USED,
|
||||
/*MobPet*/ NOT_USED
|
||||
};
|
||||
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
// inventory
|
||||
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
|
||||
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion)
|
||||
{
|
||||
// not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...)
|
||||
// a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified
|
||||
// ALL of these values need to be verified before pushing to live
|
||||
@@ -704,7 +742,8 @@ uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
|
||||
return NOT_USED;
|
||||
}
|
||||
|
||||
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
|
||||
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion)
|
||||
{
|
||||
// these are for the new inventory system (RoF)..not the current (Ti) one...
|
||||
// 0x0000000000200000 is SlotPowerSource (SoF+)
|
||||
// 0x0000000080000000 is SlotGeneral9 (RoF+)
|
||||
@@ -730,7 +769,8 @@ uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
|
||||
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
|
||||
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion)
|
||||
{
|
||||
static const uint64 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ 0x00000000005FFFFF,
|
||||
@@ -751,7 +791,8 @@ uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
|
||||
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
|
||||
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion)
|
||||
{
|
||||
static const uint64 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ 0x000000007F800000,
|
||||
@@ -772,7 +813,8 @@ uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
|
||||
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
|
||||
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion)
|
||||
{
|
||||
static const uint64 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ 0x0000000200000000,
|
||||
@@ -793,7 +835,8 @@ uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
|
||||
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
|
||||
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion)
|
||||
{
|
||||
static const bool local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ false,
|
||||
/*62*/ false,
|
||||
@@ -814,7 +857,8 @@ bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
|
||||
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
|
||||
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion)
|
||||
{
|
||||
static const bool local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ false,
|
||||
/*62*/ false,
|
||||
@@ -835,7 +879,8 @@ bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
|
||||
}
|
||||
|
||||
// items
|
||||
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
|
||||
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion)
|
||||
{
|
||||
static const uint16 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ EmuConstants::ITEM_COMMON_SIZE,
|
||||
@@ -855,7 +900,8 @@ uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
|
||||
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion)
|
||||
{
|
||||
static const uint16 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ EmuConstants::ITEM_CONTAINER_SIZE,
|
||||
@@ -875,7 +921,8 @@ uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
|
||||
bool EQLimits::CoinHasWeight(ClientVersion clientVersion)
|
||||
{
|
||||
static const bool local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ true,
|
||||
/*62*/ true,
|
||||
@@ -894,63 +941,3 @@ bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
|
||||
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint32 EQLimits::BandoliersCount(ClientVersion clientVersion) {
|
||||
static const uint32 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*Titanium*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*SoF*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*SoD*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*Underfoot*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*RoF*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
/*RoF2*/ EmuConstants::BANDOLIERS_COUNT,
|
||||
|
||||
/*NPC*/ NOT_USED,
|
||||
/*Merc*/ NOT_USED,
|
||||
/*Bot*/ NOT_USED,
|
||||
/*Pet*/ NOT_USED
|
||||
};
|
||||
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint32 EQLimits::BandolierSize(ClientVersion clientVersion) {
|
||||
static const uint32 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*Titanium*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*SoF*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*SoD*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*Underfoot*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*RoF*/ EmuConstants::BANDOLIER_SIZE,
|
||||
/*RoF2*/ EmuConstants::BANDOLIER_SIZE,
|
||||
|
||||
/*NPC*/ NOT_USED,
|
||||
/*Merc*/ NOT_USED,
|
||||
/*Bot*/ NOT_USED,
|
||||
/*Pet*/ NOT_USED
|
||||
};
|
||||
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
uint32 EQLimits::PotionBeltSize(ClientVersion clientVersion) {
|
||||
static const uint32 local[CLIENT_VERSION_COUNT] = {
|
||||
/*Unknown*/ NOT_USED,
|
||||
/*62*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*Titanium*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*SoF*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*SoD*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*Underfoot*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*RoF*/ EmuConstants::POTION_BELT_SIZE,
|
||||
/*RoF2*/ EmuConstants::POTION_BELT_SIZE,
|
||||
|
||||
/*NPC*/ NOT_USED,
|
||||
/*Merc*/ NOT_USED,
|
||||
/*Bot*/ NOT_USED,
|
||||
/*Pet*/ NOT_USED
|
||||
};
|
||||
|
||||
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
|
||||
}
|
||||
|
||||
+16
-20
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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
|
||||
@@ -42,12 +42,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//using namespace RoF2::maps; // server inventory maps enumeration (code and database sync'd to reference)
|
||||
//using namespace RoF::slots; // server possessions slots enumeration (code and database sync'd to reference)
|
||||
|
||||
class EmuConstants {
|
||||
class EmuConstants
|
||||
{
|
||||
// an immutable value is required to initialize arrays, etc... use this class as a repository for those
|
||||
public:
|
||||
// database
|
||||
static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client
|
||||
|
||||
static const size_t CHARACTER_CREATION_LIMIT = RoF2::consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
// inventory
|
||||
static uint16 InventoryMapSize(int16 indexMap);
|
||||
//static std::string InventoryLocationName(Location_Struct location);
|
||||
@@ -140,23 +143,18 @@ public:
|
||||
static const uint16 ITEM_COMMON_SIZE = RoF::consts::ITEM_COMMON_SIZE;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = Titanium::consts::ITEM_CONTAINER_SIZE;
|
||||
|
||||
// player profile
|
||||
//static const uint32 CLASS_BITMASK = 0; // needs value
|
||||
//static const uint32 RACE_BITMASK = 0; // needs value
|
||||
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t BANDOLIERS_SIZE = RoF2::consts::BANDOLIERS_SIZE; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = RoF2::consts::BANDOLIER_ITEM_COUNT; // number of equipment slots in bandolier instance
|
||||
|
||||
// BANDOLIERS_COUNT sets maximum limit..active limit will need to be handled by the appropriate AA
|
||||
static const uint32 BANDOLIERS_COUNT = Titanium::consts::BANDOLIERS_COUNT; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
|
||||
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t POTION_BELT_ITEM_COUNT = RoF2::consts::POTION_BELT_ITEM_COUNT;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
|
||||
// legacy-related functions
|
||||
//static int ServerToPerlSlot(int slot); // encode
|
||||
//static int PerlToServerSlot(int slot); // decode
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = RoF2::consts::TEXT_LINK_BODY_LENGTH;
|
||||
};
|
||||
|
||||
class EQLimits {
|
||||
class EQLimits
|
||||
{
|
||||
// values should default to a non-beneficial value..unless value conflicts with intended operation
|
||||
//
|
||||
// EmuConstants may be used as references..but, not every reference needs to be in EmuConstants (i.e., AllowsEmptyBagInBag(), CoinHasWeight(), etc...)
|
||||
@@ -174,6 +172,9 @@ public:
|
||||
static bool IsValidMobClientVersion(ClientVersion clientVersion);
|
||||
static ClientVersion ValidateMobClientVersion(ClientVersion clientVersion);
|
||||
|
||||
// database
|
||||
static size_t CharacterCreationLimit(ClientVersion clientVersion);
|
||||
|
||||
// inventory
|
||||
static uint16 InventoryMapSize(int16 indexMap, ClientVersion clientVersion);
|
||||
static uint64 PossessionsBitmask(ClientVersion clientVersion);
|
||||
@@ -190,11 +191,6 @@ public:
|
||||
|
||||
// player profile
|
||||
static bool CoinHasWeight(ClientVersion clientVersion);
|
||||
|
||||
static uint32 BandoliersCount(ClientVersion clientVersion);
|
||||
static uint32 BandolierSize(ClientVersion clientVersion);
|
||||
|
||||
static uint32 PotionBeltSize(ClientVersion clientVersion);
|
||||
};
|
||||
|
||||
#endif /* EQ_DICTIONARY_H */
|
||||
|
||||
+141
-124
@@ -15,6 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef EQ_PACKET_STRUCTS_H
|
||||
#define EQ_PACKET_STRUCTS_H
|
||||
|
||||
@@ -123,83 +124,81 @@ struct LDoNTrapTemplate
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
** Color_Struct
|
||||
** Size: 4 bytes
|
||||
** Used for convenience
|
||||
** Merth: Gave struct a name so gcc 2.96 would compile
|
||||
**
|
||||
*/
|
||||
// All clients translate the character select information to some degree
|
||||
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
/*12*/ uint32 heroforgemodel;
|
||||
/*16*/ uint32 material2; // Same as material?
|
||||
/*20*/
|
||||
struct EquipStruct
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
uint32 HeroForgeModel;
|
||||
uint32 Material2; // Same as material?
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
uint32 heroforgemodel;
|
||||
uint32 material2;
|
||||
Color_Struct color;
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
uint32 HeroForgeModel;
|
||||
uint32 Material2;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
/*
|
||||
** Character Selection Struct
|
||||
** Length: 1704 Bytes
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*0000*/ uint32 race[10]; // Characters Race
|
||||
/*0040*/ //Color_Struct cs_colors[10][9]; // Characters Equipment Colors
|
||||
/*0400*/ uint8 beardcolor[10]; // Characters beard Color
|
||||
/*0410*/ uint8 hairstyle[10]; // Characters hair style
|
||||
/*0420*/ //uint32 equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
|
||||
/*0000*/ CharSelectEquip equip[10][9];
|
||||
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
|
||||
/*0820*/ uint32 drakkin_heritage[10]; // added for SoF
|
||||
/*0860*/ uint32 drakkin_tattoo[10]; // added for SoF
|
||||
/*0900*/ uint32 drakkin_details[10]; // added for SoF
|
||||
/*0940*/ uint32 deity[10]; // Characters Deity
|
||||
/*0980*/ uint8 gohome[10]; // 1=Go Home available, 0=not
|
||||
/*0990*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
|
||||
/*1000*/ uint8 beard[10]; // Characters Beard Type
|
||||
/*1010*/ uint8 unknown902[10]; // 10x ff
|
||||
/*1020*/ uint32 primary[10]; // Characters primary IDFile number
|
||||
/*1060*/ uint8 haircolor[10]; // Characters Hair Color
|
||||
/*1070*/ uint8 unknown0962[2]; // 2x 00
|
||||
/*1072*/ uint32 zone[10]; // Characters Current Zone
|
||||
/*1112*/ uint8 class_[10]; // Characters Classes
|
||||
/*1022*/ uint8 face[10]; // Characters Face Type
|
||||
/*1032*/ char name[10][64]; // Characters Names
|
||||
/*1672*/ uint8 gender[10]; // Characters Gender
|
||||
/*1682*/ uint8 eyecolor1[10]; // Characters Eye Color
|
||||
/*1692*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
|
||||
/*1702*/ uint8 level[10]; // Characters Levels
|
||||
/*1712*/
|
||||
// RoF2-based hybrid struct
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
char Name[64];
|
||||
uint8 Class;
|
||||
uint32 Race;
|
||||
uint8 Level;
|
||||
uint8 ShroudClass;
|
||||
uint32 ShroudRace;
|
||||
uint16 Zone;
|
||||
uint16 Instance;
|
||||
uint8 Gender;
|
||||
uint8 Face;
|
||||
CharSelectEquip Equip[9];
|
||||
uint8 Unknown15; // Seen FF
|
||||
uint8 Unknown19; // Seen FF
|
||||
uint32 DrakkinTattoo;
|
||||
uint32 DrakkinDetails;
|
||||
uint32 Deity;
|
||||
uint32 PrimaryIDFile;
|
||||
uint32 SecondaryIDFile;
|
||||
uint8 HairColor;
|
||||
uint8 BeardColor;
|
||||
uint8 EyeColor1;
|
||||
uint8 EyeColor2;
|
||||
uint8 HairStyle;
|
||||
uint8 Beard;
|
||||
uint8 GoHome; // Seen 0 for new char and 1 for existing
|
||||
uint8 Tutorial; // Seen 1 for new char or 0 for existing
|
||||
uint32 DrakkinHeritage;
|
||||
uint8 Unknown1; // Seen 0
|
||||
uint8 Enabled; // Originally labeled as 'CharEnabled' - unknown purpose and setting
|
||||
uint32 LastLogin;
|
||||
uint8 Unknown2; // Seen 0
|
||||
};
|
||||
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
uint32 CharCount; //number of chars in this packet
|
||||
uint32 TotalChars; //total number of chars allowed?
|
||||
CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -756,29 +755,46 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct MovePotionToBelt_Struct {
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[EmuConstants::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[EmuConstants::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct MovePotionToBelt_Struct
|
||||
{
|
||||
uint32 Action;
|
||||
uint32 SlotNumber;
|
||||
uint32 ItemID;
|
||||
@@ -1103,7 +1119,7 @@ struct PlayerProfile_Struct
|
||||
/*12800*/ uint32 expAA;
|
||||
/*12804*/ uint32 aapoints; //avaliable, unspent
|
||||
/*12808*/ uint8 unknown12844[36];
|
||||
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
|
||||
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_SIZE];
|
||||
/*14124*/ uint8 unknown14160[4506];
|
||||
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
|
||||
/*19240*/ uint32 timeentitledonaccount;
|
||||
@@ -1249,7 +1265,7 @@ struct ZoneChange_Struct {
|
||||
|
||||
// Whatever you send to the client in RequestClientZoneChange_Struct.type, the client will send back
|
||||
// to the server in ZoneChange_Struct.zone_reason. My guess is this is a memo field of sorts.
|
||||
// WildcardX 27 January 2008
|
||||
// 27 January 2008
|
||||
|
||||
struct RequestClientZoneChange_Struct {
|
||||
/*00*/ uint16 zone_id;
|
||||
@@ -2405,11 +2421,11 @@ struct InspectResponse_Struct {
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ char itemnames[23][64];
|
||||
/*1480*/uint32 itemicons[23];
|
||||
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess) -U
|
||||
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess)
|
||||
/*1860*/
|
||||
};
|
||||
|
||||
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed) -U
|
||||
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed)
|
||||
struct InspectMessage_Struct {
|
||||
/*000*/ char text[256];
|
||||
/*256*/
|
||||
@@ -2518,7 +2534,7 @@ struct BookRequest_Struct {
|
||||
**
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ uint16 unknown008; //
|
||||
/*10*/ uint16 unknown010; //
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
@@ -2537,8 +2553,8 @@ struct Object_Struct {
|
||||
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*92*/
|
||||
};
|
||||
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
// 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
|
||||
/*
|
||||
** Click Object Struct
|
||||
@@ -2595,7 +2611,7 @@ struct CloseContainer_Struct {
|
||||
*/
|
||||
struct Door_Struct
|
||||
{
|
||||
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it: Daeken M. BlackBlade //changed both to 32: Trevius
|
||||
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it //changed both to 32
|
||||
/*0032*/ float yPos; // y loc
|
||||
/*0036*/ float xPos; // x loc
|
||||
/*0040*/ float zPos; // z loc
|
||||
@@ -2761,7 +2777,8 @@ struct BazaarWelcome_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint8 Unknown012[8];
|
||||
uint32 Unknown012;
|
||||
uint32 Unknown016;
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
@@ -3146,6 +3163,7 @@ struct Trader_ShowItems_Struct{
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Unknown08[3];
|
||||
/*020*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct{
|
||||
@@ -3191,9 +3209,10 @@ struct TraderDelItem_Struct{
|
||||
|
||||
struct TraderClick_Struct{
|
||||
/*000*/ uint32 TraderID;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*004*/ uint32 Code;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Approval;
|
||||
/*016*/
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
@@ -4104,30 +4123,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
@@ -4530,19 +4554,12 @@ struct InternalVeteranReward
|
||||
/*012*/ InternalVeteranRewardItem items[8];
|
||||
};
|
||||
|
||||
struct VeteranClaimReply
|
||||
struct VeteranClaim
|
||||
{
|
||||
/*000*/ char name[64];
|
||||
/*064*/ uint32 claim_id;
|
||||
/*068*/ uint32 reject_field;
|
||||
/*072*/ uint32 unknown072;
|
||||
};
|
||||
|
||||
struct VeteranClaimRequest
|
||||
{
|
||||
/*000*/ char name_data[64]; //name + other data
|
||||
/*000*/ char name[64]; //name + other data
|
||||
/*064*/ uint32 claim_id;
|
||||
/*068*/ uint32 unknown068;
|
||||
/*072*/ uint32 action;
|
||||
};
|
||||
|
||||
struct GMSearchCorpse_Struct
|
||||
|
||||
+120
-38
@@ -506,6 +506,7 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||
return slot_id;
|
||||
}
|
||||
|
||||
// Behavioral change - Limbo is no longer checked due to improper handling of return value
|
||||
if (where & invWhereCursor) {
|
||||
// Check cursor queue
|
||||
slot_id = _HasItem(m_cursor, item_id, quantity);
|
||||
@@ -552,6 +553,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
|
||||
return slot_id;
|
||||
}
|
||||
|
||||
// Behavioral change - Limbo is no longer checked due to improper handling of return value
|
||||
if (where & invWhereCursor) {
|
||||
// Check cursor queue
|
||||
slot_id = _HasItemByUse(m_cursor, use, quantity);
|
||||
@@ -597,6 +599,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
||||
return slot_id;
|
||||
}
|
||||
|
||||
// Behavioral change - Limbo is no longer checked due to improper handling of return value
|
||||
if (where & invWhereCursor) {
|
||||
// Check cursor queue
|
||||
slot_id = _HasItemByLoreGroup(m_cursor, loregroup);
|
||||
@@ -657,7 +660,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
|
||||
// If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot().
|
||||
//
|
||||
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U
|
||||
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias
|
||||
|
||||
if (!inst || !inst->GetID())
|
||||
return INVALID_INDEX;
|
||||
@@ -990,33 +993,43 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
uint8 Inventory::FindHighestLightValue()
|
||||
uint8 Inventory::FindBrightestLightType()
|
||||
{
|
||||
uint8 light_value = NOT_USED;
|
||||
uint8 brightest_light_type = 0;
|
||||
|
||||
// NOTE: The client does not recognize augment light sources, applied or otherwise, and should not be parsed
|
||||
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
|
||||
if ((iter->first < EmuConstants::EQUIPMENT_BEGIN || iter->first > EmuConstants::EQUIPMENT_END) && iter->first != MainPowerSource) { continue; }
|
||||
if (iter->first == MainAmmo) { continue; }
|
||||
|
||||
auto inst = iter->second;
|
||||
if (inst == nullptr) { continue; }
|
||||
auto item = inst->GetItem();
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > light_value) { light_value = item->Light; }
|
||||
|
||||
if (LightProfile_Struct::IsLevelGreater(item->Light, brightest_light_type))
|
||||
brightest_light_type = item->Light;
|
||||
}
|
||||
|
||||
uint8 general_light_type = 0;
|
||||
for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) {
|
||||
if (iter->first < EmuConstants::GENERAL_BEGIN || iter->first > EmuConstants::GENERAL_END) { continue; }
|
||||
|
||||
auto inst = iter->second;
|
||||
if (inst == nullptr) { continue; }
|
||||
auto item = inst->GetItem();
|
||||
if (item == nullptr) { continue; }
|
||||
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight) { continue; }
|
||||
if (item->Light & 0xF0) { continue; }
|
||||
if (item->Light > light_value) { light_value = item->Light; }
|
||||
|
||||
if (item->ItemClass != ItemClassCommon) { continue; }
|
||||
if (item->Light < 9 || item->Light > 13) { continue; }
|
||||
|
||||
if (LightProfile_Struct::TypeToLevel(item->Light))
|
||||
general_light_type = item->Light;
|
||||
}
|
||||
|
||||
return light_value;
|
||||
if (LightProfile_Struct::IsLevelGreater(general_light_type, brightest_light_type))
|
||||
brightest_light_type = general_light_type;
|
||||
|
||||
return brightest_light_type;
|
||||
}
|
||||
|
||||
void Inventory::dumpEntireInventory() {
|
||||
@@ -1059,7 +1072,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &col
|
||||
}
|
||||
|
||||
if (t_inst && !t_inst->IsType(ItemClassContainer)) {
|
||||
for (auto b_iter = t_inst->_begin(); b_iter != t_inst->_end(); ++b_iter) {
|
||||
for (auto b_iter = t_inst->_cbegin(); b_iter != t_inst->_cend(); ++b_iter) {
|
||||
if (b_iter->second == inst) {
|
||||
return Inventory::CalcSlotId(iter->first, b_iter->first);
|
||||
}
|
||||
@@ -1070,13 +1083,10 @@ int Inventory::GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &col
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection) {
|
||||
iter_inst it;
|
||||
iter_contents itb;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
for (it = collection.begin(); it != collection.end(); ++it) {
|
||||
inst = it->second;
|
||||
void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
|
||||
{
|
||||
for (auto it = collection.cbegin(); it != collection.cend(); ++it) {
|
||||
auto inst = it->second;
|
||||
if (!inst || !inst->GetItem())
|
||||
continue;
|
||||
|
||||
@@ -1087,14 +1097,13 @@ void Inventory::dumpItemCollection(const std::map<int16, ItemInst*> &collection)
|
||||
}
|
||||
}
|
||||
|
||||
void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) {
|
||||
iter_contents itb;
|
||||
|
||||
void Inventory::dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it)
|
||||
{
|
||||
if (!inst || !inst->IsType(ItemClassContainer))
|
||||
return;
|
||||
|
||||
// Go through bag, if bag
|
||||
for (itb = inst->_begin(); itb != inst->_end(); ++itb) {
|
||||
for (auto itb = inst->_cbegin(); itb != inst->_cend(); ++itb) {
|
||||
ItemInst* baginst = itb->second;
|
||||
if (!baginst || !baginst->GetItem())
|
||||
continue;
|
||||
@@ -1109,7 +1118,7 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) {
|
||||
// Internal Method: Retrieves item within an inventory bucket
|
||||
ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const
|
||||
{
|
||||
iter_inst it = bucket.find(slot_id);
|
||||
auto it = bucket.find(slot_id);
|
||||
if (it != bucket.end()) {
|
||||
return it->second;
|
||||
}
|
||||
@@ -1122,6 +1131,8 @@ ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 sl
|
||||
// Assumes item has already been allocated
|
||||
int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
|
||||
{
|
||||
// What happens here when we _PutItem(MainCursor)? Bad things..really bad things...
|
||||
//
|
||||
// If putting a nullptr into slot, we need to remove slot without memory delete
|
||||
if (inst == nullptr) {
|
||||
//Why do we not delete the poped item here????
|
||||
@@ -1203,7 +1214,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1230,11 +1241,11 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
// found, it is presented as being available on the cursor. In cases of a parity check, this
|
||||
// is sufficient. However, in cases where referential criteria is considered, this can lead
|
||||
// to unintended results. Funtionality should be observed when referencing the return value
|
||||
// of this query -U
|
||||
// of this query
|
||||
|
||||
uint8 quantity_found = 0;
|
||||
|
||||
for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) {
|
||||
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
|
||||
auto inst = *iter;
|
||||
if (inst == nullptr) { continue; }
|
||||
|
||||
@@ -1251,7 +1262,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1266,6 +1277,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
|
||||
return legacy::SLOT_AUGMENT;
|
||||
}
|
||||
}
|
||||
|
||||
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
|
||||
break;
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
@@ -1288,7 +1302,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1308,7 +1322,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
{
|
||||
uint8 quantity_found = 0;
|
||||
|
||||
for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) {
|
||||
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
|
||||
auto inst = *iter;
|
||||
if (inst == nullptr) { continue; }
|
||||
|
||||
@@ -1320,7 +1334,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1330,6 +1344,9 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
|
||||
return Inventory::CalcSlotId(MainCursor, bag_iter->first);
|
||||
}
|
||||
}
|
||||
|
||||
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
|
||||
break;
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
@@ -1354,7 +1371,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1377,7 +1394,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
|
||||
// Internal Method: Checks an inventory queue type bucket for a particular item
|
||||
int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
{
|
||||
for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) {
|
||||
for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) {
|
||||
auto inst = *iter;
|
||||
if (inst == nullptr) { continue; }
|
||||
|
||||
@@ -1394,7 +1411,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
|
||||
if (!inst->IsType(ItemClassContainer)) { continue; }
|
||||
|
||||
for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) {
|
||||
for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) {
|
||||
auto bag_inst = bag_iter->second;
|
||||
if (bag_inst == nullptr) { continue; }
|
||||
|
||||
@@ -1409,6 +1426,9 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
|
||||
return legacy::SLOT_AUGMENT;
|
||||
}
|
||||
}
|
||||
|
||||
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
|
||||
break;
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
@@ -1504,8 +1524,7 @@ ItemInst::ItemInst(const ItemInst& copy)
|
||||
m_attuned=copy.m_attuned;
|
||||
m_merchantcount=copy.m_merchantcount;
|
||||
// Copy container contents
|
||||
iter_contents it;
|
||||
for (it=copy.m_contents.begin(); it!=copy.m_contents.end(); ++it) {
|
||||
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
|
||||
ItemInst* inst_old = it->second;
|
||||
ItemInst* inst_new = nullptr;
|
||||
|
||||
@@ -1675,7 +1694,7 @@ bool ItemInst::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
||||
// Retrieve item inside container
|
||||
ItemInst* ItemInst::GetItem(uint8 index) const
|
||||
{
|
||||
iter_contents it = m_contents.find(index);
|
||||
auto it = m_contents.find(index);
|
||||
if (it != m_contents.end()) {
|
||||
return it->second;
|
||||
}
|
||||
@@ -1738,7 +1757,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
|
||||
// TODO: This needs work...
|
||||
|
||||
// Destroy container contents
|
||||
iter_contents cur, end, del;
|
||||
std::map<uint8, ItemInst*>::const_iterator cur, end, del;
|
||||
cur = m_contents.begin();
|
||||
end = m_contents.end();
|
||||
for (; cur != end;) {
|
||||
@@ -2138,7 +2157,7 @@ ItemInst* ItemInst::Clone() const
|
||||
}
|
||||
|
||||
bool ItemInst::IsSlotAllowed(int16 slot_id) const {
|
||||
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid -U
|
||||
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid
|
||||
if (!m_item) { return false; }
|
||||
else if (Inventory::SupportsContainers(slot_id)) { return true; }
|
||||
else if (m_item->Slots & (1 << slot_id)) { return true; }
|
||||
@@ -2351,3 +2370,66 @@ bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const
|
||||
|
||||
return (IsRace && IsClass);
|
||||
}
|
||||
|
||||
//
|
||||
// struct LightProfile_Struct
|
||||
//
|
||||
uint8 LightProfile_Struct::TypeToLevel(uint8 lightType)
|
||||
{
|
||||
switch (lightType) {
|
||||
case lightTypeGlobeOfStars:
|
||||
return lightLevelBrilliant; // 10
|
||||
case lightTypeFlamelessLantern:
|
||||
case lightTypeGreaterLightstone:
|
||||
return lightLevelLargeMagic; // 9
|
||||
case lightTypeLargeLantern:
|
||||
return lightLevelLargeLantern; // 8
|
||||
case lightTypeSteinOfMoggok:
|
||||
case lightTypeLightstone:
|
||||
return lightLevelMagicLantern; // 7
|
||||
case lightTypeSmallLantern:
|
||||
return lightLevelSmallLantern; // 6
|
||||
case lightTypeColdlight:
|
||||
case lightTypeUnknown2:
|
||||
return lightLevelBlueLight; // 5
|
||||
case lightTypeFireBeetleEye:
|
||||
case lightTypeUnknown1:
|
||||
return lightLevelRedLight; // 4
|
||||
case lightTypeTinyGlowingSkull:
|
||||
case lightTypeLightGlobe:
|
||||
return lightLevelSmallMagic; // 3
|
||||
case lightTypeTorch:
|
||||
return lightLevelTorch; // 2
|
||||
case lightLevelCandle:
|
||||
return lightLevelCandle; // 1
|
||||
default:
|
||||
return lightLevelUnlit; // 0
|
||||
}
|
||||
}
|
||||
|
||||
bool LightProfile_Struct::IsLevelGreater(uint8 leftType, uint8 rightType)
|
||||
{
|
||||
static const uint8 light_levels[LIGHT_TYPES_COUNT] = {
|
||||
lightLevelUnlit, /* lightTypeNone */
|
||||
lightLevelCandle, /* lightTypeCandle */
|
||||
lightLevelTorch, /* lightTypeTorch */
|
||||
lightLevelSmallMagic, /* lightTypeTinyGlowingSkull */
|
||||
lightLevelSmallLantern, /* lightTypeSmallLantern */
|
||||
lightLevelMagicLantern, /* lightTypeSteinOfMoggok */
|
||||
lightLevelLargeLantern, /* lightTypeLargeLantern */
|
||||
lightLevelLargeMagic, /* lightTypeFlamelessLantern */
|
||||
lightLevelBrilliant, /* lightTypeGlobeOfStars */
|
||||
lightLevelSmallMagic, /* lightTypeLightGlobe */
|
||||
lightLevelMagicLantern, /* lightTypeLightstone */
|
||||
lightLevelLargeMagic, /* lightTypeGreaterLightstone */
|
||||
lightLevelRedLight, /* lightTypeFireBeetleEye */
|
||||
lightLevelBlueLight, /* lightTypeColdlight */
|
||||
lightLevelRedLight, /* lightTypeUnknown1 */
|
||||
lightLevelBlueLight /* lightTypeUnknown2 */
|
||||
};
|
||||
|
||||
if (leftType >= LIGHT_TYPES_COUNT) { leftType = lightTypeNone; }
|
||||
if (rightType >= LIGHT_TYPES_COUNT) { rightType = lightTypeNone; }
|
||||
|
||||
return (light_levels[leftType] > light_levels[rightType]);
|
||||
}
|
||||
|
||||
+47
-11
@@ -33,9 +33,6 @@ class EvolveInfo; // Stores information about an evolving item family
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
// Helper typedefs
|
||||
typedef std::map<int16, ItemInst*>::const_iterator iter_inst;
|
||||
typedef std::map<uint8, ItemInst*>::const_iterator iter_contents;
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
@@ -86,8 +83,8 @@ public:
|
||||
// Public Methods
|
||||
/////////////////////////
|
||||
|
||||
inline std::list<ItemInst*>::const_iterator begin() { return m_list.begin(); }
|
||||
inline std::list<ItemInst*>::const_iterator end() { return m_list.end(); }
|
||||
inline std::list<ItemInst*>::const_iterator cbegin() { return m_list.cbegin(); }
|
||||
inline std::list<ItemInst*>::const_iterator cend() { return m_list.cend(); }
|
||||
|
||||
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
||||
inline bool empty() { return m_list.empty(); }
|
||||
@@ -140,8 +137,8 @@ public:
|
||||
ItemInst* GetItem(int16 slot_id) const;
|
||||
ItemInst* GetItem(int16 slot_id, uint8 bagidx) const;
|
||||
|
||||
inline std::list<ItemInst*>::const_iterator cursor_begin() { return m_cursor.begin(); }
|
||||
inline std::list<ItemInst*>::const_iterator cursor_end() { return m_cursor.end(); }
|
||||
inline std::list<ItemInst*>::const_iterator cursor_cbegin() { return m_cursor.cbegin(); }
|
||||
inline std::list<ItemInst*>::const_iterator cursor_cend() { return m_cursor.cend(); }
|
||||
|
||||
inline int CursorSize() { return m_cursor.size(); }
|
||||
inline bool CursorEmpty() { return m_cursor.empty(); }
|
||||
@@ -207,7 +204,7 @@ public:
|
||||
|
||||
int GetSlotByItemInst(ItemInst *inst);
|
||||
|
||||
uint8 FindHighestLightValue();
|
||||
uint8 FindBrightestLightType();
|
||||
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
@@ -227,7 +224,7 @@ protected:
|
||||
|
||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst);
|
||||
void dumpItemCollection(const std::map<int16, ItemInst*> &collection);
|
||||
void dumpBagContents(ItemInst *inst, iter_inst *it);
|
||||
void dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it);
|
||||
|
||||
// Retrieves item within an inventory bucket
|
||||
ItemInst* _GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const;
|
||||
@@ -425,8 +422,8 @@ protected:
|
||||
//////////////////////////
|
||||
// Protected Members
|
||||
//////////////////////////
|
||||
iter_contents _begin() { return m_contents.begin(); }
|
||||
iter_contents _end() { return m_contents.end(); }
|
||||
std::map<uint8, ItemInst*>::const_iterator _cbegin() { return m_contents.cbegin(); }
|
||||
std::map<uint8, ItemInst*>::const_iterator _cend() { return m_contents.cend(); }
|
||||
|
||||
friend class Inventory;
|
||||
|
||||
@@ -475,4 +472,43 @@ public:
|
||||
~EvolveInfo();
|
||||
};
|
||||
|
||||
struct LightProfile_Struct
|
||||
{
|
||||
/*
|
||||
Current criteria (light types):
|
||||
Equipment: { 0 .. 15 }
|
||||
General: { 9 .. 13 }
|
||||
|
||||
Notes:
|
||||
- Initial character load and item movement updates use different light source update behaviors
|
||||
-- Server procedure matches the item movement behavior since most updates occur post-character load
|
||||
- MainAmmo is not considered when determining light sources
|
||||
- No 'Sub' or 'Aug' items are recognized as light sources
|
||||
- Light types '< 9' and '> 13' are not considered for general (carried) light sources
|
||||
- If values > 0x0F are valid, then assignment limiters will need to be removed
|
||||
- MainCursor 'appears' to be a valid light source update slot..but, have not experienced updates during debug sessions
|
||||
- All clients have a bug regarding stackable items (light and sound updates are not processed when picking up an item)
|
||||
-- The timer-based update cancels out the invalid light source
|
||||
*/
|
||||
|
||||
static uint8 TypeToLevel(uint8 lightType);
|
||||
static bool IsLevelGreater(uint8 leftType, uint8 rightType);
|
||||
|
||||
// Light types (classifications)
|
||||
struct {
|
||||
uint8 Innate; // Defined by db field `npc_types`.`light` - where appropriate
|
||||
uint8 Equipment; // Item_Struct::light value of worn/carried equipment
|
||||
uint8 Spell; // Set value of any light-producing spell (can be modded to mimic equip_light behavior)
|
||||
uint8 Active; // Highest value of all light sources
|
||||
} Type;
|
||||
|
||||
// Light levels (intensities) - used to determine which light source should be active
|
||||
struct {
|
||||
uint8 Innate;
|
||||
uint8 Equipment;
|
||||
uint8 Spell;
|
||||
uint8 Active;
|
||||
} Level;
|
||||
};
|
||||
|
||||
#endif // #define __ITEM_H
|
||||
|
||||
@@ -180,7 +180,7 @@ IN(OP_GMLastName, GMLastName_Struct);
|
||||
IN(OP_GMToggle, GMToggle_Struct);
|
||||
IN(OP_LFGCommand, LFG_Struct);
|
||||
IN(OP_GMGoto, GMSummon_Struct);
|
||||
IN(OP_TraderShop, TraderClick_Struct);
|
||||
INv(OP_TraderShop, TraderClick_Struct);
|
||||
IN(OP_ShopRequest, Merchant_Click_Struct);
|
||||
IN(OP_Bazaar, BazaarSearch_Struct);
|
||||
//alt:IN(OP_Bazaar, BazaarWelcome_Struct); //alternate structure for OP_Bazaar
|
||||
@@ -399,7 +399,7 @@ OUT(OP_Weather, Weather_Struct);
|
||||
OUT(OP_ZoneChange, ZoneChange_Struct);
|
||||
OUT(OP_ZoneInUnknown, ZoneInUnknown_Struct);
|
||||
|
||||
//this is the set of opcodes which are allready listed
|
||||
//this is the set of opcodes which are already listed
|
||||
//in the IN section above, but are also sent OUT
|
||||
#ifdef DISJOINT_DIRECTIONS
|
||||
OUTz(OP_ClientReady); //follows OP_SetServerFilter
|
||||
@@ -449,7 +449,7 @@ OUT(OP_Trader, TraderBuy_Struct); //3 possible lengths
|
||||
//alt:OUT(OP_Trader, Trader_ShowItems_Struct);
|
||||
//alt:OUT(OP_Trader, Trader_Struct);
|
||||
OUT(OP_TraderBuy, TraderBuy_Struct);
|
||||
OUT(OP_TraderShop, TraderClick_Struct);
|
||||
OUTv(OP_TraderShop, TraderClick_Struct);
|
||||
OUT(OP_WearChange, WearChange_Struct);
|
||||
OUT(OP_ZoneEntry, ServerZoneEntry_Struct);
|
||||
#endif
|
||||
|
||||
+212
-165
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
|
||||
namespace RoF
|
||||
{
|
||||
@@ -2043,7 +2045,7 @@ namespace RoF
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_tint[r].color);
|
||||
outapp->WriteUInt32(emu->item_tint[r].Color);
|
||||
}
|
||||
// Write zeroes for extra two tint values
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2053,7 +2055,7 @@ namespace RoF
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_tint[r].color);
|
||||
outapp->WriteUInt32(emu->item_tint[r].Color);
|
||||
}
|
||||
// Write zeroes for extra two tint values
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2286,46 +2288,52 @@ namespace RoF
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_PLAYER_BANDOLIER);
|
||||
outapp->WriteUInt32(consts::BANDOLIERS_SIZE);
|
||||
|
||||
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_COUNT; r++)
|
||||
{
|
||||
outapp->WriteString(emu->bandoliers[r].name);
|
||||
|
||||
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
|
||||
{
|
||||
outapp->WriteString(emu->bandoliers[r].items[j].item_name);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].items[j].item_id);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].items[j].icon);
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
outapp->WriteString(emu->bandoliers[r].Name);
|
||||
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
|
||||
outapp->WriteString(emu->bandoliers[r].Items[j].Name);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID);
|
||||
if (emu->bandoliers[r].Items[j].Icon) {
|
||||
outapp->WriteSInt32(emu->bandoliers[r].Items[j].Icon);
|
||||
}
|
||||
else {
|
||||
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - EmuConstants::BANDOLIERS_COUNT; r++)
|
||||
{
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (uint32 r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
outapp->WriteString("");
|
||||
|
||||
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
|
||||
{
|
||||
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
|
||||
outapp->WriteString("");
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_POTIONS_IN_BELT);
|
||||
outapp->WriteUInt32(consts::POTION_BELT_ITEM_COUNT);
|
||||
|
||||
for (uint32 r = 0; r < EmuConstants::POTION_BELT_SIZE; r++)
|
||||
{
|
||||
outapp->WriteString(emu->potionbelt.items[r].item_name);
|
||||
outapp->WriteUInt32(emu->potionbelt.items[r].item_id);
|
||||
outapp->WriteUInt32(emu->potionbelt.items[r].icon);
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (uint32 r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
outapp->WriteString(emu->potionbelt.Items[r].Name);
|
||||
outapp->WriteUInt32(emu->potionbelt.Items[r].ID);
|
||||
if (emu->potionbelt.Items[r].Icon) {
|
||||
outapp->WriteSInt32(emu->potionbelt.Items[r].Icon);
|
||||
}
|
||||
else {
|
||||
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - EmuConstants::POTION_BELT_SIZE; r++)
|
||||
{
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (uint32 r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
outapp->WriteString("");
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
|
||||
outapp->WriteSInt32(-1); // Unknown;
|
||||
@@ -2418,7 +2426,7 @@ namespace RoF
|
||||
outapp->WriteUInt32(emu->silver_bank);
|
||||
outapp->WriteUInt32(emu->copper_bank);
|
||||
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(emu->platinum_shared);
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
@@ -2891,85 +2899,99 @@ namespace RoF
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_VAR_ENCODE(CharacterSelect_Struct);
|
||||
|
||||
//EQApplicationPacket *packet = *p;
|
||||
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
|
||||
// Zero-character count shunt
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
|
||||
int char_count;
|
||||
int namelen = 0;
|
||||
for (char_count = 0; char_count < 10; char_count++) {
|
||||
if (emu->name[char_count][0] == '\0')
|
||||
break;
|
||||
if (strcmp(emu->name[char_count], "<none>") == 0)
|
||||
break;
|
||||
namelen += strlen(emu->name[char_count]);
|
||||
FINISH_ENCODE();
|
||||
return;
|
||||
}
|
||||
|
||||
int total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ namelen;
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
size_t names_length = 0;
|
||||
size_t character_count = 0;
|
||||
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
names_length += strlen(emu_cse->Name);
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
size_t total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ names_length;
|
||||
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
|
||||
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
//unsigned char *eq_buffer = new unsigned char[total_length];
|
||||
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
|
||||
eq->CharCount = character_count;
|
||||
//eq->TotalChars = emu->TotalChars;
|
||||
|
||||
eq->char_count = char_count;
|
||||
//eq->total_chars = 10;
|
||||
//if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
// eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
unsigned char *bufptr = (unsigned char *)eq->entries;
|
||||
int r;
|
||||
for (r = 0; r < char_count; r++) {
|
||||
{ //pre-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
|
||||
emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
|
||||
unsigned char *eq_ptr = __packet->pBuffer;
|
||||
eq_ptr += sizeof(structs::CharacterSelect_Struct);
|
||||
|
||||
for (int counter = 0; counter < character_count; ++counter) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
strcpy(eq_cse->Name, emu_cse->Name);
|
||||
eq_ptr += strlen(eq_cse->Name);
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Class = emu_cse->Class;
|
||||
eq_cse->Race = emu_cse->Race;
|
||||
eq_cse->Level = emu_cse->Level;
|
||||
eq_cse->ShroudClass = emu_cse->ShroudClass;
|
||||
eq_cse->ShroudRace = emu_cse->ShroudRace;
|
||||
eq_cse->Zone = emu_cse->Zone;
|
||||
eq_cse->Instance = emu_cse->Instance;
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
|
||||
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
|
||||
}
|
||||
//adjust for name.
|
||||
bufptr += strlen(emu->name[r]);
|
||||
{ //post-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->class_ = emu->class_[r];
|
||||
eq2->race = emu->race[r];
|
||||
eq2->level = emu->level[r];
|
||||
eq2->class_2 = emu->class_[r];
|
||||
eq2->race2 = emu->race[r];
|
||||
eq2->zone = emu->zone[r];
|
||||
eq2->instance = 0;
|
||||
eq2->gender = emu->gender[r];
|
||||
eq2->face = emu->face[r];
|
||||
int k;
|
||||
for (k = 0; k < _MaterialCount; k++) {
|
||||
eq2->equip[k].material = emu->equip[r][k].material;
|
||||
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
|
||||
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
|
||||
eq2->equip[k].heroforgemodel = emu->equip[r][k].heroforgemodel;
|
||||
eq2->equip[k].material2 = emu->equip[r][k].material2;
|
||||
eq2->equip[k].color.color = emu->equip[r][k].color.color;
|
||||
}
|
||||
eq2->u15 = 0xff;
|
||||
eq2->u19 = 0xFF;
|
||||
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
|
||||
eq2->drakkin_details = emu->drakkin_details[r];
|
||||
eq2->deity = emu->deity[r];
|
||||
eq2->primary = emu->primary[r];
|
||||
eq2->secondary = emu->secondary[r];
|
||||
eq2->haircolor = emu->haircolor[r];
|
||||
eq2->beardcolor = emu->beardcolor[r];
|
||||
eq2->eyecolor1 = emu->eyecolor1[r];
|
||||
eq2->eyecolor2 = emu->eyecolor2[r];
|
||||
eq2->hairstyle = emu->hairstyle[r];
|
||||
eq2->beard = emu->beard[r];
|
||||
eq2->char_enabled = 1;
|
||||
eq2->tutorial = emu->tutorial[r];
|
||||
eq2->drakkin_heritage = emu->drakkin_heritage[r];
|
||||
eq2->unknown1 = 0;
|
||||
eq2->gohome = emu->gohome[r];
|
||||
eq2->LastLogin = 1212696584;
|
||||
eq2->unknown2 = 0;
|
||||
}
|
||||
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
|
||||
eq_cse->Unknown15 = emu_cse->Unknown15;
|
||||
eq_cse->Unknown19 = emu_cse->Unknown19;
|
||||
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
|
||||
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
|
||||
eq_cse->Deity = emu_cse->Deity;
|
||||
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
|
||||
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->BeardColor = emu_cse->BeardColor;
|
||||
eq_cse->EyeColor1 = emu_cse->EyeColor1;
|
||||
eq_cse->EyeColor2 = emu_cse->EyeColor2;
|
||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||
eq_cse->Beard = emu_cse->Beard;
|
||||
eq_cse->GoHome = emu_cse->GoHome;
|
||||
eq_cse->Tutorial = emu_cse->Tutorial;
|
||||
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
|
||||
eq_cse->Unknown1 = emu_cse->Unknown1;
|
||||
eq_cse->Enabled = emu_cse->Enabled;
|
||||
eq_cse->LastLogin = emu_cse->LastLogin;
|
||||
eq_cse->Unknown2 = emu_cse->Unknown2;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3588,37 +3610,71 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_VetClaimReply)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(VeteranClaim);
|
||||
SETUP_DIRECT_ENCODE(VeteranClaim, structs::VeteranClaim);
|
||||
|
||||
memcpy(eq->name, emu->name, sizeof(emu->name));
|
||||
OUT(claim_id);
|
||||
OUT(action);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_VetRewardsAvaliable)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
auto __emu_buffer = inapp->pBuffer;
|
||||
|
||||
uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward));
|
||||
*p = nullptr;
|
||||
|
||||
EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count));
|
||||
uchar *old_data = __emu_buffer;
|
||||
uchar *data = outapp_create->pBuffer;
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
structs::VeteranReward *vr = (structs::VeteranReward*)data;
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward*)old_data;
|
||||
// calculate size of names, note the packet DOES NOT have null termed c-strings
|
||||
std::vector<uint32> name_lengths;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
|
||||
|
||||
vr->claim_count = ivr->claim_count;
|
||||
vr->claim_id = ivr->claim_id;
|
||||
vr->number_available = ivr->number_available;
|
||||
for (int x = 0; x < 8; ++x)
|
||||
{
|
||||
vr->items[x].item_id = ivr->items[x].item_id;
|
||||
strncpy(vr->items[x].item_name, ivr->items[x].item_name, sizeof(vr->items[x].item_name));
|
||||
vr->items[x].charges = ivr->items[x].charges;
|
||||
for (int i = 0; i < ivr->claim_count; i++) {
|
||||
uint32 length = strnlen(ivr->items[i].item_name, 63);
|
||||
if (length)
|
||||
name_lengths.push_back(length);
|
||||
}
|
||||
|
||||
old_data += sizeof(InternalVeteranReward);
|
||||
data += sizeof(structs::VeteranReward);
|
||||
__emu_buffer += sizeof(InternalVeteranReward);
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
uint32 packet_size = std::accumulate(name_lengths.begin(), name_lengths.end(), 0) +
|
||||
sizeof(structs::VeteranReward) + (sizeof(structs::VeteranRewardEntry) * count) +
|
||||
// size of name_lengths is the same as item count
|
||||
(sizeof(structs::VeteranRewardItem) * name_lengths.size());
|
||||
|
||||
// build packet now!
|
||||
auto outapp = new EQApplicationPacket(OP_VetRewardsAvaliable, packet_size);
|
||||
__emu_buffer = inapp->pBuffer;
|
||||
|
||||
outapp->WriteUInt32(count);
|
||||
auto name_itr = name_lengths.begin();
|
||||
for (int i = 0; i < count; i++) {
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
|
||||
|
||||
outapp->WriteUInt32(ivr->claim_id);
|
||||
outapp->WriteUInt32(ivr->number_available);
|
||||
outapp->WriteUInt32(ivr->claim_count);
|
||||
outapp->WriteUInt8(1); // enabled
|
||||
|
||||
for (int j = 0; j < ivr->claim_count; j++) {
|
||||
assert(name_itr != name_lengths.end()); // the way it's written, it should never happen, so just assert
|
||||
outapp->WriteUInt32(*name_itr);
|
||||
outapp->WriteData(ivr->items[j].item_name, *name_itr);
|
||||
outapp->WriteUInt32(ivr->items[j].item_id);
|
||||
outapp->WriteUInt32(ivr->items[j].charges);
|
||||
++name_itr;
|
||||
}
|
||||
|
||||
__emu_buffer += sizeof(InternalVeteranReward);
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
@@ -3633,7 +3689,7 @@ namespace RoF
|
||||
OUT(elite_material);
|
||||
OUT(hero_forge_model);
|
||||
OUT(unknown18);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3724,42 +3780,23 @@ namespace RoF
|
||||
|
||||
ENCODE(OP_ZonePlayerToBind)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
|
||||
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
|
||||
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
|
||||
|
||||
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
|
||||
__packet->SetWritePosition(0);
|
||||
__packet->WriteUInt16(emu->bind_zone_id);
|
||||
__packet->WriteUInt16(emu->bind_instance_id);
|
||||
__packet->WriteFloat(emu->x);
|
||||
__packet->WriteFloat(emu->y);
|
||||
__packet->WriteFloat(emu->z);
|
||||
__packet->WriteFloat(emu->heading);
|
||||
__packet->WriteString(emu->zone_name);
|
||||
__packet->WriteUInt8(1); // save items
|
||||
__packet->WriteUInt32(0); // hp
|
||||
__packet->WriteUInt32(0); // mana
|
||||
__packet->WriteUInt32(0); // endurance
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
|
||||
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
|
||||
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
|
||||
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
|
||||
|
||||
zph->x = zps->x;
|
||||
zph->y = zps->y;
|
||||
zph->z = zps->z;
|
||||
zph->heading = zps->heading;
|
||||
zph->bind_zone_id = 0;
|
||||
zph->bind_instance_id = zps->bind_instance_id;
|
||||
strncpy(zph->zone_name, zps->zone_name, sizeof(zph->zone_name));
|
||||
|
||||
zpf->unknown021 = 1;
|
||||
zpf->unknown022 = 0;
|
||||
zpf->unknown023 = 0;
|
||||
zpf->unknown024 = 0;
|
||||
|
||||
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
|
||||
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
|
||||
|
||||
delete[] buffer1;
|
||||
delete[] buffer2;
|
||||
delete[](*p)->pBuffer;
|
||||
|
||||
(*p)->pBuffer = new unsigned char[ss.str().size()];
|
||||
(*p)->size = ss.str().size();
|
||||
|
||||
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
|
||||
dest->FastQueuePacket(&(*p));
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ZoneServerInfo)
|
||||
@@ -3807,8 +3844,8 @@ namespace RoF
|
||||
PacketSize += strlen(emu->name);
|
||||
PacketSize += strlen(emu->lastName);
|
||||
|
||||
emu->title[0] = 0;
|
||||
emu->suffix[0] = 0;
|
||||
emu->title[31] = 0;
|
||||
emu->suffix[31] = 0;
|
||||
|
||||
if (strlen(emu->title))
|
||||
PacketSize += strlen(emu->title) + 1;
|
||||
@@ -3963,18 +4000,18 @@ namespace RoF
|
||||
for (k = 0; k < 9; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
|
||||
}
|
||||
}
|
||||
|
||||
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
|
||||
|
||||
for (k = 0; k < 9; k++) {
|
||||
Equipment[k].material = emu->equipment[k].material;
|
||||
Equipment[k].unknown1 = emu->equipment[k].unknown1;
|
||||
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
|
||||
Equipment[k].heroforgemodel = emu->equipment[k].heroforgemodel;
|
||||
Equipment[k].material2 = emu->equipment[k].material2;
|
||||
Equipment[k].Material = emu->equipment[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
|
||||
Equipment[k].HeroForgeModel = emu->equipment[k].HeroForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment[k].Material2;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::EquipStruct) * 9);
|
||||
@@ -3987,13 +4024,13 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
@@ -4888,7 +4925,7 @@ namespace RoF
|
||||
slot_id = legacy::SLOT_TRADESKILL; // 1000
|
||||
}
|
||||
emu->container_slot = slot_id;
|
||||
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented -U
|
||||
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -4923,6 +4960,16 @@ namespace RoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_VetClaimRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::VeteranClaim);
|
||||
SETUP_DIRECT_DECODE(VeteranClaim, structs::VeteranClaim);
|
||||
|
||||
IN(claim_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ZoneChange)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::ZoneChange_Struct);
|
||||
@@ -4983,7 +5030,7 @@ namespace RoF
|
||||
|
||||
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
||||
|
||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%012d", item->ID);
|
||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
||||
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
hdr.unknown004 = 0;
|
||||
|
||||
+365
-190
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
|
||||
namespace RoF2
|
||||
{
|
||||
@@ -104,7 +106,7 @@ namespace RoF2
|
||||
{
|
||||
//all opcodes default to passthrough.
|
||||
#include "ss_register.h"
|
||||
#include "rof_ops.h"
|
||||
#include "rof2_ops.h"
|
||||
}
|
||||
|
||||
std::string Strategy::Describe() const
|
||||
@@ -2118,7 +2120,7 @@ namespace RoF2
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_tint[r].color);
|
||||
outapp->WriteUInt32(emu->item_tint[r].Color);
|
||||
}
|
||||
// Write zeroes for extra two tint values
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2128,7 +2130,7 @@ namespace RoF2
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_tint[r].color);
|
||||
outapp->WriteUInt32(emu->item_tint[r].Color);
|
||||
}
|
||||
// Write zeroes for extra two tint values
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2360,46 +2362,52 @@ namespace RoF2
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
outapp->WriteUInt8(0); // Unknown
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_PLAYER_BANDOLIER);
|
||||
outapp->WriteUInt32(consts::BANDOLIERS_SIZE);
|
||||
|
||||
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_COUNT; r++)
|
||||
{
|
||||
outapp->WriteString(emu->bandoliers[r].name);
|
||||
|
||||
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
|
||||
{
|
||||
outapp->WriteString(emu->bandoliers[r].items[j].item_name);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].items[j].item_id);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].items[j].icon);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - EmuConstants::BANDOLIERS_COUNT; r++)
|
||||
{
|
||||
outapp->WriteString("");
|
||||
|
||||
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
|
||||
{
|
||||
outapp->WriteString("");
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(structs::MAX_POTIONS_IN_BELT);
|
||||
|
||||
for (uint32 r = 0; r < EmuConstants::POTION_BELT_SIZE; r++)
|
||||
{
|
||||
outapp->WriteString(emu->potionbelt.items[r].item_name);
|
||||
outapp->WriteUInt32(emu->potionbelt.items[r].item_id);
|
||||
outapp->WriteUInt32(emu->potionbelt.items[r].icon);
|
||||
}
|
||||
|
||||
for (uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - EmuConstants::POTION_BELT_SIZE; r++)
|
||||
{
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
outapp->WriteString(emu->bandoliers[r].Name);
|
||||
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
|
||||
outapp->WriteString(emu->bandoliers[r].Items[j].Name);
|
||||
outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID);
|
||||
if (emu->bandoliers[r].Items[j].Icon) {
|
||||
outapp->WriteSInt32(emu->bandoliers[r].Items[j].Icon);
|
||||
}
|
||||
else {
|
||||
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (uint32 r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
outapp->WriteString("");
|
||||
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
|
||||
outapp->WriteString("");
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(consts::POTION_BELT_ITEM_COUNT);
|
||||
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (uint32 r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
outapp->WriteString(emu->potionbelt.Items[r].Name);
|
||||
outapp->WriteUInt32(emu->potionbelt.Items[r].ID);
|
||||
if (emu->potionbelt.Items[r].Icon) {
|
||||
outapp->WriteSInt32(emu->potionbelt.Items[r].Icon);
|
||||
}
|
||||
else {
|
||||
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
}
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (uint32 r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
outapp->WriteString("");
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteSInt32(-1);
|
||||
}
|
||||
|
||||
outapp->WriteSInt32(-1); // Unknown;
|
||||
@@ -2493,7 +2501,7 @@ namespace RoF2
|
||||
outapp->WriteUInt32(emu->silver_bank);
|
||||
outapp->WriteUInt32(emu->copper_bank);
|
||||
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(emu->platinum_shared);
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
outapp->WriteUInt32(0); // Unknown
|
||||
@@ -2975,85 +2983,99 @@ namespace RoF2
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_VAR_ENCODE(CharacterSelect_Struct);
|
||||
|
||||
//EQApplicationPacket *packet = *p;
|
||||
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
|
||||
// Zero-character count shunt
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
|
||||
int char_count;
|
||||
int namelen = 0;
|
||||
for (char_count = 0; char_count < 10; char_count++) {
|
||||
if (emu->name[char_count][0] == '\0')
|
||||
break;
|
||||
if (strcmp(emu->name[char_count], "<none>") == 0)
|
||||
break;
|
||||
namelen += strlen(emu->name[char_count]);
|
||||
FINISH_ENCODE();
|
||||
return;
|
||||
}
|
||||
|
||||
int total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ namelen;
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
size_t names_length = 0;
|
||||
size_t character_count = 0;
|
||||
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
names_length += strlen(emu_cse->Name);
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
size_t total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ names_length;
|
||||
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
|
||||
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
//unsigned char *eq_buffer = new unsigned char[total_length];
|
||||
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
|
||||
eq->CharCount = character_count;
|
||||
//eq->TotalChars = emu->TotalChars;
|
||||
|
||||
eq->char_count = char_count;
|
||||
//eq->total_chars = 10;
|
||||
//if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
// eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
unsigned char *bufptr = (unsigned char *)eq->entries;
|
||||
int r;
|
||||
for (r = 0; r < char_count; r++) {
|
||||
{ //pre-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
|
||||
emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
|
||||
unsigned char *eq_ptr = __packet->pBuffer;
|
||||
eq_ptr += sizeof(structs::CharacterSelect_Struct);
|
||||
|
||||
for (int counter = 0; counter < character_count; ++counter) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
strcpy(eq_cse->Name, emu_cse->Name);
|
||||
eq_ptr += strlen(eq_cse->Name);
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Class = emu_cse->Class;
|
||||
eq_cse->Race = emu_cse->Race;
|
||||
eq_cse->Level = emu_cse->Level;
|
||||
eq_cse->ShroudClass = emu_cse->ShroudClass;
|
||||
eq_cse->ShroudRace = emu_cse->ShroudRace;
|
||||
eq_cse->Zone = emu_cse->Zone;
|
||||
eq_cse->Instance = emu_cse->Instance;
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
|
||||
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
|
||||
}
|
||||
//adjust for name.
|
||||
bufptr += strlen(emu->name[r]);
|
||||
{ //post-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->class_ = emu->class_[r];
|
||||
eq2->race = emu->race[r];
|
||||
eq2->level = emu->level[r];
|
||||
eq2->class_2 = emu->class_[r];
|
||||
eq2->race2 = emu->race[r];
|
||||
eq2->zone = emu->zone[r];
|
||||
eq2->instance = 0;
|
||||
eq2->gender = emu->gender[r];
|
||||
eq2->face = emu->face[r];
|
||||
int k;
|
||||
for (k = 0; k < _MaterialCount; k++) {
|
||||
eq2->equip[k].material = emu->equip[r][k].material;
|
||||
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
|
||||
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
|
||||
eq2->equip[k].heroforgemodel = emu->equip[r][k].heroforgemodel;
|
||||
eq2->equip[k].material2 = emu->equip[r][k].material2;
|
||||
eq2->equip[k].color.color = emu->equip[r][k].color.color;
|
||||
}
|
||||
eq2->u15 = 0xff;
|
||||
eq2->u19 = 0xFF;
|
||||
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
|
||||
eq2->drakkin_details = emu->drakkin_details[r];
|
||||
eq2->deity = emu->deity[r];
|
||||
eq2->primary = emu->primary[r];
|
||||
eq2->secondary = emu->secondary[r];
|
||||
eq2->haircolor = emu->haircolor[r];
|
||||
eq2->beardcolor = emu->beardcolor[r];
|
||||
eq2->eyecolor1 = emu->eyecolor1[r];
|
||||
eq2->eyecolor2 = emu->eyecolor2[r];
|
||||
eq2->hairstyle = emu->hairstyle[r];
|
||||
eq2->beard = emu->beard[r];
|
||||
eq2->char_enabled = 1;
|
||||
eq2->tutorial = emu->tutorial[r];
|
||||
eq2->drakkin_heritage = emu->drakkin_heritage[r];
|
||||
eq2->unknown1 = 0;
|
||||
eq2->gohome = emu->gohome[r];
|
||||
eq2->LastLogin = 1212696584;
|
||||
eq2->unknown2 = 0;
|
||||
}
|
||||
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
|
||||
eq_cse->Unknown15 = emu_cse->Unknown15;
|
||||
eq_cse->Unknown19 = emu_cse->Unknown19;
|
||||
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
|
||||
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
|
||||
eq_cse->Deity = emu_cse->Deity;
|
||||
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
|
||||
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->BeardColor = emu_cse->BeardColor;
|
||||
eq_cse->EyeColor1 = emu_cse->EyeColor1;
|
||||
eq_cse->EyeColor2 = emu_cse->EyeColor2;
|
||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||
eq_cse->Beard = emu_cse->Beard;
|
||||
eq_cse->GoHome = emu_cse->GoHome;
|
||||
eq_cse->Tutorial = emu_cse->Tutorial;
|
||||
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
|
||||
eq_cse->Unknown1 = emu_cse->Unknown1;
|
||||
eq_cse->Enabled = emu_cse->Enabled;
|
||||
eq_cse->LastLogin = emu_cse->LastLogin;
|
||||
eq_cse->Unknown2 = emu_cse->Unknown2;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3563,12 +3585,13 @@ namespace RoF2
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 200; i++)
|
||||
{
|
||||
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||
eq->items[i].Unknown18 = 0;
|
||||
if (i < 80) {
|
||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", emu->SerialNumber[i]);
|
||||
eq->ItemCost[i] = emu->ItemCost[i];
|
||||
}
|
||||
else {
|
||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", 0);
|
||||
eq->ItemCost[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -3581,10 +3604,11 @@ namespace RoF2
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
|
||||
eq->Code = emu->Code;
|
||||
strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||
//strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||
//snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", 0);
|
||||
eq->TraderID = emu->TraderID;
|
||||
eq->Stacksize = 0;
|
||||
eq->Price = 0;
|
||||
//eq->Stacksize = 0;
|
||||
//eq->Price = 0;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -3619,6 +3643,78 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderDelItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderDelItem_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderDelItem_Struct, structs::TraderDelItem_Struct);
|
||||
|
||||
OUT(TraderID);
|
||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderDelItem): TraderID %d, SerialNumber: %d", emu->TraderID, emu->ItemID);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderShop)
|
||||
{
|
||||
uint32 psize = (*p)->size;
|
||||
if (psize == sizeof(TraderClick_Struct))
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
|
||||
eq->Code = 28; // Seen on Live
|
||||
OUT(TraderID);
|
||||
OUT(Approval);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
else if (psize == sizeof(BazaarWelcome_Struct))
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(BazaarWelcome_Struct);
|
||||
SETUP_DIRECT_ENCODE(BazaarWelcome_Struct, structs::BazaarWelcome_Struct);
|
||||
|
||||
eq->Code = emu->Beginning.Action;
|
||||
eq->EntityID = emu->Unknown012;
|
||||
OUT(Traders);
|
||||
OUT(Items);
|
||||
eq->Traders2 = emu->Traders;
|
||||
eq->Items2 = emu->Items;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||
eq->Code, eq->Traders, eq->Items);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
else if (psize == sizeof(TraderBuy_Struct))
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(Action);
|
||||
OUT(TraderID);
|
||||
|
||||
//memcpy(eq->BuyerName, emu->BuyerName, sizeof(eq->BuyerName));
|
||||
//memcpy(eq->SellerName, emu->SellerName, sizeof(eq->SellerName));
|
||||
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(AlreadySold);
|
||||
OUT(Price);
|
||||
OUT(Quantity);
|
||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, emu->ItemName);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Encode Size Unknown (%d)", psize);
|
||||
}
|
||||
}
|
||||
|
||||
ENCODE(OP_TributeInfo)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(TributeAbility_Struct);
|
||||
@@ -3655,37 +3751,71 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_VetClaimReply)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(VeteranClaim);
|
||||
SETUP_DIRECT_ENCODE(VeteranClaim, structs::VeteranClaim);
|
||||
|
||||
memcpy(eq->name, emu->name, sizeof(emu->name));
|
||||
OUT(claim_id);
|
||||
OUT(action);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_VetRewardsAvaliable)
|
||||
{
|
||||
EQApplicationPacket *inapp = *p;
|
||||
unsigned char * __emu_buffer = inapp->pBuffer;
|
||||
auto __emu_buffer = inapp->pBuffer;
|
||||
|
||||
uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward));
|
||||
*p = nullptr;
|
||||
|
||||
EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count));
|
||||
uchar *old_data = __emu_buffer;
|
||||
uchar *data = outapp_create->pBuffer;
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
structs::VeteranReward *vr = (structs::VeteranReward*)data;
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward*)old_data;
|
||||
// calculate size of names, note the packet DOES NOT have null termed c-strings
|
||||
std::vector<uint32> name_lengths;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
|
||||
|
||||
vr->claim_count = ivr->claim_count;
|
||||
vr->claim_id = ivr->claim_id;
|
||||
vr->number_available = ivr->number_available;
|
||||
for (int x = 0; x < 8; ++x)
|
||||
{
|
||||
vr->items[x].item_id = ivr->items[x].item_id;
|
||||
strncpy(vr->items[x].item_name, ivr->items[x].item_name, sizeof(vr->items[x].item_name));
|
||||
vr->items[x].charges = ivr->items[x].charges;
|
||||
for (int i = 0; i < ivr->claim_count; i++) {
|
||||
uint32 length = strnlen(ivr->items[i].item_name, 63);
|
||||
if (length)
|
||||
name_lengths.push_back(length);
|
||||
}
|
||||
|
||||
old_data += sizeof(InternalVeteranReward);
|
||||
data += sizeof(structs::VeteranReward);
|
||||
__emu_buffer += sizeof(InternalVeteranReward);
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp_create);
|
||||
uint32 packet_size = std::accumulate(name_lengths.begin(), name_lengths.end(), 0) +
|
||||
sizeof(structs::VeteranReward) + (sizeof(structs::VeteranRewardEntry) * count) +
|
||||
// size of name_lengths is the same as item count
|
||||
(sizeof(structs::VeteranRewardItem) * name_lengths.size());
|
||||
|
||||
// build packet now!
|
||||
auto outapp = new EQApplicationPacket(OP_VetRewardsAvaliable, packet_size);
|
||||
__emu_buffer = inapp->pBuffer;
|
||||
|
||||
outapp->WriteUInt32(count);
|
||||
auto name_itr = name_lengths.begin();
|
||||
for (int i = 0; i < count; i++) {
|
||||
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
|
||||
|
||||
outapp->WriteUInt32(ivr->claim_id);
|
||||
outapp->WriteUInt32(ivr->number_available);
|
||||
outapp->WriteUInt32(ivr->claim_count);
|
||||
outapp->WriteUInt8(1); // enabled
|
||||
|
||||
for (int j = 0; j < ivr->claim_count; j++) {
|
||||
assert(name_itr != name_lengths.end()); // the way it's written, it should never happen, so just assert
|
||||
outapp->WriteUInt32(*name_itr);
|
||||
outapp->WriteData(ivr->items[j].item_name, *name_itr);
|
||||
outapp->WriteUInt32(ivr->items[j].item_id);
|
||||
outapp->WriteUInt32(ivr->items[j].charges);
|
||||
++name_itr;
|
||||
}
|
||||
|
||||
__emu_buffer += sizeof(InternalVeteranReward);
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
delete inapp;
|
||||
}
|
||||
|
||||
@@ -3700,7 +3830,7 @@ namespace RoF2
|
||||
OUT(elite_material);
|
||||
OUT(hero_forge_model);
|
||||
OUT(unknown18);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -3791,42 +3921,23 @@ namespace RoF2
|
||||
|
||||
ENCODE(OP_ZonePlayerToBind)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
|
||||
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
|
||||
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
|
||||
|
||||
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
|
||||
__packet->SetWritePosition(0);
|
||||
__packet->WriteUInt16(emu->bind_zone_id);
|
||||
__packet->WriteUInt16(emu->bind_instance_id);
|
||||
__packet->WriteFloat(emu->x);
|
||||
__packet->WriteFloat(emu->y);
|
||||
__packet->WriteFloat(emu->z);
|
||||
__packet->WriteFloat(emu->heading);
|
||||
__packet->WriteString(emu->zone_name);
|
||||
__packet->WriteUInt8(1); // save items
|
||||
__packet->WriteUInt32(0); // hp
|
||||
__packet->WriteUInt32(0); // mana
|
||||
__packet->WriteUInt32(0); // endurance
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
|
||||
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
|
||||
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
|
||||
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
|
||||
|
||||
zph->x = zps->x;
|
||||
zph->y = zps->y;
|
||||
zph->z = zps->z;
|
||||
zph->heading = zps->heading;
|
||||
zph->bind_zone_id = 0;
|
||||
zph->bind_instance_id = zps->bind_instance_id;
|
||||
strncpy(zph->zone_name, zps->zone_name, sizeof(zph->zone_name));
|
||||
|
||||
zpf->unknown021 = 1;
|
||||
zpf->unknown022 = 0;
|
||||
zpf->unknown023 = 0;
|
||||
zpf->unknown024 = 0;
|
||||
|
||||
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
|
||||
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
|
||||
|
||||
delete[] buffer1;
|
||||
delete[] buffer2;
|
||||
delete[](*p)->pBuffer;
|
||||
|
||||
(*p)->pBuffer = new unsigned char[ss.str().size()];
|
||||
(*p)->size = ss.str().size();
|
||||
|
||||
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
|
||||
dest->FastQueuePacket(&(*p));
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ZoneServerInfo)
|
||||
@@ -3874,8 +3985,8 @@ namespace RoF2
|
||||
PacketSize += strlen(emu->name);
|
||||
PacketSize += strlen(emu->lastName);
|
||||
|
||||
emu->title[0] = 0;
|
||||
emu->suffix[0] = 0;
|
||||
emu->title[31] = 0;
|
||||
emu->suffix[31] = 0;
|
||||
|
||||
if (strlen(emu->title))
|
||||
PacketSize += strlen(emu->title) + 1;
|
||||
@@ -4034,18 +4145,18 @@ namespace RoF2
|
||||
for (k = 0; k < 9; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
|
||||
}
|
||||
}
|
||||
|
||||
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
|
||||
|
||||
for (k = 0; k < 9; k++) {
|
||||
Equipment[k].material = emu->equipment[k].material;
|
||||
Equipment[k].unknown1 = emu->equipment[k].unknown1;
|
||||
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
|
||||
Equipment[k].heroforgemodel = emu->equipment[k].heroforgemodel;
|
||||
Equipment[k].material2 = emu->equipment[k].material2;
|
||||
Equipment[k].Material = emu->equipment[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
|
||||
Equipment[k].HeroForgeModel = emu->equipment[k].HeroForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment[k].Material2;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::EquipStruct) * 9);
|
||||
@@ -4058,13 +4169,13 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
@@ -4200,7 +4311,6 @@ namespace RoF2
|
||||
return;
|
||||
|
||||
SETUP_DIRECT_DECODE(NewBazaarInspect_Struct, structs::NewBazaarInspect_Struct);
|
||||
MEMSET_IN(structs::NewBazaarInspect_Struct);
|
||||
|
||||
IN(Beginning.Action);
|
||||
memcpy(emu->Name, eq->Name, sizeof(emu->Name));
|
||||
@@ -4897,7 +5007,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::ClickTrader_Struct);
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
MEMSET_IN(ClickTrader_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
@@ -4913,7 +5022,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
MEMSET_IN(Trader_ShowItems_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
emu->TraderID = eq->TraderID;
|
||||
@@ -4924,9 +5032,8 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderStatus_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderStatus_Struct, structs::TraderStatus_Struct);
|
||||
MEMSET_IN(TraderStatus_Struct);
|
||||
|
||||
emu->Code = eq->Code;
|
||||
emu->Code = eq->Code; // 11 = Start Trader, 2 = End Trader, 22 = ? - Guessing
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -4936,7 +5043,6 @@ namespace RoF2
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
@@ -4948,6 +5054,65 @@ namespace RoF2
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderShop)
|
||||
{
|
||||
uint32 psize = __packet->size;
|
||||
if (psize == sizeof(structs::TraderClick_Struct))
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
|
||||
IN(Code);
|
||||
IN(TraderID);
|
||||
IN(Approval);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderClick_Struct Code %d, TraderID %d, Approval %d",
|
||||
eq->Code, eq->TraderID, eq->Approval);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
else if (psize == sizeof(structs::BazaarWelcome_Struct))
|
||||
{
|
||||
// Don't think this size gets used in RoF+ - Leaving for now...
|
||||
DECODE_LENGTH_EXACT(structs::BazaarWelcome_Struct);
|
||||
SETUP_DIRECT_DECODE(BazaarWelcome_Struct, structs::BazaarWelcome_Struct);
|
||||
|
||||
emu->Beginning.Action = eq->Code;
|
||||
IN(Traders);
|
||||
IN(Items);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||
eq->Code, eq->Traders, eq->Items);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
else if (psize == sizeof(structs::TraderBuy_Struct))
|
||||
{
|
||||
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct (Unknowns) Unknown004 %d, Unknown008 %d, Unknown012 %d, Unknown076 %d, Unknown276 %d",
|
||||
eq->Unknown004, eq->Unknown008, eq->Unknown012, eq->Unknown076, eq->Unknown276);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, eq->ItemName);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
else if (psize == 4)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Forwarding packet as-is with size 4");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Decode Size Unknown (%d)", psize);
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_TradeSkillCombine)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::NewCombine_Struct);
|
||||
@@ -4958,7 +5123,7 @@ namespace RoF2
|
||||
slot_id = legacy::SLOT_TRADESKILL; // 1000
|
||||
}
|
||||
emu->container_slot = slot_id;
|
||||
emu->guildtribute_slot = RoF2ToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented -U
|
||||
emu->guildtribute_slot = RoF2ToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -4993,6 +5158,16 @@ namespace RoF2
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_VetClaimRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::VeteranClaim);
|
||||
SETUP_DIRECT_DECODE(VeteranClaim, structs::VeteranClaim);
|
||||
|
||||
IN(claim_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ZoneChange)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::ZoneChange_Struct);
|
||||
@@ -5053,7 +5228,7 @@ namespace RoF2
|
||||
|
||||
//sprintf(hdr.unknown000, "06e0002Y1W00");
|
||||
|
||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%012d", item->ID);
|
||||
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
|
||||
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
hdr.unknown004 = 0;
|
||||
@@ -5464,10 +5639,10 @@ namespace RoF2
|
||||
RoF2::structs::WornEffectStruct ibes;
|
||||
memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
ibes.effect = 0xffffffff;
|
||||
ibes.level2 = 0;
|
||||
ibes.type = 0;
|
||||
ibes.level = 0;
|
||||
ibes.effect = item->Bard.Effect;
|
||||
ibes.level2 = item->Bard.Level2;
|
||||
ibes.type = item->Bard.Type;
|
||||
ibes.level = item->Bard.Level;
|
||||
//ibes.unknown6 = 0xffffffff;
|
||||
|
||||
ss.write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
|
||||
|
||||
@@ -103,6 +103,8 @@ namespace RoF2 {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 24;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -178,9 +180,10 @@ namespace RoF2 {
|
||||
static const uint16 ITEM_COMMON_SIZE = 6;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
// Begin RoF2 Encodes
|
||||
|
||||
E(OP_SendMembershipDetails)
|
||||
E(OP_TraderShop)
|
||||
E(OP_TraderDelItem)
|
||||
|
||||
// incoming packets that require a DECODE translation:
|
||||
// Begin RoF2 Decodes
|
||||
|
||||
D(OP_TraderShop)
|
||||
|
||||
// End RoF2 Encodes/Decodes
|
||||
|
||||
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
|
||||
@@ -107,6 +111,7 @@ E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeInfo)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetClaimReply)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_WhoAllResponse)
|
||||
@@ -170,6 +175,7 @@ D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_VetClaimRequest)
|
||||
D(OP_WhoAllRequest)
|
||||
D(OP_ZoneChange)
|
||||
D(OP_ZoneEntry)
|
||||
|
||||
+216
-145
@@ -97,11 +97,6 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_TRIBUTE_TIERS = 10;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 20;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
|
||||
static const uint32 MAX_POTIONS_IN_BELT = 5;
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
@@ -114,7 +109,7 @@ static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
|
||||
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300;
|
||||
static const uint32 MAX_PP_DISCIPLINES = 200; // was 100
|
||||
static const uint32 MAX_PP_DISCIPLINES = 300; // was 200
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
static const uint32 MAX_RECAST_TYPES = 20;
|
||||
|
||||
@@ -147,84 +142,87 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
/*12*/ uint32 heroforgemodel;
|
||||
/*16*/ uint32 material2; // Same as material?
|
||||
/*20*/
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
uint32 HeroForgeModel;
|
||||
uint32 Material2;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
uint32 heroforgemodel;
|
||||
uint32 material2;
|
||||
Color_Struct color;
|
||||
};
|
||||
|
||||
struct CharacterSelectEntry_Struct {
|
||||
/*0000*/ char name[1]; // Name null terminated
|
||||
/*0000*/ uint8 class_;
|
||||
/*0000*/ uint32 race;
|
||||
/*0000*/ uint8 level;
|
||||
/*0000*/ uint8 class_2;
|
||||
/*0000*/ uint32 race2;
|
||||
/*0000*/ uint16 zone;
|
||||
/*0000*/ uint16 instance;
|
||||
/*0000*/ uint8 gender;
|
||||
/*0000*/ uint8 face;
|
||||
/*0000*/ CharSelectEquip equip[9];
|
||||
/*0000*/ uint8 u15; // Seen FF
|
||||
/*0000*/ uint8 u19; // Seen FF
|
||||
/*0000*/ uint32 drakkin_tattoo;
|
||||
/*0000*/ uint32 drakkin_details;
|
||||
/*0000*/ uint32 deity;
|
||||
/*0000*/ uint32 primary;
|
||||
/*0000*/ uint32 secondary;
|
||||
/*0000*/ uint8 haircolor;
|
||||
/*0000*/ uint8 beardcolor;
|
||||
/*0000*/ uint8 eyecolor1;
|
||||
/*0000*/ uint8 eyecolor2;
|
||||
/*0000*/ uint8 hairstyle;
|
||||
/*0000*/ uint8 beard;
|
||||
/*0000*/ uint8 char_enabled;
|
||||
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
|
||||
/*0000*/ uint32 drakkin_heritage;
|
||||
/*0000*/ uint8 unknown1; // Seen 0
|
||||
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
/*0000*/ char Name[1]; // Name null terminated
|
||||
/*0000*/ uint8 Class;
|
||||
/*0000*/ uint32 Race;
|
||||
/*0000*/ uint8 Level;
|
||||
/*0000*/ uint8 ShroudClass;
|
||||
/*0000*/ uint32 ShroudRace;
|
||||
/*0000*/ uint16 Zone;
|
||||
/*0000*/ uint16 Instance;
|
||||
/*0000*/ uint8 Gender;
|
||||
/*0000*/ uint8 Face;
|
||||
/*0000*/ CharSelectEquip Equip[9];
|
||||
/*0000*/ uint8 Unknown15; // Seen FF
|
||||
/*0000*/ uint8 Unknown19; // Seen FF
|
||||
/*0000*/ uint32 DrakkinTattoo;
|
||||
/*0000*/ uint32 DrakkinDetails;
|
||||
/*0000*/ uint32 Deity;
|
||||
/*0000*/ uint32 PrimaryIDFile;
|
||||
/*0000*/ uint32 SecondaryIDFile;
|
||||
/*0000*/ uint8 HairColor;
|
||||
/*0000*/ uint8 BeardColor;
|
||||
/*0000*/ uint8 EyeColor1;
|
||||
/*0000*/ uint8 EyeColor2;
|
||||
/*0000*/ uint8 HairStyle;
|
||||
/*0000*/ uint8 Beard;
|
||||
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
|
||||
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
|
||||
/*0000*/ uint32 DrakkinHeritage;
|
||||
/*0000*/ uint8 Unknown1; // Seen 0
|
||||
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
|
||||
/*0000*/ uint32 LastLogin;
|
||||
/*0000*/ uint8 unknown2; // Seen 0
|
||||
/*0000*/ uint8 Unknown2; // Seen 0
|
||||
};
|
||||
|
||||
/*
|
||||
** Character Selection Struct
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*000*/ uint32 char_count; //number of chars in this packet
|
||||
/*004*/ CharacterSelectEntry_Struct entries[0];
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*000*/ uint32 CharCount; //number of chars in this packet
|
||||
/*004*/ CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct EquipStruct
|
||||
{
|
||||
/*00*/ uint32 Material;
|
||||
/*04*/ uint32 Unknown1;
|
||||
/*08*/ uint32 EliteMaterial;
|
||||
/*12*/ uint32 HeroForgeModel;
|
||||
/*16*/ uint32 Material2; // Same as material?
|
||||
/*20*/
|
||||
};
|
||||
|
||||
|
||||
struct Membership_Entry_Struct
|
||||
{
|
||||
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
|
||||
@@ -896,38 +894,66 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
struct BandolierItem_Struct {
|
||||
char item_name[1]; // Variable Length
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct_Old {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[1]; // Variable Length
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
};
|
||||
|
||||
struct Bandolier_Struct_Old {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
//len = 72
|
||||
struct BandolierItem_Struct_Old
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct Bandolier_Struct_Old
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct_Old
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct_Old
|
||||
{
|
||||
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct GroupLeadershipAA_Struct {
|
||||
@@ -1137,7 +1163,7 @@ union
|
||||
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
|
||||
/*12953*/ uint16 unknown_rof20; //
|
||||
/*12955*/ uint32 bandolier_count; // Seen 20
|
||||
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
|
||||
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
|
||||
/*13699*/ uint32 potionbelt_count; // Seen 5
|
||||
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
|
||||
/*13748*/ int32 unknown_rof21; // Seen -1
|
||||
@@ -2865,7 +2891,7 @@ struct SetRunMode_Struct {
|
||||
};
|
||||
|
||||
// EnvDamage is EnvDamage2 without a few bytes at the end.
|
||||
// Size: 37 bytes
|
||||
// Size: 39 bytes
|
||||
struct EnvDamage2_Struct {
|
||||
/*0000*/ uint32 id;
|
||||
/*0004*/ uint16 unknown4;
|
||||
@@ -2877,7 +2903,8 @@ struct EnvDamage2_Struct {
|
||||
/*0031*/ uint16 unknown31; // New to Underfoot - Seen 66
|
||||
/*0033*/ uint16 constant; // Always FFFF
|
||||
/*0035*/ uint16 unknown35;
|
||||
/*0037*/
|
||||
/*0037*/ uint16 unknown37;
|
||||
/*0039*/
|
||||
};
|
||||
|
||||
//Bazaar Stuff
|
||||
@@ -2913,10 +2940,12 @@ struct BazaarWindowStart_Struct {
|
||||
|
||||
|
||||
struct BazaarWelcome_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint8 Unknown012[8];
|
||||
uint32 Code;
|
||||
uint32 EntityID;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint32 Traders2;
|
||||
uint32 Items2;
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
@@ -3199,6 +3228,13 @@ struct BecomeTrader_Struct {
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint16 TraderID;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct_WIP {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ char SerialNumber[17];
|
||||
/*021*/ uint8 Unknown21;
|
||||
@@ -3216,6 +3252,26 @@ struct TraderStatus_Struct {
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Unknown012;
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char BuyerName[64];
|
||||
/*084*/ char SellerName[64];
|
||||
/*148*/ char Unknown148[32];
|
||||
/*180*/ char ItemName[64];
|
||||
/*244*/ char SerialNumber[16];
|
||||
/*260*/ uint32 Unknown076;
|
||||
/*264*/ uint32 ItemID;
|
||||
/*268*/ uint32 Price;
|
||||
/*272*/ uint32 AlreadySold;
|
||||
/*276*/ uint32 Unknown276;
|
||||
/*280*/ uint32 Quantity;
|
||||
/*284*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct_OLD {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Price;
|
||||
@@ -3245,25 +3301,19 @@ struct MoneyUpdate_Struct{
|
||||
int32 copper;
|
||||
};
|
||||
|
||||
//struct MoneyUpdate_Struct
|
||||
//{
|
||||
//*0000*/ uint32 spawn_id; // ***Placeholder
|
||||
//*0004*/ uint32 cointype; // Coin Type
|
||||
//*0008*/ uint32 amount; // Amount
|
||||
//*0012*/
|
||||
//};
|
||||
|
||||
|
||||
struct TraderDelItem_Struct{
|
||||
uint32 slotid;
|
||||
uint32 quantity;
|
||||
uint32 unknown;
|
||||
/*000*/ uint32 Unknown000;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ char SerialNumber[16];
|
||||
/*024*/ uint32 Unknown012;
|
||||
/*028*/
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 approval;
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Approval;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
@@ -3566,7 +3616,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ ItemSlotStruct container_slot;
|
||||
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
|
||||
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
|
||||
/*24*/
|
||||
};
|
||||
|
||||
@@ -4087,30 +4137,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
@@ -4352,7 +4407,7 @@ struct RoF2SlotStruct
|
||||
|
||||
struct ItemSerializationHeader
|
||||
{
|
||||
/*000*/ char unknown000[13]; // New for HoT. Looks like a string.
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
@@ -4497,7 +4552,7 @@ struct ItemSecondaryBodyStruct
|
||||
uint32 augtype;
|
||||
// swapped augrestrict and augdistiller positions
|
||||
// (this swap does show the proper augment restrictions in Item Information window now)
|
||||
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
|
||||
// unsure what the purpose of augdistiller is at this time 3/17/2014
|
||||
int32 augrestrict2; // New to December 10th 2012 client - Hidden Aug Restriction
|
||||
uint32 augrestrict;
|
||||
AugSlotStruct augslots[6];
|
||||
@@ -4672,17 +4727,33 @@ struct AugmentInfo_Struct
|
||||
|
||||
struct VeteranRewardItem
|
||||
{
|
||||
/*000*/ uint32 item_id;
|
||||
/*004*/ uint32 charges;
|
||||
/*008*/ char item_name[64];
|
||||
/*000*/ uint32 name_length;
|
||||
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
|
||||
/*???*/ uint32 item_id;
|
||||
/*???*/ uint32 charges;
|
||||
};
|
||||
|
||||
struct VeteranRewardEntry
|
||||
{
|
||||
/*000*/ uint32 claim_id; // guessed
|
||||
/*004*/ uint32 avaliable_count;
|
||||
/*008*/ uint32 claim_count;
|
||||
/*012*/ char enabled;
|
||||
/*013*/ //VeteranRewardItem items[0];
|
||||
};
|
||||
|
||||
struct VeteranReward
|
||||
{
|
||||
/*000*/ uint32 claim_id;
|
||||
/*004*/ uint32 number_available;
|
||||
/*008*/ uint32 claim_count;
|
||||
/*012*/ VeteranRewardItem items[8];
|
||||
/*000*/ uint32 claim_count;
|
||||
/*004*/ //VeteranRewardEntry entries[0];
|
||||
};
|
||||
|
||||
struct VeteranClaim
|
||||
{
|
||||
/*000*/ char name[68]; //name + other data
|
||||
/*068*/ uint32 claim_id;
|
||||
/*072*/ uint32 unknown072;
|
||||
/*076*/ uint32 action;
|
||||
};
|
||||
|
||||
struct ExpeditionEntryHeader_Struct
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace RoF {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 24;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -177,9 +179,10 @@ namespace RoF {
|
||||
static const uint16 ITEM_COMMON_SIZE = 6;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 55;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeInfo)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetClaimReply)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_WhoAllResponse)
|
||||
@@ -159,6 +160,7 @@ D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_VetClaimRequest)
|
||||
D(OP_WhoAllRequest)
|
||||
D(OP_ZoneChange)
|
||||
D(OP_ZoneEntry)
|
||||
|
||||
+170
-124
@@ -97,11 +97,6 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_TRIBUTE_TIERS = 10;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 20;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
|
||||
static const uint32 MAX_POTIONS_IN_BELT = 5;
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
@@ -147,71 +142,87 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
uint32 heroforgemodel;
|
||||
uint32 material2;
|
||||
Color_Struct color;
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
uint32 HeroForgeModel;
|
||||
uint32 Material2;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
struct CharacterSelectEntry_Struct {
|
||||
/*0000*/ char name[1]; // Name null terminated
|
||||
/*0000*/ uint8 class_;
|
||||
/*0000*/ uint32 race;
|
||||
/*0000*/ uint8 level;
|
||||
/*0000*/ uint8 class_2;
|
||||
/*0000*/ uint32 race2;
|
||||
/*0000*/ uint16 zone;
|
||||
/*0000*/ uint16 instance;
|
||||
/*0000*/ uint8 gender;
|
||||
/*0000*/ uint8 face;
|
||||
/*0000*/ CharSelectEquip equip[9];
|
||||
/*0000*/ uint8 u15; // Seen FF
|
||||
/*0000*/ uint8 u19; // Seen FF
|
||||
/*0000*/ uint32 drakkin_tattoo;
|
||||
/*0000*/ uint32 drakkin_details;
|
||||
/*0000*/ uint32 deity;
|
||||
/*0000*/ uint32 primary;
|
||||
/*0000*/ uint32 secondary;
|
||||
/*0000*/ uint8 haircolor;
|
||||
/*0000*/ uint8 beardcolor;
|
||||
/*0000*/ uint8 eyecolor1;
|
||||
/*0000*/ uint8 eyecolor2;
|
||||
/*0000*/ uint8 hairstyle;
|
||||
/*0000*/ uint8 beard;
|
||||
/*0000*/ uint8 char_enabled;
|
||||
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
|
||||
/*0000*/ uint32 drakkin_heritage;
|
||||
/*0000*/ uint8 unknown1; // Seen 0
|
||||
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
/*0000*/ char Name[1]; // Name null terminated
|
||||
/*0000*/ uint8 Class;
|
||||
/*0000*/ uint32 Race;
|
||||
/*0000*/ uint8 Level;
|
||||
/*0000*/ uint8 ShroudClass;
|
||||
/*0000*/ uint32 ShroudRace;
|
||||
/*0000*/ uint16 Zone;
|
||||
/*0000*/ uint16 Instance;
|
||||
/*0000*/ uint8 Gender;
|
||||
/*0000*/ uint8 Face;
|
||||
/*0000*/ CharSelectEquip Equip[9];
|
||||
/*0000*/ uint8 Unknown15; // Seen FF
|
||||
/*0000*/ uint8 Unknown19; // Seen FF
|
||||
/*0000*/ uint32 DrakkinTattoo;
|
||||
/*0000*/ uint32 DrakkinDetails;
|
||||
/*0000*/ uint32 Deity;
|
||||
/*0000*/ uint32 PrimaryIDFile;
|
||||
/*0000*/ uint32 SecondaryIDFile;
|
||||
/*0000*/ uint8 HairColor;
|
||||
/*0000*/ uint8 BeardColor;
|
||||
/*0000*/ uint8 EyeColor1;
|
||||
/*0000*/ uint8 EyeColor2;
|
||||
/*0000*/ uint8 HairStyle;
|
||||
/*0000*/ uint8 Beard;
|
||||
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
|
||||
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
|
||||
/*0000*/ uint32 DrakkinHeritage;
|
||||
/*0000*/ uint8 Unknown1; // Seen 0
|
||||
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
|
||||
/*0000*/ uint32 LastLogin;
|
||||
/*0000*/ uint8 unknown2; // Seen 0
|
||||
/*0000*/ uint8 Unknown2; // Seen 0
|
||||
};
|
||||
|
||||
/*
|
||||
** Character Selection Struct
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*000*/ uint32 char_count; //number of chars in this packet
|
||||
/*004*/ CharacterSelectEntry_Struct entries[0];
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*000*/ uint32 CharCount; //number of chars in this packet
|
||||
/*004*/ CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct EquipStruct
|
||||
{
|
||||
/*00*/ uint32 Material;
|
||||
/*04*/ uint32 Unknown1;
|
||||
/*08*/ uint32 EliteMaterial;
|
||||
/*12*/ uint32 HeroForgeModel;
|
||||
/*16*/ uint32 Material2; // Same as material?
|
||||
/*20*/
|
||||
};
|
||||
|
||||
|
||||
struct Membership_Entry_Struct
|
||||
{
|
||||
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
|
||||
@@ -252,20 +263,6 @@ struct Membership_Struct
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
/*12*/ uint32 heroforgemodel;
|
||||
/*16*/ uint32 material2; // Same as material?
|
||||
/*20*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Generic Spawn Struct
|
||||
** Length: 897 Octets
|
||||
@@ -880,38 +877,66 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
struct BandolierItem_Struct {
|
||||
char item_name[1]; // Variable Length
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct_Old {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[1]; // Variable Length
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
};
|
||||
|
||||
struct Bandolier_Struct_Old {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
//len = 72
|
||||
struct BandolierItem_Struct_Old
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct Bandolier_Struct_Old
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
char Name[1]; // Variable Length
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct_Old
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct PotionBelt_Struct_Old
|
||||
{
|
||||
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct GroupLeadershipAA_Struct {
|
||||
@@ -1121,7 +1146,7 @@ union
|
||||
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
|
||||
/*12953*/ uint16 unknown_rof20; //
|
||||
/*12955*/ uint32 bandolier_count; // Seen 20
|
||||
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
|
||||
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
|
||||
/*13699*/ uint32 potionbelt_count; // Seen 5
|
||||
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
|
||||
/*13748*/ int32 unknown_rof21; // Seen -1
|
||||
@@ -3592,7 +3617,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ ItemSlotStruct container_slot;
|
||||
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
|
||||
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
|
||||
/*24*/
|
||||
};
|
||||
|
||||
@@ -4113,30 +4138,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
@@ -4378,7 +4408,7 @@ struct RoFSlotStruct
|
||||
|
||||
struct ItemSerializationHeader
|
||||
{
|
||||
/*000*/ char unknown000[13]; // New for HoT. Looks like a string.
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
@@ -4524,7 +4554,7 @@ struct ItemSecondaryBodyStruct
|
||||
uint32 augtype;
|
||||
// swapped augrestrict and augdistiller positions
|
||||
// (this swap does show the proper augment restrictions in Item Information window now)
|
||||
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
|
||||
// unsure what the purpose of augdistiller is at this time 3/17/2014
|
||||
uint32 augdistiller; // New to December 10th 2012 client - NEW
|
||||
uint32 augrestrict;
|
||||
AugSlotStruct augslots[6];
|
||||
@@ -4688,17 +4718,33 @@ struct AugmentInfo_Struct
|
||||
|
||||
struct VeteranRewardItem
|
||||
{
|
||||
/*000*/ uint32 item_id;
|
||||
/*004*/ uint32 charges;
|
||||
/*008*/ char item_name[64];
|
||||
/*000*/ uint32 name_length;
|
||||
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
|
||||
/*???*/ uint32 item_id;
|
||||
/*???*/ uint32 charges;
|
||||
};
|
||||
|
||||
struct VeteranRewardEntry
|
||||
{
|
||||
/*000*/ uint32 claim_id; // guessed
|
||||
/*004*/ uint32 avaliable_count;
|
||||
/*008*/ uint32 claim_count;
|
||||
/*012*/ char enabled;
|
||||
/*013*/ //VeteranRewardItem items[0];
|
||||
};
|
||||
|
||||
struct VeteranReward
|
||||
{
|
||||
/*000*/ uint32 claim_id;
|
||||
/*004*/ uint32 number_available;
|
||||
/*008*/ uint32 claim_count;
|
||||
/*012*/ VeteranRewardItem items[8];
|
||||
/*000*/ uint32 claim_count;
|
||||
/*004*/ //VeteranRewardEntry entries[0];
|
||||
};
|
||||
|
||||
struct VeteranClaim
|
||||
{
|
||||
/*000*/ char name[68]; //name + other data
|
||||
/*068*/ uint32 claim_id;
|
||||
/*072*/ uint32 unknown072;
|
||||
/*076*/ uint32 action;
|
||||
};
|
||||
|
||||
struct ExpeditionEntryHeader_Struct
|
||||
|
||||
+139
-119
@@ -1542,13 +1542,13 @@ namespace SoD
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = 0; r < 9; r++) {
|
||||
eq->equipment[r].material = emu->item_material[r];
|
||||
eq->equipment[r].unknown1 = 0;
|
||||
eq->equipment[r].elitematerial = 0;
|
||||
eq->equipment[r].Material = emu->item_material[r];
|
||||
eq->equipment[r].Unknown1 = 0;
|
||||
eq->equipment[r].EliteMaterial = 0;
|
||||
//eq->colors[r].color = emu->colors[r].color;
|
||||
}
|
||||
for (r = 0; r < 7; r++) {
|
||||
OUT(item_tint[r].color);
|
||||
OUT(item_tint[r].Color);
|
||||
}
|
||||
// OUT(unknown00224[48]);
|
||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||
@@ -1606,26 +1606,46 @@ namespace SoD
|
||||
OUT(endurance);
|
||||
OUT(aapoints_spent);
|
||||
OUT(aapoints);
|
||||
|
||||
// OUT(unknown06160[4]);
|
||||
//NOTE: new client supports 20 bandoliers, our internal rep
|
||||
//only supports 4..
|
||||
for (r = 0; r < 4; r++) {
|
||||
OUT_str(bandoliers[r].name);
|
||||
uint32 k;
|
||||
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
|
||||
OUT(bandoliers[r].items[k].item_id);
|
||||
OUT(bandoliers[r].items[k].icon);
|
||||
OUT_str(bandoliers[r].items[k].item_name);
|
||||
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
OUT_str(bandoliers[r].Name);
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
OUT(bandoliers[r].Items[k].ID);
|
||||
OUT(bandoliers[r].Items[k].Icon);
|
||||
OUT_str(bandoliers[r].Items[k].Name);
|
||||
}
|
||||
}
|
||||
// OUT(unknown07444[5120]);
|
||||
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
|
||||
OUT(potionbelt.items[r].item_id);
|
||||
OUT(potionbelt.items[r].icon);
|
||||
OUT_str(potionbelt.items[r].item_name);
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
eq->bandoliers[r].Name[0] = '\0';
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
eq->bandoliers[r].Items[k].ID = 0;
|
||||
eq->bandoliers[r].Items[k].Icon = 0;
|
||||
eq->bandoliers[r].Items[k].Name[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// OUT(unknown07444[5120]);
|
||||
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
OUT(potionbelt.Items[r].ID);
|
||||
OUT(potionbelt.Items[r].Icon);
|
||||
OUT_str(potionbelt.Items[r].Name);
|
||||
}
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
eq->potionbelt.Items[r].ID = 0;
|
||||
eq->potionbelt.Items[r].Icon = 0;
|
||||
eq->potionbelt.Items[r].Name[0] = '\0';
|
||||
}
|
||||
|
||||
// OUT(unknown12852[8]);
|
||||
// OUT(unknown12864[76]);
|
||||
|
||||
OUT_str(name);
|
||||
OUT_str(last_name);
|
||||
OUT(guild_id);
|
||||
@@ -1891,76 +1911,95 @@ namespace SoD
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_VAR_ENCODE(CharacterSelect_Struct);
|
||||
|
||||
//EQApplicationPacket *packet = *p;
|
||||
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
|
||||
// Zero-character count shunt
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
int char_count;
|
||||
int namelen = 0;
|
||||
for (char_count = 0; char_count < 10; char_count++) {
|
||||
if (emu->name[char_count][0] == '\0')
|
||||
break;
|
||||
if (strcmp(emu->name[char_count], "<none>") == 0)
|
||||
break;
|
||||
namelen += strlen(emu->name[char_count]);
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
FINISH_ENCODE();
|
||||
return;
|
||||
}
|
||||
|
||||
int total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ namelen;
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
size_t names_length = 0;
|
||||
size_t character_count = 0;
|
||||
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
names_length += strlen(emu_cse->Name);
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
size_t total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ names_length;
|
||||
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
|
||||
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
//unsigned char *eq_buffer = new unsigned char[total_length];
|
||||
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
|
||||
eq->CharCount = character_count;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
eq->char_count = char_count;
|
||||
eq->total_chars = 10;
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
unsigned char *bufptr = (unsigned char *)eq->entries;
|
||||
int r;
|
||||
for (r = 0; r < char_count; r++) {
|
||||
{ //pre-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->level = emu->level[r];
|
||||
eq2->hairstyle = emu->hairstyle[r];
|
||||
eq2->gender = emu->gender[r];
|
||||
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
|
||||
emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
|
||||
unsigned char *eq_ptr = __packet->pBuffer;
|
||||
eq_ptr += sizeof(structs::CharacterSelect_Struct);
|
||||
|
||||
for (int counter = 0; counter < character_count; ++counter) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Level = emu_cse->Level;
|
||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
|
||||
strcpy(eq_cse->Name, emu_cse->Name);
|
||||
eq_ptr += strlen(eq_cse->Name);
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Beard = emu_cse->Beard;
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
|
||||
}
|
||||
//adjust for name.
|
||||
bufptr += strlen(emu->name[r]);
|
||||
{ //post-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->beard = emu->beard[r];
|
||||
eq2->haircolor = emu->haircolor[r];
|
||||
eq2->face = emu->face[r];
|
||||
int k;
|
||||
for (k = 0; k < _MaterialCount; k++) {
|
||||
eq2->equip[k].material = emu->equip[r][k].material;
|
||||
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
|
||||
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
|
||||
eq2->equip[k].color.color = emu->equip[r][k].color.color;
|
||||
}
|
||||
eq2->primary = emu->primary[r];
|
||||
eq2->secondary = emu->secondary[r];
|
||||
eq2->tutorial = emu->tutorial[r]; // was u15
|
||||
eq2->u15 = 0xff;
|
||||
eq2->deity = emu->deity[r];
|
||||
eq2->zone = emu->zone[r];
|
||||
eq2->u19 = 0xFF;
|
||||
eq2->race = emu->race[r];
|
||||
eq2->gohome = emu->gohome[r];
|
||||
eq2->class_ = emu->class_[r];
|
||||
eq2->eyecolor1 = emu->eyecolor1[r];
|
||||
eq2->beardcolor = emu->beardcolor[r];
|
||||
eq2->eyecolor2 = emu->eyecolor2[r];
|
||||
eq2->drakkin_heritage = emu->drakkin_heritage[r];
|
||||
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
|
||||
eq2->drakkin_details = emu->drakkin_details[r];
|
||||
}
|
||||
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
|
||||
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
|
||||
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
|
||||
eq_cse->Tutorial = emu_cse->Tutorial;
|
||||
eq_cse->Unknown15 = emu_cse->Unknown15;
|
||||
eq_cse->Deity = emu_cse->Deity;
|
||||
eq_cse->Zone = emu_cse->Zone;
|
||||
eq_cse->Unknown19 = emu_cse->Unknown19;
|
||||
eq_cse->Race = emu_cse->Race;
|
||||
eq_cse->GoHome = emu_cse->GoHome;
|
||||
eq_cse->Class = emu_cse->Class;
|
||||
eq_cse->EyeColor1 = emu_cse->EyeColor1;
|
||||
eq_cse->BeardColor = emu_cse->BeardColor;
|
||||
eq_cse->EyeColor2 = emu_cse->EyeColor2;
|
||||
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
|
||||
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
|
||||
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2355,7 +2394,7 @@ namespace SoD
|
||||
OUT(material);
|
||||
OUT(unknown06);
|
||||
OUT(elite_material);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2427,42 +2466,23 @@ namespace SoD
|
||||
|
||||
ENCODE(OP_ZonePlayerToBind)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
|
||||
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
|
||||
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
|
||||
|
||||
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
|
||||
__packet->SetWritePosition(0);
|
||||
__packet->WriteUInt16(emu->bind_zone_id);
|
||||
__packet->WriteUInt16(emu->bind_instance_id);
|
||||
__packet->WriteFloat(emu->x);
|
||||
__packet->WriteFloat(emu->y);
|
||||
__packet->WriteFloat(emu->z);
|
||||
__packet->WriteFloat(emu->heading);
|
||||
__packet->WriteString(emu->zone_name);
|
||||
__packet->WriteUInt8(1); // save items
|
||||
__packet->WriteUInt32(0); // hp
|
||||
__packet->WriteUInt32(0); // mana
|
||||
__packet->WriteUInt32(0); // endurance
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
|
||||
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
|
||||
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
|
||||
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
|
||||
|
||||
zph->x = zps->x;
|
||||
zph->y = zps->y;
|
||||
zph->z = zps->z;
|
||||
zph->heading = zps->heading;
|
||||
zph->bind_zone_id = zps->bind_zone_id;
|
||||
zph->bind_instance_id = zps->bind_instance_id;
|
||||
strcpy(zph->zone_name, zps->zone_name);
|
||||
|
||||
zpf->unknown021 = 1;
|
||||
zpf->unknown022 = 0;
|
||||
zpf->unknown023 = 0;
|
||||
zpf->unknown024 = 0;
|
||||
|
||||
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
|
||||
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
|
||||
|
||||
delete[] buffer1;
|
||||
delete[] buffer2;
|
||||
delete[](*p)->pBuffer;
|
||||
|
||||
(*p)->pBuffer = new unsigned char[ss.str().size()];
|
||||
(*p)->size = ss.str().size();
|
||||
|
||||
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
|
||||
dest->FastQueuePacket(&(*p));
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ZoneServerInfo)
|
||||
@@ -2742,7 +2762,7 @@ namespace SoD
|
||||
for (k = 0; k < 9; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2752,11 +2772,11 @@ namespace SoD
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
}
|
||||
@@ -2767,9 +2787,9 @@ namespace SoD
|
||||
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
|
||||
|
||||
for (k = 0; k < 9; k++) {
|
||||
Equipment[k].material = emu->equipment[k].material;
|
||||
Equipment[k].unknown1 = emu->equipment[k].unknown1;
|
||||
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
|
||||
Equipment[k].Material = emu->equipment[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::EquipStruct) * 9);
|
||||
@@ -3484,7 +3504,7 @@ namespace SoD
|
||||
IN(material);
|
||||
IN(unknown06);
|
||||
IN(elite_material);
|
||||
IN(color.color);
|
||||
IN(color.Color);
|
||||
IN(wear_slot_id);
|
||||
emu->hero_forge_model = 0;
|
||||
emu->unknown18 = 0;
|
||||
|
||||
@@ -101,6 +101,8 @@ namespace SoD {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 24;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -174,9 +176,10 @@ namespace SoD {
|
||||
static const uint16 ITEM_COMMON_SIZE = 5;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 10;
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
+111
-92
@@ -103,54 +103,53 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
//totally guessed;
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
Color_Struct color;
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
struct CharacterSelectEntry_Struct {
|
||||
/*0000*/ uint8 level; //
|
||||
/*0000*/ uint8 hairstyle; //
|
||||
/*0002*/ uint8 gender; //
|
||||
/*0003*/ char name[1]; //variable length, edi+0
|
||||
/*0000*/ uint8 beard; //
|
||||
/*0001*/ uint8 haircolor; //
|
||||
/*0000*/ uint8 face; //
|
||||
/*0000*/ CharSelectEquip equip[9];
|
||||
/*0000*/ uint32 primary; //
|
||||
/*0000*/ uint32 secondary; //
|
||||
/*0000*/ uint8 u15; // 0xff
|
||||
/*0000*/ uint32 deity; //
|
||||
/*0000*/ uint16 zone; //
|
||||
/*0000*/ uint16 instance;
|
||||
/*0000*/ uint8 gohome; //
|
||||
/*0000*/ uint8 u19; // 0xff
|
||||
/*0000*/ uint32 race; //
|
||||
/*0000*/ uint8 tutorial; //
|
||||
/*0000*/ uint8 class_; //
|
||||
/*0000*/ uint8 eyecolor1; //
|
||||
/*0000*/ uint8 beardcolor; //
|
||||
/*0000*/ uint8 eyecolor2; //
|
||||
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
|
||||
/*0000*/ uint8 unknown; // New field to SoD
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
/*0000*/ uint8 Level; //
|
||||
/*0000*/ uint8 HairStyle; //
|
||||
/*0002*/ uint8 Gender; //
|
||||
/*0003*/ char Name[1]; // variable length, edi+0
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[9];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
/*0000*/ uint32 Deity; //
|
||||
/*0000*/ uint16 Zone; //
|
||||
/*0000*/ uint16 Instance;
|
||||
/*0000*/ uint8 GoHome; //
|
||||
/*0000*/ uint8 Unknown19; // 0xff
|
||||
/*0000*/ uint32 Race; //
|
||||
/*0000*/ uint8 Tutorial; //
|
||||
/*0000*/ uint8 Class; //
|
||||
/*0000*/ uint8 EyeColor1; //
|
||||
/*0000*/ uint8 BeardColor; //
|
||||
/*0000*/ uint8 EyeColor2; //
|
||||
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
|
||||
/*0000*/ uint8 Unknown; // New field to SoD
|
||||
|
||||
};
|
||||
|
||||
@@ -158,20 +157,22 @@ struct CharacterSelectEntry_Struct {
|
||||
** Character Selection Struct
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*0000*/ uint32 char_count; //number of chars in this packet
|
||||
/*0004*/ uint32 total_chars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct entries[0];
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*0000*/ uint32 CharCount; //number of chars in this packet
|
||||
/*0004*/ uint32 TotalChars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 12 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
struct EquipStruct
|
||||
{
|
||||
/*00*/ uint32 Material;
|
||||
/*04*/ uint32 Unknown1;
|
||||
/*08*/ uint32 EliteMaterial;
|
||||
/*12*/
|
||||
};
|
||||
|
||||
@@ -676,9 +677,6 @@ struct Disciplines_Struct {
|
||||
};
|
||||
|
||||
static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 20;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
static const uint32 MAX_POTIONS_IN_BELT = 5;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
|
||||
struct Tribute_Struct {
|
||||
@@ -686,26 +684,42 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
@@ -925,7 +939,7 @@ struct PlayerProfile_Struct
|
||||
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
|
||||
/*08292*/ uint32 aapoints; // Unspent AA points
|
||||
/*08296*/ uint8 unknown06160[4];
|
||||
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
|
||||
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
|
||||
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
|
||||
/*15060*/ uint8 unknown12852[8];
|
||||
/*15068*/ uint32 available_slots;
|
||||
@@ -2357,7 +2371,7 @@ struct BookRequest_Struct {
|
||||
**
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ uint32 unknown008; // Something related to the linked list?
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||
@@ -2377,8 +2391,8 @@ struct Object_Struct {
|
||||
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*104*/
|
||||
};
|
||||
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
//01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
|
||||
/*
|
||||
** Click Object Struct
|
||||
@@ -3686,30 +3700,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
|
||||
+138
-118
@@ -1200,13 +1200,13 @@ namespace SoF
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = 0; r < 9; r++) {
|
||||
eq->equipment[r].material = emu->item_material[r];
|
||||
eq->equipment[r].unknown1 = 0;
|
||||
eq->equipment[r].elitematerial = 0;
|
||||
eq->equipment[r].Material = emu->item_material[r];
|
||||
eq->equipment[r].Unknown1 = 0;
|
||||
eq->equipment[r].EliteMaterial = 0;
|
||||
//eq->colors[r].color = emu->colors[r].color;
|
||||
}
|
||||
for (r = 0; r < 7; r++) {
|
||||
OUT(item_tint[r].color);
|
||||
OUT(item_tint[r].Color);
|
||||
}
|
||||
// OUT(unknown00224[48]);
|
||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||
@@ -1264,26 +1264,46 @@ namespace SoF
|
||||
OUT(endurance);
|
||||
OUT(aapoints_spent);
|
||||
OUT(aapoints);
|
||||
|
||||
// OUT(unknown06160[4]);
|
||||
//NOTE: new client supports 20 bandoliers, our internal rep
|
||||
//only supports 4..
|
||||
for (r = 0; r < 4; r++) {
|
||||
OUT_str(bandoliers[r].name);
|
||||
uint32 k;
|
||||
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
|
||||
OUT(bandoliers[r].items[k].item_id);
|
||||
OUT(bandoliers[r].items[k].icon);
|
||||
OUT_str(bandoliers[r].items[k].item_name);
|
||||
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
OUT_str(bandoliers[r].Name);
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
OUT(bandoliers[r].Items[k].ID);
|
||||
OUT(bandoliers[r].Items[k].Icon);
|
||||
OUT_str(bandoliers[r].Items[k].Name);
|
||||
}
|
||||
}
|
||||
// OUT(unknown07444[5120]);
|
||||
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
|
||||
OUT(potionbelt.items[r].item_id);
|
||||
OUT(potionbelt.items[r].icon);
|
||||
OUT_str(potionbelt.items[r].item_name);
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
eq->bandoliers[r].Name[0] = '\0';
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
eq->bandoliers[r].Items[k].ID = 0;
|
||||
eq->bandoliers[r].Items[k].Icon = 0;
|
||||
eq->bandoliers[r].Items[k].Name[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// OUT(unknown07444[5120]);
|
||||
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
OUT(potionbelt.Items[r].ID);
|
||||
OUT(potionbelt.Items[r].Icon);
|
||||
OUT_str(potionbelt.Items[r].Name);
|
||||
}
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
eq->potionbelt.Items[r].ID = 0;
|
||||
eq->potionbelt.Items[r].Icon = 0;
|
||||
eq->potionbelt.Items[r].Name[0] = '\0';
|
||||
}
|
||||
|
||||
// OUT(unknown12852[8]);
|
||||
// OUT(unknown12864[76]);
|
||||
|
||||
OUT_str(name);
|
||||
OUT_str(last_name);
|
||||
OUT(guild_id);
|
||||
@@ -1550,76 +1570,95 @@ namespace SoF
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_VAR_ENCODE(CharacterSelect_Struct);
|
||||
|
||||
//EQApplicationPacket *packet = *p;
|
||||
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
|
||||
// Zero-character count shunt
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
int char_count;
|
||||
int namelen = 0;
|
||||
for (char_count = 0; char_count < 10; char_count++) {
|
||||
if (emu->name[char_count][0] == '\0')
|
||||
break;
|
||||
if (strcmp(emu->name[char_count], "<none>") == 0)
|
||||
break;
|
||||
namelen += strlen(emu->name[char_count]);
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
FINISH_ENCODE();
|
||||
return;
|
||||
}
|
||||
|
||||
int total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ namelen;
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
size_t names_length = 0;
|
||||
size_t character_count = 0;
|
||||
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
names_length += strlen(emu_cse->Name);
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
size_t total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ names_length;
|
||||
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
|
||||
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
//unsigned char *eq_buffer = new unsigned char[total_length];
|
||||
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
|
||||
eq->CharCount = character_count;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
eq->char_count = char_count;
|
||||
eq->total_chars = 10;
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
unsigned char *bufptr = (unsigned char *)eq->entries;
|
||||
int r;
|
||||
for (r = 0; r < char_count; r++) {
|
||||
{ //pre-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->level = emu->level[r];
|
||||
eq2->hairstyle = emu->hairstyle[r];
|
||||
eq2->gender = emu->gender[r];
|
||||
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
|
||||
emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
|
||||
unsigned char *eq_ptr = __packet->pBuffer;
|
||||
eq_ptr += sizeof(structs::CharacterSelect_Struct);
|
||||
|
||||
for (int counter = 0; counter < character_count; ++counter) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Level = emu_cse->Level;
|
||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
|
||||
strcpy(eq_cse->Name, emu_cse->Name);
|
||||
eq_ptr += strlen(eq_cse->Name);
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Beard = emu_cse->Beard;
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
|
||||
}
|
||||
//adjust for name.
|
||||
bufptr += strlen(emu->name[r]);
|
||||
{ //post-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->beard = emu->beard[r];
|
||||
eq2->haircolor = emu->haircolor[r];
|
||||
eq2->face = emu->face[r];
|
||||
int k;
|
||||
for (k = 0; k < _MaterialCount; k++) {
|
||||
eq2->equip[k].material = emu->equip[r][k].material;
|
||||
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
|
||||
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
|
||||
eq2->equip[k].color.color = emu->equip[r][k].color.color;
|
||||
}
|
||||
eq2->primary = emu->primary[r];
|
||||
eq2->secondary = emu->secondary[r];
|
||||
eq2->tutorial = emu->tutorial[r]; // was u15
|
||||
eq2->u15 = 0xff;
|
||||
eq2->deity = emu->deity[r];
|
||||
eq2->zone = emu->zone[r];
|
||||
eq2->u19 = 0xFF;
|
||||
eq2->race = emu->race[r];
|
||||
eq2->gohome = emu->gohome[r];
|
||||
eq2->class_ = emu->class_[r];
|
||||
eq2->eyecolor1 = emu->eyecolor1[r];
|
||||
eq2->beardcolor = emu->beardcolor[r];
|
||||
eq2->eyecolor2 = emu->eyecolor2[r];
|
||||
eq2->drakkin_heritage = emu->drakkin_heritage[r];
|
||||
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
|
||||
eq2->drakkin_details = emu->drakkin_details[r];
|
||||
}
|
||||
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
|
||||
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
|
||||
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
|
||||
eq_cse->Tutorial = emu_cse->Tutorial;
|
||||
eq_cse->Unknown15 = emu_cse->Unknown15;
|
||||
eq_cse->Deity = emu_cse->Deity;
|
||||
eq_cse->Zone = emu_cse->Zone;
|
||||
eq_cse->Unknown19 = emu_cse->Unknown19;
|
||||
eq_cse->Race = emu_cse->Race;
|
||||
eq_cse->GoHome = emu_cse->GoHome;
|
||||
eq_cse->Class = emu_cse->Class;
|
||||
eq_cse->EyeColor1 = emu_cse->EyeColor1;
|
||||
eq_cse->BeardColor = emu_cse->BeardColor;
|
||||
eq_cse->EyeColor2 = emu_cse->EyeColor2;
|
||||
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
|
||||
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
|
||||
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -1941,7 +1980,7 @@ namespace SoF
|
||||
OUT(material);
|
||||
OUT(unknown06);
|
||||
OUT(elite_material);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -1951,42 +1990,23 @@ namespace SoF
|
||||
|
||||
ENCODE(OP_ZonePlayerToBind)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
|
||||
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
|
||||
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
|
||||
|
||||
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
|
||||
__packet->SetWritePosition(0);
|
||||
__packet->WriteUInt16(emu->bind_zone_id);
|
||||
__packet->WriteUInt16(emu->bind_instance_id);
|
||||
__packet->WriteFloat(emu->x);
|
||||
__packet->WriteFloat(emu->y);
|
||||
__packet->WriteFloat(emu->z);
|
||||
__packet->WriteFloat(emu->heading);
|
||||
__packet->WriteString(emu->zone_name);
|
||||
__packet->WriteUInt8(1); // save items
|
||||
__packet->WriteUInt32(0); // hp
|
||||
__packet->WriteUInt32(0); // mana
|
||||
__packet->WriteUInt32(0); // endurance
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
|
||||
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
|
||||
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
|
||||
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
|
||||
|
||||
zph->x = zps->x;
|
||||
zph->y = zps->y;
|
||||
zph->z = zps->z;
|
||||
zph->heading = zps->heading;
|
||||
zph->bind_zone_id = zps->bind_zone_id;
|
||||
zph->bind_instance_id = zps->bind_instance_id;
|
||||
strcpy(zph->zone_name, zps->zone_name);
|
||||
|
||||
zpf->unknown021 = 1;
|
||||
zpf->unknown022 = 0;
|
||||
zpf->unknown023 = 0;
|
||||
zpf->unknown024 = 0;
|
||||
|
||||
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
|
||||
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
|
||||
|
||||
delete[] buffer1;
|
||||
delete[] buffer2;
|
||||
delete[](*p)->pBuffer;
|
||||
|
||||
(*p)->pBuffer = new unsigned char[ss.str().size()];
|
||||
(*p)->size = ss.str().size();
|
||||
|
||||
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
|
||||
dest->FastQueuePacket(&(*p));
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ZoneServerInfo)
|
||||
@@ -2044,10 +2064,10 @@ namespace SoF
|
||||
eq->drakkin_heritage = emu->drakkin_heritage;
|
||||
eq->gender = emu->gender;
|
||||
for (k = 0; k < 9; k++) {
|
||||
eq->equipment[k].material = emu->equipment[k].material;
|
||||
eq->equipment[k].unknown1 = emu->equipment[k].unknown1;
|
||||
eq->equipment[k].elitematerial = emu->equipment[k].elitematerial;
|
||||
eq->colors[k].color = emu->colors[k].color;
|
||||
eq->equipment[k].Material = emu->equipment[k].Material;
|
||||
eq->equipment[k].Unknown1 = emu->equipment[k].Unknown1;
|
||||
eq->equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
|
||||
eq->colors[k].Color = emu->colors[k].Color;
|
||||
}
|
||||
eq->StandState = emu->StandState;
|
||||
eq->guildID = emu->guildID;
|
||||
@@ -2109,7 +2129,7 @@ namespace SoF
|
||||
eq->petOwnerId = emu->petOwnerId;
|
||||
eq->pvp = 0; // 0 = non-pvp colored name, 1 = red pvp name
|
||||
for (k = 0; k < 9; k++) {
|
||||
eq->colors[k].color = emu->colors[k].color;
|
||||
eq->colors[k].Color = emu->colors[k].Color;
|
||||
}
|
||||
eq->anon = emu->anon;
|
||||
eq->face = emu->face;
|
||||
@@ -2808,7 +2828,7 @@ namespace SoF
|
||||
IN(material);
|
||||
IN(unknown06);
|
||||
IN(elite_material);
|
||||
IN(color.color);
|
||||
IN(color.Color);
|
||||
IN(wear_slot_id);
|
||||
emu->hero_forge_model = 0;
|
||||
emu->unknown18 = 0;
|
||||
|
||||
@@ -101,6 +101,8 @@ namespace SoF {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 24;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -174,9 +176,10 @@ namespace SoF {
|
||||
static const uint16 ITEM_COMMON_SIZE = 5;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 10;
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
+110
-90
@@ -103,72 +103,74 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
Color_Struct color;
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
struct CharacterSelectEntry_Struct {
|
||||
/*0000*/ uint8 level; //
|
||||
/*0000*/ uint8 hairstyle; //
|
||||
/*0002*/ uint8 gender; //
|
||||
/*0003*/ char name[1]; //variable length, edi+0
|
||||
/*0000*/ uint8 beard; //
|
||||
/*0001*/ uint8 haircolor; //
|
||||
/*0000*/ uint8 face; //
|
||||
/*0000*/ CharSelectEquip equip[9];
|
||||
/*0000*/ uint32 primary; //
|
||||
/*0000*/ uint32 secondary; //
|
||||
/*0000*/ uint8 u15; // 0xff
|
||||
/*0000*/ uint32 deity; //
|
||||
/*0000*/ uint16 zone; //
|
||||
/*0000*/ uint16 instance;
|
||||
/*0000*/ uint8 gohome; //
|
||||
/*0000*/ uint8 u19; // 0xff
|
||||
/*0000*/ uint32 race; //
|
||||
/*0000*/ uint8 tutorial; //
|
||||
/*0000*/ uint8 class_; //
|
||||
/*0000*/ uint8 eyecolor1; //
|
||||
/*0000*/ uint8 beardcolor; //
|
||||
/*0000*/ uint8 eyecolor2; //
|
||||
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
/*0000*/ uint8 Level; //
|
||||
/*0000*/ uint8 HairStyle; //
|
||||
/*0002*/ uint8 Gender; //
|
||||
/*0003*/ char Name[1]; // variable length, edi+0
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[9];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
/*0000*/ uint32 Deity; //
|
||||
/*0000*/ uint16 Zone; //
|
||||
/*0000*/ uint16 Instance;
|
||||
/*0000*/ uint8 GoHome; //
|
||||
/*0000*/ uint8 Unknown19; // 0xff
|
||||
/*0000*/ uint32 Race; //
|
||||
/*0000*/ uint8 Tutorial; //
|
||||
/*0000*/ uint8 Class; //
|
||||
/*0000*/ uint8 EyeColor1; //
|
||||
/*0000*/ uint8 BeardColor; //
|
||||
/*0000*/ uint8 EyeColor2; //
|
||||
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
|
||||
};
|
||||
|
||||
/*
|
||||
** Character Selection Struct
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*0000*/ uint32 char_count; //number of chars in this packet
|
||||
/*0004*/ uint32 total_chars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct entries[0];
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*0000*/ uint32 CharCount; //number of chars in this packet
|
||||
/*0004*/ uint32 TotalChars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 12 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
struct EquipStruct
|
||||
{
|
||||
/*00*/ uint32 Material;
|
||||
/*04*/ uint32 Unknown1;
|
||||
/*08*/ uint32 EliteMaterial;
|
||||
/*12*/
|
||||
};
|
||||
|
||||
@@ -653,9 +655,6 @@ struct Disciplines_Struct {
|
||||
};
|
||||
|
||||
static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 20;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
static const uint32 MAX_POTIONS_IN_BELT = 5;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
|
||||
struct Tribute_Struct {
|
||||
@@ -663,26 +662,42 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
@@ -901,7 +916,7 @@ struct PlayerProfile_Struct //23576 Octets
|
||||
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
|
||||
/*08292*/ uint32 aapoints; // Unspent AA points
|
||||
/*08296*/ uint8 unknown06160[4];
|
||||
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
|
||||
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
|
||||
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
|
||||
/*15060*/ uint8 unknown12852[8];
|
||||
/*15068*/ uint32 available_slots;
|
||||
@@ -2290,7 +2305,7 @@ struct BookRequest_Struct {
|
||||
**
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ uint32 unknown008; // Something related to the linked list?
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||
@@ -2310,8 +2325,8 @@ struct Object_Struct {
|
||||
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*104*/
|
||||
};
|
||||
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
//01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
|
||||
/*
|
||||
** Click Object Struct
|
||||
@@ -3548,30 +3563,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
|
||||
@@ -41,6 +41,11 @@
|
||||
memset(__packet->pBuffer, 0, len); \
|
||||
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
||||
|
||||
#define ALLOC_LEN_ENCODE(len) \
|
||||
__packet->pBuffer = new unsigned char[len]; \
|
||||
__packet->size = len; \
|
||||
memset(__packet->pBuffer, 0, len); \
|
||||
|
||||
//a shorter assignment for direct mode
|
||||
#undef OUT
|
||||
#define OUT(x) eq->x = emu->x;
|
||||
@@ -124,14 +129,14 @@
|
||||
//check length of packet before decoding. Call before setup.
|
||||
#define DECODE_LENGTH_EXACT(struct_) \
|
||||
if(__packet->size != sizeof(struct_)) { \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
#define DECODE_LENGTH_ATLEAST(struct_) \
|
||||
if(__packet->size < sizeof(struct_)) { \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
+130
-49
@@ -865,7 +865,7 @@ namespace Titanium
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = 0; r < 9; r++) {
|
||||
OUT(item_material[r]);
|
||||
OUT(item_tint[r].color);
|
||||
OUT(item_tint[r].Color);
|
||||
}
|
||||
// OUT(unknown00224[48]);
|
||||
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
|
||||
@@ -922,24 +922,46 @@ namespace Titanium
|
||||
OUT(endurance);
|
||||
OUT(aapoints_spent);
|
||||
OUT(aapoints);
|
||||
|
||||
// OUT(unknown06160[4]);
|
||||
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER; r++) {
|
||||
OUT_str(bandoliers[r].name);
|
||||
uint32 k;
|
||||
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
|
||||
OUT(bandoliers[r].items[k].item_id);
|
||||
OUT(bandoliers[r].items[k].icon);
|
||||
OUT_str(bandoliers[r].items[k].item_name);
|
||||
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
OUT_str(bandoliers[r].Name);
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
OUT(bandoliers[r].Items[k].ID);
|
||||
OUT(bandoliers[r].Items[k].Icon);
|
||||
OUT_str(bandoliers[r].Items[k].Name);
|
||||
}
|
||||
}
|
||||
// OUT(unknown07444[5120]);
|
||||
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER_ITEMS; r++) {
|
||||
OUT(potionbelt.items[r].item_id);
|
||||
OUT(potionbelt.items[r].icon);
|
||||
OUT_str(potionbelt.items[r].item_name);
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
eq->bandoliers[r].Name[0] = '\0';
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
eq->bandoliers[r].Items[k].ID = 0;
|
||||
eq->bandoliers[r].Items[k].Icon = 0;
|
||||
eq->bandoliers[r].Items[k].Name[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// OUT(unknown07444[5120]);
|
||||
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
OUT(potionbelt.Items[r].ID);
|
||||
OUT(potionbelt.Items[r].Icon);
|
||||
OUT_str(potionbelt.Items[r].Name);
|
||||
}
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
eq->potionbelt.Items[r].ID = 0;
|
||||
eq->potionbelt.Items[r].Icon = 0;
|
||||
eq->potionbelt.Items[r].Name[0] = '\0';
|
||||
}
|
||||
|
||||
// OUT(unknown12852[8]);
|
||||
// OUT(unknown12864[76]);
|
||||
|
||||
OUT_str(name);
|
||||
OUT_str(last_name);
|
||||
OUT(guild_id);
|
||||
@@ -1048,7 +1070,7 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed -U
|
||||
// no apparent slot translation needed
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
@@ -1133,39 +1155,98 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_DIRECT_ENCODE(CharacterSelect_Struct, structs::CharacterSelect_Struct);
|
||||
|
||||
int r;
|
||||
for (r = 0; r < 10; r++) {
|
||||
OUT(zone[r]);
|
||||
OUT(eyecolor1[r]);
|
||||
OUT(eyecolor2[r]);
|
||||
OUT(hairstyle[r]);
|
||||
OUT(primary[r]);
|
||||
if (emu->race[r] > 473)
|
||||
eq->race[r] = 1;
|
||||
else
|
||||
eq->race[r] = emu->race[r];
|
||||
OUT(class_[r]);
|
||||
OUT_str(name[r]);
|
||||
OUT(gender[r]);
|
||||
OUT(level[r]);
|
||||
OUT(secondary[r]);
|
||||
OUT(face[r]);
|
||||
OUT(beard[r]);
|
||||
int k;
|
||||
for (k = 0; k < 9; k++) {
|
||||
eq->equip[r][k] = emu->equip[r][k].material;
|
||||
eq->cs_colors[r][k].color = emu->equip[r][k].color.color;
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
for (size_t index = 0; index < 10; ++index) {
|
||||
memset(eq->Name[index], 0, 64);
|
||||
}
|
||||
|
||||
// Non character-indexed packet fields
|
||||
eq->Unknown830[0] = 0;
|
||||
eq->Unknown830[1] = 0;
|
||||
eq->Unknown0962[0] = 0;
|
||||
eq->Unknown0962[1] = 0;
|
||||
|
||||
size_t char_index = 0;
|
||||
for (; char_index < emu->CharCount && char_index < 8; ++char_index) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
|
||||
eq->Race[char_index] = emu_cse->Race;
|
||||
if (eq->Race[char_index] > 473)
|
||||
eq->Race[char_index] = 1;
|
||||
|
||||
for (int index = 0; index < _MaterialCount; ++index) {
|
||||
eq->CS_Colors[char_index][index].Color = emu_cse->Equip[index].Color.Color;
|
||||
}
|
||||
OUT(haircolor[r]);
|
||||
OUT(gohome[r]);
|
||||
OUT(tutorial[r]);
|
||||
OUT(deity[r]);
|
||||
OUT(beardcolor[r]);
|
||||
eq->unknown820[r] = 0xFF;
|
||||
eq->unknown902[r] = 0xFF;
|
||||
|
||||
eq->BeardColor[char_index] = emu_cse->BeardColor;
|
||||
eq->HairStyle[char_index] = emu_cse->HairStyle;
|
||||
|
||||
for (int index = 0; index < _MaterialCount; ++index) {
|
||||
eq->Equip[char_index][index] = emu_cse->Equip[index].Material;
|
||||
}
|
||||
|
||||
eq->SecondaryIDFile[char_index] = emu_cse->SecondaryIDFile;
|
||||
eq->Unknown820[char_index] = (uint8)0xFF;
|
||||
eq->Deity[char_index] = emu_cse->Deity;
|
||||
eq->GoHome[char_index] = emu_cse->GoHome;
|
||||
eq->Tutorial[char_index] = emu_cse->Tutorial;
|
||||
eq->Beard[char_index] = emu_cse->Beard;
|
||||
eq->Unknown902[char_index] = (uint8)0xFF;
|
||||
eq->PrimaryIDFile[char_index] = emu_cse->PrimaryIDFile;
|
||||
eq->HairColor[char_index] = emu_cse->HairColor;
|
||||
eq->Zone[char_index] = emu_cse->Zone;
|
||||
eq->Class[char_index] = emu_cse->Class;
|
||||
eq->Face[char_index] = emu_cse->Face;
|
||||
|
||||
memcpy(eq->Name[char_index], emu_cse->Name, 64);
|
||||
|
||||
eq->Gender[char_index] = emu_cse->Gender;
|
||||
eq->EyeColor1[char_index] = emu_cse->EyeColor1;
|
||||
eq->EyeColor2[char_index] = emu_cse->EyeColor2;
|
||||
eq->Level[char_index] = emu_cse->Level;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
for (; char_index < 10; ++char_index) {
|
||||
eq->Race[char_index] = 0;
|
||||
|
||||
for (int index = 0; index < _MaterialCount; ++index) {
|
||||
eq->CS_Colors[char_index][index].Color = 0;
|
||||
}
|
||||
|
||||
eq->BeardColor[char_index] = 0;
|
||||
eq->HairStyle[char_index] = 0;
|
||||
|
||||
for (int index = 0; index < _MaterialCount; ++index) {
|
||||
eq->Equip[char_index][index] = 0;
|
||||
}
|
||||
|
||||
eq->SecondaryIDFile[char_index] = 0;
|
||||
eq->Unknown820[char_index] = (uint8)0xFF;
|
||||
eq->Deity[char_index] = 0;
|
||||
eq->GoHome[char_index] = 0;
|
||||
eq->Tutorial[char_index] = 0;
|
||||
eq->Beard[char_index] = 0;
|
||||
eq->Unknown902[char_index] = (uint8)0xFF;
|
||||
eq->PrimaryIDFile[char_index] = 0;
|
||||
eq->HairColor[char_index] = 0;
|
||||
eq->Zone[char_index] = 0;
|
||||
eq->Class[char_index] = 0;
|
||||
eq->Face[char_index] = 0;
|
||||
|
||||
strncpy(eq->Name[char_index], "<none>", 6);
|
||||
|
||||
eq->Gender[char_index] = 0;
|
||||
eq->EyeColor1[char_index] = 0;
|
||||
eq->EyeColor2[char_index] = 0;
|
||||
eq->Level[char_index] = 0;
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -1383,7 +1464,7 @@ namespace Titanium
|
||||
|
||||
OUT(spawn_id);
|
||||
OUT(material);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -1475,8 +1556,8 @@ namespace Titanium
|
||||
eq->guildrank = emu->guildrank;
|
||||
// eq->unknown0194[3] = emu->unknown0194[3];
|
||||
for (k = 0; k < 9; k++) {
|
||||
eq->equipment[k] = emu->equipment[k].material;
|
||||
eq->colors[k].color = emu->colors[k].color;
|
||||
eq->equipment[k] = emu->equipment[k].Material;
|
||||
eq->colors[k].Color = emu->colors[k].Color;
|
||||
}
|
||||
for (k = 0; k < 8; k++) {
|
||||
eq->set_to_0xFF[k] = 0xFF;
|
||||
@@ -1868,7 +1949,7 @@ namespace Titanium
|
||||
|
||||
DECODE(OP_ReadBook)
|
||||
{
|
||||
// no apparent slot translation needed -U
|
||||
// no apparent slot translation needed
|
||||
DECODE_LENGTH_ATLEAST(structs::BookRequest_Struct);
|
||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||
|
||||
@@ -1952,7 +2033,7 @@ namespace Titanium
|
||||
|
||||
IN(spawn_id);
|
||||
IN(material);
|
||||
IN(color.color);
|
||||
IN(color.Color);
|
||||
IN(wear_slot_id);
|
||||
emu->unknown06 = 0;
|
||||
emu->elite_material = 0;
|
||||
|
||||
@@ -100,6 +100,8 @@ namespace Titanium {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 16;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -173,9 +175,10 @@ namespace Titanium {
|
||||
static const uint16 ITEM_COMMON_SIZE = 5;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 10;
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 4;
|
||||
static const size_t BANDOLIERS_SIZE = 4; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 4;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 45;
|
||||
}
|
||||
|
||||
@@ -99,16 +99,14 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -117,31 +115,32 @@ struct Color_Struct
|
||||
** Length: 1704 Bytes
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*0000*/ uint32 race[10]; // Characters Race
|
||||
/*0040*/ Color_Struct cs_colors[10][9]; // Characters Equipment Colors
|
||||
/*0400*/ uint8 beardcolor[10]; // Characters beard Color
|
||||
/*0410*/ uint8 hairstyle[10]; // Characters hair style
|
||||
/*0420*/ uint32 equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
|
||||
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
|
||||
/*0820*/ uint8 unknown820[10]; // 10x ff
|
||||
/*0830*/ uint8 unknown830[2]; // 2x 00
|
||||
/*0832*/ uint32 deity[10]; // Characters Deity
|
||||
/*0872*/ uint8 gohome[10]; // 1=Go Home available, 0=not
|
||||
/*0882*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
|
||||
/*0892*/ uint8 beard[10]; // Characters Beard Type
|
||||
/*0902*/ uint8 unknown902[10]; // 10x ff
|
||||
/*0912*/ uint32 primary[10]; // Characters primary IDFile number
|
||||
/*0952*/ uint8 haircolor[10]; // Characters Hair Color
|
||||
/*0962*/ uint8 unknown0962[2]; // 2x 00
|
||||
/*0964*/ uint32 zone[10]; // Characters Current Zone
|
||||
/*1004*/ uint8 class_[10]; // Characters Classes
|
||||
/*1014*/ uint8 face[10]; // Characters Face Type
|
||||
/*1024*/ char name[10][64]; // Characters Names
|
||||
/*1664*/ uint8 gender[10]; // Characters Gender
|
||||
/*1674*/ uint8 eyecolor1[10]; // Characters Eye Color
|
||||
/*1684*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
|
||||
/*1694*/ uint8 level[10]; // Characters Levels
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*0000*/ uint32 Race[10]; // Characters Race
|
||||
/*0040*/ Color_Struct CS_Colors[10][9]; // Characters Equipment Colors
|
||||
/*0400*/ uint8 BeardColor[10]; // Characters beard Color
|
||||
/*0410*/ uint8 HairStyle[10]; // Characters hair style
|
||||
/*0420*/ uint32 Equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
|
||||
/*0780*/ uint32 SecondaryIDFile[10]; // Characters secondary IDFile number
|
||||
/*0820*/ uint8 Unknown820[10]; // 10x ff
|
||||
/*0830*/ uint8 Unknown830[2]; // 2x 00
|
||||
/*0832*/ uint32 Deity[10]; // Characters Deity
|
||||
/*0872*/ uint8 GoHome[10]; // 1=Go Home available, 0=not
|
||||
/*0882*/ uint8 Tutorial[10]; // 1=Tutorial available, 0=not
|
||||
/*0892*/ uint8 Beard[10]; // Characters Beard Type
|
||||
/*0902*/ uint8 Unknown902[10]; // 10x ff
|
||||
/*0912*/ uint32 PrimaryIDFile[10]; // Characters primary IDFile number
|
||||
/*0952*/ uint8 HairColor[10]; // Characters Hair Color
|
||||
/*0962*/ uint8 Unknown0962[2]; // 2x 00
|
||||
/*0964*/ uint32 Zone[10]; // Characters Current Zone
|
||||
/*1004*/ uint8 Class[10]; // Characters Classes
|
||||
/*1014*/ uint8 Face[10]; // Characters Face Type
|
||||
/*1024*/ char Name[10][64]; // Characters Names
|
||||
/*1664*/ uint8 Gender[10]; // Characters Gender
|
||||
/*1674*/ uint8 EyeColor1[10]; // Characters Eye Color
|
||||
/*1684*/ uint8 EyeColor2[10]; // Characters Eye 2 Color
|
||||
/*1694*/ uint8 Level[10]; // Characters Levels
|
||||
/*1704*/
|
||||
};
|
||||
|
||||
@@ -586,34 +585,48 @@ struct Disciplines_Struct {
|
||||
};
|
||||
|
||||
static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 4;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
struct Tribute_Struct {
|
||||
uint32 tribute;
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
@@ -817,7 +830,7 @@ struct PlayerProfile_Struct
|
||||
/*06152*/ uint32 aapoints_spent; // Number of spent AA points
|
||||
/*06156*/ uint32 aapoints; // Unspent AA points
|
||||
/*06160*/ uint8 unknown06160[4];
|
||||
/*06164*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // bandolier contents
|
||||
/*06164*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // bandolier contents
|
||||
/*07444*/ uint8 unknown07444[5120];
|
||||
/*12564*/ PotionBelt_Struct potionbelt; // potion belt
|
||||
/*12852*/ uint8 unknown12852[8];
|
||||
@@ -1997,7 +2010,7 @@ struct BookRequest_Struct {
|
||||
**
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ uint16 unknown008[2]; //
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||
@@ -2016,8 +2029,8 @@ struct Object_Struct {
|
||||
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*92*/
|
||||
};
|
||||
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
//01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
|
||||
/*
|
||||
** Click Object Struct
|
||||
@@ -3030,30 +3043,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct Arrow_Struct {
|
||||
|
||||
+146
-119
@@ -1791,13 +1791,13 @@ namespace UF
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = 0; r < 9; r++) {
|
||||
eq->equipment[r].material = emu->item_material[r];
|
||||
eq->equipment[r].unknown1 = 0;
|
||||
eq->equipment[r].elitematerial = 0;
|
||||
eq->equipment[r].Material = emu->item_material[r];
|
||||
eq->equipment[r].Unknown1 = 0;
|
||||
eq->equipment[r].EliteMaterial = 0;
|
||||
//eq->colors[r].color = emu->colors[r].color;
|
||||
}
|
||||
for (r = 0; r < 7; r++) {
|
||||
OUT(item_tint[r].color);
|
||||
OUT(item_tint[r].Color);
|
||||
}
|
||||
// OUT(unknown00224[48]);
|
||||
//NOTE: new client supports 300 AAs, our internal rep/PP
|
||||
@@ -1868,26 +1868,46 @@ namespace UF
|
||||
OUT(endurance);
|
||||
OUT(aapoints_spent);
|
||||
OUT(aapoints);
|
||||
|
||||
// OUT(unknown06160[4]);
|
||||
//NOTE: new client supports 20 bandoliers, our internal rep
|
||||
//only supports 4..
|
||||
for (r = 0; r < 4; r++) {
|
||||
OUT_str(bandoliers[r].name);
|
||||
uint32 k;
|
||||
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
|
||||
OUT(bandoliers[r].items[k].item_id);
|
||||
OUT(bandoliers[r].items[k].icon);
|
||||
OUT_str(bandoliers[r].items[k].item_name);
|
||||
|
||||
// Copy bandoliers where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
OUT_str(bandoliers[r].Name);
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
OUT(bandoliers[r].Items[k].ID);
|
||||
OUT(bandoliers[r].Items[k].Icon);
|
||||
OUT_str(bandoliers[r].Items[k].Name);
|
||||
}
|
||||
}
|
||||
// OUT(unknown07444[5120]);
|
||||
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
|
||||
OUT(potionbelt.items[r].item_id);
|
||||
OUT(potionbelt.items[r].icon);
|
||||
OUT_str(potionbelt.items[r].item_name);
|
||||
// Nullify bandoliers where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
|
||||
eq->bandoliers[r].Name[0] = '\0';
|
||||
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
|
||||
eq->bandoliers[r].Items[k].ID = 0;
|
||||
eq->bandoliers[r].Items[k].Icon = 0;
|
||||
eq->bandoliers[r].Items[k].Name[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// OUT(unknown07444[5120]);
|
||||
|
||||
// Copy potion belt where server and client indexes converge
|
||||
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
OUT(potionbelt.Items[r].ID);
|
||||
OUT(potionbelt.Items[r].Icon);
|
||||
OUT_str(potionbelt.Items[r].Name);
|
||||
}
|
||||
// Nullify potion belt where server and client indexes diverge, with a client bias
|
||||
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
|
||||
eq->potionbelt.Items[r].ID = 0;
|
||||
eq->potionbelt.Items[r].Icon = 0;
|
||||
eq->potionbelt.Items[r].Name[0] = '\0';
|
||||
}
|
||||
|
||||
// OUT(unknown12852[8]);
|
||||
// OUT(unknown12864[76]);
|
||||
|
||||
OUT_str(name);
|
||||
OUT_str(last_name);
|
||||
OUT(guild_id);
|
||||
@@ -2174,77 +2194,103 @@ namespace UF
|
||||
|
||||
ENCODE(OP_SendCharInfo)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
|
||||
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
|
||||
SETUP_VAR_ENCODE(CharacterSelect_Struct);
|
||||
|
||||
//EQApplicationPacket *packet = *p;
|
||||
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
|
||||
// Zero-character count shunt
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
int char_count;
|
||||
int namelen = 0;
|
||||
for (char_count = 0; char_count < 10; char_count++) {
|
||||
if (emu->name[char_count][0] == '\0')
|
||||
break;
|
||||
if (strcmp(emu->name[char_count], "<none>") == 0)
|
||||
break;
|
||||
namelen += strlen(emu->name[char_count]);
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars'
|
||||
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
|
||||
eq->TotalChars = adjusted_total;
|
||||
|
||||
FINISH_ENCODE();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
size_t names_length = 0;
|
||||
size_t character_count = 0;
|
||||
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
names_length += strlen(emu_cse->Name);
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
int total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ namelen;
|
||||
size_t total_length = sizeof(structs::CharacterSelect_Struct)
|
||||
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
|
||||
+ names_length;
|
||||
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
|
||||
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
|
||||
|
||||
//unsigned char *eq_buffer = new unsigned char[total_length];
|
||||
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
|
||||
eq->CharCount = character_count;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
eq->char_count = char_count;
|
||||
eq->total_chars = 10;
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
unsigned char *bufptr = (unsigned char *)eq->entries;
|
||||
int r;
|
||||
for (r = 0; r < char_count; r++) {
|
||||
{ //pre-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->level = emu->level[r];
|
||||
eq2->hairstyle = emu->hairstyle[r];
|
||||
eq2->gender = emu->gender[r];
|
||||
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
|
||||
}
|
||||
//adjust for name.
|
||||
bufptr += strlen(emu->name[r]);
|
||||
{ //post-name section...
|
||||
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
|
||||
eq2->beard = emu->beard[r];
|
||||
eq2->haircolor = emu->haircolor[r];
|
||||
eq2->face = emu->face[r];
|
||||
int k;
|
||||
for (k = 0; k < _MaterialCount; k++) {
|
||||
eq2->equip[k].material = emu->equip[r][k].material;
|
||||
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
|
||||
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
|
||||
eq2->equip[k].color.color = emu->equip[r][k].color.color;
|
||||
}
|
||||
eq2->primary = emu->primary[r];
|
||||
eq2->secondary = emu->secondary[r];
|
||||
eq2->tutorial = emu->tutorial[r]; // was u15
|
||||
eq2->u15 = 0xff;
|
||||
eq2->deity = emu->deity[r];
|
||||
eq2->zone = emu->zone[r];
|
||||
eq2->u19 = 0xFF;
|
||||
eq2->race = emu->race[r];
|
||||
eq2->gohome = emu->gohome[r];
|
||||
eq2->class_ = emu->class_[r];
|
||||
eq2->eyecolor1 = emu->eyecolor1[r];
|
||||
eq2->beardcolor = emu->beardcolor[r];
|
||||
eq2->eyecolor2 = emu->eyecolor2[r];
|
||||
eq2->drakkin_heritage = emu->drakkin_heritage[r];
|
||||
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
|
||||
eq2->drakkin_details = emu->drakkin_details[r];
|
||||
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars' in this client
|
||||
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
|
||||
eq->TotalChars = adjusted_total;
|
||||
|
||||
emu_ptr = __emu_buffer;
|
||||
emu_ptr += sizeof(CharacterSelect_Struct);
|
||||
|
||||
unsigned char *eq_ptr = __packet->pBuffer;
|
||||
eq_ptr += sizeof(structs::CharacterSelect_Struct);
|
||||
|
||||
for (int counter = 0; counter < character_count; ++counter) {
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Level = emu_cse->Level;
|
||||
eq_cse->HairStyle = emu_cse->HairStyle;
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
|
||||
strcpy(eq_cse->Name, emu_cse->Name);
|
||||
eq_ptr += strlen(eq_cse->Name);
|
||||
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr;
|
||||
|
||||
eq_cse->Beard = emu_cse->Beard;
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < _MaterialCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
|
||||
}
|
||||
|
||||
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
|
||||
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
|
||||
eq_cse->Tutorial = emu_cse->Tutorial;
|
||||
eq_cse->Unknown15 = emu_cse->Unknown15;
|
||||
eq_cse->Deity = emu_cse->Deity;
|
||||
eq_cse->Zone = emu_cse->Zone;
|
||||
eq_cse->Unknown19 = emu_cse->Unknown19;
|
||||
eq_cse->Race = emu_cse->Race;
|
||||
eq_cse->GoHome = emu_cse->GoHome;
|
||||
eq_cse->Class = emu_cse->Class;
|
||||
eq_cse->EyeColor1 = emu_cse->EyeColor1;
|
||||
eq_cse->BeardColor = emu_cse->BeardColor;
|
||||
eq_cse->EyeColor2 = emu_cse->EyeColor2;
|
||||
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
|
||||
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
|
||||
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
|
||||
|
||||
emu_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
|
||||
}
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2621,7 +2667,7 @@ namespace UF
|
||||
OUT(material);
|
||||
OUT(unknown06);
|
||||
OUT(elite_material);
|
||||
OUT(color.color);
|
||||
OUT(color.Color);
|
||||
OUT(wear_slot_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -2693,42 +2739,23 @@ namespace UF
|
||||
|
||||
ENCODE(OP_ZonePlayerToBind)
|
||||
{
|
||||
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
|
||||
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
|
||||
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
|
||||
|
||||
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
|
||||
__packet->SetWritePosition(0);
|
||||
__packet->WriteUInt16(emu->bind_zone_id);
|
||||
__packet->WriteUInt16(emu->bind_instance_id);
|
||||
__packet->WriteFloat(emu->x);
|
||||
__packet->WriteFloat(emu->y);
|
||||
__packet->WriteFloat(emu->z);
|
||||
__packet->WriteFloat(emu->heading);
|
||||
__packet->WriteString(emu->zone_name);
|
||||
__packet->WriteUInt8(1); // save items
|
||||
__packet->WriteUInt32(0); // hp
|
||||
__packet->WriteUInt32(0); // mana
|
||||
__packet->WriteUInt32(0); // endurance
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
|
||||
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
|
||||
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
|
||||
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
|
||||
|
||||
zph->x = zps->x;
|
||||
zph->y = zps->y;
|
||||
zph->z = zps->z;
|
||||
zph->heading = zps->heading;
|
||||
zph->bind_zone_id = zps->bind_zone_id;
|
||||
zph->bind_instance_id = zps->bind_instance_id;
|
||||
strcpy(zph->zone_name, zps->zone_name);
|
||||
|
||||
zpf->unknown021 = 1;
|
||||
zpf->unknown022 = 0;
|
||||
zpf->unknown023 = 0;
|
||||
zpf->unknown024 = 0;
|
||||
|
||||
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
|
||||
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
|
||||
|
||||
delete[] buffer1;
|
||||
delete[] buffer2;
|
||||
delete[](*p)->pBuffer;
|
||||
|
||||
(*p)->pBuffer = new unsigned char[ss.str().size()];
|
||||
(*p)->size = ss.str().size();
|
||||
|
||||
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
|
||||
dest->FastQueuePacket(&(*p));
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ZoneServerInfo)
|
||||
@@ -3002,7 +3029,7 @@ namespace UF
|
||||
for (k = 0; k < 9; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3012,11 +3039,11 @@ namespace UF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
}
|
||||
@@ -3026,9 +3053,9 @@ namespace UF
|
||||
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
|
||||
|
||||
for (k = 0; k < 9; k++) {
|
||||
Equipment[k].material = emu->equipment[k].material;
|
||||
Equipment[k].unknown1 = emu->equipment[k].unknown1;
|
||||
Equipment[k].elitematerial = emu->equipment[k].elitematerial;
|
||||
Equipment[k].Material = emu->equipment[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::EquipStruct) * 9);
|
||||
@@ -3728,7 +3755,7 @@ namespace UF
|
||||
IN(material);
|
||||
IN(unknown06);
|
||||
IN(elite_material);
|
||||
IN(color.color);
|
||||
IN(color.Color);
|
||||
IN(wear_slot_id);
|
||||
emu->hero_forge_model = 0;
|
||||
emu->unknown18 = 0;
|
||||
|
||||
@@ -101,6 +101,8 @@ namespace UF {
|
||||
}
|
||||
|
||||
namespace consts {
|
||||
static const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
|
||||
static const uint16 MAP_BANK_SIZE = 24;
|
||||
static const uint16 MAP_SHARED_BANK_SIZE = 2;
|
||||
@@ -174,9 +176,10 @@ namespace UF {
|
||||
static const uint16 ITEM_COMMON_SIZE = 5;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 10;
|
||||
|
||||
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
|
||||
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
|
||||
static const uint32 POTION_BELT_SIZE = 5;
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 50;
|
||||
}
|
||||
|
||||
+111
-91
@@ -103,53 +103,53 @@ struct AdventureInfo {
|
||||
*/
|
||||
struct Color_Struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 blue;
|
||||
uint8 green;
|
||||
uint8 red;
|
||||
uint8 use_tint; // if there's a tint this is FF
|
||||
} rgb;
|
||||
uint32 color;
|
||||
union {
|
||||
struct {
|
||||
uint8 blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
} RGB;
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
|
||||
struct CharSelectEquip {
|
||||
uint32 material;
|
||||
uint32 unknown1;
|
||||
uint32 elitematerial;
|
||||
Color_Struct color;
|
||||
struct CharSelectEquip
|
||||
{
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
Color_Struct Color;
|
||||
};
|
||||
|
||||
struct CharacterSelectEntry_Struct {
|
||||
/*0000*/ uint8 level; //
|
||||
/*0000*/ uint8 hairstyle; //
|
||||
/*0002*/ uint8 gender; //
|
||||
/*0003*/ char name[1]; //variable length, edi+0
|
||||
/*0000*/ uint8 beard; //
|
||||
/*0001*/ uint8 haircolor; //
|
||||
/*0000*/ uint8 face; //
|
||||
/*0000*/ CharSelectEquip equip[9];
|
||||
/*0000*/ uint32 primary; //
|
||||
/*0000*/ uint32 secondary; //
|
||||
/*0000*/ uint8 u15; // 0xff
|
||||
/*0000*/ uint32 deity; //
|
||||
/*0000*/ uint16 zone; //
|
||||
/*0000*/ uint16 instance;
|
||||
/*0000*/ uint8 gohome; //
|
||||
/*0000*/ uint8 u19; // 0xff
|
||||
/*0000*/ uint32 race; //
|
||||
/*0000*/ uint8 tutorial; //
|
||||
/*0000*/ uint8 class_; //
|
||||
/*0000*/ uint8 eyecolor1; //
|
||||
/*0000*/ uint8 beardcolor; //
|
||||
/*0000*/ uint8 eyecolor2; //
|
||||
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
|
||||
/*0000*/ uint8 unknown; // New field to Underfoot
|
||||
struct CharacterSelectEntry_Struct
|
||||
{
|
||||
/*0000*/ uint8 Level; //
|
||||
/*0000*/ uint8 HairStyle; //
|
||||
/*0002*/ uint8 Gender; //
|
||||
/*0003*/ char Name[1]; // variable length, edi+0
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[9];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
/*0000*/ uint32 Deity; //
|
||||
/*0000*/ uint16 Zone; //
|
||||
/*0000*/ uint16 Instance;
|
||||
/*0000*/ uint8 GoHome; //
|
||||
/*0000*/ uint8 Unknown19; // 0xff
|
||||
/*0000*/ uint32 Race; //
|
||||
/*0000*/ uint8 Tutorial; //
|
||||
/*0000*/ uint8 Class; //
|
||||
/*0000*/ uint8 EyeColor1; //
|
||||
/*0000*/ uint8 BeardColor; //
|
||||
/*0000*/ uint8 EyeColor2; //
|
||||
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
|
||||
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
|
||||
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
|
||||
/*0000*/ uint8 Unknown; // New field to Underfoot
|
||||
|
||||
};
|
||||
|
||||
@@ -157,20 +157,22 @@ struct CharacterSelectEntry_Struct {
|
||||
** Character Selection Struct
|
||||
**
|
||||
*/
|
||||
struct CharacterSelect_Struct {
|
||||
/*0000*/ uint32 char_count; //number of chars in this packet
|
||||
/*0004*/ uint32 total_chars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct entries[0];
|
||||
struct CharacterSelect_Struct
|
||||
{
|
||||
/*0000*/ uint32 CharCount; //number of chars in this packet
|
||||
/*0004*/ uint32 TotalChars; //total number of chars allowed?
|
||||
/*0008*/ CharacterSelectEntry_Struct Entries[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Visible equiptment.
|
||||
* Size: 12 Octets
|
||||
*/
|
||||
struct EquipStruct {
|
||||
/*00*/ uint32 material;
|
||||
/*04*/ uint32 unknown1;
|
||||
/*08*/ uint32 elitematerial;
|
||||
struct EquipStruct
|
||||
{
|
||||
/*00*/ uint32 Material;
|
||||
/*04*/ uint32 Unknown1;
|
||||
/*08*/ uint32 EliteMaterial;
|
||||
/*12*/
|
||||
};
|
||||
|
||||
@@ -722,9 +724,6 @@ struct Disciplines_Struct {
|
||||
};
|
||||
|
||||
static const uint32 MAX_PLAYER_TRIBUTES = 5;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER = 20;
|
||||
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
|
||||
static const uint32 MAX_POTIONS_IN_BELT = 5;
|
||||
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
|
||||
|
||||
struct Tribute_Struct {
|
||||
@@ -732,26 +731,42 @@ struct Tribute_Struct {
|
||||
uint32 tier;
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct {
|
||||
uint32 item_id;
|
||||
uint32 icon;
|
||||
char item_name[64];
|
||||
};
|
||||
|
||||
//len = 320
|
||||
enum { //bandolier item positions
|
||||
bandolierMainHand = 0,
|
||||
bandolierOffHand,
|
||||
// Bandolier item positions
|
||||
enum
|
||||
{
|
||||
bandolierPrimary = 0,
|
||||
bandolierSecondary,
|
||||
bandolierRange,
|
||||
bandolierAmmo
|
||||
};
|
||||
struct Bandolier_Struct {
|
||||
char name[32];
|
||||
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
|
||||
|
||||
//len = 72
|
||||
struct BandolierItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
|
||||
//len = 320
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
struct PotionBeltItem_Struct
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 Icon;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
@@ -974,7 +989,7 @@ struct PlayerProfile_Struct
|
||||
/*11236*/ uint32 aapoints_spent; // Number of spent AA points
|
||||
/*11240*/ uint32 aapoints; // Unspent AA points
|
||||
/*11244*/ uint8 unknown11244[4];
|
||||
/*11248*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
|
||||
/*11248*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
|
||||
/*17648*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
|
||||
/*18008*/ uint8 unknown18008[8];
|
||||
/*18016*/ uint32 available_slots;
|
||||
@@ -2425,7 +2440,7 @@ struct BookRequest_Struct {
|
||||
**
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ uint32 unknown008; // Something related to the linked list?
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||
@@ -2445,8 +2460,8 @@ struct Object_Struct {
|
||||
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*104*/
|
||||
};
|
||||
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
//01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
|
||||
/*
|
||||
** Click Object Struct
|
||||
@@ -3758,30 +3773,35 @@ struct DynamicWall_Struct {
|
||||
/*80*/
|
||||
};
|
||||
|
||||
enum { //bandolier actions
|
||||
BandolierCreate = 0,
|
||||
BandolierRemove = 1,
|
||||
BandolierSet = 2
|
||||
// Bandolier actions
|
||||
enum
|
||||
{
|
||||
bandolierCreate = 0,
|
||||
bandolierRemove,
|
||||
bandolierSet
|
||||
};
|
||||
|
||||
struct BandolierCreate_Struct {
|
||||
/*00*/ uint32 action; //0 for create
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ char name[32];
|
||||
/*37*/ uint16 unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 unknown39; //0
|
||||
struct BandolierCreate_Struct
|
||||
{
|
||||
/*00*/ uint32 Action; //0 for create
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ char Name[32];
|
||||
/*37*/ uint16 Unknown37; //seen 0x93FD
|
||||
/*39*/ uint8 Unknown39; //0
|
||||
};
|
||||
|
||||
struct BandolierDelete_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierDelete_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
struct BandolierSet_Struct {
|
||||
/*00*/ uint32 action;
|
||||
/*04*/ uint8 number;
|
||||
/*05*/ uint8 unknown05[35];
|
||||
struct BandolierSet_Struct
|
||||
{
|
||||
/*00*/ uint32 Action;
|
||||
/*04*/ uint8 Number;
|
||||
/*05*/ uint8 Unknown05[35];
|
||||
};
|
||||
|
||||
// Not 100% sure on this struct. Live as of 1/1/11 is different than UF. Seems to work 'OK'
|
||||
|
||||
+5
-1
@@ -133,6 +133,9 @@ RULE_INT ( Skills, MaxTrainTradeskills, 21 )
|
||||
RULE_BOOL ( Skills, UseLimitTradeskillSearchSkillDiff, true )
|
||||
RULE_INT ( Skills, MaxTradeskillSearchSkillDiff, 50 )
|
||||
RULE_INT ( Skills, MaxTrainSpecializations, 50 ) // Max level a GM trainer will train casting specializations
|
||||
RULE_INT ( Skills, SwimmingStartValue, 100 )
|
||||
RULE_BOOL ( Skills, TrainSenseHeading, false )
|
||||
RULE_INT ( Skills, SenseHeadingStartValue, 200 )
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Pets )
|
||||
@@ -300,7 +303,7 @@ RULE_INT ( Spells, MaxCastTimeReduction, 50) //Max percent your spell cast time
|
||||
RULE_INT ( Spells, RootBreakFromSpells, 55) //Chance for root to break when cast on.
|
||||
RULE_INT ( Spells, DeathSaveCharismaMod, 3) //Determines how much charisma effects chance of death save firing.
|
||||
RULE_INT ( Spells, DivineInterventionHeal, 8000) //Divine intervention heal amount.
|
||||
RULE_BOOL ( Spells, AdditiveBonusValues, false) //Allow certain bonuses to be calculated by adding together the value from each item, instead of taking the highest value. (ie Add together all Cleave Effects)
|
||||
RULE_INT ( Spells, AdditiveBonusWornType, 0) //Calc worn bonuses to add together (instead of taking highest) if set to THIS worn type. (2=Will covert live items automatically)
|
||||
RULE_BOOL ( Spells, UseCHAScribeHack, false) //ScribeSpells and TrainDiscs quest functions will ignore entries where field 12 is CHA. What's the best way to do this?
|
||||
RULE_BOOL ( Spells, BuffLevelRestrictions, true) //Buffs will not land on low level toons like live
|
||||
RULE_INT ( Spells, RootBreakCheckChance, 70) //Determines chance for a root break check to occur each buff tick.
|
||||
@@ -329,6 +332,7 @@ RULE_BOOL ( Spells, Jun182014HundredHandsRevamp, false) // this should be true f
|
||||
RULE_BOOL ( Spells, SwarmPetTargetLock, false) // Use old method of swarm pets target locking till target dies then despawning.
|
||||
RULE_BOOL ( Spells, NPC_UseFocusFromSpells, true) // Allow npcs to use most spell derived focus effects.
|
||||
RULE_BOOL ( Spells, NPC_UseFocusFromItems, false) // Allow npcs to use most item derived focus effects.
|
||||
RULE_BOOL ( Spells, UseAdditiveFocusFromWornSlot, false) // Allows an additive focus effect to be calculated from worn slot.
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Combat )
|
||||
|
||||
+24
-20
@@ -151,28 +151,31 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
|
||||
|
||||
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
|
||||
// If we never save tribute slots..how are we to ever benefit from them!!? The client
|
||||
// object is destroyed upon zoning - including its inventory object..and if tributes
|
||||
// don't exist in the database, then they will never be loaded when the new client
|
||||
// object is created in the new zone object... Something to consider... -U
|
||||
//
|
||||
// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline)
|
||||
|
||||
//never save tribute slots:
|
||||
if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
|
||||
return true;
|
||||
|
||||
if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
|
||||
// Shared bank inventory
|
||||
if (!inst)
|
||||
return DeleteSharedBankSlot(char_id, slot_id);
|
||||
else
|
||||
return UpdateSharedBankSlot(char_id, inst, slot_id);
|
||||
if (!inst) {
|
||||
return DeleteSharedBankSlot(char_id, slot_id);
|
||||
}
|
||||
else {
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateSharedBankSlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteSharedBankSlot(char_id, slot_id);
|
||||
return UpdateSharedBankSlot(char_id, inst, slot_id);
|
||||
}
|
||||
}
|
||||
else if (!inst) { // All other inventory
|
||||
return DeleteInventorySlot(char_id, slot_id);
|
||||
}
|
||||
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateInventorySlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteInventorySlot(char_id, slot_id);
|
||||
return UpdateInventorySlot(char_id, inst, slot_id);
|
||||
}
|
||||
|
||||
@@ -209,7 +212,9 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id))
|
||||
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
@@ -253,7 +258,9 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) {
|
||||
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
@@ -1158,7 +1165,7 @@ void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
|
||||
auto row = results.begin();
|
||||
|
||||
list_count = static_cast<uint32>(atoul(row[0]));
|
||||
max_lists = static_cast<uint32>(atoul(row[1]));
|
||||
max_lists = static_cast<uint32>(atoul(row[1] ? row[1] : "0"));
|
||||
}
|
||||
|
||||
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
|
||||
@@ -1235,9 +1242,6 @@ bool SharedDatabase::LoadNPCFactionLists() {
|
||||
uint32 list_count = 0;
|
||||
uint32 max_lists = 0;
|
||||
GetFactionListInfo(list_count, max_lists);
|
||||
if(list_count == 0) {
|
||||
EQ_EXCEPT("SharedDatabase", "Database returned no result");
|
||||
}
|
||||
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<NPCFactionList>::estimated_size(
|
||||
list_count, max_lists));
|
||||
|
||||
@@ -1837,7 +1841,7 @@ void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot
|
||||
auto row = results.begin();
|
||||
|
||||
loot_table_count = static_cast<uint32>(atoul(row[0]));
|
||||
max_loot_table = static_cast<uint32>(atoul(row[1]));
|
||||
max_loot_table = static_cast<uint32>(atoul(row[1] ? row[1] : "0"));
|
||||
loot_table_entries = static_cast<uint32>(atoul(row[2]));
|
||||
}
|
||||
|
||||
@@ -1858,7 +1862,7 @@ void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_d
|
||||
auto row =results.begin();
|
||||
|
||||
loot_drop_count = static_cast<uint32>(atoul(row[0]));
|
||||
max_loot_drop = static_cast<uint32>(atoul(row[1]));
|
||||
max_loot_drop = static_cast<uint32>(atoul(row[1] ? row[1] : "0"));
|
||||
loot_drop_entries = static_cast<uint32>(atoul(row[2]));
|
||||
}
|
||||
|
||||
@@ -2074,4 +2078,4 @@ bool SharedDatabase::VerifyToken(std::string token, int& status) {
|
||||
auto row = results.begin();
|
||||
status = atoi(row[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,8 @@ enum SkillUseTypes
|
||||
|
||||
// temporary until it can be sorted out...
|
||||
#define HIGHEST_SKILL SkillFrenzy
|
||||
// Spell Effects use this value to determine if an effect applies to all skills.
|
||||
#define ALL_SKILLS -1
|
||||
|
||||
// server profile does not reflect this yet..so, prefixed with 'PACKET_'
|
||||
#define PACKET_SKILL_ARRAY_SIZE 100
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
||||
|
||||
#define CURRENT_VERSION "1.0.0"
|
||||
#define CURRENT_VERSION "1.1.3"
|
||||
|
||||
/*
|
||||
Everytime a Database SQL is added to Github,
|
||||
@@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9075
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9077
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
|
||||
Reference in New Issue
Block a user