Mining Cut 3 fix: launchers do not count toward rock reach (Q12 A)

Weapon.CanMine is the one mining predicate; LockWeapon overrides it to
false. Entity.VisibleChunksInReach counts only weapons that can mine.

Tests: LaunchersDoNotCountTowardChunkReach (a launcher-only ship is offered
no rock; a gun of 200 beside a launcher of 400 is offered the near rock
only) and AnOfflineWeaponAddsNoReach (Soul F8: reach reads Active, not
Enabled).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-01 13:02:26 +02:00
commit f88d1fc1b3
4 changed files with 84 additions and 4 deletions

View file

@ -65,6 +65,9 @@ public class LockWeapon : InstantWeapon
// before a shot is ever attempted.
public bool IsLocked => _lock > .99f;
// Q12 A: a launcher cannot mine.
public override bool CanMine => false;
public LockWeapon(LockWeaponData data, EquippedItem item) : base(data, item)
{

View file

@ -88,6 +88,11 @@ public abstract class Weapon : Behavior, IActivatedBehavior
public float Spread { get; protected set; }
public float Velocity { get; protected set; }
// Mining Cut 3 fix (Q12 A, "launchers cannot mine"): whether this weapon can mine a chunk. The one mining
// predicate: chunk reach (Entity.VisibleChunksInReach) reads it, and so does anything that decides a weapon
// may work a chunk. A launcher overrides it.
public virtual bool CanMine => true;
protected bool _firing;
public bool Firing

View file

@ -371,14 +371,14 @@ public abstract class Entity
// enters VisibleEntities: its info exceeds TargetDetectionInfoThreshold.
public bool ChunkVisible(ChunkId chunk) => ChunkInfo(chunk) > ItemManager.GameplaySettings.TargetDetectionInfoThreshold;
// Mining Cut 3 (Q13 A): the reach for picking a chunk -- the longest range among this entity's active weapons.
// Every visible chunk within it, written into `into` (cleared first). Cycling and any programmatic chunk pick
// read this, so there is one reach rule.
// Mining Cut 3 (Q13 A): the reach for picking a chunk -- the longest range among this entity's active weapons
// that can mine (Weapon.CanMine, Q12 A). Every visible chunk within it, written into `into` (cleared first).
// Cycling and any programmatic chunk pick read this, so there is one reach rule.
public void VisibleChunksInReach(List<ChunkId> into)
{
var reach = 0f;
foreach (var weapon in _weapons)
if (weapon.Item == null || weapon.Item.Active.Value)
if (weapon.CanMine && (weapon.Item == null || weapon.Item.Active.Value))
reach = max(reach, weapon.Range);
Zone.ChunksNear(Position.xz, reach, into);
into.RemoveAll(chunk => !ChunkVisible(chunk));