Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Substrate/BlockEntities/BlockEntityFruitingBag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ internal float Fertility
}
private float _fertility = -1;

private bool RequiresCellarForCultivation => SubstrateModSystem.Config.RequireCellarForCultivation;
private int MaxCultivationLightLevel => SubstrateModSystem.Config.MaxCultivationLightLevel;
private bool IsInCellar() => CellarUtil.IsInCellar(Api, Pos);
private BlockPos LightCheckPos => Block is BlockGrowBed ? Pos.UpCopy() : Pos;
private int CurrentLightLevel => Api.World.BlockAccessor.GetLightLevel(LightCheckPos, EnumLightLevelType.MaxLight);
private bool IsLightLevelSuitable() => CurrentLightLevel <= MaxCultivationLightLevel;
private bool CanCultivateHere() => (!RequiresCellarForCultivation || IsInCellar()) && IsLightLevelSuitable();

public override void Initialize(ICoreAPI api)
{
base.Initialize(api);
Expand Down Expand Up @@ -134,6 +142,12 @@ private void Tick(float deltaTime)
{
if (Api.Side != EnumAppSide.Server || !Inoculated) return;

if (!CanCultivateHere())
{
_lastColonizeProgressTimestamp = 0;
return;
}

if (Fertility <= 0)
{
_inoculatedMushroom = null;
Expand Down Expand Up @@ -209,6 +223,19 @@ public bool OnInteract(IWorldAccessor world, IPlayer byPlayer, BlockSelection bl
return false;
}

if (!CanCultivateHere())
{
if (Api is ICoreClientAPI capi)
{
var errorCode = !IsLightLevelSuitable() ? "requires-darkness" : "requires-cellar";
var message = !IsLightLevelSuitable()
? Lang.Get("substrate:notice-too-bright-for-cultivation", MaxCultivationLightLevel)
: Lang.Get("substrate:notice-requires-cellar");
capi.TriggerIngameError(this, errorCode, message);
}
return false;
}

_inoculatedMushroom = mushroomVariant;
_colonizeDuration = NextColonizeIncrement();

Expand Down Expand Up @@ -250,6 +277,10 @@ public override void GetBlockInfo(IPlayer forPlayer, StringBuilder dsc)
dsc.AppendLine(Lang.Get("substrate:fruitingbag-remaining-fertility", Fertility / MaxFertility * 100));
if (GetOpenFaceCount() == 0)
dsc.AppendLine(Lang.Get("substrate:notice-no-available-grow-spots"));
if (RequiresCellarForCultivation && !IsInCellar())
dsc.AppendLine(Lang.Get("substrate:notice-requires-cellar"));
if (!IsLightLevelSuitable())
dsc.AppendLine(Lang.Get("substrate:notice-too-bright-for-cultivation", MaxCultivationLightLevel));
}
else
{
Expand Down
8 changes: 8 additions & 0 deletions Substrate/Config/SubstrateConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Substrate.Config
{
public class SubstrateConfig
{
public bool RequireCellarForCultivation { get; set; } = true;
public int MaxCultivationLightLevel { get; set; } = 8;
}
}
7 changes: 6 additions & 1 deletion Substrate/SubstrateModSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Substrate.Behaviors;
using Substrate.BlockEntities;
using Substrate.Blocks;
using Substrate.Config;
using Substrate.Utils;
using Substrate.Utils.CodecPattern;
using Substrate.Utils.CodecPattern.Codecs;
Expand All @@ -21,12 +22,16 @@ namespace Substrate
{
public class SubstrateModSystem : ModSystem
{
internal static ILogger Logger { get; private set; }
internal static ILogger? Logger { get; private set; }
internal static SubstrateConfig Config { get; private set; } = new();

// Called on server and client
// Useful for registering block/entity classes on both sides
public override void Start(ICoreAPI api)
{
Config = api.LoadModConfig<SubstrateConfig>("SubstrateConfig.json") ?? new SubstrateConfig();
api.StoreModConfig(Config, "SubstrateConfig.json");

api.RegisterBlockClass("BlockFruitingBag", typeof(BlockFruitingBag));
api.RegisterBlockClass("BlockGrowBed", typeof(BlockGrowBed));
api.RegisterBlockEntityClass("FruitingBag", typeof(BlockEntityFruitingBag));
Expand Down
33 changes: 33 additions & 0 deletions Substrate/Utils/CellarUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using Vintagestory.API.Common;
using Vintagestory.API.MathTools;
using Vintagestory.GameContent;

namespace Substrate.Utils
{
internal static class CellarUtil
{
// Determines if the BlockPos is within a cellar
// This mirrors the vanilla logic for determining a cellar
// but unfortunately there seems to be no API that directly asks
// for if something is a cellar or not, we are just allowed to query
// the room properties and copy what vanilla does.
public static bool IsInCellar(ICoreAPI api, BlockPos pos)
{
try
{
var roomRegistry = api.ModLoader.GetModSystem<RoomRegistry>();
var room = roomRegistry?.GetRoomForPosition(pos);
if (room == null) return false;

return room.ExitCount == 0 && room.NonSkylightCount > 0;
}
catch (Exception ex)
{
SubstrateModSystem.Logger?.Warning($"Cellar detection failed: {ex.Message}");
api.Logger.Warning($"Cellar detection failed: {ex.Message}");
return true;
}
}
}
}
4 changes: 3 additions & 1 deletion Substrate/assets/substrate/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
"notice-moldy": "The substrate has <font color=\"orange\">molded</font>! Break to recycle.",
"notice-no-available-grow-spots": "<font color=\"orange\">Lack of space to grow is causing fertility waste!</font>",
"notice-cannot-grow-mushroom-with-block": "{0} can only grow in a {1}!",
"notice-requires-cellar": "Mushroom cultivation must be done in a cellar.",
"notice-too-bright-for-cultivation": "It is too bright for mushroom cultivation here. Light level must be {0} or lower.",

"fruitingbag-insert-sporeprint": "Add Spore Print",
"fruitingbag-insert-substrate": "Add Substrate",
Expand Down Expand Up @@ -163,4 +165,4 @@
"mushroom-libertycap": "Liberty Cap",
"mushroom-sickener": "Sickener",
"mushroom-wavycap": "Wavy Cap"
}
}