Updated item/say links for all clients. They should be a little easier to keep track of now.

This commit is contained in:
Uleat 2014-12-25 11:04:01 -05:00
parent 15fbb722eb
commit 270fe3389c
8 changed files with 213 additions and 218 deletions

View File

@ -1,5 +1,8 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 12/25/2014 ==
Uleat: Updated 'links' code for all clients
== 12/24/2014 ==
Trevius: (RoF+) Added herosforgemodel field to the npc_types table.
Trevius: (RoF2) Updated item links from #npcstat command output.

View File

@ -11718,7 +11718,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
c->Message(13, "Database Error: %s", TempErrorMessage.c_str());
return;
}
if(item2 == 0) {
if(item2 == nullptr) {
c->Message(15, "I need something for my %s (Item %i)", equipped[i], i);
continue;
}
@ -11726,79 +11726,31 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
is2Hweapon = true;
}
char* itemLink = 0;
if((i == MainCharm) || (i == MainRange) || (i == MainPrimary) || (i == MainSecondary) || (i == MainAmmo)) {
if (c->GetClientVersion() >= EQClientSoF)
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0,
0
);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
else
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
}
else {
if (c->GetClientVersion() >= EQClientSoF)
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0,
0
);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
else
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
}
char* link_core = nullptr;
std::string link_base;
// I could not find a difference between the criteria positive code and the criteria negative code..
// ..so, I deleted the check (criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo })
c->MakeItemLink(
link_core,
item2,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
item1->GetAugmentItemID(5)
);
if (link_core)
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item2->Name, 0x12);
else
link_base = "<CLIENT VERSION ERROR>";
c->Message(15, "Using %s in my %s (Item %i)", link_base.c_str(), equipped[i], i);
safe_delete_array(link_core);
}
}
else {

View File

@ -815,8 +815,11 @@ public:
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);
bool MakeItemLink(char* &ret_link, const Item_Struct* item, uint32 aug0=0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0);
bool MakeItemLink(char* &ret_link, const Item_Struct* item, uint32 aug0=0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0, uint8 evolving=0, uint8 evolvedlevel=0);
bool MakeItemLink(char* &ret_link, const ItemInst* inst);
bool MakeTaskLink(char* &ret_link);
bool MakeBlankLink(char* &ret_link);
static bool MakeBlankLink_(char* &ret_link);
int GetItemLinkHash(const ItemInst* inst);
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
@ -834,11 +837,11 @@ public:
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
bool Thirsty() const {if (GetGM()) return false; return m_pp.thirst_level <= 3000;}
int32 GetHunger() const { return m_pp.hunger_level; }
int32 GetThirst() const { return m_pp.thirst_level; }
void SetHunger(int32 in_hunger);
void SetThirst(int32 in_thirst);
void SetConsumption(int32 in_hunger, int32 in_thirst);
int32 GetHunger() const { return m_pp.hunger_level; }
int32 GetThirst() const { return m_pp.thirst_level; }
void SetHunger(int32 in_hunger);
void SetThirst(int32 in_thirst);
void SetConsumption(int32 in_hunger, int32 in_thirst);
bool CheckTradeLoreConflict(Client* other);
void LinkDead();

View File

