Log in

View Full Version : NPC Conversation


CodeMephit
07-16-2008, 11:15 AM
I am trying to make two NPCs respond to each other in a script. The scenario should play out like this:


Player: "Hail NPC1"
NPC1: "Hi Player. This is my friend NPC2. Say Hi, NPC2."
NPC2: "Hey Player."
NPC1: "If you [need] us for anything, just let me know."


I could *fake* NPC2's voice using $client->Message...

if($text=~/hail/i){
quest::say("Hi $name. This is my friend NPC2. Say hi, NPC2.");
$client->Message(1,"NPC2 says 'Hey $name.'");
quest::say("If you [need] us for anything, just let me know.");
}

I would rather not have to use this method because you must specify the color of the text (the "1"). But if the player has changed their default colors, that one line will show up different than all the other quest chatter.

So ultimately my question is this: Can you get one NPC to respond to another NPC?

Thanks,
-Codemephit

Congdar
07-16-2008, 11:39 AM
look at the part of the Cleric Epic 1.0 quest in lakerathe where there is a conversation between two npc's using quest::signalwith()

Natasha_Whitewater.pl
Shmendrik_Lavawalker.pl

CodeMephit
07-16-2008, 12:22 PM
Pure genius Congdar!! Thanks for the uber-fast reply.
Here is my take on how to do it. (Posting in case someone else may need to know how it's done.)


quest::signalwith(NPC_ID, SIGNAL_NUMBER, PAUSE);


NPC1 (Bob - ID#456)

sub EVENT_SAY{
if($text=~/hail/i){
quest::say("Hi $name. This is my friend Joe. Say hi, Joe.");
quest::signalwith(123, 1, 2);
}
}

sub EVENT_SIGNAL{
if($signal == 2){
quest::say("If you [need] us for anything, just let me know.");
}
}


NPC2 (Joe - ID#123)

sub EVENT_SIGNAL{
if($signal == 1){
quest::say("Hey $name.");
quest::signalwith(456, 2, 2);
}
}


-Codemephit

Lillu
09-08-2009, 03:58 PM
any way to pass on the client name data to NPC2? because this way the 2nd npc wont know who hailed NPC1. $name basically works for NPC1 only.

trevius
09-08-2009, 04:57 PM
Here is how I do that:

NPC1 (the NPC that the client is currently dealing with)
sub EVENT_SAY {

if ($text=~/Hail/i)
{
quest::say("I think you wanted to speak with my friend over here.");
my $ClientID = $client->GetID(); #Get the client's entity ID
my $CIDSignal = $ClientID + 1000; #Add 1000 to entity ID for signalling
quest::signalwith(2701139, $CIDSignal); #Send the Entity ID of the client +1000 to the other NPC
}


}


NPC2 (the NPC that we are sending the client info to)
my $ClientName; #Only setting this here so the name can be used in other sub events if needed.

sub EVENT_SIGNAL {

if ($signal > 1000 && $signal < 3000)
{

my $ClientID = $signal - 1000; #Subtract the 1000 we added to the signal before it was sent
my $ClientByID = $entity_list->GetClientByID($ClientID); #Get client by entity ID
$ClientName = $ClientByID->GetCleanName(); #Get Client's name
quest::say("Hello there, $ClientName!");
}


}

Basically, you can add any amount you want to it. Entity IDs only go up to 1502 or so, so you can send different ranges for different things you might want to check just by adding different amounts to them. So, maybe for this response, I want to add 1000 to the entity ID and check on the other NPC for any from 1000-3000, but maybe I want to have a second response for something else too. If so, you can just add a different amount like 5000 and then have the other NPC check for 5000-7000 signal IDs.

BTW, I haven't tested the exact script as I posted it here, because I modified an existing one I use to simplify it. But, I think this should work for you. If not, it should be easy enough to get the idea of what you need to be doing. If you have any issues, just put some say messages in there to debug it, so you can see where it might be failing. Here is an example of what I mean by that:

if ($text=~/Hail/i)
{
quest::say("I think you wanted to speak with my friend over here.");
my $ClientID = $client->GetID(); #Get the client's entity ID
quest::say("I got Entity ID $ClientID.");
my $CIDSignal = $ClientID + 1000; #Add 1000 to entity ID for signalling
quest::say("Added 1000 to the Entity ID to get $CIDSignal.");
quest::signalwith(2701139, $CIDSignal); #Send the Entity ID of the client +1000 to the other NPC
quest::say("Signal $CIDSignal sent to NPCID 2701139.");
}

If you put say messages like that after each step, it makes it really easy to see where they are failing. Also, I usually add any variables to the say message so I can see what it is actually getting to make sure something isn't wrong with that part.

Lillu
09-08-2009, 05:29 PM
Thanks Trev! So if I understand it correctly, the trick is to transfer client id with signal, and to use signal ranges for separate responses based on the fact that Entity IDs are always lower than ~1500.

trevius
09-08-2009, 06:06 PM
Yeah, you basically send the signal by adding 1000 or whatever to your client's entity ID. So, if your client's entity ID was 264, the signal would be 1264. Then, the NPC that gets that signal knows that anything from 1000-3000 is a client ID and a signal to do something particular. It then subtracts 1000 from the signal ID and then has 264, which is the client's entity ID that it can no do just about anything with. If you wanted to have different responses, you could just add 1000 to the first signal, then something like 3000 to the second, 5000 to the 3rd and so on. And then you just check for ranges in EVENT_SIGNAL instead of an exact signal ID number, like I show in the example.

Lemme know if you have any problems or questions on it.

Lillu
09-08-2009, 06:18 PM
All clear, tested, and works like magic. Thanks! :)

trevius
09-08-2009, 07:08 PM
Nice sig :) I really love what you did with your hub zone there. It gets my vote for best hub zone in EQEmu :D

Lillu
09-09-2009, 06:06 AM
Thanks Trev! Nice words from someone having an amazing custom server as yours.. :)

(sorry for the offtopic)