As you already might know I want to add a function to UOX3 that sends a list of items (and maybe one that sends a list of chars) to the JS engine, but I don't seem to be able to find a way.
That's what I found out so far:
There doesn't seem to be a way to send an array, you can only send strings, numeric values or objects. So while I could send the serial of the item for a single list entry instead of the item object I need to send the list itself as an object or as part of an object.
What I tried so far:
Sending a CDataList as an Object, that failed badly. It eigther didn't work at all or it crashed the server. It's also not very easy to check (inside the iterate functions) whether the object send by the script really is a CDataList or not.
Creating a very basic item and directly using it's CDataList, basically using the item as a wrapper for the CDataList. That worked and I could use the alread present functions to iterate over the list, but according to Giwo it can cause data corruption so it's not an option eighter.
I also thought about creating a new wrapper object class, that only contains a bunch of data lists. But this is more or less the same approach I used with the basic item above, and as I currently don't understand how that could cause data corruption I'm not shure that this idea would work.
Any ideas?
I'm Stuck: Sending a list of objects to a Script
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
There is no way I know of to pass an array directly, thus short of creating and sending an object linked to a class that wrapped an array (such as CDataList) which I am hesitant to do, the next best way is the current manner in which we run through lists.
If you notice, AreaCharFunction() populates a list, then on every match calls the function name we specify. Something similar using X,Y,Z would likely be your best bet to accomplish what you were going for.
If you notice, AreaCharFunction() populates a list, then on every match calls the function name we specify. Something similar using X,Y,Z would likely be your best bet to accomplish what you were going for.
Scott
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
And if I only store the item/char serials inside the array and send them to the JS function? I don't think this could cause any corrupt data.giwo wrote:There is no way I know of to pass an array directly, thus short of creating and sending an object linked to a class that wrapped an array (such as CDataList) which I am hesitant to do, the next best way is the current manner in which we run through lists.
I'll have a look at it, but for the scripts I have in mind I need to somehow get the list of items/chars inside the main function (for ex. to do comparisions on them). Calling a function on each item won't help me there.giwo wrote:If you notice, AreaCharFunction() populates a list, then on every match calls the function name we specify. Something similar using X,Y,Z would likely be your best bet to accomplish what you were going for.
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
Well, the CDataList is just a generic wrapper, it can contain anything, much like a vector.
Where corruption comes in is when you use an already existant DataList (like on a character or in a region) and then add items which should not be on that datalist. In the case of manually putting items on another items datalist, you will wind up having the same items saved twice, and thus created twice, with the same serial numbers, causing worldfile corruption.
So if you created your own instance of CDataList, you should be able to pass that to the JS engine in the same way we pass a CChar, it's just another class. The problem is the overhead you will get from creating a new JS class, with new methods.
Where corruption comes in is when you use an already existant DataList (like on a character or in a region) and then add items which should not be on that datalist. In the case of manually putting items on another items datalist, you will wind up having the same items saved twice, and thus created twice, with the same serial numbers, causing worldfile corruption.
So if you created your own instance of CDataList, you should be able to pass that to the JS engine in the same way we pass a CChar, it's just another class. The problem is the overhead you will get from creating a new JS class, with new methods.
Scott
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Hmmm, but this should only happen when the wrapper item containing the list gets saved. So setting ShouldSave() to false on the wrapper item could prevent it, as the list entrys are only pointers to the actual items and not new instances of them (I think).giwo wrote:Where corruption comes in is when you use an already existant DataList (like on a character or in a region) and then add items which should not be on that datalist. In the case of manually putting items on another items datalist, you will wind up having the same items saved twice, and thus created twice, with the same serial numbers, causing worldfile corruption.
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
Yes, the list entrys are just pointers to objects, not actual objects themselves. And setting ShouldSave() to false would stop it from saving and thus keep it from creatind duplicate worldfile entries.
Regardless, creating an item for any purpose other than to create an actual item is bad behavior. If there really is need to pass a list to JS (which I haven't really come across an absolute need yet) the proper way would be to create a new instance of CDataList and make a JS class for it.
As I noted, though, I'm not sure the effort and the resource usage is really worth it, as anything that needs to be done should be able to be accomplished using our current form of list handling.
Regardless, creating an item for any purpose other than to create an actual item is bad behavior. If there really is need to pass a list to JS (which I haven't really come across an absolute need yet) the proper way would be to create a new instance of CDataList and make a JS class for it.
As I noted, though, I'm not sure the effort and the resource usage is really worth it, as anything that needs to be done should be able to be accomplished using our current form of list handling.
Scott
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Agreed.giwo wrote: Regardless, creating an item for any purpose other than to create an actual item is bad behavior.
I think that's the way I'm going to do it.giwo wrote:If there really is need to pass a list to JS (which I haven't really come across an absolute need yet) the proper way would be to create a new instance of CDataList and make a JS class for it.
Well, ultimately I would like the ability to create custom AIs through JS. But for an AI to be worth anything it needs a way get aware of items and chars in it's environment.giwo wrote:As I noted, though, I'm not sure the effort and the resource usage is really worth it, as anything that needs to be done should be able to be accomplished using our current form of list handling.
If you don't like or want such a function just say so and I'll keep it out of the CVS and only use it on my local builds.
-
Maarc
- Developer
- Posts: 576
- Joined: Sat Mar 27, 2004 6:22 am
- Location: Fleet, UK
- Has thanked: 0
- Been thanked: 0
- Contact:
I'm already looking at ways to help improve AI. And really, AreaCharacterFunction/AreaItemFunction would work well for making decisions, if there was an easy way to early abort.
One of the things I'm working on is an upgrade to some combat related things (the tracking of damage and healing). This way, we can apportion karma/fame better, and exposing this information (who does how much damage/healing aggregate over time, but getting rid of entries over 5 minutes old) to the JS would allow you to write AI that is somewhat more intelligent (ie attack the person who's doing the most damage to you, or the person doing the most healing to your current target, etc).
One of the things I'm working on is an upgrade to some combat related things (the tracking of damage and healing). This way, we can apportion karma/fame better, and exposing this information (who does how much damage/healing aggregate over time, but getting rid of entries over 5 minutes old) to the JS would allow you to write AI that is somewhat more intelligent (ie attack the person who's doing the most damage to you, or the person doing the most healing to your current target, etc).