diff --git a/HarmonySrc/WolfBag.cs b/HarmonySrc/WolfBag.cs
index f63085e..fb59687 100644
--- a/HarmonySrc/WolfBag.cs
+++ b/HarmonySrc/WolfBag.cs
@@ -352,7 +352,7 @@ namespace NecromancerTome
}
if (best == null)
{
- return false;
+ return TryPickupBlock(_world, _player, cam, from, _wolf);
}
ItemStack rest = Take(best.itemStack);
if (rest == null)
@@ -370,6 +370,64 @@ namespace NecromancerTome
return true;
}
+ /// E на подбираемую «природную мелочь» мира - камешек rock01 и т. п. (тест 13.10: «лутающие одержимые и
+ /// питомцы не могут подбирать предметы, например камни»): блок с CanPickup, что персонаж поднимает по E, - в
+ /// сумку (что выдаёт - Block.OnBlockPickedUp, как у игры), блок убрать. Только IsTerrainDecoration: CanPickup
+ /// есть и у построек игрока (каркасы, фонари, котелки) - их по E не утаскиваем. Чужой участок - как у игры
+ /// (CanPickupBlockAt). Ближайший к лучу камеры в PickupReach от того, кто подбирает.
+ static bool TryPickupBlock(World _world, EntityPlayerLocal _player, Transform _cam, Vector3 _from, EntityAlive _who)
+ {
+ Vector3i c = World.worldToBlockPos(_who.position);
+ int r = Mathf.CeilToInt(PickupReach);
+ Vector3i best = Vector3i.zero;
+ BlockValue bestBv = BlockValue.Air;
+ float bestDeg = PickupAimDeg;
+ for (int x = -r; x <= r; x++)
+ for (int y = -1; y <= 2; y++)
+ for (int z = -r; z <= r; z++)
+ {
+ Vector3i p = new Vector3i(c.x + x, c.y + y, c.z + z);
+ BlockValue bv = _world.GetBlock(p);
+ if (bv.isair || bv.ischild)
+ {
+ continue;
+ }
+ Block b = bv.Block;
+ if (b == null || !b.CanPickup || !b.IsTerrainDecoration)
+ {
+ continue;
+ }
+ Vector3 at = p.ToVector3() + new Vector3(0.5f, 0.3f, 0.5f);
+ if ((at - _who.position).sqrMagnitude > PickupReach * PickupReach)
+ {
+ continue;
+ }
+ float deg = Vector3.Angle(_cam.forward, at - _from);
+ if (deg < bestDeg)
+ {
+ bestDeg = deg;
+ best = p;
+ bestBv = bv;
+ }
+ }
+ if (bestBv.isair || !_world.CanPickupBlockAt(best, GameManager.Instance.GetPersistentLocalPlayer()))
+ {
+ return false;
+ }
+ ItemStack st = bestBv.Block.OnBlockPickedUp(_world, best, bestBv, _player.entityId);
+ ItemStack rest = Take(st);
+ if (rest == null)
+ {
+ return true;
+ }
+ if (rest.IsEmpty())
+ {
+ _world.SetBlockRPC(best, BlockValue.Air);
+ Debug.Log("[NecromancerTome] WolfBag: поднят блок " + bestBv.Block.GetBlockName() + " " + best);
+ }
+ return true;
+ }
+
/// «Взять всё» - по ячейкам, пока есть место.
public static void TakeAll(TEFeatureStorage _te)
{
diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll
index 6b33be1..469330b 100644
Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ
diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb
index 110c750..100bcc7 100644
Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