ID:1738971
 
Keywords: help, intelligence, npc, talk
(See the best response by Ganite.)
Hello everyone, I wanted to ask how to make it so that an npc response to you talking to them. Like you say Hello (NPC NAME) and they respond with hi (Player Name). And is it possible to have a basic conversation with them. You can ask How are you and they say how they are feeling or whatever. I just want to know if it's possible to have an actual conversation with an npc as if your talking to a person and if so then how do I get started.

do you mean like type in something and send it to them and they respond ?
Yea,like them having artificial intelligence
oh
Dayvon64 wrote:
Is it possible to have a basic conversation with them?

Yes, it is.

If so then how do I get started.
Really matters on how advanced you want it, though I believe something along the lines of this would work.

(I'm not too good at DM, just thought I'd take a swing at this. I'm sorry if I gave you the wrong information but I think it should work. I have tested it and it worked for me)

mob
verb
Talk()
switch(alert("Whats your question?",,"Whats your favortie color?","Whats your name?","Nothing"))
if("Whats your favortie color?")
alert("Jake says :My favorite color is blue!")
if("Whats your name?")
alert("Jake.")
else
alert("I'll see you around!")



What he wants would have to be done in the OOC/Say proc/verb. A simple way I could think of is use findtext when a NPC is in view and if the name matches the name you say (If the NPC is in view) it responds back. It would just be a lot of if statements.


I'm guessing.
I see, this was just my guess of one way to do it.
1) was that code example not correct because I wanted to try it