@ -5632,75 +5632,74 @@ void command_givemoney(Client *c, const Seperator *sep)
void command_itemsearch(Client *c, const Seperator *sep)
{
if (sep->arg[1][0] == 0)
if (sep->arg[1][0] == 0) {
c->Message(0, "Usage: #itemsearch [search string]");
}
else
{
const char *search_criteria=sep->argplus[1];
const Item_Struct* item = 0;
const Item_Struct* item = nullptr;
if (Seperator::IsNumber(search_criteria)) {
item = database.GetItem(atoi(search_criteria));
if (item)
if (c->GetClientVersion() >= EQClientRoF2)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientRoF)
{
c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientSoF)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
if (item) {
char* link_core = nullptr;
std::string link_base;
c->MakeItemLink(link_core, item);
if (link_core)
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item->Name, 0x12);
else
{
c->Message(0, " %i: %c%06X000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else
link_base = "<CLIENT VERSION ERROR>";
c->Message(0, "%i: %s", (int)item->ID, link_base.c_str());
safe_delete_array(link_core);
}
else {
c->Message(0, "Item #%s not found", search_criteria);
}
return;
}
int count = 0;
int count = NOT_USED;
char sName[64];
char sCriteria[255];
strn0cpy(sCriteria, search_criteria, sizeof(sCriteria));
strupr(sCriteria);
char* pdest;
uint32 it = 0;
uint32 it = NOT_USED;
while ((item = database.IterateItems(&it))) {
strn0cpy(sName, item->Name, sizeof(sName));
strupr(sName);
pdest = strstr(sName, sCriteria);
if (pdest != nullptr) {
if (c->GetClientVersion() >= EQClientRoF2)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000000000%s%c", (int)item->ID, 0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientRoF)
{
c->Message(0, " %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else if (c->GetClientVersion() >= EQClientSoF)
{
c->Message(0, " %i: %c%06X00000000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
char* link_core = nullptr;
std::string link_base;
c->MakeItemLink(link_core, item);
if (link_core)
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item->Name, 0x12);
else
{
c->Message(0, " %i: %c%06X000000000000000000000000000000000000000%s%c",(int) item->ID,0x12, item->ID, item->Name, 0x12);
}
count++;
link_base = "<CLIENT VERSION ERROR>";
c->Message(0, "%i: %s", (int)item->ID, link_base.c_str());
safe_delete_array(link_core);
++count;
}
if (count == 50)
break;
}
if (count == 50)
c->Message(0, "50 items shown...too many results.");
else
c->Message(0, "%i items found", count);
}
}

View File

@ -1027,7 +1027,7 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
}
}
bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5) {
bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) {
//we're sending back the entire "link", minus the null characters & item name
//that way, we can use it for regular links & Task links
//note: initiator needs to pass us ret_link
@ -1049,13 +1049,19 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
//length:
//1 5 5 5 5 5 5 1 4 1 8 = 45
//evolving item info: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145#558
uint8 evolving = 0;
uint16 loregroup = 0;
uint8 evolvedlevel = 0;
int hash = 0;
//int hash = GetItemLinkHash(inst); //eventually this will work (currently crashes zone), but for now we'll skip the extra overhead
if (GetClientVersion() >= EQClientRoF2)
{
int hash = NOT_USED;
// Tested with UF and RoF..there appears to be a problem with using non-augment arguments below...
// Currently, enabling them causes misalignments in what the client expects. I haven't looked
// into it further to determine the cause..but, the function is setup to accept the parameters.
// Note: some links appear with '00000' in front of the name..so, it's likely we need to send
// some additional information when certain parameters are true -U
switch (GetClientVersion()) {
case EQClientRoF2:
// This operator contains 14 parameter masks..but, only 13 parameter values.
// Even so, the client link appears ok... Need to figure out the discrepancy -U
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
@ -1065,17 +1071,14 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
aug3,
aug4,
aug5,
//0, this, or below, needs to be activated..not sure which yet
evolving,
//0, this, or above, needs to be activated..not sure which yet
loregroup,
evolvedlevel,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else if (GetClientVersion() >= EQClientRoF)
{
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
@ -1085,15 +1088,16 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
aug3,
aug4,
aug5,
evolving,
loregroup,
evolvedlevel,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else if (GetClientVersion() >= EQClientSoF)
{
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
@ -1102,15 +1106,14 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
aug2,
aug3,
aug4,
evolving,
loregroup,
evolvedlevel,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else
{
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item->ID,
@ -1119,14 +1122,16 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
aug2,
aug3,
aug4,
evolving,
loregroup,
evolvedlevel,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
hash
);
return true;
case EQClient62:
default:
return false;
}
return true;
}
bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
@ -1141,10 +1146,64 @@ bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5)
inst->GetAugmentItemID(5),
inst->IsEvolving(),
inst->GetEvolveLvl()
);
}
bool Client::MakeTaskLink(char* &ret_link)
{
switch (GetClientVersion()) {
case EQClientRoF2:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000014505DC2");
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "0000000000000000000000000000000000000000014505DC2");
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000014505DC2");
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "000000000000000000000000000000014505DC2");
return true;
case EQClient62:
default:
return false;
}
}
bool Client::MakeBlankLink(char* &ret_link)
{
switch (GetClientVersion()) {
case EQClientRoF2:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000000000");
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "0000000000000000000000000000000000000000000000000");
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000");
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "000000000000000000000000000000000000000");
return true;
case EQClient62:
default:
return false;
}
}
bool Client::MakeBlankLink_(char* &ret_link)
{
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000000000"); // should be same as newest/longest client in local operator
return true;
}
int Client::GetItemLinkHash(const ItemInst* inst) {
//pre-Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=70&postdays=0&postorder=asc
//Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145

View File

@ -517,7 +517,7 @@ void NPC::QueryLoot(Client* to)
to->MakeItemLink(itemLinkCore, item);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, item->Name, 0x12) : "null");
to->Message(0, "%s, ID: %u, Level: (min: , max: )", itemLink.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level);
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", itemLink.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level);
safe_delete_array(itemLinkCore);
}

