Open amis92 opened 2 years ago
value
I've investigated negative values in detail.
Generally, negative values work "as normal", except "-1" for a type=max constraint, which is equivalent to no limit. The logic might not be tied to max, but for min
a non-positive value is the same as no limit anyway. Do note, that any other negative value for a max
is processed as that value (and not as "no limit").
BattleScribe Data Editor does some additional validations on value
:
As an interesting quirk, when an entry has a constraint of type=min scope=parent value=0, the entry is hidden in Roster Editor, as it's not allowed to be selected. As expected, using a Modifier to Set that constraint's value to -1 makes this entry selectable (unlimited) and it's correctly shown in Roster Editor. However, when using a Modifier to Decrease the value by 1 (making it 0 - 1 = -1
- unlimited), the Roster Editor does not show the entry (incorrectly?), as that entry is unlimited due to the new value of max constraint.
In different comparison/field/scope combinations, different entries are allowed as filters. We'll use numeric comparison
to mean all comparison operators that operate on numbers - that excludes the (not)-instance-of
comparisons. Those will be called instance-of comparison
.
selections
or CostsWhen field
is selections
or a specific Cost or Cost Limit, the following rules apply.
The comparison
must be numeric
(for instance-of
the field
is disabled, and so cannot have value).
scope=self
and scope=parent
allows filter to be:
any
, unit
, model
, upgrade
;scope
entry.scope=force
and scope=roster
allows filter to be:
any
, unit
, model
, upgrade
;scope=specific entry
allows filter to be:
any
, unit
, model
, upgrade
;scope
entry.When comparison
is instance-of
, the field
is disabled and the following rules apply.
scope=self
, scope=parent
and scope=ancestor
allows filter to be:
any
, unit
, model
, upgrade
;scope=primary-category
allows filter to be:
any
, unit
, model
, upgrade
;scope=force
allows filter to be:
any
, unit
, model
, upgrade
;scope=primary-catalogue
allows filter to be:
scope=specific entry
allows filter to be:
any
, unit
, model
, upgrade
forces
When field
is forces
, the following rules apply.
The comparison
must be numeric
(for instance-of
the field
is disabled, and so cannot have value).
scope=force
and scope=roster
allows filter to be:
any
;scope=specific Force Entry
allows filter to be:
any
;scope
force entry.
We need to document queries: what are legal combinations, how do they work, what are the results.
BS Nodes
The elements in BattleScribe that use queries are:
condition
,constraint
,repeat
.These elements appear as children in other BattleScribe elements:
condition
can be child of:modifier
,modifierGroup
,conditionGroup
.repeat
can be child of:modifier
,modifierGroup
.constraint
can be child of:selectionEntry
,selectionEntryGroup
,entryLink
,forceEntry
,categoryLink
inforceEntry
,categoryEntry
.It's important to list all elements that can contain
modifier
s, since then they can also containconditions
andrepeats
within thosemodifier
s.modifier
can be child of:constraint
(see list above)profile
,rule
,infoGroup
,infoLink
.Query components
The elements of a query are:
field
- what is the counted value.scope
- where (in what subtree) are the values counted.childId
aka Filter By - which of the candidate entries/values do we actually process.value
- reference value that the query result is compared with.comparison
-condition
andconstraint
uses it to compare the result with a referencevalue
.shared
,value-is-percentage
,include-child-selections
,include-child-forces
,round-up
.Known options
Field
Allowed values for a
field
in a Query:selections
- count the selections.forces
- count the forces.scope
has to be Roster,filter
is unused).Special cases:
forces
field allows only the followingscope
values:force
,roster
, specific force entry.scope=roster
. Thefield
is then formatted likelimit::{type-id}
where{type-id}
is the ID of the Cost Type.Scope
Scope can be one of:
self
- restrictedparent
ancestor
- restrictedprimary-category
- restrictedforce
roster
primary-catalogue
Special cases:
self
is not allowed inconstraint
s.ancestor
andprimary-category
are only allowed withcomparison
of(not)instance-of
.Filter
Filter can be one of:
any
(Anything) - noop.unit/model/upgrade
(Unit/Model/Upgrade) - all elements with specified EntryKind (type) are returned.When
filter
has specified value:any
(anything) - all elements in thescope
are returned.scope
with specified EntryKind (type) are returned.scope
with specified category linked are returned.scope
that are instance of that entry.scope
that are instance of that entry.Special cases:
childId
/filter
inconstraint
is disabled. It is implicitly the constraint's parent entry.Value
repeat
used to divide query result into "buckets", and for each such bucket there are N repetitions of the modifier applied (N isrepeats
value in BS XML).repeat
requires a positivevalue
.constraint
used to compare usingcomparison
operator.condition
used to compare usingcomparison
operator. If it's ainstance-of
kind of operator, thevalue
is unused.Generally, negative values work as expected. The exception here is a
-1
value for atype=max
constraint
- in that case, it is interpreted as "infinity" or "no limit". Further modifications of the value (e.g. by Modifiers) are calculated as normal, e.g. when a constraint of-1
is modifed to increase value by 1, now the maximum is 0 so the selections are not allowed. Any other negative value (e.g.-2
) is treated normally (no special behavior).Comparison
repeat
has none.condition
has all numeric comparison operators and two special ones (instance-of):(not-)equal to
greater/less than (or equal)
(not-)instance of
.constraint
hasmin
(greater than or equal
) andmax
(less than or equal
).Special cases:
scope
isancestor
orprimary-category
,comparison
must be(not)instance-of
, thus those scopes are not available forconstraint
andrepeat
.(not-)instance-of
value ofcomparison
is a special case incondition
queries: there's nofield
defined,scope
defines the checked entry, andchildId
/filter
defines the type/entry thescope
should be "instance of". Whenfilter
is:any
(anything) - it's a noop, always satisfied.scope
should have that type.scope
should have that category linked.scope
should be instance of that entry.scope
should be instance of that entry.Options
shared
- the query should sum up all instances ofchildId
/filter
in scope, disregarding the selection path. BS author explainer. ❓ When is this option allowed in Data Editor UI?value-is-percentage
- thevalue
should be interpreted as percentage, and is limited to the range[0; 100]
.include-child-selections
- the scope includes selection subtrees (recursive/all descendants).include-child-forces
- the scope includes force subtrees (recursive/all descendants).round-up
- used inrepeat
calculations, rounds the division of result byvalue
up, instead of down as is by default.Loose notes
constraint
hascomparison
defined differently: it hastype
ofmin
ormax
- those are equivalent togreater than or equal
andless than or equal
values oftype
incondition
.value
can be negative forconstraint
andcondition
. Details: https://github.com/BSData/phalanx/issues/45#issuecomment-1197259096repeat
has nocomparison
(type
), but instead declares a number of repetitions per multiplications of referencevalue
in query result ((result / value) * repeats
).constraint
ofmax
value has an interesting quirk. When an entry has a constraint of type=min scope=parent value=0, the entry is hidden in Roster Editor, as it's not allowed to be selected. As expected, using a Modifier to Set that constraint's value to -1 makes this entry selectable (unlimited) and it's correctly shown in Roster Editor. However, when using a Modifier to Decrease the value by 1 (making it0 - 1 = -1
- unlimited), the Roster Editor does not show the entry (incorrectly?), as that entry is unlimited due to the new value of max constraint.❓ What are other unobvious interactions?