Jump to content

Building placement area tweaking


Recommended Posts

Hello all,

First of all, I wasn't able to find similar topics with the searching tools and I apologies if a similar topic has been already raised. It's not about making geometric placement vanilla. It's more about tweaking the allowed building area for new structure. Because the current one is kind of broken.

Main example: You are not able to build a farm next to a wall. But you CAN build walls/ next to a farm. Even on top of it.

Screen to illustrate the issue (here, I use geometric placement to show the allowed building area):

Spoiler

placement1.thumb.png.8e140d2f800884e02b4c378f13be8654.png

placement2.thumb.png.95161a0d98a67edcf068280789710bd2.png

placement3.png.e1398a3ae87b32fa50233ab9ad7b6b7e.png

In order to make this farm, I have to destroy the walls, build the farm, then rebuild the walls around it, which is kind of silly and waste some resources (which car be a pain when using thulecite/moonrock walls). Of course, this happen to other construction, like grass/twigs, etc...

I think there's a mod that kinda fix that issue (realistic placement) but if I'm correct, it change the actual allowed area, I admit that I've never took the time to test it. It's also not a really really important tweak. And if I'm correct, having a lot of building in a confined area make the game laggy. But I wanted to discuss this with you.

Finally, If you have a link to a similar subject, a mod or something else related, I'd be glad to check it.

Have a nice day.

 

 

This happens because of how works DS and DST building. There are 3 types of structures: Small (Potted Succulent, Mini-Sign), Normal (Chests, Walls) and Big (Any other structure really). Small ones can be builded everywhere, normal ones close, but not too much and big ones takes medium distance between any structure. I wish small/normal structures didn't taken more place that they actually do, its really feels like ancient bug everyone just accepts.

Indeed, and after more research I have found more than 3 types actually (here's a list with some example): 

   - Tiny(can be put anywhere): Mini sign (I guess this is the only one of his kind)
   - very small(anywhere but in the point of other building, let's say Radius = 0): Replica relic disc, walls
   - small(Radius = 1): Potted plant, chest.
   - Low medium(R = 2): Scarecrow, fridge, mushlight, ...
   - Medium(R=4): mush planter
   - Large(R=6): crock pot, beebox, drying rack, science machine etc...

Here are the screen to illustrate them (I didn't check ALL structures

Spoiler

area1.jpg.138d352ea273f54803622a13eeb48596.jpgarea2.jpg.c2d9df6151e6f925b315e2651a4ff8b8.jpgarea3.jpg.77e6139dc178b278064be5f0ca1cda56.jpgarea4.jpg.81ab7537ac5ab6f6a1d3dc05f447b498.jpgarea5.jpg.03b490b779b6823c5851178b80494c67.jpgarea6.jpg.76dbef29cf579b1ab2eaea65dc640141.jpg

The existence of these types and which structure are put in those is not the issue here.

The issue is: When you want to build a structure of type X, the radius Rx of that structure is used for all structures around (as an example, on the last screenshot above, you can see that when building a crockpot, the radius of the crockpot (R=6 here) is used around all structures, even the minisign).

I guess this is for performance reason. It's easier to take as a variable the current object than reading the type for each structure nearby. But I don't think this is an impossible task to do either. I mean, the position of each structure are already checked, why not check the type as well?

I will do some research in the code itself. Maybe this is modable. 

EDIT:

Ok I get some info from the prefabs and code. There is 4 "type" of spacing:

From constants.lua

DEPLOYSPACING =
{
    DEFAULT = 0,
    MEDIUM = 1,
    LESS = 2,
    NONE = 3,
	PLACER_DEFAULT = 4,
}

And the mini_sign, is in fact an exception:

from prefabs/minisign.lua:

        inst.components.deployable.min_spacing = 0

And there's is also some other exceptions, like the tooth traps with a value of .75.

I will continue my reading, I think that the key is in component/deployable.lua.

Hello again, I have some good news.

I managed to understand how it works (partially at least) and even coded a little mod as a proof of concept. As you can see on the screen below, when building, the allowed area is calculated with the min_spacing of the entities around, not the min_spacing of the recipe itself.

Spoiler

spacing_fix.thumb.jpg.7ba5dc6dde1f21c1543c15f045872b1c.jpg

So, for some explanation of how it works:

  • When you Build a recipe (from the crafting tab like the fridge):
    The Class function Builder:CanBuildAtPoint from "components/builder_replica.lua" is used to check if you can build at point, which only invoke the function Map:CanDeployRecipeAtPoint from "components/map.lua". This one do some check about the ground and recipe specific check and finally use Map:IsDeployPointClear.
  • When you deploy an item (from the inventory like the minisign)
    The function Deployable:CanDeploy who will use the correct deploy function related to the item type (like a wall, a turf etc..) which always check is the point is clear with Map:IsDeployPointClear

As you can see, the only function that matter here is Map:IsDeployPointClear which takes the minimum spacing min_spacing of the recipe/deployable item as an argument (see below the function).

This function find all entities in a radius of min_spacing and then check if it's not too close with the Map:IsNearOther by default. The only thing to change here is the min_spacing_sq normally computed with the min_spacing of the recipe/item and used for each entities. To "fix" it, we just need to compute that min_spacing_sq with the min_spacing of the entities, something like that:

Spoiler

function Map:IsDeployPointClear(pt, inst, min_spacing, min_spacing_sq_fn, near_other_fn)
+  local recipe_min_spacing_sq = min_spacing ~= nil and min_spacing * min_spacing or nil   -- <<---change here
-   local min_spacing_sq = min_spacing ~= nil and min_spacing * min_spacing or nil
    near_other_fn = near_other_fn or IsNearOther
    for i, v in ipairs(TheSim:FindEntities(pt.x, 0, pt.z, math.max(DEPLOY_EXTRA_SPACING, min_spacing), nil, DEPLOY_IGNORE_TAGS)) do
+      local entity_spacing = GetEntityMinSpacing(v)                                                                                                              -- <<<-- and here
+      local min_spacing_sq = entity_spacing ~= nil and entity_spacing * entity_spacing or recipe_min_spacing_sq            --     <<-- and here
        if v ~= inst and
            v.entity:IsVisible() and
            v.components.placer == nil and
            v.entity:GetParent() == nil and
            near_other_fn(v, pt, min_spacing_sq_fn ~= nil and min_spacing_sq_fn(v) or min_spacing_sq) then
            return false
        end
    end
    return true
end

 

Note that this is not the way that I have done it in my mod. Because I wasn't able to change a function of the component Map (I tried with the classic AppComponentPostInit). I feel that it's a particular component because I've seen their function called only in the form of TheWorld.Map:... is there a way to change the function of Map:IsDeployPointClear in modmain.lua? Because of that, my mod change the Builder:CanBuildAtPoint function, in a really dirty way.

(By the way, I wonder if it will not be easier to use that min_spacing_sq_fn argument to do the fix, since it use the entity "v" as argument, to be investigate)

The main trick here is the GetEntityMinSpacing(v) that will fetch the min_spacing of the entities nearby. For now I was only able to fetch it for building entities, not for the deployable. For these, I feel that there is a way with the inst.replica.inventoryitem:DeploySpacingRadius(). But I wasn't able to find a link between the entity and its inventoryitem instance, I still investigate and will be back if I find something. I will also try to find a way to modify directly the Map:IsDeployPointClear. Do you have any idea about how to do it ?

SamuelD

 

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...