View File

@ -2468,6 +2468,7 @@ const char* QuestManager::varlink(char* perltext, int item_id) {
return "INVALID ITEM ID IN VARLINK";
char* link = 0;
char* tempstr = 0;
// already uses Client::operator-based item link method
if (initiator->MakeItemLink(link, inst)) { // make a link to the item
snprintf(perltext, 250, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12);
}
@ -2658,24 +2659,33 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
sayid = sayid + 500000;
//Create the say link as an item link hash
char linktext[250];
char* link_core = nullptr;
std::string say_link;
if (initiator) {
if (initiator->GetClientVersion() >= EQClientRoF2)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientRoF)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "0000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientSoF)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000", LinkName, 0x12);
initiator->MakeBlankLink(link_core);
if (link_core)
say_link = StringFormat("%c%06x%s%s%c", 0x12, sayid, link_core, LinkName, 0x12);
else
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "000000000000000000000000000000000000000", LinkName, 0x12);
} else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones.
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
say_link = "<CLIENT VERSION ERROR>";
safe_delete_array(link_core);
}
else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones.
Client::MakeBlankLink_(link_core); // Note: this is a global operator
}
strcpy(Phrase,linktext);
return Phrase;
if (say_link.length() > 250)
strcpy(Phrase, "<SAYLINK OVER-LENGTH ERROR>");
else if (say_link.length() == 0)
strcpy(Phrase, "<SAYLINK NULL-LENGTH ERROR>");
else
strcpy(Phrase, say_link.c_str());
// Why do we have '(char*)Phrase' as an argument and then return it?
// The current behavior of this function doesn't allow recursive action
return Phrase;
}
const char* QuestManager::getguildnamebyid(int guild_id) {

View File

@ -2743,17 +2743,17 @@ void TaskManager::SendSingleActiveTaskToClient(Client *c, int TaskIndex, bool Ta
}
}
void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal) {
if((TaskID<1) || (TaskID>=MAXTASKS) || !Tasks[TaskID]) return;
void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal)
{
if ((TaskID < 1) || (TaskID >= MAXTASKS) || !Tasks[TaskID])
return;
int PacketLength = sizeof(TaskDescriptionHeader_Struct) + strlen(Tasks[TaskID]->Title) + 1
+ sizeof(TaskDescriptionData1_Struct) + strlen(Tasks[TaskID]->Description) + 1
+ sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct);
std::string RewardText;
int ItemID = 0;
int ItemID = NOT_USED;
// If there is an item make the Reward text into a link to the item (only the first item if a list
// is specified). I have been unable to get multiple item links to work.
@ -2768,62 +2768,31 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
if(ItemID < 0)
ItemID = 0;
}
if(ItemID) {
char *RewardTmp = 0;
if(strlen(Tasks[TaskID]->Reward) != 0) {
char* link_core = nullptr;
std::string reward_link;
switch(c->GetClientVersion()) {
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
break;
}
case EQClientRoF:
{
MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
break;
}
default:
{
// All clients after Titanium
MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
}
}
c->MakeTaskLink(link_core);
if (link_core && (strlen(Tasks[TaskID]->Reward) != 0)) {
reward_link = StringFormat("%c%06x%s%s%c", 0x12, ItemID, link_core, Tasks[TaskID]->Reward, 0x12);
}
else if (link_core) {
const Item_Struct* Item = database.GetItem(ItemID);
if (Item)
reward_link = StringFormat("%c%06x%s%s%c", 0x12, ItemID, link_core, Item->Name, 0x12);
else
reward_link = "<ITEM ID ERROR>";
}
else {
const Item_Struct *Item = database.GetItem(ItemID);
if(Item) {
switch(c->GetClientVersion()) {
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
break;
}
case EQClientRoF:
{
MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
break;
}
default:
{
// All clients after Titanium
MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
}
}
}
reward_link = "<CLIENT VERSION ERROR>";
}
if(RewardTmp) RewardText += RewardTmp;
safe_delete_array(RewardTmp);
if(reward_link.length() != 0)
RewardText += reward_link.c_str();
safe_delete_array(link_core);
}
else {
RewardText += Tasks[TaskID]->Reward;