43 lines
2.2 KiB
C#
43 lines
2.2 KiB
C#
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||
|
|
|
||
|
|
using CultMath;
|
||
|
|
using static CultMath.math;
|
||
|
|
|
||
|
|
// Cut 1 (docs/fire-control-cut.md): geometry only. Whether a weapon bears on a point is decided here and
|
||
|
|
// nowhere else -- no prefab, transform, ArticulationPoint or renderer may influence it (R6, R7). Mount
|
||
|
|
// direction and arc are both derived per read from catalog data and the item's authored rotation; neither
|
||
|
|
// is ever stored on the entity.
|
||
|
|
public static class FireControl
|
||
|
|
{
|
||
|
|
// The planar unit vector a hardpoint's weapon points along, derived solely from the item's authored
|
||
|
|
// rotation (R6, the same convention reaction thrusters already use) -- never from a live Unity
|
||
|
|
// transform. This is the item-rotation path Behavior.Direction now uses unconditionally, after the
|
||
|
|
// HardpointTransforms readback branch is deleted.
|
||
|
|
public static float3 MountDirection(EquippedItem item)
|
||
|
|
{
|
||
|
|
var itemDirection = item.Entity.Direction.Rotate(item.EquippableItem.Rotation);
|
||
|
|
return normalize(float3(itemDirection.x, 0, itemDirection.y));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Full arc width in degrees: the per-hardpoint override when authored (nonzero), else
|
||
|
|
// GameplaySettings.FiringArc. Zero on the hardpoint means "use the default," not "no arc."
|
||
|
|
public static float ArcFor(EquippedItem item)
|
||
|
|
{
|
||
|
|
var hardpoint = item.Entity.Hardpoints[item.Position.x, item.Position.y];
|
||
|
|
var arc = hardpoint?.FiringArc ?? 0f;
|
||
|
|
return arc > 0 ? arc : item.ItemManager.GameplaySettings.FiringArc;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Planar bearing test (R7: the simulation is 2D, the 3D is set dressing -- target height never enters
|
||
|
|
// this). An arc of 360 degrees or more passes unconditionally, which is how a turret hardpoint
|
||
|
|
// (authored FiringArc: 360, Q1) tracks all the way around without a second type.
|
||
|
|
public static bool InArc(EquippedItem weapon, float3 toTarget)
|
||
|
|
{
|
||
|
|
var arc = ArcFor(weapon);
|
||
|
|
if (arc >= 360f) return true;
|
||
|
|
var planarTarget = normalize(float3(toTarget.x, 0, toTarget.z));
|
||
|
|
return dot(MountDirection(weapon), planarTarget) >= cos(radians(arc / 2f));
|
||
|
|
}
|
||
|
|
}
|