LockOn states its hostile's patrol order and fit quality; dice streams, patrol circuit and projector range pinned
ScenarioStage.Patrol(entity, near) states a piloted entity's patrol order (the orbit nearest a point) and RunStart applies it over the drawn circuit. LockOn stages its fit at .6 and the hostile on the orbit by the player. Tests: every SimulationDice stream draws independently of every other (they already did: the stream is mixed into the hash), the pilot's sample offset is on its own stream's grid, a patrol circuit does not move with items minted first, Crossing.ProjectorRange is read against the live range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
27be39284f
commit
bbfd816851
7 changed files with 85 additions and 2 deletions
|
|
@ -54,6 +54,9 @@ public static class RunStart
|
|||
placed.Entity.SetIff(player, hostile);
|
||||
player.SetIff(placed.Entity, hostile);
|
||||
arena.Admit(placed.Entity, placed.Piloted);
|
||||
// A stated patrol order replaces the circuit the zone drew for the pilot it just admitted.
|
||||
if (placed.Circuit != null)
|
||||
((PatrolOrbitsTask) arena.Agents.Last(agent => ReferenceEquals(agent.Ship, placed.Entity)).Task).Circuit = placed.Circuit;
|
||||
}
|
||||
return new Staged { Player = player, Credits = stage.Credits, Entities = stage.Placed.Select(placed => placed.Entity).ToList() };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using CultMath;
|
||||
using GameCult.Caching;
|
||||
using static CultMath.math;
|
||||
using float2 = CultMath.float2;
|
||||
using float3 = CultMath.float3;
|
||||
|
|
@ -48,6 +49,7 @@ public sealed class ScenarioStage
|
|||
public Entity Entity;
|
||||
public ScenarioStance Stance;
|
||||
public bool Piloted;
|
||||
public CultRecordKey[] Circuit;
|
||||
}
|
||||
|
||||
// A hull fitted slot by slot: each slot a design or a product, the hull cell it goes in, and its rotation. A name is
|
||||
|
|
@ -134,6 +136,18 @@ public sealed class ScenarioStage
|
|||
return entity;
|
||||
}
|
||||
|
||||
// The patrol order a piloted entity starts on: the one orbit that sits nearest `near` when the stage opens. A check
|
||||
// that rests on where a pilot goes states it here, so the pilot's circuit is not a draw. An entity that is not
|
||||
// piloted or not placed is a failure.
|
||||
public void Patrol(Entity entity, float2 near)
|
||||
{
|
||||
var placement = _placed.FirstOrDefault(p => ReferenceEquals(p.Entity, entity));
|
||||
if (placement == null || !placement.Piloted) { _failures.Add($"patrol: {entity?.Name ?? "no entity"} is not a placed, piloted ship"); return; }
|
||||
var orbit = Arena.Orbits.Keys.OrderBy(key => lengthsq(Arena.GetOrbitPosition(key) - near)).Cast<CultRecordKey?>().FirstOrDefault();
|
||||
if (orbit == null) { _failures.Add("patrol: the arena has no orbit to patrol"); return; }
|
||||
placement.Circuit = new[] { orbit.Value };
|
||||
}
|
||||
|
||||
// Items in the entity's first cargo bay, one per name. A name is an equippable or consumable design (open: the stage
|
||||
// chooses its product) or a product of one (pinned); a name that is neither is a failure.
|
||||
public void Cargo(Entity entity, params string[] names)
|
||||
|
|
|
|||
|
|
@ -18,11 +18,15 @@ public sealed class LockOn : Scenario
|
|||
// within a second.
|
||||
public static readonly CultMath.float2 HostileAt = float2(-2000, 3450);
|
||||
|
||||
// The fit's lots are minted at this quality, and the hostile's patrol order is stated, so the lock follows from the
|
||||
// staged situation and not from item draws or the pilot's drawn circuit (ruling scenario-stages-hostile-task).
|
||||
const float StagedQuality = .6f;
|
||||
|
||||
public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast);
|
||||
|
||||
public override void Stage(ScenarioStage stage)
|
||||
{
|
||||
var fighter = stage.Fit("Longinus",
|
||||
var fighter = stage.Fit("Longinus", StagedQuality,
|
||||
("Cockpit 2x2", int2(2, 6), None),
|
||||
("Large Drive", int2(1, 0), Reversed),
|
||||
("Large Drive", int2(3, 0), Reversed),
|
||||
|
|
@ -41,6 +45,7 @@ public sealed class LockOn : Scenario
|
|||
("Store-All Plus", int2(2, 8), None)); // Cargo Bay
|
||||
|
||||
stage.Player(fighter, float2(0, 0), facing: float2(0, 1));
|
||||
stage.Place(fighter, HostileAt, facing: normalize(-HostileAt), stance: ScenarioStance.Hostile, piloted: true);
|
||||
var hostile = stage.Place(fighter, HostileAt, facing: normalize(-HostileAt), stance: ScenarioStance.Hostile, piloted: true);
|
||||
stage.Patrol(hostile, float2(0, 0)); // it patrols the orbit by the player, which brings it into lock range
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue