|
|
|
 |
 |
 |
 |
|
 |
 |
|
 |
 |
|
 |
|

07-16-2009, 01:23 PM
|
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
On a read-through pass, I noticed a cosmetic glitch.
Line 13628 in command.cpp sends an error message that tries to refer to 'id' after it has been reset to 0.
The fix:
Code:
...
if (id == 0)
{
- c->Message(0, "ERROR: An object already exists with the id %u", id);
+ c->Message(0, "ERROR: An object already exists with the id %u", atoi(sep->arg[2]));
return;
}
...
|

07-16-2009, 01:35 PM
|
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
Minor typo on Line 13980:
Code:
od.unknown008[1] = atoi(sep->arg[4]);
o->SetObjectData(&od);
c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you comit to the database with '#object Save'. Support for this property is on a per-model basis, mostly seen in smaller objects such as chests and tables.", id, od.unknown008[1]);
|

07-17-2009, 12:24 AM
|
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
Once the #object command has been tested out and committed to the SVN, I'll get to work porting the functionality to #door and #groundspawn (I"ll probably give that one a '#gs' alias. Heh.)
|

07-17-2009, 02:45 AM
|
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
MakeAnyLenString() would be preferable to your snprintf in this case, would of saved you a lot of time too, just have to remember to free the pointer it creates afterward.
|
 |
|
 |

07-17-2009, 03:04 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Thank you Shendare! I got the changes in and it compiled perfectly this time. I also got it tested and everything I tried worked perfectly. I committed this to SVN R783. It is very cool to finally be able to have options to manipulate objects in game like that. The command will be a huge help to people in need of it, and will make easy work of things that were considerably more time consuming before this was available. So, great job!
From what I have seen so far, the only suggestion I might make would be a way to bool whether or not it is going to move your character when you do a ToMe move. In cases of dealing with large items, the move might be needed, but when trying to fine tune the positioning, it might be nice to just be able to move a slight bit and do another ToMe until it is perfectly placed. Also, having it report it's current loc after being moved that way would be nice, so you could then do an X Y Z move to tweak the position as well. Those are minor things and just things to consider for the future of this command.
I also played with trying to use it to spawn doors, but sadly, I guess door models don't play nice with object packets like I had assumed they would. I guess that anything with a IT<model number> that can be applied to an item as a graphic is considered an object, and anything without that is considered a door and they can't be used interchangeably between the packet types. That puts a bit of a damper on being able to have the option of using object packets to perfectly position doors. I am pretty sure we could still use door packets to do it, but unfortunately I know of no way to remove doors, so it will be a bit harder to do perfectly like with objects without having to restart the zone. If there was any case on live of something considered a door (that uses door packets) that disappears, we could collect that info and make use of it, but I am not aware of a single case of that happening on Live. Maybe ground spawns would work, but I think they work like object packets, so I kinda doubt it.
With the addition of the #object command, I can see other possibilities popping up to make use of spawning and despawning objects in real-time. If a quest command was made that could manipulate them in similar ways, I am sure neat stuff could be done with that. It probably wouldn't get used too often, but is just another neat idea possibility for the future.
Thanks again, Shendare! That is one heck of a chunk of code!
|
 |
|
 |

07-17-2009, 04:23 AM
|
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
I still have some reservations on this, don't consider it final.
|
 |
|
 |

