Rework say links

We now consume 1 item ID for say links, this means you will be able to create
more items! We used ID 0xFFFFF for this, which is the max ID an item can be
in the item links. You have the rest to play with!

Normal say links pass the ID in the first aug slot and silent say links
in the second aug slot. This means we can have MANY more say links as well!
This commit is contained in:
Michael Cook (mackal) 2016-01-20 22:31:35 -05:00
parent 04b7ba7a1d
commit d86307c720
5 changed files with 72 additions and 88 deletions

View File

@ -273,6 +273,9 @@ enum {
#define NPC_DEFAULT_LOGGING_ENABLED false
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
#define SAYLINK_ITEM_ID 0xFFFFF
/*

View File

@ -13774,11 +13774,10 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
}
safe_delete_array(escaped_string);
sayid += 500000;
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetProxyItemID(sayid);
linker.SetProxyItemID(SAYLINK_ITEM_ID);
linker.SetProxyAugment1ID(sayid);
linker.SetProxyText(name);
auto say_link = linker.GenerateLink();

View File

@ -8090,97 +8090,80 @@ void Client::Handle_OP_InstillDoubt(const EQApplicationPacket *app)
void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
{
if (app->size != sizeof(ItemViewRequest_Struct)){
Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, sizeof(ItemViewRequest_Struct));
if (app->size != sizeof(ItemViewRequest_Struct)) {
Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size,
sizeof(ItemViewRequest_Struct));
DumpPacket(app);
return;
}
DumpPacket(app);
ItemViewRequest_Struct* ivrs = (ItemViewRequest_Struct*)app->pBuffer;
ItemViewRequest_Struct *ivrs = (ItemViewRequest_Struct *)app->pBuffer;
//todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data from the item DB
// todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data
// from the item DB
const Item_Struct* item = database.GetItem(ivrs->item_id);
const Item_Struct *item = database.GetItem(ivrs->item_id);
if (!item) {
if (ivrs->item_id > 500000)
{
std::string response = "";
int sayid = ivrs->item_id - 500000;
bool silentsaylink = false;
if (sayid > 250000) //Silent Saylink
{
sayid = sayid - 250000;
silentsaylink = true;
}
if (sayid > 0)
{
std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str());
return;
}
if (results.RowCount() != 1) {
Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str());
return;
}
auto row = results.begin();
response = row[0];
}
if ((response).size() > 0)
{
if (!mod_saylink(response, silentsaylink)) { return; }
if (GetTarget() && GetTarget()->IsNPC())
{
if (silentsaylink)
{
parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0);
parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0);
}
else
{
Message(7, "You say, '%s'", response.c_str());
ChannelMessageReceived(8, 0, 100, response.c_str());
}
return;
}
else
{
if (silentsaylink)
{
parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0);
}
else
{
Message(7, "You say, '%s'", response.c_str());
ChannelMessageReceived(8, 0, 100, response.c_str());
}
return;
}
}
else
{
Message(13, "Error: Say Link not found or is too long.");
return;
}
}
else {
if (ivrs->item_id != SAYLINK_ITEM_ID) {
Message(13, "Error: The item for the link you have clicked on does not exist!");
return;
}
// This new scheme will shuttle the ID in the first augment for non-silent links
// and the second augment for silent.
std::string response = "";
bool silentsaylink = ivrs->augments[1] > 0 ? true : false;
int sayid = silentsaylink ? ivrs->augments[1] : ivrs->augments[0];
if (sayid > 0) {
std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str());
return;
}
if (results.RowCount() != 1) {
Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str());
return;
}
auto row = results.begin();
response = row[0];
}
if ((response).size() > 0) {
if (!mod_saylink(response, silentsaylink)) {
return;
}
if (GetTarget() && GetTarget()->IsNPC()) {
if (silentsaylink) {
parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0);
parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0);
} else {
Message(7, "You say, '%s'", response.c_str());
ChannelMessageReceived(8, 0, 100, response.c_str());
}
return;
} else {
if (silentsaylink) {
parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0);
} else {
Message(7, "You say, '%s'", response.c_str());
ChannelMessageReceived(8, 0, 100, response.c_str());
}
return;
}
} else {
Message(13, "Error: Say Link not found or is too long.");
return;
}
}
ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
ItemInst *inst =
database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2],
ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
if (inst) {
SendItemPacket(0, inst, ItemPacketViewLink);
safe_delete(inst);

View File

@ -2766,14 +2766,13 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
}
safe_delete_array(escaped_string);
if (silent)
sayid = sayid + 750000;
else
sayid = sayid + 500000;
//Create the say link as an item link hash
Client::TextLink linker;
linker.SetProxyItemID(sayid);
linker.SetProxyItemID(SAYLINK_ITEM_ID);
if (silent)
linker.SetProxyAugment2ID(sayid);
else
linker.SetProxyAugment1ID(sayid);
linker.SetProxyText(LinkName);
auto say_link = linker.GenerateLink();
@ -3164,4 +3163,4 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
entity_list.QueueClients(0, outapp);
safe_delete(outapp);
}
}

View File

@ -292,7 +292,7 @@ bool Zone::LoadGroundSpawns() {
char* name=0;
uint32 gsnumber=0;
for(gsindex=0;gsindex<50;gsindex++){
if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item<500000){
if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item<SAYLINK_ITEM_ID){
ItemInst* inst = nullptr;
inst = database.CreateItem(groundspawn.spawn[gsindex].item);
gsnumber=groundspawn.spawn[gsindex].max_allowed;