Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 [2] 3

Author Topic: [SCRIPTING] DFHack Lua/Ruby scripting questions thread  (Read 6200 times)

Atomic Chicken

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #15 on: August 29, 2016, 05:23:37 am »

I also found the fog_of_war and designation flags in map_block which I'm using to filter the list to visible items.  Not sure fow is useful here though.
I carried out some research on this a while ago, so here's the info in case you still need it:

The value in fog_of_war corresponds to the character displayed when the tile is outside the adventurer's vision range. Tiles which have never been within vision range are initially set to 0 and the value is updated when the tile exits/enters vision range. designation.hidden is only set to true for tiles which have never been within vision range. Hence, both fog_of_war and hidden are only useful for determining whether a tile has been seen before; they cannot be used to determine whether the tile or its contents are visible to the adventurer at a given moment.

designation.pile is what you're actually after. I don't know why it was named as such, but setting it to true is what makes a tile appear to be within vision range.
« Last Edit: August 29, 2016, 05:29:10 am by Atomic Chicken »
Logged
As mentioned in the previous turn, the most exciting field of battle this year will be in the Arstotzkan capitol, with plenty of close-quarter fighting and siege warfare.  Arstotzka, accordingly, spent their design phase developing a high-altitude tactical bomber. 

Warmist

  • Bay Watcher
  • Master of unfinished jobs
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #16 on: August 29, 2016, 06:53:51 am »

designation.pile is what you're actually after. I don't know why it was named as such, but setting it to true is what makes a tile appear to be within vision range.
It's probably called like that because it's used for something else in fort mode (IIRC)

figment

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #17 on: August 29, 2016, 08:39:34 pm »

Thanks for the feedback.  I was using designation.pile and yes its name is confusing but I found it in the reveals script.  I will probably remove the other flags since they seem redundant for my purposes based on your description.

I plan to use in adventure mode so everything is turnbased so a sidebar that is only open temporarily would be fine.  I would like to be able to show and move the map around using the screen view and use the cursor to focus on items.   I'll look at gui/liquids and what it does if its similar to what I want.

I am using TWBT at the moment, I'll remove and try again but it would be hard to live without.  I also removed all of the screen painting and invalidation calls except for the example code and subclassed directly from View and not Screen or FramedWindow figuring that the screen painter for Screen would blank the whole screen.
« Last Edit: August 29, 2016, 08:47:44 pm by figment »
Logged

mifki

  • Bay Watcher
  • works secretly...
    • View Profile
    • mifki
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #18 on: August 29, 2016, 09:31:30 pm »

I plan to use in adventure mode so everything is turnbased so a sidebar that is only open temporarily would be fine.  I would like to be able to show and move the map around using the screen view and use the cursor to focus on items.   I'll look at gui/liquids and what it does if its similar to what I want.

gui/liquids is a bit different as it inherits from a special class for menu overlays that works in the fortress mode only. I can't say anything whether it's possible to do what you want in just Lua or not. However how I'd do it is interpose render/feed methods in C++ and then call Lua code to do actual processing and output (if you prefer Lua). In this case you will be able to provide real-time information as the adventurer moves or in look/throw/whatever modes you want, and will have less problems with TWBT.

figment

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #19 on: August 29, 2016, 10:03:51 pm »

Sigh.  The problem appears to be with TWBT after all.  The menu I was creating works fine with TWBT disabled.  I'll have to research that some more.  I consider it a must have plugin so will try and figure out what I can do.  I now understand some of the vtable hooks better after getting TWBT working on my Win64 build (which by the way is really awesome and very professionally done imo... the hooks that is).   

I can presumably put together a bootstrap in C++ and maybe do the sidebar base features in that and the complex stuff in lua like you say.   The project just snowballs in complexity but such is life I suppose. 
« Last Edit: August 29, 2016, 10:05:36 pm by figment »
Logged

