2019-06-25 00:53:45 +02:00
|
|
|
import 'dart:collection';
|
|
|
|
|
2019-07-10 14:16:13 +02:00
|
|
|
import 'package:flutter/widgets.dart';
|
2019-06-25 00:53:45 +02:00
|
|
|
import 'package:json_annotation/json_annotation.dart';
|
|
|
|
|
2019-07-16 23:37:18 +02:00
|
|
|
part 'warband_roster.g.dart';
|
2019-06-25 00:53:45 +02:00
|
|
|
|
|
|
|
abstract class Unit {
|
|
|
|
static List<String> _splitListFromJson(String list) {
|
|
|
|
if (list == null) {
|
2019-08-01 00:05:42 +02:00
|
|
|
return [];
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
|
|
|
return list.split(new RegExp(r" *, *"));
|
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
static String _joinListToJson(List<String> list) {
|
|
|
|
return list.join(', ');
|
|
|
|
}
|
|
|
|
|
2019-06-25 00:53:45 +02:00
|
|
|
static Stats _statsFromJson(String stats) {
|
2019-07-06 00:44:20 +02:00
|
|
|
RegExp re = new RegExp(
|
|
|
|
r"\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*");
|
2019-08-01 00:05:42 +02:00
|
|
|
var matchList = re.allMatches(stats).toList();
|
|
|
|
|
|
|
|
if (matchList.isEmpty) {
|
|
|
|
throw FormatException(
|
|
|
|
'The stats "' + stats + '" are not in the right format.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var matches = matchList.first;
|
2019-06-25 00:53:45 +02:00
|
|
|
return Stats(
|
2019-07-06 00:44:20 +02:00
|
|
|
int.tryParse(matches.group(1)) ?? 0,
|
|
|
|
int.tryParse(matches.group(2)) ?? 0,
|
|
|
|
int.tryParse(matches.group(3)) ?? 0,
|
|
|
|
int.tryParse(matches.group(4)) ?? 0,
|
|
|
|
int.tryParse(matches.group(5)) ?? 0,
|
|
|
|
int.tryParse(matches.group(6)) ?? 0,
|
|
|
|
int.tryParse(matches.group(7)) ?? 0,
|
|
|
|
int.tryParse(matches.group(8)) ?? 0,
|
|
|
|
int.tryParse(matches.group(9)) ?? 0,
|
|
|
|
int.tryParse(matches.group(10)) ?? 0);
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
2019-08-08 20:15:06 +02:00
|
|
|
|
|
|
|
static String _statsToJson(Stats stats) {
|
|
|
|
return 'M${stats.movement}, WS${stats.weaponSkill}, BS${stats.ballisticSkill}, S${stats.strength}, T${stats.toughtness}, W${stats.wounds}, I${stats.initiative}, A${stats.attacks}, Ld${stats.leadership}, Sv${stats.save}';
|
|
|
|
}
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonSerializable(nullable: true, anyMap: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
class HenchmenGroup extends Unit {
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(
|
|
|
|
name: 'group',
|
|
|
|
fromJson: _henchmenHeaderFromJson,
|
|
|
|
toJson: _henchmengroupHeaderToJson,
|
|
|
|
required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final HashMap<String, String> header;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String name;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String type;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
int number;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
int experience;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(
|
|
|
|
fromJson: Unit._statsFromJson, toJson: Unit._statsToJson, required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final Stats stats;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<String> weapons;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-08-01 00:05:42 +02:00
|
|
|
final List<String> armour;
|
2019-06-25 00:53:45 +02:00
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
HenchmenGroup(this.header, this.stats, this.weapons, this.armour) {
|
2019-06-25 00:53:45 +02:00
|
|
|
this.name = this.header['name'];
|
|
|
|
this.type = this.header['type'];
|
|
|
|
this.number = int.tryParse(this.header['number']) ?? 1;
|
|
|
|
this.experience = int.tryParse(this.header['experience']) ?? 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HashMap<String, String> _henchmenHeaderFromJson(String header) {
|
|
|
|
HashMap<String, String> h = new HashMap();
|
2019-07-06 00:44:20 +02:00
|
|
|
RegExp re =
|
|
|
|
new RegExp(r"([^\(]+)\(([0-9]+)x?\s+([^\)]+)\)\s*\[([0-9]+)XP\]\s*");
|
2019-08-01 00:05:42 +02:00
|
|
|
var matchList = re.allMatches(header).toList();
|
|
|
|
|
|
|
|
if (matchList.isEmpty) {
|
|
|
|
throw FormatException('The henchmen group header "' +
|
|
|
|
header +
|
|
|
|
'" is not in the right format.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var matches = matchList.first;
|
2019-06-25 00:53:45 +02:00
|
|
|
|
|
|
|
h['name'] = matches.group(1);
|
2019-06-27 00:16:58 +02:00
|
|
|
h['number'] = matches.group(2);
|
|
|
|
h['type'] = matches.group(3);
|
2019-06-25 00:53:45 +02:00
|
|
|
h['experience'] = matches.group(4);
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
static String _henchmengroupHeaderToJson(
|
|
|
|
HashMap<String, String> henchmenGroup) {
|
|
|
|
return '${henchmenGroup['name']} (${henchmenGroup['number']} ${henchmenGroup['type']}) [${henchmenGroup['experience']}XP]';
|
|
|
|
}
|
|
|
|
|
2019-07-06 00:44:20 +02:00
|
|
|
factory HenchmenGroup.fromJson(yaml) => _$HenchmenGroupFromJson(yaml);
|
2019-08-08 20:15:06 +02:00
|
|
|
Map<String, dynamic> toJson() => _$HenchmenGroupToJson(this);
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonSerializable(nullable: true, anyMap: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
class Hero extends Unit {
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(
|
|
|
|
name: 'hero',
|
|
|
|
fromJson: _heroHeaderFromJson,
|
|
|
|
toJson: _heroHeaderToJson,
|
|
|
|
required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final HashMap<String, String> header;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String name;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String type;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
int experience;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(
|
|
|
|
fromJson: Unit._statsFromJson, toJson: Unit._statsToJson, required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final Stats stats;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<String> skilllists;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<String> weapons;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-08-01 00:05:42 +02:00
|
|
|
final List<String> armour;
|
2019-06-25 00:53:45 +02:00
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(fromJson: Unit._splitListFromJson, toJson: Unit._joinListToJson)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<String> rules;
|
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
@JsonKey(defaultValue: 0)
|
2019-06-25 00:53:45 +02:00
|
|
|
final int warbandaddition;
|
|
|
|
|
2019-08-07 14:55:33 +02:00
|
|
|
@JsonKey(defaultValue: false, name: 'hiredsword')
|
|
|
|
final bool hiredSword;
|
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
Hero(this.stats, this.skilllists, this.weapons, this.armour, this.rules,
|
2019-08-07 14:55:33 +02:00
|
|
|
this.warbandaddition, this.header, this.hiredSword) {
|
2019-06-25 00:53:45 +02:00
|
|
|
this.name = this.header['name'];
|
|
|
|
this.type = this.header['type'];
|
|
|
|
this.experience = int.tryParse(this.header['experience']) ?? 0;
|
|
|
|
}
|
2019-07-06 00:44:20 +02:00
|
|
|
|
|
|
|
factory Hero.fromJson(yaml) => _$HeroFromJson(yaml);
|
2019-08-08 20:15:06 +02:00
|
|
|
Map<String, dynamic> toJson() => _$HeroToJson(this);
|
2019-06-25 00:53:45 +02:00
|
|
|
|
|
|
|
static HashMap<String, String> _heroHeaderFromJson(String header) {
|
|
|
|
HashMap<String, String> h = new HashMap();
|
2019-07-06 00:44:20 +02:00
|
|
|
RegExp re = new RegExp(r"([^\(]+)\(([^\)]+)\)\s*\[([0-9]+)XP\]\s*");
|
2019-08-01 00:05:42 +02:00
|
|
|
var matchList = re.allMatches(header).toList();
|
|
|
|
|
|
|
|
if (matchList.isEmpty) {
|
|
|
|
throw FormatException(
|
|
|
|
'The hero header "' + header + '" is not in the right format.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var matches = matchList.first;
|
2019-06-25 00:53:45 +02:00
|
|
|
|
|
|
|
h['name'] = matches.group(1);
|
|
|
|
h['type'] = matches.group(2);
|
|
|
|
h['experience'] = matches.group(3);
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
2019-08-08 20:15:06 +02:00
|
|
|
|
|
|
|
static String _heroHeaderToJson(HashMap<String, String> heroHeader) {
|
|
|
|
return '${heroHeader['name']} (${heroHeader['type']}) [${heroHeader['experience']}XP]';
|
|
|
|
}
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 14:16:13 +02:00
|
|
|
@immutable
|
2019-06-25 00:53:45 +02:00
|
|
|
class Stats {
|
|
|
|
final int movement;
|
|
|
|
final int weaponSkill;
|
|
|
|
final int ballisticSkill;
|
|
|
|
final int strength;
|
|
|
|
final int toughtness;
|
|
|
|
final int wounds;
|
|
|
|
final int initiative;
|
|
|
|
final int attacks;
|
|
|
|
final int leadership;
|
|
|
|
final int save;
|
|
|
|
|
2019-07-06 00:44:20 +02:00
|
|
|
Stats(
|
|
|
|
this.movement,
|
|
|
|
this.weaponSkill,
|
|
|
|
this.ballisticSkill,
|
|
|
|
this.strength,
|
|
|
|
this.toughtness,
|
|
|
|
this.wounds,
|
|
|
|
this.initiative,
|
|
|
|
this.attacks,
|
|
|
|
this.leadership,
|
|
|
|
this.save);
|
2019-06-25 00:53:45 +02:00
|
|
|
}
|
|
|
|
|
2019-07-07 22:31:06 +02:00
|
|
|
class Version {
|
|
|
|
String gitHash;
|
|
|
|
String date;
|
|
|
|
|
|
|
|
String author;
|
|
|
|
String message;
|
|
|
|
|
|
|
|
Version(this.gitHash, this.date, this.author, this.message);
|
2019-08-08 20:15:06 +02:00
|
|
|
|
|
|
|
factory Version.fromJson(yaml) {
|
|
|
|
return Version(
|
|
|
|
yaml['gitHash'], yaml['date'], yaml['author'], yaml['message']);
|
|
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
|
|
return {
|
|
|
|
'gitHash': gitHash,
|
|
|
|
'date': date,
|
|
|
|
'author': author,
|
|
|
|
'message': message
|
|
|
|
};
|
|
|
|
}
|
2019-07-07 22:31:06 +02:00
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonSerializable(nullable: true, anyMap: true)
|
2019-07-16 23:37:18 +02:00
|
|
|
class WarbandRoster {
|
2019-07-06 00:44:20 +02:00
|
|
|
/// Store the complete string of name and race. This will split up into the
|
|
|
|
/// fields name and race.
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(
|
|
|
|
name: 'warband',
|
|
|
|
fromJson: _warbandNameAndRaceFromJson,
|
|
|
|
toJson: _warbandNameAndRaceToJson,
|
|
|
|
required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final HashMap<String, String> nameAndRace;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String name;
|
|
|
|
@JsonKey(ignore: true)
|
|
|
|
String race;
|
|
|
|
|
2019-07-25 16:44:51 +02:00
|
|
|
@JsonKey(name: 'active', defaultValue: true)
|
2019-07-09 23:43:57 +02:00
|
|
|
bool active;
|
|
|
|
|
2019-07-25 16:44:51 +02:00
|
|
|
@JsonKey(name: 'campaign', defaultValue: 0)
|
2019-06-25 00:53:45 +02:00
|
|
|
final int campaignPoints;
|
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
@JsonKey(required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final String objective;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
@JsonKey(required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final String alignment;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
|
|
|
@JsonKey(defaultValue: '')
|
2019-06-25 00:53:45 +02:00
|
|
|
final String achievments;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
|
|
|
@JsonKey(defaultValue: 0)
|
2019-06-25 00:53:45 +02:00
|
|
|
final int gc;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
|
|
|
@JsonKey(defaultValue: 0)
|
2019-06-25 00:53:45 +02:00
|
|
|
final int shards;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
|
|
|
@JsonKey(defaultValue: '')
|
2019-06-25 00:53:45 +02:00
|
|
|
final String equipment;
|
2019-07-25 16:44:51 +02:00
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
@JsonKey(required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<Hero> heros;
|
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
@JsonKey(name: 'henchmen', required: true)
|
2019-06-25 00:53:45 +02:00
|
|
|
final List<HenchmenGroup> henchmenGroups;
|
|
|
|
|
2019-07-06 00:44:20 +02:00
|
|
|
/// The players name is not defined in the yml file. This will be added later
|
2019-07-27 00:09:51 +02:00
|
|
|
/// from the GitHubAdapter. Same goes for the lastSyncVersion and currentVersion.
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(required: false, defaultValue: 'Lonely Recluse')
|
|
|
|
String playerName;
|
2019-07-07 22:31:06 +02:00
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(required: false)
|
2019-07-27 00:09:51 +02:00
|
|
|
String filePath;
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(required: false)
|
2019-07-30 00:30:39 +02:00
|
|
|
Version version;
|
2019-07-09 23:43:57 +02:00
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
@JsonKey(required: false, defaultValue: true)
|
|
|
|
bool unseen;
|
2019-07-06 00:44:20 +02:00
|
|
|
|
2019-07-16 23:37:18 +02:00
|
|
|
WarbandRoster(
|
2019-07-06 00:44:20 +02:00
|
|
|
this.nameAndRace,
|
|
|
|
this.campaignPoints,
|
|
|
|
this.objective,
|
|
|
|
this.alignment,
|
|
|
|
this.gc,
|
|
|
|
this.shards,
|
|
|
|
this.equipment,
|
|
|
|
this.achievments,
|
|
|
|
this.heros,
|
2019-08-08 20:15:06 +02:00
|
|
|
this.henchmenGroups,
|
|
|
|
this.playerName,
|
|
|
|
this.filePath,
|
|
|
|
this.version,
|
|
|
|
this.unseen) {
|
2019-06-25 00:53:45 +02:00
|
|
|
this.name = this.nameAndRace['name'];
|
|
|
|
this.race = this.nameAndRace['race'];
|
|
|
|
}
|
|
|
|
|
2019-07-10 14:16:13 +02:00
|
|
|
int experience() {
|
|
|
|
// TODO: Calculate
|
|
|
|
return 1337;
|
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
static HashMap<String, String> _warbandNameAndRaceFromJson(
|
|
|
|
String nameAndRace) {
|
2019-06-25 00:53:45 +02:00
|
|
|
HashMap<String, String> nr = new HashMap();
|
|
|
|
RegExp re = new RegExp(r"(.*) \((.*)\)");
|
|
|
|
|
2019-08-01 00:05:42 +02:00
|
|
|
var matchList = re.allMatches(nameAndRace).toList();
|
|
|
|
|
|
|
|
if (matchList.isEmpty) {
|
|
|
|
throw FormatException(
|
|
|
|
'Name and race "' + nameAndRace + '" are not in the right format.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var matches = matchList.first;
|
|
|
|
nr['name'] = matches.group(1).toString();
|
|
|
|
nr['race'] = matches.group(2).toString();
|
2019-06-25 00:53:45 +02:00
|
|
|
|
|
|
|
return nr;
|
|
|
|
}
|
|
|
|
|
2019-08-08 20:15:06 +02:00
|
|
|
static String _warbandNameAndRaceToJson(HashMap<String, String> nameAndRace) {
|
|
|
|
return '${nameAndRace['name']} (${nameAndRace['race']})';
|
|
|
|
}
|
|
|
|
|
2019-07-16 23:37:18 +02:00
|
|
|
factory WarbandRoster.fromJson(yaml) => _$WarbandRosterFromJson(yaml);
|
2019-08-08 20:15:06 +02:00
|
|
|
Map<String, dynamic> toJson() => _$WarbandRosterToJson(this);
|
2019-07-06 00:44:20 +02:00
|
|
|
}
|