Jump to content

Recommended Posts

Hello, My idea is the machine will auto turn on when plants nearby has water percent lower than X... And my question is how to check that water percent.
 
i know the standard process is find the entity first then check it and set conditions. But i dont sure find what, tile soil or plants... I have tried on plant but is'nt seem right and for the soil im completely stuck. Please help! thank you.
 
local function checkWaterOfPlant(inst)
 
    local x,y,z = inst.Transform:GetWorldPosition()
    local plantNeedWater = TheSim:FindEntities(x,y,z, RANGE, nil, nil, "farm_plant")
 
    if plantNeedWater.??? <= 0.1 then
        inst.components.machine:TurnOn()
    elseif plantNeedWater.??? > 0.99 then
        inst.components.machine:TurnOff()
    end
 
end
 

If you need the exact value for the soil, there's no choice but to upvalue hack the farming_manager component's _moisturegrid table (example: my mod here.)

Your alternatives are to check if the soil is moist at all using:

local function test_fn(plant)
    if TheWorld.components.farming_manager:IsSoilMoistAtPoint(plant.Transform:GetWorldPosition()) then
        return true
    end
end

or check if the plant is currently demanding water using:

local function test_fn(plant)
    local ps = plant.components.farmplantstress
    if ps and ps.stressors.moisture and ps.stressors_testfns.moisture and --has moisture need
        ps.stressors_testfns.moisture(plant, ps.stressors.moisture, false) and --moisture need is unmet
        (not plant.components.growable or plant.components.growable:GetCurrentStageData().tendable) --only growing plants can be satisfied
            return true
    end
end

Be aware that your plantNeedWater is a table and would need to be iterated with a loop. It would be better to just use FindEntity:

local ent = FindEntity(inst, RANGE, test_fn, {"farm_plant"}, {"farm_plant_killjoy"})

if ent then
    inst.components.machine:TurnOn()
else
    inst.components.machine:TurnOff()
end
Edited by Bumber64
  • GL Happy 1

I tried your code and it succeeded in finding the entity. But another problem is that I enforce the condition in the prefab file.

I put this in in prefabfn:

    inst:DoPeriodicTask(0, checkWaterOfPlants)

and the result is a machine that repeats "TurnOn" endlessly or say it's not really "TurnOn". And "TurnOff" also. Am i wrong to use DoPeriodicTask and if it, how can i excute this

local ent = FindEntity(inst, RANGE, test_fn, {"farm_plant"}, {"farm_plant_killjoy"})

if ent then
    inst.components.machine:TurnOn()
else
    inst.components.machine:TurnOff()
end

Thank you again and honestly i'm kinda new in lua :D 

I would use 1 for the time (same as ice flingomatic) instead of 0 (lots of unnecessary calculations.) You can also save the task as a variable in case you want to cancel it for some reason (e.g., the machine is damaged.)

inst.checkTask = inst:DoPeriodicTask(1, checkWaterOfPlants)

--To cancel:
if inst.checkTask then
    inst.checkTask:Cancel()
    inst.checkTask = nil
end

Looks like Machine:TurnOn doesn't check if it's already on, so we should do that:

local ent = FindEntity(inst, RANGE, test_fn, {"farm_plant"}, {"farm_plant_killjoy"})

local m = inst.components.machine
if not m.ison and ent then --we're off and a plant needs water
    m:TurnOn()
elseif m.ison then --we're on and no plants need water
    m:TurnOff()
end --else we're currently in the proper state and do nothing

I also forgot to account for Wormwood planting crops outside soil, which doesn't have non-rain moisture:

local function test_fn(plant)
    local x,y,z = plant.Transform:GetWorldPosition()
    if TheWorld.Map:GetTile(TheWorld.Map:GetTileCoordsAtPoint(x,y,z)) == WORLD_TILES.FARMING_SOIL and
        TheWorld.components.farming_manager:IsSoilMoistAtPoint(x,y,z) then
            return true
    end
end

or

local function test_fn(plant)
    local ps = plant.components.farmplantstress
    if ps and ps.stressors.moisture and ps.stressors_testfns.moisture and --has moisture need
        ps.stressors_testfns.moisture(plant, ps.stressors.moisture, false) and --moisture need is unmet
        (not plant.components.growable or plant.components.growable:GetCurrentStageData().tendable) and --only growing plants can be satisfied
        TheWorld.Map:GetTile(TheWorld.Map:GetTileCoordsAtPoint(plant.Transform:GetWorldPosition())) == WORLD_TILES.FARMING_SOIL then --on soil
            return true
    end
end
  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...