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 }