235 lines
6.9 KiB
Go
235 lines
6.9 KiB
Go
|
package parser
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
//"fmt"
|
||
|
|
||
|
//"github.com/davecgh/go-spew/spew"
|
||
|
"github.com/ghodss/yaml"
|
||
|
)
|
||
|
|
||
|
type Warband struct {
|
||
|
Warband *WarbandName `json:"warband"`
|
||
|
Rating int `json:"rating"`
|
||
|
CampaignPoints int `json:"campaign"`
|
||
|
GoldCrowns int `json:"gc"`
|
||
|
Shards int `json:"shards"`
|
||
|
Equipment *ItemList `json:"equipment"`
|
||
|
Heros []*Hero `json:"heros"`
|
||
|
HenchmenGroups []*HenchmenGroup `json:"henchmen"`
|
||
|
Notes string `json:"notes"`
|
||
|
Objective string `json:"objective"`
|
||
|
|
||
|
Henchmen_sum_xp int
|
||
|
Henchmen_cnt int
|
||
|
Hero_sum_xp int
|
||
|
Hero_cnt int
|
||
|
Hiredsword_sum_xp int
|
||
|
Hiredsword_cnt int
|
||
|
Large_cnt int
|
||
|
Routtest int
|
||
|
WarbandAddition_sum int
|
||
|
}
|
||
|
|
||
|
type WarbandName struct {
|
||
|
Name string
|
||
|
Race string
|
||
|
}
|
||
|
|
||
|
type ItemList struct {
|
||
|
List []string
|
||
|
}
|
||
|
|
||
|
type Hero struct {
|
||
|
Header string `json:"hero"`
|
||
|
Name string
|
||
|
Type string
|
||
|
Experience int
|
||
|
WarbandAddition int `json:"warbandaddition,omitempty"`
|
||
|
Stats *Stats `json:"stats,omitempty"`
|
||
|
Large bool `json:"large"`
|
||
|
HiredSword bool `json:"hiredsword"`
|
||
|
Weapons *ItemList `json:"weapons,omitempty"`
|
||
|
Armour *ItemList `json:"armour,omitempty"`
|
||
|
Rules *ItemList `json:"rules,omitempty"`
|
||
|
SkillLists *ItemList `json:"skilllists,omitempty"`
|
||
|
BSkillLists Skilllist
|
||
|
}
|
||
|
|
||
|
type HenchmenGroup struct {
|
||
|
Header string `json:"group"`
|
||
|
Name string
|
||
|
Number int
|
||
|
Type string
|
||
|
Experience int
|
||
|
Large bool `json:"large"`
|
||
|
Stats *Stats `json:"stats"`
|
||
|
Weapons *ItemList `json:"weapons"`
|
||
|
Armour *ItemList `json:"armour"`
|
||
|
Rules *ItemList `json:"rules"`
|
||
|
}
|
||
|
|
||
|
type Weapons struct {
|
||
|
MainHand string
|
||
|
OffHand string
|
||
|
}
|
||
|
|
||
|
type Stats struct {
|
||
|
Movement string
|
||
|
WeaponSkill int
|
||
|
BallisticSkill int
|
||
|
Strength int
|
||
|
Toughness int
|
||
|
Wounds int
|
||
|
Initiative int
|
||
|
Attacks int
|
||
|
Leadership int
|
||
|
Save string
|
||
|
}
|
||
|
|
||
|
type Skilllist struct {
|
||
|
Strength bool
|
||
|
Academic bool
|
||
|
Combat bool
|
||
|
Shooting bool
|
||
|
Speed bool
|
||
|
Special bool
|
||
|
}
|
||
|
|
||
|
func (stats *Stats) UnmarshalJSON(b []byte) error {
|
||
|
regex := regexp.MustCompile(`"\s*M([0-9]+[dD]*[6]*)\s*,\s*WS([0-9]+)\s*,\s*BS([0-9]+)\s*,\s*S([0-9]+)\s*,\s*T([0-9]+)\s*,\s*W([0-9]+)\s*,\s*I([0-9]+)\s*,\s*A([0-9]+)\s*,\s*Ld([0-9]+)\s*,\s*Sv([0-9\-]+)\s*"`)
|
||
|
matches := regex.FindStringSubmatch(string(b))
|
||
|
stats.Movement = matches[1]
|
||
|
stats.WeaponSkill, _ = strconv.Atoi(matches[2])
|
||
|
stats.BallisticSkill, _ = strconv.Atoi(matches[3])
|
||
|
stats.Strength, _ = strconv.Atoi(matches[4])
|
||
|
stats.Toughness, _ = strconv.Atoi(matches[5])
|
||
|
stats.Wounds, _ = strconv.Atoi(matches[6])
|
||
|
stats.Initiative, _ = strconv.Atoi(matches[7])
|
||
|
stats.Attacks, _ = strconv.Atoi(matches[8])
|
||
|
stats.Leadership, _ = strconv.Atoi(matches[9])
|
||
|
stats.Save = matches[10]
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (warband *WarbandName) UnmarshalJSON(b []byte) error {
|
||
|
regex := regexp.MustCompile(`"([^\(]+)\(([^\)]+)\)`)
|
||
|
matches := regex.FindStringSubmatch(string(b))
|
||
|
warband.Name = strings.TrimSpace(matches[1])
|
||
|
warband.Race = strings.TrimSpace(matches[2])
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (itemList *ItemList) UnmarshalJSON(b []byte) error {
|
||
|
items := strings.Split(string(b[1:len(b)-1]), ",")
|
||
|
for _, item := range items {
|
||
|
itemList.List = append(itemList.List, strings.TrimSpace(item))
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (hands *Weapons) UnmarshalJSON(b []byte) error {
|
||
|
items := strings.Split(string(b[1:len(b)-1]), ",")
|
||
|
hands.MainHand = strings.TrimSpace(items[0])
|
||
|
if len(items) > 1 {
|
||
|
hands.OffHand = strings.TrimSpace(items[1])
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func ParseWarband(warbandDefinition []byte) Warband {
|
||
|
var warband Warband
|
||
|
|
||
|
err := yaml.Unmarshal(warbandDefinition, &warband)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
for _, h := range warband.Heros {
|
||
|
regex := regexp.MustCompile(`([^\(]+)\(([^\)]+)\)\s*\[([0-9]+)XP\]\s*`)
|
||
|
matches := regex.FindStringSubmatch(string(h.Header))
|
||
|
h.Name = strings.TrimSpace(matches[1])
|
||
|
h.Type = strings.TrimSpace(matches[2])
|
||
|
h.Experience, _ = strconv.Atoi(strings.TrimSpace(matches[3]))
|
||
|
if h.WarbandAddition > 0 {
|
||
|
warband.Rating = warband.Rating + h.WarbandAddition
|
||
|
warband.WarbandAddition_sum = warband.WarbandAddition_sum + h.WarbandAddition
|
||
|
}
|
||
|
|
||
|
if !h.Large && !h.HiredSword {
|
||
|
warband.Rating = warband.Rating + h.Experience + 5
|
||
|
warband.Hero_sum_xp = warband.Hero_sum_xp + h.Experience
|
||
|
warband.Hero_cnt = warband.Hero_cnt + 1
|
||
|
} else if h.Large {
|
||
|
warband.Rating = warband.Rating + h.Experience + 20
|
||
|
warband.Hero_sum_xp = warband.Hero_sum_xp + h.Experience
|
||
|
warband.Large_cnt = warband.Large_cnt + 1
|
||
|
} else if h.HiredSword {
|
||
|
warband.Rating = warband.Rating + h.Experience + 5
|
||
|
warband.Hiredsword_sum_xp = warband.Hiredsword_sum_xp + h.Experience
|
||
|
warband.Hiredsword_cnt = warband.Hiredsword_cnt + 1
|
||
|
} // TODO it is not possible that a large hired sword can be added
|
||
|
|
||
|
// hier text Skill listen-Name zu boolschen Wert umwandeln
|
||
|
h.BSkillLists.Speed = false
|
||
|
h.BSkillLists.Shooting = false
|
||
|
h.BSkillLists.Special = false
|
||
|
h.BSkillLists.Combat = false
|
||
|
h.BSkillLists.Academic = false
|
||
|
h.BSkillLists.Strength = false
|
||
|
for _, s := range h.SkillLists.List {
|
||
|
if strings.EqualFold(s, "Speed") {
|
||
|
h.BSkillLists.Speed = true
|
||
|
}
|
||
|
if strings.EqualFold(s, "Shooting") {
|
||
|
h.BSkillLists.Shooting = true
|
||
|
}
|
||
|
if strings.EqualFold(s, "Special") {
|
||
|
h.BSkillLists.Special = true
|
||
|
}
|
||
|
if strings.EqualFold(s, "Combat") {
|
||
|
h.BSkillLists.Combat = true
|
||
|
}
|
||
|
if strings.EqualFold(s, "Academic") {
|
||
|
h.BSkillLists.Academic = true
|
||
|
}
|
||
|
if strings.EqualFold(s, "Strength") {
|
||
|
h.BSkillLists.Strength = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, hg := range warband.HenchmenGroups {
|
||
|
regex := regexp.MustCompile(`([^\(]+)\(([0-9]+)x?\s+([^\)]+)\)\s*\[([0-9]+)XP\]\s*`)
|
||
|
matches := regex.FindStringSubmatch(string(hg.Header))
|
||
|
hg.Name = strings.TrimSpace(matches[1])
|
||
|
hg.Number, _ = strconv.Atoi(strings.TrimSpace(matches[2]))
|
||
|
hg.Type = strings.TrimSpace(matches[3])
|
||
|
hg.Experience, _ = strconv.Atoi(strings.TrimSpace(matches[4]))
|
||
|
if !hg.Large {
|
||
|
warband.Henchmen_sum_xp = warband.Henchmen_sum_xp + (hg.Experience * hg.Number)
|
||
|
warband.Henchmen_cnt = warband.Henchmen_cnt + hg.Number
|
||
|
warband.Rating = warband.Rating + (hg.Experience+5)*hg.Number
|
||
|
} else {
|
||
|
warband.Henchmen_sum_xp = warband.Henchmen_sum_xp + (hg.Experience * hg.Number)
|
||
|
warband.Large_cnt = warband.Large_cnt + 1
|
||
|
warband.Rating = warband.Rating + (hg.Experience+20)*hg.Number
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
warband.Routtest = int(math.RoundToEven(float64(warband.Hero_cnt+warband.Henchmen_cnt+warband.Large_cnt+warband.Hiredsword_cnt) / 4.0))
|
||
|
if float64(warband.Hero_cnt+warband.Henchmen_cnt+warband.Large_cnt+warband.Hiredsword_cnt)/4.0 > float64(warband.Routtest) {
|
||
|
warband.Routtest = warband.Routtest + 1
|
||
|
}
|
||
|
|
||
|
//spew.Dump(warband)
|
||
|
|
||
|
return warband
|
||
|
}
|