attributes: @Material(field) resolved as @Node is; @OneOf on a string field takes words, and every registry row's value is checked against them - words on another field, or constants on a string, is an error; reseeded
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d82dc3162f
commit
81cb992fad
10 changed files with 75030 additions and 73286 deletions
|
|
@ -11,6 +11,8 @@
|
|||
# @Color tint: int = 0
|
||||
# @Node(model) grip: string = "" # a node inside the glTF the field `model` names
|
||||
# @Clip(model) idle: string = "" # a clip inside that glTF
|
||||
# @Material(model) skin: string = "" # a material inside it
|
||||
# @OneOf("box", "hull") shape: string = "" # a string field: one of these words
|
||||
# @Color @Tint(TSLOT_HAIR) hair: int = 0 # a colour for that tint slot (a constant that exists)
|
||||
# @Derived reach: float = 0.0 # worked out at boot: anything written is overwritten
|
||||
# @Text @Multiline blurb: string = "" # read by the player, so translated; prose
|
||||
|
|
@ -19,9 +21,10 @@
|
|||
# @AppendOnly @ByKey registry Items of Item as IT from "items.lres"
|
||||
#
|
||||
# They change nothing the program does. A target the program does not have at all is a warning and
|
||||
# "unresolved" in the schema (a package names the game's registry it cannot import). Four are checked: @Ref must name a registry that exists,
|
||||
# @Node and @Clip a field of its record that names a glTF (attrs_node.ludic), and a listing @OneOf
|
||||
# constants that exist, and @Tint a constant that exists (a slot's row in the game's registry). A
|
||||
# "unresolved" in the schema (a package names the game's registry it cannot import). Checked: @Ref
|
||||
# names a registry; @Node, @Clip and @Material a field of their record naming a glTF
|
||||
# (attrs_node.ludic); a listing @OneOf constants (or, on a string field, words - and every row's value
|
||||
# one of them); and @Tint a constant (a slot's row in the game's registry). A
|
||||
# field's or a registry's attributes are a group (Node.at, g_rg_at): a run of names, each with its
|
||||
# arguments as JSON values - an identifier or a string as a string, a number as written.
|
||||
var g_at_start: []int = new []int # a group's first attribute ...
|
||||
|
|
@ -47,6 +50,8 @@ function at_push(g: int, name: pointer, args: pointer, first: pointer, nargs: in
|
|||
push(g_at_first, first)
|
||||
push(g_at_nargs, nargs)
|
||||
push(g_at_unres, false)
|
||||
push(g_at_strs, g_at_strs_next)
|
||||
g_at_strs_next = false
|
||||
g_at_count[g] = g_at_count[g] + 1
|
||||
}
|
||||
# `(a, "b", -1.5)` after an attribute's name, if it is there, as a JSON array; the first argument
|
||||
|
|
@ -55,11 +60,15 @@ var g_at_arg0: pointer = null
|
|||
var g_at_argn: int = 0
|
||||
var g_at_allnum: bool = true # every argument a number
|
||||
var g_at_allid: bool = true # every argument a name
|
||||
var g_at_allstr: bool = true # every argument a string
|
||||
var g_at_strs: []bool = new []bool # per attribute: its arguments were all strings
|
||||
var g_at_strs_next: bool = false # what at_push files for the attribute it pushes
|
||||
function at_args() -> pointer {
|
||||
g_at_arg0 = null
|
||||
g_at_argn = 0
|
||||
g_at_allnum = true
|
||||
g_at_allid = true
|
||||
g_at_allstr = true
|
||||
if not is_op("(") { return "[]" }
|
||||
pi += 1
|
||||
var out: pointer = "["
|
||||
|
|
@ -69,6 +78,7 @@ function at_args() -> pointer {
|
|||
if is_op("-") { neg = true; pi += 1 }
|
||||
let t = toks[pi]
|
||||
if t.kind != TK_ID { g_at_allid = false }
|
||||
if t.kind != TK_STR { g_at_allstr = false }
|
||||
var v: pointer = null
|
||||
var raw: pointer = null
|
||||
if t.kind == TK_INT {
|
||||
|
|
@ -108,7 +118,7 @@ function at_lead0(raw: pointer) -> pointer {
|
|||
# the editor attributes a field may carry, and what each takes
|
||||
function at_field_known(a: pointer) -> bool {
|
||||
if (a == "Ref") or (a == "OneOf") or (a == "Range") or (a == "Unit") or (a == "Asset") or (a == "Color") { return true }
|
||||
return (a == "Node") or (a == "Clip") or (a == "Tint") or at_flag(a)
|
||||
return (a == "Node") or (a == "Clip") or (a == "Material") or (a == "Tint") or at_flag(a)
|
||||
}
|
||||
# the attributes that take nothing: they say what a field is
|
||||
function at_flag(a: pointer) -> bool {
|
||||
|
|
@ -118,10 +128,11 @@ function at_flag(a: pointer) -> bool {
|
|||
function at_field(g: int, a: pointer) -> void {
|
||||
let args = at_args()
|
||||
let n = g_at_argn
|
||||
if (a == "Ref") or (a == "Node") or (a == "Clip") or (a == "Tint") {
|
||||
if (a == "Ref") or (a == "Node") or (a == "Clip") or (a == "Material") or (a == "Tint") {
|
||||
if n != 1 or toks[pi - 2].kind != TK_ID { perr(`@{a} takes one name: @{a}(Items)`) }
|
||||
}
|
||||
if (a == "OneOf") and (n < 1 or not g_at_allid) { perr("@OneOf takes a prefix or constants: @OneOf(GR_) or @OneOf(GR_GOLD, GR_SILVER)") }
|
||||
if (a == "OneOf") and (n < 1 or not (g_at_allid or g_at_allstr)) { perr("@OneOf takes a prefix, constants or words: @OneOf(GR_), @OneOf(GR_GOLD, GR_SILVER) or @OneOf(\"box\", \"hull\")") }
|
||||
g_at_strs_next = (a == "OneOf") and g_at_allstr
|
||||
if (a == "Range") and n != 2 { perr("@Range takes the least and the most: @Range(0, 1.5)") }
|
||||
if (a == "Range") and not g_at_allnum { perr("@Range takes two numbers: @Range(0, 1.5)") }
|
||||
if ((a == "Unit") or (a == "Asset")) and (n != 1 or toks[pi - 2].kind != TK_STR) { perr(`@{a} takes one string: @{a}("m/s")`) }
|
||||
|
|
@ -180,7 +191,7 @@ function at_check_field(d: Node, f: Node) -> void {
|
|||
var j = g_at_start[g]
|
||||
while j < g_at_start[g] + g_at_count[g] {
|
||||
if (g_at_name[j] == "Ref") and reg_find(g_at_first[j]) < 0 { at_target(d, f, j, "a registry") }
|
||||
if (g_at_name[j] == "Node") or (g_at_name[j] == "Clip") { at_check_node(d, f, g_at_name[j], g_at_first[j]) }
|
||||
if (g_at_name[j] == "Node") or (g_at_name[j] == "Clip") or (g_at_name[j] == "Material") { at_check_node(d, f, g_at_name[j], g_at_first[j]) }
|
||||
if g_at_name[j] == "OneOf" { at_check_oneof(d, f, j) }
|
||||
if (g_at_name[j] == "Tint") and not at_const_exists(g_at_first[j]) { at_const_target(d, f, j, g_at_first[j]) }
|
||||
j += 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue