mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-16 08:42:25 +00:00
Merge master, fix conflicts
This commit is contained in:
commit
b3c53e5907
@ -1,5 +1,12 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 02/20/2015 ==
|
||||
demonstar55: Implement claims for RoF/RoF2 (should no longer crash the client!)
|
||||
- fixed bugs related to claims for the rest of the clients (woo infinite loops)
|
||||
|
||||
== 02/18/2015 ==
|
||||
Trevius: Fix for potential recursive loops if using RemoveFromHateList() within EVENT_HATE_LIST.
|
||||
|
||||
== 02/17/2015 ==
|
||||
Uleat: Implemented per-client character creation limiting. Caps are unknown atm..so, don't get over-zealous!
|
||||
Notes:
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -2776,7 +2776,8 @@ struct BazaarWelcome_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint8 Unknown012[8];
|
||||
uint32 Unknown012;
|
||||
uint32 Unknown016;
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
@ -3207,7 +3208,7 @@ struct TraderDelItem_Struct{
|
||||
|
||||
struct TraderClick_Struct{
|
||||
/*000*/ uint32 TraderID;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*004*/ uint32 Code;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Approval;
|
||||
/*016*/
|
||||
@ -4552,19 +4553,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
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
|
||||
namespace RoF
|
||||
{
|
||||
@ -3608,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;
|
||||
}
|
||||
|
||||
@ -4924,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);
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
#include <cassert>
|
||||
|
||||
namespace RoF2
|
||||
{
|
||||
@ -3667,6 +3669,23 @@ namespace RoF2
|
||||
|
||||
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);
|
||||
@ -3732,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;
|
||||
}
|
||||
|
||||
@ -5009,8 +5062,25 @@ namespace RoF2
|
||||
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();
|
||||
}
|
||||
@ -5026,9 +5096,9 @@ namespace RoF2
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): (Unknowns) Unknown004 %d, Unknown008 %d, Unknown012 %d, Unknown076 %d, Unknown276 %d",
|
||||
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): Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||
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();
|
||||
@ -5088,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);
|
||||
|
||||
@ -111,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)
|
||||
@ -174,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)
|
||||
|
||||
@ -2940,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 {
|
||||
@ -4725,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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -4718,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
|
||||
|
||||
@ -1918,7 +1918,7 @@ namespace SoD
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = eq->TotalChars;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
@ -1577,7 +1577,7 @@ namespace SoF
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = eq->TotalChars;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
@ -1192,12 +1192,12 @@ namespace Titanium
|
||||
}
|
||||
|
||||
eq->SecondaryIDFile[char_index] = emu_cse->SecondaryIDFile;
|
||||
eq->Unknown820[char_index] = 0xFF;
|
||||
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] = 0xFF;
|
||||
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;
|
||||
@ -1229,18 +1229,20 @@ namespace Titanium
|
||||
}
|
||||
|
||||
eq->SecondaryIDFile[char_index] = 0;
|
||||
eq->Unknown820[char_index] = 0xFF;
|
||||
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] = 0xFF;
|
||||
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;
|
||||
//eq->Name[char_index][0] = '\0'; // Cleared above
|
||||
|
||||
strncpy(eq->Name[char_index], "<none>", 6);
|
||||
|
||||
eq->Gender[char_index] = 0;
|
||||
eq->EyeColor1[char_index] = 0;
|
||||
eq->EyeColor2[char_index] = 0;
|
||||
|
||||
@ -2201,7 +2201,7 @@ namespace UF
|
||||
if (emu->CharCount == 0) {
|
||||
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
|
||||
eq->CharCount = emu->CharCount;
|
||||
eq->TotalChars = eq->TotalChars;
|
||||
eq->TotalChars = emu->TotalChars;
|
||||
|
||||
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
|
||||
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
@ -525,7 +525,7 @@ OP_KnowledgeBase=0x0000
|
||||
OP_SlashAdventure=0x571a # /adventure
|
||||
OP_VetRewardsAvaliable=0x0557
|
||||
OP_VetClaimRequest=0x6ba0
|
||||
OP_VetClaimReply=0x0000
|
||||
OP_VetClaimReply=0x407e
|
||||
OP_BecomePVPPrompt=0x36B2 #guessed from ASM
|
||||
OP_PVPStats=0x5cc0
|
||||
OP_PVPLeaderBoardRequest=0x61d2
|
||||
|
||||
@ -115,7 +115,16 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
cse->Instance = 0;
|
||||
cse->Gender = (uint8)atoi(row[2]);
|
||||
cse->Face = (uint8)atoi(row[15]);
|
||||
cse->Equip[0] = { 0 }; // Processed below
|
||||
|
||||
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++) { // Processed below
|
||||
cse->Equip[matslot].Material = 0;
|
||||
cse->Equip[matslot].Unknown1 = 0;
|
||||
cse->Equip[matslot].EliteMaterial = 0;
|
||||
cse->Equip[matslot].HeroForgeModel = 0;
|
||||
cse->Equip[matslot].Material2 = 0;
|
||||
cse->Equip[matslot].Color.Color = 0;
|
||||
}
|
||||
|
||||
cse->Unknown15 = 0xFF;
|
||||
cse->Unknown19 = 0xFF;
|
||||
cse->DrakkinTattoo = (uint32)atoi(row[17]);
|
||||
@ -194,6 +203,18 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
}
|
||||
/* Bind End */
|
||||
|
||||
/* Load Character Material Data for Char Select */
|
||||
cquery = StringFormat("SELECT slot, red, green, blue, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
|
||||
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
|
||||
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
|
||||
slot = atoi(row_b[0]);
|
||||
pp.item_tint[slot].RGB.Red = atoi(row_b[1]);
|
||||
pp.item_tint[slot].RGB.Green = atoi(row_b[2]);
|
||||
pp.item_tint[slot].RGB.Blue = atoi(row_b[3]);
|
||||
pp.item_tint[slot].RGB.UseTint = atoi(row_b[4]);
|
||||
}
|
||||
/* Character Material Data End */
|
||||
|
||||
/* Load Inventory */
|
||||
// If we ensure that the material data is updated appropriately, we can do away with inventory loads
|
||||
if (GetInventory(accountID, cse->Name, &inv)) {
|
||||
@ -252,17 +273,6 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
}
|
||||
/* Load Inventory End */
|
||||
|
||||
/* Load Character Material Data for Char Select */
|
||||
cquery = StringFormat("SELECT slot, red, green, blue, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
|
||||
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
|
||||
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
|
||||
slot = atoi(row_b[0]);
|
||||
pp.item_tint[slot].RGB.Red = atoi(row_b[1]);
|
||||
pp.item_tint[slot].RGB.Green = atoi(row_b[2]);
|
||||
pp.item_tint[slot].RGB.Blue = atoi(row_b[3]);
|
||||
pp.item_tint[slot].RGB.UseTint = atoi(row_b[4]);
|
||||
}
|
||||
|
||||
buff_ptr += sizeof(CharacterSelectEntry_Struct);
|
||||
}
|
||||
}
|
||||
|
||||
@ -917,6 +917,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
||||
{
|
||||
int dmg = 0;
|
||||
int banedmg = 0;
|
||||
int x = 0;
|
||||
|
||||
if(!against || against->GetInvul() || against->GetSpecialAbility(IMMUNE_MELEE)){
|
||||
return 0;
|
||||
@ -945,10 +946,20 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
||||
bool MagicWeapon = false;
|
||||
if(weapon_item->GetItem() && weapon_item->GetItem()->Magic)
|
||||
MagicWeapon = true;
|
||||
else {
|
||||
else
|
||||
if(spellbonuses.MagicWeapon || itembonuses.MagicWeapon)
|
||||
MagicWeapon = true;
|
||||
}
|
||||
else
|
||||
// An augment on the weapon that is marked magic makes
|
||||
// the item magical.
|
||||
for(x = 0; MagicWeapon == false && x < EmuConstants::ITEM_COMMON_SIZE; x++)
|
||||
{
|
||||
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem())
|
||||
{
|
||||
if (weapon_item->GetAugment(x)->GetItem()->Magic)
|
||||
MagicWeapon = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(MagicWeapon) {
|
||||
|
||||
|
||||
@ -5362,35 +5362,35 @@ void Client::SendRewards()
|
||||
FastQueuePacket(&vetapp);
|
||||
}
|
||||
|
||||
bool Client::TryReward(uint32 claim_id) {
|
||||
//Make sure we have an open spot
|
||||
//Make sure we have it in our acct and count > 0
|
||||
//Make sure the entry was found
|
||||
//If we meet all the criteria:
|
||||
//Decrement our count by 1 if it > 1 delete if it == 1
|
||||
//Create our item in bag if necessary at the free inv slot
|
||||
//save
|
||||
bool Client::TryReward(uint32 claim_id)
|
||||
{
|
||||
// Make sure we have an open spot
|
||||
// Make sure we have it in our acct and count > 0
|
||||
// Make sure the entry was found
|
||||
// If we meet all the criteria:
|
||||
// Decrement our count by 1 if it > 1 delete if it == 1
|
||||
// Create our item in bag if necessary at the free inv slot
|
||||
// save
|
||||
uint32 free_slot = 0xFFFFFFFF;
|
||||
|
||||
for(int i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; ++i) {
|
||||
for (int i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; ++i) {
|
||||
ItemInst *item = GetInv().GetItem(i);
|
||||
if(!item) {
|
||||
if (!item) {
|
||||
free_slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(free_slot == 0xFFFFFFFF)
|
||||
if (free_slot == 0xFFFFFFFF)
|
||||
return false;
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
std::string query = StringFormat("SELECT amount FROM account_rewards "
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
if (!results.Success())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
@ -5398,58 +5398,57 @@ bool Client::TryReward(uint32 claim_id) {
|
||||
auto row = results.begin();
|
||||
|
||||
uint32 amt = atoi(row[0]);
|
||||
if(amt == 0)
|
||||
if (amt == 0)
|
||||
return false;
|
||||
|
||||
std::list<InternalVeteranReward>::iterator iter = zone->VeteranRewards.begin();
|
||||
for (; iter != zone->VeteranRewards.end(); ++row)
|
||||
if((*iter).claim_id == claim_id)
|
||||
break;
|
||||
auto iter = std::find_if(zone->VeteranRewards.begin(), zone->VeteranRewards.end(),
|
||||
[claim_id](const InternalVeteranReward &a) { return a.claim_id == claim_id; });
|
||||
|
||||
if(iter == zone->VeteranRewards.end())
|
||||
if (iter == zone->VeteranRewards.end())
|
||||
return false;
|
||||
|
||||
if(amt == 1) {
|
||||
if (amt == 1) {
|
||||
query = StringFormat("DELETE FROM account_rewards "
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
query = StringFormat("UPDATE account_rewards SET amount = (amount-1) "
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
"WHERE account_id = %i AND reward_id = %i",
|
||||
AccountID(), claim_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
InternalVeteranReward ivr = (*iter);
|
||||
auto &ivr = (*iter);
|
||||
ItemInst *claim = database.CreateItemOld(ivr.items[0].item_id, ivr.items[0].charges);
|
||||
if(!claim) {
|
||||
if (!claim) {
|
||||
Save();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lore_conflict = CheckLoreConflict(claim->GetItem());
|
||||
|
||||
for(int y = 1; y < 8; y++)
|
||||
if(ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
|
||||
for (int y = 1; y < 8; y++)
|
||||
if (ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
|
||||
ItemInst *item_temp = database.CreateItemOld(ivr.items[y].item_id, ivr.items[y].charges);
|
||||
if(item_temp) {
|
||||
if(CheckLoreConflict(item_temp->GetItem())) {
|
||||
if (item_temp) {
|
||||
if (CheckLoreConflict(item_temp->GetItem())) {
|
||||
lore_conflict = true;
|
||||
DuplicateLoreMessage(ivr.items[y].item_id);
|
||||
}
|
||||
claim->PutItem(y-1, *item_temp);
|
||||
claim->PutItem(y - 1, *item_temp);
|
||||
safe_delete(item_temp);
|
||||
}
|
||||
}
|
||||
|
||||
if(lore_conflict) {
|
||||
if (lore_conflict) {
|
||||
safe_delete(claim);
|
||||
return true;
|
||||
}
|
||||
|
||||
PutItemInInventory(free_slot, *claim);
|
||||
SendItemPacket(free_slot, claim, ItemPacketTrade);
|
||||
safe_delete(claim);
|
||||
|
||||
Save();
|
||||
return true;
|
||||
|
||||
@ -13516,49 +13516,68 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app)
|
||||
|
||||
if (app->size == sizeof(TraderClick_Struct))
|
||||
{
|
||||
// This is when a potential purchaser right clicks on this client who is in Trader mode to
|
||||
// browse their goods.
|
||||
|
||||
TraderClick_Struct* tcs = (TraderClick_Struct*)app->pBuffer;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderClick_Struct));
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Handle_OP_TraderShop: TraderClick_Struct TraderID %d, Code %d, Unknown008 %d, Approval %d",
|
||||
tcs->TraderID, tcs->Code, tcs->Unknown008, tcs->Approval);
|
||||
|
||||
TraderClick_Struct* outtcs = (TraderClick_Struct*)outapp->pBuffer;
|
||||
|
||||
Client* Trader = entity_list.GetClientByID(tcs->TraderID);
|
||||
|
||||
if (Trader)
|
||||
if (tcs->Code == BazaarWelcome)
|
||||
{
|
||||
outtcs->Approval = Trader->WithCustomer(GetID());
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Shop Request (%s) to (%s) with Approval: %d", GetCleanName(), Trader->GetCleanName(), outtcs->Approval);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: entity_list.GetClientByID(tcs->traderid)"
|
||||
" returned a nullptr pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
outtcs->TraderID = tcs->TraderID;
|
||||
|
||||
outtcs->Unknown008 = 0x3f800000;
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
|
||||
if (outtcs->Approval) {
|
||||
this->BulkSendTraderInventory(Trader->CharacterID());
|
||||
Trader->Trader_CustomerBrowsing(this);
|
||||
TraderID = tcs->TraderID;
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Inventory Sent");
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Sent Bazaar Welcome Info");
|
||||
SendBazaarWelcome();
|
||||
}
|
||||
else
|
||||
{
|
||||
Message_StringID(clientMessageYellow, TRADER_BUSY);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy");
|
||||
// This is when a potential purchaser right clicks on this client who is in Trader mode to
|
||||
// browse their goods.
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderClick_Struct));
|
||||
|
||||
TraderClick_Struct* outtcs = (TraderClick_Struct*)outapp->pBuffer;
|
||||
|
||||
Client* Trader = entity_list.GetClientByID(tcs->TraderID);
|
||||
|
||||
if (Trader)
|
||||
{
|
||||
outtcs->Approval = Trader->WithCustomer(GetID());
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Shop Request (%s) to (%s) with Approval: %d", GetCleanName(), Trader->GetCleanName(), outtcs->Approval);
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: entity_list.GetClientByID(tcs->traderid)"
|
||||
" returned a nullptr pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
outtcs->TraderID = tcs->TraderID;
|
||||
|
||||
outtcs->Unknown008 = 0x3f800000;
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
|
||||
if (outtcs->Approval) {
|
||||
this->BulkSendTraderInventory(Trader->CharacterID());
|
||||
Trader->Trader_CustomerBrowsing(this);
|
||||
TraderID = tcs->TraderID;
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Inventory Sent");
|
||||
}
|
||||
else
|
||||
{
|
||||
Message_StringID(clientMessageYellow, TRADER_BUSY);
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy");
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (app->size == sizeof(BazaarWelcome_Struct))
|
||||
{
|
||||
// RoF+
|
||||
// Client requested Bazaar Welcome Info (Trader and Item Total Counts)
|
||||
SendBazaarWelcome();
|
||||
Log.Out(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Sent Bazaar Welcome Info");
|
||||
}
|
||||
else if (app->size == sizeof(TraderBuy_Struct))
|
||||
{
|
||||
@ -13774,41 +13793,32 @@ void Client::Handle_OP_TributeUpdate(const EQApplicationPacket *app)
|
||||
|
||||
void Client::Handle_OP_VetClaimRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size < sizeof(VeteranClaimRequest))
|
||||
{
|
||||
Log.Out(Logs::General, Logs::None, "OP_VetClaimRequest size lower than expected: got %u expected at least %u", app->size, sizeof(VeteranClaimRequest));
|
||||
if (app->size < sizeof(VeteranClaim)) {
|
||||
Log.Out(Logs::General, Logs::None,
|
||||
"OP_VetClaimRequest size lower than expected: got %u expected at least %u", app->size,
|
||||
sizeof(VeteranClaim));
|
||||
DumpPacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
VeteranClaimRequest *vcr = (VeteranClaimRequest*)app->pBuffer;
|
||||
VeteranClaim *vcr = (VeteranClaim *)app->pBuffer;
|
||||
|
||||
if (vcr->claim_id == 0xFFFFFFFF) //request update packet
|
||||
{
|
||||
if (vcr->claim_id == 0xFFFFFFFF) { // request update packet
|
||||
SendRewards();
|
||||
return;
|
||||
}
|
||||
else //try to claim something!
|
||||
{
|
||||
if (!TryReward(vcr->claim_id))
|
||||
{
|
||||
Message(13, "Your claim has been rejected.");
|
||||
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetClaimReply, sizeof(VeteranClaimReply));
|
||||
VeteranClaimReply * cr = (VeteranClaimReply*)vetapp->pBuffer;
|
||||
strcpy(cr->name, GetName());
|
||||
cr->claim_id = vcr->claim_id;
|
||||
cr->reject_field = -1;
|
||||
FastQueuePacket(&vetapp);
|
||||
}
|
||||
else
|
||||
{
|
||||
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetClaimReply, sizeof(VeteranClaimReply));
|
||||
VeteranClaimReply * cr = (VeteranClaimReply*)vetapp->pBuffer;
|
||||
strcpy(cr->name, GetName());
|
||||
cr->claim_id = vcr->claim_id;
|
||||
cr->reject_field = 0;
|
||||
FastQueuePacket(&vetapp);
|
||||
}
|
||||
}
|
||||
// try to claim something!
|
||||
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetClaimReply, sizeof(VeteranClaim));
|
||||
VeteranClaim *cr = (VeteranClaim *)vetapp->pBuffer;
|
||||
strcpy(cr->name, GetName());
|
||||
cr->claim_id = vcr->claim_id;
|
||||
|
||||
if (!TryReward(vcr->claim_id))
|
||||
cr->action = 1;
|
||||
else
|
||||
cr->action = 0;
|
||||
|
||||
FastQueuePacket(&vetapp);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_VoiceMacroIn(const EQApplicationPacket *app)
|
||||
|
||||
@ -1844,7 +1844,7 @@ void Client::DoHPRegen() {
|
||||
}
|
||||
|
||||
void Client::DoManaRegen() {
|
||||
if (GetMana() >= max_mana)
|
||||
if (GetMana() >= max_mana && spellbonuses.ManaRegen >= 0)
|
||||
return;
|
||||
|
||||
SetMana(GetMana() + CalcManaRegen() + RestRegenMana);
|
||||
|
||||
@ -219,17 +219,17 @@ bool HateList::RemoveEntFromHateList(Mob *in_entity)
|
||||
{
|
||||
if ((*iterator)->entity_on_hatelist == in_entity)
|
||||
{
|
||||
if (in_entity)
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "0", 0);
|
||||
is_found = true;
|
||||
|
||||
|
||||
if (in_entity && in_entity->IsClient())
|
||||
in_entity->CastToClient()->DecrementAggroCount();
|
||||
|
||||
delete (*iterator);
|
||||
iterator = list.erase(iterator);
|
||||
|
||||
if (in_entity)
|
||||
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "0", 0);
|
||||
|
||||
}
|
||||
else
|
||||
++iterator;
|
||||
|
||||
@ -1558,18 +1558,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic
|
||||
return;
|
||||
}
|
||||
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
|
||||
if (Trader->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
//outapp = new EQApplicationPacket(OP_TraderShop, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
//outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
}
|
||||
|
||||
outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Trader, sizeof(TraderBuy_Struct));
|
||||
|
||||
TraderBuy_Struct* outtbs = (TraderBuy_Struct*)outapp->pBuffer;
|
||||
|
||||
@ -1701,7 +1690,15 @@ void Client::SendBazaarWelcome()
|
||||
if (results.Success() && results.RowCount() == 1){
|
||||
auto row = results.begin();
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
outapp = new EQApplicationPacket(OP_TraderShop, sizeof(BazaarWelcome_Struct));
|
||||
}
|
||||
else
|
||||
{
|
||||
outapp = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarWelcome_Struct));
|
||||
}
|
||||
|
||||
memset(outapp->pBuffer,0,outapp->size);
|
||||
|
||||
@ -1712,6 +1709,11 @@ void Client::SendBazaarWelcome()
|
||||
bws->Traders = atoi(row[0]);
|
||||
bws->Items = atoi(row[1]);
|
||||
|
||||
if (GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
bws->Unknown012 = GetID();
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
@ -1231,20 +1231,25 @@ bool ZoneDatabase::LoadCharacterTribute(uint32 character_id, PlayerProfile_Struc
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp)
|
||||
bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct *pp)
|
||||
{
|
||||
std::string query = StringFormat("SELECT `potion_id`, `item_id`, `icon` FROM `character_potionbelt` WHERE `id` = %u LIMIT %u",
|
||||
character_id, EmuConstants::POTION_BELT_ITEM_COUNT);
|
||||
auto results = database.QueryDatabase(query); int i = 0;
|
||||
for (i = 0; i < EmuConstants::POTION_BELT_ITEM_COUNT; i++){
|
||||
std::string query =
|
||||
StringFormat("SELECT `potion_id`, `item_id`, `icon` FROM `character_potionbelt` WHERE `id` = %u LIMIT %u",
|
||||
character_id, EmuConstants::POTION_BELT_ITEM_COUNT);
|
||||
auto results = database.QueryDatabase(query);
|
||||
int i = 0;
|
||||
for (i = 0; i < EmuConstants::POTION_BELT_ITEM_COUNT; i++) {
|
||||
pp->potionbelt.Items[i].Icon = 0;
|
||||
pp->potionbelt.Items[i].ID = 0;
|
||||
pp->potionbelt.Items[i].Name[0] = '\0';
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
i = atoi(row[0]);
|
||||
const ItemData *item_data = database.GetItem(atoi(row[1]));
|
||||
if (item_data == nullptr) { continue; }
|
||||
if (!item_data)
|
||||
continue;
|
||||
|
||||
pp->potionbelt.Items[i].ID = item_data->ID;
|
||||
pp->potionbelt.Items[i].Icon = atoi(row[2]);
|
||||
strncpy(pp->potionbelt.Items[i].Name, item_data->Name, 64);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user