07-17-2009, 10:58 AM
|
|
Dragon
|
|
Join Date: Apr 2009
Location: California
Posts: 814
|
|
Yeah, KLS, MakeAnyLenString was certainly an option. I went with snprintf instead to lower a bunch of heap allocations I considered unnecessary. I can elaborate.
Utilizing snprintf, the memory for the string gets allocated just once at the beginning of the function, and is reused with each call to snprintf. The only caveat is to make sure I set aside a large enough buffer for all of my possible uses.
With MakeAnyLenString, for anyone reading who isn't familiar with it, the memory for the string is allocated with each MakeAnyLenString call, and re-allocated as many times as necessary within the function to fit the result string, starting with 256 bytes and doubling each time, re-performing the vsnprintf() call and its process time for each re-allocation as well. This means you don't have to worry about how large the string is, but it also means you could end up with three or four heap allocations per call for larger strings, and re-performing the vsnprintf() call for each allocation until you get one that fits within the buffer, potentially wasting time and fragmenting the heap.
If there's a standing dev preference for the use of MakeAnyLenString over snprintf, I have no problem changing the code to use it instead. I just felt I would explain why I didn't in this case, where the query string buffer might be re-used several times in a single function call.
As for your suggestions, Trev, at the very least adding a coordinate report in 'Move ToMe' is a simple and very worthwhile idea, requiring just one line addition at (what shows in my current source as) Line 14145:
File: command.cpp - object_command()
Code:
...
// GetHeading() returns half of the actual heading, for some reason
x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f);
y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f);
c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2.0f);
+ c->Message(0, "Object %u moved to %.1f, %.1f, %.1f, heading %.1f", id, od.x, od.y, od.z, o->GetHeading());
}
else // Move to x, y, z [h]
...
Unfortunately, not bumping the player back when using 'Move ToMe' always caused problems during my debugging. The model would get summoned into my character's location at his feet, and because the model was always considered solid as a moveable tradeskill object, my character then either (1) couldn't move at all and I had to use #goto, or (2) got bumped up atop the object or bumped out of the object. Both rather throw a wrench in fine tuning location by moving your character slightly with another 'Move ToMe'.
However, adding the coordinate report before bumping your character back will allow numeric fine-tuning, at least, and was a very good idea. I should have thought to add it to 'Move' after putting it in 'Add'.
Now, what problem exactly were you having with door models, Trev? I was able to use FELDOOR2 and DOOR1 while debugging the command in Felwithe.
|
 |
|
 |
 |
|
 |

07-19-2009, 07:16 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Interesting... Doors do seem to work just fine when I test your example. The place I was testing them in was Dreadspire and most of the doors there have considerably longer names than doors in older zones. Here are some examples:
Quote:
OBJ_LIBRY_HIDEDOOR
OBJ_MAINCASTLE_DOOR
OBJ_DINE_LDOOR
OBJ_DINE_RDOOR
OBJ_DNGRM_LDOOR
OBJ_DINERM_RDOOR
OBJ_MAINCASTLE_DOOR
OBJ_HIDDENDOOR
OBJ_BDRM_LDOOR
OBJ_BDRM_RDOOR
OBJ_LIBRY_SWITCH
MAYONGSWITCHA
MAYONGSWITCHB
OBJ_MAINCASTLE_DOOR
OBJ_TORTURE_DOOR
|
I didn't try all of those, but I did try a few. My best guess is that the problem is with the length of the new door names. I made sure to try some under 16 chars, but that didn't make any difference. Maybe we are setting the limit lower than it should be somewhere. Also, for it to work on all doors, we might need to look into increasing the limit from 16 chars to 20 or so. I went through a while back and set it so doors can use 32 chars, because they were previously set to 16 for no reason. From looking at the packet structure on Titanium, it looks like we could easily bump objects up to 32 as well:
Code:
/*44*/ char object_name[20]; // Name of object, usually something like IT63_ACTORDEF
/*64*/ float unknown064; // seems like coords, not always valid, all 0 on most world objects
/*68*/ float unknown068; // seems like coords, not always valid, all 0 on most world objects
/*72*/ float unknown072; // seems like coords, not always valid, all 0 on most world objects
Those last 3 fields there are bogus and could be combined with the 20 from the object name to make 32. For some reason, live sends bogus info in their name fields after the name, but it has no use at all and is somewhat random in many cases. I would guess that they do that to throw people like us off, but I'm not falling for it :P
So, if we change the structure, we would also have to change everything else related to object name to be able to handle 32 characters in length. I think that would fix the issue I was seeing in Dreadspire at least. Probably even some old zones would have issues with this limitation, so it wouldn't hurt to get it fixed at some point.
|
 |
|
 |
| Thread Tools |
|
|
| Display Modes |
Hybrid Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 04:07 AM.
|
|
 |
|
 |
|
|
|
 |
|
 |
|
 |