Author Topic: After solving a quest rewarding the player with an object  (Read 4447 times)

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
After solving a quest rewarding the player with an object
« on: March 27, 2008, 01:32:56 pm »
Shoot me if this is noobish, but I want to find out.
In this piece of code from Leo.c a player who solves a quest is rewarded with exp and coins.
Code: [Select]
int CompleteQuest(object ob){
    string *quests;
    quests = ob->GetQuests();
    if(!ob->GetQuest("Orc Slayer Quest")){
        ob->AddQuest("the Orc Slayer","Orc Slayer Quest");
        eventForce("say You have solved the Orc Slayer Quest. Congratulations!");
        eventForce("say I hereby award you 10 quest points, and 2000 experience points!");
        ob->AddQuestPoints(10);
        ob->AddExperiencePoints(2000);
              ob->CompleteQuest("the Orc Slayer", "Orc Slayer Quest");
        reload("/domains/town/room/valley",0,1);
        reload("/domains/town/room/orc_fortress",0,1);
        reload("/domains/town/room/orc_temple",0,1);
    }
    return 1;

Now say I want this solver to receive an item besides his money and exp, how would I do that? I'm not quite figuring out the command.  ???
Right after 'ob->AddExperiencePoints(2000); I figure there must be something like:
'ob->AddObject(this_player, /path-to-item)'.

Does anyone have a really simple example or a reference in the default lib?
Eventually I'd like to program NPC's to return parts of items as part of the quest.
So upon saying or giving something to NPC 'A' a player would receive an item which is necessary to receive the next
piece from NPC 'B', which can be taken to NPC 'C' and so on...

Help's appreciated!
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.

Offline Tricky

  • BFF
  • ***
  • Posts: 189
  • I like what I code and I code what I like!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #1 on: March 27, 2008, 02:28:11 pm »
In this case ob is the player object. What you need to do is add an extra object variable and initialize it with the item you want to give to the player, ie...

Code: [Select]
int CompleteQuest(object ob){
    string *quests;
    quests = ob->GetQuests();
    if(!ob->GetQuest("Orc Slayer Quest")){
        /* Clone the object to be given to the player. */
        object item = clone_object("/path/to/object");
        /* ... */
        ob->AddQuest("the Orc Slayer","Orc Slayer Quest");
        eventForce("say You have solved the Orc Slayer Quest. Congratulations!");
        eventForce("say I hereby award you 10 quest points, and 2000 experience points!");
        ob->AddQuestPoints(10);
        ob->AddExperiencePoints(2000);
        /* as mentioned above, ob is already initialized with this_player() */
        if (!item->eventMove(ob)) {
            /* Oh dear, something went wrong. */
            ;
        }
        ob->CompleteQuest("the Orc Slayer", "Orc Slayer Quest");
        reload("/domains/town/room/valley",0,1);
        reload("/domains/town/room/orc_fortress",0,1);
        reload("/domains/town/room/orc_temple",0,1);
    }
    return 1;
}

You get the idea.

Tricky

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #2 on: March 27, 2008, 02:40:41 pm »
I'm on it! Thanks Tricky.
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #3 on: March 27, 2008, 02:41:32 pm »
Oh and gratz with your totally non-important BFF status :)
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #4 on: March 27, 2008, 04:13:15 pm »
You sure btw that clone_object is the correct command? Doesn't seem to work.
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.

Offline irmo

  • Acquaintance
  • *
  • Posts: 36
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #5 on: March 27, 2008, 04:29:23 pm »
Thanks Tricky! I'm sure this will be helpfull for a lot more people, not just Atomic and me.

And, indeed, clone_object doesn't seem to work in ds. I believe it should either be 'clone' without the _object, or 'load_object'. Anyway, this was very educational. I would love to see more of this sort of stuff. It should be simple for experienced coders to come up with examples, but it's probably hard to imagine how helpfull it can be to us. Perhaps it's a good idea to open a sub forum for teacher/student kind of topics?

Tricky for president!
« Last Edit: March 27, 2008, 04:31:25 pm by irmo »
I'm not as think as you drunk I am.

Offline Tricky

  • BFF
  • ***
  • Posts: 189
  • I like what I code and I code what I like!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #6 on: March 27, 2008, 05:07:50 pm »
Thanks Tricky! I'm sure this will be helpfull for a lot more people, not just Atomic and me.
I may not use the DS lib but I am useful sometimes.  ;D

And, indeed, clone_object doesn't seem to work in ds. I believe it should either be 'clone' without the _object, or 'load_object'. Anyway, this was very educational. I would love to see more of this sort of stuff. It should be simple for experienced coders to come up with examples, but it's probably hard to imagine how helpfull it can be to us. Perhaps it's a good idea to open a sub forum for teacher/student kind of topics?
Just did a quick check, clone_object() hasn't been overridden yet. The clone you are thinking about is a creator command. Looking further into that command shows that it doesn't use the clone_object() efun but uses new, it also has eventMove within it. Might be a good read for someone who wants to learn how to transfer objects about NPC's and players, or even the environment of the player/NPC, ie room.  ;)

