26 Sep, 2009, David Haley wrote in the 21st comment:
Votes: 0
Maybe I should have added sarcasm tags. :rolleyes:
26 Sep, 2009, Tyche wrote in the 22nd comment:
Votes: 0
Scandum said:
More of a design related response, but the whole concept of quest objectives saved on the player is fundamentally flawed. Players should keep their own quest logs if they have a poor memory, and builders should focus on writing the actual quest instead of a game mechanism introduced by graphical games so idiots can play their games. More often than not the summarized objective becomes the quest, instead of what the NPCs say or do, which is probably as immersion breaking as it gets.


The goal might be scoring. I keep quests in an expandable bit field. That way I only score the quest once, although characters may repeat it as often as they like.
26 Sep, 2009, David Haley wrote in the 23rd comment:
Votes: 0
It also can be used as a trophy collection of sorts for players. There are any number of reasons why many games have quest logs – not the least of which is that players like them.
26 Sep, 2009, Scandum wrote in the 24th comment:
Votes: 0
David Haley said:
not the least of which is that players like them.

……. seriously?
26 Sep, 2009, David Haley wrote in the 25th comment:
Votes: 0
Seriously what?
26 Sep, 2009, Scandum wrote in the 26th comment:
Votes: 0
Where's your handbook of what players like and what players do not like?
26 Sep, 2009, David Haley wrote in the 27th comment:
Votes: 0
Probably about the same place as your handbook on how stupid players are. :rolleyes: Anyhow, let's try to move this back to useful conversation…
26 Sep, 2009, JohnnyStarr wrote in the 28th comment:
Votes: 0
In a text enviornment you need all the info you can get right?
The entire reason i am dong this is because as a player, it was
Always something i wanted.

Ps. Sorry for the assumption David.
26 Sep, 2009, JohnnyStarr wrote in the 29th comment:
Votes: 0
Real quick, since the issue was the loading the list in the right order,
And not quest design, if you feel a doubly linked list isn't wise, then
How should i go about it?
26 Sep, 2009, Scandum wrote in the 30th comment:
Votes: 0
staryavsky said:
Real quick, since the issue was the loading the list in the right order,
And not quest design, if you feel a doubly linked list isn't wise, then
How should i go about it?

I think David is confused, head and tail pointers solve your problem, and they can be used with both doubly and singly linked lists.
26 Sep, 2009, David Haley wrote in the 31st comment:
Votes: 0
No worries :smile: Personally Star, I think having a quest log is an exceedingly good idea, and a quest system without one has some issues. Despite what Scandum thinks, you have several major and very successful single- and multi-player games on your side, so I think you're probably safe. :wink:

I would go with a singly-linked list. Have a single pointer, 'quests' or something, and have it point to a quest_list_node structure of some kind. Each quest_list_node contains a pointer to the quest_data, and a 'next' pointer to the following node in the linked list (or null).

Then, insertion means sticking things in the front of the list. (It's usually easier to maintain singly-linked lists than doubly-linked lists.)

Now, if the order in which things are inserted into the list is important, you can use a doubly-linked list, or just keep a pointer to the last element in the list. Or, you can just always put things in front, and when you display things, do it in reverse.
26 Sep, 2009, Davion wrote in the 32nd comment:
Votes: 0
Scandum said:
staryavsky said:
Real quick, since the issue was the loading the list in the right order,
And not quest design, if you feel a doubly linked list isn't wise, then
How should i go about it?

I think David is confused, head and tail pointers solve your problem, and they can be used with both doubly and singly linked lists.


Pretty sure he's replying to the actual code solution Kline provided.
26 Sep, 2009, JohnnyStarr wrote in the 33rd comment:
Votes: 0
Cool,
How might one display a singly list in reverse?
26 Sep, 2009, KaVir wrote in the 34th comment:
Votes: 0
staryavsky said:
How might one display a singly list in reverse?

You could use recursion, but I'd strongly suggest you don't. Either reverse the order of the list (as has been suggested), or if you need to iterate through it in both directions, change it to a double linked list.
26 Sep, 2009, David Haley wrote in the 35th comment:
Votes: 0
Yes. If you need to go both ways, use a doubly-linked list. If you need to go one way, build the list in the correct fashion, by sticking things in front (in which case you don't need a tail pointer) or at the end (in which case you should use a tail pointer, to avoid the O(N) insertion cost).
26 Sep, 2009, JohnnyStarr wrote in the 36th comment:
Votes: 0
if(!ch->quest_first )
ch->quest_first = quest;
if( ch->quest_last )
ch->quest_last->next = quest;
ch->quest_last = quest;


in this example, as brought out by davion, i dont see how the head
pointer 'quests' knows about what's added to the tail pointer.
as discussed about the iteration in previous posts, you would do:
for ( q = quests; q != NULL; q = q->next )


where does 'quests' meet the tail pointer?
27 Sep, 2009, Scandum wrote in the 37th comment:
Votes: 0
You'd probably want to use:
for (q = ch->quest_first ; q ; q = q->next)


ch->quest_last is only used for inserting nodes at the end of the list. I guess you could check against ch->quest_last in the loop, but it's easier to assume that the last node doesn't have a ->next pointer.
27 Sep, 2009, David Haley wrote in the 38th comment:
Votes: 0
staryavsky said:
i dont see how the head pointer 'quests' knows about what's added to the tail pointer.

Well, it doesn't. That's actually part of the beauty! As opposed to an array which needs to have a fixed, known amount of allocated memory (and sure, this can be reallocated), a linked list can go on "forever". The first node in the list is simply there, and it points to the next node, or not. That node might, or might not, point to another node. And so the chain just keeps on going, until it stops and the list is over.

So when does "quests" meet the tail pointer? Well, as you step through the list with "q = q->next", you will eventually find a node that has a NULL next pointer. That one is the tail pointer. But, you don't need to be aware of this: you simply need to know that as you go through it, you will eventually stop upon hitting the NULL pointer. The tail pointer is used for insertion, not iteration.
27 Sep, 2009, JohnnyStarr wrote in the 39th comment:
Votes: 0
Yes,
I understand there are 2 pointers.
I understand that the tail pointer adds elements to the back.
I dont understand how -based on davions example- the head pointer
Which is used to traverse the list can be aware of the tail.

Meaning, nowhere in the example does it say quest_first->next
27 Sep, 2009, David Haley wrote in the 40th comment:
Votes: 0
Well, quest_first is set to the first thing inserted (the line where quest_first != NULL is checked).
Then, you take the last element, and set its next to the new quest node.
So, the first node isn't aware of the things that are happening to the last list node.

Here is Davion's code, but with comments:

// If the list is empty (because quest_first is null) , set
// the new node to be the first quest node.
if(!ch->quest_first )
ch->quest_first = quest;

// If we have a last node, update its 'next' pointer to the new node.
if( ch->quest_last )
ch->quest_last->next = quest;

// In any case, the new node is now the last quest node.
ch->quest_last = quest;
20.0/49