fix(drill): place spots found up to 15 m from the navmesh; count only this run's Oxide errors (#22)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 1m28s
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 1m28s
Run 49: place.set.each was refused "4.4 m from the navmesh", because OnMesh searched 3 m and returned the unsnapped point; Place now searches 15 m. The drill reported run 48's four error lines again: oxideErrors read the whole day's Oxide log, and now reads only what was added after the drill started the rig. Refs #20, #22 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1113,9 +1113,10 @@ namespace Oxide.Plugins
|
||||
|
||||
private IEnumerator Place(Vector3 field)
|
||||
{
|
||||
// A roamer's spot must be on the navmesh when it is set (D219), so both spots are put there.
|
||||
Vector3 a = OnMesh(field + new Vector3(-40, 0, 0));
|
||||
Vector3 b = OnMesh(field + new Vector3(-40, 0, 30));
|
||||
// A roamer's spot must be on the navmesh when it is set (D219), so both spots are put there; the
|
||||
// wider search because a fixed offset from the field can land a few metres off it (run 49: 4.4 m).
|
||||
Vector3 a = OnMesh(field + new Vector3(-40, 0, 0), 15f);
|
||||
Vector3 b = OnMesh(field + new Vector3(-40, 0, 30), 15f);
|
||||
StandIn(OnMesh(field + new Vector3(-40, 0, 110)), 8);
|
||||
string eachRefusal = Api<string>("RunicNpc_SetPlacement", "t_each", Placement("t_each", a, 3, 20f, "each"));
|
||||
Check("place.set.each", eachRefusal == null, eachRefusal ?? "");
|
||||
@@ -1569,11 +1570,11 @@ namespace Oxide.Plugins
|
||||
return floor;
|
||||
}
|
||||
|
||||
private static Vector3 OnMesh(Vector3 p)
|
||||
private static Vector3 OnMesh(Vector3 p, float radius = 3f)
|
||||
{
|
||||
p.y = TerrainMeta.HeightMap.GetHeight(p);
|
||||
NavMeshHit hit;
|
||||
return SampleNavmesh(p, 3f, out hit) ? hit.position : p;
|
||||
return SampleNavmesh(p, radius, out hit) ? hit.position : p;
|
||||
}
|
||||
|
||||
private static JObject Placement(string profile, Vector3 at, int count, float respawn, string mode) =>
|
||||
|
||||
@@ -281,6 +281,7 @@ async function live(a) {
|
||||
for (const f of FRESH_DATA) await p.rm(rig, f) // already gone is fine: rm swallows it
|
||||
await p.write(rig, KITS_FILE, JSON.stringify(harnessKits(), null, 2))
|
||||
|
||||
const logMark = await oxideLogMark(p, rig)
|
||||
log(`starting ${RIG} on ${branch}`)
|
||||
const started = Date.now()
|
||||
await p.power(rig, 'start')
|
||||
@@ -298,7 +299,7 @@ async function live(a) {
|
||||
const status = await waitStatus(p, rig, 30 * 60000)
|
||||
if (!status) {
|
||||
finding('RunicNPC did not load: `rnpc.status` never answered.')
|
||||
result.oxideErrors = await oxideErrors(p, rig)
|
||||
result.oxideErrors = await oxideErrors(p, rig, logMark)
|
||||
return
|
||||
}
|
||||
result.status = status
|
||||
@@ -322,7 +323,7 @@ async function live(a) {
|
||||
}
|
||||
if (!accepted) {
|
||||
finding('The test harness did not load (`rnt.run all` was not answered).')
|
||||
result.oxideErrors = await oxideErrors(p, rig)
|
||||
result.oxideErrors = await oxideErrors(p, rig, logMark)
|
||||
return
|
||||
}
|
||||
result.ran = true
|
||||
@@ -337,7 +338,7 @@ async function live(a) {
|
||||
}
|
||||
for (const f of result.harness.failed) finding(`Harness: ${f}`)
|
||||
log(`harness: ${result.harness.pass} pass, ${result.harness.fail} fail`)
|
||||
result.oxideErrors = await oxideErrors(p, rig)
|
||||
result.oxideErrors = await oxideErrors(p, rig, logMark)
|
||||
if (result.oxideErrors.length) finding(`RunicNPC logged ${result.oxideErrors.length} error line(s) in Oxide's log during the run.`)
|
||||
await p.command(rig, 'rnt.clear').catch(() => {})
|
||||
} catch (e) {
|
||||
@@ -490,10 +491,17 @@ function summarise(lines) {
|
||||
}
|
||||
|
||||
/** RunicNPC's and the harness's error lines from today's Oxide log. */
|
||||
async function oxideErrors(p, id) {
|
||||
/** Where Oxide's log of today ends now, so oxideErrors reads only what a run adds (run 49 counted run 48's). */
|
||||
async function oxideLogMark(p, id) {
|
||||
const day = now().slice(0, 10)
|
||||
return { day, length: ((await p.readOr(id, `/oxide/logs/oxide_${day}.txt`, '')) || '').length }
|
||||
}
|
||||
|
||||
async function oxideErrors(p, id, since = null) {
|
||||
const day = now().slice(0, 10)
|
||||
const text = (await p.readOr(id, `/oxide/logs/oxide_${day}.txt`, '')) || ''
|
||||
return text
|
||||
.slice(since && since.day === day ? since.length : 0)
|
||||
.split('\n')
|
||||
.filter((l) => /RunicNPC|RunicNpcTest/.test(l) && /\[Error\]|Exception|Failed|error CS/.test(l))
|
||||
.slice(-40)
|
||||
|
||||
Reference in New Issue
Block a user