Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #1  
Old 04-13-2009, 04:55 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default Say Links

This is an interesting idea I had a while back, but never really put much thought into it until recently. Basically, the idea is that we could make a way for quest text from NPCs to have links in them that would essentially look like item links, but instead of showing the item when you click them, it would make the NPC respond as if you had said what ever the name of the link was.

For example, I could have an NPC that says something like this:

Quote:
Soandso says,'Would you like to test a say link?'
And, if you clicked the word "test" there, it would reply as if you had typed "/say test".

So far, I have the basic concept working. I have been able to get this to work with a predefined catch phrase. If we could figure out how to get the actual link name from the quest script, I think it would be pretty easy to make this fully functional.

Here is what I have so far:

NOTE: This is test code, not a finished product yet. Just for development purposes

In client_packet.cpp, replace the following:
Code:
void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
{
	if(app->size != sizeof(ItemViewRequest_Struct)){
		LogFile->write(EQEMuLog::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;

	//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);
	if (!item) {
		Message(13, "Error: The item for the link you have clicked on does not exist!");
		return;
	}

	ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4]);
	if (inst) {
		SendItemPacket(0, inst, ItemPacketViewLink);
		safe_delete(inst);
	}
	return;
}
With this:
Code:
void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
{
	if(app->size != sizeof(ItemViewRequest_Struct)){
		LogFile->write(EQEMuLog::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;

	//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);
	if (!item) {
		if (ivrs->item_id == 999999)
		{
			this->ChannelMessageReceived(8, 1, 100, "test");
			return;
		}
		else
		{
			Message(13, "Error: The item for the link you have clicked on does not exist!");
			return;
		}
	}

	ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4]);
	if (inst) {
		SendItemPacket(0, inst, ItemPacketViewLink);
		safe_delete(inst);
	}
	return;
}
Then, to test that, you just set an NPC to use this example quest script:
Code:
sub EVENT_SAY {

my $clientver = $client->GetClientVersion(); #this is just so the example works for all clients
my $test_sof = sprintf("%c%06X%s%s%c",0x12,999999,"00000000000000000000000000000000000000000000","test",0x12);
my $test = sprintf("%c%06X%s%s%c",0x12,999999,"000000000000000000000000000000000000000","test",0x12);

  if($text=~/hail/i && $clientver == 3) {
      quest::say("Would you like to $test_sof a say link?"); }

  if($text=~/hail/i && $clientver != 3) {
      quest::say("Would you like to $test a say link?"); }

  if ($text =~/test/i) {
      quest::say ("This test was a success!"); }

}
Then, simply hail the NPC and click the "test" link in the message and it will reply appropriately.

I am sure we could make a quest command that would make creating say links very quick. It could be something like quest::saylink(message), where "message" would be the name of the link. The only hard part would be figuring out a way to pass the message string into the Handle_OP_ItemLinkClick function. I don't know if it would even be possible, but if so, it should be easy to finish this off. It is too bad that the name of the item link isn't passed from the client when they click a link, or this would be extremely simple to finish off. I just can't think of any way to possibly pass that string into this function.

This definitely isn't a high priority or anything, but I thought it would be pretty cool to see working. I am actually surprised SOE hasn't done something like this yet. I think it would definitely bump the EQ quest system a little closer to being current. Not that I mind typing them out, but I bet some players would really like it. Of course, players would still be able to type it out if they preferred to do so.

If anyone has any suggestions on how to finish this off, I am sure some people would enjoy playing with it

Edit:
The only way I can think of to maybe get this working would be to have the quest::saylink() command set to automatically generate unique bogus item IDs for every saylink used in each quest file and store them to memory when the server boots up. It would basically be like generating a list of fake items, accept it shouldn't take too much memory since it only needs an item ID and then the message, not all other item stats. As long as it started at item ID 500k on up, I don't think we would ever have to worry about real item IDs ever overlapping into the say link ones. This would be above my coding skill level to write though, but maybe there is a simpler way to do it.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 04-13-2009 at 01:14 PM..
Reply With Quote
  #2  
Old 04-19-2009, 11:43 AM
warhawk
Sarnak
 
Join Date: Mar 2008
Posts: 47
Default

Trev

This is a great idea. I've always hated the quest system (typing text) in EQ.

Good luck with it.

War
Reply With Quote
  #3  
Old 04-19-2009, 05:01 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I have been thinking about this a bit more and I think I know of a way to make it work smoothly with the minimal amount of work. Here is what I am thinking:

1. Add a new table named "saylinks" that has 2 fields: ID and Phrase. The ID field would just be an auto-incrementing ID number. The Phrase field would be a the string for the actual phrase we are wanting to create a link fro.

2. Add an in-game command that will allow admins to add a phrase to the new saylink table. This command would be called something like #addsaylink <message> and it would just add the new message and assign it to the auto-incremented ID. This way, an admin can go through their quest prompts from in game and add the links as they see them. This is optional, but I think it would be a nice feature to help simplify the process. Of course, people could simple update the table manually if they preferred.

3. Create a new quest command that would generate the hash of the item link directly into a script text message. For example:

Code:
quest::say("This is a quest::saylink(link) example.");
And that line would show this when the NPC says it:

Code:
Soanso says,'This is a link example'
This may be one of the hardest parts, because I am not sure how to have it convert the quest command directly into the hash when it is inside of a string like that. I am pretty sure that quest::ChooseRandom() works inside of a string like that, so I may have to do some looking into how it works for that command. Otherwise, we would have to do something like this instead:

Code:
my $link = quest::saylink(link);
quest::say("This is a $link example.");
Which should be easy enough to do, but for scripting purposes, it would make things much quicker and simpler to do it the first way inside the actual string.

4. The quest::saylink() command would be set to query the saylink table in the database. Since the ID numbers would start at 1 and go up from there, the saylink quest function would then simple add 1 million to that number to create the item_id number for the hash. So, if the table had the first phrase as ID 1, that would be converted to 1000001 as the ID number. Then, the Handle_OP_ItemLinkClick would just be set to look for any item_id over 1 million and handle any that are as a say link.

5. Once the Handle_OP_ItemLinkClick finds a hash that needs to be treated as a say link, it will just do a simple database query in the saylink table for the phrase that matches that item ID. Since the item ID had 1 million added to it, it would need to subtract 1 million before doing the query. Then, it would simply parse it like it does in the code I first submitted here.

I think the hard parts are going to be getting the quest command to output an item link from directly within a string, and also to get the queries working perfectly. I am not much of a query guru, so I may need help to make sure the query is set properly. Basically it would just be querying the string that would be the hard part. We would need to make sure that it finds the exact match, and not just a partial or one that just contains the string.

The saylink table would be set to use the phrase as the key, so there wouldn't be multiple entries for the same phrase. There isn't any need to have more than 1 entry for the same string anyway.

Last, there would just need to be a few error messages set in place to report if something is missing. Like, if you try to use quest::saylink() without actually having that string in the saylink table. It could have the NPC give some warning about needing to update the database.

I don't know how many admins would use a system like this. I just think it would be something interesting and new. I have a feeling that once people actually see it working, it will grow on them quickly.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #4  
Old 04-19-2009, 07:28 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Just thought of a way to make this considerably more simple to use. Basically, everything would remain the same, accept you would no longer need to update the saylink table manually or via commands at all. The only thing people wanting to use this system would need to do would be to add the quest::saylink() functions into their quest::say() messages to replace the current ones they have set.

The idea is that the quest::saylink() command would do it's query of the saylink table to see if it had a matching string. If it doesn't find a match, the new idea is that it would simply create one itself at the time the link is generated. So, once the scripts have the quest::saylink() command added, as players go through the quest prompts in-game, it will populate the saylink table automatically and then save them for future use.

I think this is probably about as simple as it can get. Now, if only I can figure out how to actually make it do all of that properly :P

By using this system along with the $client->Message function, you could in theory have complete conversations between the player and an NPC without any other player seeing a single message. This seems like it might be useful in highly populated city areas to reduce spam considerably. It also might make some players feel more comfortable to go through all of an NPC's quest prompts. I know at least a few people who feel like they are spamming others when they speak with NPCs, and so they are shy about doing it. I can't wait to try this system out if it ever gets completed. Any suggestions are more than welcome
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 04-20-2009 at 03:33 AM..
Reply With Quote
  #5  
Old 04-19-2009, 09:33 PM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

I might be missing something, but why mess with the database at all? What about structuring it something like:

quest::saylink(text,value)

and have the function return a link to a fictitious item. You could use your plan of using item values over 1,000,000, or maybe negative item values if you wanted to be sure of never interfering with anything. Then you could adjust the code to activate a ChannelMessageReceived function based on the value you entered.

So, for example quest::saylink("test",1) would create a link on the word "test." When you clicked it, it would send a message of SayLink1, or something along those lines. That way, you could have multiple saylinks in one quest without too much complexity. I won't have a chance to look at the source for a bit, but I have a basic idea of how it might be coded.
Reply With Quote
  #6  
Old 04-20-2009, 01:44 AM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

I played around with the idea a little bit tonight, and here's what I've come up with as a first attempt.
Code:
Index: zone/client_packet.cpp
===================================================================
--- zone/client_packet.cpp	(revision 437)
+++ zone/client_packet.cpp	(working copy)
@@ -2163,8 +2166,17 @@
 
 	const Item_Struct* item = database.GetItem(ivrs->item_id);
 	if (!item) {
-		Message(13, "Error: The item for the link you have clicked on does not exist!");
-		return;
+		if (ivrs->item_id > 1000000)
+		{
+			char response[20];
+			sprintf(response,"SayLink%u",ivrs->item_id - 1000000);
+			this->ChannelMessageReceived(8, 1, 100, response);
+			return;
+		}
+		else {
+			Message(13, "Error: The item for the link you have clicked on does not exist!");
+			return;
+		}
 	}
 
 	ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4]);
@@ -7155,7 +7167,7 @@
 	if(!p_timers.Load(&database)) {
 		LogFile->write(EQEMuLog::Error, "Unable to load ability timers from the database for %s (%i)!", GetCleanName(), CharacterID());
 	}
-
+	
 #ifdef _EQDEBUG
 	printf("Dumping inventory on load:\n");
 	m_inv.dumpInventory();
Index: zone/perlparser.cpp
===================================================================
--- zone/perlparser.cpp	(revision 437)
+++ zone/perlparser.cpp	(working copy)
@@ -2446,7 +2446,31 @@
 	XSRETURN_UV(quantity);
 }
 
