Compare commits
18 Commits
v2.0.0-dev
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a1f3f16bf | |||
| 44e0ea15ff | |||
| 3f928fa4bc | |||
| 136826aa68 | |||
| c5d34ec1b5 | |||
| d7ca3f8e99 | |||
| b8e356cb23 | |||
| 6813ac84d0 | |||
| afdf3425b0 | |||
| 0f1bcece53 | |||
| b3b262b208 | |||
| a87825df6d | |||
| 3fca34a009 | |||
| 3c02539207 | |||
| 1776a26374 | |||
| 7126ae4f88 | |||
| 8f68b140bf | |||
| bcd4d34111 |
137
.timetracker
137
.timetracker
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"total": 625681,
|
"total": 676860,
|
||||||
"sessions": [
|
"sessions": [
|
||||||
{
|
{
|
||||||
"begin": "2026-01-09T17:26:02+01:00",
|
"begin": "2026-01-09T17:26:02+01:00",
|
||||||
@@ -1415,6 +1415,141 @@
|
|||||||
"begin": "2026-03-29T08:19:40+02:00",
|
"begin": "2026-03-29T08:19:40+02:00",
|
||||||
"end": "2026-03-29T09:38:35+02:00",
|
"end": "2026-03-29T09:38:35+02:00",
|
||||||
"duration": 4734
|
"duration": 4734
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-03-30T00:33:23+02:00",
|
||||||
|
"end": "2026-03-30T01:23:09+02:00",
|
||||||
|
"duration": 2986
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-04-07T22:11:37+02:00",
|
||||||
|
"end": "2026-04-07T22:37:52+02:00",
|
||||||
|
"duration": 1575
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-22T16:05:00+02:00",
|
||||||
|
"end": "2026-05-22T16:20:11+02:00",
|
||||||
|
"duration": 911
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-22T16:20:15+02:00",
|
||||||
|
"end": "2026-05-22T16:43:59+02:00",
|
||||||
|
"duration": 1424
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-22T16:47:46+02:00",
|
||||||
|
"end": "2026-05-22T17:08:18+02:00",
|
||||||
|
"duration": 1231
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-22T17:36:43+02:00",
|
||||||
|
"end": "2026-05-22T17:36:52+02:00",
|
||||||
|
"duration": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-23T02:43:28+02:00",
|
||||||
|
"end": "2026-05-23T03:08:51+02:00",
|
||||||
|
"duration": 1523
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-23T03:10:56+02:00",
|
||||||
|
"end": "2026-05-23T03:44:31+02:00",
|
||||||
|
"duration": 2015
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T04:17:33+02:00",
|
||||||
|
"end": "2026-05-24T04:42:36+02:00",
|
||||||
|
"duration": 1503
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T05:43:24+02:00",
|
||||||
|
"end": "2026-05-24T06:28:26+02:00",
|
||||||
|
"duration": 2702
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T06:28:37+02:00",
|
||||||
|
"end": "2026-05-24T06:48:38+02:00",
|
||||||
|
"duration": 1201
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T06:50:13+02:00",
|
||||||
|
"end": "2026-05-24T06:50:54+02:00",
|
||||||
|
"duration": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T06:51:03+02:00",
|
||||||
|
"end": "2026-05-24T06:53:00+02:00",
|
||||||
|
"duration": 116
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T06:53:21+02:00",
|
||||||
|
"end": "2026-05-24T08:00:35+02:00",
|
||||||
|
"duration": 4033
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T08:00:36+02:00",
|
||||||
|
"end": "2026-05-24T08:36:26+02:00",
|
||||||
|
"duration": 2150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T08:36:27+02:00",
|
||||||
|
"end": "2026-05-24T08:51:27+02:00",
|
||||||
|
"duration": 900
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T08:51:27+02:00",
|
||||||
|
"end": "2026-05-24T10:42:30+02:00",
|
||||||
|
"duration": 6662
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T10:42:30+02:00",
|
||||||
|
"end": "2026-05-24T10:45:32+02:00",
|
||||||
|
"duration": 181
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T10:45:43+02:00",
|
||||||
|
"end": "2026-05-24T11:14:02+02:00",
|
||||||
|
"duration": 1698
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T12:55:01+02:00",
|
||||||
|
"end": "2026-05-24T13:15:18+02:00",
|
||||||
|
"duration": 1217
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-24T13:16:44+02:00",
|
||||||
|
"end": "2026-05-24T13:38:36+02:00",
|
||||||
|
"duration": 1312
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T02:37:48+02:00",
|
||||||
|
"end": "2026-05-25T02:57:49+02:00",
|
||||||
|
"duration": 1201
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T04:46:47+02:00",
|
||||||
|
"end": "2026-05-25T05:48:38+02:00",
|
||||||
|
"duration": 3710
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T05:48:38+02:00",
|
||||||
|
"end": "2026-05-25T07:50:07+02:00",
|
||||||
|
"duration": 7288
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T07:57:23+02:00",
|
||||||
|
"end": "2026-05-25T08:19:38+02:00",
|
||||||
|
"duration": 1334
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T08:27:09+02:00",
|
||||||
|
"end": "2026-05-25T08:50:02+02:00",
|
||||||
|
"duration": 1373
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "2026-05-25T09:06:05+02:00",
|
||||||
|
"end": "2026-05-25T09:20:50+02:00",
|
||||||
|
"duration": 884
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
23
.vscode/launch.json
vendored
Normal file
23
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Vintage Story Client (Beehives)",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
"projectPath": "${workspaceFolder}/OrekiWoofsBeehives/OrekiWoofsBeehives.csproj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vintage Story Client (RoamingBees)",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
"projectPath": "${workspaceFolder}/RoamingBees/RoamingBees/RoamingBees.csproj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vintage Story Client (Beehives + RoamingBees)",
|
||||||
|
"type": "dotnet",
|
||||||
|
"request": "launch",
|
||||||
|
"projectPath": "${workspaceFolder}/OrekiWoofsBees.Full/OrekiWoofsBees.Full.csproj"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
50
.vscode/tasks.json
vendored
Normal file
50
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "check env",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "if [ \"${input:buildConfig}\" = \"Version22\" ]; then [ -n \"$VINTAGE_STORY_22\" ] || { echo 'ERROR: VINTAGE_STORY_22 is not set'; exit 1; }; [ -n \"$VINTAGE_STORY_DATA_22\" ] || { echo 'ERROR: VINTAGE_STORY_DATA_22 is not set'; exit 1; }; else [ -n \"$VINTAGE_STORY_21\" ] || { echo 'ERROR: VINTAGE_STORY_21 is not set'; exit 1; }; [ -n \"$VINTAGE_STORY_DATA_21\" ] || { echo 'ERROR: VINTAGE_STORY_DATA_21 is not set'; exit 1; }; fi",
|
||||||
|
"windows": {
|
||||||
|
"command": "if ('${input:buildConfig}' -eq 'Version22') { if (-not $env:VINTAGE_STORY_22) { Write-Host 'ERROR: VINTAGE_STORY_22 is not set'; exit 1 }; if (-not $env:VINTAGE_STORY_DATA_22) { Write-Host 'ERROR: VINTAGE_STORY_DATA_22 is not set'; exit 1 } } else { if (-not $env:VINTAGE_STORY_21) { Write-Host 'ERROR: VINTAGE_STORY_21 is not set'; exit 1 }; if (-not $env:VINTAGE_STORY_DATA_21) { Write-Host 'ERROR: VINTAGE_STORY_DATA_21 is not set'; exit 1 } }"
|
||||||
|
},
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build mod",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"dependsOn": ["check env"],
|
||||||
|
"dependsOrder": "sequence",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${input:buildProject}",
|
||||||
|
"-c",
|
||||||
|
"${input:buildConfig}",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"id": "buildConfig",
|
||||||
|
"type": "pickString",
|
||||||
|
"description": "Build configuration",
|
||||||
|
"options": ["Debug", "Release", "Version22"],
|
||||||
|
"default": "Debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "buildProject",
|
||||||
|
"type": "pickString",
|
||||||
|
"description": "Project to build",
|
||||||
|
"options": [
|
||||||
|
"${workspaceFolder}/OrekiWoofsBeehives/OrekiWoofsBeehives.csproj",
|
||||||
|
"${workspaceFolder}/RoamingBees/RoamingBees/RoamingBees.csproj",
|
||||||
|
"${workspaceFolder}/OrekiWoofsBees.Full/OrekiWoofsBees.Full.csproj"
|
||||||
|
],
|
||||||
|
"default": "${workspaceFolder}/OrekiWoofsBees.Full/OrekiWoofsBees.Full.csproj"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<Solution>
|
<Solution>
|
||||||
<Configurations>
|
<Configurations>
|
||||||
<BuildType Name="Debug22" />
|
<BuildType Name="Version22" />
|
||||||
<BuildType Name="Debug" />
|
<BuildType Name="Debug" />
|
||||||
<BuildType Name="Release" />
|
<BuildType Name="Release" />
|
||||||
</Configurations>
|
</Configurations>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
</Folder>
|
</Folder>
|
||||||
<Project Path="OrekiWoofsBeehives/OrekiWoofsBeehives.csproj" />
|
<Project Path="OrekiWoofsBeehives/OrekiWoofsBeehives.csproj" />
|
||||||
<Project Path="OrekiWoofsBees.Common/OrekiWoofsBees.Common.csproj" Id="e53bd51a-4c0e-4482-9e20-1361d42e72ea">
|
<Project Path="OrekiWoofsBees.Common/OrekiWoofsBees.Common.csproj" Id="e53bd51a-4c0e-4482-9e20-1361d42e72ea">
|
||||||
<BuildType Solution="Debug22|*" Project="Release" />
|
<BuildType Solution="Version22|*" Project="Release" />
|
||||||
</Project>
|
</Project>
|
||||||
<Project Path="RoamingBees/RoamingBees/RoamingBees.csproj" Id="7f545210-d3d4-4232-b6d6-7a10be19290c" />
|
<Project Path="RoamingBees/RoamingBees/RoamingBees.csproj" Id="7f545210-d3d4-4232-b6d6-7a10be19290c" />
|
||||||
<Project Path="RoamingBees/ZZCakeBuild/RoamingBeesCakeBuild.csproj" Id="742949f3-29ab-48ef-bb9a-903055795dfb" />
|
<Project Path="RoamingBees/ZZCakeBuild/RoamingBeesCakeBuild.csproj" Id="742949f3-29ab-48ef-bb9a-903055795dfb" />
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class BlockBehaviorBeehiveAffected(Block block) : BlockBehavior(block)
|
|||||||
: " " + Lang.Get("orekiwoofsbeehives:blockinfo-as-a-plant", GetLocalizedPlantTypeText(isFlower, isCrop));
|
: " " + Lang.Get("orekiwoofsbeehives:blockinfo-as-a-plant", GetLocalizedPlantTypeText(isFlower, isCrop));
|
||||||
|
|
||||||
var inRangeText = Lang.Get("orekiwoofsbeehives:blockinfo-in-range-beehive", beehiveCount);
|
var inRangeText = Lang.Get("orekiwoofsbeehives:blockinfo-in-range-beehive", beehiveCount);
|
||||||
return inRangeText + growthOrPlantText;
|
return '\n' + inRangeText + growthOrPlantText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetLocalizedPlantTypeText(bool isFlower, bool isCrop)
|
private static string GetLocalizedPlantTypeText(bool isFlower, bool isCrop)
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public readonly record struct BeehiveStats
|
|||||||
currentTemperature += 5;
|
currentTemperature += 5;
|
||||||
|
|
||||||
if (OrekiWoofsBeehivesModSystem.IsSteadyGreenhousesLoaded)
|
if (OrekiWoofsBeehivesModSystem.IsSteadyGreenhousesLoaded)
|
||||||
return Math.Max(currentTemperature, Config.Instance.MaxTemperatureGrowth);
|
return Math.Max(currentTemperature, Config.Instance.TemperatureOptimal);
|
||||||
|
|
||||||
return currentTemperature;
|
return currentTemperature;
|
||||||
}
|
}
|
||||||
@@ -113,13 +113,13 @@ public readonly record struct BeehiveStats
|
|||||||
{
|
{
|
||||||
var cfg = Config.Instance;
|
var cfg = Config.Instance;
|
||||||
|
|
||||||
if (currentTemperature >= cfg.MaxTemperatureGrowth)
|
if (currentTemperature >= cfg.TemperatureOptimal)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
if (currentTemperature <= cfg.MinTemperatureGrowth)
|
if (currentTemperature <= cfg.TemperatureMinimum)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
float temperatureRange = cfg.MaxTemperatureGrowth - cfg.MinTemperatureGrowth;
|
float temperatureRange = cfg.TemperatureOptimal - cfg.TemperatureMinimum;
|
||||||
return (currentTemperature - cfg.MinTemperatureGrowth) / temperatureRange;
|
return (currentTemperature - cfg.TemperatureMinimum) / temperatureRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double CalculateFramesPerDay(BlockEntityReusableBeehive beehive, double temperatureMultiplier)
|
private static double CalculateFramesPerDay(BlockEntityReusableBeehive beehive, double temperatureMultiplier)
|
||||||
@@ -161,16 +161,16 @@ public readonly record struct BeehiveStats
|
|||||||
private static double GetWinterReverseRamp(float currentTemperature)
|
private static double GetWinterReverseRamp(float currentTemperature)
|
||||||
{
|
{
|
||||||
var cfg = Config.Instance;
|
var cfg = Config.Instance;
|
||||||
if (currentTemperature >= cfg.MaxTemperatureGrowth)
|
if (currentTemperature >= cfg.TemperatureOptimal)
|
||||||
return 0;
|
return 0;
|
||||||
if (currentTemperature <= cfg.MinTemperatureGrowth)
|
if (currentTemperature <= cfg.TemperatureMinimum)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
float temperatureRange = cfg.MaxTemperatureGrowth - cfg.MinTemperatureGrowth;
|
float temperatureRange = cfg.TemperatureOptimal - cfg.TemperatureMinimum;
|
||||||
if (temperatureRange <= 0)
|
if (temperatureRange <= 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 1.0 - ((currentTemperature - cfg.MinTemperatureGrowth) / temperatureRange);
|
return 1.0 - ((currentTemperature - cfg.TemperatureMinimum) / temperatureRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double GetEffectiveFlowers(BlockEntityReusableBeehive beehive)
|
private static double GetEffectiveFlowers(BlockEntityReusableBeehive beehive)
|
||||||
|
|||||||
@@ -295,19 +295,19 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
Disperse();
|
Disperse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartMigrating(double nowHours, BlockPos targetPos, bool targetIsVanillaSkep, string? targetPopulatedSkepCode)
|
private void StartMigrating(double nowHours, StructVec3i targetPos, bool targetIsVanillaSkep, string? targetPopulatedSkepCode)
|
||||||
{
|
{
|
||||||
StopCandidateRefresh();
|
StopCandidateRefresh();
|
||||||
SwarmState = SwarmState.MigratingToNewHive;
|
SwarmState = SwarmState.MigratingToNewHive;
|
||||||
stateStartTotalHours = nowHours;
|
stateStartTotalHours = nowHours;
|
||||||
migrationStartPopulation = Population;
|
migrationStartPopulation = Population;
|
||||||
transferredDuringMigration = 0;
|
transferredDuringMigration = 0;
|
||||||
this.targetPos = targetPos.Copy();
|
this.targetPos = targetPos.ToBlockPos();
|
||||||
this.targetIsVanillaSkep = targetIsVanillaSkep;
|
this.targetIsVanillaSkep = targetIsVanillaSkep;
|
||||||
this.targetPopulatedSkepCode = targetPopulatedSkepCode;
|
this.targetPopulatedSkepCode = targetPopulatedSkepCode;
|
||||||
retryDay = -1;
|
retryDay = -1;
|
||||||
|
|
||||||
if (!targetIsVanillaSkep && Api.World.BlockAccessor.GetBlockEntity(targetPos) is BlockEntityReusableBeehive targetHive)
|
if (!targetIsVanillaSkep && Api.World.BlockAccessor.GetBlockEntity(this.targetPos) is BlockEntityReusableBeehive targetHive)
|
||||||
targetHive.SetIncomingSwarm(Pos);
|
targetHive.SetIncomingSwarm(Pos);
|
||||||
|
|
||||||
MarkDirty(false);
|
MarkDirty(false);
|
||||||
@@ -382,7 +382,7 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var score = CalculateBeehiveTargetScore(hive, targetPos, radius);
|
var score = CalculateBeehiveTargetScore(hive, targetPos, radius);
|
||||||
candidates.Add(new SwarmTargetCandidate(targetPos, false, score, null));
|
candidates.Add(new SwarmTargetCandidate(StructVec3i.FromBlockPos(targetPos), false, score, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var score = CalculateSkepTargetScore(targetPos, radius);
|
var score = CalculateSkepTargetScore(targetPos, radius);
|
||||||
candidates.Add(new SwarmTargetCandidate(targetPos, true, score, entry.Value));
|
candidates.Add(new SwarmTargetCandidate(StructVec3i.FromBlockPos(targetPos), true, score, entry.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,13 +411,13 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryConvertSkepToPopulated(BlockPos pos, string populatedCode)
|
private bool TryConvertSkepToPopulated(StructVec3i pos, string populatedCode)
|
||||||
{
|
{
|
||||||
var block = Api.World.GetBlock(new AssetLocation(populatedCode));
|
var block = Api.World.GetBlock(new AssetLocation(populatedCode));
|
||||||
if (block == null || block.Id == 0)
|
if (block == null || block.Id == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Api.World.BlockAccessor.ExchangeBlock(block.BlockId, pos);
|
Api.World.BlockAccessor.ExchangeBlock(block.BlockId, pos.ToBlockPos());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,6 +612,7 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
tree.SetBlockPos("targetPos", targetPos);
|
tree.SetBlockPos("targetPos", targetPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly BlockPos _tempBlockPos = new(0, 0, 0);
|
||||||
private TreeArrayAttribute BuildCandidateHivesTreeArray()
|
private TreeArrayAttribute BuildCandidateHivesTreeArray()
|
||||||
{
|
{
|
||||||
if (targetHiveCandidates == null)
|
if (targetHiveCandidates == null)
|
||||||
@@ -622,7 +623,8 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var entry = new TreeAttribute();
|
var entry = new TreeAttribute();
|
||||||
entry.SetBlockPos("pos", targetHiveCandidates[i].Pos);
|
_tempBlockPos.Set(targetHiveCandidates[i].Pos.X, targetHiveCandidates[i].Pos.Y, targetHiveCandidates[i].Pos.Z);
|
||||||
|
entry.SetBlockPos("pos", _tempBlockPos); // safe, as internally does 3x SetInt
|
||||||
entries[i] = entry;
|
entries[i] = entry;
|
||||||
}
|
}
|
||||||
return new TreeArrayAttribute(entries);
|
return new TreeArrayAttribute(entries);
|
||||||
@@ -659,5 +661,5 @@ public class BlockEntityBeeSwarm : BlockEntity
|
|||||||
Api.GetOrekiWoofsBeehives()?.BroadcastUnloadDebug(message);
|
Api.GetOrekiWoofsBeehives()?.BroadcastUnloadDebug(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly record struct SwarmTargetCandidate(BlockPos Pos, bool IsVanillaSkep, double Score, string? PopulatedSkepCode);
|
private readonly record struct SwarmTargetCandidate(StructVec3i Pos, bool IsVanillaSkep, double Score, string? PopulatedSkepCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
|
|
||||||
private readonly Stopwatch stopwatch = new();
|
private readonly Stopwatch stopwatch = new();
|
||||||
private readonly StringBuilder infoStringBuilder = new();
|
private readonly StringBuilder infoStringBuilder = new();
|
||||||
private readonly InventoryGeneric inventory;
|
private readonly InventoryGeneric inventory = new(8, null, null);
|
||||||
private double lastUpdateTotalHours = 0;
|
private double lastUpdateTotalHours = 0;
|
||||||
private bool wasFullyScanned;
|
private bool wasFullyScanned;
|
||||||
private float? scanningProgress;
|
private float? scanningProgress;
|
||||||
@@ -32,6 +32,7 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
private bool isInGreenhouse;
|
private bool isInGreenhouse;
|
||||||
private BlockPos? activeSwarmPos;
|
private BlockPos? activeSwarmPos;
|
||||||
private BlockPos? incomingSwarmPos;
|
private BlockPos? incomingSwarmPos;
|
||||||
|
private int? registeredRadius;
|
||||||
|
|
||||||
public override InventoryBase Inventory => inventory;
|
public override InventoryBase Inventory => inventory;
|
||||||
public override string InventoryClassName => "beehive";
|
public override string InventoryClassName => "beehive";
|
||||||
@@ -53,11 +54,6 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
|
|
||||||
public Mod? Mod { get; private set; }
|
public Mod? Mod { get; private set; }
|
||||||
|
|
||||||
public BlockEntityReusableBeehive()
|
|
||||||
{
|
|
||||||
inventory = new InventoryGeneric(8, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsOpen { get; set; }
|
public bool IsOpen { get; set; }
|
||||||
|
|
||||||
public override void Initialize(ICoreAPI api)
|
public override void Initialize(ICoreAPI api)
|
||||||
@@ -82,6 +78,7 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
plantPositionRegistry.RegisterBeehive(Pos, Config.Instance.BeehiveRadius);
|
plantPositionRegistry.RegisterBeehive(Pos, Config.Instance.BeehiveRadius);
|
||||||
|
registeredRadius = Config.Instance.BeehiveRadius;
|
||||||
|
|
||||||
var beehivesModSystem = Api.GetOrekiWoofsBeehives();
|
var beehivesModSystem = Api.GetOrekiWoofsBeehives();
|
||||||
if (beehivesModSystem is null)
|
if (beehivesModSystem is null)
|
||||||
@@ -152,10 +149,35 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
stopwatch.LogTime(this, 0.05, "after flowers and crops");
|
stopwatch.LogTime(this, 0.05, "after flowers and crops");
|
||||||
UpdateBeePopulationAndHoney();
|
UpdateBeePopulationAndHoney();
|
||||||
stopwatch.LogTime(this, 0.05, "after population and honey");
|
stopwatch.LogTime(this, 0.05, "after population and honey");
|
||||||
|
UpdateRadius();
|
||||||
|
|
||||||
stopwatch.StopAndLogTime(this, 0.05);
|
stopwatch.StopAndLogTime(this, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateRadius()
|
||||||
|
{
|
||||||
|
if (registeredRadius == Config.Instance.BeehiveRadius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scanningProgress = 0;
|
||||||
|
rescanningProgress = 0;
|
||||||
|
FlowersAround = null;
|
||||||
|
CropsAround = null;
|
||||||
|
wasFullyScanned = false;
|
||||||
|
|
||||||
|
var plantPositionRegistry = Api.GetPlantPositionRegistry();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
plantPositionRegistry?.UpdateBeehiveRadius(Pos, Config.Instance.BeehiveRadius);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Mod?.Logger.Warning("Couldn't update radius");
|
||||||
|
Mod?.Logger.Warning(e);
|
||||||
|
}
|
||||||
|
registeredRadius = Config.Instance.BeehiveRadius;
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearStaleIncomingSwarmReservation()
|
private void ClearStaleIncomingSwarmReservation()
|
||||||
{
|
{
|
||||||
if (incomingSwarmPos == null)
|
if (incomingSwarmPos == null)
|
||||||
@@ -309,7 +331,7 @@ public class BlockEntityReusableBeehive : BlockEntityContainer, IModEntity
|
|||||||
var cfg = Config.Instance;
|
var cfg = Config.Instance;
|
||||||
var ratePerHour = 1.0 / Math.Max(1, cfg.PreSwarmDurationHours);
|
var ratePerHour = 1.0 / Math.Max(1, cfg.PreSwarmDurationHours);
|
||||||
|
|
||||||
if (stats.Components.Temperature >= cfg.MaxTemperatureGrowth)
|
if (stats.Components.Temperature >= cfg.TemperatureOptimal)
|
||||||
PreSwarmProgress += ratePerHour * hoursElapsed;
|
PreSwarmProgress += ratePerHour * hoursElapsed;
|
||||||
else
|
else
|
||||||
PreSwarmProgress -= ratePerHour * hoursElapsed;
|
PreSwarmProgress -= ratePerHour * hoursElapsed;
|
||||||
|
|||||||
@@ -527,9 +527,9 @@ public class BlockReusableBeehive : Block
|
|||||||
return baseColor;
|
return baseColor;
|
||||||
|
|
||||||
if (IsFilledFeedFrame(be.Inventory[slotIndex].Itemstack))
|
if (IsFilledFeedFrame(be.Inventory[slotIndex].Itemstack))
|
||||||
return new Vec4f(0.8f, 0.2f, 0f, baseColor.A);
|
return new Vec4f(0.8f / 3f, 0.2f / 3f, 0f, baseColor.A);
|
||||||
|
|
||||||
return new Vec4f(0.6f, 0.3f, 0f, baseColor.A);
|
return new Vec4f(0.2f, 0.1f, 0f, baseColor.A);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsFrame(ItemStack? stack)
|
private static bool IsFrame(ItemStack? stack)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class Config
|
|||||||
|
|
||||||
[ProtoMember(57)]
|
[ProtoMember(57)]
|
||||||
[ConfigCommand(serverSide: true)]
|
[ConfigCommand(serverSide: true)]
|
||||||
public bool SwarmSettingAfterPlacing { get; set; } = false;
|
public bool SwarmSettingAfterPlacing { get; set; } = true;
|
||||||
|
|
||||||
[ProtoMember(5)]
|
[ProtoMember(5)]
|
||||||
[ConfigCommand(serverSide: true, Min = 0, Max = 1000)]
|
[ConfigCommand(serverSide: true, Min = 0, Max = 1000)]
|
||||||
@@ -142,11 +142,11 @@ public class Config
|
|||||||
// weather effects
|
// weather effects
|
||||||
[ProtoMember(15)]
|
[ProtoMember(15)]
|
||||||
[ConfigCommand(serverSide: true, Min = -20, Max = 20)]
|
[ConfigCommand(serverSide: true, Min = -20, Max = 20)]
|
||||||
public float MinTemperatureGrowth { get; set; } = 0f;
|
public float TemperatureMinimum { get; set; } = 0f;
|
||||||
|
|
||||||
[ProtoMember(16)]
|
[ProtoMember(16)]
|
||||||
[ConfigCommand(serverSide: true, Min = 0, Max = 40)]
|
[ConfigCommand(serverSide: true, Min = 0, Max = 40)]
|
||||||
public float MaxTemperatureGrowth { get; set; } = 10f;
|
public float TemperatureOptimal { get; set; } = 10f;
|
||||||
|
|
||||||
[ProtoMember(35)]
|
[ProtoMember(35)]
|
||||||
[ConfigCommand(serverSide: true)]
|
[ConfigCommand(serverSide: true)]
|
||||||
@@ -164,7 +164,7 @@ public class Config
|
|||||||
// client-side
|
// client-side
|
||||||
[ProtoMember(29)]
|
[ProtoMember(29)]
|
||||||
[ConfigCommand(serverSide: false, Min = 0, Max = 4)]
|
[ConfigCommand(serverSide: false, Min = 0, Max = 4)]
|
||||||
public int InformationVerbosity { get; set; } = 1;
|
public int InformationVerbosity { get; set; } = 2;
|
||||||
|
|
||||||
[ProtoMember(44)]
|
[ProtoMember(44)]
|
||||||
[ConfigCommand(serverSide: false)]
|
[ConfigCommand(serverSide: false)]
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public static class BeehiveInfoStringBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cfg = Config.Instance;
|
var cfg = Config.Instance;
|
||||||
var isIncreasing = stats.Components.Temperature >= cfg.MaxTemperatureGrowth;
|
var isIncreasing = stats.Components.Temperature >= cfg.TemperatureOptimal;
|
||||||
|
|
||||||
string detail;
|
string detail;
|
||||||
if (isIncreasing)
|
if (isIncreasing)
|
||||||
@@ -337,9 +337,9 @@ public static class BeehiveInfoStringBuilder
|
|||||||
|
|
||||||
if (verbosity is >= 1 and < 3)
|
if (verbosity is >= 1 and < 3)
|
||||||
{
|
{
|
||||||
if (temperature <= cfg.MinTemperatureGrowth)
|
if (temperature <= cfg.TemperatureMinimum)
|
||||||
builder.AppendLine(Lang.Get("orekiwoofsbeehives:beehive-info-temperature-overwintering"));
|
builder.AppendLine(Lang.Get("orekiwoofsbeehives:beehive-info-temperature-overwintering"));
|
||||||
else if (temperature < cfg.MaxTemperatureGrowth)
|
else if (temperature < cfg.TemperatureOptimal)
|
||||||
builder.AppendLine(Lang.Get("orekiwoofsbeehives:beehive-info-temperature-cold"));
|
builder.AppendLine(Lang.Get("orekiwoofsbeehives:beehive-info-temperature-cold"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -356,7 +356,7 @@ public static class BeehiveInfoStringBuilder
|
|||||||
|
|
||||||
if (cfg.WinterHardMode
|
if (cfg.WinterHardMode
|
||||||
&& stats.Components.FilledFramesCount <= 0
|
&& stats.Components.FilledFramesCount <= 0
|
||||||
&& temperature <= cfg.MinTemperatureGrowth)
|
&& temperature <= cfg.TemperatureMinimum)
|
||||||
builder.AppendLine($"<font color=\"#ff0000\">{Lang.Get("orekiwoofsbeehives:beehive-info-winter-starving")}</font>");
|
builder.AppendLine($"<font color=\"#ff0000\">{Lang.Get("orekiwoofsbeehives:beehive-info-winter-starving")}</font>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,11 @@ public partial class OrekiWoofsBeehivesModSystem : ModSystem
|
|||||||
Config.Instance ??= new Config();
|
Config.Instance ??= new Config();
|
||||||
|
|
||||||
ConvertOldCropBonus(oldCropBonus, Config.Instance);
|
ConvertOldCropBonus(oldCropBonus, Config.Instance);
|
||||||
|
var temperatureMigrated = ConvertBackCompatibilityTemperature(api, Config.Instance);
|
||||||
|
|
||||||
api.StoreModConfig(Config.Instance, config_filename);
|
api.StoreModConfig(Config.Instance, config_filename);
|
||||||
|
|
||||||
if (oldCropBonus is not null && api.ModLoader.IsModEnabled("configlib"))
|
if ((oldCropBonus is not null || temperatureMigrated) && api.ModLoader.IsModEnabled("configlib"))
|
||||||
ReloadConfigForConfigLib(api);
|
ReloadConfigForConfigLib(api);
|
||||||
|
|
||||||
api.Event.PlayerJoin += OnPlayerJoin;
|
api.Event.PlayerJoin += OnPlayerJoin;
|
||||||
@@ -176,4 +177,33 @@ public partial class OrekiWoofsBeehivesModSystem : ModSystem
|
|||||||
|
|
||||||
Mod.Logger.Event($"Converted CropBonus:{cropBonus} to YieldBoost:{config.YieldBoost}, SpeedBoost:{config.SpeedBoost}");
|
Mod.Logger.Event($"Converted CropBonus:{cropBonus} to YieldBoost:{config.YieldBoost}, SpeedBoost:{config.SpeedBoost}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ConvertBackCompatibilityTemperature(ICoreAPI api, Config config)
|
||||||
|
{
|
||||||
|
const string old_min_temperature_growth_key = "MinTemperatureGrowth";
|
||||||
|
const string old_max_temperature_growth_key = "MaxTemperatureGrowth";
|
||||||
|
|
||||||
|
var cfgJson = api.LoadModConfig(config_filename);
|
||||||
|
if (cfgJson is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var migrated = false;
|
||||||
|
|
||||||
|
if (!cfgJson.KeyExists(nameof(Config.TemperatureMinimum)) && cfgJson.KeyExists(old_min_temperature_growth_key))
|
||||||
|
{
|
||||||
|
config.TemperatureMinimum = cfgJson[old_min_temperature_growth_key].AsFloat(config.TemperatureMinimum);
|
||||||
|
migrated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cfgJson.KeyExists(nameof(Config.TemperatureOptimal)) && cfgJson.KeyExists(old_max_temperature_growth_key))
|
||||||
|
{
|
||||||
|
config.TemperatureOptimal = cfgJson[old_max_temperature_growth_key].AsFloat(config.TemperatureOptimal);
|
||||||
|
migrated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (migrated)
|
||||||
|
Mod.Logger.Event($"Converted legacy temperature config values to TemperatureMinimum:{config.TemperatureMinimum}, TemperatureOptimal:{config.TemperatureOptimal}");
|
||||||
|
|
||||||
|
return migrated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,16 @@
|
|||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<OutputPath>bin\$(Configuration)\Mods\orekiwoofsbeehives</OutputPath>
|
<OutputPath>bin\$(Configuration)\Mods\orekiwoofsbeehives</OutputPath>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_21)</VINTAGE_STORY_DATA>
|
||||||
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug22'">
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
<VINTAGE_STORY_DATA Condition="'$(VINTAGE_STORY_DATA_22)' != '' and Exists('$(VINTAGE_STORY_DATA_22)')">$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(VINTAGE_STORY_DATA)' != '' and Exists('$(VINTAGE_STORY_DATA)')">
|
<PropertyGroup Condition="'$(VINTAGE_STORY_DATA)' != '' and Exists('$(VINTAGE_STORY_DATA)')">
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public static class BEFarmland_GetGrowthRate_Patch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG22
|
#if VERSION22
|
||||||
[HarmonyPatch(typeof(BlockEntitySoilNutrition), nameof(BlockEntitySoilNutrition.GetGrowthRate), [typeof(EnumSoilNutrient)])]
|
[HarmonyPatch(typeof(BlockEntitySoilNutrition), nameof(BlockEntitySoilNutrition.GetGrowthRate), [typeof(EnumSoilNutrient)])]
|
||||||
[HarmonyPatchCategory("1.22")]
|
[HarmonyPatchCategory("1.22")]
|
||||||
public static class BESoilNutrition_GetGrowthRate_Patch
|
public static class BESoilNutrition_GetGrowthRate_Patch
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
"beehiveframe-filled-feed": {
|
"beehiveframe-filled-feed": {
|
||||||
"center": "game:block/food/grain/flax"
|
"center": "game:block/food/grain/flax"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"collisionBox": { "x1": 0.125, "y1": 0, "z1": 0.125, "x2": 0.875, "y2": 0.0625, "z2": 0.875 },
|
||||||
|
"selectionBox": { "x1": 0.125, "y1": 0, "z1": 0.125, "x2": 0.875, "y2": 0.0625, "z2": 0.875 }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "name": "Unplaceable" },
|
{ "name": "Unplaceable" },
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"code": "InformationVerbosity",
|
"code": "InformationVerbosity",
|
||||||
"comment": "config-desc-InformationVerbosity",
|
"comment": "config-desc-InformationVerbosity",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"default": 1,
|
"default": 2,
|
||||||
"range": {
|
"range": {
|
||||||
"min": 0,
|
"min": 0,
|
||||||
"max": 4
|
"max": 4
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
"code": "SwarmSettingAfterPlacing",
|
"code": "SwarmSettingAfterPlacing",
|
||||||
"comment": "config-desc-SwarmSettingAfterPlacing",
|
"comment": "config-desc-SwarmSettingAfterPlacing",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "PreSwarmDurationHours",
|
"code": "PreSwarmDurationHours",
|
||||||
@@ -387,8 +387,8 @@
|
|||||||
"title": "Weather Effects"
|
"title": "Weather Effects"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "MinTemperatureGrowth",
|
"code": "TemperatureMinimum",
|
||||||
"comment": "config-desc-MinTemperatureGrowth",
|
"comment": "config-desc-TemperatureMinimum",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default": 0.0,
|
"default": 0.0,
|
||||||
"range": {
|
"range": {
|
||||||
@@ -397,8 +397,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "MaxTemperatureGrowth",
|
"code": "TemperatureOptimal",
|
||||||
"comment": "config-desc-MaxTemperatureGrowth",
|
"comment": "config-desc-TemperatureOptimal",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default": 10.0,
|
"default": 10.0,
|
||||||
"range": {
|
"range": {
|
||||||
|
|||||||
@@ -112,8 +112,8 @@
|
|||||||
"config-desc-WinterHardMode": "Enables winter hard mode for additional winter mechanics.",
|
"config-desc-WinterHardMode": "Enables winter hard mode for additional winter mechanics.",
|
||||||
"config-desc-WinterDailyBeeDeathsWithoutFood": "Extra daily bee deaths in winter when there are no filled/feed frames. Works only with WinterHardMode enabled.",
|
"config-desc-WinterDailyBeeDeathsWithoutFood": "Extra daily bee deaths in winter when there are no filled/feed frames. Works only with WinterHardMode enabled.",
|
||||||
"config-desc-WinterFoodConsumptionMultiplier": "Winter food consumption multiplier (0-1). From 10C to 0C this effect ramps up in reverse relative to honey production; below 0C it stays at max. Works only with WinterHardMode enabled.",
|
"config-desc-WinterFoodConsumptionMultiplier": "Winter food consumption multiplier (0-1). From 10C to 0C this effect ramps up in reverse relative to honey production; below 0C it stays at max. Works only with WinterHardMode enabled.",
|
||||||
"config-desc-MinTemperatureGrowth": "Temperature at which bee growth and honey production stops.",
|
"config-desc-TemperatureMinimum": "Temperature at which bee growth and honey production stops.",
|
||||||
"config-desc-MaxTemperatureGrowth": "Temperature at which bee growth and honey production reaches maximum.",
|
"config-desc-TemperatureOptimal": "Temperature at which bee growth and honey production reaches maximum.",
|
||||||
"config-desc-GreenhouseAffectsBeehive": "Whether greenhouses give 5C temperature boost to the beehive.",
|
"config-desc-GreenhouseAffectsBeehive": "Whether greenhouses give 5C temperature boost to the beehive.",
|
||||||
"config-desc-BeesPerParticle": "Number of bees represented by each particle group. If this is 1000, there are 5000 bees in a beehive, then the beehive will spawn at most 5 particles.",
|
"config-desc-BeesPerParticle": "Number of bees represented by each particle group. If this is 1000, there are 5000 bees in a beehive, then the beehive will spawn at most 5 particles.",
|
||||||
"config-desc-BeehiveAlwaysSpawnNumberOfBees": "Will spawn this amount of bees per beehive block, regardless of their population.",
|
"config-desc-BeehiveAlwaysSpawnNumberOfBees": "Will spawn this amount of bees per beehive block, regardless of their population.",
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
"blockhelp-beehive-enable-swarm": "Enable swarming",
|
"blockhelp-beehive-enable-swarm": "Enable swarming",
|
||||||
"blockhelp-beehive-disable-swarm": "Disable swarming",
|
"blockhelp-beehive-disable-swarm": "Disable swarming",
|
||||||
"config-desc-EnableSwarms": "Whether beehives can produce swarms.",
|
"config-desc-EnableSwarms": "Whether beehives can produce swarms.",
|
||||||
"config-desc-PreSwarmDurationHours": "Duration in hours for bees to build up their swarm urge (0 to 100%). Progress only increases at MaxTemperatureGrowth or higher; otherwise it decreases.",
|
"config-desc-PreSwarmDurationHours": "Duration in hours for bees to build up their swarm urge (0 to 100%). Progress only increases at TemperatureOptimal or higher; otherwise it decreases.",
|
||||||
"config-desc-SwarmSettingAfterPlacing": "Whether a newly placed beehive has swarming enabled or disabled. Can be changed with a wrench.",
|
"config-desc-SwarmSettingAfterPlacing": "Whether a newly placed beehive has swarming enabled or disabled. Can be changed with a wrench.",
|
||||||
"setpopulation-desc": "Set bee population of the beehive block you are currently looking at.",
|
"setpopulation-desc": "Set bee population of the beehive block you are currently looking at.",
|
||||||
"debugunload-desc": "Enable or disable unload catch-up debug messages in server chat.",
|
"debugunload-desc": "Enable or disable unload catch-up debug messages in server chat.",
|
||||||
|
|||||||
@@ -111,8 +111,8 @@
|
|||||||
"config-desc-WinterHardMode": "Включает усложнённый зимний режим с дополнительными зимними механиками.",
|
"config-desc-WinterHardMode": "Включает усложнённый зимний режим с дополнительными зимними механиками.",
|
||||||
"config-desc-WinterDailyBeeDeathsWithoutFood": "Дополнительная ежедневная гибель пчёл зимой, когда нет заполненных/кормовых рамок. Работает только с включенным WinterHardMode.",
|
"config-desc-WinterDailyBeeDeathsWithoutFood": "Дополнительная ежедневная гибель пчёл зимой, когда нет заполненных/кормовых рамок. Работает только с включенным WinterHardMode.",
|
||||||
"config-desc-WinterFoodConsumptionMultiplier": "Коэффициент потребления зимних продуктов питания (0-1). При температуре от 10° C до 0° C этот эффект увеличивается в обратном направлении относительно производства мёда; при температуре ниже 0° C он остается максимальным. Работает только при включенном режиме WinterHardMode.",
|
"config-desc-WinterFoodConsumptionMultiplier": "Коэффициент потребления зимних продуктов питания (0-1). При температуре от 10° C до 0° C этот эффект увеличивается в обратном направлении относительно производства мёда; при температуре ниже 0° C он остается максимальным. Работает только при включенном режиме WinterHardMode.",
|
||||||
"config-desc-MinTemperatureGrowth": "Температура, при которой прекращается рост пчёл и производство мёда.",
|
"config-desc-TemperatureMinimum": "Температура, при которой прекращается рост пчёл и производство мёда.",
|
||||||
"config-desc-MaxTemperatureGrowth": "Температура, при которой рост пчёл и производство мёда достигают максимума.",
|
"config-desc-TemperatureOptimal": "Температура, при которой рост пчёл и производство мёда достигают максимума.",
|
||||||
"config-desc-GreenhouseAffectsBeehive": "Дают ли теплицы повышение температуры в улье на 5°C.",
|
"config-desc-GreenhouseAffectsBeehive": "Дают ли теплицы повышение температуры в улье на 5°C.",
|
||||||
"config-desc-BeesPerParticle": "Количество пчёл, представленных каждой группой частиц. Если это 1000, а в улье 5000 пчёл, тогда улей породит не более 5 частиц.",
|
"config-desc-BeesPerParticle": "Количество пчёл, представленных каждой группой частиц. Если это 1000, а в улье 5000 пчёл, тогда улей породит не более 5 частиц.",
|
||||||
"config-desc-BeehiveAlwaysSpawnNumberOfBees": "Всегда создаёт указанное количество пчёл на блок улья независимо от их численности.",
|
"config-desc-BeehiveAlwaysSpawnNumberOfBees": "Всегда создаёт указанное количество пчёл на блок улья независимо от их численности.",
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
"blockhelp-beehive-enable-swarm": "Включить роение",
|
"blockhelp-beehive-enable-swarm": "Включить роение",
|
||||||
"blockhelp-beehive-disable-swarm": "Отключить роение",
|
"blockhelp-beehive-disable-swarm": "Отключить роение",
|
||||||
"config-desc-EnableSwarms": "Определяет, могут ли ульи выпускать рои.",
|
"config-desc-EnableSwarms": "Определяет, могут ли ульи выпускать рои.",
|
||||||
"config-desc-PreSwarmDurationHours": "Время в часах, за которое у пчёл накапливается готовность к роению (0–100%). Прогресс растёт только при MaxTemperatureGrowth или выше, иначе уменьшается.",
|
"config-desc-PreSwarmDurationHours": "Время в часах, за которое у пчёл накапливается готовность к роению (0–100%). Прогресс растёт только при TemperatureOptimal или выше, иначе уменьшается.",
|
||||||
"config-desc-SwarmSettingAfterPlacing": "Будет ли в только что установленном улье включено или отключено роение. Можно изменить гаечным ключом.",
|
"config-desc-SwarmSettingAfterPlacing": "Будет ли в только что установленном улье включено или отключено роение. Можно изменить гаечным ключом.",
|
||||||
"setpopulation-desc": "Установить численность пчёл в улье, на который вы сейчас смотрите.",
|
"setpopulation-desc": "Установить численность пчёл в улье, на который вы сейчас смотрите.",
|
||||||
"debugunload-desc": "Включить или отключить отладочные сообщения догоняющей обработки после выгрузки в чате сервера.",
|
"debugunload-desc": "Включить или отключить отладочные сообщения догоняющей обработки после выгрузки в чате сервера.",
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"op": "addMerge",
|
||||||
|
"path": "/behaviors",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"name": "Carryable",
|
||||||
|
"properties": {
|
||||||
|
"interactDelay": 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"file": "orekiwoofsbeehives:blocktypes/beehive",
|
||||||
|
"dependsOn": [
|
||||||
|
{
|
||||||
|
"modid": "carryon"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"OrekiWoof"
|
"OrekiWoof"
|
||||||
],
|
],
|
||||||
"description": "Beehive with 8 slots for honey frames. Boosts your plants.",
|
"description": "Beehive with 8 slots for honey frames. Boosts your plants.",
|
||||||
"version": "2.0.0-dev.7",
|
"version": "2.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"game": "1.21.0"
|
"game": "1.21.0"
|
||||||
}
|
}
|
||||||
|
|||||||
54
OrekiWoofsBees.Common/CompatibilityUtil.cs
Normal file
54
OrekiWoofsBees.Common/CompatibilityUtil.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using Vintagestory.API.Common;
|
||||||
|
|
||||||
|
namespace OrekiWoofsBees.Common;
|
||||||
|
|
||||||
|
public static class CompatibilityUtil
|
||||||
|
{
|
||||||
|
private const string fruiting_bush_behavior_name = "BEBehaviorFruitingBush";
|
||||||
|
private const string b_state_field_name = "BState";
|
||||||
|
private const string growthstate_property_name = "Growthstate";
|
||||||
|
private const int flowering_growth_state_value = 2;
|
||||||
|
|
||||||
|
private static System.Func<BlockEntityBehavior, bool>? is_fruiting_bush_flowering_check;
|
||||||
|
|
||||||
|
public static bool IsFruitingBushFlowering(this BlockEntityBehavior behavior)
|
||||||
|
{
|
||||||
|
var behaviorType = behavior.GetType();
|
||||||
|
if (!IsFruitingBushBehaviorType(behaviorType))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var check = is_fruiting_bush_flowering_check ??= BuildIsFruitingBushFloweringCheck(behaviorType);
|
||||||
|
return check(behavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsFruitingBushBehaviorType(Type behaviorType)
|
||||||
|
{
|
||||||
|
for (var type = behaviorType; type is not null; type = type.BaseType)
|
||||||
|
{
|
||||||
|
if (type.Name == fruiting_bush_behavior_name)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static System.Func<BlockEntityBehavior, bool> BuildIsFruitingBushFloweringCheck(Type behaviorType)
|
||||||
|
{
|
||||||
|
var bStateField = behaviorType.GetField(b_state_field_name, BindingFlags.Instance | BindingFlags.Public)!;
|
||||||
|
var growthStateProperty = bStateField.FieldType.GetProperty(growthstate_property_name, BindingFlags.Instance | BindingFlags.Public)!;
|
||||||
|
|
||||||
|
var behaviorParameter = Expression.Parameter(typeof(BlockEntityBehavior), "behavior");
|
||||||
|
var typedBehavior = Expression.Convert(behaviorParameter, behaviorType);
|
||||||
|
var bState = Expression.Field(typedBehavior, bStateField);
|
||||||
|
var growthState = Expression.Property(bState, growthStateProperty);
|
||||||
|
|
||||||
|
var comparison = Expression.Equal(
|
||||||
|
Expression.Convert(growthState, typeof(int)),
|
||||||
|
Expression.Constant(flowering_growth_state_value));
|
||||||
|
|
||||||
|
return Expression.Lambda<System.Func<BlockEntityBehavior, bool>>(comparison, behaviorParameter).Compile();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ namespace OrekiWoofsBees.Common;
|
|||||||
|
|
||||||
public static class DiagnosticsUtil
|
public static class DiagnosticsUtil
|
||||||
{
|
{
|
||||||
public static void StopAndLogTime<T>(
|
public static bool StopAndLogTime<T>(
|
||||||
this Stopwatch stopwatch,
|
this Stopwatch stopwatch,
|
||||||
T instance,
|
T instance,
|
||||||
double totalSecondsThreshold,
|
double totalSecondsThreshold,
|
||||||
@@ -14,7 +14,11 @@ public static class DiagnosticsUtil
|
|||||||
{
|
{
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
if (stopwatch.Elapsed.TotalSeconds >= totalSecondsThreshold)
|
if (stopwatch.Elapsed.TotalSeconds >= totalSecondsThreshold)
|
||||||
|
{
|
||||||
instance.Mod?.Logger.Warning($"{typeof(T).Name}.{callerName} ({note}) took {stopwatch.Elapsed.TotalSeconds:F2}s");
|
instance.Mod?.Logger.Warning($"{typeof(T).Name}.{callerName} ({note}) took {stopwatch.Elapsed.TotalSeconds:F2}s");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LogTime<T>(
|
public static void LogTime<T>(
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public interface IPlantPositionRegistry
|
|||||||
|
|
||||||
void RegisterBeehive(BlockPos pos, int radius);
|
void RegisterBeehive(BlockPos pos, int radius);
|
||||||
|
|
||||||
|
void UpdateBeehiveRadius(BlockPos pos, int radius);
|
||||||
|
|
||||||
void RemovePlantPosition(BlockPos pos, Block block);
|
void RemovePlantPosition(BlockPos pos, Block block);
|
||||||
|
|
||||||
void UnregisterBeehive(BlockPos pos);
|
void UnregisterBeehive(BlockPos pos);
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_21)</VINTAGE_STORY_DATA>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug22'">
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
<VINTAGE_STORY_DATA Condition="'$(VINTAGE_STORY_DATA_22)' != '' and Exists('$(VINTAGE_STORY_DATA_22)')">$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="configlib">
|
<Reference Include="configlib">
|
||||||
<HintPath>E:\Code\VintageStory\configlib_1.10.14\configlib.dll</HintPath>
|
<HintPath>$(VS_CONFIGLIB)</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
|||||||
|
|
||||||
private static readonly Dictionary<int, ScanOffsetTable> offsetTables = [];
|
private static readonly Dictionary<int, ScanOffsetTable> offsetTables = [];
|
||||||
|
|
||||||
|
private readonly Stopwatch getCountsStopwatch = new();
|
||||||
|
private readonly Stopwatch getPlantsStopwatch = new();
|
||||||
private long? tickListenerId;
|
private long? tickListenerId;
|
||||||
private readonly Dictionary<StructVec3i, BeehiveScanCursor> beehives = [];
|
private readonly Dictionary<StructVec3i, BeehiveScanCursor> beehives = [];
|
||||||
private readonly HashSet<StructVec3i> flowerPositions = [];
|
private readonly HashSet<StructVec3i> flowerPositions = [];
|
||||||
@@ -77,6 +79,15 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
|||||||
beehives[key] = new BeehiveScanCursor(pos, radius);
|
beehives[key] = new BeehiveScanCursor(pos, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateBeehiveRadius(BlockPos pos, int radius)
|
||||||
|
{
|
||||||
|
if (!offsetTables.ContainsKey(radius))
|
||||||
|
offsetTables[radius] = new ScanOffsetTable(radius);
|
||||||
|
|
||||||
|
var key = StructVec3i.FromBlockPos(pos);
|
||||||
|
beehives[key] = new BeehiveScanCursor(pos, radius);
|
||||||
|
}
|
||||||
|
|
||||||
public void UnregisterBeehive(BlockPos pos)
|
public void UnregisterBeehive(BlockPos pos)
|
||||||
{
|
{
|
||||||
var key = StructVec3i.FromBlockPos(pos);
|
var key = StructVec3i.FromBlockPos(pos);
|
||||||
@@ -88,6 +99,7 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
|||||||
float RescanProgress
|
float RescanProgress
|
||||||
) GetPlantsNearPosition(BlockPos hivePos, int radius, List<StructVec3i> flowerPositionsBuffer, List<StructVec3i> cropPositionsBuffer)
|
) GetPlantsNearPosition(BlockPos hivePos, int radius, List<StructVec3i> flowerPositionsBuffer, List<StructVec3i> cropPositionsBuffer)
|
||||||
{
|
{
|
||||||
|
getPlantsStopwatch.Restart();
|
||||||
flowerPositionsBuffer.Clear();
|
flowerPositionsBuffer.Clear();
|
||||||
cropPositionsBuffer.Clear();
|
cropPositionsBuffer.Clear();
|
||||||
|
|
||||||
@@ -119,11 +131,13 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
|||||||
rescanProgress = cursor.GetRescanProgress(offsetTables);
|
rescanProgress = cursor.GetRescanProgress(offsetTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPlantsStopwatch.StopAndLogTime(this, 0.1, $"radius: {radius}, in: {initialProgress}, re: {rescanProgress}, totals: {flowerPositions.Count}+{cropPositions.Count}");
|
||||||
return (initialProgress, rescanProgress);
|
return (initialProgress, rescanProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (int FlowerCount, int CropCount, float InitialScanProgress, float RescanProgress) GetPlantCountsNearPosition(BlockPos hivePos, int radius)
|
public (int FlowerCount, int CropCount, float InitialScanProgress, float RescanProgress) GetPlantCountsNearPosition(BlockPos hivePos, int radius)
|
||||||
{
|
{
|
||||||
|
getCountsStopwatch.Restart();
|
||||||
int flowers = 0;
|
int flowers = 0;
|
||||||
foreach (var flowerPos in flowerPositions)
|
foreach (var flowerPos in flowerPositions)
|
||||||
{
|
{
|
||||||
@@ -151,6 +165,7 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
|||||||
rescanProgress = cursor.GetRescanProgress(offsetTables);
|
rescanProgress = cursor.GetRescanProgress(offsetTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCountsStopwatch.StopAndLogTime(this, 0.1, $"radius: {radius}, fl: {flowers}, cr: {crops}, in: {initialProgress}, re: {rescanProgress}, totals: {flowerPositions.Count}+{cropPositions.Count}");
|
||||||
return (flowers, crops, initialProgress, rescanProgress);
|
return (flowers, crops, initialProgress, rescanProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,23 @@ public static class PlantRecognitionUtilities
|
|||||||
|
|
||||||
public static bool IsFlower(Block block, IBlockAccessor accessor, BlockPos pos)
|
public static bool IsFlower(Block block, IBlockAccessor accessor, BlockPos pos)
|
||||||
{
|
{
|
||||||
if (block.FirstCodePart() == "flower")
|
var code = block.FirstCodePart();
|
||||||
|
if (code == "flower")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (code == "fruitingbush")
|
||||||
|
{
|
||||||
|
var blockEntity = accessor.GetBlockEntity(pos);
|
||||||
|
if (blockEntity is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var behavior in blockEntity.Behaviors)
|
||||||
|
{
|
||||||
|
if (behavior.IsFruitingBushFlowering())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (block is BlockPlantContainer)
|
if (block is BlockPlantContainer)
|
||||||
{
|
{
|
||||||
var plantContainer = block.GetBlockEntity<BlockEntityPlantContainer?>(pos);
|
var plantContainer = block.GetBlockEntity<BlockEntityPlantContainer?>(pos);
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ namespace OrekiWoofsBees.Common;
|
|||||||
public readonly record struct StructVec3i(int X, int Y, int Z)
|
public readonly record struct StructVec3i(int X, int Y, int Z)
|
||||||
{
|
{
|
||||||
public static StructVec3i FromBlockPos(BlockPos pos) => new(pos.X, pos.Y, pos.Z);
|
public static StructVec3i FromBlockPos(BlockPos pos) => new(pos.X, pos.Y, pos.Z);
|
||||||
|
|
||||||
|
public BlockPos ToBlockPos() => new(X, Y, Z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||||
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_21)</VINTAGE_STORY_DATA>
|
||||||
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug22'">
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VintageStoryDataPathArgs> --dataPath "..\VintageStoryDataBeehives\Data22"</VintageStoryDataPathArgs>
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(VINTAGE_STORY_DATA)' != '' and Exists('$(VINTAGE_STORY_DATA)')">
|
||||||
|
<VintageStoryDataPathArgs> --dataPath "$(VINTAGE_STORY_DATA)"</VintageStoryDataPathArgs>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="BuildBothMods" BeforeTargets="Build">
|
<Target Name="BuildBothMods" BeforeTargets="Build">
|
||||||
|
|||||||
@@ -39,7 +39,13 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
|
|
||||||
private ClimateCondition? climate;
|
private ClimateCondition? climate;
|
||||||
private Vec3d? windVec;
|
private Vec3d? windVec;
|
||||||
private readonly Stopwatch stopwatch = new();
|
private int? registeredRadius;
|
||||||
|
private int onParticleTickStopwatchTriggerCount;
|
||||||
|
private int spawnStopwatchTriggerCount;
|
||||||
|
private readonly Stopwatch plantInfoStopwatch = new();
|
||||||
|
private readonly Stopwatch particleStopwatch = new();
|
||||||
|
private readonly Stopwatch serverSpawnStopwatch = new();
|
||||||
|
private readonly Stopwatch handleSpawnStopwatch = new();
|
||||||
private readonly List<StructVec3i> flowerPositions = [];
|
private readonly List<StructVec3i> flowerPositions = [];
|
||||||
private readonly List<StructVec3i> cropPositions = [];
|
private readonly List<StructVec3i> cropPositions = [];
|
||||||
private readonly List<Vector3> relativePlantPositions = [];
|
private readonly List<Vector3> relativePlantPositions = [];
|
||||||
@@ -47,7 +53,6 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
public const string TARGET_BEE_PARTICLE_COUNT_ATTRIBUTE = "roamingbees_targetBeeParticleCount";
|
public const string TARGET_BEE_PARTICLE_COUNT_ATTRIBUTE = "roamingbees_targetBeeParticleCount";
|
||||||
public const string RADIUS_ATTRIBUTE = "roamingbees_radius";
|
public const string RADIUS_ATTRIBUTE = "roamingbees_radius";
|
||||||
public const string NETWORK_CHANNEL_NAME = "bee particle spawns";
|
public const string NETWORK_CHANNEL_NAME = "bee particle spawns";
|
||||||
public const int SERVER_TICK_FREQUENCY_DECREASE = 50;
|
|
||||||
|
|
||||||
public int ActiveBeesCount => activeBees.Count;
|
public int ActiveBeesCount => activeBees.Count;
|
||||||
public IEnumerable<BeeSpawnPacket> ActiveBeesPackets => activeBees.Select(x => x.SpawnPacket);
|
public IEnumerable<BeeSpawnPacket> ActiveBeesPackets => activeBees.Select(x => x.SpawnPacket);
|
||||||
@@ -83,12 +88,28 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
plantPositionRegistry = api.GetPlantPositionRegistry();
|
plantPositionRegistry = api.GetPlantPositionRegistry();
|
||||||
var radius = GetRadiusFromBlockEntity();
|
var radius = GetRadiusFromBlockEntity();
|
||||||
plantPositionRegistry?.RegisterBeehive(Blockentity.Pos, radius);
|
plantPositionRegistry?.RegisterBeehive(Blockentity.Pos, radius);
|
||||||
|
registeredRadius = radius;
|
||||||
|
|
||||||
var updateFrequency = 20;
|
var updateFrequency = 20;
|
||||||
if (api.Side == EnumAppSide.Server)
|
|
||||||
updateFrequency *= SERVER_TICK_FREQUENCY_DECREASE;
|
|
||||||
Blockentity.RegisterGameTickListener(OnParticleTick, updateFrequency);
|
Blockentity.RegisterGameTickListener(OnParticleTick, updateFrequency);
|
||||||
Blockentity.RegisterGameTickListener(UpdateClimateInfo, 10000);
|
Blockentity.RegisterGameTickListener(UpdateClimateInfo, 10000);
|
||||||
|
Blockentity.RegisterGameTickListener(DecreaseStopwatchCounts, 60000);
|
||||||
|
if (api.Side.IsServer())
|
||||||
|
{
|
||||||
|
Blockentity.RegisterGameTickListener(OnSpawnTick, 500);
|
||||||
|
Blockentity.RegisterGameTickListener(OnUpdatePlantInfoTick, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DecreaseStopwatchCounts(float dt)
|
||||||
|
{
|
||||||
|
if (spawnStopwatchTriggerCount > 10)
|
||||||
|
modSystem?.Mod.Logger.Warning($"{nameof(spawnStopwatchTriggerCount)} is {spawnStopwatchTriggerCount}");
|
||||||
|
spawnStopwatchTriggerCount = Math.Max(0, spawnStopwatchTriggerCount - 1);
|
||||||
|
|
||||||
|
if (onParticleTickStopwatchTriggerCount > 10)
|
||||||
|
modSystem?.Mod.Logger.Warning($"{nameof(onParticleTickStopwatchTriggerCount)} is {onParticleTickStopwatchTriggerCount}");
|
||||||
|
onParticleTickStopwatchTriggerCount = Math.Max(0, onParticleTickStopwatchTriggerCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateClimateInfo(float dt)
|
private void UpdateClimateInfo(float dt)
|
||||||
@@ -97,13 +118,13 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
climate = Api.World.BlockAccessor.GetClimateAt(Blockentity.Pos, EnumGetClimateMode.NowValues);
|
climate = Api.World.BlockAccessor.GetClimateAt(Blockentity.Pos, EnumGetClimateMode.NowValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly TreeAttribute _tempTreeAttribute = new();
|
||||||
private int GetRadiusFromBlockEntity()
|
private int GetRadiusFromBlockEntity()
|
||||||
{
|
{
|
||||||
var radius = properties[RADIUS_ATTRIBUTE].AsInt(10);
|
var radius = properties[RADIUS_ATTRIBUTE].AsInt(10);
|
||||||
|
_tempTreeAttribute.Clear();
|
||||||
var tree = new TreeAttribute();
|
Blockentity.ToTreeAttributes(_tempTreeAttribute);
|
||||||
Blockentity.ToTreeAttributes(tree);
|
radius = _tempTreeAttribute.GetAsInt(RADIUS_ATTRIBUTE, radius);
|
||||||
radius = tree.GetAsInt(RADIUS_ATTRIBUTE, radius);
|
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +171,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
|
|
||||||
public void HandleBeeParticleSpawn(BeeSpawnPacket packet, bool catchup = false)
|
public void HandleBeeParticleSpawn(BeeSpawnPacket packet, bool catchup = false)
|
||||||
{
|
{
|
||||||
stopwatch.Restart();
|
handleSpawnStopwatch.Restart();
|
||||||
if (Blockentity.Pos != packet.HivePosition)
|
if (Blockentity.Pos != packet.HivePosition)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -189,7 +210,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
for (var i = 0; i < totalDelta / 0.1f; i++)
|
for (var i = 0; i < totalDelta / 0.1f; i++)
|
||||||
bee.Step(0.1f, 0.1f); // todo
|
bee.Step(0.1f, 0.1f); // todo
|
||||||
}
|
}
|
||||||
stopwatch.StopAndLogTime(this, 0.05);
|
handleSpawnStopwatch.StopAndLogTime(this, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
@@ -204,12 +225,43 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
activeBees.Clear();
|
activeBees.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnParticleTick(float dt)
|
private void OnUpdatePlantInfoTick(float dt)
|
||||||
{
|
{
|
||||||
if (Block is BlockSkep && !Config.Instance.EnableOnVanillaSkeps)
|
if (!ShouldTick())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stopwatch.Restart();
|
plantInfoStopwatch.Restart();
|
||||||
|
UpdatePlantInfo();
|
||||||
|
UpdateRadius();
|
||||||
|
|
||||||
|
var note = $"global bees: {modSystem?.GlobalActiveBees}, registered hives: {modSystem?.BeeSpawnPacketDistributor?.SpawnHandlersCount}, radius: {Config.Instance.BeeRoamingRadius}";
|
||||||
|
plantInfoStopwatch.StopAndLogTime(this, 0.1, note);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRadius()
|
||||||
|
{
|
||||||
|
var radius = GetRadiusFromBlockEntity();
|
||||||
|
if (registeredRadius == radius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var plantPositionRegistry = Api.GetPlantPositionRegistry();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
plantPositionRegistry?.UpdateBeehiveRadius(Pos, radius);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Mod?.Logger.Warning("Couldn't update radius");
|
||||||
|
Mod?.Logger.Warning(e);
|
||||||
|
}
|
||||||
|
registeredRadius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldTick()
|
||||||
|
{
|
||||||
|
if (Block is BlockSkep && !Config.Instance.EnableOnVanillaSkeps)
|
||||||
|
return false;
|
||||||
|
|
||||||
var isFgc = Block?.Code?.Domain == "fromgoldencombs";
|
var isFgc = Block?.Code?.Domain == "fromgoldencombs";
|
||||||
var path = Block?.Code?.Path ?? string.Empty;
|
var path = Block?.Code?.Path ?? string.Empty;
|
||||||
var isFgcLangstroth = isFgc && path.Contains("langstrothstack", StringComparison.OrdinalIgnoreCase);
|
var isFgcLangstroth = isFgc && path.Contains("langstrothstack", StringComparison.OrdinalIgnoreCase);
|
||||||
@@ -218,22 +270,37 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
if (isFgcLangstroth)
|
if (isFgcLangstroth)
|
||||||
{
|
{
|
||||||
if (!Config.Instance.EnableOnFgcLangstroth)
|
if (!Config.Instance.EnableOnFgcLangstroth)
|
||||||
return;
|
return false;
|
||||||
if (!HasRequiredLangstrothBase())
|
if (!HasRequiredLangstrothBase())
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFgcCeramic && !Config.Instance.EnableOnFgcCeramic)
|
if (isFgcCeramic && !Config.Instance.EnableOnFgcCeramic)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnParticleTick(float dt)
|
||||||
|
{
|
||||||
|
if (!ShouldTick())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var isFgc = Block?.Code?.Domain == "fromgoldencombs";
|
||||||
|
var path = Block?.Code?.Path ?? string.Empty;
|
||||||
|
var isFgcLangstroth = isFgc && path.Contains("langstrothstack", StringComparison.OrdinalIgnoreCase);
|
||||||
|
var isFgcCeramic = isFgc && path.Contains("ceramicbroodpot", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
particleStopwatch.Restart();
|
||||||
|
|
||||||
entityAttributeSnapshot.Clear();
|
entityAttributeSnapshot.Clear();
|
||||||
Blockentity.ToTreeAttributes(entityAttributeSnapshot);
|
Blockentity.ToTreeAttributes(entityAttributeSnapshot);
|
||||||
|
|
||||||
var targetBeeParticleCount = GetTargetBeeParticleCountFromBlockEntity();
|
var targetBeeParticleCount = GetTargetBeeParticleCountFromBlockEntity();
|
||||||
if (targetBeeParticleCount <= 0)
|
TargetParticleCount = Math.Max(0, targetBeeParticleCount);
|
||||||
|
|
||||||
|
if (TargetParticleCount <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TargetParticleCount = Math.Max(0, targetBeeParticleCount);
|
|
||||||
if (Block is BlockSkep)
|
if (Block is BlockSkep)
|
||||||
TargetParticleCount = Config.Instance.RoamingBeesPerVanillaSkep;
|
TargetParticleCount = Config.Instance.RoamingBeesPerVanillaSkep;
|
||||||
if (isFgcLangstroth)
|
if (isFgcLangstroth)
|
||||||
@@ -241,14 +308,9 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
if (isFgcCeramic)
|
if (isFgcCeramic)
|
||||||
TargetParticleCount = Config.Instance.RoamingBeesPerFgcCeramic;
|
TargetParticleCount = Config.Instance.RoamingBeesPerFgcCeramic;
|
||||||
|
|
||||||
if (Api.Side == EnumAppSide.Server)
|
|
||||||
{
|
|
||||||
UpdatePlantInfo();
|
|
||||||
stopwatch.LogTime(this, 0.05, "after UpdatePlantInfo");
|
|
||||||
}
|
|
||||||
|
|
||||||
Update(dt);
|
Update(dt);
|
||||||
stopwatch.StopAndLogTime(this, 0.05);
|
if (particleStopwatch.StopAndLogTime(this, 0.1, note: $"global bees: {modSystem?.GlobalActiveBees}, registered hives: {modSystem?.BeeSpawnPacketDistributor?.SpawnHandlersCount}"))
|
||||||
|
onParticleTickStopwatchTriggerCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(float dt)
|
private void Update(float dt)
|
||||||
@@ -265,7 +327,10 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
temperature = climate?.Temperature ?? 20f;
|
temperature = climate?.Temperature ?? 20f;
|
||||||
|
|
||||||
// iterate from end to easily remove from list
|
// iterate from end to easily remove from list
|
||||||
for (int i = activeBees.Count - 1; i >= 0; i--)
|
var end = activeBees.Count - 1;
|
||||||
|
end -= onParticleTickStopwatchTriggerCount * 10;
|
||||||
|
|
||||||
|
for (int i = end; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var bee = activeBees[i];
|
var bee = activeBees[i];
|
||||||
|
|
||||||
@@ -276,10 +341,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
BeeVisualParticleRenderer.Spawn(clientWorld, Blockentity.Pos, bee);
|
BeeVisualParticleRenderer.Spawn(clientWorld, Blockentity.Pos, bee);
|
||||||
}
|
}
|
||||||
if (Api.Side == EnumAppSide.Server)
|
if (Api.Side == EnumAppSide.Server)
|
||||||
{
|
bee.Step(dt, windSpeed);
|
||||||
for (var j = 0; j < SERVER_TICK_FREQUENCY_DECREASE; j++)
|
|
||||||
bee.Step(dt / SERVER_TICK_FREQUENCY_DECREASE, windSpeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bee.ShouldBeDespawned && modSystem != null)
|
if (bee.ShouldBeDespawned && modSystem != null)
|
||||||
{
|
{
|
||||||
@@ -289,12 +351,28 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
}
|
}
|
||||||
|
|
||||||
TimeSinceLastSpawn += dt;
|
TimeSinceLastSpawn += dt;
|
||||||
if (Api.Side == EnumAppSide.Server)
|
}
|
||||||
|
|
||||||
|
private void OnSpawnTick(float dt)
|
||||||
|
{
|
||||||
|
if (!ShouldTick())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (climate is null || windVec is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
serverSpawnStopwatch.Restart();
|
||||||
TrySpawnNewBee(TargetParticleCount);
|
TrySpawnNewBee(TargetParticleCount);
|
||||||
|
if (serverSpawnStopwatch.StopAndLogTime(this, 0.1))
|
||||||
|
spawnStopwatchTriggerCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TrySpawnNewBee(int targetParticleCount)
|
private void TrySpawnNewBee(int targetParticleCount)
|
||||||
{
|
{
|
||||||
|
int desiredParticleCount = targetParticleCount;
|
||||||
|
if (activeBees.Count >= desiredParticleCount)
|
||||||
|
return;
|
||||||
|
|
||||||
if (TimeSinceLastSpawn < spawn_cooldown_seconds)
|
if (TimeSinceLastSpawn < spawn_cooldown_seconds)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -305,7 +383,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
|
|
||||||
var sunPos = Api.World.Calendar.GetSunPosition(new Vec3d(Blockentity.Pos.X, Blockentity.Pos.Y, Blockentity.Pos.Z), Api.World.Calendar.TotalDays);
|
var sunPos = Api.World.Calendar.GetSunPosition(new Vec3d(Blockentity.Pos.X, Blockentity.Pos.Y, Blockentity.Pos.Z), Api.World.Calendar.TotalDays);
|
||||||
float sunAltitudeDegrees = MathF.Asin(sunPos.Y) * 180f / GameMath.PI;
|
float sunAltitudeDegrees = MathF.Asin(sunPos.Y) * 180f / GameMath.PI;
|
||||||
if (sunPos.Y <= cfg.SunAltitudeMinDegrees)
|
if (sunAltitudeDegrees <= cfg.SunAltitudeMinDegrees)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rainfall >= cfg.RainfallSpawnStopThreshold)
|
if (rainfall >= cfg.RainfallSpawnStopThreshold)
|
||||||
@@ -318,10 +396,6 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
|||||||
if (modSystem.GlobalActiveBees >= maxGlobal)
|
if (modSystem.GlobalActiveBees >= maxGlobal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int desiredParticleCount = targetParticleCount;
|
|
||||||
if (activeBees.Count >= desiredParticleCount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float sunAltitudeModifier = 1 - Math.Clamp((sunAltitudeDegrees - cfg.SunAltitudeMinDegrees) / cfg.SunAltitudeRangeDegrees, 0f, 1f);
|
float sunAltitudeModifier = 1 - Math.Clamp((sunAltitudeDegrees - cfg.SunAltitudeMinDegrees) / cfg.SunAltitudeRangeDegrees, 0f, 1f);
|
||||||
float sunAltitudeCooldownPenalty = sunAltitudeModifier * cfg.MaxSunAltitudeCooldownPenalty;
|
float sunAltitudeCooldownPenalty = sunAltitudeModifier * cfg.MaxSunAltitudeCooldownPenalty;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ internal class BeeSpawnPacketDistributor(RoamingBeesModSystem modSystem, EnumApp
|
|||||||
private Dictionary<Vector3, IBeeSpawnHandler> spawnHandlers { get; } = [];
|
private Dictionary<Vector3, IBeeSpawnHandler> spawnHandlers { get; } = [];
|
||||||
private Dictionary<Vector3, IBeeSpawnCatchup> catchupHandlers { get; } = [];
|
private Dictionary<Vector3, IBeeSpawnCatchup> catchupHandlers { get; } = [];
|
||||||
|
|
||||||
|
public int SpawnHandlersCount => spawnHandlers.Count;
|
||||||
|
|
||||||
public void Register(BlockPos position, object manager)
|
public void Register(BlockPos position, object manager)
|
||||||
{
|
{
|
||||||
if (manager is IBeeSpawnHandler spawnHandler)
|
if (manager is IBeeSpawnHandler spawnHandler)
|
||||||
|
|||||||
@@ -5,14 +5,16 @@
|
|||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<OutputPath>bin\$(Configuration)\Mods\roamingbees</OutputPath>
|
<OutputPath>bin\$(Configuration)\Mods\roamingbees</OutputPath>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_21)</VINTAGE_STORY_DATA>
|
||||||
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
<VintageStoryDataPathArgs></VintageStoryDataPathArgs>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug22'">
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
<VINTAGE_STORY_DATA Condition="'$(VINTAGE_STORY_DATA_22)' != '' and Exists('$(VINTAGE_STORY_DATA_22)')">$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
<VINTAGE_STORY_DATA>$(VINTAGE_STORY_DATA_22)</VINTAGE_STORY_DATA>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(VINTAGE_STORY_DATA)' != '' and Exists('$(VINTAGE_STORY_DATA)')">
|
<PropertyGroup Condition="'$(VINTAGE_STORY_DATA)' != '' and Exists('$(VINTAGE_STORY_DATA)')">
|
||||||
|
|||||||
@@ -1,52 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"op": "addMerge",
|
|
||||||
"path": "/entityBehaviors",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"name": "BlockEntityBehaviorRoamingBees",
|
|
||||||
"properties": {
|
|
||||||
"facingVariantKey": "",
|
|
||||||
"entrancePositions": {
|
|
||||||
"north": [0.5, 0.1, 0.8],
|
|
||||||
"east": [0.2, 0.1, 0.5],
|
|
||||||
"south": [0.5, 0.1, 0.2],
|
|
||||||
"west": [0.8, 0.1, 0.5]
|
|
||||||
},
|
|
||||||
"frontDirections": {
|
|
||||||
"north": [0, 0, 1],
|
|
||||||
"east": [-1, 0, 0],
|
|
||||||
"south": [0, 0, -1],
|
|
||||||
"west": [1, 0, 0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"file": "fromgoldencombs:blocktypes/ceramicpot/ceramicbroodpot",
|
|
||||||
"side": "Server",
|
|
||||||
"dependsOn": [
|
|
||||||
{
|
|
||||||
"modid": "fromgoldencombs"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"op": "addMerge",
|
|
||||||
"path": "/behaviorsByType/*",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"name": "BlockBehaviorRoamingBees"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"file": "fromgoldencombs:blocktypes/ceramicpot/ceramicbroodpot",
|
|
||||||
"side": "Server",
|
|
||||||
"dependsOn": [
|
|
||||||
{
|
|
||||||
"modid": "fromgoldencombs"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"op": "addMerge",
|
"op": "addMerge",
|
||||||
"path": "/entityBehaviors",
|
"path": "/entityBehaviors",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"OrekiWoof"
|
"OrekiWoof"
|
||||||
],
|
],
|
||||||
"description": "Cute immersive roaming bees. Now on vanilla skeps and other mods' hives.",
|
"description": "Cute immersive roaming bees. Now on vanilla skeps and other mods' hives.",
|
||||||
"version": "2.0.0-dev.7",
|
"version": "2.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"game": "1.21.0"
|
"game": "1.21.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
## 1) ClientSide mode
|
## 1) ClientSide mode
|
||||||
- Server: `InformationVerbosityServerSideType=ClientSide`, `InformationVerbosityServer=4`
|
- Server: `InformationVerbosityServerSideType=ClientSide`, `InformationVerbosityServer=4`
|
||||||
- Client: `InformationVerbosity=1`
|
- Client: `InformationVerbosity=2`
|
||||||
- Expected: client uses `1`
|
- Expected: client uses `2`
|
||||||
|
|
||||||
## 2) ServerRecommended mode (override OFF)
|
## 2) ServerRecommended mode (override OFF)
|
||||||
- Server: `InformationVerbosityServerSideType=ServerRecommended`, `InformationVerbosityServer=4`
|
- Server: `InformationVerbosityServerSideType=ServerRecommended`, `InformationVerbosityServer=4`
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
|
|
||||||
## 3) ServerRecommended mode (override ON)
|
## 3) ServerRecommended mode (override ON)
|
||||||
- Same as above, but `DisableServerRecommended=true`
|
- Same as above, but `DisableServerRecommended=true`
|
||||||
- Expected: client uses `1`
|
- Expected: client uses `2`
|
||||||
|
|
||||||
## 4) ServerForced mode
|
## 4) ServerForced mode
|
||||||
- Server: `InformationVerbosityServerSideType=ServerForced`, `InformationVerbosityServer=4`
|
- Server: `InformationVerbosityServerSideType=ServerForced`, `InformationVerbosityServer=4`
|
||||||
- Client: `InformationVerbosity=1`, `DisableServerRecommended=true`
|
- Client: `InformationVerbosity=2`, `DisableServerRecommended=true`
|
||||||
- Expected: client uses `4`
|
- Expected: client uses `4`
|
||||||
|
|
||||||
## 5) Client-side settings stay client-side
|
## 5) Client-side settings stay client-side
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
/beehives BeehiveConsideredEmptyBelowPopulation 500
|
/beehives BeehiveConsideredEmptyBelowPopulation 500
|
||||||
/beehives PopulationPercentRequirementForSwarm 80
|
/beehives PopulationPercentRequirementForSwarm 80
|
||||||
/beehives SwarmPopulationPercentage 0.2
|
/beehives SwarmPopulationPercentage 0.2
|
||||||
/beehives MaxTemperatureGrowth 10
|
/beehives TemperatureOptimal 10
|
||||||
```
|
```
|
||||||
|
|
||||||
## 1) Open-for-incoming is always below-threshold
|
## 1) Open-for-incoming is always below-threshold
|
||||||
@@ -44,13 +44,13 @@
|
|||||||
|
|
||||||
## 2b) Pre-swarm progress builds at optimal temperature
|
## 2b) Pre-swarm progress builds at optimal temperature
|
||||||
- Source hive above required percent, cooldown expired.
|
- Source hive above required percent, cooldown expired.
|
||||||
- Ensure temperature is at or above `MaxTemperatureGrowth`.
|
- Ensure temperature is at or above `TemperatureOptimal`.
|
||||||
- Expected: block info shows "Bees are preparing to swarm" (v1) or progress % (v2+).
|
- Expected: block info shows "Bees are preparing to swarm" (v1) or progress % (v2+).
|
||||||
- Expected: progress increases from 0 to 100% over `PreSwarmDurationHours` hours.
|
- Expected: progress increases from 0 to 100% over `PreSwarmDurationHours` hours.
|
||||||
|
|
||||||
## 2c) Pre-swarm progress decreases in cold
|
## 2c) Pre-swarm progress decreases in cold
|
||||||
- Start with some pre-swarm progress built up.
|
- Start with some pre-swarm progress built up.
|
||||||
- Drop temperature below `MaxTemperatureGrowth`.
|
- Drop temperature below `TemperatureOptimal`.
|
||||||
- Expected: pre-swarm progress decreases back toward 0.
|
- Expected: pre-swarm progress decreases back toward 0.
|
||||||
- Expected: swarm does not trigger until progress reaches 100% again.
|
- Expected: swarm does not trigger until progress reaches 100% again.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||||
<Configurations>Debug;Release;Debug22</Configurations>
|
<Configurations>Debug;Release;Version22</Configurations>
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_21)</VINTAGE_STORY>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Version22'">
|
||||||
|
<VINTAGE_STORY>$(VINTAGE_STORY_22)</VINTAGE_STORY>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
1
build.sh
1
build.sh
@@ -1 +1,2 @@
|
|||||||
dotnet run --project ./ZZCakeBuild/OrekiWoofsBeehivesCakeBuild.csproj -- "$@"
|
dotnet run --project ./ZZCakeBuild/OrekiWoofsBeehivesCakeBuild.csproj -- "$@"
|
||||||
|
dotnet run --project ./RoamingBees/ZZCakeBuild/RoamingBeesCakeBuild.csproj -- "$@" && cp ./RoamingBees/Releases/* ./Releases
|
||||||
|
|||||||
6
printLatestCommits.sh
Executable file
6
printLatestCommits.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
count="${1:-10}"
|
||||||
|
|
||||||
|
git -C "$script_dir" log -n "$count" --pretty=format:%s | awk '{ lines[NR] = $0 } END { for (i = NR; i >= 1; i--) print lines[i] }'
|
||||||
Reference in New Issue
Block a user