Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: DFHack Script: Builder (Local Map Editing Tool)  (Read 4803 times)

Nolimit

  • Bay Watcher
    • View Profile
DFHack Script: Builder (Local Map Editing Tool)
« on: September 15, 2017, 05:03:30 am »

So, I wrote lua script for making natural/smooth walls/floors/fortifications/ramps/stairs/holes.  It works in a similar way to Tiletypes plugin, except it has a gui for settings and allows mass selection of tiles. I'm not a coder, so I'm also looking for a feedback, 'cause I probably messed something up.

Easiest way to use it is to create keybindings, I used: keybinding add Ctrl-Z "builder" and keybinding add Alt-Z "builder -s". Without argument command used to select an area by using it twice in two corners, and argument -s used for settings gui. It also includes paint mode, which can be used to change material of existing tile. It doesn't change materials of soil floors, soil walls, trees. But changes natural/smooth walls, floors etc. and constructed walls, floors etc. (Construction item material currently doesn't change, so if deconstructed it will return original item). More information can be found using 'builder ?'.

Use with caution! It can be really slow for big selected areas!
Spoiler: builder.lua (click to show/hide)

I also have a few questions. I would love to include ability to create constructions. And while I can change tiletype to constructed wall, and I can add new construction in df.global.world.constructions, but they do not 'connect'. Constructed wall on a map will be without material and upon deconstruction my added construction entry will remain in df.global.world.constructions. I assume that there is some other thing in the memory that connects constructions to map tiles. Same question for buildings: how can I connect buildings from df.global.world.buildings to map tile?

For building creation I could also use dfhack.buildings.constructWithItems(), but it creates designation for building. I can change building stage for it to 1, and it would appear as fully constructed building, but there still will be a job associated with it. Moving item to this building using moveToBuilding() doesn't work, and deleting job may cause crash. So is there a way to make fully constructed building using this function?

And another question, which I probably could figure out by myself, but to make things easier I decided to ask here. Currently my script will not work for map edges, and will require -reset to work properly after. That's because it will check adjusting tiles in cardinal directions and above tile. I want some simple solution to prevent its usage at the top and bottom of the map, and at all four edges.
« Last Edit: September 17, 2017, 07:36:24 am by Nolimit »
Logged

Fleeting Frames

  • Bay Watcher
  • Spooky cart at distance
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #1 on: September 16, 2017, 05:20:59 am »

Trying it out....

||

Not bad!

||

I can see it being really useful for replacing accidentally dug tiles for OCDs.

Might be neat if it could alter minecart tracks as well, but there's other commands like autodump to dismantle the deathtraps as well.

Though, seems like attempting to hide newly-created floors has problems:

||

First, it applies the area in a rectangle, not circle in this case.

Second, obviously you can still see the tiles, and on k-look there's nothing in it and they're still marked as Inside/Outside Light Above Ground.

It does change to subterranean with painting standard "keep as it is" revealed walls, though.

Placing a wall over natural ramp doesn't quite work properly and doesn't generate the floor above:

||

This is solved by first painting a floor, then a wall.

To prevent usage on all six faces of embark box, you can get x,y,z dimensions of embark from df.global.ui.unk_mapedge_x , _y and _z or df.global.ui.map_edge.surface_x, _y, _z. The values in array vary, but the greatest value is always 1 less than the tiles in that direction.(143, 239 and 68 for 3x5 embark, for instance). There's probably other ways, too.

Nolimit

  • Bay Watcher
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #2 on: September 17, 2017, 05:44:14 am »

Thanks for your reply. As for minecart tracks, I thought about it and it may be worth it's own script. There is almost no reason to apply track in a square or circle and definitely no reason to apply them to multiple z-levels at once. Also wall connections currently applied automatically to all surrounding walls and for tracks it doesn't always make sense to connect to every other track around. So i think I'll make a separate script for tracks at some point.

As for hiding, hidden flag doesn't work if tile is above ground (it changes to hidden in memory, but wouldn't appear hidden). Also tile wouldn't change to underground if it is outside (I can remove that condition, but I tried to keep it realistic to the game, where no outside tiles could also be subterranean). That means that it wouldn't hide outside tiles, unless you'll create some sort of roof above. Not sure if it was what you've experienced, though. If it something else, I'd like to see more details.

It does change to subterranean with painting standard "keep as it is" revealed walls, though.
Not sure how to recreate this. What I tried: I made an area of natural floor underground and changed it to above ground. Then applied smooth walls with underground: 'keep as it is', and it shows that walls are inside, above ground and light. When I set underground status to 'underground' they appear dark and subterranean. So, again I would like to know more details, if it's not too hard for you, also check if there are any errors in dfhack console.