2)I wanted to have the npc sort of like a small pixe so like it floats above you or whatever and when ever you say like Hey (name of the pixe) or something along those lines. So my worry is would I have to prest sentences for it to say and also could i make it so that it can only be in say. Like pixie is in inventory you take pixie out so that it floats visibly next to you. And you can just casually say Hey(Elfon) how are you feeling. and the pixie says I'm bored let's have some fun. Or like Hey(Elfon) what should we do and he says let's fight or something else. Also I would like to have it so that others can talk to it aswell. I hope this all makes sense
Best response
mob/verb
Say(txt as text)
for(var/mob/Fairy/F in usr.fairieslist)//if u put the fairy in a list
if(F.fairyout) //if the fairy is summoned
if(findtext("[F.name] how are you?")
usr << "<b>[F.name]:>/b> I'm great!"
else return
usr << "<b>[usr.name]:>/b> [txt]"


or if they only have availabe 1 fairy:
mob/verb
Say(txt as text)
for(var/mob/Fairy/F in view())
if(F.owner == usr)
if(findtext("[F.name] how are you?")
usr << "<b>[F.name]:>/b> I'm great!"
else return
usr << "<b>[usr.name]:>/b> [txt]"

I didn't test this before giving it to you but I think it should give you what you want.
In response to Ganite
The issue with your snippet (not to say that it's bad or anything) is that it doesn't account for the absolute complexity nightmare that the thread's author is asking for. Any changes in punctuation, capitalization, spelling, or phrasing will cause this to fail. You'd have to say the phrase exactly as it was programmed in.

The alternative of course is... well, a rather complex system of parsing and understanding what the player is saying, weighing words to determine the proper response. I believe this field is natural language processing.
In response to LordAndrew
Figured, I was just trying to give him a way (only way I know). But if he can't figure out the more complex way he will have to resort to this method and make it clear to players. Or an alternative he could just make code words/phrases just for the spirit to make my way work more efficient.
Ganite I like your way and I will certainly resort to it, but you know I would like a bit more complex and I won't stop looking for that way. Which is why I need you guys help. Either way I might just use this instead because it's awesome as heck.
In response to LordAndrew
Which is why games that offer dialogue exchange usually force you to choose from a list of dialogue options and in return, you get one of a select few responses.
So I tried to enter the code Granite sent the last one that says 1 fairy and it said that comma was missing. Why do I do?
Add atleast 2 arguments inside of the findtext() so like if(findtext("1","2"))
Ganite I tried to add but it did not work
Ok where in there should I look?
Honestly this sort of thing would take massive amounts of effort. No one will help you on this one, this will have to be done on your own. Speech can be as complicated as 20 lines of code as shown above to hundreds which the later is what it sounds you want
but i think a good talking mechanism is what bioware games have. You have a wheel and a choice of select phrases that you must select. This is probably the best way to get it done
I'm not sure how easy this is to read but hopefully tinkering with it will help you understand this problem a bit more. Below is a screenshot of how I used it.

Goodluck!
#define FALSE 0
#define TRUE 1

mob
Player
icon_state = "player"
verb/Say(var/phrase as text)
//First, display what you've said
view(4,src) << "<b>[src]:</b> [phrase]"
//Then, for every NPC around you
for(var/mob/NPCS/F in oview(4,src))
//Have that NPC evaluate your phrase,
//and pass in your name too in case they should respond
F.eval_phrase(phrase,src.name)
NPCS
var
//This is a list of Questions that this NPC may process
list/Question/questions
proc
//This is how we will actually process what is said,
// and respond to the source
eval_phrase(var/phrase,var/source)
//First we loop through our questions
for(var/Question/P in src.questions)
//We ask each of our questions to evaluate your phrase
if(P.eval_phrase(phrase,src))
//If your phrase turned out to signal the question,
//the question will give us the proper response
var/response = P.response()

//Then we will pass this response to our NPC in case it has its own
//behavior for it
respond(response,source)

break
respond(var/response,var/toWhom)
world << "[response], [toWhom]"
//Based on the above definition, we can define any NPC
//to respond to questions by
//1. Adding a predefined Question to their questions variable
//2. Thats it. We can also modify respond(var/response,var/toWhom)
// if we wnat to control further how they respond.
Fairy
icon_state = "fairy"

//In this case, we have defined what FairyHello() accepts as a question
//and response elsewhere
questions = list(new /Question/FairyHello())

//Ignore this, this is for my testing
New()
.=..()
name = pick(names)

//In this case, a fairy will take the questions proper response
//and add your name to it
respond(var/response,var/toWhom)
view(4,src) << "[response],[toWhom]"
//Based on the above definition,
//this is how we would make an NPC that responds differently
Ogre
icon_state = "ogre"
//We give it different questions, that we define elsewhere
questions = list(new /Question/GenericHello(), new /Question/OgreGoodbye())
//We change how it responds, slightly
respond(var/response,var/toWhom)
view(6,src) << "Ogre says [response] [toWhom]"
//And thats it
Ghoul
questions = list(new /Question/GenericHello())

//In this one we dont define response, so it will have a default response

//Now for the definitions of our Question objects and everything else really
Question
//You will see what PhraseTypes are under this. Basically,
//they are a class of phrases that are similar, such as
//Hello dude
//Hey man
//Hows it going
var/PhraseType/question
var/PhraseType/response
proc
//The question is asked earlier to evaluate
//if your phrase merits a response from it
//To do this, it asks its phrase type to check
//if your phrase was considered 'one of its kinds of phrases'
eval_phrase(var/phrase,var/name)
return src.question.eval_phrase(phrase,name)
response()
return src.response.response()
FairyHello
question = new /PhraseType/Hellos()
response = new /PhraseType/Hellos()
GenericHello
question = new /PhraseType/Hellos()
response = new /PhraseType/Hellos()
OgreGoodbye
question = new /PhraseType/Goodbye()
response = new /PhraseType/Goodbye()
//This is a grouping of the phrase definitions listed after this
PhraseType
var
list/phrases = list()
proc
eval_phrase(var/phrase,var/name)
if(!phrases)
return FALSE
for(var/Phrase/P in phrases)
if(P.eval_phrase(phrase,name))
return TRUE
//Default case
return FALSE
response()
var/Phrase/phrase = pick(phrases)
return phrase.response()

Hellos
phrases = list(new /Phrase/Hello, new /Phrase/WhatsUp, new /Phrase/HowsItGoing, new /Phrase/HowAreYou)
Goodbye
phrases = list (new /Phrase/Goodbye)
//A phrase just represents a set of similar phrase beginnings
//and all of their equivalent endings
Phrase
var
list/synonyms
list/endings
Hello
synonyms = list("hi","hello","hey","wassup")
WhatsUp
synonyms = list("what's","whats","what is","what")
endings = list("up","going on","happening")
HowsItGoing
synonyms = list("hows","how is")
endings = list("it going")
HowAreYou
synonyms = list("how")
endings = list("are you","are ye","is it going")
Goodbye
synonyms = list("Goodbye","Cya","Bye","Ciao pues")
//This is where the real phrase analyzing comes in
proc/eval_phrase(var/phrase,var/name)
phrase = lowertext(phrase)
var/hasPhrase = FALSE
//First, we check if your phrase contains the beginning
//of the phrase we are looking for
//Example: you say "what is up"
//This phrase is: WhatsUp
//This phrase first looks for "what's", but you didn't say that
//Then it looks for "whats", but you didn't say that
//Then it looks for "what is", and you did say that
for(var/word in synonyms)
var/position = findtext("[phrase]","[word]")
//If we find "what is" from our example,
//we will now look for a proper ending after "what is"
//Proper endings would be "up","going on", or "happening"
if(position)
//If there are no endings at all for this phrase
if(!endings)
//Then we must have found the phrase
hasPhrase = TRUE
break
//Else, look for our ending
for(var/ending in endings)
//This is the part of the string (start-end)
//where the ending will be found
//Start is basically right after the first chunk
//of the phrase, in our example case itd be after "what is"
var/start = position + lentext(word)
var/end = start + lentext(ending) + 1
if(findtext(phrase,ending,start,end))
hasPhrase = TRUE
break
if(hasPhrase)
//If we found the phrase, just made sure the persons name was used
if(findtext("[phrase]","[name]"))
return TRUE
return FALSE
//If someone is asking for a response made from this phrase,
//just pick a phrase beginning
//and match it with an ending
proc/response()
var/response = pick(synonyms)
response += " " + pick(endings)
return response

Page: 1 2