diff --git a/.timetracker b/.timetracker index a8c1ff1..ef2524d 100644 --- a/.timetracker +++ b/.timetracker @@ -1,5 +1,5 @@ { - "total": 602351, + "total": 605357, "sessions": [ { "begin": "2026-01-09T17:26:02+01:00", @@ -1360,6 +1360,11 @@ "begin": "2026-03-21T01:43:25+01:00", "end": "2026-03-21T04:23:47+01:00", "duration": 9621 + }, + { + "begin": "2026-03-22T03:01:07+01:00", + "end": "2026-03-22T03:51:14+01:00", + "duration": 3006 } ] } \ No newline at end of file diff --git a/OrekiWoofsBeehives/Behaviors/BlockEntityBehaviorBeehiveYieldMultiplier.cs b/OrekiWoofsBeehives/Behaviors/BlockEntityBehaviorBeehiveYieldMultiplier.cs index 97b6281..2cd840a 100644 --- a/OrekiWoofsBeehives/Behaviors/BlockEntityBehaviorBeehiveYieldMultiplier.cs +++ b/OrekiWoofsBeehives/Behaviors/BlockEntityBehaviorBeehiveYieldMultiplier.cs @@ -57,12 +57,13 @@ public class BlockEntityBehaviorBeehiveYieldMultiplier(BlockEntity blockEntity) } } + private readonly BlockPos _onServerTickBlockPos = new(0); private void OnServerTick(float dt) { if (Blockentity.Block is not BlockFarmland) return; - BlockPos cropPos = Blockentity.Pos.UpCopy(); + BlockPos cropPos = _onServerTickBlockPos.Set(Blockentity.Pos.X, Blockentity.Pos.Y + 1, Blockentity.Pos.Z); if (Api.World.BlockAccessor.GetBlock(cropPos) is not BlockCrop crop) { ClearTracking(); diff --git a/OrekiWoofsBeehives/BlockEntities/BlockEntityBeeSwarm.cs b/OrekiWoofsBeehives/BlockEntities/BlockEntityBeeSwarm.cs index 770d9ba..5d70247 100644 --- a/OrekiWoofsBeehives/BlockEntities/BlockEntityBeeSwarm.cs +++ b/OrekiWoofsBeehives/BlockEntities/BlockEntityBeeSwarm.cs @@ -354,9 +354,12 @@ public class BlockEntityBeeSwarm : BlockEntity return targetHive.AddBeePopulationFromSwarm(amount); } + private readonly List _findEligibleTargetsList = []; + private readonly BlockPos _findEligibleTargetsBlockPos = new(0); private List FindEligibleTargets() { - var candidates = new List(); + var candidates = _findEligibleTargetsList; + candidates.Clear(); var cfg = Config.Instance; var radius = Math.Max(1, cfg.BeehiveRadius); @@ -365,7 +368,7 @@ public class BlockEntityBeeSwarm : BlockEntity { foreach (var pos in modSystem.BeehiveRegistry.BeehivePositions) { - var targetPos = new BlockPos(pos.X, pos.Y, pos.Z); + var targetPos = _findEligibleTargetsBlockPos.Set(pos.X, pos.Y, pos.Z); if (targetPos.Equals(OriginHivePos) || targetPos.Equals(Pos)) continue; diff --git a/OrekiWoofsBeehives/BlockEntities/BlockEntityReusableBeehive.cs b/OrekiWoofsBeehives/BlockEntities/BlockEntityReusableBeehive.cs index c8d13cc..4136044 100644 --- a/OrekiWoofsBeehives/BlockEntities/BlockEntityReusableBeehive.cs +++ b/OrekiWoofsBeehives/BlockEntities/BlockEntityReusableBeehive.cs @@ -223,7 +223,7 @@ public class BlockEntityReusableBeehive : BlockEntityContainer return; double hoursPerDay = Api.World.Calendar.HoursPerDay; - double daysElapsed = hoursElapsed / hoursPerDay; + double daysElapsed; var maxDaysSkip = 0.3; var maxHoursSkip = maxDaysSkip * hoursPerDay; diff --git a/OrekiWoofsBees.Common/PlantPositionRegistryModSystem2.cs b/OrekiWoofsBees.Common/PlantPositionRegistryModSystem2.cs index 5dee948..2613354 100644 --- a/OrekiWoofsBees.Common/PlantPositionRegistryModSystem2.cs +++ b/OrekiWoofsBees.Common/PlantPositionRegistryModSystem2.cs @@ -15,6 +15,8 @@ namespace OrekiWoofsBees.Common; /// public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry { + private readonly static BlockPos staticBlockPos = new(0); + private const int default_blocks_per_tick = 20; private const int tick_interval_ms = 20; @@ -231,21 +233,20 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry cursor.Advance(); - var block = accessor.GetBlock(blockPos); - var structPos = new StructVec3i(blockPos.X, blockPos.Y, blockPos.Z); + var block = accessor.GetBlock(staticBlockPos.Set(blockPos.X, blockPos.Y, blockPos.Z)); if (block == null || block.BlockId == 0) { // block is air or unloaded - remove from caches if present - flowerPositions.Remove(structPos); - cropPositions.Remove(structPos); + flowerPositions.Remove(blockPos); + cropPositions.Remove(blockPos); continue; } // check if this is soil with soil below - mark as soil floor if (block is BlockSoil) { - var blockBelow = accessor.GetBlock(blockPos.DownCopy()); + var blockBelow = accessor.GetBlockRaw(blockPos.X, blockPos.Y - 1, blockPos.Z); if (blockBelow is BlockSoil) { // found soil floor - record it @@ -263,18 +264,18 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry if (PlantRecognitionUtilities.IsCrop(block)) { - cropPositions.Add(structPos); - flowerPositions.Remove(structPos); + cropPositions.Add(blockPos); + flowerPositions.Remove(blockPos); } else if (PlantRecognitionUtilities.IsFlower(block, accessor, blockPos)) { - flowerPositions.Add(structPos); - cropPositions.Remove(structPos); + flowerPositions.Add(blockPos); + cropPositions.Remove(blockPos); } else { - flowerPositions.Remove(structPos); - cropPositions.Remove(structPos); + flowerPositions.Remove(blockPos); + cropPositions.Remove(blockPos); } } @@ -290,7 +291,7 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry /// 2. pick the closest horizontal space vertically /// 3. check the next closest block to the beehive in this horizontal space /// - private (BeehiveScanCursor Cursor, BlockPos BlockPos)? GetNextBlockToCheck() + private (BeehiveScanCursor Cursor, StructVec3i BlockPos)? GetNextBlockToCheck() { if (beehives.Count == 0) return null; @@ -327,9 +328,9 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry } else { - var beehivesList = beehives.Values.ToList(); + var beehivesList = beehives.Values; lastScannedBeehiveIndex = (lastScannedBeehiveIndex + 1) % beehivesList.Count; - bestCursor = beehivesList[lastScannedBeehiveIndex]; + bestCursor = beehivesList.ElementAt(lastScannedBeehiveIndex); } if (bestCursor == null) @@ -350,15 +351,14 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry private int currentIndex = 0; - public BlockPos GetCurrentBlockPos(Dictionary tables) + public StructVec3i GetCurrentBlockPos(Dictionary tables) { var table = tables[Radius]; var (X, Y, Z) = table.GetOffset(currentIndex); - return new BlockPos( + return new( HivePos.X + X, HivePos.Y + Y, - HivePos.Z + Z, - HivePos.dimension + HivePos.Z + Z ); } diff --git a/OrekiWoofsBees.Common/PlantRecognitionUtilities.cs b/OrekiWoofsBees.Common/PlantRecognitionUtilities.cs index 5b9f765..90ca3c9 100644 --- a/OrekiWoofsBees.Common/PlantRecognitionUtilities.cs +++ b/OrekiWoofsBees.Common/PlantRecognitionUtilities.cs @@ -6,6 +6,8 @@ namespace OrekiWoofsBees.Common; public static class PlantRecognitionUtilities { + private static readonly BlockPos blockPos = new(0); + public static bool IsCrop(Block block) { return block is BlockCrop; @@ -38,8 +40,12 @@ public static class PlantRecognitionUtilities return false; } + public static bool IsFlower(Block block, IBlockAccessor accessor, StructVec3i pos) => IsFlower(block, accessor, blockPos.Set(pos.X, pos.Y, pos.Z)); + public static bool IsPlant(Block block, IBlockAccessor accessor, BlockPos pos) { return IsCrop(block) || IsFlower(block, accessor, pos); } + + public static bool IsPlant(Block block, IBlockAccessor accessor, StructVec3i pos) => IsPlant(block, accessor, blockPos.Set(pos.X, pos.Y, pos.Z)); } diff --git a/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorBeeSwarm.cs b/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorBeeSwarm.cs index e8e41ef..e010f90 100644 --- a/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorBeeSwarm.cs +++ b/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorBeeSwarm.cs @@ -40,6 +40,8 @@ public class BlockEntityBehaviorBeeSwarm(BlockEntity blockEntity) : BlockEntityB private double hangingDurationHours = 5.0; private double migrationPhaseDurationHours = 5.0; + private Vec3d windVec = new(1, 0, 0); + public int ActiveBeesCount => activeBees.Count; public int ActiveHoveringCount => activeBees.Count(b => b.Role == BeeRole.Hovering); public int ActiveTravelingCount => activeBees.Count(b => b.Role == BeeRole.Traveling); @@ -77,9 +79,15 @@ public class BlockEntityBehaviorBeeSwarm(BlockEntity blockEntity) : BlockEntityB var updateFrequency = 20; if (api.Side == EnumAppSide.Server) updateFrequency *= server_tick_frequency_decrease; + Blockentity.RegisterGameTickListener(UpdateWindSpeed, 10000); Blockentity.RegisterGameTickListener(OnTick, updateFrequency); } + private void UpdateWindSpeed(float dt) + { + windVec = Api.World.BlockAccessor.GetWindSpeedAt(Blockentity.Pos); + } + private void BuildHoverSurfaceMap() { shapeElements = ComputeShapeElements(); @@ -316,7 +324,6 @@ public class BlockEntityBehaviorBeeSwarm(BlockEntity blockEntity) : BlockEntityB ReadSwarmAttributesFromBlockEntity(); - var windVec = Api.World.BlockAccessor.GetWindSpeedAt(Blockentity.Pos); var windSpeed = (float)Math.Min(windVec.Length(), 1.0); for (int i = activeBees.Count - 1; i >= 0; i--) diff --git a/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorRoamingBees.cs b/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorRoamingBees.cs index d1a9a7b..8f875c6 100644 --- a/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorRoamingBees.cs +++ b/RoamingBees/RoamingBees/Behaviors/BlockEntityBehaviorRoamingBees.cs @@ -37,6 +37,9 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti private float temperature; private bool initialized; + private ClimateCondition? climate; + private Vec3d? windVec; + private readonly List flowerPositions = []; private readonly List cropPositions = []; private readonly List relativePlantPositions = []; @@ -83,6 +86,13 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti if (api.Side == EnumAppSide.Server) updateFrequency *= SERVER_TICK_FREQUENCY_DECREASE; Blockentity.RegisterGameTickListener(OnParticleTick, updateFrequency); + Blockentity.RegisterGameTickListener(UpdateClimateInfo, 10000); + } + + private void UpdateClimateInfo(float dt) + { + windVec = Api.World.BlockAccessor.GetWindSpeedAt(Blockentity.Pos); + climate = Api.World.BlockAccessor.GetClimateAt(Blockentity.Pos, EnumGetClimateMode.NowValues); } private int GetRadiusFromBlockEntity() @@ -230,11 +240,12 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti { if (dt > 10f) return; - dt = Math.Min(0.5f, dt); - var windVec = Api.World.BlockAccessor.GetWindSpeedAt(Blockentity.Pos); + if (climate is null || windVec is null) + return; + + dt = Math.Min(0.5f, dt); var windSpeed = (float)Math.Min(windVec.Length(), 1.0); - var climate = Api.World.BlockAccessor.GetClimateAt(Blockentity.Pos, EnumGetClimateMode.NowValues); rainfall = climate?.Rainfall ?? 0f; temperature = climate?.Temperature ?? 20f; @@ -391,7 +402,15 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti InitialScanProgress = initialScanProgress; RescanProgress = rescanProgress; - foreach (var pos in flowerPositions.Concat(cropPositions)) + foreach (var pos in flowerPositions) + { + float relX = pos.X - Blockentity.Pos.X + 0.5f; + float relY = pos.Y - Blockentity.Pos.Y + 0.5f; + float relZ = pos.Z - Blockentity.Pos.Z + 0.5f; + relativePlantPositions.Add(new Vector3(relX, relY, relZ)); + } + + foreach (var pos in cropPositions) { float relX = pos.X - Blockentity.Pos.X + 0.5f; float relY = pos.Y - Blockentity.Pos.Y + 0.5f;