Placing a wall over natural ramp doesn't quite work properly and doesn't generate the floor above:
Same here, couldn't find a way to recreate this. Tried both smooth and natural walls on tiles with natural and constructed ramps, and it always creates floor above. Normally it should check tile above for 'solid' tiles a.k.a. roof. Ramp top shouldn't be considered 'solid', and if there is no 'solid' roof it should create a floor. The only way I can see when it wouldn't work, is when execution of the script breaks before reaching the line where it creates the floor. In this case there should be an error in console and I would like to see it. Everytime I try it, it works for me, but maybe I miss some other conditions.

As for circle, currently it's just a placeholder, I haven't really bothered with a math for proper ellipse calculations. In the future I am planing to add other shapes too, like hollow ring and hollow rectangle. As for now, I would suggest to avoid using it.

I also updated code in the first post, now it will give you a warning if your cursor is 2 tiles near the edge. I end up using df.global.world.map.x_count, y_count and z_count, as it is much simpler. Also df.global.ui.unk_mapedge_z doesn't go to the top of the map for some reason.
Logged

Fleeting Frames

  • Bay Watcher
  • Spooky cart at distance
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #3 on: September 17, 2017, 06:37:13 am »

Regarding walls changing to subterranean, settings:

||

Painting a 2x2:

||

For ramps, Hm. Interesting. Simply channeling a hole in the ground and then painting a wall with above setting does create floor top. It works fine aboveground with default settings, but not the underground ones.
i.e.
   __surface
▼#
#▲▼
##▲

Works fine for the white ramp, but other two don't. No errors in console, sadly.

Testing in 43.03-r1, for what's it is worth - I know that it doesn't have some construction-related memory spaces filled that 43.05-r2 and 42.06-r1 have (which is why my construct with cloth doesn't work with that in particular).

Warnings seem to work fine.

Nolimit

  • Bay Watcher
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #4 on: September 17, 2017, 08:04:06 am »

Found a problem with walls over ramps, it actually wasn't working for walls underground no matter what initial tile is. Updated first post again with a fix.

As for subterranean: from what I see it works as intended. I guess I also should rename underground to subterranean as it is how it's referred in the game. Basicly if underground status is set to 'underground' it will try to change all tiles to subterranean, and it will only fail and keep them 'Above ground' if it is an open tile (floors, ramps, stairs etc.), and it doesn't have a roof, and above tile isn't outside. Wall always considered inside, and will always change their above ground/subterranean status based on setting.

I'm also using 0.43.05-r1. So you're saying that in 0.43.05-r2 there are more construction related memory filled, interesting... I don't remember what exactly, but something turned me off from -r2 version. Maybe it wasn't supporting twbt or something.
Logged

Fleeting Frames

  • Bay Watcher
  • Spooky cart at distance
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #5 on: September 17, 2017, 08:09:45 am »

Nice hotfix, it now works for underground ramps (though previous version still worked if one painted floor first, then wall).

Also, I'm saying 43.05-r1 (where I created cwc) and r2 have more addresses than 43.03-r1. Don't know if 43.05-r2 and 43.05-r1 have any differences regarding this.
« Last Edit: September 17, 2017, 08:13:22 am by Fleeting Frames »
Logged

Nolimit

  • Bay Watcher
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #6 on: September 17, 2017, 09:20:31 am »

Also, I'm saying 43.05-r1 (where I created cwc) and r2 have more addresses than 43.03-r1. Don't know if 43.05-r2 and 43.05-r1 have any differences regarding this.

Got it. Is there any documentation on df architecture for dfhack? Maybe I could find something about how buildings and constructions are placed on the map.

My end goal is to create some sort of cheat engine to be able to change map (in multiple scripts, or maybe arrange it in one at the end). It may be used for cheating, testing, adventure maps or fixing aesthetics. But right now I have no clue how to spawn buildings, and I'm kind of stuck because of this. In a meantime I could work on minecart tracks. After you mentioned them I got some new ideas on that.
Logged

Fleeting Frames

  • Bay Watcher
  • Spooky cart at distance
    • View Profile
Re: DFHack Script: Builder (Local Map Editing Tool)
« Reply #7 on: September 17, 2017, 11:46:11 am »

Well, I know all the memory addresses used are kept in file called symbols.xml, and you can track the related issues of, say, replacing unknowns with appropriately named variables on github.

In your place, for that question, I'd find a script that already places buildings on the map and then learn from it. I suspect you might end needing a similar workaround as create-item does (i.e. grabbing first unit on the map and using it for reaction to produce items.).