Game Development Community

dev|Pro Game Development Curriculum

Torque DB - Journal System Example

by Matthew Langley · 04/14/2005 (11:29 pm) · 65 comments

Torque DB: Journal System Example

Here is the zip file

This is a completely TorqueScript Database, included is a bunch of pics and description of it, the best advice I could give is to go into the database scripts... I have included some good commenting and good descriptions before most functions :)

Note: this also includes a full Journal System example... for this example I modified guiMessageVectorCtrl.cc and guiMessageVectorCtrl.h

here I will detail my modifications and how to quickly add those to yours... (I didn't add much and I didn't take away anything)...

note: the book graphic included was done using an academic version of Photoshop, it is for non-commercial use only

Steps to implement this resource:

First - either back up your entire Torque folder or at least back up your guiMessageVectorCtrl.cc and guiMessageVectorCtrl.h (Torque\SDK\engine\gui by default)

1. Modify the source code

first go to "guiMessageVectorCtrl.h"
search for this line of code

//   void onMouseMove(const GuiEvent &event);

and uncomment it... like this

void onMouseMove(const GuiEvent &event);

thats all for the .h file ;) We're just adding that function back in that was commented out

second go to "guiMessageVectorCtrl.cc"


now scroll down all the way to the bottom of the file, you should see this set of code

mMouseDown      = false;
   mMouseSpecialLine = -1;
   mMouseSpecialRef  = -1;

add this before it

//---------------------------------------------
   //Matthew "King BoB" Langley - Resource: Journal System...
   Con::executef(this, 2, "clickLineCallback", Con::getIntArg( mMouseSpecialLine ));
   //---------------------------------------------

this is simply providing a callback that passes the line you click on

now add this function to the end of the file

//---------------------------------------------
//Matthew "King BoB" Langley - Resource: Journal System...


void GuiMessageVectorCtrl::onMouseMove(const GuiEvent& event)
{
	//Parent::onMouseMove(event);

	S32 currLine;
   	S32 currRef;
   	findSpecialFromCoord(globalToLocalCoord(event.mousePoint), &currLine, &currRef);

   	Con::executef(this, 2, "moveLineCallback", Con::getIntArg( currLine ));

}

//---------------------------------------------


