ID:1351561
 
(See the best response by Ter13.)
Code:
mob/var/quests = list()

FetchQuests
var
mob/M
quest_obj
reward_XP = 0
reward_object = "No Items"
reward_gold = 0
title
desc
thanks
question
finished = 0
proc
Check()
var/obj/O
O = locate (quest_obj) in M
if(O)
Reward(M)
Del(O)
return
else if(finished)
M << "[thanks]"
else
M << "[question]"
Reward(mob/M)
if(reward_object != "No Items")
new reward_object(M)
M.gebots += reward_gold
M.HP.addXP(reward_XP)
M << "<br><i>From this quest you have gained:</i> <br><b>[reward_XP]</b> XP<br><b>[reward_object]</b><br><b>[reward_gold] Gebots</b>"
M << "[thanks]"
finished = 1
Sample
quest_obj = /obj/SampleObj
reward_XP = 10
reward_object = "Sword of Butts"
reward_gold = 50
title = "Emblem - Reges"
desc = "I must get the Reges Emblem for one of the soldiers."
thanks = "<b>Reges Soldier</b>: Thanks, you've done the Reges a great service that we won't forget."
question = "<b>Reges Soldier</b>: Have you found the emblem yet, like I asked?"


obj/SampleObj
icon = 'Reges.dmi'
icon_state = "emblem"
verb/Take()
set src in oview(1)
src.loc = usr

mob/SampleQuest
name = "Reges Soldier"
icon = 'player.dmi'
var/FetchQuests/Sample/Q
verb/Talk()
set src in oview(1)
if(/FetchQuests/Sample in usr.quests)
Q.Check()
usr << "<b>[src]:</b> Hey, [usr]. Could you help us with something? We somehow left our emblem by a tree, and for some reason, it's important. I need you to find it for me, please."
usr.quests += Q


Problem description:
I can't make the Quest datum apply to the player himself. usr doesn't work, and if I add a proc like "StartQuest", my only option is to make another variable equivalent to M, which gives me errors. I don't know what to do!
This is your problem:

        if(/FetchQuests/Sample in usr.quests)
Q.Check()


You are checking if a type value is in a list. Obviously, an initialized quest will not be equal to the type.

I think this is more what you meant to do:
if(usr.quests.Find(Q))


Other than that, though, this is a miraculously inefficient way of going about designing your quest system. Give me a few minutes to give you some pointers.
Best response
Okay, here's why your quest system doesn't really seem that elegant.

Mostly, it's because you are defining way too much about the quest into the object.

None of your behavior actually has to know about the player that the quest belongs to ahead of time.

Your current system uses one quest object per player. You only need one quest object per unique quest.

Try this on for size:

mob/player
var/list
quests
New()
. = ..()
quests = list()

FetchQuests
var
tmp/id = 0
quest_obj
reward_XP = 0
reward_object
reward_gold = 0
title
desc
thanks
question
proc
Check(var/mob/player/M)
switch(M.quests[src]) //use switch, as it's faster and intended for just this situation
if(1)
var/obj/O
O = locate (quest_obj) in M
if(O)
Reward(M)
Del(O)
return
if(2)
M << thanks
return
if(null)
M.quests[src] = 1
M << question
Reward(var/mob/player/M)
if(reward_object != null)
new reward_object(M)
M.gebots += reward_gold
M.HP.addXP(reward_XP)
M << "<br><i>From this quest you have gained:</i> <br><b>[reward_XP]</b> XP<br><b>[reward_object]</b><br><b>[reward_gold] Gebots</b>"
M << thanks
M.quests[src] += 1

obj/SampleObj
icon = 'Reges.dmi'
icon_state = "emblem"
verb/Take()
set src in oview(1)
src.loc = usr

mob/SampleQuest
name = "Reges Soldier"
icon = 'player.dmi'
var
FetchQuests/Q
verb/Talk()
set src in oview(1)
Q.Check(usr)


I also slimmed down your abuse of needless strings, and your needless delimiting of variables as strings.

I would suggest using types to create reward items rather than strings, as that method is significantly slower than using absolute paths stored in a variable owing to the fact that the VM has to do a tree search to find which string correlates to the type path.

This is still not ideal, but at least it's somewhat sensible now.

I would also avoid creating quests the way you are. You should probably dump your entire world's quests and questgiving NPCs into a savefile. You will also need to save the quest's id, and make sure the id is unique in order to ensure that the player loads with the proper quest completion status after saving and quitting. Another thing you need to pay attention to: You need to keep a global list of all quests that are saved, so that when players load from the savefile, you can grab quest references out of the global list.

This is a trick I learned from lummox:

array[objref]


Apparently, you can associate arrays to just about anything, so we're abusing this little quirk to avoid the overhead of text, and keep the benefits of associative lists.

As for your saving system:

mob/player
var/tmp
list/quests

Write(var/savefile/F)
. = ..()
F.cd = "quests"
for(var/FetchQuests/Q in src.quests)
F << Q.id
F << src.quests[Q]
F.cd = ".."

Read(var/savefile/F)
. = ..()
F.cd = "quests"
var/q
var/s
while(!F.eof)
F >> q
F >> s
src.quests[q] = s
F.cd = ".."

var
list/globalquests = list()

proc
saveQuests()
var/savefile/F = new/savefile("allquests.sav")
for(var/v in globalquests)
F << v
loadQuests()
var/savefile/F = new/savefile("allquests.sav")
var/FetchQuests/Q
while(!F.eof)
F >> Q
globalquests += Q
Q.id = globalquests.len


Now, there are a few things that are missing here. One, you can never extend FetchQuests into a different type, so you will probably want to Root FetchQuests to a general Quest type, then leave a few unified method handles for interacting with it. But that's much later. In the meantime, this will at least show you the theory of what you are doing, and give you some direction to head towards.

As for creating quests the first time, you will probably have to either create a "quest creation system", or you can just hardcode them in a separate code file, run a test world, dump your savefile, then unlink the code file you define specific quests in.
Eh, "Sword of Butts" was just for testing purposes, since I didn't feel like making any reward OBJ's just yet. Thank you, though!
In response to GamerMania
GamerMania wrote:
Eh, "Sword of Butts" was just for testing purposes, since I didn't feel like making any reward OBJ's just yet. Thank you, though!

I updated my response with some advice on saving this kind of a system. Hate to keep one-upping you, but I keep seeing you writing systems that are *ALMOST* well thought out. You did good on this one, just a few minor concepts missed.