+XS(XS__SayLink);
+XS(XS__SayLink) {
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: saylink(text, saylinkID)");
+	dXSTARG;
 
+	Const_char * RETVAL;
+	char text[250];
+	uint16 ID;
+	
+	strcpy(text,(char *)SvPV_nolen(ST(0)));
+
+	ID = (int)SvUV(ST(1));
+	
+	RETVAL = quest_manager.SayLink(text,ID);
+
+	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
+	XSRETURN(1);
+}
+
+
+
+
+
 /*
 This is the callback perl will look for to setup the
 quest package's XSUBs
@@ -2617,6 +2641,7 @@
 		newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
 		newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
 		newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
+		newXS(strcpy(buf, "saylink"), XS__SayLink, file);
 
 	XSRETURN_YES;
 }
Index: zone/questmgr.cpp
===================================================================
--- zone/questmgr.cpp	(revision 437)
+++ zone/questmgr.cpp	(working copy)
@@ -1821,3 +1821,10 @@
 
 	return Quant;	// return the quantity of itemid (0 if it was never found)
 }
+
+const char * QuestManager::SayLink(char* text, uint16 value) {
+	char linktext[250];
+	sprintf(linktext,"%c%06X%s%s%c",0x12,1000000+value,"000000000000000000000000000000000000000",text,0x12);
+	strcpy(text,linktext);
+	return text;
+};
Index: zone/questmgr.h
===================================================================
--- zone/questmgr.h	(revision 437)
+++ zone/questmgr.h	(working copy)
@@ -197,6 +197,8 @@
 
 	void MerchantSetItem(int32 NPCid, int32 itemid, int32 quantity = 0);
 	int32 MerchantCountItem(int32 NPCid, int32 itemid);
+
+	const char* SayLink(char* text, uint16 value);
 	
 	//not in here because it retains perl types
 	//thing ChooseRandom(array_of_things)
It only does the Titanium formating at the moment, and it will break if there are ever legitimate item ids over 1 million, but I tested a couple of different things and it seems to do all right. There's not much in the way of error checking, so it'll probably crash the zone if anything too strange gets entered as parameters.

The syntax is quest::saylink(message,n)
And when the link is clicked, it sends a message "SayLinkn". Here was my simple test script:
Code:
my $test1 = quest::saylink("trying,1");
my $test2 = quest::saylink("forget,2");

sub EVENT_SAY {
  if($text=~/Hail/i) {
    quest::say("I've noticed that sometimes certain words I say just feel... different.  Should I keep $test1 to see what I can do with them, or just $test2 the whole thing?");
  }

  if($text=~/SayLink1/) {
    quest::say("You're right, I bet I can make something out of them.");
  }
  if($text=~/SayLink2/) {
    quest::say("I knew it was too much to hope for.");
  }
}
Reply With Quote
  #7  
Old 04-20-2009, 04:52 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Thanks for the info

I had thought about doing something like that, but it wouldn't be quite as ideal as what I am wanting to do with it. Basically, I want to make the saylinks an option to players. So, if they prefer clicking the links, they can click them, but if they prefer to just type the phrase, they can do that as well. And, it wouldn't require any extra scripting to handle the saylinks or normal say messages. I know at least a few players who play almost solely with the keyboard and only ever have to touch their mouse when they are looting a corpse.

The idea you had would work fine, but it would make quest scripting a bit more involved, which is one of the main things I am trying not to do. If I can't get the way I am wanting to do it working, we could definitely put it in the way you have it coded though.

Here is the difference of what it would take to write the same exact quest to use your code as it would for what I am suggesting (including the option to /say the phrase):

Your idea:
Code:
my $test1 = quest::saylink("test,1");

sub EVENT_SAY {
  if($text=~/Hail/i) {
    quest::say("Would you like to $test1 a say link?");
  }

  if($text=~/SayLink1/) {
    quest::say("The test was a success!");
  }
  if($text=~/test/i) {
    quest::say("The test was a success!");
  }
}
My idea:
Code:
my $test1 = quest::saylink("test");

sub EVENT_SAY {
  if($text=~/Hail/i) {
    quest::say("Would you like to $test1 a say link?");
  }

  if($text=~/test/i) {
    quest::say("The test was a success!");
  }
}
Not really a huge deal, but it would get tougher to manage if you have long scripts with lots of phrases and text.

I really appreciate the help on this though. I think it will be something cool to play with when it is all done. I bet players will be really surprised to see it when it first shows up on servers. And, I bet it isn't long before EQLive has something similar lol.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 04-20-2009 at 02:12 PM..
Reply With Quote
  #8  
Old 04-20-2009, 07:39 AM
janusd
Sarnak
 
Join Date: Jan 2008
Posts: 47
Default

What're you saying Trev? That we've had some great ideas that showed up on Live? Why, that just means SoE listens to its fanbase.
Reply With Quote
  #9  
Old 04-20-2009, 12:04 PM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

Ok, that's a good point. You could also probably cram a second string into the space that's normally used for augments and that sort of thing. It would mean you're limited to just under 40 characters for the response string, but that doesn't seem like it would be a problem very often.
Reply With Quote
  #10  
Old 04-20-2009, 07:34 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I thought about using the augments section for handling the phrase, but coding that is out of my skill range. It would have to be able to take the string and then fill in the rest of the nulls after it to make sure that it builds the link properly. Then, after the link is clicked, it would need to have a way to take each of those fields and tie them together and then convert them back into a string.

If you know how to do that, I am sure 40 characters would be plenty for almost any scenario. That would probably be the best possible way to handle say links. By putting the string into the actual link, the item ID wouldn't matter at all. So, the item ID that the quest::saylink() command creates could be hard set to 999999 (or any other invalid item ID number) for all links it creates.


Also, an a related topic, I was playing with the code you posted to handle saylinks and was trying to get it to work where you only input the item ID, and have it create a normal item link from just that. There is already a quest command for quest::itemlink(), but that command causes the NPC to send a tell to the player with a link to the item. Something I have wanted for a long time is a very simple way to create an item link to an actual item that can be set as a variable for use in the middle of a say message. On Storm Haven, we currently have to do something like this to create an itemlink:

Code:
my $cloth_cap = sprintf("%c%06X%s%s%c",0x12,1001,"000000000000000000000000000000000000000","Cloth Cap",0x12);

sub EVENT_SAY {

  if ($text =~/Hail/i) {
  quest::say ("Here is a link to a $cloth_cap."); }

}
While that isn't overly complex to do, it would be nice if we could do something like this instead:

Code:
my $cloth_cap = quest::itemlink(1001);

sub EVENT_SAY {

  if ($text =~/Hail/i) {
  quest::say ("Here is a link to a $cloth_cap."); }

}
The way you wrote the quest::saylink() command above actually works nicely for this. But it could be simplified a bit more by having it do a GetItem() and then an item->name to automatically populate the name of the itemlink. I worked with what you wrote for a while last night, but everything I tried to do was crashing the zone lol. Not trying to derail this thread at all, but figured I would mention this since I worked on it a while last night.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #11  
Old 04-21-2009, 11:04 AM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

I haven't gotten a chance to look at using the augments section to store anything yet, but I did come up with some code for storing a link as a perl variable. The syntax is just $var = quest::itemlink2(item id).

My source is way too messed up for a diff right now, but here's the changes I made for this. The total string, including all the link variables and stuff, is limited to 250 chars (totally arbitrary number) right now, so no ridiculously long item names.

questmgr.h add:
Code:
const char* ItemLink2(char* perltext, int item_id);
questmgr.cpp:
Code:
const char* QuestManager::ItemLink2(char* perltext, int item_id) {
	const ItemInst* inst = database.CreateItem(item_id, 20, 99999, 99999, 99999, 99999, 99998);
	if (!inst) return 0;	// return an empty string if the item is invalid
	char* link = 0;
	char* tempstr = 0;
	if (initiator->MakeItemLink(link, inst)) {	// make a link to the item
		MakeAnyLenString(&tempstr, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12);	// format the string that the client receives
		strncpy(perltext, tempstr,250);	// the perl string is only 250 chars, so make sure the link isn't too large
		safe_delete_array(tempstr);	// MakeAnyLenString() uses new, so clean up after it
	}
	safe_delete_array(link);	// MakeItemLink() uses new also
	return perltext;
}
perlparser.cpp:
Code:
XS(XS__ItemLink2);
XS(XS__ItemLink2) {
	dXSARGS;
	if (items != 1)
		Perl_croak(aTHX_ "Usage: itemlink2(itemID)");
	dXSTARG;

	Const_char * RETVAL;
	char text[250];
	uint16 itemID;
	itemID = (int)SvUV(ST(0));
	
	RETVAL = quest_manager.ItemLink2(text, itemID);

	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
	XSRETURN(1);
}
and at the bottom of perlparser add:
Code:
newXS(strcpy(buf, "itemlink2"), XS__ItemLink2, file);

By the way, the most likely cause of your zone crashes is in passing (char *) strings back and forth between functions. It's really easy to accidently write more to the char array than you allocated and overwrite other stuff on the stack. At least, that's what seemed to cause all of my problems.
Reply With Quote
  #12  
Old 04-21-2009, 05:06 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Thanks, realityincarnate! I will get that tested and submitted if it tests good. I may rename it to something like quest::varlink() so it is easier to remember that it is for creating variables with item links if that is ok with you.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #13  
Old 04-21-2009, 07:28 PM
realityincarnate
Developer
 
Join Date: Dec 2007
Posts: 122
Default

Change anything you want, I just wasn't feeling especially creative when I tried to think of what to call it. Definitely give it some real testing; all I did was try with a couple of newbie items and one fake item id to make sure it wasn't crashing anything. I'm sure there's a more efficient way to handle the string as well, but I just wanted something that didn't take much work and wouldn't cause an overflow.

I played around with the say links a little bit more, also, and I was able to force a test string into the augments, lore, etc. variables, but clicking the item link no longer triggered any response from the server at all. The normal item links still worked fine, so I'm not sure if the client does some checking of it's own, or if I just broke something. In any case, I probably won't have much chance to take a look at it for a few days, but I'm cautiously optimistic for now.

And while we're talking about links, I have what's probably a really dumb question. How do you actually create a link to an item in game? I know I've done it before, but I can't for the life of me remember how.
Reply With Quote
  #14  
Old 04-21-2009, 10:59 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

You just right click the item to show it's properties and then click on the icon for the item in the item stats window. That will send a link to your chat window if that is what you were asking about.

Sounds like you are making some interesting progress on putting the string into the say link. I figured it wouldn't be too hard to get the string in there. But, getting it out correctly would be the hard part. Maybe you can change it slightly to have it make the NPC do a say message with whatever it things the string from the say link is. That should work to help debug what is happening when you click the link.

Since the packet breaks down the link into the ItemViewRequest_Structure for use in the link click handling, the string that you put in there would be split into multiple chunks. Then they just need to be put back together into a string that we can use. Maybe that wouldn't be all that hard to do afterall. We would need to get the info in Hex form, and then convert it from hex into a section of a string. Then, just create a string by adding them all together end-to-end back into 1 string.

If you get time to post what you have so far, I could look at the packet being sent by the client and see if it is sending the right string. If so, then it probably just isn't being put back together properly after it gets to the link click handling. If you are too busy though, no rush. This isn't high priority or anything
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #15  
Old 04-22-2009, 05:55 AM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Hmm, this is interesting; I tried your itemlink2 code and it works for the most part. There is only 1 issue I have found with it. The issue is that it only works for item IDs that are less than 65536. It appears that it is only allotting and int16 worth of space for the item ID. Maybe it is cutting it off after that for some reason. This happens on both SoF and Titanium clients.

If I use this from within the script:
Code:
my $test3 = sprintf("%c%06X%s%s%c",0x12,71709,"000000000000000000000000000000000000000","Mask of Defiant Rage",0x12);
That works perfectly fine to show the correct item link.

But, if I try to use this:
Code:
my $mask = quest::varlink(71709);
The link returns item ID 6173 (Acrylia Reinforced Sleeves). And if I convert 6173 to hex, I get 181D. And if I convert 71709 to hex, I get 1181D. So, it makes sense that it is cutting off the first 1 in 1181D. I don't know why it would do this. The only thing I can think of is that maybe it is an issue with the MakeItemLink() function.

For any item ID less than 65536 it works great though. So, once this issue is resolved, I think this command should be ready to go.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 09:59 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3