and that (as you've probably guessed) is simply passing the line you move over... note: this is not optimized, this probably could be cut down a lot, I'm simply using an existing function, I could make my own function (based off of the "findSpecialFromCoord" that only returns the line; however, I presently don't have the time to do so =/ This seems to not affect things much though, have run into little FPS loss (if any)... I look forward to hearing results...


2. Script end of it

ok, well the script end of it is very easy, simply take the included zip file... unzip it and it should contain three folders a .gui file and a .png image, grab the two folders database and journal, drop these in Torque\SDK\example\starter.fps\client (or if you decide to put them elsewhere)... and be sure to include these exec statements (easy to put them in Torque\SDK\example\starter.fps\client\init.cs)

exec("./scripts/journal/journal.cs");
exec("./scripts/database/TorqueDB.cs");

now grab the .gui file and .png
journal.gui
journalbook.png

then put them in Torque\SDK\example\starter.fps\client\ui\

and be sure to add an exec for

exec("./ui/journal.gui");

best place is to put it in init.cs as well with the other .gui exec statements


make sure you change

$torqueDBPath = "starter.fps/data/journalData/";

if needed (its at the top of file.cs)

that will point to where you want to put your journalData folder... this holds the config and output text file... note I have two Dump commands in file.cs... one for plain text and the regular one will encrypt... later I will include some instructions on generating new encryptions... (its a very basic encryption)

ok, now if you recompile for the C++ changes, then simply fire up Torque... bring up the console and type
journalDebug();

you should see the book come up with your journal entries, try selecting and clicking... note the first menu takes you a level "above" "entry"... after that you cannot get back to entry (unless you add your own way to)... I'm hoping to add more functionality to an overal view, though right now wanted to at least release this.




now here is some more information about the rest of this, hopefully I can create some step by step instruction, but again just wanted to get this out there at least :)



here is the layout
www.razedskyz.com/games/torque/plan/journalDiagram1(small).JPGwww.razedskyz.com/games/torque/plan/journalDiagram2(small).JPG

here is the journal system in action
www.razedskyz.com/games/torque/plan/journalpic1.JPGwww.razedskyz.com/games/torque/plan/journalpic2.JPG
first here is the config file... a basic text file.

www.razedskyz.com/games/torque/plan/journalconfig.JPG
as you can see it starts off with

this begins what you can think of a new journal class or type... you don't even really have to think of it as journal specific... as you can see down a few lines I have ... which works perfectly well.

after the "<>" tag (this starts the type)...
you see text starting with a "-"... this denotes a property... so we now assign name, text, and item to the "entry" type.

and name, value, power to the "item" type.

the next file you can see how we use it.

www.razedskyz.com/games/torque/plan/journaltext.JPG
here we see an .. (note: for simplicity I have it started the same way with an html style <> tag)
then the sub property -name is being assigned "BoB"... then values are assigned to text and item... in this case you could think of it as if the player talked to "BoB" and was assigned the quest with the reward (which you could easily change item to reward in the config file) by accomplishing "Go here and do that."
Next entry I clip off some entries for testing... and at the end i have an Item... beginning with the same tag and ending with the tag...(this all keeps it extremeley simple to write and edit, though when I'm finished you should never have to manually edit journal.txt... even though as you can see its simple enough

ok, so I've shown you a couple of text file, how exciting, lol... ok let me show you some debug info output from loading these file through my parsers...

www.razedskyz.com/games/torque/plan/console.JPG
all of these variables are scriptobjects used as arrays, minus $journalMainTags... which was left as a standard single dimension array... I used scripts objects due to the need of having multi-dimension arrays (even got up to a 3 dimensional array =/)... plus as I saw in the resource I beleive these can then be passed (though still have to test)... which adds a large ammount of usability if one wanted to change them to local variables instead.

ok... first off
$journalMainTags...
this (as you can probably see) holds each different type loaded from the config file... right now simply two... entry and item...
more importantly these arrays run together, so you grab the array value of entry or item and then get full access to all the values under the main array.
(as you can see I like seperating things for organization and usability)...

$journalSubTags contains the properties of those main taqgs listed in $journalMainTags...

as you can see [0][0] is name
and [1][0] is name...
reinforcing my method of keeping them aligned with eachother.

$mainValueArray holds the instance (or what you could think of as an instance for you OO programmers out there) of each type loaded from journal.txt
[0] - entry
[0] - entry
[0] - entry
[1] - item
following the journal.txt format of three entries and an item... this is good for quick navigation and later when I implement searching abilities, optimizing the access of information without looping through the entire main array.

now we get to the big boy, the 3-dimensional array... $subValueArray... the first array value denotes the same as the other arrays... the type... 0 is for the first type loaded, entry... 1 is for the second type loaded, item. Again as you have seen this is all dynamically loaded through the config file. It then loads an instance of each of those... first an instance of the "entry"..
[0][0] denoting the first instance (the second 0)... of the first class/type (the first 0)... then it defines [0][0][0] = BoB
this takes the first intance of the first class and adds its first property (again using OO programming principals) and sets it to BoB... this would be the name...
note it loads these in order of the config file... not the journal file...
if you put
name
item
text

it will load
[0] - name
[1] - item
[2] - text

even if the journal is written
item
name
text

NOTE this was added , lol this is a bit dated writeup (at least part of this is a bit dated, though a good description) - ignore the "which I plan on adding"
... now with the right array writing functions (which I plan on adding, as well as an easy template to write your own for customization) the order should always be correct, but figured I'd specify that it loads the config file, then loads the journal and comparesthe first config entry until it gets the journal entry matching, it doesnt simply load it, hoping it all is in proper order. This added for some interesting loops and code, but was well worth it for the control it grants you.

after the first entry it then addes
[0][1][0] - BoB2

first [0] means first class/type (still entry) the [1] meaning the second 'instance' of this class/type... and [0] being the first property... which can be referenced by the class/type number
[0] and the property number [0]...
to
$journalSubTags.contents[0].contents[0] - name
to find the property name.

then it adds a third instance (as many instances as you want can be loaded)... then it goes to the new class/type... [1]... which can be referenced using the same number with
$journalMainTags[1] - item

so it loads item data in
[1][0][0] - rod of death
[1][0][1] - 500
[1][0][2] - death


according to the properties in
$journalSubTags.contents[1].contents[0] - name
$journalSubTags.contents[1].contents[1] - value
$journalSubTags.contents[1].contents[2] - power


[image][/image]



------------------- ARRAYS --------------------------
$journalMainTags
------------------------------------------------------------------
$journalMainTags[0] - entry
$journalMainTags[1] - item
------------------------------------------------------------------
$journalSubTags
------------------------------------------------------------------
$journalSubTags.contents[0].contents[0] - name
$journalSubTags.contents[0].contents[1] - text
$journalSubTags.contents[0].contents[2] - item
$journalSubTags.contents[0].contents[3] - image
$journalSubTags.contents[1].contents[0] - name
$journalSubTags.contents[1].contents[1] - value
$journalSubTags.contents[1].contents[2] - power
------------------------------------------------------------------
$mainValueArray
------------------------------------------------------------------
$mainValueArray.contents[0] - 3
$mainValueArray.contents[1] - 1
------------------------------------------------------------------
$subValueArray
------------------------------------------------------------------
$subValueArray.contents[0].contents[0].contents[0] - Quest given by: BoB
$subValueArray.contents[0].contents[0].contents[1] - Quest text: Go here and do that
$subValueArray.contents[0].contents[0].contents[2] - Quest item: sword of fire
$subValueArray.contents[0].contents[0].contents[3] - Dark.Game/client/ui/GarageGames.jpg
$subValueArray.contents[0].contents[1].contents[0] - BoB2
$subValueArray.contents[0].contents[1].contents[1] - slay the beast and return its head
$subValueArray.contents[0].contents[1].contents[2] - rod of death
$subValueArray.contents[0].contents[1].contents[3] - Dark.Game/client/ui/background.jpg
$subValueArray.contents[0].contents[2].contents[0] - BoB3
$subValueArray.contents[0].contents[2].contents[1] - Go here and do that3
$subValueArray.contents[0].contents[2].contents[2] - shield of valor
$subValueArray.contents[1].contents[0].contents[0] - rod of death
$subValueArray.contents[1].contents[0].contents[1] - 500
$subValueArray.contents[1].contents[0].contents[2] - death
------------------------------------------------------------------

---------------------- VARIABLES -----------------------
$journalArrayCount contents: 22
$mainTagCount contents: 2
$subTagCount[0] contents: 4
$subTagCount[1] contents: 3
$sub2TagCount contents: 0
"



Functions for the journal system

--------------------- File loading and unloading Functions---------------------------

.dumpFile()

This function takes all of the existing information in the arrays and dumps it to a config (setup file)

as well as a journal file that holds all of the entries, data, etc.


.loadFile()

This function is the heap of loops that parses the config file to gain access to the values it will parse

the journal file with. It loads all the information into the arrays as well as the counters that keep track of

everything.

--------------------- Data Manipulation Functions (what you will most likely use the most

of)---------------------------

------Delete functions

.deleteClass()

This function will delete a class if you pass it the class you want deleted... for example
say I wanted to delete the "entry" class...
TorqueDB.deleteProperty("entry");
This will delete that class, as well as all of the instances of that class, updating the arrays
and counters properly


.deleteProperty()

This function will delete a property if you pass it the class and the property you want deleted... for

example
say I wanted to delete the "name" property of the "entry" class...
TorqueDB.deleteProperty("entry", "name");
This will delete that property for the class, and in all of the instances of that class, updating the arrays
and counters properly


.deleteInstance()

This function will delete an instance if you pass it the class, identifying property and value(instance)

of that
property... for example... say I want to delete the "entry"(class) with the "name" (property) of "BoB2"

(instance)
TorqueDB.deleteInstance("entry", "name", "BoB2");
this successfully deleted that instance and correctly updates the arrays and counters

------Write functions

.writeClass()

This will add a new class to the data that will eventually be dumped to the config file
Important to remember you must write the class with this function then populate its
properties with the following functions... You must include one property and value
so it will add one instance on creation, further instances can be added via the
TorqueDB.addInstance function as used inside this function... for example
TorqueDB.writeClass("spell", "name", "ball of fire");
this will add the spell class, which in turn adds "" and "" to the config


.writeProperty()

This will add a new property to the specified class that will eventually be dumped to
the config file... for example
TorqueDB.writeProperty("spell", "damage");
this will add the spell class, which in turn adds "" and "" to the config

------Write functions - to the data (journal in my example)

.writePropertyValue()

This function will write a value to a property. For example... say I wanted to change the name of my

"rod of death"
under the "item" class. I would do this
TorqueDB.writePropertyvalue("item", "name", "rod of death", "name", "new rod of death");
As you can see I pass all the information needed to identify the rod of death and to change its property


.addInstance()

This function will add an instance... Key things to remember, the class must exist and the
property must exist already... using the above functions this is accomplished...
you must specify at least one starting value to reference the instance, can be any that you
created or that are already there
for example... say you wanted to add an instance of the "item" class, thats called
"Sword of Fire"
TorqueDB.addInstance("item", "name", "Sword of Fire");
now the instance of item with the name property of "Sword of Fire" has been added
from here you can use TorqueDB.writePropertyValue to add values to the existing properties
of the "item" class or the TorqueDB.writeProperty to add more properties to the "item"
class
NOTE: the following is a bit more advanced, knowledge of Script Object arrays is needed
you do not NEED to use them, the above specifies normal use, this is additional use
Now I also added support for passing it ScriptObject arrays... though you could just loop
this function and create all sorts of instances I figured I'd make this resource as robust
as possible... There are two types of ScriptObject arrays that it will take... "single" and
"multi"... to pass a ScriptObject array you would call do a call like
TorqueDB.addInstance("entry", "single", $testArray);
note the first value is the same, the class, the second specifies "single" or "multi" and
the last is the ScriptObject array, the code will automatically detect if its a ScriptObject
array and process it accordingly... for example

Example of "single"

$testArray = new ScriptObject();
$testArray.contents[0] = new ScriptObject();
$testArray.contents[1] = new ScriptObject();

$testArray.contents[0].contents[0] = "name";
$testArray.contents[0].contents[1] = "person1";
$testArray.contents[0].contents[2] = "text";
$testArray.contents[0].contents[3] = "BLAH BLAH BLAH";
$testArray.contents[0].contents[4] = "item";
$testArray.contents[0].contents[5] = "Sword of Fire";
$testArray.contents[1].contents[0] = "name";
$testArray.contents[1].contents[1] = "person2";
$testArray.contents[1].contents[2] = "text";
$testArray.contents[1].contents[3] = "blah blah blah";
$testArray.contents[1].contents[4] = "item";
$testArray.contents[1].contents[5] = "Sword of Death";

Example of "multi"

$testArray = new ScriptObject();
$testArray.contents[0] = new ScriptObject();
$testArray.contents[1] = new ScriptObject();

$testArray.contents[0].contents[0] = "name";
$testArray.contents[0].contents[1] = "person1";
$testArray.contents[0].contents[2] = "person2";
$testArray.contents[0].contents[3] = "person3";
$testArray.contents[0].contents[4] = "person4";
$testArray.contents[1].contents[0] = "item";
$testArray.contents[1].contents[1] = "sword1";
$testArray.contents[1].contents[2] = "sword2";
$testArray.contents[1].contents[3] = "sword3";
$testArray.contents[1].contents[4] = "sword4";


Single is set up like this
Array[0][0] - property
Array[0][1] - value
Array[0][2] - property
Array[0][3] - value
Array[1][0] - property
Array[1][1] - value
Array[1][2] - property
Array[1][3] - value
etc etc... this will create two new instances, the first array number denotes the seperation
of instances....

Multi is set up like this
Array[0][0] - property
Array[0][1] - value
Array[0][2] - value
Array[0][3] - value
Array[1][0] - property
Array[1][1] - value
Array[1][2] - value
Array[1][3] - value
Now this is quite a bit different, six different instances will be created, basically multi
is a good way to spam a bunch of simple instances, while single adds instances with multiple
properties


------Search functions

.searchByClass()

search by passing the class and returning the entire class contents
for example... I have "entry" and "item" classes... If I want to
return all entry types I would use
$entries = TorqueDB.searchByClass("entry");
then I could use
echo($entries.contents[0].contents[0]);
and the first property of the first "entry" should display in console
this will be usefull if you use this system as inventory, dialog, etc,
like a database, so you can return only the type you want


.searchByInstanceWithClass()

search by passing the class, property, and instance and returning the instance
for example... I want to get the item by the property "name" of "rod of death" and I know
its of class "item"... I would use
$testInstance = TorqueDB.searchByInstanceWithClass("item", "name", "rod of death");
then I could use
echo($testInstance.contents[0]);
and the first property of "rod of death" would be displayed in console, which would be
"rod of death"
the name we searched by...
echo($testInstance.contents[1]);
would reveal "500"


.searchByInstance()

search by passing the property, and instance and returning the instance, without passing class
note: its recommended to use the previous function, specifying the class will increase efficiency
especially if you have a lot of classes
for example... I want to get the item by the property "name" of "rod of death" without knowing
the class... note: the property instance must be unique! or it will simply return the first
match it finds
$testInstance = TorqueDB.searchByInstance("name", "rod of death");
then I could use
echo($testInstance.contents[0]);
and the first property of "rod of death" would be displayed in console, which would be
"rod of death"
the name we searched by...
echo($testInstance.contents[1]);
would reveal "500"


.searchByPropertyWithClass()

search by passing the class, property, instance, and return property and returning the
property value you specified in %returnProperty
for example... I want to get the item by the property "name" of "rod of death" and I know
its of class "item" and I want to get its "value" I would use
$testProperty = TorqueDB.searchByPropertyWithClass("item", "name", "rod of death", "value");
then I could use
echo($testProperty);
and it would reveal the "value" of "500"


.searchByProperty()

search by passing the property, instance, and return property and returning the
property value you specified in %returnProperty
for example... I want to get the item by the property "name" of "rod of death" and I know
its of class "item" and I want to get its "value" I would use
$testProperty = TorqueDB.searchByProperty("name", "rod of death", "value");
then I could use
echo($testProperty);
and it would reveal the "value" of "500"


-----------------------------------------------------------
Using these search functions... heres an example
-----------------------------------------------------------

Say you have the quest for the "rod of death"... the user wants to know its value...so you do
$testProperty = TorqueDB.searchByPropertyWithClass("item", "name", "rod of death", "value");
The value returns "500"... they like this... so they then want to see what the quest entails..
to get the text associated with the journal entry for this, you would do
$testProperty = TorqueDB.searchByPropertyWithClass("entry", "item", "rod of death", "text");
and it returns "slay the beast and return its head"
then the user asks, who do I return it to... you would get this info by
$testProperty = TorqueDB.searchByPropertyWithClass("entry", "item", "rod of death", "name");
which would return "BoB2"
this is just an example of the many ways to manipulate these functions... note I did include
search functions 'without' the class specification, though you can tell this will decrease
search efficiency

Another great use for this will be setting up a user searchable journal, item list
really its more like a database that can be used for anything... Quite nifty...
In all truth with the functions given it isnt too hard, though it won't be very smart...
(unless you add a bit of a smartness to it, like estimating what the user means, etc)
I may include GUIs and such for this by the time I release this resource, lol if you see it
included then I decided to go ahead and do that, if not then you shouldn't have much trouble
doing it yourself
I may even add functionality to search through the text of each entry, though adding searching
by item, name, or any 'property' or 'class' should be a snap with these functions



------Return functions

.returnClass()

This is for internal uses, it will return the class number used in the data arrays
by passing it the class name ... for example
$classNum = TorqueDB.returnClass("entry");
will return "0"... which then could be identified by using it in the arrays, like
echo($journalMainTags[TorqueDB.returnClass("entry")]);
should display "entry"


.returnProperty()

This is for internal uses, it will return the property number used in the data arrays
by passing a class, and property... for example
$propertyNum = TorqueDB.returnProperty("item","name");
this will return the array number


.returnInstance()

This is for internal uses, it will return the instance number used in the data arrays
by passing a class, property, and instance... for example
$instanceNum = TorqueDB.returnInstance("item","name","rod of death");
this will return the array number


.returnClassName()

This function is used if you have the internal array class Number and want to get the
class name... After some thought I decided to use the above return commands passing the
text name... like "entry" rather than having you convert it to the 0 it is in the internal
array... so I added these two function to help if you already have the number and need the
name, whether for the above functions or for another use... for example
$className = TorqueDB.returnClassName(0);
echo($className);
this should display "entry" in the console


.returnPropertyName()

Heres the second number to name function... pass it the class "text" and the property
number an it will return the property name, look above for reasons you might use this
... for example
$propertyName = TorqueDB.returnPropertyName("entry", 0);
echo($propertyName);
this should print "name" in the console







--------------------- Debug Functions---------------------------

.debug()
and
.debugInfo()

I included a couple debug functions, one that loads the file and displays the journal ... the other is

called from the debug command but can be run seperately also, debugInfo is very usefull it will display all the

contents of the arrays and counters, correctly labeled.


--------------------- String Helper Functions---------------------------


.getTagName()

Here is an internal command that is very usefull... it will get the name out of a tag... for example...

you pass it "" and it gets "entry" out of it... just a helper string function

.returnStringAfter()

Here is another internal helper string function... pass it .returnStringAfter("name=bob", "=") and it

will return "bob"...

.returnStringBefore()

Same as .returnStringAfter except it returns the string before the character

--------------------- Display Functions---------------------------

.displaySub(%lastMenu, %obj)

This function will display a sub object of the journal overlayed over the journal (as well as an image in

the right pane if you have one under that sub... In a journal example this displays the journal entry, the text,

the name, items associated with it, etc... Basically this displays an "instance"

.displayType(%lastMenu)

This will display all of the types or "classes"... so if you have an "entry" class and an "item" class

then it will display entry and item... so then you can browse down further

.displayMain(%lastMenu, %obj)

This will display the contents of a type or "class"... so if you want to display all the journal entries

this would be the function that would... note: the first property of an entry is what is display when listing

all the entries, so you can choose to make the first entry a name, a title, or whatever you choose.

About the author

Was a GG Associate and then joined GG in 2005. Lead tool dev for T2D and T3D. In 2011 joined mobile company ngmoco/DeNA and spent about 4 years working game and server tech. 2014 joined startup Merigo Games developing server technology.

#41
08/23/2005 (8:55 am)
Ok looks like theres a very small bug in the version thats up there...

in journal.cs

in the function

function gmvText::moveLineCallback(%this, %obj)

Journal.displayText();
should be
Journal.displayText($obj);


Now I've been making some performance tweaks to the display system of the journal, in trying to get the line highlighting and back/next buttons to work it came out pretty inefficient, not crippling, should be fine if you don't plan to run it while the player is doing something, though I've made some mods before that increased the performance a lot so trying to "re-discover" them lol... In other words I'll be updating this with this fix and more, though time is pretty pressed right now... when I do it should be a drop in t ype fix, no changes to how you use it just how it displays things.
#42
08/23/2005 (9:01 am)
Actually now that I look at it I think the version up there has the optimizations... the script behind the journal end is pretty sloppy though, hopefully I can clean it up some... the database end is pretty clean and well commented though...

Originally the displaying of the journal cycled through most of the entries just to display a single page of them... so if you had 1,000 (like that journalDebug(); example has) it would get some frame hits when moving through it... seems the version up there now has that fixed...
#43
08/24/2005 (8:41 pm)
To Matthew :
I changed the 10000 to 10 in "for loop"(function Journal::prepareData(%this))
and check DBPath.
1.I had see the book.('Entry','Item','Entry' root and my pic)
2.mousemove() OK! (the mouse position have blue line text)
3.mouseclick() fail! no action.
4.console.log
------------------- ARRAYS --------------------------
$journalMainTags
------------------------------------------------------------------
$journalMainTags[0] - entry
$journalMainTags[1] - item
$journalMainTags[2] - entry
------------------------------------------------------------------
$journalSubTags
------------------------------------------------------------------
$journalSubTags.contents[0].contents[0] - name
$journalSubTags.contents[0].contents[1] - text
$journalSubTags.contents[0].contents[2] - item
$journalSubTags.contents[0].contents[3] - image
$journalSubTags.contents[0].contents[4] - name
$journalSubTags.contents[0].contents[5] - NpcName
$journalSubTags.contents[0].contents[6] - Text
$journalSubTags.contents[0].contents[7] - Summary
$journalSubTags.contents[0].contents[8] - Reward
$journalSubTags.contents[0].contents[9] - Status
$journalSubTags.contents[1].contents[0] - name
$journalSubTags.contents[1].contents[1] - value
$journalSubTags.contents[1].contents[2] - power
------------------------------------------------------------------
$mainValueArray
------------------------------------------------------------------
$mainValueArray.contents[0] - 4
$mainValueArray.contents[1] - 2
------------------------------------------------------------------
$subValueArray
------------------------------------------------------------------
$subValueArray.contents[0].contents[0].contents[0] - quest given by: bob
$subValueArray.contents[0].contents[0].contents[1] - quest text: go here and do that
$subValueArray.contents[0].contents[0].contents[2] - quest item: sword of fire
$subValueArray.contents[0].contents[0].contents[3] - spacetime/client/ui/back1.png
$subValueArray.contents[0].contents[1].contents[0] - bob2
$subValueArray.contents[0].contents[1].contents[1] - slay the beast and return its head
$subValueArray.contents[0].contents[1].contents[2] - rod of death
$subValueArray.contents[0].contents[1].contents[3] - spacetime/client/ui/back2.png
$subValueArray.contents[0].contents[2].contents[0] - bob3
$subValueArray.contents[0].contents[2].contents[1] - go here and do that3
$subValueArray.contents[0].contents[2].contents[2] - shield of valor
$subValueArray.contents[0].contents[3].contents[0] - Quest Name
$subValueArray.contents[0].contents[3].contents[1] - Quest Text
$subValueArray.contents[0].contents[3].contents[5] - NpcName
$subValueArray.contents[0].contents[3].contents[7] - Summary
$subValueArray.contents[0].contents[3].contents[8] - Reward
$subValueArray.contents[0].contents[3].contents[9] - Status
$subValueArray.contents[1].contents[0].contents[0] - rod of death
$subValueArray.contents[1].contents[0].contents[1] - 500
$subValueArray.contents[1].contents[0].contents[2] - death
$subValueArray.contents[1].contents[1].contents[0] - staff of power
$subValueArray.contents[1].contents[1].contents[1] - 500
------------------------------------------------------------------

---------------------- VARIABLES -----------------------
$journalArrayCount contents: 39
$mainTagCount contents: 3
$subTagCount[0] contents: 10
$subTagCount[1] contents: 3
$sub2TagCount contents: 0
Loading Data
loading - 0
loading - 1
loading - 2
loading - 3
loading - 4
mouse0 input device created.
attempting moveLineCallback
line: 2 has been moved from 1247
attempting moveLineCallback
line: 1 has been moved from 1247
attempting moveLineCallback
line: 0 has been moved from 1247
attempting moveLineCallback
line: 1 has been moved from 1247
attempting moveLineCallback
line: 2 has been moved from 1247
attempting moveLineCallback
line: 1 has been moved from 1247
attempting moveLineCallback
line: 0 has been moved from 1247
attempting moveLineCallback
line: 1 has been moved from 1247
attempting moveLineCallback
line: 2 has been moved from 1247
Object Before:
Object After:
Loading sub obj name obj =
%obj after is: 0
Sub menu: journal main type object: 0
Object Before:
Object After:
Loading sub obj name obj =
%obj after is: 0
Sub menu: journal main type object: 0
Exporting client prefs
Exporting client config
Exporting client prefs
Exporting client config
Exporting client prefs
Exporting client config
Exporting client prefs
Exporting server prefs
Shutting down the OpenGL display device...
Making the GL rendering context not current...
Deleting the GL rendering context...
Releasing the device context...

Thanks for your help!
#44
08/25/2005 (8:31 am)
@ccljyc: good idea to change from 10,000 to 10. The 10,000 was just for testing purposes :)

Hmm so everything besides mouse clicking works presently ?

When you first load that demo click on entry... you should then see the sub entries and be able to click to see the pic (if there is one) and the info, then click again to go back up...

I actually start this a single level too high, I should really have it load the "entry" first, though wanted to show that you could use this for multiple things, that "entry" was just one table in the DB :)

I have a T2D tutorial that details how to modify things in the DB step by step, I need to work up a TGE one and then create some shortcut function for people just u sing this as a journal.
#45
08/26/2005 (12:21 am)
OnMouseUp()
add it
//Matthew "King BoB" Langley - Resource: Journal System...
Con::executef(this, 2, "clickLineCallback", Con::getIntArg( mMouseSpecialLine ));
//---------------------------------------------
I add to wrong way for this before.

And click book link then got token and picture.
When I "mousemove()" out of the text range that got nothing(Only see journalbook.png) and can't recover.
#46
08/27/2005 (7:53 am)
Matthew, I tried again and still only get "entry, item, entry" in the book. When hovering over those three entries, I get this in the console:
attempting moveLineCallback
line: 1 has been moved from 1271
attempting moveLineCallback
line: 2 has been moved from 1271

Also in your bug fix above [ Journal.displayText($obj); ], I noticed in the debugger that $obj has no value and actually couldn
#47
09/08/2005 (11:40 pm)
continue...
I changed all "Journal.displayText();" to "Journal.displayText($obj);"
If I call journal.readJournal(); in debug mode,
recover everything on book
#48
10/04/2005 (12:08 am)
Sorry for the delay in testing this... but this is what the movelinecallback should look like to function right... also if you don't see any text after running journalDebug() then you don't have the same font I had Torque render out, you can change that in the .gui file I have you place in the ui folder

function gmvText::moveLineCallback(%this, %obj)
{
	if((%obj != -1) && (%obj != $currentLine))
	{
		$currentLine = %obj;
		if($debugMsg::journalDebug)   echo("attempting moveLineCallback");
		if($debugMsg::journalDebug)   echo("line:" SPC %obj SPC "has been moved from" SPC %this);
		Journal.displayText($journalMainType);
		
	}
}
#49
01/19/2006 (12:17 am)
Awesome resource!

EDIT: When I run journalDebug, it feeds out a list of about 9998 phantom entires named unifromly as 'person1', 'person2', 'person3' etc.

Any help is hugely appreciated.
#50
01/19/2006 (1:10 pm)
That is just the testing function... this is the journalDebug() function

function journalDebug()
{
        testBook();
	Journal.debug();
	Journal.prepareData();
	TorqueDB.addInstance("entry", "single", $testArray);
	
}
#51
01/19/2006 (1:12 pm)
In turn that calls the prepareData() function, thi sfunction basically populates a test array with all those person values for texting

function Journal::prepareData(%this)
{
	if($debugMsg::journalDebug)   echo("Loading Data");
	$testArray = new ScriptObject();
	for(%i=0;%i<10000;%i++)
	{
		echo("loading - " @ %i);
		$testArray.contents[%i] = new ScriptObject();
		$testArray.contents[%i].contents[0] = "name";
		$testArray.contents[%i].contents[1] = "person" @ %i;
	}
}

and then calls an addInstance on the $testArray which then adds that entire array to the database... so to do your own debug command just use the first line ...

Journal.debug();
#52
01/19/2006 (3:59 pm)
Thanks ;)
#53
03/24/2006 (12:08 pm)
The link doesn't seem to be working.
#54
04/23/2006 (4:38 pm)
its 2:37 am here so i'm pretty tired and didnt read through whole resource.

