Compare commits
2 Commits
statupgrad
...
8d9303c8bc
Author | SHA1 | Date | |
---|---|---|---|
8d9303c8bc
|
|||
ad9e5764f1
|
25
README.md
25
README.md
@ -42,7 +42,7 @@ A bucket of game state.
|
|||||||
|
|
||||||
### Stat
|
### Stat
|
||||||
|
|
||||||
An arbitrary variable (or function, if it's calculated) tagged with some stuff to make it easier to display to the player.
|
An arbitrary variable (or function, if it's calculated) tagged with some stuff to make it easier to display to the player. Stats can be extracted automatically (see "Stat Extraction" below).
|
||||||
|
|
||||||
### StatsCollection
|
### StatsCollection
|
||||||
|
|
||||||
@ -57,3 +57,26 @@ There are some special errors that Rules can use to "communicate with" the rule
|
|||||||
### Messages
|
### Messages
|
||||||
|
|
||||||
For now, strings but inconvenient. Intended to provide forwards compatibility when we eventually include some way to format text, where all the stuff written for "it's just a string" would break if not for having this extra type in the way to wrap it where we can stay compatible with "it's just a string" mode.
|
For now, strings but inconvenient. Intended to provide forwards compatibility when we eventually include some way to format text, where all the stuff written for "it's just a string" would break if not for having this extra type in the way to wrap it where we can stay compatible with "it's just a string" mode.
|
||||||
|
|
||||||
|
## Stat Extraction
|
||||||
|
The function `ExtractStats` creates a stats list automatically by searching through a struct's fields and methods. The following things are recognized as stats:
|
||||||
|
|
||||||
|
* any method with a name like `StatFoo` or `HiddenStatFoo` (the latter are marked as invisible stats, which show up only in debug mode with the implementation in BasicStatsPane)
|
||||||
|
* any exported field with a type that is already a `Stat`; the `Stored[T]` and `Hidden[T]` generic types are containers for this
|
||||||
|
* any exported field tagged with `cardsim:"stat"`
|
||||||
|
* or `cardsim:"hidden"` for hidden stats. `"hiddenstat"` also works.
|
||||||
|
* you can use `"round2"` to round to two decimal places -- you can use any integer here, not just 2. works with both `float` types.
|
||||||
|
* `"hiddenround3"` (or any other number) creates a hidden rounded stat.
|
||||||
|
* To change the display name of a stat, use a separate tag phrase in addition to the stat tag, `cardsim_name:"name"`.
|
||||||
|
* For example: `cardsim:"stat" cardsim_name:"Stat Display Name"` creates a visible stat that shows up as "Stat Display Name".
|
||||||
|
* `cardsim:"hiddenround1" cardsim_name:"Hidden Rounded Stat"` creates an invisible stat that shows up, rounded to one decimal place, as "Hidden Rounded Stat".
|
||||||
|
|
||||||
|
Stat extraction can implement most or all of your type's `Stats` method for you:
|
||||||
|
|
||||||
|
```
|
||||||
|
func (e *ExampleType) Stats() []cardsim.Stat {
|
||||||
|
return cardsim.ExtractStats(e)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
ExtractStats puts methods first (lexicographically), then fields (in the order they appear). You can use `cardsim.SortStats` to instead put visible stats before hidden stats, alphabetized (case-insensitive).
|
||||||
|
@ -138,6 +138,10 @@ func (s statFunc[T]) Visible() bool {
|
|||||||
// start of another word, if it's not at the end). To insert a space between
|
// start of another word, if it's not at the end). To insert a space between
|
||||||
// consecutive capital letters, insert an underscore (`_`). This name inference
|
// consecutive capital letters, insert an underscore (`_`). This name inference
|
||||||
// trims "Stat" and "HiddenStat" off the front of method names.
|
// trims "Stat" and "HiddenStat" off the front of method names.
|
||||||
|
//
|
||||||
|
// To override the name extracted from a field name, add `cardsim_name:"name"`
|
||||||
|
// to the tag, where the name part is the name you want to use. It will not be
|
||||||
|
// formatted further - use normal spaces, capitalization, etc.
|
||||||
func ExtractStats(x any) []Stat {
|
func ExtractStats(x any) []Stat {
|
||||||
v := reflect.ValueOf(x)
|
v := reflect.ValueOf(x)
|
||||||
for k := v.Kind(); k == reflect.Pointer || k == reflect.Interface; k = v.Kind() {
|
for k := v.Kind(); k == reflect.Pointer || k == reflect.Interface; k = v.Kind() {
|
||||||
@ -248,6 +252,9 @@ func ExtractStats(x any) []Stat {
|
|||||||
continue // not identifiably a stat
|
continue // not identifiably a stat
|
||||||
}
|
}
|
||||||
nm := strings.Join(explode(sf.Name), " ")
|
nm := strings.Join(explode(sf.Name), " ")
|
||||||
|
if t := sf.Tag.Get("cardsim_name"); t != "" {
|
||||||
|
nm = t
|
||||||
|
}
|
||||||
if known[nm] {
|
if known[nm] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ func (i inverseDivision) OptionText(p *player) (cardsim.Message, error) {
|
|||||||
|
|
||||||
func (i inverseDivision) Enact(p *player) (cardsim.Message, error) {
|
func (i inverseDivision) Enact(p *player) (cardsim.Message, error) {
|
||||||
if p.Stats.Number.Value == 0 {
|
if p.Stats.Number.Value == 0 {
|
||||||
return nil, errors.New("you can't divide by zero!")
|
return nil, errors.New("you can't divide by zero")
|
||||||
}
|
}
|
||||||
p.Stats.Number.Value = int(i) / p.Stats.Number.Value
|
p.Stats.Number.Value = int(i) / p.Stats.Number.Value
|
||||||
return cardsim.MsgStr("Inverse divided."), nil
|
return cardsim.MsgStr("Inverse divided."), nil
|
||||||
|
@ -12,7 +12,7 @@ type SmokeTestCollection struct {
|
|||||||
|
|
||||||
Flavor cardsim.Stored[string]
|
Flavor cardsim.Stored[string]
|
||||||
|
|
||||||
Things int `cardsim:"stat"`
|
Things int `cardsim:"stat" cardsim_name:"A Renamed Thing"`
|
||||||
MoreThings int `cardsim:"hidden"`
|
MoreThings int `cardsim:"hidden"`
|
||||||
FloatyThings float64 `cardsim:"round1"`
|
FloatyThings float64 `cardsim:"round1"`
|
||||||
Label string `cardsim:"stat"`
|
Label string `cardsim:"stat"`
|
||||||
|
Reference in New Issue
Block a user