ID:163932
 
I have an NPC that gives you a rare item after going througha hard dungeon. The problem is, he will keep giving it to you even after you already recieved it. Any help?
Avlein wrote:
I have an NPC that gives you a rare item after going througha hard dungeon. The problem is, he will keep giving it to you even after you already recieved it. Any help?

If you need help on checking if there is an item already in the inventory, then you can use locate() to determine if an object of a certain type is in a container. In this case, you want to check if an item is in the player's inventory. Therefore, you can do something like this:

var/obj/questitem/Q = locate() in src.contents // assuming 'src' in the context is the player
if(Q) // Q will be null if nothing was found, so something was found
src << "You already have the quest item!"


However, if you foresee that the item may leave the player's inventory at any time, you will have to use other methods to prevent the player from getting it again after they used the item.
In response to Unknown Person
Yeah, but the problem is that they keep dropping it everywhere.

IS there any way I can make the NPC 'ID' whoever had gained the item already?
In response to Avlein
It would probably be better to make items gained from NPC's and the like non-droppable, you wouldn't want people getting items without talking to the NPC.
In response to Nadrew
Good idea. Thanks.
In response to Avlein
You could make a mob list to keep track of which quests they've completed. Then just check the list to see if they've completed the quest before giving them the reward item.

mob
var/list/quests_completed


// Call this when completing a quest!
// The argument is the name of the quest which has been completed.
proc/FinishQuest(quest_name)

// If its not a list already, make it into one.
if(!src.quests_completed)
src.quests_completed = list()

// Add that quest to the completed list and inform the player (optional).
src.quests_completed += quest_name
src << "You've completed the [quest_name] quest!"
return


// Check this to see if a quest has been completed already.
// The argument is the name of the quest to check for completion.
// Returns 1 if it has been completed and 0 if it hasn't.
proc/QuestCompleted(quest_name)

// They don't even have a quests list, of course they
// haven't completed this quest yet!
if(!src.quests_completed)
return 0

// If the quest name is found in the completed list, they've already done it
if(quest_name in src.quests_completed)
return 1
return 0




// EXAMPLE
mob/farmer_joe
name = "Farmer Joe"

verb/Quest()
set src in range(usr, 1)
if(!usr.QuestCompleted("peanuts"))
// player has not completed this quest

var/obj/peanuts/P = locate(/obj/peanuts) in usr.contents

if(P)
// player has quest item
usr << "[src] says: Thank you very much!"
del(P)
usr.FinishQuest("peanuts")

else
// no quest item
usr << "[src] says: I need you to bring me some peanuts!"

else
// player HAS completed this quest
usr << "[src] says: Lovely weather we're having, eh?"
In response to Avlein
Ah. One more problem.

Now he says this.

"Here's your prize! A portable radio!
You already have the radio! stop talking to me!"

Is there anyway to make him say that the 2nd time you talk to him?
In response to Avlein
Look at the code.
Read the DM Guide.
Your just asking "specific" questions, reading the DM Guide for 30 minutes would show you how to do that.
In response to Flame Sage
Um. Well, i'm new at this. And I don't understand the guide. Actually, I don't even know where to look at the guide.

Right now, my code is like this.

            verb
Talk()
set src in oview(1)
usr << "Fake KW: What?! You beat my level?! I bet you cheated! Oh well. Take this prize. It's a Portable Radio. It will allow you to play music anywhere."
usr.contents += new /obj/item/PortableRadio
var/obj/item/PortableRadio = locate() in usr.contents
if(PortableRadio)
usr << "You already have the Radio! Stop talking to me!"
return

He will just say both lines together, and keep giving radios.
In response to Avlein
It would be better to make a var and once you complete the questy the var becomes true, because if you drop it he will give it again, since it loops to see if its inside your inventory.

- Miran94
In response to Avlein
Ugh...This is getting ridiculous. The Byond guide isn't helping much either.

Anyone, can you tell me how to make him stop giving out radios? ;_;
In response to Avlein
I just told you.
In response to Miran94
I'm sorry. But I don't know how to do that... Can you explain a bit further?
In response to Avlein
Let me dissect the snippet you have shown us:
verb
Talk()
set src in oview(1) //Sets the verb 1 step from the person who has it
usr << "Fake KW: What?! You beat my level?! I bet you cheated! Oh well. Take this prize. It's a Portable Radio. It will allow you to play music anywhere." //This message will be told regardless if the person already beat it before or not as it is not under any conditional statement.
usr.contents += new /obj/item/PortableRadio //Adds the item to the usr's contents regardless if they already got it or not. A better form of typing this is new/obj/item/___(usr)
var/obj/item/PortableRadio = locate() in usr.contents //Checks if an /obj/item is in the contents (note that it is not checking for a portable radio..: var/___path here___/var__nickname
if(PortableRadio) //If an /obj/item is found
usr << "You already have the Radio! Stop talking to me!" //message is given
return //stops rest of code block, which is useless since this is the end anyways. Maybe you wanted this at the top before the person gets the item? ;/


If you read the comments, I mentioned how to fix your little problems (per say).
In response to Avlein
Wow, I feel like everyone is totally ignoring my whole solution in [link].
In response to Foomer
Foomer wrote:
Wow, I feel like everyone is totally ignoring my whole solution in [link].

lol your solution would require him to integrate that into his game, he wants u to write the whole game code for him lol =P
In response to White Flare
I already found my solution. Thanks everyone.