Adding a 'bulk transplant' feature

Individually transplanting renewable plants is rather tedious, so I thought I’d look into implementing a “bulk transplant” feature. Generally speaking, the intention is to drag a selection box and have all selected plants pop to the cursor one after the other, similar to the way the item placement from storage works.

It was easy enough to add a new button to the Harvest sub-menu and implement a bit of test code (largely copypasta from the harvest aka “Gather” functions) to ensure I could filter out plants (based on renewability):

[code]function ResourceCallHandler:box_transplant_resources(session, response)
stonehearth.selection:select_xz_region()
:set_max_size(80)
:require_supported(true)
:use_outline_marquee(Color4(0, 255, 0, 32), Color4(0, 255, 0, 255))
:set_cursor(‘stonehearth:cursors:harvest’)
:set_find_support_filter(function(result)
if result.entity:get_component(‘terrain’) then
return true
end
return stonehearth.selection.FILTER_IGNORE
end)
:done(function(selector, box)
_radiant.call(‘stonehearth:server_box_transplant_resources’, box)
response:resolve(true)
end)
:fail(function(selector)
response:reject(‘no region’)
end)
:go()
end

function ResourceCallHandler:server_box_transplant_resources(session, response, box)
local cube = Cube3(Point3(box.min.x, box.min.y, box.min.z),
Point3(box.max.x, box.max.y, box.max.z))

local entities = radiant.terrain.get_entities_in_cube(cube)

for _, entity in pairs(entities) do
local renewable = entity:get_component(‘stonehearth:renewable_resource_node’)
if renewable then
bt_log:debug(‘renewable: %s’, entity)
else
bt_log:debug(‘non-renewable: %s’, entity)
end
end
end[/code]

But I’m finding it less simple to actually do something useful. For now, all I mean to do is stick something into that if renewable block to have each item pop to the cursor in turn (though it would be nice to sort entities by type beforehand if practical). AFAICT I just need to find a way to make use of the PlaceItemCallHandler class or maybe just some of its functions. But I don’t know how to make use of a call handler from within a call handler, if that’s even possible or appropriate, or if it’s actually much more complicated than that. Any suggestions would be appreciated.

1 Like

This would be a useful too to have :smile:

After further studying the code I get the impression I’m going about this all wrong. :’(

I thought that aside from adding the button I would only need to deal with lua, but the core function of the entire process - choose_place_item_location - seems to require communication with the js side of things in a way I’m nowhere near close to wrapping my head around.