Tricky for president!
Umm...

Tricky

Edit: Forgot to add, /cmds/creators/clone.c

Offline irmo

  • Acquaintance
  • *
  • Posts: 36
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #7 on: March 28, 2008, 09:37:02 am »
Thanks again, Tricky, that was also usefull. I think 'new'  is probably the most common way to do this sort of stuff in ds. I'm currently reading through the lib, doing the needed research, and it's been interesting and educational so far.

I ran into a minor problem, which is somewhat disturbing because eventhough it's not a huge problem, I would like to find a way to solve this. I'll take Leo as an example again, when giving him the Orcslayer and thereby solving the quest, the following problem occurs:

give orcslayer to leo
Leo exclaims in English, "You have solved the Orc Slayer Quest.
    Congratulations!"
Leo exclaims in English, "I hereby award you 10 quest points, and 2000
    experience points!"
You give Leo a finely crafted short sword.


As you can see, the output of me giving Leo the sword comes last. It isn't too much of a problem in this example, but looks rather strange - wrong even - in some of the quests that I'm trying to create. Is there a way to change the format, so the message "You give <person> <object>"  will be displayed directly after giving the object?

Examples and hints will be greatly appreciated, as so are the ones above.
Thanks in advance,

-Irmo.
I'm not as think as you drunk I am.

Offline Tricky

  • BFF
  • ***
  • Posts: 189
  • I like what I code and I code what I like!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #8 on: March 28, 2008, 09:49:42 am »
In eventRecieveObject() (just after CompleteQuest() function) what I would do is to delay the calling of the CompletQuest() func by wrapping it in a call_out()

Code: [Select]
    if( ob->GetKeyName() == "orc slayer" )
        call_out("CompleteQuest", 1, player);

This should make it print out the quest completion text after the message of giving the sword to Leo. Can't promise that of course.

Cratylus or someone more intimate with the event flow of DS would probably be able to give a more detailed and better answer.

Tricky

Offline irmo

  • Acquaintance
  • *
  • Posts: 36
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #9 on: March 28, 2008, 10:02:28 am »
Woh, that's a fast reply. :)

I'll go give this example a try, and I'll post the outcome of my test in this topic in case someone else is interested, unless Cratylus, or someone else who's more experienced with ds, provides us with the needed info before I get a chance to do so.

Thanks again Tricky! I'm learning a lot and I'm sure this topic will be of use to others as well. :)
I'm not as think as you drunk I am.

Offline irmo

  • Acquaintance
  • *
  • Posts: 36
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #10 on: March 28, 2008, 12:51:19 pm »
I failed to get the latest example to work, although it did give me a good understanding of how it's suppose to work.

Code: [Select]
int eventReceiveObject() {
    object ob, player;
    ob = previous_object();
    player = this_player();

       if( !ob || !::eventReceiveObject() ) return 0;
       if( ob->GetKeyName() == "orc slayer" ) CompleteQuest(player);
         if( ob->GetKeyName() == "orc slayer" )
           call_out("CompleteQuest", 1, player);
       
    AddCarriedMass((int)ob->GetMass());
    return 1;

}

I take it that's how it's suppose to look? The file will update fine. But after updating and reloading the npc, it will still come out in the same format - with the "You give 'person' 'object" still at the very end of the sequence.

I was unsure if there was a ; missing at the end of:

Code: [Select]
if( ob->GetKeyName() == "orc slayer" )
So I tried both options, both with the same negative result. Did I by any chance put those two lines of code in the wrong place?

-Irmo
I'm not as think as you drunk I am.

Offline Tricky

  • BFF
  • ***
  • Posts: 189
  • I like what I code and I code what I like!
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #11 on: March 28, 2008, 01:10:50 pm »
Ah! What I failed to mention was that you needed to replace the line
Code: [Select]
    if( ob->GetKeyName() == "orc slayer" ) CompleteQuest(player);
with
Code: [Select]
    if( ob->GetKeyName() == "orc slayer" )
        call_out("CompleteQuest", 1, player);
so the final piece of code looks like
Code: [Select]
int eventReceiveObject() {
    object ob, player;
    ob = previous_object();
    player = this_player();

    if( !ob || !::eventReceiveObject() ) return 0;
    if( ob->GetKeyName() == "orc slayer" )
        call_out("CompleteQuest", 1, player);

    AddCarriedMass((int)ob->GetMass());
    return 1;
}
I put the call_out on a separate line to shorten it for small width clients. You don't have to have the code that executes upon the condition of an if statement being true on the same line.

What that call_out efun is doing is calling CompleteQuest(player) after a delay of 1 second.

Tricky

Offline irmo

  • Acquaintance
  • *
  • Posts: 36
    • View Profile
Re: After solving a quest rewarding the player with an object
« Reply #12 on: March 28, 2008, 01:32:32 pm »
Ah, that makes sense. It totally worked, exactly the way I wanted it too. Thanks a ton! This really made my day. :)
I'm not as think as you drunk I am.