Dirst

  • Bay Watcher
  • [EASILY_DISTRA
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #20 on: August 29, 2016, 11:00:07 pm »

 
The project just snowballs in complexity but such is life I suppose.
This is a known problem with modding DF.  For example, mifki started out trying to get his zeros to not look like coffins, and we ended up with the massive TWBT package. :)
Logged
Just got back, updating:
(0.42 & 0.43) The Earth Strikes Back! v2.15 - Pay attention...  It's a mine!  It's-a not yours!
(0.42 & 0.43) Appearance Tweaks v1.03 - Tease those hippies about their pointy ears.
(0.42 & 0.43) Accessibility Utility v1.04 - Console tools to navigate the map

mifki

  • Bay Watcher
  • works secretly...
    • View Profile
    • mifki
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #21 on: August 29, 2016, 11:50:09 pm »

Sigh.  The problem appears to be with TWBT after all.  The menu I was creating works fine with TWBT disabled.  I'll have to research that some more.  I consider it a must have plugin so will try and figure out what I can do.  I now understand some of the vtable hooks better after getting TWBT working on my Win64 build (which by the way is really awesome and very professionally done imo... the hooks that is).   

I can presumably put together a bootstrap in C++ and maybe do the sidebar base features in that and the complex stuff in lua like you say.   The project just snowballs in complexity but such is life I suppose.

TWBT won't render map if there's any screen on top of the main screen because there's no way to know whether that screen covers the entire map or not. Now I'm thinking that it should be possible (at least as an option) to render the map always - it's just a waste of resources, unless there were some other reasons I did it this way. You can disable these checks in renderer.hpp and see.

figment

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #22 on: September 03, 2016, 10:32:34 am »

I recompiled TWBT and edited write_tile_arrays_text to always make stuff transparent when derived from dfhack_viewscreen and it worked.

So I'm guessing one solution would be to detect that the current screen is a dfhack_viewscreen and add a getViewRect equivalent and only allow that function to override when in that rectangle.  I presume that would require the dfhack Screen class to be complicit somehow since it seems to only have a size and not position available. This might make for a reasonably general solution but need acceptance of dfhack team.  Will test this a little bit to see if it really works without too much overhead.

Edit:  Well ran into a number of issues with Lua and not sure why I'm getting stack problems regarding plugin_update but as the function callback worked and I think my logic would largely work.  I even checked lua_gettop and used the StackUnwinder and seems good to me.  I'll try to call from someplace other than at the start of display_new but that seemed reasonable.  I can move it to ::draw but seems about the same and needs to be after window resizing.  Seems related to the output console getting invoked while trying to call the functions on the global lua stack.  Its either that or figure out how to just call lua functions without the safe_lua_call.

Edit 2:  I've decided the problem is dfhack does not have adequate locking mechanisms on the global lua state and this is fundamentally a multithread issue.  I decided to move the code from TWBT mostly to Screen in dfhack and make it mostly optional.  Code to check if the view has a view rectangle will be done before every render (or maybe after resize) and cached in the dfhack_lua_viewscreen. TWBT will then check if derived from dfhack_viewscreen and pull the cached size when determining transparency in write_tile_arrays_text.   Ok.  Now with that done will get back to the fun stuff and make a sidebar.
« Last Edit: September 03, 2016, 04:01:08 pm by figment »
Logged

gchristopher

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #23 on: September 03, 2016, 10:49:09 pm »

Is there any good tutorial for learning how lua scripting works in DF context for someone with no prior experience?
Do you mean no experience with Lua, or no experience with programming?

If the latter, then you should find/try any programming tutorial that seems friendly. It doesn't really have to be Lua.

If the former, Lua is easy, just crib from the many DF-specific examples that are out there. The main effort is learning how the structures provided by dfhack relate to the game, and the various utility functions. (Like dfhack.gui.getSelectedUnit() etc...)


Question:

Given X/Y/Z, isn't there a utility function to get the object structure for the current tile? (tiletype, occupancy, plants, etc?) Does anyone know offhand what that is? My search skill has been failing.
Logged

gchristopher

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #24 on: September 03, 2016, 11:05:12 pm »

Given X/Y/Z, isn't there a utility function to get the object structure for the current tile? (tiletype, occupancy, plants, etc?) Does anyone know offhand what that is? My search skill has been failing.
It's dfhack.maps.getBlock(x,y,z) and also I'm an idiot who can't RTFM. Leaving this here as evidence of my shame.
Logged

lethosor

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #25 on: September 03, 2016, 11:30:14 pm »

