Author Topic: Persistent Inn System - W.I.P.  (Read 1428 times)

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« on: January 03, 2012, 02:34:32 am »


               

This thread shows my progress as I develop a set of scripts for persistent rental housing (inns/hotels etc...). I saw a few nice systems on the vault, but they weren't exactly what I wanted. To show my work in progress, I have pasted all of the scripts which are part of this project to pastebin. For the most recent code, you'll need to see the most recent posts. I want to track the evolution of the scripts, and thus leave the older posts unedited. (EDIT I broke this rule to activate syntax highlighting)

 

[edit - I've been working on this again and am nearing completion of all the needed features.

the updated code is v2_inc_housing]

Description of the parts:
- Persistency is set up to use NBDE(improved bioware database). But could likely be very quickly adjusted  to use any DB system. I have but 2 or three database calls.
- "aa_rentroom" is the name of the conversation file. It is reusable for any inn, and has dynamic text at every owner's node and every player reponse. Custom tokens are used for everything the player reads.
The conversation "aa_rentroom" is defined by three nodes as follows:

  • (1) show the room types available - up to 5 as defined by the builder. player selects one of the room types
  • (2) show up to 3 duration options  (1 night, 1 week, 1 month) for the room of the type selected by the player along with the cost associated with each duration. Display important info about the room such as how many occupants can fit, cost, services available (does it have a locked door? bath? continental breakfast? laundry?) etc....
  • (3) display for the pc what room they got, and any of the specifics the innkeeper needs to explain (such as check out time, where the room is, how to request services if any, house rules etc...) And if one of the room's services is "private" then give to the player a room key and set it up to work with their room door.

- The most important script in the conversation file is "aa_rentroom_tok". This script is attached to every one of the "owners's"  nodes in "Text appears when"
- Every "text appears when" slot for the player's responses has something like "aa_ck_token100" and an "action taken" script like "aa_conv_branch1". Each node has at most five of these kinds of responses. So there are 5 of each of these files as follows:
aa_ck_token100,aa_ck_token101, aa_ck_token102, aa_ck_token103,  aa_ck_token104, aa_conv_branch1, aa_conv_branch2,  aa_conv_branch3  aa_conv_branch4  aa_conv_branch5

-The script include for the system is "aa_inc_housing" and is called thus far by "aa_rentroom_tok". This contains all the working parts. I have not included my own master which has the utility scripts and the NBDE database system.
- I need one more script that handles garbage collection, and to place it in both the onconversation abort and finish slots. This will be a simple thing that deletes all temporary  local variables set on both the PC and NPC dyuring the course of the conversation. I have not yet written it.


Objects required: 
Perhaps the biggest drawback for the builder are the number of data objects, and local variables that this system requires. Its complicated enough that I may have to make some palette items (waypoints so that they can double as map points) prepopulated with local variables, and documentation of how the system works in the "comments" section. I hate to create items in teh palette and add objects to the module, but without these this system is hard to understand.

These objects include:

  • one or more inn keepers with a conversation that is either composed entirely of "aa_rentroom" or launches that conversation on the innkeeper. Each innkeeper needs a local string that contains the tag of the "inn" waypoint. See below. I think it is better to only have one innkeeper, and to only allow one PC at a time to converse with the innkeeper. But perhaps someone can improve the system to elimnate the problem of one pc quickly renting a room that another PC was just about to rent. (This would break the conversation if it occurred).
  • an "inn" waypoint with a tag unique to the inn. The inn is loaded with a ton of local variables. See the INN struct in "aa_inc_housing"
  • Each room is created by placing a waypoint tagged with the inntag + the number of the room. A number of local vars further define the room see the function InitializeRooms() in aa_inc_housing for more information.
  • A generic "room key" that is retagged, renamed and redescribed (SetDescription) by this system to work with the specific room door.

Keys:
A subsystem that I use alongside this but which is not strictly necessary is my key system (not to be confused with the old public transit system in Alameda County, CA). I have tag scripted keys that can unlock/lock doors that have a matching identifier. This enables all doors in an inn to be accessed by the innkeeper's master key, and yet room keys can open specific room doors. Its a very simple system that anyone can code. One more caveat - I rewrote my tag script activation so that they don't read the whole tag but only a subtag within the tag. GetTagPrefix() is used in that script. so a key could be tagged with key_innroom1 which would launch the do_key script instead of do_key_innroom1. And it functions as a key that looks for a local string on a door of "key_innroom1"

* * *

