ID:1457494
 
(See the best response by Ss4toby.)
Code:
Dial
var/npct = ""
var/responses = list()

Resp
var/respt
var/Dial/next

mob/var/talktarget

mob/proc
ShowDial()
winshow(usr,"dial",1)
GetDial(mob/M,var/Dial/D)
var/Resp/R
src.talktarget = M
winset(src,"npctalk",{"\
<title>
[M.name]</title>
<br>
<br>
<style>
body{
background: black;
color: white;
}
</style>
<body>
<b>
[D.npct]
</b>
</body>"}
)
winset(src,"playerchoice",{"cells="1x""})
for(R in D.responses)
src<<output("<a href=?src=\ref[src];action=[R]>[R.respt]</a>","playerchoice:1,++")

mob
Topic(href,href_list[])
switch(href_list["action"])
if(Resp) //undefined var
GetDial(src.talktarget,Resp.next)


Problem description:

It calls Resp an undefined var, therefore calling Resp.next an undefined var. However, I'm not sure how to make it recognize a datum as a defined var. I tried putting var/ BEFORE resp in the if() statement, but that only gave me more errors.

What the code does:

The code is supposed to create a dialogue system similar to The Elder Scrolls games, where each line of dialogue and each player response are recognized as their own object. The dialogue text is output to a browser in a window, and then the possible responses are listed in a grid, with all of the actions being listed as the datums, creating the potential for infinite responses, if I wanted it that way.

EDIT:

I just fixed a few things in the code, because quite a few of these lines were causing compiler and runtime errors, and even glitches. Here's an updated version:

Dial
var/npct = ""
var/responses = list()

Resp
var/respt
var/Dial/next

mob/var/talktarget

Dial/TestDial
npct = "Hello, I'm Santa Clause. You are a worthless piece of crap."
responses = list(/Resp/TestDialRA,/Resp/TestDialRB,/Resp/TestDialRC)

Resp
TestDialRA
respt = "No, you!"
TestDialRB
respt = "Okay. :("
TestDialRC
respt = "How dare you!"

mob/proc
ShowDial()
winshow(src,"dial",1)
GetDial(mob/M,Dial/D)
var/Resp/R
var/i=1
src.talktarget = M
src << browse("[M.name]","window=dial")
winset(src,"playerchoice",{"cells="1x1"})
for(R in D.responses)
src<<output("<a href=?src=\ref[src];action=[R]>[R.respt]</a>","[i++],[i++]")

/*mob
Topic(href,href_list[])
switch(href_list["action"])
if(Resp) //undefined var
GetDial(src.talktarget,Resp.next)


*/


The problem I have here is listing the responses, I'm not sure why, but none of them are showing up in my Dial window.
Best response
I don't understand why you are using a grid for something like this?

Well, onto the problems I noticed...

You are attempting to loop through /Resp datums but are scripting to where there aren't actually any inside your responses list, only the paths. To fix that simply add new in front of each path.

responses = list(new/Resp/TestDialRA,new/Resp/TestDialRB)


Im not entirely sure, but I do believe you are using winset() incorrectly as well. It should be winset(src,"parentWindow.gridName","cells=1x1").

Also, the way you've set the grid, I believe you aren't using output correctly, and it would display output in a diagonal slash downwards. That can easily be fixed though.

src<<output("<a href=?src=\ref[src];action=[R]>[R.respt]</a>","gridName:1,[i++]")


Now, I could be wrong on some of my points, because I'm not sure if setting a grid to default will cause it to react differently to commands (I prefer on-screen interaction opposed to the use of grids). However, my suggestions should help you tremendously.
Thank you! The responses are now finally showing up. Now, my only problem is making the topic recognize what a Resp is. After that, this dialogue system will almost be good to go!
Okay, I've finally made the Topic() proc without errors, but it just doesn't work.

Dial
var/npct = ""
var/responses = list()

Resp
var/respt
var/Dial/next

mob/var/talktarget


mob/proc
ShowDial()
winshow(src,"dial",1)
GetDial(mob/M,Dial/D)
var/Resp/R
var/i=1
src.talktarget = M
src << browse("<body bgcolor = black> <font color = white><h3>[M.name]</h3><br><p>[D.npct]</p>","window=dial")
winset(src,"playerchoice",{"cells="1x1"})
for(R in D.responses)
src<<output("<a href=?src=\ref[src];action=[R]>[R.respt]</a>","playerchoice:1,[i++]")

mob
Topic(href,href_list[])
switch(href_list["action"])
if(/Resp) //undefined var
var/Resp/R = href_list["action"]
GetDial(src.talktarget,R.next)


Sometimes, I really wish we were given more control over the DM engine.
Your if check there is obviously your problem.

It looks like you're trying to execute a safety check, but you aren't quite sure how.

I haven't fiddled with Topic() much, but I assume that this would work, or something like it:

var/r = href_list["action"]
if(istype(r, /Resp))
In response to GamerMania
Your problem is that you're just passing the literal text "/Resp" through your link, which isn't enough information to figure out which /Resp object they actually selected.

What you need to do is use the \ref text macro to embed the object instance's ID in your link. Then in Topic(), you can pass that ID to locate() to get an actual object reference back. You'll also want to track which Dial the player is currently interacting with, because they can "spoof" the link to reference any Resp instance ID they want (as the reference puts it, "Never trust those sneaky players!")

Here's an example:
Dial
var/npct = ""
var/responses = list()

Resp
var/respt
var/Dial/next

mob
var
mob/talktarget
Dial/activeDial

proc
ShowDial()
winshow(src,"dial",1)

GetDial(mob/M,Dial/D)
src.talktarget = M
src.activeDial = D // Remember which Dial is active so we can verify that a selected response is valid

if(D)
src << browse("<body bgcolor=black><font color=white><h3>[M.name]</h3><p>[D.npct]</p></font></body>", "window=dial")

var/i=1
for(var/Resp/R in D.responses)
src<<output("<a href='?src=\ref[src];action=respond;response=\ref[R]'>[R.respt]</a>","playerchoice:1,[i++]")

winset(src, "playerchoice", {"cells="1x[i-1]"}) // Moved this to the end for less visual-stutter

mob
Topic(href,href_list[])
switch(href_list["action"])
if("respond") // If the link had its action set to "respond"
var/respId = href_list["response"] // Get the /Resp object's ID from the link's "response" param
var/Resp/R = locate(respId) // Use locate() to get the object based on the ID
if(istype(R) && activeDial && (R in activeDial.responses)) // Verify that this is a valid object, and not an old/spoofed link
GetDial(src.talktarget,R.next)
That works perfectly, DarkCampainger. Thank you!