Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Suggestions & Ideas / Questjournal - Understanding and Debugging Quests
« Last post by erwin on January 05, 2017, 08:29:52 pm »
Hi all,

This post is meant to illustrate how to debug quest scripts with the questjournal. Writing triggers for the questjournal itself (and debugging them)will be in another post.

PS (sorry Roland, Thotter in advance) - feel free to add on to this post, clarify it if I skip some points.

questflags now look like this: questcardx_questname, for example, there's:

Code: [Select]
questcard7_viking
questcard19_riddle

To find all quest related triggers pertaining to that questcard, you can simply do
Code: [Select]
tsearch all questcardxx, example:
Code: [Select]
*find triggers related to questcard 19
tsearch all questcard19

All flags related to this quest will be in this flag. Sometimes, there may be subflags, eg
Code: [Select]
questcard19a
questcard19b
...

Most flags follow the below style. Here, we have a fake flag (questcard200_myquest), and show how it might look like, when you search for this flag on a player.

Code: [Select]
questcard200_myquest: noprog 0 notdone inprog 2 notdone inprog 3 done noprog 0 done
How do you read this? You can think of this in "groups of 3", so in this zone, there are four quests.

For the first quest, the player is not on the quest, is at step 0, and hasn't completed it.
For the second quest, the player is on the quest, is at step 2, and hasn't completed it.
For the third quest, the player is on the quest, is at step 3, and has completed the quest at least once.
For the fourth quest, the player has completed the quest, and hasn't restarted it again.

Think of noprog / inprog as noprogress and inprogress, notdone and done as whether the player has completed the quest at least once.

So we have two benefits already: First, flags are consolidated into one flag (less spam when you vstat a player's flags). Secondly, you can tsearch questflags easily by tsearch questcardxx.

However, because there are "multiple flags" on one flag (multiple variables in one array), things are a bit trickier.

Previously, you could do something like:
Code: [Select]
if !%actor.varexists(hanna)%
  * Player doesn't have this flag
  %send% %actor% You are not on this quest!
  %send% %actor% I will put you on this quest!
  set hanna 1
  remote hanna %actor.id%
else
  * Player has this flag
  set hanna %actor.hanna%
  if %hanna% == 1
    %send% %actor% You are on step 1. Let me progress you to step 2
    set hanna 2
    remote hanna %actor.id%
  elseif %hanna% == 2
    %send% %actor% You are on step 2. Let me progress you to step 3
    set hanna 2
    remote hanna %actor.id%
  endif
endif

How can you do this now? Let's imagine Hanna is the third quest for this zone, so we need to look at the third group, i.e. the group in bold here.

questcard200_myquest: noprog 0 notdone inprog 2 notdone inprog 3 done noprog 0 done

Let's look at a WRONG way to do this first.

Code: [Select]
* A wrong way
if !%actor.varexists(questcard200_myquest)%
  %send% %actor% You are not on this quest!
  %send% %actor% I will put you on this quest!
  set questcard200_myquest noprog 0 notdone noprog 0 notdone inprog 1 notdone noprog 0 notdone
  remote questcard200_myquest %actor.id%
endif

You might think the above code makes sense, since you're setting just the variables for the third quest. But, what if the player was on the other quests? You'd be resetting his or her progress.

Thus, every questcard now has up to three FUNCTIONS. A room function, a obj function, and a mob function. You can tsearch to find these functions, which look like this, and each have identical code (only the type - room, obj, mob differs).

Code: [Select]
* Example of an object function
Name: 'Questcard200 obj function',  VNum: [12345], RNum: [----]
Trigger Intended Assignment: Objects
Trigger Type: FUNCTION , Numeric Arg: 100, Arg list: None
Commands:
* Create this questflag if it doesn't exist
if !%actor.varexists(questcard200_quest)%
  set questcard200_quest noprog 0 notdone noprog 0 notdone noprog 0 notdone noprog 0 notdone
  remote questcard200_quest %actor.id%

  * To reassure people that their old flags aren't deleted
  * suppose they completed quest 1 before
  if %actor.varexists(oldflag1)%
    replace_word done 3 questcard200_quest
    rdelete oldflag1 %actor.id% 
  endif
 
  remote questcard200_quest %actor.id%
endif

Now, this is what you can do:
Code: [Select]
* Need to check if is PC before calling any functions.
if %actor.is_pc%
  *For any trigger which deals with questflags 
  *Call the appropriate function (room, mob or obj?)
  *Pretend it's an object so call the function above

  * This function sets the questflag ONCE, if it doesn't exist.
  function 12345
  * The below line can't bug, because we've created the flag if it didn't exist.
  set questcard200_quest %actor.questcard200_quest%

  * Now, proceed as normal, eg:

  if %questcard200_quest.wordat(7)% == noprog
    %send% %actor% You are not on this quest.
    %send% %actor% I will put you on this quest
    %send% %actor% I will replace the 7th word in your flag to show you are now in progress
    replace_word inprog 7 questcard200_quest
    %send% %actor% I will replace the 8th word by 1 to show you are now on step 1 for this quest
    replace_word 1 8 questcard200_quest
    remote questcard200_quest %actor.id%
  else
    if %questcard200_quest.wordat(8)% == 1
      %send% %actor% You are on step 1
      replace_word 2 8 questcard200_quest
      remote questcard200_quest %actor.id%
      %send% %actor% Now you are on step 2
    elseif %questcard200_quest.wordat(8)% == 2
      %send% %actor perfect, let's give you a reward
      if %questcard200_quest.wordat(9)% == notdone
        %send% %actor% You haven't done this quest before, so I'll give you a big reward!
        replace_word done 9 questcard200_quest
      else
        %send% %actor% You've done this quest before, so a smaller reward!
      endif
      * Reset all other questflags for this quest so
      replace_word 7 noprog questcard200_quest
      replace_word 8 0 questcard200_quest
      remote questcard200_quest %actor.id%
    endif
  endif
endif

So this is how the code would look like. Finally - how can we debug?

Here's some common errors.

Firstly, the trigger is not enclosed within:
Code: [Select]
if %actor.is_pc%
  ...
endif

Previously, you didn't need to have this check. Now you always need to have it.

Secondly, the WRONG type of function is called. We called function 12345, which was an Object function. If the trigger was a Mobile trigger, then you must call an Mobile function. If the trigger was a Room trigger, then you must call a Room function. Again, these three functions would have identical code, just different types.

Thirdly, logic wise. In this case, this is usually a problem with the old quest. As you can see, quests have the same logic. However, we have just used replace_word and wordat to work with arrays.



Finally, you may have a question. Hold on: How do I know if this player's quest is the THIRD quest or the FOURTH quest? Good question! Imms have a command (note me if you can't get this to work): questcheck card<num> debug <playername>, which actually goes into way more detail what each variable represents.




12
News & Announcements / Re: How many action figures have YOU collected?
« Last post by Mott on January 03, 2017, 07:14:10 am »
lol then i will have to wait till next halloween to collect them all!
13
News & Announcements / Re: How many action figures have YOU collected?
« Last post by Kvetch on January 02, 2017, 08:15:02 pm »
Those action figures were part of a Halloween thing - not the "real" action figures for whatever quest that is.
14
News & Announcements / Re: How many action figures have YOU collected?
« Last post by Mott on December 31, 2016, 09:32:28 am »
You are missing

a Shorty collectible action figure

on the list. 

Or is it not supposed to exist in 4D these days?
I've been gone too long, so I have no idea where I got that Shorty action figure from...
15
Suggestions & Ideas / Re: Questjournal v1
« Last post by rynald on December 19, 2016, 01:42:46 pm »
That's great news, i'm a fan of the journal. You can join gitlab as far as i'm concerned, but it doesn't track triggers (yet), only code.
16
Suggestions & Ideas / Re: Questjournal v1
« Last post by erwin on December 19, 2016, 03:18:40 am »
*actually you know what - add me to the 4D Github if there's one. I'll also upload my trigger files for each quest. This makes it easy for everyone to debug.
17
Suggestions & Ideas / Re: Questjournal v1
« Last post by erwin on December 19, 2016, 03:11:41 am »
Back!

Here's the new plan - with Vryce, Jubei, and Mott helping.

The idea is to *rigorously* do and complete the quest journal. This also means extensively playtesting old quests.

Cycle will be slow, but this ensures no bugs.
18
Building Board / Checking to see if a door is open or closed
« Last post by Kvetch on September 18, 2016, 07:25:12 pm »
I'd been whining about this for a while:
When you have an exit that has a door do you:
1) describe the door : like look east - you see a large oak door - since the player wouldn't know what room was beyond it unless they have already visited it, or
2) describe the room that lies beyond the door: like look east - you see the library there - since they should be able to know the neighboring room is a library if the door is open.

If the door is closed, 2 doesn't make sense.  If the door is open, 1 doesn't make sense, but there was always only one exit description.

After whining again yesterday, Roland did a look into it for me and found out this:

room trig:

if %self.east% /= closed
 
and in a mob trigger:

if %self.room.north% /= closed
 
See http://old.tbamud.com/Oasis_DG_pages/contents/variables.htm in the Rooms section for the details.

So now, if you're really into doing scripts and really want a different description for your exit if there is a door - you can do it. 

Yay.
19
Building Board / Re: Day/Night script
« Last post by Kvetch on September 09, 2016, 07:33:51 pm »
Still love you, Parn and I'm redoing the haunted house again.  Could use your amazing ideas and scripting skills on that again.

FYI: I had tried to use that %actor.room.vnum% on some global time loading scripts and realized it wouldn't work since there's not a command that anyone would do - so there would be no %actor% in that case.  So.. it became %self.vnum% for that.  These %actor.room.vnum%'s could probably be changed to %self.vnum% and have it work too.
20
Building Board / Re: Day/Night script
« Last post by Parnassus on September 08, 2016, 04:33:31 pm »
Butbutbut....it was SUPPOSED to work!  I dunno why it doesn't work *sniff*.  In fact, we tweaked it and tweaked it on the buildport and it really seemed to me that it was working but when I tried it in the game, well, it just didn't work *sob*.
Pages: 1 [2] 3 4 ... 10