feat!: RunicNPC v1.0.0, edge → main (runicnpc 9e step 3, merge 1 of 3) #19
12
plugin.toml
12
plugin.toml
@@ -24,9 +24,11 @@
|
|||||||
#
|
#
|
||||||
# 1 was stage 0's: `RunicNpc_ApiVersion()` and nothing else.
|
# 1 was stage 0's: `RunicNpc_ApiVersion()` and nothing else.
|
||||||
# 2 was stage 2's whole API, PLAN.md §4.
|
# 2 was stage 2's whole API, PLAN.md §4.
|
||||||
# Current: 3 — stage 4 (D249): RunicNpc_AddPlacement, _RenamePlacement, _RespawnPlacement and the
|
# 3 was stage 4 (D249): RunicNpc_AddPlacement, _RenamePlacement, _RespawnPlacement and the
|
||||||
# OnRunicNpcPlacementChanged hook, documented in docs/runicnpc/API.md.
|
# OnRunicNpcPlacementChanged hook.
|
||||||
api = 3
|
# Current: 4 — stage 5: RunicNpc_Factions, _SetFactions, _Escort, _Ally, _Tether, the profile's stage 5
|
||||||
|
# fields, a placement's tether, and the OnRunicNpcEscortEnded hook, documented in docs/runicnpc/API.md.
|
||||||
|
api = 4
|
||||||
|
|
||||||
# ── Framework floors ─────────────────────────────────────────────────────────
|
# ── Framework floors ─────────────────────────────────────────────────────────
|
||||||
#
|
#
|
||||||
@@ -45,6 +47,6 @@ min_carbon_version = "2.0.259"
|
|||||||
# `doctor`, which reports a missing one rather than installing it. The PR check
|
# `doctor`, which reports a missing one rather than installing it. The PR check
|
||||||
# holds this list and the plugin's `// Requires:` lines equal.
|
# holds this list and the plugin's `// Requires:` lines equal.
|
||||||
#
|
#
|
||||||
# ZoneManager is NOT listed: a zone tether is optional (PLAN.md §6), and a
|
# ZoneManager is NOT listed: a zone tether is optional (PLAN.md §6). A placement
|
||||||
# profile that asks for one on a server without it is refused when it is saved.
|
# or an event step that asks for one on a server without it is refused (D272).
|
||||||
requires_plugins = ["Kits"]
|
requires_plugins = ["Kits"]
|
||||||
|
|||||||
1904
plugin/RunicNPC.cs
1904
plugin/RunicNPC.cs
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,17 @@ const PLUGIN_TOML = path.join(ROOT, 'plugin.toml')
|
|||||||
* That half cannot be read statically; it is the reviewer's to check, which is
|
* That half cannot be read statically; it is the reviewer's to check, which is
|
||||||
* why the reason goes here where the reviewer will see it.
|
* why the reason goes here where the reviewer will see it.
|
||||||
*/
|
*/
|
||||||
const ANSWERS_DELIBERATELY = Object.create(null)
|
const ANSWERS_DELIBERATELY = Object.assign(Object.create(null), {
|
||||||
|
// Stage 5 (D259, D264): turrets: ignore. Answers false for RunicNPC's own NPCs whose profile says
|
||||||
|
// ignore, so no auto turret, flame turret or shotgun trap targets them; null for everything else.
|
||||||
|
CanBeTargeted: 'turrets: ignore (D259, D264), our own NPCs only',
|
||||||
|
// Stage 5 (D261, D271): TruePVE's and NextGenPVE's question. Answers only for one of ours facing a
|
||||||
|
// real player, with the profile's two PVE checkboxes; null for everything else.
|
||||||
|
CanEntityTakeDamage: 'PVE allowed both ways, or the profile opt-out (D261, D271), our own NPCs only',
|
||||||
|
// Stage 5 (D271): cancels damage only when one of ours whose profile says it cannot hurt players
|
||||||
|
// hits a real player. Its other job, defending an ally or escort (D257, D269), never answers.
|
||||||
|
OnEntityTakeDamage: 'a harmless profile never hurts a player (D271), our own NPCs only',
|
||||||
|
})
|
||||||
|
|
||||||
/** Plugins RunicNPC must require, whatever else it requires (D217). */
|
/** Plugins RunicNPC must require, whatever else it requires (D217). */
|
||||||
const REQUIRED_PLUGINS = ['Kits']
|
const REQUIRED_PLUGINS = ['Kits']
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ test('returning null is not good enough — the signature is the rule', () => {
|
|||||||
// `return null` today is one edit away from `return true` tomorrow, and the
|
// `return null` today is one edit away from `return true` tomorrow, and the
|
||||||
// edit that breaks it looks harmless in a diff. A void method cannot be turned
|
// edit that breaks it looks harmless in a diff. A void method cannot be turned
|
||||||
// into a veto without changing its signature, which is visible.
|
// into a veto without changing its signature, which is visible.
|
||||||
const methods = ` private bool CanBeTargeted(BaseCombatEntity entity, AutoTurret turret)
|
const methods = ` private bool CanLootEntity(BasePlayer player, StorageContainer container)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}`
|
}`
|
||||||
|
|
||||||
const problems = check(source({ expected: ['CanBeTargeted'], methods }), toml())
|
const problems = check(source({ expected: ['CanLootEntity'], methods }), toml())
|
||||||
assert.match(problems[0], /CanBeTargeted returns bool, not void/)
|
assert.match(problems[0], /CanLootEntity returns bool, not void/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('a method that is not shaped like a hook is left alone', () => {
|
test('a method that is not shaped like a hook is left alone', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user