mirror of
https://github.com/DungeonPaper/dungeon_world_data.git
synced 2026-05-17 18:08:01 +00:00
new classes wip + parsing
This commit is contained in:
57
.vscode/launch.json
vendored
57
.vscode/launch.json
vendored
@@ -4,28 +4,35 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "All Tests",
|
||||
"type": "dart",
|
||||
"request": "launch",
|
||||
"program": "test/"
|
||||
},
|
||||
{
|
||||
"name": "Main",
|
||||
"program": "bin/dw_data.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "Example",
|
||||
"program": "example/example.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "Dump Dart",
|
||||
"program": "scripts/dump/dump.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
}, ]
|
||||
}
|
||||
{
|
||||
"name": "Dart - Current File",
|
||||
"type": "dart",
|
||||
"request": "launch",
|
||||
"program": "${file}"
|
||||
},
|
||||
{
|
||||
"name": "All Tests",
|
||||
"type": "dart",
|
||||
"request": "launch",
|
||||
"program": "test/"
|
||||
},
|
||||
{
|
||||
"name": "Main",
|
||||
"program": "bin/dw_data.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "Example",
|
||||
"program": "example/example.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "Dump Dart",
|
||||
"program": "scripts/dump/dump.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Defines a default set of lint rules enforced for
|
||||
# projects at Google. For details and rationale,
|
||||
# see https://github.com/dart-lang/pedantic#enabled-lints.
|
||||
include: package:pedantic/analysis_options.yaml
|
||||
include: package:lints/recommended.yaml
|
||||
analyzer:
|
||||
exclude:
|
||||
- example/*.dart
|
||||
|
||||
3
lib/_utils/uuid.dart
Normal file
3
lib/_utils/uuid.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
String uuid() => Uuid().v4();
|
||||
88
lib/alignment.dart
Normal file
88
lib/alignment.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class AlignmentValue {
|
||||
AlignmentValue({
|
||||
required this.key,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
final String key;
|
||||
final String description;
|
||||
|
||||
AlignmentValue copyWith({
|
||||
String? key,
|
||||
String? description,
|
||||
}) =>
|
||||
AlignmentValue(
|
||||
key: key ?? this.key,
|
||||
description: description ?? this.description,
|
||||
);
|
||||
|
||||
factory AlignmentValue.fromRawJson(String str) =>
|
||||
AlignmentValue.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory AlignmentValue.fromJson(Map<String, dynamic> json) => AlignmentValue(
|
||||
key: json["key"],
|
||||
description: json["description"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"key": key,
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
|
||||
class AlignmentValues {
|
||||
AlignmentValues({
|
||||
required this.good,
|
||||
required this.evil,
|
||||
required this.lawful,
|
||||
required this.neutral,
|
||||
required this.chaotic,
|
||||
});
|
||||
|
||||
final String good;
|
||||
final String evil;
|
||||
final String lawful;
|
||||
final String neutral;
|
||||
final String chaotic;
|
||||
|
||||
AlignmentValues copyWith({
|
||||
String? good,
|
||||
String? evil,
|
||||
String? lawful,
|
||||
String? neutral,
|
||||
String? chaotic,
|
||||
}) =>
|
||||
AlignmentValues(
|
||||
good: good ?? this.good,
|
||||
evil: evil ?? this.evil,
|
||||
lawful: lawful ?? this.lawful,
|
||||
neutral: neutral ?? this.neutral,
|
||||
chaotic: chaotic ?? this.chaotic,
|
||||
);
|
||||
|
||||
factory AlignmentValues.fromRawJson(String str) =>
|
||||
AlignmentValues.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory AlignmentValues.fromJson(Map<String, dynamic> json) =>
|
||||
AlignmentValues(
|
||||
good: json["good"],
|
||||
evil: json["evil"],
|
||||
lawful: json["lawful"],
|
||||
neutral: json["neutral"],
|
||||
chaotic: json["chaotic"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"good": good,
|
||||
"evil": evil,
|
||||
"lawful": lawful,
|
||||
"neutral": neutral,
|
||||
"chaotic": chaotic,
|
||||
};
|
||||
}
|
||||
40
lib/bond.dart
Normal file
40
lib/bond.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class Bond {
|
||||
Bond({
|
||||
required this.key,
|
||||
required this.description,
|
||||
required this.completed,
|
||||
});
|
||||
|
||||
final String key;
|
||||
final String description;
|
||||
final bool completed;
|
||||
|
||||
Bond copyWith({
|
||||
String? key,
|
||||
String? description,
|
||||
bool? completed,
|
||||
}) =>
|
||||
Bond(
|
||||
key: key ?? this.key,
|
||||
description: description ?? this.description,
|
||||
completed: completed ?? this.completed,
|
||||
);
|
||||
|
||||
factory Bond.fromRawJson(String str) => Bond.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Bond.fromJson(Map<String, dynamic> json) => Bond(
|
||||
key: json["key"],
|
||||
completed: json["completed"],
|
||||
description: json["description"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"key": key,
|
||||
"description": description,
|
||||
"completed": completed,
|
||||
};
|
||||
}
|
||||
89
lib/character_class.dart
Normal file
89
lib/character_class.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'alignment.dart';
|
||||
import 'dice.dart';
|
||||
import 'gear_choice.dart';
|
||||
|
||||
class CharacterClass {
|
||||
CharacterClass({
|
||||
required this.meta,
|
||||
required this.name,
|
||||
required this.key,
|
||||
required this.description,
|
||||
required this.damageDice,
|
||||
required this.load,
|
||||
required this.hp,
|
||||
required this.alignments,
|
||||
required this.bonds,
|
||||
required this.gearChoices,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String name;
|
||||
final String key;
|
||||
final String description;
|
||||
final Dice damageDice;
|
||||
final int load;
|
||||
final int hp;
|
||||
final AlignmentValues alignments;
|
||||
final List<String> bonds;
|
||||
final List<GearChoice> gearChoices;
|
||||
|
||||
CharacterClass copyWith({
|
||||
dynamic meta,
|
||||
String? name,
|
||||
String? key,
|
||||
String? description,
|
||||
Dice? damageDice,
|
||||
int? load,
|
||||
int? hp,
|
||||
AlignmentValues? alignments,
|
||||
List<String>? bonds,
|
||||
List<GearChoice>? gearChoices,
|
||||
}) =>
|
||||
CharacterClass(
|
||||
meta: meta ?? this.meta,
|
||||
name: name ?? this.name,
|
||||
key: key ?? this.key,
|
||||
description: description ?? this.description,
|
||||
damageDice: damageDice ?? this.damageDice,
|
||||
load: load ?? this.load,
|
||||
hp: hp ?? this.hp,
|
||||
alignments: alignments ?? this.alignments,
|
||||
bonds: bonds ?? this.bonds,
|
||||
gearChoices: gearChoices ?? this.gearChoices,
|
||||
);
|
||||
|
||||
factory CharacterClass.fromRawJson(String str) =>
|
||||
CharacterClass.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory CharacterClass.fromJson(Map<String, dynamic> json) => CharacterClass(
|
||||
meta: json['_meta'],
|
||||
name: json["name"],
|
||||
key: json["key"],
|
||||
description: json["description"],
|
||||
damageDice: Dice.fromJson(json["damageDice"]),
|
||||
load: json["load"],
|
||||
hp: json["hp"],
|
||||
alignments: AlignmentValues.fromJson(json["alignments"]),
|
||||
bonds: List<String>.from(json["bonds"].map((x) => x)),
|
||||
gearChoices: List<GearChoice>.from(
|
||||
json["gearChoices"].map((x) => GearChoice.fromJson(x)),
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"name": name,
|
||||
"key": key,
|
||||
"description": description,
|
||||
"damageDice": damageDice.toJson(),
|
||||
"load": load,
|
||||
"hp": hp,
|
||||
"alignments": alignments.toJson(),
|
||||
"bonds": List<dynamic>.from(bonds.map((x) => x)),
|
||||
"gearChoices": List<dynamic>.from(gearChoices.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
105
lib/dice.dart
Normal file
105
lib/dice.dart
Normal file
@@ -0,0 +1,105 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
class Dice {
|
||||
Dice({
|
||||
required this.amount,
|
||||
required this.sides,
|
||||
this.modifier,
|
||||
});
|
||||
|
||||
final int amount;
|
||||
final int sides;
|
||||
final int? modifier;
|
||||
|
||||
Dice copyWith({
|
||||
int? amount,
|
||||
int? sides,
|
||||
int? modifier,
|
||||
}) =>
|
||||
Dice(
|
||||
amount: amount ?? this.amount,
|
||||
sides: sides ?? this.sides,
|
||||
modifier: modifier ?? this.modifier,
|
||||
);
|
||||
|
||||
factory Dice.fromRawJson(String str) => Dice.fromJson(json.decode(str));
|
||||
|
||||
static Dice d4 = Dice(amount: 1, sides: 4);
|
||||
static Dice d6 = Dice(amount: 1, sides: 6);
|
||||
static Dice d8 = Dice(amount: 1, sides: 8);
|
||||
static Dice d10 = Dice(amount: 1, sides: 10);
|
||||
static Dice d12 = Dice(amount: 1, sides: 12);
|
||||
static Dice d20 = Dice(amount: 1, sides: 20);
|
||||
static Dice d60 = Dice(amount: 1, sides: 60);
|
||||
static Dice d100 = Dice(amount: 1, sides: 100);
|
||||
|
||||
String toRawJson() => toJson();
|
||||
|
||||
factory Dice.fromJson(String json) {
|
||||
var parts = json.split("d");
|
||||
var amount = int.tryParse(parts[0]);
|
||||
int? sides;
|
||||
int? modifier;
|
||||
if (parts[1].contains(RegExp(r'[-+]'))) {
|
||||
var idx = parts[1].indexOf(RegExp(r'[^0-9]'));
|
||||
sides = int.tryParse(parts[1].substring(0, idx));
|
||||
modifier = int.tryParse(parts[1].substring(idx));
|
||||
} else {
|
||||
sides = int.tryParse(parts[1]);
|
||||
}
|
||||
|
||||
if (sides == null || amount == null) {
|
||||
throw Exception("Dice parsing failed");
|
||||
}
|
||||
|
||||
return Dice(
|
||||
amount: amount,
|
||||
sides: sides,
|
||||
modifier: modifier,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => "${amount}d$sides$modifierWithSign";
|
||||
|
||||
String toJson() => toString();
|
||||
|
||||
String get modifierWithSign => modifier == null
|
||||
? ""
|
||||
: modifier! > 0
|
||||
? "+$modifier"
|
||||
: "$modifier";
|
||||
|
||||
DiceResult roll() => DiceResult.roll(this);
|
||||
|
||||
operator *(int amount) => copyWith(amount: this.amount * amount);
|
||||
operator /(int amount) => copyWith(amount: this.amount ~/ amount);
|
||||
}
|
||||
|
||||
class DiceResult {
|
||||
final Dice dice;
|
||||
final List<int> results;
|
||||
|
||||
DiceResult({required this.dice, required this.results});
|
||||
|
||||
static List<DiceResult> rollMany(List<Dice> dice) {
|
||||
return dice.map((d) {
|
||||
var arr = <int>[];
|
||||
for (var i = 0; i < d.amount; i++) {
|
||||
arr.add(Random().nextInt(d.sides));
|
||||
}
|
||||
return DiceResult(dice: d, results: arr);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
int get total =>
|
||||
results.reduce((all, cur) => all + cur) + (dice.modifier ?? 0);
|
||||
|
||||
bool get didHitNaturalMax => indexOfNaturalMax >= 0;
|
||||
int get indexOfNaturalMax => results.indexOf(dice.sides);
|
||||
|
||||
static DiceResult roll(Dice dice) {
|
||||
return rollMany([dice])[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export 'alignment.dart';
|
||||
export 'bond.dart';
|
||||
export 'bond.dart';
|
||||
export 'character_class.dart';
|
||||
export 'dice.dart';
|
||||
export 'gear_choice.dart';
|
||||
export 'gear_selection.dart';
|
||||
export 'item.dart';
|
||||
export 'move.dart';
|
||||
export 'race.dart';
|
||||
export 'spell.dart';
|
||||
export 'tag.dart';
|
||||
|
||||
44
lib/gear_choice.dart
Normal file
44
lib/gear_choice.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'gear_selection.dart';
|
||||
|
||||
class GearChoice {
|
||||
GearChoice({
|
||||
required this.key,
|
||||
required this.description,
|
||||
required this.selections,
|
||||
});
|
||||
|
||||
final String key;
|
||||
final String description;
|
||||
final List<GearSelection> selections;
|
||||
|
||||
GearChoice copyWith({
|
||||
String? key,
|
||||
String? description,
|
||||
List<GearSelection>? selections,
|
||||
}) =>
|
||||
GearChoice(
|
||||
key: key ?? this.key,
|
||||
description: description ?? this.description,
|
||||
selections: selections ?? this.selections,
|
||||
);
|
||||
|
||||
factory GearChoice.fromRawJson(String str) =>
|
||||
GearChoice.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory GearChoice.fromJson(Map<String, dynamic> json) => GearChoice(
|
||||
key: json["key"],
|
||||
description: json["description"],
|
||||
selections: List<GearSelection>.from(
|
||||
json["selections"].map((x) => GearSelection.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"key": key,
|
||||
"description": description,
|
||||
"selections": List<dynamic>.from(selections.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
37
lib/gear_option.dart
Normal file
37
lib/gear_option.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'item.dart';
|
||||
|
||||
class GearOption {
|
||||
GearOption({
|
||||
required this.item,
|
||||
required this.amount,
|
||||
});
|
||||
|
||||
final Item item;
|
||||
final double amount;
|
||||
|
||||
GearOption copyWith({
|
||||
Item? item,
|
||||
double? amount,
|
||||
}) =>
|
||||
GearOption(
|
||||
item: item ?? this.item,
|
||||
amount: amount ?? this.amount,
|
||||
);
|
||||
|
||||
factory GearOption.fromRawJson(String str) =>
|
||||
GearOption.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory GearOption.fromJson(Map<String, dynamic> json) => GearOption(
|
||||
item: json["item"],
|
||||
amount: json["amount"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"item": item,
|
||||
"amount": amount,
|
||||
};
|
||||
}
|
||||
45
lib/gear_selection.dart
Normal file
45
lib/gear_selection.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'gear_option.dart';
|
||||
import 'item.dart';
|
||||
|
||||
class GearSelection {
|
||||
GearSelection({
|
||||
required this.description,
|
||||
required this.items,
|
||||
required this.gold,
|
||||
});
|
||||
|
||||
final String description;
|
||||
final List<GearOption> items;
|
||||
final int gold;
|
||||
|
||||
GearSelection copyWith({
|
||||
String? description,
|
||||
List<GearOption>? items,
|
||||
int? gold,
|
||||
}) =>
|
||||
GearSelection(
|
||||
description: description ?? this.description,
|
||||
items: items ?? this.items,
|
||||
gold: gold ?? this.gold,
|
||||
);
|
||||
|
||||
factory GearSelection.fromRawJson(String str) =>
|
||||
GearSelection.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory GearSelection.fromJson(Map<String, dynamic> json) => GearSelection(
|
||||
description: json["description"],
|
||||
items: List<GearOption>.from(
|
||||
json["items"].map((x) => GearOption.fromJson(x))),
|
||||
gold: json["gold"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"description": description,
|
||||
"items": List<dynamic>.from(items.map((x) => x.toJson())),
|
||||
"gold": gold,
|
||||
};
|
||||
}
|
||||
53
lib/item.dart
Normal file
53
lib/item.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'tag.dart';
|
||||
|
||||
class Item {
|
||||
Item({
|
||||
required this.meta,
|
||||
required this.key,
|
||||
required this.description,
|
||||
required this.name,
|
||||
required this.tags,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String key;
|
||||
final String name;
|
||||
final String description;
|
||||
final List<Tag> tags;
|
||||
|
||||
Item copyWith({
|
||||
dynamic meta,
|
||||
String? key,
|
||||
String? name,
|
||||
List<Tag>? tags,
|
||||
}) =>
|
||||
Item(
|
||||
meta: meta ?? this.meta,
|
||||
key: key ?? this.key,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
tags: tags ?? this.tags,
|
||||
);
|
||||
|
||||
factory Item.fromRawJson(String str) => Item.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Item.fromJson(Map<String, dynamic> json) => Item(
|
||||
meta: json["_meta"],
|
||||
key: json["key"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
tags: List<Tag>.from(json["tags"].map((x) => Tag.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"key": key,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"tags": List<dynamic>.from(tags.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
38
lib/models/repository.dart
Normal file
38
lib/models/repository.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
class Repository {}
|
||||
|
||||
class RepositoryItem<T> {
|
||||
final Map<String, Map<String, T>> _cache = {};
|
||||
String currentLocale;
|
||||
|
||||
RepositoryItem({
|
||||
required this.currentLocale,
|
||||
});
|
||||
|
||||
List<T> get list {
|
||||
_ensureLocale(currentLocale);
|
||||
return _cache[currentLocale]!.values.toList();
|
||||
}
|
||||
|
||||
Map<String, T> get map {
|
||||
_ensureLocale(currentLocale);
|
||||
return _cache[currentLocale]!;
|
||||
}
|
||||
|
||||
void registerLocale(String locale) {
|
||||
if (_cache[locale] != null) {
|
||||
return;
|
||||
}
|
||||
_cache[locale] = {};
|
||||
}
|
||||
|
||||
void addItems(String locale, Map<String, T> items) {
|
||||
_ensureLocale(locale);
|
||||
_cache[locale]!.addAll(items);
|
||||
}
|
||||
|
||||
void _ensureLocale(String locale) {
|
||||
if (_cache[locale] == null) {
|
||||
throw Exception('Locale $locale does not exist.');
|
||||
}
|
||||
}
|
||||
}
|
||||
67
lib/monster.dart
Normal file
67
lib/monster.dart
Normal file
@@ -0,0 +1,67 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'move.dart';
|
||||
import 'tag.dart';
|
||||
|
||||
class Monster {
|
||||
Monster({
|
||||
required this.meta,
|
||||
required this.key,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.instinct,
|
||||
required this.tags,
|
||||
required this.moves,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String key;
|
||||
final String name;
|
||||
final String description;
|
||||
final String instinct;
|
||||
final List<Tag> tags;
|
||||
final List<String> moves;
|
||||
|
||||
Monster copyWith({
|
||||
dynamic meta,
|
||||
String? key,
|
||||
String? name,
|
||||
String? description,
|
||||
String? instinct,
|
||||
List<Tag>? tags,
|
||||
List<String>? moves,
|
||||
}) =>
|
||||
Monster(
|
||||
meta: meta ?? this.meta,
|
||||
key: key ?? this.key,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
instinct: instinct ?? this.instinct,
|
||||
tags: tags ?? this.tags,
|
||||
moves: moves ?? this.moves,
|
||||
);
|
||||
|
||||
factory Monster.fromRawJson(String str) => Monster.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Monster.fromJson(Map<String, dynamic> json) => Monster(
|
||||
meta: json["_meta"],
|
||||
key: json["key"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
instinct: json["instinct"],
|
||||
tags: List<Tag>.from(json["tags"].map((x) => Tag.fromJson(x))),
|
||||
moves: json["moves"].map((x) => x),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"key": key,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"instinct": instinct,
|
||||
"tags": List<dynamic>.from(tags.map((x) => x.toJson())),
|
||||
"moves": moves,
|
||||
};
|
||||
}
|
||||
88
lib/move.dart
Normal file
88
lib/move.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'dice.dart';
|
||||
import 'tag.dart';
|
||||
|
||||
enum MoveCategory {
|
||||
starting,
|
||||
basic,
|
||||
advanced1,
|
||||
advanced2,
|
||||
other,
|
||||
}
|
||||
|
||||
class Move {
|
||||
Move({
|
||||
required this.meta,
|
||||
required this.key,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.explanation,
|
||||
required this.dice,
|
||||
required this.classKeys,
|
||||
required this.tags,
|
||||
required this.category,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String key;
|
||||
final String name;
|
||||
final String description;
|
||||
final String explanation;
|
||||
final List<Dice> dice;
|
||||
final List<String> classKeys;
|
||||
final List<Tag> tags;
|
||||
final MoveCategory category;
|
||||
|
||||
Move copyWith({
|
||||
dynamic meta,
|
||||
String? key,
|
||||
String? name,
|
||||
String? description,
|
||||
String? explanation,
|
||||
List<Dice>? dice,
|
||||
List<String>? classKeys,
|
||||
List<Tag>? tags,
|
||||
MoveCategory? category,
|
||||
}) =>
|
||||
Move(
|
||||
meta: meta ?? this.meta,
|
||||
key: key ?? this.key,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
explanation: explanation ?? this.explanation,
|
||||
dice: dice ?? this.dice,
|
||||
classKeys: classKeys ?? this.classKeys,
|
||||
tags: tags ?? this.tags,
|
||||
category: category ?? this.category,
|
||||
);
|
||||
|
||||
factory Move.fromRawJson(String str) => Move.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Move.fromJson(Map<String, dynamic> json) => Move(
|
||||
meta: json["_meta"],
|
||||
key: json["key"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
explanation: json["explanation"],
|
||||
dice: List<Dice>.from(json["dice"].map((x) => x.toJson())),
|
||||
classKeys: List<String>.from(json["classKeys"].map((x) => x)),
|
||||
tags: List<Tag>.from(json["tags"].map((x) => Tag.fromJson(x))),
|
||||
category: MoveCategory.values
|
||||
.firstWhere((element) => element.name == json["category"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"key": key,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"explanation": explanation,
|
||||
"dice": List<String>.from(dice.map((x) => x.toJson())),
|
||||
"classKeys": List<dynamic>.from(classKeys.map((x) => x)),
|
||||
"tags": List<dynamic>.from(tags.map((x) => x.toJson())),
|
||||
"category": category.name,
|
||||
};
|
||||
}
|
||||
66
lib/race.dart
Normal file
66
lib/race.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'tag.dart';
|
||||
|
||||
class Race {
|
||||
Race({
|
||||
required this.meta,
|
||||
required this.key,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.explanation,
|
||||
required this.classKeys,
|
||||
required this.tags,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String key;
|
||||
final String name;
|
||||
final String description;
|
||||
final String explanation;
|
||||
final List<String> classKeys;
|
||||
final List<Tag> tags;
|
||||
|
||||
Race copyWith({
|
||||
dynamic meta,
|
||||
String? key,
|
||||
String? name,
|
||||
String? description,
|
||||
String? explanation,
|
||||
List<String>? classKeys,
|
||||
List<Tag>? tags,
|
||||
}) =>
|
||||
Race(
|
||||
meta: meta ?? this.meta,
|
||||
key: key ?? this.key,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
explanation: explanation ?? this.explanation,
|
||||
classKeys: classKeys ?? this.classKeys,
|
||||
tags: tags ?? this.tags,
|
||||
);
|
||||
|
||||
factory Race.fromRawJson(String str) => Race.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Race.fromJson(Map<String, dynamic> json) => Race(
|
||||
meta: json["_meta"],
|
||||
key: json["key"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
explanation: json["explanation"],
|
||||
classKeys: List<String>.from(json["classKeys"].map((x) => x)),
|
||||
tags: List<Tag>.from(json["tags"].map((x) => Tag.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"key": key,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"explanation": explanation,
|
||||
"classKeys": List<dynamic>.from(classKeys.map((x) => x)),
|
||||
"tags": List<dynamic>.from(tags.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
66
lib/spell.dart
Normal file
66
lib/spell.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'tag.dart';
|
||||
|
||||
class Spell {
|
||||
Spell({
|
||||
required this.meta,
|
||||
required this.key,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.explanation,
|
||||
required this.classKeys,
|
||||
required this.tags,
|
||||
});
|
||||
|
||||
final dynamic meta;
|
||||
final String key;
|
||||
final String name;
|
||||
final String description;
|
||||
final String explanation;
|
||||
final List<String> classKeys;
|
||||
final List<Tag> tags;
|
||||
|
||||
Spell copyWith({
|
||||
dynamic meta,
|
||||
String? key,
|
||||
String? name,
|
||||
String? description,
|
||||
String? explanation,
|
||||
List<String>? classKeys,
|
||||
List<Tag>? tags,
|
||||
}) =>
|
||||
Spell(
|
||||
meta: meta ?? this.meta,
|
||||
key: key ?? this.key,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
explanation: explanation ?? this.explanation,
|
||||
classKeys: classKeys ?? this.classKeys,
|
||||
tags: tags ?? this.tags,
|
||||
);
|
||||
|
||||
factory Spell.fromRawJson(String str) => Spell.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Spell.fromJson(Map<String, dynamic> json) => Spell(
|
||||
meta: json["_meta"],
|
||||
key: json["key"],
|
||||
name: json["name"],
|
||||
description: json["description"],
|
||||
explanation: json["explanation"],
|
||||
classKeys: List<String>.from(json["classKeys"].map((x) => x)),
|
||||
tags: List<Tag>.from(json["tags"].map((x) => Tag.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"_meta": meta,
|
||||
"key": key,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"explanation": explanation,
|
||||
"classKeys": List<dynamic>.from(classKeys.map((x) => x)),
|
||||
"tags": List<dynamic>.from(tags.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
40
lib/tag.dart
Normal file
40
lib/tag.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class Tag {
|
||||
Tag({
|
||||
required this.name,
|
||||
required this.value,
|
||||
this.description = "",
|
||||
});
|
||||
|
||||
final String name;
|
||||
final dynamic value;
|
||||
final String description;
|
||||
|
||||
Tag copyWith({
|
||||
String? name,
|
||||
dynamic value,
|
||||
String? description,
|
||||
}) =>
|
||||
Tag(
|
||||
name: name ?? this.name,
|
||||
value: value ?? this.value,
|
||||
description: description ?? this.description,
|
||||
);
|
||||
|
||||
factory Tag.fromRawJson(String str) => Tag.fromJson(json.decode(str));
|
||||
|
||||
String toRawJson() => json.encode(toJson());
|
||||
|
||||
factory Tag.fromJson(Map<String, dynamic> json) => Tag(
|
||||
name: json["name"],
|
||||
value: json["value"],
|
||||
description: json["description"] ?? "",
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"name": name,
|
||||
"value": value,
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
@@ -92,13 +92,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -135,7 +128,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
lints:
|
||||
dependency: transitive
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
|
||||
@@ -8,13 +8,13 @@ environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
collection: ^1.15.0-nullsafety.4
|
||||
meta: ^1.1.0
|
||||
quiver: ^3.0.1
|
||||
uuid: ^3.0.4
|
||||
collection: ^1.15.0-nullsafety.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.4
|
||||
lints: ^1.0.1
|
||||
dart_style: ^2.0.3
|
||||
path: ^1.6.4
|
||||
test: ^1.6.4
|
||||
|
||||
242
scripts/migrate/v2_to_v3.dart
Normal file
242
scripts/migrate/v2_to_v3.dart
Normal file
@@ -0,0 +1,242 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dungeon_world_data/_old/dw_data.dart' as old;
|
||||
import 'package:dungeon_world_data/_utils/uuid.dart';
|
||||
import 'package:dungeon_world_data/dungeon_world_data.dart';
|
||||
import 'package:dungeon_world_data/gear_option.dart';
|
||||
import 'package:dungeon_world_data/monster.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
final _jsonOut = path.join(
|
||||
path.dirname(Platform.script.path),
|
||||
'dump.json',
|
||||
);
|
||||
|
||||
Map<String, String> strFixMap = {
|
||||
"—": "-",
|
||||
"–": "-",
|
||||
"’": "'",
|
||||
"“": "\"",
|
||||
"”": "\"",
|
||||
};
|
||||
|
||||
final json = <String, List<Map<String, dynamic>>>{
|
||||
'moves': [],
|
||||
'races': [],
|
||||
'classes': [],
|
||||
'spells': [],
|
||||
'items': [],
|
||||
'monsters': [],
|
||||
'tags': [],
|
||||
};
|
||||
|
||||
final defaultTags = <Tag>[
|
||||
Tag(name: "language", value: "EN"),
|
||||
Tag(name: "source", value: "repo"),
|
||||
];
|
||||
|
||||
main() async {
|
||||
print("Starting...");
|
||||
// Basic moves
|
||||
print("Adding ${old.dungeonWorld.basicMoves.length} basic moves");
|
||||
for (var move in old.dungeonWorld.basicMoves) {
|
||||
json['moves']!.add(moveMapper(move, MoveCategory.basic).toJson());
|
||||
}
|
||||
|
||||
for (var cls in old.dungeonWorld.classes) {
|
||||
// Starting moves
|
||||
print("Adding ${cls.startingMoves.length} starting moves");
|
||||
for (var move in cls.startingMoves) {
|
||||
json['moves']!.add(moveMapper(move, MoveCategory.starting).toJson());
|
||||
}
|
||||
|
||||
// Advanced Moves 1
|
||||
print("Adding ${cls.advancedMoves1.length} advanced1 moves");
|
||||
for (var move in cls.advancedMoves1) {
|
||||
json['moves']!.add(moveMapper(move, MoveCategory.advanced1).toJson());
|
||||
}
|
||||
|
||||
// Advanced Moves 1
|
||||
print("Adding ${cls.advancedMoves2.length} advanced2 moves");
|
||||
for (var move in cls.advancedMoves2) {
|
||||
json['moves']!.add(moveMapper(move, MoveCategory.advanced2).toJson());
|
||||
}
|
||||
|
||||
// Races
|
||||
print("Adding ${cls.raceMoves.length} races");
|
||||
for (var race in cls.raceMoves) {
|
||||
json['races']!
|
||||
.add(raceMapper(race, cls.key ?? makeKey(cls.name)).toJson());
|
||||
}
|
||||
|
||||
// Classes
|
||||
json['classes']!.add(classMapper(cls).toJson());
|
||||
}
|
||||
print("Total ${json['classes']!.length} classes");
|
||||
|
||||
// Spells
|
||||
print("Adding ${old.dungeonWorld.spells.length} spells");
|
||||
for (var spell in old.dungeonWorld.spells) {
|
||||
json['spells']!.add(spellMapper(spell).toJson());
|
||||
}
|
||||
|
||||
print("Adding ${old.dungeonWorld.equipment.length} items");
|
||||
for (var equip in old.dungeonWorld.equipment) {
|
||||
json['items']!.add(equipMapper(equip).toJson());
|
||||
}
|
||||
|
||||
print("Adding ${old.dungeonWorld.monsters.length} monsters");
|
||||
for (var mon in old.dungeonWorld.monsters) {
|
||||
json['monsters']!.add(monsterMapper(mon).toJson());
|
||||
}
|
||||
|
||||
print("Adding ${old.dungeonWorld.tags.length} tags");
|
||||
for (var tag in old.dungeonWorld.tags) {
|
||||
json['tags']!.add(tagMapper(tag).toJson());
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
await File(_jsonOut).writeAsString(jsonEncode(json));
|
||||
print("Done");
|
||||
}
|
||||
|
||||
String fix(String? str) {
|
||||
if (str == null || str.trim().isEmpty) {
|
||||
return "";
|
||||
}
|
||||
for (var _fix in strFixMap.entries) {
|
||||
str = str!.replaceAll(_fix.key, _fix.value);
|
||||
}
|
||||
return str!.trim();
|
||||
}
|
||||
|
||||
String makeKey(String str) {
|
||||
return fix(str)
|
||||
.replaceAll(RegExp('["\']'), "")
|
||||
.replaceAll(RegExp(r'[^a-z]+', caseSensitive: false), '_')
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
Set<Dice> guessDice(String str) {
|
||||
var basicRollPattern = RegExp(r'\broll\+[a-z]{3}\b', caseSensitive: false);
|
||||
var dicePattern = RegExp(r'\b\dd\d\b', caseSensitive: false);
|
||||
var found = <Dice>{};
|
||||
var basicRollMatches = basicRollPattern.allMatches(str);
|
||||
for (var match in basicRollMatches) {
|
||||
found.add(Dice.d6 * 2);
|
||||
}
|
||||
var diceMatches = dicePattern.allMatches(str);
|
||||
for (var match in diceMatches) {
|
||||
found.add(Dice.fromJson(match.input.substring(match.start, match.end)));
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
Move moveMapper(old.Move move, MoveCategory category) => Move(
|
||||
category: category,
|
||||
classKeys: move.classes,
|
||||
description: fix(move.description),
|
||||
dice: guessDice(fix(move.description)).toList(),
|
||||
explanation: fix(move.explanation ?? ""),
|
||||
key: makeKey(move.name),
|
||||
meta: null,
|
||||
name: fix(move.name),
|
||||
tags: defaultTags,
|
||||
);
|
||||
|
||||
Race raceMapper(old.Move move, String classKey) => Race(
|
||||
classKeys: [classKey],
|
||||
description: fix(move.description),
|
||||
explanation: fix(move.explanation ?? ""),
|
||||
key: makeKey(move.name),
|
||||
meta: null,
|
||||
name: fix(move.name),
|
||||
tags: defaultTags,
|
||||
);
|
||||
|
||||
Spell spellMapper(old.Spell spell) => Spell(
|
||||
classKeys: [],
|
||||
description: fix(spell.description),
|
||||
explanation: "",
|
||||
key: makeKey(spell.name),
|
||||
meta: null,
|
||||
name: fix(spell.name),
|
||||
tags: [...defaultTags, ...spell.tags.map((t) => tagMapper(t))],
|
||||
);
|
||||
|
||||
Tag tagMapper(old.Tag t) => Tag.fromJson(t.toJSON().runtimeType == String
|
||||
? {"name": t.toJSON()}
|
||||
: {"name": t.name, "value": t.value, "description": fix(t.description)});
|
||||
|
||||
Item equipMapper(old.Equipment equip) => Item(
|
||||
key: makeKey(equip.name),
|
||||
meta: null,
|
||||
name: fix(equip.name),
|
||||
description: fix(equip.description),
|
||||
tags: equip.tags.map((t) => tagMapper(t)).toList(),
|
||||
);
|
||||
|
||||
Monster monsterMapper(old.Monster move) => Monster(
|
||||
instinct: fix(move.instinct),
|
||||
description: fix(move.description),
|
||||
key: makeKey(move.name),
|
||||
meta: null,
|
||||
name: fix(move.name),
|
||||
tags: defaultTags,
|
||||
moves: move.moves,
|
||||
);
|
||||
|
||||
CharacterClass classMapper(old.PlayerClass cls) => CharacterClass(
|
||||
alignments: AlignmentValues(
|
||||
chaotic: fix(cls.alignments['chaotic']?.description ?? ""),
|
||||
neutral: fix(cls.alignments['neutral']?.description ?? ""),
|
||||
evil: fix(cls.alignments['evil']?.description ?? ""),
|
||||
good: fix(cls.alignments['good']?.description ?? ""),
|
||||
lawful: fix(cls.alignments['lawful']?.description ?? ""),
|
||||
),
|
||||
bonds: cls.bonds.map(fix).toList(),
|
||||
damageDice: Dice.fromJson(cls.damage.toString()),
|
||||
description: fix(cls.description),
|
||||
gearChoices: cls.gearChoices
|
||||
.map(
|
||||
(c) => GearChoice(
|
||||
key: c.key ?? uuid(),
|
||||
description: fix(c.label),
|
||||
selections: c.gearOptions
|
||||
.map(
|
||||
(o) => GearSelection(
|
||||
description: o.name + '(TODO: INCOMPLETE)',
|
||||
items: [
|
||||
GearOption(
|
||||
amount: o.name.contains(RegExp(r'[0-9]+'))
|
||||
? double.tryParse(RegExp(r'[0-9]+')
|
||||
.firstMatch(o.name)
|
||||
?.group(0) ??
|
||||
"1.0") ??
|
||||
1.0
|
||||
: 1.0,
|
||||
item: Item(
|
||||
key: makeKey(o.name),
|
||||
meta: null,
|
||||
name: fix(o.name),
|
||||
description: fix(o.name),
|
||||
tags: defaultTags,
|
||||
),
|
||||
),
|
||||
],
|
||||
gold: 0,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
hp: cls.baseHP.toInt(),
|
||||
key: makeKey(cls.name),
|
||||
load: cls.load.toInt(),
|
||||
name: cls.name,
|
||||
meta: null,
|
||||
);
|
||||
@@ -1,75 +1,48 @@
|
||||
import 'package:dungeon_world_data/dw_data.dart';
|
||||
import 'package:dungeon_world_data/dice.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Dice', () {
|
||||
test('Sides and amount', () {
|
||||
var expected = Dice(6, 2);
|
||||
expect(expected.sides, equals(6));
|
||||
expect(expected.amount, equals(2));
|
||||
group("Parse JSON", () {
|
||||
test("No modifier", () {
|
||||
var str = "1d6";
|
||||
var dice = Dice.fromJson(str);
|
||||
expect(dice.amount, equals(1));
|
||||
expect(dice.sides, equals(6));
|
||||
expect(dice.modifier, equals(null));
|
||||
});
|
||||
test("With positive modifier", () {
|
||||
var str = "3d8+3";
|
||||
var dice = Dice.fromJson(str);
|
||||
expect(dice.amount, equals(3));
|
||||
expect(dice.sides, equals(8));
|
||||
expect(dice.modifier, equals(3));
|
||||
});
|
||||
test("With negative modifier", () {
|
||||
var str = "2d20-4";
|
||||
var dice = Dice.fromJson(str);
|
||||
expect(dice.amount, equals(2));
|
||||
expect(dice.sides, equals(20));
|
||||
expect(dice.modifier, equals(-4));
|
||||
});
|
||||
});
|
||||
|
||||
test('String representation', () {
|
||||
var dice1 = Dice(10, 4);
|
||||
var dice2 = Dice(6, 2, 3);
|
||||
var dice3 = Dice(20, 2, -4);
|
||||
expect(dice1.toString(), equals('4d10'));
|
||||
expect(dice2.toString(), equals('2d6+3'));
|
||||
expect(dice3.toString(), equals('2d20-4'));
|
||||
});
|
||||
|
||||
test('Multiplication', () {
|
||||
num amt = 10;
|
||||
var dice = Dice.d12 * amt;
|
||||
expect(dice.amount, amt);
|
||||
});
|
||||
|
||||
test('Equality', () {
|
||||
var compare = {
|
||||
Dice(4): Dice.d4,
|
||||
Dice(6): Dice.d6,
|
||||
Dice(8): Dice.d8,
|
||||
Dice(10): Dice.d10,
|
||||
Dice(12): Dice.d12,
|
||||
Dice(20): Dice.d20,
|
||||
};
|
||||
for (var d in compare.keys) {
|
||||
expect(d, equals(compare[d]));
|
||||
expect(compare.values.where((el) => el == d).length, equals(1));
|
||||
}
|
||||
});
|
||||
|
||||
test('Roll', () {
|
||||
var d1 = Dice.d6;
|
||||
var d2 = Dice.d12 * 2;
|
||||
var d3 = Dice.d8 * 3;
|
||||
var roll1 = d1.getRoll();
|
||||
var roll2 = d2.getRoll();
|
||||
var roll3 = d3.getRoll();
|
||||
|
||||
expect(roll1.results[0], greaterThanOrEqualTo(1));
|
||||
expect(roll1.results[0], lessThanOrEqualTo(6));
|
||||
|
||||
expect(roll2.results.length, equals(d2.amount));
|
||||
expect(roll2.results[0], greaterThanOrEqualTo(1));
|
||||
expect(roll2.results[0], lessThanOrEqualTo(12));
|
||||
expect(roll2.results[1], greaterThanOrEqualTo(1));
|
||||
expect(roll2.results[1], lessThanOrEqualTo(12));
|
||||
|
||||
expect(roll3.results.length, equals(d3.amount));
|
||||
expect(roll3.results[0], greaterThanOrEqualTo(1));
|
||||
expect(roll3.results[0], lessThanOrEqualTo(8));
|
||||
expect(roll3.results[1], greaterThanOrEqualTo(1));
|
||||
expect(roll3.results[1], lessThanOrEqualTo(8));
|
||||
expect(roll3.results[2], greaterThanOrEqualTo(1));
|
||||
expect(roll3.results[2], lessThanOrEqualTo(8));
|
||||
});
|
||||
|
||||
test('Roll', () {
|
||||
var dice = Dice.d6;
|
||||
var roll = dice.getRoll();
|
||||
expect(roll.results[0], greaterThanOrEqualTo(1));
|
||||
expect(roll.results[0], lessThanOrEqualTo(6));
|
||||
group("Dump JSON", () {
|
||||
test("No modifier", () {
|
||||
var str = "1d6";
|
||||
var dice = Dice(amount: 1, sides: 6);
|
||||
expect(dice.toJson(), equals(str));
|
||||
});
|
||||
test("With positive modifier", () {
|
||||
var str = "3d8+3";
|
||||
var dice = Dice(amount: 3, sides: 8, modifier: 3);
|
||||
expect(dice.toJson(), equals(str));
|
||||
});
|
||||
test("With negative modifier", () {
|
||||
var str = "2d20-4";
|
||||
var dice = Dice(amount: 2, sides: 20, modifier: -4);
|
||||
expect(dice.toJson(), equals(str));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user