People seem to be very particular about the kinds of lots that they like to play: one story, two story, with or without a basement, with or without a foundation.
For a long time now, I've thought that it would be nice to be able to easily add levels (and possibly remove them as well).
I believe that this would be a pretty easy utility to write.
- Create a new level at the bottom, top, or in-between.
- Adjust the elevation of all objects above the new level; initially, might be able to have people use ConstrainFloorElevation to adjust existing stuff themselves. This same logic could be used to enhance the GridAdjuster.
- The base game may not be able to handle too many levels.
- Need to ensure that all instances of Min and Max level are changed appropriately. There seem to be a number of records where these values are stored.
- Do not adjust 2ARY instances 0x5C??, since they control terrain paints and should remain at the ground level, even when adding a new ground level.
I finished the code for adding a new level to the grid (3D Array Instance 1), but have not yet got the code done for moving all existing stuff up a level. Things that need to be moved:
- OBJT, XOBJ, XMTO (objects)
- WGRA (walls)
- FPL (fence posts)
- 3D Array Instance 0 (floors)
Things that shouldn't be moved:
- OBJT, XOBJ (portals)
- 3D Array Instance 0 (roads)
All of the other 3D Array instances need to have a new level added. Mainly, the 3D Arrays need to have all levels above the new level moved up one.
There may be other things which need to be moved, but these were the only ones flagged by the LotAdjuster.
Unfortunately, the base game crashes with a lot with too many levels, so this limit may be hardcoded.
I had no problems adding a new level to 9 Fledgling Flats using M&G. However, I verified that people cannot use CFE as a replacement for moving walls up.
My test case is to add a second story above the living space and below the multi-level roof, and to add a "real" basement (ie, two levels under the existing living space).
At this time, I'm not considering allowing people to add a true underground level (level = -1). It's easy to do, just add a pool to the lot, save, and then remove the pool.
However, I *did* create a basement using the "true underground level" and it didn't work very well. The main problem is that the game won't let you move down to a negative level, so it was impossible to manipulate the level (add walls, add floors, add furniture, etc). I finally gave up on the idea.
If you'd like, I could look for my test lot and post it here, for you to experiment with. I think you'll find that V1ND1CARE's method is better.
I can also try adding a level = -2 and see how quickly the game crashes.
Ah, well, no big deal. It would have been interesting, methinks, but I`m not sure I could have done anything useful with the lot. If it ever does turn up, let me know?
Will do. I'm a packrat, so I probably have it somewhere. If I remember correctly, it was pretty easy to create, so I might just make another when I have a moment.
Originally Posted by GeneralOperationsDirector
Regarding underground levels in general, have you tested the game with level=-2? If so, with or without data for that level, and did it crash?
No, I'm still working on raising the walls above an added level. Getting some odd behavior which I haven't pinned down yet.
Until I get the walls moving up a level correctly, I'm not 100% sure that I've gotten all of the various arrays resized and the min and max levels changed correctly. That's probably a minimal requirement for level = -2.
Level = -1 is a lot easier than level = -2, since I let the game create the level for me, then just moved the walls down.
Speaking of adding levels, what changes when you add AND DELETE a pool, leaving the lot unchanged, but saving the lot with a new empty pool level? How empty can level=-1 be and still exist without crashing the game? What happens if you create a level=-2 with data that minimal?
I haven't done a binary diff of all of the records in a lot after adding and deleting a pool, then parsed those records to determine all of the changed fields, so I don't have a list of the changes. I will do that if it becomes necessary (hopefully not). (If you're looking for something to do, this info would definitely be helpful.)
What I've been doing instead is to use my knowledge of the records within lot packages, and the changes required to expand a lot, and what I actually know about levels, to make the changes that I believe are a minimal requirement to add a level.
As far as I can tell, once a level is added, it is never removed, no matter how empty, and there's no "minimal requirement" for a level. As far as I can tell, additional levels are primarily additional levels in the 3D arrays, plus increased maximum level fields in various records and changes to the level and possibly to the elevation of walls, roofs, objects, etc. Adding a negative level would also require changes to all of the minimum level fields in various records.
I suppose that I wasn't clear enough above. I have never successfully added a level to a lot. Until I can successfully add a level to a lot, there's no way for me to determine what happens when I add level = -2. Until you started talking about negative levels, I wasn't even considering allowing people to add level = -1, since that's the one level that the game is actually willing to add on it's own.
My assumption is that all added levels will be completely empty, since I can't imagine what I'd actually put on the new levels that would be useful in any way. I'm also starting with the assumption that a new level should have a relative elevation of 3.0, although I could be convinced to let people specify the new elevation.
Finally managed to get the walls to move up correctly, so that it's more obvious where the new level has been added. However, there's something odd going on with the floor tiles. They appear in the correct place, but I am unable to select (with the eyedropper) or change them. This is true even after a room is added on the newly added level. All changes are directed to the ground level.
I'm going to take a closer look at the default values used for the various 3D Array instances.
Still to be done:
- Move objects up
- Keep road at correct level
Hmm, interesting. I may look into that sometime, but, unfortunately, not likely soon enough to be useful to you [see an this postfor why]. I`m mostly trying to bounce ideas off of you, to see which ones are most likely to be helpful to either of us. I apologize for any that don`t work out, and hope that enough are useful to be worth wading through the rest.
I found the problem: the WRLD record is very sensitive to changes in the maximum level. It originally has a maximum level (3, in this case) which is less than any of the other records (4 in my test lot). I was setting it to the new number of levels (5), which was creating odd problems. Now, I'm just adding one to the maxlevel field and that seems to have resolved everything.
Not sure at this time. I'll have to run some automated testing to see if I can figure out the rules for the WRLD MaxLevel. For now, just adding 1 seems to be the correct logic.
I know that the depth of 3D Arrays is MaxLevel - MinLevel from the WGRA record, I usually just use the one from WGRA Instance 5. MinLevel is always either 0 or -1 (or -2 for the -2 level test which is closer to happening).
Now that I've got this much working, I should probably go back and see whether it works to add more levels in the base game.
Oh, one other discovery: 3D Array Instances 9 (place), 0xA (load), and 0xB (light) seem to contain Room IDs from the various WGRA instances (array B). Guess I should update the wiki, but the 3D Array record is already terribly complex with all of the info that niol added.
That pool idea is an interesting solution to a house I made about a year ago. After I made it, (no foundation) I decided the front living area needed to be dropped. I was unsuccessful in adding a foundation or dropping steps down - the walls wanted to slope instead of being vertical. I ended up sproinging the whole house. lol Good thing I always keep backups. Next time I load the game, I'll have to try that pool idea in the living area and report back. :0)
WARNING This is an early test version. It will probably destroy your lot. You have only yourself to blame.
WARNING DO NOT share lots made with this tool.
Specify the level that you want to add. Walls and floors for levels above this will be moved up. Furniture, roofs, etc will not (yet). If you add level = 0, you will get a road in the air; you can remove it using "moveobjects on" and the normal floor tiles removal mechanism.
Removed test version. Newer test version available.
I'm not happy with the name of this tool. For one thing, I'm hoping to add code to remove levels as well as add them. But LevelAdjuster just sounds too much like LotAdjuster for my comfort. Besides, lots of people have taken to abbreviating the LotAdjuster as LA and this tool would have the exact same abbreviation.
Furniture, windows, doors, etc now moving up a level. However, if an object is sitting on top of another object (table lamp, sink, computer, etc.), then it is moved up 16 clicks too much. If you grab the object and let go again (press <esc>), the object will snap down to it's correct location, so it would appear that I'm pretty close.
That was much harder than I expected. Turns out that the object record (OBJT) doesn't have level information, just elevation data. The level info seems to be stored in the XMTO record. Info on XMTO is severely restricted: http://www.sims2wiki.info/wiki.php?title=XMTO
So, somehow I have to figure out the correlation between the XMTO and OBJT, so that I can be sure to move only objects which are above the level being added.
Well, I spent quite a bit of time looking at the various record formats and I have concluded that it will take "too long" for me to find the level information for the objects, since I'm really hoping to have this out in a week or so.
So, plan 4 (see below for plans 1 to 3) is to have people specify which objects they want moved by specifying an elevation (in floating point or in clicks). Anything above that elevation will be moved up. Not a perfect solution, but perhaps adequate for version 1.
I tried this on Belle's Townhomes from AL and you can see the results... worked pretty well, all things considered.
Or, perhaps I'll try plan 5: add new levels with an elevation of 0 and let people use CFE to change them if they want.
However, it occurs to me that I should probably allow people to specify a range for the new level, similar to the ranges available in the GridAjduster and ConvertiWall. This would allow people to change a normal home into a split level (or vice-versa).
Although both Inge Jones and I previously believed that all OBJT records contained a corresponding XOBJ record with the same instance number, I am now convinced that this isn't true. Unfortunately, my original plan was to get the level for an OBJT record from the corresponding XOBJ record. Nix plan 1.
Then, I thought that I might be able to find an XOBJ record which corresponded to the OBJT record by examining the list of associated instances in the OBJM record. However, this still didn't always provide a XOBJ record for every OBJT. Nix plan 2.
My next thought was that I might be able to use the level in the XMTO record instead of the XOBJ record, but I have been unable to determine the correlation between XMTO and OBJT, although I'm convinced that such a correlation exists. This is because objects will not move up a level until I change the level in the XMTO record. Nix plan 3 for now, although I'd like to explore this further when I get some time.