66 lines
1.9 KiB
Go
66 lines
1.9 KiB
Go
package common
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type CurrencyWarsMergeRules struct {
|
|
Format uint32 `json:"format_version"`
|
|
Client string `json:"target_client_version"`
|
|
Assembly string `json:"target_assembly_sha256"`
|
|
Capture string `json:"source_capture_sha256"`
|
|
Copies uint32 `json:"copies_required"`
|
|
OrdinaryMaxStar uint32 `json:"ordinary_max_star"`
|
|
}
|
|
|
|
func (c *CurrencyWarsCatalog) MergeRules() (CurrencyWarsMergeRules, error) {
|
|
var r CurrencyWarsMergeRules
|
|
raw, e := ReadResourceFile("resources/CurrencyWarsMergeRules.json")
|
|
if e != nil {
|
|
return r, e
|
|
}
|
|
if e = json.Unmarshal(raw, &r); e != nil {
|
|
return r, e
|
|
}
|
|
digest, e := hex.DecodeString(r.Capture)
|
|
if e != nil || len(digest) != sha256.Size || r.Format != 1 || r.Client != c.ClientVersion || r.Assembly != c.Provenance.GameAssemblySHA256 || r.Copies < 2 || r.Copies > 64 || r.OrdinaryMaxStar == 0 || r.OrdinaryMaxStar > 16 {
|
|
return r, fmt.Errorf("CW merge rules missing or revision differs")
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// Reserve merged cards as their physical underlying copies. Ordinary full-star
|
|
// roles are excluded from new draws; returning unsold offers keeps exclusion.
|
|
func (p *CurrencyWarsCardPool) ReserveOwned(c *CurrencyWarsCatalog, id, star uint32) error {
|
|
entry, ok := p.Roles[id]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
base, e := c.CapturedRole(id)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
rules, e := c.MergeRules()
|
|
if e != nil {
|
|
return e
|
|
}
|
|
if star < base.DefaultStar || star > base.MaxStar {
|
|
return fmt.Errorf("CW owned star is invalid")
|
|
}
|
|
copies := uint64(1)
|
|
for s := base.DefaultStar; s < star; s++ {
|
|
copies *= uint64(rules.Copies)
|
|
}
|
|
if copies >= uint64(entry.Remaining) {
|
|
entry.Remaining = 0
|
|
} else {
|
|
entry.Remaining -= uint32(copies)
|
|
}
|
|
entry.Disabled = entry.Disabled || star >= rules.OrdinaryMaxStar || entry.Remaining == 0
|
|
p.Roles[id] = entry
|
|
return nil
|
|
}
|