The World of Layonara
NWN Discussions and Suggestions => NWN Ideas, Suggestions, Requests => Topic started by: Hellblazer on July 01, 2010, 05:10:50 am
-
I was thinking that it could be a good idea, if there would be an other page added or to the boat captain discussion screen that would say:
So basically the idea would be to see
conversation 1
Captain: What can I do for you Mate?
Char: I'm looking for passage
Conversation 2
Captain: Well do you have a ticket?
Char: 1 yes I do
2 No, sorry.
that's where we could see a new conversation screen that would say one of those two bellow
As you go through your pack to find your boat tickets, you notice that you have "x amount" of tickets left.
Or
As you are ripping a ticket from the booklet, you notice that you have "x amount" of tickets left.
option: 1 continue
then conversation 4
Captain: Where do you want to sail
Char: sailing choices.
Seems like a good idea.
-
Straightforward answer here:
The current system (I can only surmise) uses the "HasItem()" boolean function to determine whether the user has the necessary item (a boat ticket) on them. This function is optimized by Bioware (in fact, items might actually be hashed when you add them to your inventory for that purpose, to avoid a linear search).
The code involved looks like this:
int StartingConditional()
{
// Make sure the PC speaker has these items in their inventory
return HasItem(GetPCSpeaker(), "boat_ticket_tag"));
}
To determine how many copies of item x are on your character, however...
void main()
{
object oPC = GetPCSpeaker();
int nCount = 0;
// To count how many items we find
object oLoop = GetFirstItemInInventory(oPC);
// Get first item in players inventory
while (oLoop != OBJECT_INVALID)
// Loop through all his/her inventory
{
if(GetTag(oLoop) == "boat_ticket_tag")
{
nCount++;
// Increase nCount by one for each item found
}
oLoop = GetNextItemInInventory(oPC);
// Get next item in the players inventory
}
}
This would cause a lag spike any time anyone had that conversation. Not as severe a one as when they log in and the server has to create everything in their inventory, but similar. Sadly, there's no quicker or more efficient way to do it. It's because of this that (for example) Jasmin in the Swamp only takes one knuckle bone at a time.
So doable, but the potential impact on the server (particularly for the people whose inventories are cluttered enough that this would be convenient) seems to outweigh that convenience.
-
Would there be a way to delay the search for one loop per certain heartbeat? A bit like spreading the loading of a house onto a longer time period? Maybe a message through the server message instead once the delayed count has been made instead of an automatic message in the discussion with the captain?
-
Would there be a way to delay the search for one loop per certain heartbeat? A bit like spreading the loading of a house onto a longer time period? Maybe a message through the server message instead once the delayed count has been made instead of an automatic message in the discussion with the captain?
There's not really any easy way that could be done. Bioware doesn't provide any easy way to maintain an iterable list of items in an inventory - partially because any point after the script starts, the inventory could conceivably change. Even if there were a simple way to do it, houses only have to be loaded once. This script would fire every time anyone took a boat anywhere.
One way this could be simplified would be to replace the physical "tickets" with a variable on the PC (or more precisely, on their Gem of Memory), but that would make it difficult to give tickets to other people. Alternately, tickets could be done away with altogether and just have the captains take gold. That would, however, mean that buying tickets in bulk or getting successful Appraise/Bluff/Intimidate/Persuade checks to reduce their cost would no longer be an option.
So there are solutions, but they would involve trade-offs.
-
Thanks for the info.
-
Okay. For the sake of accuracy(1), HasItem() is a wrapper for GetItemPossessedBy(). GetItemPossessedBy() returns the object, in this case the stack of tickets. Getting a valid object, you could GetItemStackSize() to see how many tickets are in that particular stack. That information (about that stack) could then be returned in the conversation.
Regards,
Script Wrecked.
(1) because I can't help myself
-
Would that give some lag in return then?
-
No inventory iteration, no (more) lag (than is currently caused by HasItem()).
-
I should have mentioned that, yeah. GetStackSize() would give you the number of tickets in the stack. Just not necessarily the number of tickets you have.
-
Alright getting somewhere possibly. The stack item is updated when it reduce or gets bigger in size right? So would the GetItemStackSize() take that into account or does it just return the maximum number possible for that stack type?
-
The current stack size.
-
So then my proposition would be possible without adding any lag, and would return it in the conversation?
-
Yup..
-
Cool!