is this designed for multiplayer games?
#55
06/24/2006 (7:37 am)
Matthew,
this is a really cool resource!!!
thanks!
#56
07/31/2006 (4:05 pm)
( nevermind )
#57
11/06/2006 (12:23 pm)
Hi Matthew,

This looks perfect for my little watershed educational game that i'm making in TGB. I got a hold of the Sickhead games adventure kit which has really given me a head start. However, i've been struggling with setting up an array to hold the NPC and PC conversation strings (dialogue), the code for the NPC conversation triggers is all implemented and working but how to actually store the dialogue in an array was causing significant problems for me as i've only been coding for 4 weeks (i'm a producer at heart). But, to finally get to the point, your DB looks ideal for me, is there any issues i should be aware of for implementing this into TGB? And, if i have any major problems modifying and implementing your code would you be willing to point me in the right direction every once in a while?

All the Best,

Jonathan
#58
07/30/2007 (2:25 pm)
I am surprised anyone has actually got this working.

First impressions tells me its a great resource, but not been able to get it to run, is pushing me to yet again spend the money on one of my developers to rewrite another non working torque freebee.

Has anyone managed to get this going on tge 1.5 ?

I am experiencing the same problems that "Nick Zafiris" and "ccljyc" are/were.
#59
07/30/2007 (2:40 pm)
Well considering this resource was designed for TGE 1.3 and also on TGB back when it was called "Torque 2D" (originally created this over 2 years ago) it's expected to have problems now :)
#60
07/31/2007 (12:58 am)
Fair enough, I have jumped on the band wagon a little late here. After long and heated discussions with my development team, we have decided to Implement a slightly more generic DB which will handle all rpg type elements which will handle additional items such as, quests, inventory, conversations, npc actions, etc using xml.

If it does not cost too much I will gladly submit it.

I apologise for seeming rude Matthew, but only once going through the vast amount of code you submitted(at an attempt for a fix) for this item for free, did I find much respect for your work ;)