I recompiled TWBT and edited write_tile_arrays_text to always make stuff transparent when derived from dfhack_viewscreen and it worked.

So I'm guessing one solution would be to detect that the current screen is a dfhack_viewscreen and add a getViewRect equivalent and only allow that function to override when in that rectangle.  I presume that would require the dfhack Screen class to be complicit somehow since it seems to only have a size and not position available. This might make for a reasonably general solution but need acceptance of dfhack team.  Will test this a little bit to see if it really works without too much overhead.

...

...
One issue is that overlays don't necessarily have to be rectangles. They usually are, but it's not required, and there's no reason for it to be required currently.

Mifki did come up with a solution that involves rendering the vanilla dwarfmode/adventurer screens to a separate text buffer, overlaying whatever DFHack screens draw (as text, not explicitly to the map) to that, then rendering the result. (At least, that's how I remember it.)



Given X/Y/Z, isn't there a utility function to get the object structure for the current tile? (tiletype, occupancy, plants, etc?) Does anyone know offhand what that is? My search skill has been failing.
It's dfhack.maps.getBlock(x,y,z) and also I'm an idiot who can't RTFM. Leaving this here as evidence of my shame.
Yeah, the closest you can get to information for a single tile (without making up your own wrapper) is information for all tiles in the 16x16 block containing that tile.

Also, you should probably be using getTileBlock(x, y, z). The difference is that getBlock(1, 1, 3) returns the second block from the north and west edge from the map (i.e. tiles (16, 16, 3) to (31, 31, 3)), while getTileBlock(1, 1, 3) returns the block containing the tile (1, 1, 3), from which you can get information about that tile. In that case, getTileBlock(1, 1, 3) would be the same as getBlock(0, 0, 3).

Edit: an example:
Spoiler: Example (click to show/hide)
getTileBlock(1,1,0) returns the block containing the red tile, while getBlock(1,1,0) returns the blue block.
« Last Edit: September 03, 2016, 11:33:08 pm by lethosor »
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

figment

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #26 on: September 03, 2016, 11:55:50 pm »

One issue is that overlays don't necessarily have to be rectangles. They usually are, but it's not required, and there's no reason for it to be required currently.

Mifki did come up with a solution that involves rendering the vanilla dwarfmode/adventurer screens to a separate text buffer, overlaying whatever DFHack screens draw (as text, not explicitly to the map) to that, then rendering the result. (At least, that's how I remember it.)
I think that was the code I was editing.  It does seem to be there but doesn't work for the dfhack viewscreens.  I'll make it optional so that its not necessarily on for all views only for ones with the callback implemented.


Ok. Running into issues with Lua forms again.  I'm really confused by the dynamic layout engine for automatically placing widgets/subviews/... .  Sometimes it works as I expect some times it doesn't. 

My issue is that I would like to have the view dynamically size based on the size of the screen.  I suppose I can manually calculate all of the positions but it seems like there was some basic support.  For example, a subview stack might be { Label, FilteredList, Edit, Label, HorizontalRule, Label, HorizontalRule, Label }  where HorizontalRule is a new widget I created to draw a straight line and CustomControl was just something with custom drawing.   I'd like everything but the FilteredList to be fixed size in a vertical layout but the items below the list are relative to the bottom.

Sometimes the labels and edit controls seem to understand their position in the stack sometimes they don't but I'm not sure why.  I was able to workaround the sizing of the edit box by using a pane and forcing a height constraint by using on_layout.  There don't seem to be easy ways of constraining the sizes of some widgets, am I missing something or is the current behavior not anticipating use like this. 

I suppose I can write something myself or force layout but hate reinventing the wheel.  Having said that I do have a nice dynamic layout engine from a couple of decades ago for C that might work reasonably well here.  I'd worry about conflicts with existing widgets or creating a fork of sorts though.
Logged

Warmist

  • Bay Watcher
  • Master of unfinished jobs
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #27 on: September 04, 2016, 03:46:37 am »

One issue is that overlays don't necessarily have to be rectangles. They usually are, but it's not required, and there's no reason for it to be required currently.

Mifki did come up with a solution that involves rendering the vanilla dwarfmode/adventurer screens to a separate text buffer, overlaying whatever DFHack screens draw (as text, not explicitly to the map) to that, then rendering the result. (At least, that's how I remember it.)
I think that was the code I was editing.  It does seem to be there but doesn't work for the dfhack viewscreens.  I'll make it optional so that its not necessarily on for all views only for ones with the callback implemented.


Ok. Running into issues with Lua forms again.  I'm really confused by the dynamic layout engine for automatically placing widgets/subviews/... .  Sometimes it works as I expect some times it doesn't. 

My issue is that I would like to have the view dynamically size based on the size of the screen.  I suppose I can manually calculate all of the positions but it seems like there was some basic support.  For example, a subview stack might be { Label, FilteredList, Edit, Label, HorizontalRule, Label, HorizontalRule, Label }  where HorizontalRule is a new widget I created to draw a straight line and CustomControl was just something with custom drawing.   I'd like everything but the FilteredList to be fixed size in a vertical layout but the items below the list are relative to the bottom.

Sometimes the labels and edit controls seem to understand their position in the stack sometimes they don't but I'm not sure why.  I was able to workaround the sizing of the edit box by using a pane and forcing a height constraint by using on_layout.  There don't seem to be easy ways of constraining the sizes of some widgets, am I missing something or is the current behavior not anticipating use like this. 

I suppose I can write something myself or force layout but hate reinventing the wheel.  Having said that I do have a nice dynamic layout engine from a couple of decades ago for C that might work reasonably well here.  I'd worry about conflicts with existing widgets or creating a fork of sorts though.
Yeah the layout system is not perfect but it was enough for me at least. It has either one pinned side + size or both pinned + dynamic size. More like msvc forms?
Not sure what you meant by "sometimes they don't" maybe you could share a minimal example that does that?

Also imho you could do "the Qt way" i.e. containers that manage the layout. E.g. you could make a grid layout, where you can say which columns and rows are fixed and which grow.

figment

  • Bay Watcher
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #28 on: September 04, 2016, 09:32:19 am »

Not sure what you meant by "sometimes they don't" maybe you could share a minimal example that does that?


Basically the following code generates the following view.  Some of the Text Labels dont show (probably drawn over) and its like the Labels are positioning evenly across the bar.  The list view does not stop, I commented out the limiting code in panel for screen shot.

Code:
Spoiler (click to show/hide)
Image:
Spoiler (click to show/hide)
Also imho you could do "the Qt way" i.e. containers that manage the layout. E.g. you could make a grid layout, where you can say which columns and rows are fixed and which grow.
Yes, I plan to adopt some old code.  I cannot find the article its based on right now. Anyway, easier to port than to develop from scratch and the concepts are solid.  Basically its like most layout engines where you have fixed, percent, tofit, rest.  I can take advantage and draw the separators with correct characters presumably.

I'm confused between the frame_rect and body_rect in the widgets. Is frame supposed to be relative to screen and body relative to frame?

The only other issue I keep having with this is lua class inheritance via the defclass is wonky.  It seems like super should be the base class of the parent and allow calling base methods but doesn't seem to work for me consistently.  There is a lot of code that seems to work though.  Not sure if its because its in a different lua file or something.


Edit:  After reviewing documentation again I think it does explain parts that confused me previously with regard to alignment. So before I embark on a code journey I'll see if inheriting from Widget for my HorizontalBar and using the frame attr correctly will help me.
« Last Edit: September 04, 2016, 10:01:11 am by figment »
Logged

Warmist

  • Bay Watcher
  • Master of unfinished jobs
    • View Profile
Re: [SCRIPTING] DFHack Lua/Ruby scripting questions thread
« Reply #29 on: September 04, 2016, 04:32:08 pm »

In your example the "widgets.Panel" does not have the "frame" setting at all. Thins makes it at middle or sth...

Frame_rect is outside (in parent coords) and body_rect is inside (in parent coords) e.g. if you have frame_rect={t=2} and body_rect={t=3} it has 2 tile outline before "frame" (the box) is drawn and 3 tiles until the contents are drawn. That is if i remember correctly.

For me at least the thing i missed most is text auto flow - adding newlines automatically.

Pages: 1 [2] 3