Issues I've already seen that need to be changed so that the code makes more sense and functions more naturally:

  • In retrospect I wish I had named those token scripts 101-105, instead of 100-104 and may change that later.
  • I should increase all of my indexes by 1, because my roomtype index starts at 0 instead of 1. That was a mistake, and creates a problem with the scripts.
  • Also my use of the Struct is kludgey and clumsy, and can be improved, but I'm not sure how to stream line it yet. Perhaps by making a sub struct for roomtype. Can you put a struct inside of a struct?

* * *

I know this system is no big deal for the real programmers out there, but for the lesser skilled amongst us such as myself I think its good to look at each other's work, share ideas, and thus improve. Thats why I am posting this in progress. Feedback is welcome. Especially that which pushes me to structure my code more effectively and efficiently.  


               
               

               


                     Modifié par henesua, 27 avril 2014 - 10:01 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #1 on: January 03, 2012, 02:56:13 am »


               I am not sure how inportant resource count is to you,  If it is something you are looking at keeping at a as low as possiable, you could use just one script for the PC responce scripts instead of 5 of them.   I if you need more information on how just let me know.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #2 on: January 03, 2012, 02:57:50 am »


               Yes, how do I use just one pc response script?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #3 on: January 03, 2012, 03:27:42 am »


               

henesua wrote...

Yes, how do I use just one pc response script?


*cringe*   Guess I stated that a little off.   It is the TextApearsWhen scripts we can reduce for the starting conditions on the PC responces.  unfortunately there is no way to reduce the Action taken scripts. 

it is basicly done by setting a local on the speaker.  every time a starting condition is ran it increases the local.  This way the script only has to read the Local to know what node it is on.    here is an example. 

http://pastebin.com/DAP07hzH 
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #4 on: January 03, 2012, 04:04:50 am »


                Thanks. So here is my new version of aa_ck_token100

This will now be on all "Text Appears When" slots for the PC Responses.
I can see that I will likely need some garbage collection to reset that token value to zero. But your modulus looks like it will help prevent that problem if I always set up five responses.

This is very useful as it eliminates the need for four scripts. I wish there was a way to use only one script in "Actions taken" as well. Let me know if you think of anything.
               
               

               


                     Modifié par henesua, 03 janvier 2012 - 04:18 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #5 on: January 03, 2012, 06:24:24 am »


               Revised aa_ck_token100

I had discovered a number of errors in the previous script.
               
               

               


                     Modifié par henesua, 04 janvier 2012 - 05:26 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #6 on: January 05, 2012, 03:44:29 pm »


                Update.
I am at the point of testing the code. Here is what the code looks like before testing:

aa_rentroom_tok
aa_inc_housing

I would like to slim down the scripts more, but have not had the time to sit down and rip all this code apart to get at the absolute essentials. I am seeking advice on how to make these scripts much leaner. Do I need all those functions? Is there a much leaner way to handle all of this? Is there an adjustment to my data structures that I have overlooked which would make this better?

The module resources now required after recent edits (and apparently as slim as I can go without combining aa_inc_housing with aa_rentroom_tok):

conversation
  • aa_rentroom
scripts
  • aa_rentroom_tok
  • aa_inc_housing
  • aa_ck_token100
  • aa_conv_branch1
  • aa_conv_branch2
  • aa_conv_branch3
  • aa_conv_branch4
  • aa_conv_branch5 
Items:
  • aa_rentalkey
Game Objects (placed in toolset):
  • Inn Keeper - Creature object
  • Inn - One Waypoint
  • Rooms - One Waypoint Each

               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #7 on: January 05, 2012, 06:18:43 pm »


               Looks promising.
It looks like no one has answered your question about structs inside of structs yet.
Here is how you can nest structs. This appears to be legal in NWN Aurora:

struct Stats
{
    int nFirst;
    string sOther;
    string sMeh;
};

struct Info
{
    string sStuff;
    int nThing;
    struct Stats Test;
};

struct Info GetInfo()
{
    struct Info Garble;
    Garble.sStuff = "MyStuff";
    Garble.Test.sOther = "Klergh";
    return Garble;
}

void main()

    struct Info MyStruct = GetInfo();
    MyStruct.Test.sMeh = "Blah";
    WriteTimestampedLogEntry(MyStruct.Test.sMeh);
    WriteTimestampedLogEntry(MyStruct.Test.sOther);
}


               
               

               


                     Modifié par wyldhunt1, 05 janvier 2012 - 07:07 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #8 on: January 05, 2012, 06:40:56 pm »


               I have yet to test nested structs myself. Thanks for looking into it for me!

While getting off the bus on the way to work this morning I realized that I have only begun to develop this system. I have yet to work out a number of things that are important:

How does one kick a PC out of a room that they are no longer paying for?
What happens if a PC keeps a key rather than returns it?
How does a PC request an extension of their stay?
How does a PC tell the innkeeper that other PCs will be sharing their room?

So I have more work to do!
               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #9 on: January 05, 2012, 07:01:01 pm »


               

henesua wrote...

I have yet to test nested structs myself. Thanks for looking into it for me!

While getting off the bus on the way to work this morning I realized that I have only begun to develop this system. I have yet to work out a number of things that are important:

How does one kick a PC out of a room that they are no longer paying for?
What happens if a PC keeps a key rather than returns it?
How does a PC request an extension of their stay?
How does a PC tell the innkeeper that other PCs will be sharing their room?

So I have more work to do!


I updated my example above to demonstrate a bit more with structs.

These systems can be very complex.
Here's my thoughts on it:
You can't kick a PC out of a room when time runs out unless you're running a HB script.
Add a check to the OnActivate script to ensure that their time isn't up. If it is, delete the key and don't unlock the door.
In the conversation, you may want one more branch. Check to see if the PC already has a room. If they do, offer to extend it. Depending on how nice you are, you can either reset the time based on the current time, or add their existing time to the new time.
I was curious how you were going to handle shared rooms myself. Unless there's a trigger in every room to count the players entering, this'll be hard to track.
If you do use a trigger, that could also be used to check how much time they have left and call a "RemovePC()" function when the time is up unless they've left the trigger.

Pastebin is down at the moment, so I used Google...
Here is an include that we use to help with time functions. It requires APS for persistence, so you may need to modify it for the default database.
https://docs.google....fchSPYYJxU/edit
               
               

               


                     Modifié par wyldhunt1, 05 janvier 2012 - 07:01 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #10 on: January 05, 2012, 07:16:51 pm »


               Actually I have a checkin and checkout time for each inn, an int which indicates the hour. Couldn't I have the module's heartbeat event "tell" the inn what hour it is. By "tell" I mean call a function which iterates through all "Inns" in the module, and queries each to start a "checkin" or "checkout" process?
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #11 on: January 06, 2012, 01:46:07 pm »


               A question:
are there any dynamic conversation frameworks out there for use? Perhaps I am wasting my time creating a new one. Please let me know. Thanks.

While bug testing I realized that I am working on two systems here. One is a framework for a dynamic conversation and the other is the persistent inn system.

The scripts for the dynamic conversation framework are:
  • aa_ck_token100
  • aa_conv_branch1
  • aa_conv_branch2
  • aa_conv_branch3
  • aa_conv_branch4
  • aa_conv_branch5
  • aa_conv_end
Which means that the persistent inn system for some users could be leaner, although use of this system with a dynamic conversation depends upon these 7 files. Anyway, I am just thinking outloud about how this system can be used, and about how I should package it for use.

Note:
I am not done bug testing yet. Fixed many problems thoughout the package. When finished, I'll upload the changes to pastebin and if I have time explain the differences.
               
               

               


                     Modifié par henesua, 06 janvier 2012 - 01:49 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #12 on: January 06, 2012, 03:48:36 pm »


               Debugging finished. Rental of a room and marking of the room as rented all appear to work. The correct key is also given to the PC.

Here are the latest versions of changed files (i left in my DEBUG checks. these will be removed later):
aa_rentroom_tok
aa_inc_housing
aa_conv_lastbranch1

New Files:
aa_conv_end
aa_conv_nodeprev


The first  problem I encountered was my use of GetLastSpeaker to get the NPC speaker. I changed this to OBJECT_SELF.
The next problem were a few instances where I had removed too much from the code when i had earlier tried to slim it down. Example: Room Type needs to be included in the persistant room data string because it is used to sort through room data.
A few other typos were found which created big problems and took a long time to locate.
               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #13 on: January 06, 2012, 05:57:16 pm »


               I've never used it, but here is the conversation editor that I've heard the most about:
http://nwvault.ign.c....Detail&id=2985

EDIT:
I found another one as well:
http://nwvault.ign.c....Detail&id=3495
               
               

               


                     Modifié par wyldhunt1, 06 janvier 2012 - 06:14 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Persistent Inn System - W.I.P.
« Reply #14 on: January 06, 2012, 06:27:49 pm »


               Interesting. Those look heavier than I expected. I'll take a look at those to figure out what use they may be for me.

My thinking is that this persistent inn system should be adaptable to any of these kinds of conversation systems. I intend to strip out my dynamic conversation stuff, and only provide it as an add on or separate package. If this zz dialog works for me, we'll see how I can make this system work with it.