diff --git a/README.md b/README.md index 05cbe55..c9bbe4f 100644 --- a/README.md +++ b/README.md @@ -5,27 +5,42 @@ This dart package contains data for Dungeon World, such as classes, moves, spells, equipment, etc. Homebew classes included: -* Immolator -* Barbarian. + +- Immolator +- Barbarian. ## How to use -After importing, access `dungeonWorld` to access the entire data structure. + +After importing, access `dungeonWorldData` to access the entire data structure. There is more information in the doc directory. ## Available data -| Name | Type | Description | -| ---- | ---- | ----------- | -| basicMoves | `List` | Dungeon World's basic moves, such as Hack & Slash, Defy Danger, etc. | -| specialMoves | `List` | Dungeon World's special moves, such as Make Camp, Take Watch, etc. | -| classes | `List` | All of Dungeon World's classes, plus some homebrews. See `PlayerClass` class for a full description of the usable properties. | -| equipment | `List` | Dungeon World's main list of items. | -| spells | `List` | Dungeon World's main spellbook list. Each class can have its own spells list, see `PlayerClass` in the docs for more information. | -| monsters | `List` | Dungeon World's main monster list. | -| tags | `List` | List of all basic tags, along with descriptions. | +| Code | Type | +| ----------------------------------- | ----------------------------- | +| `dungeonWorldData.characterClasses` | `Map` | +| `dungeonWorldData.items` | `Map` | +| `dungeonWorldData.moves` | `Map` | +| `dungeonWorldData.races` | `Map` | +| `dungeonWorldData.spells` | `Map` | +| `dungeonWorldData.monsters` | `Map` | +| `dungeonWorldData.tags` | `Map` | There is also a `Dice` class, with simple dice rolling functionality for your use. +## Translations + +The data is currently only available in English, but a localization engine is implemented. + +- Use `dungeonWorldData.initLocale(locale)` to create a new locale reference. +- Use `dungeonWorldData.addForLocale` or `dungeonWorldData.addAllForLocale` to add items to the locales. +- Use `dungeonWorldData.changeLocale(locale)` to change to a different locale. + +At any given locale, getting items via the generic getter `get(key)` and `[]` operator will give you +only data for the current locale. + +You can use `getItemFor(locale, key)` to get data for a specific, non-current locale on the fly. + ## Credits Credits to ~vindexus who created https://www.npmjs.com/package/dungeonworld-data. @@ -33,7 +48,29 @@ The data is from there, this package simply wraps it up for Dart. ## Contributing +I am developing this package on my free time, so any support, whether code, issues, or just stars is +very helpful to sustaining its life. If you are feeling incredibly generous and would like to donate +just a small amount to help sustain this project, I would be very very thankful! + + + Buy Me a Coffee at ko-fi.com + + +I welcome any issues or pull requests on GitHub. If you find a bug, or would like a new feature, +don't hesitate to open an appropriate issue and I will do my best to reply promptly. + +## Code Contributors + 1. Make your changes -1. Run tests, and add new tests if appropriate. Make sure nothing breaks. -1. Create a PR, explain what your changes do. -1. Profit! +2. Run tests, and add new tests if appropriate. Make sure nothing breaks. +3. Create a PR, explain what your changes do. +4. Profit! + +If you want to translate DW data for this package: + +1. Create a new folder inside `lib/data` with the locale code. +2. Copy the contents of `lib/data/en-US` to your new folder +3. Update all the localization info there, including the values of each property (not the keys!), + and the meta tags that signify the language. diff --git a/lib/_repository.dart b/lib/_repository.dart index b0d422d..a455abc 100644 --- a/lib/_repository.dart +++ b/lib/_repository.dart @@ -1,6 +1,10 @@ import 'package:dungeon_world_data/dungeon_world_data.dart'; import 'package:meta/meta.dart'; +/// A repository containing game data separated by locale. +/// This class represents a single item in the repository. +/// All the localizations are stored in here, and you may use the various methods to access them, +/// change the locale, or manipulate localized versions of data. class RepositoryItem { String? _currentLocale; @@ -14,40 +18,42 @@ class RepositoryItem { } } + /// The current locale. String get currentLocale => _currentLocale!; + /// Initialize the repository for a new locale. + /// If one already exists, it will not be overwritten. void initLocale(String locale) { _cache[locale] ??= create(); } + /// Change the current locale to a new locale. Getting data will now be for this locale. void changeLocale(String locale) { _currentLocale = locale; } + /// Create a new item. T create() { throw UnimplementedError(); } + /// Set the item data for the given locale. void setForLocale(String locale, T item) { _cache[locale] = item; } + /// Get the item data for the given locale. T getForLocale(String locale) => _cache[locale]!; + /// Get the item data for the current locale. T get() => getForLocale(currentLocale); + + /// Get the item data for the current locale. + void set(T item) => setForLocale(currentLocale, item); } -class RepositoryList extends RepositoryItem> { - RepositoryList([String? initialLocale]) : super(initialLocale); - - @override - List create() => []; - - void addForLocale(String locale, T item) => _cache[locale]!.add(item); - - void add(T item) => addForLocale(currentLocale, item); -} - +/// A repository containing game data separated by locale. +/// Use this to store data that is locale-specific, such as names, descriptions, etc. class RepositoryMap extends RepositoryItem> { RepositoryMap([String? initialLocale]) : super(initialLocale); @@ -71,11 +77,16 @@ class RepositoryMap extends RepositoryItem> { Iterable get keys => _cache[currentLocale]!.keys; } +/// The main repository of Dungeon World data. +/// This class contains all the data for the game, and is the main entry point for accessing it. +/// You can switch locale using [changeLocale] and get the data for the current locale using the various getters. class DungeonWorldRepository extends RepositoryMap { + /// The current version of the data. final version = '3.0.0'; DungeonWorldRepository([String? initialLocale]) : super(initialLocale); + /// Create the initial data structure. @override create() => >{ 'CharacterClasses': {}, @@ -87,17 +98,43 @@ class DungeonWorldRepository extends RepositoryMap { 'Tags': {}, }; + /// A mapping of all the character classes. + /// The key in each entry is a unique key to the class, and the value is the class itself. Map get characterClasses => getItem('CharacterClasses').cast(); + + /// A mapping of all the items. + /// The key in each entry is a unique key to the item, and the value is the item itself. Map get items => getItem('Items').cast(); + + /// A mapping of all the monsters. + /// The key in each entry is a unique key to the monster, and the value is the monster itself. Map get monsters => getItem('Monsters').cast(); + + /// A mapping of all the moves. + /// The key in each entry is a unique key to the move, and the value is the move itself. Map get moves => getItem('Moves').cast(); + + /// A mapping of all the races. + /// The key in each entry is a unique key to the race, and the value is the race itself. Map get races => getItem('Races').cast(); + + /// A mapping of all the spells. + /// The key in each entry is a unique key to the spell, and the value is the spell itself. Map get spells => getItem('Spells').cast(); + + /// A mapping of all the tags. + /// The key in each entry is a unique key to the tag, and the value is the tag itself. Map get tags => getItem('Tags').cast(); + /// Dump all the data as a JSON map. Same as `toJsonAsMaps()` + /// @see toJsonAsMaps() + /// @see toJsonAsLists() Map toJson() => toJsonAsMaps(); + /// Dump all the data as a JSON map. Same as `toJson()` + /// @see toJson() + /// @see toJsonAsLists() Map toJsonAsMaps() => { "CharacterClasses": characterClasses.map(((key, value) => MapEntry(key, value.toJson()))), "Items": items.map(((key, value) => MapEntry(key, value.toJson()))), @@ -108,6 +145,9 @@ class DungeonWorldRepository extends RepositoryMap { "Tags": tags.map(((key, value) => MapEntry(key, value.toJson()))), }; + /// Dump all the data as a JSON lists, instead of key => value maps. + /// @see toJson() + /// @see toJsonAsMaps() Map toJsonAsLists() => { "CharacterClasses": characterClasses.values.map(((value) => value.toJson())).toList(), "Items": items.values.map(((value) => value.toJson())).toList(), diff --git a/lib/alignment.dart b/lib/alignment.dart index 32bc16c..fc85be5 100644 --- a/lib/alignment.dart +++ b/lib/alignment.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'base.dart'; +/// The alignment types available in Dungeon World enum AlignmentType { good, lawful, @@ -18,6 +19,7 @@ class Alignment with KeyMixin { required this.description, }); + /// Dynamic metadata final dynamic meta; /// The alignment being described @@ -77,6 +79,8 @@ class Alignment with KeyMixin { String toString() => 'Alignment($debugProperties)'; } +/// Describes the alignment values available in Dungeon World, and their respective +/// descriptions. class AlignmentValues { AlignmentValues({ required this.good, @@ -86,10 +90,19 @@ class AlignmentValues { required this.chaotic, }); + /// The description of the good alignment final String good; + + /// The description of the evil alignment final String evil; + + /// The description of the lawful alignment final String lawful; + + /// The description of the neutral alignment final String neutral; + + /// The description of the chaotic alignment final String chaotic; AlignmentValues copyWith({ diff --git a/lib/base.dart b/lib/base.dart index 6e75e64..db84cc6 100644 --- a/lib/base.dart +++ b/lib/base.dart @@ -1,11 +1,14 @@ import 'package:dungeon_world_data/dungeon_world_data.dart'; +/// This mixin ensures a key and a display name for an entity. mixin KeyMixin { /// This entity's unique key abstract final String key; + /// This entity's display name, as the user would see it String get displayName; + /// Get a reference to this entity, which can be used to look it up in a repository. EntityReference get reference => EntityReference( key: key, name: displayName, diff --git a/lib/character_class.dart b/lib/character_class.dart index 8c984a5..7c2072c 100644 --- a/lib/character_class.dart +++ b/lib/character_class.dart @@ -55,7 +55,7 @@ class CharacterClass with KeyMixin { /// This class's starting gear options final List gearChoices; - /// Whether this class is a Magic User + /// Whether this class is a Magic User, and therefore has access to spells final bool isSpellcaster; CharacterClass copyWith({ diff --git a/lib/data/classes.dart b/lib/data/en-US/classes.dart similarity index 100% rename from lib/data/classes.dart rename to lib/data/en-US/classes.dart diff --git a/lib/data/items.dart b/lib/data/en-US/items.dart similarity index 100% rename from lib/data/items.dart rename to lib/data/en-US/items.dart diff --git a/lib/data/monsters.dart b/lib/data/en-US/monsters.dart similarity index 100% rename from lib/data/monsters.dart rename to lib/data/en-US/monsters.dart diff --git a/lib/data/moves.dart b/lib/data/en-US/moves.dart similarity index 100% rename from lib/data/moves.dart rename to lib/data/en-US/moves.dart diff --git a/lib/data/races.dart b/lib/data/en-US/races.dart similarity index 98% rename from lib/data/races.dart rename to lib/data/en-US/races.dart index 9161b47..3ddb9d6 100644 --- a/lib/data/races.dart +++ b/lib/data/en-US/races.dart @@ -262,7 +262,9 @@ List getRaceList() => [ "description": "You may be elf, dwarf, halfling, or human, but you and your people are not from around here. At the beginning of each session, the GM will ask you something about your homeland, why you left, or what you left behind. If you answer them, mark XP.", "explanation": "", - "classKeys": [{"key": "barbarian", "name": "Barbarian", "type": "CharacterClass"}], + "classKeys": [ + {"key": "barbarian", "name": "Barbarian", "type": "CharacterClass"} + ], "tags": [], "dice": [] }) diff --git a/lib/data/spells.dart b/lib/data/en-US/spells.dart similarity index 92% rename from lib/data/spells.dart rename to lib/data/en-US/spells.dart index 4ab14ba..44f8b51 100644 --- a/lib/data/spells.dart +++ b/lib/data/en-US/spells.dart @@ -11,8 +11,8 @@ List getSpellList() => [ "level": "cantrip", "classKeys": [ {"key": "cleric", "name": "Cleric", "type": "CharacterClass"}, - {"key": - "wizard", "name": "Wizard", "type": "CharacterClass"}], + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [], "dice": [] }), @@ -303,8 +303,8 @@ List getSpellList() => [ "level": "7", "classKeys": [ {"key": "cleric", "name": "Cleric", "type": "CharacterClass"}, - {"key": - "wizard", "name": "Wizard", "type": "CharacterClass"}], + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -493,7 +493,9 @@ List getSpellList() => [ "You perform minor tricks of true magic. If you touch an item as part of the casting you can make cosmetic changes to it: clean it, soil it, cool it, warm it, flavor it, or change its color. If you cast the spell without touching an item you can instead create minor illusions no bigger than yourself. Prestidigitation illusions are crude and clearly illusions-they won't fool anyone, but they might entertain them.", "explanation": "", "level": "cantrip", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [], "dice": [] }), @@ -505,7 +507,9 @@ List getSpellList() => [ "You conjure a simple invisible construct that can do nothing but carry items. It has Load 3 and carries anything you hand to it. It cannot pick up items on its own and can only carry those you give to it. Items carried by an unseen servant appear to float in the air a few paces behind you. An unseen servant that takes damage or leaves your presence is immediately dispelled, dropping any items it carried. Otherwise the unseen servant serves you until you end the spell.", "explanation": "", "level": "cantrip", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Ongoing", "value": null, "description": ""} ], @@ -519,7 +523,9 @@ List getSpellList() => [ "Name the spirit you wish to contact (or leave it to the GM). You pull that creature through the planes, just close enough to speak to you. It is bound to answer any one question you ask to the best of its ability.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Summoning", "value": null, "description": ""} ], @@ -533,7 +539,9 @@ List getSpellList() => [ "One of your senses is briefly attuned to magic. The GM will tell you what here is magical.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""} ], @@ -547,7 +555,9 @@ List getSpellList() => [ "You form a telepathic bond with a single person you touch, enabling you to converse with that person through your thoughts. You can only have one telepathic bond at a time.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -562,7 +572,9 @@ List getSpellList() => [ "The person (not beast or monster) you touch while casting this spell counts you as a friend until they take damage or you prove otherwise.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Enchantment", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -577,7 +589,9 @@ List getSpellList() => [ "Touch an ally: nobody can see them. They're invisible! The spell persists until the target attacks or you dismiss the effect. While the spell is ongoing you can't cast a spell.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Illusion", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -592,7 +606,9 @@ List getSpellList() => [ "Projectiles of pure magic spring from your fingers. Deal 2d4 damage to one target.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Evocation", "value": null, "description": ""} ], @@ -606,7 +622,9 @@ List getSpellList() => [ "Walk a wide circle as you cast this spell. Until you prepare spells again your magic will alert you if a creature crosses that circle. Even if you are asleep, the spell will shake you from your slumber.", "explanation": "", "level": "1", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [], "dice": [] }), @@ -618,7 +636,9 @@ List getSpellList() => [ "Choose a spell or magic effect in your presence: this spell rips it apart. Lesser spells are ended, powerful magic is just reduced or dampened so long as you are nearby.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [], "dice": [] }), @@ -630,7 +650,9 @@ List getSpellList() => [ "Cast this spell and gaze into a reflective surface to see into the depths of time. The GM will reveal the details of a grim portent to you-a bleak event that will come to pass without your intervention. Theyll tell you something useful about how you can interfere with the grim portent's dark outcomes. Rare is the portent that claims \"You'll live happily ever after.\" Sorry.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""} ], @@ -644,7 +666,9 @@ List getSpellList() => [ "You evoke a mighty ball of flame that envelops your target and everyone nearby, inflicting 2d6 damage which ignores armor.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Evocation", "value": null, "description": ""} ], @@ -658,7 +682,9 @@ List getSpellList() => [ "You take the form of someone you touch while casting this spell. Your physical characteristics match theirs exactly but your behavior may not. This change persists until you take damage or choose to return to your own form. While this spell is ongoing you lose access to all your wizard moves.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Ongoing", "value": null, "description": ""} ], @@ -672,7 +698,9 @@ List getSpellList() => [ "You create an illusory image of yourself. When you are attacked, roll a d6.\n* On a 4, 5, or 6 the attack hits the illusion instead, the image then dissipates and the spell ends.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Illusion", "value": null, "description": ""} ], @@ -686,7 +714,9 @@ List getSpellList() => [ "1d4 enemies you can see of the GM's choice fall asleep. Only creatures capable of sleeping are affected. They awake as normal: loud noises, jolts, pain.", "explanation": "", "level": "3", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Enchantment", "value": null, "description": ""} ], @@ -700,7 +730,9 @@ List getSpellList() => [ "The target is held in a cage of magical force. Nothing can get in or out of the cage. The cage remains until you cast another spell or dismiss it. While the spell is ongoing, the caged creature can hear your thoughts and you cannot leave sight of the cage.", "explanation": "", "level": "5", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Evocation", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -715,7 +747,9 @@ List getSpellList() => [ "You send a request to another plane. Specify who or what you'd like to contact by location, type of creature, name, or title. You open a two-way communication with that creature. Your communication can be cut off at any time by you or the creature you contacted.", "explanation": "", "level": "5", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""} ], @@ -729,7 +763,9 @@ List getSpellList() => [ "Your touch reshapes a creature entirely, they stay in the form you craft until you cast a spell. Describe the new shape you craft, including any stat changes, significant adaptations, or major weaknesses. The GM will then tell you one or more of these:\n* The form will be unstable and temporary\n* The creature's mind will be altered as well\n* The form has an unintended benefit or weakness", "explanation": "", "level": "5", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Enchantment", "value": null, "description": ""} ], @@ -743,7 +779,9 @@ List getSpellList() => [ "A monster appears and aids you as best it can. Treat it as your character, but with access to only the basic moves. It has +1 modifier for all stats, 1 HP, and uses your damage dice. The monster also gets your choice of 1d6 of these traits:\n* It has +2 instead of +1 to one stat\n* It's not reckless\n* It does 1d8 damage\n* Its bond to your plane is strong: +2 HP for each level you have\n* It has some useful adaptation\nThe GM will tell you the type of monster you get based on the traits you select. The creature remains on this plane until it dies or you dismiss it. While the spell is ongoing you take -1 to cast a spell.", "explanation": "", "level": "5", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Summoning", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -758,7 +796,9 @@ List getSpellList() => [ "Your touch pushes your mind into someone else's. You gain 1d4 hold. Spend one hold to make the target take one of these actions:\n* Speak a few words of your choice\n* Give you something they hold\n* Make a concerted attack on a target of your choice\n* Truthfully answer one question\n\nIf you run out of hold the spell ends. If the target takes damage you lose 1 hold. While the spell is ongoing you cannot cast a spell.", "explanation": "", "level": "7", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Enchantment", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -773,7 +813,9 @@ List getSpellList() => [ "The shadows you target with this spell become a portal for you and your allies. Name a location, describing it with a number of words up to your level. Stepping through the portal deposits you and any allies present when you cast the spell at the location you described. The portal may only be used once by each ally.", "explanation": "", "level": "7", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Illusion", "value": null, "description": ""} ], @@ -787,7 +829,9 @@ List getSpellList() => [ "Choose a 5th level or lower spell you know. Describe a trigger condition using a number of words equal to your level. The chosen spell is held until you choose to unleash it or the trigger condition is met, whichever happens first. You don't have to roll for the held spell, it just takes effect. You may only have a single contingent spell held at a time; if you cast Contingency while you have a held spell, the new held spell replaces the old one.", "explanation": "", "level": "7", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Evocation", "value": null, "description": ""} ], @@ -801,7 +845,9 @@ List getSpellList() => [ "A cloud of fog drifts into this realm from beyond the Black Gates of Death, filling the immediate area. Whenever a creature in the area takes damage it takes an additional, separate 1d6 damage which ignores armor. This spell persists so long as you can see the affected area, or until you dismiss it.", "explanation": "", "level": "7", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Summoning", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -816,7 +862,9 @@ List getSpellList() => [ "Choose a target and describe a type of creature or an alignment. Creatures of the specified type or alignment cannot come within sight of the target. If a creature of the specified type does find itself within sight of the target, it immediately flees. This effect continues until you leave the target's presence or you dismiss the spell. While the spell is ongoing you take -1 to cast a spell.", "explanation": "", "level": "9", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Enchantment", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -831,7 +879,9 @@ List getSpellList() => [ "Describe an event. The GM will tell you when that event occurs, no matter where you are or how far away the event is. If you choose, you can view the location of the event as though you were there in person. You can only have one Alert active at a time.", "explanation": "", "level": "9", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Divination", "value": null, "description": ""} ], @@ -845,7 +895,9 @@ List getSpellList() => [ "You trap the soul of a dying creature within a gem. The trapped creature is aware of its imprisonment but can still be manipulated through spells, parley, and other effects. All moves against the trapped creature are at +1. You can free the soul at any time but it can never be recaptured once freed.", "explanation": "", "level": "9", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [], "dice": [] }), @@ -857,7 +909,9 @@ List getSpellList() => [ "You create a structure out of pure magical power. It can be as large as a castle or as small as a hut, but is impervious to all non-magical damage. The structure endures until you leave it or you end the spell.", "explanation": "", "level": "9", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Evocation", "value": null, "description": ""}, {"name": "Ongoing", "value": null, "description": ""} @@ -872,7 +926,9 @@ List getSpellList() => [ "You teleport a creature to your presence. Name a creature or give a short description of a type of creature. If you named a creature, that creature appears before you. If you described a type of creature, a creature of that type appears before you.", "explanation": "", "level": "9", - "classKeys": [{"key": "wizard", "name": "Wizard", "type": "CharacterClass"}], + "classKeys": [ + {"key": "wizard", "name": "Wizard", "type": "CharacterClass"} + ], "tags": [ {"name": "Summoning", "value": null, "description": ""} ], diff --git a/lib/data/tags.dart b/lib/data/en-US/tags.dart similarity index 79% rename from lib/data/tags.dart rename to lib/data/en-US/tags.dart index cd90e0a..9a2652d 100644 --- a/lib/data/tags.dart +++ b/lib/data/en-US/tags.dart @@ -7,11 +7,8 @@ List getTagList() => [ "description": "It's only useful when carefully applied to a person or to something they eat or drink." }), - Tag.fromJson({ - "name": "Awkward", - "value": null, - "description": "It's unwieldy and tough to use." - }), + Tag.fromJson( + {"name": "Awkward", "value": null, "description": "It's unwieldy and tough to use."}), Tag.fromJson({ "name": "Bonus", "value": null, @@ -30,22 +27,15 @@ List getTagList() => [ "description": "It's easy to get in trouble with it. If you interact with it without proper precautions the GM may freely invoke the consequences of your foolish actions." }), - Tag.fromJson({ - "name": "Ration", - "value": null, - "description": "It's edible, more or less." - }), + Tag.fromJson({"name": "Ration", "value": null, "description": "It's edible, more or less."}), Tag.fromJson({ "name": "Requires", "value": null, "description": "It's only useful to certain people. If you don't meet the requirements it works poorly, if at all." }), - Tag.fromJson({ - "name": "Slow", - "value": null, - "description": "It takes minutes or more to use." - }), + Tag.fromJson( + {"name": "Slow", "value": null, "description": "It takes minutes or more to use."}), Tag.fromJson({ "name": "Touch", "value": null, @@ -62,16 +52,9 @@ List getTagList() => [ "description": "Count the listed amount against your load. Something with no listed weight isn't designed to be carried. 100 coins in standard denominations is 1 weight. The same value in gems or fine art may be lighter or heavier." }), - Tag.fromJson({ - "name": "Worn", - "value": null, - "description": "To use it, you have to be wearing it." - }), - Tag.fromJson({ - "name": "Uses", - "value": null, - "description": "It can only be used n times." - }), + Tag.fromJson( + {"name": "Worn", "value": null, "description": "To use it, you have to be wearing it."}), + Tag.fromJson({"name": "Uses", "value": null, "description": "It can only be used n times."}), Tag.fromJson({ "name": "Ammo", "value": null, @@ -81,8 +64,7 @@ List getTagList() => [ Tag.fromJson({ "name": "Forceful", "value": null, - "description": - "It can knock someone back a pace, maybe even off their feet." + "description": "It can knock someone back a pace, maybe even off their feet." }), Tag.fromJson({ "name": "Damage", @@ -122,8 +104,7 @@ List getTagList() => [ Tag.fromJson({ "name": "Stun", "value": null, - "description": - "When you attack with it, it does stun damage instead of normal damage." + "description": "When you attack with it, it does stun damage instead of normal damage." }), Tag.fromJson({ "name": "Thrown", @@ -134,14 +115,12 @@ List getTagList() => [ Tag.fromJson({ "name": "Hand", "value": null, - "description": - "It's useful for attacking something within your reach, no further." + "description": "It's useful for attacking something within your reach, no further." }), Tag.fromJson({ "name": "Close", "value": null, - "description": - "It's useful for attacking something at arm's reach plus a foot or two." + "description": "It's useful for attacking something at arm's reach plus a foot or two." }), Tag.fromJson({ "name": "Reach", @@ -152,14 +131,12 @@ List getTagList() => [ Tag.fromJson({ "name": "Near", "value": null, - "description": - "It's useful for attacking if you can see the whites of their eyes." + "description": "It's useful for attacking if you can see the whites of their eyes." }), Tag.fromJson({ "name": "Far", "value": null, - "description": - "It's useful for attacking something in shouting distance." + "description": "It's useful for attacking something in shouting distance." }), Tag.fromJson({ "name": "Armor", diff --git a/lib/dice.dart b/lib/dice.dart index 068681a..56a4742 100644 --- a/lib/dice.dart +++ b/lib/dice.dart @@ -4,7 +4,11 @@ import 'dart:math'; /// Dice can have sides, an amount and modifiers. /// /// You may also use one of the rolling convenience methods. -/// For more information about rolls see DiceRoll class +/// For more information about rolls and their results see `DiceRoll` and `DiceRollResult` classes. +/// +/// You can multiply dice of the same sides together, which will return the amount of dice doubled between each other. +/// This also works for division, addition and subtraction. +/// Sides and modifiers are not affected by this, and the leftmost operant is always the one that is used. class Dice { Dice({ required this.amount, @@ -19,12 +23,24 @@ class Dice { : "-" : "+"); + /// The amount of dice to roll. In a 2d6 roll, this would be 2. final int amount; + + /// The amount of sides on the dice. In a 2d6 roll, this would be 6. final int sides; + + /// The modifier value. In a 2d6+3 roll, this would be 3. final int? modifierValue; + + /// The modifier stat. In a 2d6+DEX roll, this would be DEX. final String? modifierStat; + + /// The modifier sign. In a 2d6+3 roll, this would be +. In a 2d6-3 roll, this would be -. final String modifierSign; + /// If you want to change the modifier value, use [copyWithModifierValue] instead. + /// Otherwise, use `copyWith` to change the modifier sign, as this class is immutable, + /// and the sign is determined by the modifier value. Dice copyWith({ int? amount, int? sides, @@ -76,6 +92,8 @@ class Dice { ); } + /// Creates a copy of this dice with the modifier value set to the given stat value. + /// The sign is updated using this operation, so use it instead of [copyWith] if you want to use a stat. Dice copyWithModifierValue(int statValue) => copyWith( amount: amount, sides: sides, @@ -88,14 +106,20 @@ class Dice { String toJson() => toString(); + /// The modifier with the sign. In a 2d6+3 roll, this would be +3. In a 2d6-3 roll, this would be -3. String get modifierWithSign => hasModifier ? "$modifierSign${modifierValue?.abs() ?? modifierStat}" : ""; + /// Whether or not this dice has a modifier. bool get hasModifier => ((modifierValue != null && modifierValue != 0) || modifierStat != null); + /// The modifier name. In a 2d6+DEX roll, this would be DEX. String get modifier => hasModifier ? modifierStat ?? (modifierValue != 0 ? modifierValue : '')!.toString() : ""; + /// Rolls the dice and returns the result, a random number between 1 and the amount of sides. + /// It is returned with the dice that was rolled in a [DiceRoll] object, which also contains the + /// results of the individual dice. DiceRoll roll() { if (needsModifier) { throw Exception("Dice is being rolled without an actual modifier." @@ -109,6 +133,7 @@ class Dice { return DiceRoll(dice: this, results: arr); } + /// Whether or not this dice needs a modifier to be rolled - if it has a modifier stat but no value. bool get needsModifier => modifierStat != null && modifierValue == null; operator +(int amount) => copyWith(amount: this.amount + amount); @@ -116,6 +141,8 @@ class Dice { operator *(int amount) => copyWith(amount: this.amount * amount); operator /(int amount) => copyWith(amount: this.amount ~/ amount); + /// Flattens a list of dice into a list of dice with the amount set to 1, each dice roll separated + /// into its own dice. static List flatten(List dice) => dice.fold([], (all, cur) => [...all, ...List.filled(cur.amount, cur / cur.amount)]); @@ -133,6 +160,11 @@ class Dice { } } + /// Parses a string for dice rolls and returns a list of dice found. + /// The string must be in the format of `XdY` where X is the amount of dice and Y is the amount of sides, + /// optionally followed by a modifier in the format of `+Z` or `-Z` where Z is the modifier value. + /// + /// Example: `2d6+DEX` would return a list with a single dice with 2 amount, 6 sides and a modifier of DEX. static List guessFromString(String str) { final basicRollPattern = RegExp(r'\broll([+-][a-z]+)\b', caseSensitive: false); final dicePattern = RegExp(r'\b\dd\d+\b', caseSensitive: false); @@ -166,24 +198,32 @@ class Dice { 'amount: $amount, sides: $sides, modifierValue: $modifierValue, modifierSign: $modifierSign, modifierStat: $modifierStat'; } +/// A dice roll, containing the dice that was rolled and the results of the individual dice. class DiceRoll { final Dice dice; final List results; DiceRoll({required this.dice, required this.results}) { - assertDiceModifier(); + _assertDiceModifier(); } + /// Rolls a list of dice and returns a list of dice rolls. static List rollMany(List dice) => dice.map((d) => roll(d)).toList(); + /// Rolls a single dice and returns the result. static DiceRoll roll(Dice dice) => dice.roll(); + /// The total of the dice roll, including the modifier. int get total => results.reduce((all, cur) => all + cur) + (dice.modifierValue ?? 0); + /// Represents whether or not the dice roll was a critical hit, meaning that the highest possible + /// value was rolled. bool get didHitNaturalMax => indexOfNaturalMax >= 0; + + /// If the dice roll was a critical hit, this returns the index of the dice that was the critical hit. int get indexOfNaturalMax => results.indexOf(dice.sides); - void assertDiceModifier() { + void _assertDiceModifier() { if (dice.needsModifier) { throw Exception("Dice is being rolled without an actual modifier." "Use `dice.copyWithModifierValue(int modifierValue)`.\n" diff --git a/lib/entity_reference.dart b/lib/entity_reference.dart index a3e512a..859d0af 100644 --- a/lib/entity_reference.dart +++ b/lib/entity_reference.dart @@ -1,8 +1,16 @@ import 'dart:convert'; +/// A reference to an entity. +/// This is useful for storing the name & key of an entity without having to store the entire entity, +/// possibly for use in a dropdown or other UI element, or linking between entities in a database. class EntityReference { + /// The key of the entity. final String key; + + /// The name of the entity. final String name; + + /// The type of the entity. final String type; EntityReference({ diff --git a/lib/gear_choice.dart b/lib/gear_choice.dart index aee6bbc..4a16925 100644 --- a/lib/gear_choice.dart +++ b/lib/gear_choice.dart @@ -3,7 +3,10 @@ import 'dart:convert'; import 'base.dart'; import 'gear_selection.dart'; -/// This is the top level choice - provides one or more options to choose from. +/// Represents a choice of starting gear for a class. +/// +/// This is the top level choice - provides one or more options to choose from, +/// where each option is a [GearSelection], which is a list of [GearOption]s. /// /// For example, "choose a gift from your parents" which gives either "your father's sword" or /// "your mother's mace" @@ -18,9 +21,17 @@ class GearChoice with KeyMixin { @override final String key; + + /// The description of the gear choice. For example, "Choose a gift from your parents". final String description; + + /// The list of selections available for this gear choice. final List selections; + + /// The list of selections to preselect (if any). final List preselect; + + /// The maximum number of selections that can be made, if any. final int? maxSelections; GearChoice copyWith({ @@ -59,6 +70,7 @@ class GearChoice with KeyMixin { "maxSelections": maxSelections, }; + /// The preselected gear selections, if any. List get preselectedGearSelections => preselect.isEmpty ? [] : preselect.first == -1 diff --git a/lib/gear_option.dart b/lib/gear_option.dart index 1dbc7b3..7460d66 100644 --- a/lib/gear_option.dart +++ b/lib/gear_option.dart @@ -3,7 +3,8 @@ import 'dart:convert'; import 'base.dart'; import 'item.dart'; -/// Contains an item and amount +/// Represents a single option in a [GearSelection]. +/// Contains an item, and amount to receive. class GearOption with KeyMixin { GearOption({ required this.key, @@ -11,9 +12,14 @@ class GearOption with KeyMixin { required this.amount, }); + /// The key of the gear option. @override final String key; + + /// The item to receive. final Item item; + + /// The amount of the item to receive. final double amount; GearOption copyWith({ diff --git a/lib/gear_selection.dart b/lib/gear_selection.dart index 51192ef..2001160 100644 --- a/lib/gear_selection.dart +++ b/lib/gear_selection.dart @@ -18,8 +18,14 @@ class GearSelection with KeyMixin { @override final String key; + + /// The description of the gear selection. For example, "Your father's sword and 60 coins.". final String description; + + /// The list of options contained in this selection. final List options; + + /// The number of coins to receive. final double coins; GearSelection copyWith({ diff --git a/lib/item.dart b/lib/item.dart index 85c24a3..0f31356 100644 --- a/lib/item.dart +++ b/lib/item.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'base.dart'; import 'tag.dart'; +/// Represents an item: a potion, weapon, armor, etc. +/// Contains a name, description, and tags. class Item with KeyMixin { Item({ required this.meta, @@ -12,12 +14,19 @@ class Item with KeyMixin { required this.tags, }); + /// Dynamic metadata final dynamic meta; @override final String key; + + /// The name of the item. final String name; + + /// The description of the item. final String description; + + /// The tags of the item. final List tags; Item copyWith({ diff --git a/lib/monster.dart b/lib/monster.dart index 5cbd8e1..60ef920 100644 --- a/lib/monster.dart +++ b/lib/monster.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'base.dart'; import 'tag.dart'; +/// Represents a monster. class Monster with KeyMixin { Monster({ required this.meta, @@ -18,10 +19,20 @@ class Monster with KeyMixin { @override final String key; + + /// The name of the monster. final String name; + + /// The description of the monster. final String description; + + /// The instinct of the monster. final String instinct; + + /// The tags of the monster. final List tags; + + /// The moves of the monster. final List moves; Monster copyWith({ diff --git a/lib/move.dart b/lib/move.dart index 07e1fca..44ca50c 100644 --- a/lib/move.dart +++ b/lib/move.dart @@ -5,12 +5,24 @@ import 'dice.dart'; import 'entity_reference.dart'; import 'tag.dart'; +/// The category of a move. enum MoveCategory { + /// Starting move - attached to a class, given automatically. starting, + + /// Basic move - available to all classes. basic, + + /// Special move - available to all classes, but represent more advanced moves than basic. special, + + /// Advanced move - attached to a class, and given betweens levels 2 and 5. advanced1, + + /// Advanced move - attached to a class, and given betweens levels 6 and 10. advanced2, + + /// Other types of moves other, } @@ -31,12 +43,26 @@ class Move with KeyMixin { @override final String key; + + /// The name of the move. final String name; + + /// The description of the move - what it does, and how it works mechanically. final String description; + + /// The explanation of the move - how it works in the fiction, examples or other details. final String explanation; + + /// The dice of the move - how many dice to roll, and what size. final List dice; + + /// The class keys of the move - which classes can take this move. final List classKeys; + + /// The tags of the move final List tags; + + /// The category of the move final MoveCategory category; Move copyWith({ diff --git a/lib/race.dart b/lib/race.dart index 5b8b8ae..bd5fd2c 100644 --- a/lib/race.dart +++ b/lib/race.dart @@ -5,6 +5,7 @@ import 'dice.dart'; import 'entity_reference.dart'; import 'tag.dart'; +/// Represents a playable race such as a human, elf, or dwarf. class Race with KeyMixin { Race({ required this.meta, @@ -21,11 +22,24 @@ class Race with KeyMixin { @override final String key; + + /// The name of the race final String name; + + /// The description of the race's unique move. + /// Contains what it does, and how it works mechanically. final String description; + + /// The explanation of the race's unique move - how it works in the fiction, examples or other details. final String explanation; + + /// Classes that can be assigned to this race final List classKeys; + + /// The tags of this race final List tags; + + /// The dice list rolled when using this race's unique move. final List dice; Race copyWith({ diff --git a/lib/repository.dart b/lib/repository.dart index 72a5849..63ad5b3 100644 --- a/lib/repository.dart +++ b/lib/repository.dart @@ -1,12 +1,12 @@ import '_repository.dart' as _r; -import 'data/classes.dart'; -import 'data/items.dart'; -import 'data/monsters.dart'; -import 'data/moves.dart'; -import 'data/races.dart'; -import 'data/spells.dart'; -import 'data/tags.dart'; +import 'data/en-US/classes.dart'; +import 'data/en-US/items.dart'; +import 'data/en-US/monsters.dart'; +import 'data/en-US/moves.dart'; +import 'data/en-US/races.dart'; +import 'data/en-US/spells.dart'; +import 'data/en-US/tags.dart'; final _repo = _r.DungeonWorldRepository(); diff --git a/lib/session_mark.dart b/lib/session_mark.dart index 5b5d3ec..3885d41 100644 --- a/lib/session_mark.dart +++ b/lib/session_mark.dart @@ -2,7 +2,20 @@ import 'dart:convert'; import 'base.dart'; -enum SessionMarkType { bond, flag, endOfSession, other } +/// The type of session mark +enum SessionMarkType { + /// A bond + bond, + + /// A flag + flag, + + /// An end of session mark + endOfSession, + + /// A custom mark + other +} class SessionMark with KeyMixin { SessionMark({ @@ -14,8 +27,14 @@ class SessionMark with KeyMixin { @override final String key; + + /// The description of the session mark. When to mark it, what it means, etc. final String description; + + /// Whether or not the session mark has been completed, or checked. final bool completed; + + /// The type of session mark. final SessionMarkType type; SessionMark copyWith({ diff --git a/lib/spell.dart b/lib/spell.dart index cec4f5d..abe9c73 100644 --- a/lib/spell.dart +++ b/lib/spell.dart @@ -5,6 +5,7 @@ import 'dice.dart'; import 'entity_reference.dart'; import 'tag.dart'; +/// Represents a spell, or spell-like ability. class Spell with KeyMixin { Spell({ required this.meta, @@ -22,12 +23,26 @@ class Spell with KeyMixin { @override final String key; + + /// The name of the spell final String name; + + /// The description of the spell's effect, and how it works mechanically. final String description; + + /// The explanation of the spell's effect - how it works in the fiction, examples or other details. final String explanation; + + /// The level of the spell final String level; + + /// Classes that can use this spell final List classKeys; + + /// The dice list rolled when using this spell. final List dice; + + /// The tags of this spell final List tags; Spell copyWith({ diff --git a/lib/tag.dart b/lib/tag.dart index e6f225d..816105c 100644 --- a/lib/tag.dart +++ b/lib/tag.dart @@ -2,6 +2,9 @@ import 'dart:convert'; import 'base.dart'; +/// Represents a tag. +/// Contains a name, value, and description. +/// Examples are weight: 1, damage: 1d6, etc. class Tag with KeyMixin { Tag({ required this.name, @@ -9,8 +12,13 @@ class Tag with KeyMixin { this.description = "", }); + /// The name of the tag. final String name; + + /// The value of the tag. final dynamic value; + + /// The description of the tag. final String description; @override diff --git a/pubspec.lock b/pubspec.lock index 714c70b..35b8475 100755 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,358 +5,417 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: d93b0378aadce9c1388108067946276582c2ae89426c64c17920c74988508fed + url: "https://pub.dev" source: hosted version: "22.0.0" analyzer: dependency: transitive description: name: analyzer - url: "https://pub.dartlang.org" + sha256: "581a0281129283e75d4d67d6ac6e391c0515cdce37eb6eb4bc8a52e65d2b16b6" + url: "https://pub.dev" source: hosted version: "1.7.2" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: "3d82ff8620ec576fd38f6cec0df45a7c088b8704eb1c63d4c336392e5efca6ca" + url: "https://pub.dev" source: hosted version: "2.2.0" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: d810902f3971b6e8e2f9153c361d51bf1af1b99c25087906a50945e828a17591 + url: "https://pub.dev" source: hosted version: "2.8.1" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "5bbf32bc9e518d41ec49718e2931cd4527292c9b0c6d2dffcf7fe6b9a8a8cf72" + url: "https://pub.dev" source: hosted version: "2.1.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.dartlang.org" + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 + url: "https://pub.dev" source: hosted version: "1.3.1" cli_util: dependency: transitive description: name: cli_util - url: "https://pub.dartlang.org" + sha256: cd9cfe046f8b4d87f45abce8f14ec315a4eaedcf92a211e83fa080faf9ec7c1c + url: "https://pub.dev" source: hosted version: "0.3.3" collection: dependency: "direct main" description: name: collection - url: "https://pub.dartlang.org" + sha256: "6d4193120997ecfd09acf0e313f13dc122b119e5eca87ef57a7d065ec9183762" + url: "https://pub.dev" source: hosted version: "1.15.0" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: f08428ad63615f96a27e34221c65e1a451439b5f26030f78d790f461c686d65d + url: "https://pub.dev" source: hosted version: "3.0.1" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: ad538fa2e8f6b828d54c04a438af816ce814de404690136d3b9dfb3a436cd01c + url: "https://pub.dev" source: hosted - version: "0.15.2" + version: "1.0.3" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: cf75650c66c0316274e21d7c43d3dea246273af5955bd94e8184837cd577575c + url: "https://pub.dev" source: hosted version: "3.0.1" dart_style: dependency: "direct dev" description: name: dart_style - url: "https://pub.dartlang.org" + sha256: "4e65f1921774e1126bd4d7cbc8f866b5fc166346b87d42d0c4ca2b874b153b56" + url: "https://pub.dev" source: hosted version: "2.0.3" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: b69516f2c26a5bcac4eee2e32512e1a5205ab312b3536c1c1227b2b942b5f9ad + url: "https://pub.dev" source: hosted version: "6.1.2" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "4f4a162323c86ffc1245765cfe138872b8f069deb42f7dbb36115fa27f31469b" + url: "https://pub.dev" + source: hosted + version: "2.1.3" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: dda85ce2aefce16f7e75586acbcb1e8320bf176f69fd94082e31945d6de67f3e + url: "https://pub.dev" source: hosted version: "2.0.1" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: bfb651625e251a88804ad6d596af01ea903544757906addcb2dcdf088b5ea185 + url: "https://pub.dev" source: hosted version: "3.0.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: e362d639ba3bc07d5a71faebb98cde68c05bfbcfbbb444b60b6f60bb67719185 + url: "https://pub.dev" source: hosted version: "4.0.0" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "0d4c73c3653ab85bf696d51a9657604c900a370549196a91f33e4c39af760852" + url: "https://pub.dev" source: hosted version: "1.0.3" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: d9bdfd70d828eeb352390f81b18d6a354ef2044aa28ef25682079797fa7cd174 + url: "https://pub.dev" source: hosted version: "0.6.3" lints: dependency: "direct dev" description: name: lints - url: "https://pub.dartlang.org" + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" source: hosted version: "1.0.1" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: "0520a4826042a8a5d09ddd4755623a50d37ee536d79a70452aff8c8ad7bb6c27" + url: "https://pub.dev" source: hosted version: "1.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "38c7be344ac5057e10161a5ecb00c9d9d67ed2f150001278601dd27d9fe64206" + url: "https://pub.dev" source: hosted version: "0.12.10" meta: dependency: "direct main" description: name: meta - url: "https://pub.dartlang.org" + sha256: "5202fdd37b4da5fd14a237ed0a01cad6c1efd4c99b5b5a0d3c9237f3728c9485" + url: "https://pub.dev" source: hosted version: "1.7.0" mime: dependency: transitive description: name: mime - url: "https://pub.dartlang.org" + sha256: a7a98ea7f366e2cc9d2b20873815aebec5e2bc124fe0da9d3f7f59b0625ea180 + url: "https://pub.dev" source: hosted version: "1.0.0" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" source: hosted - version: "1.4.13" + version: "2.0.2" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "20e7154d701fedaeb219dad732815ecb66677667871127998a9a6581c2aba4ba" + url: "https://pub.dev" source: hosted version: "2.0.0" path: dependency: "direct dev" description: name: path - url: "https://pub.dartlang.org" + sha256: "2ad4cddff7f5cc0e2d13069f2a3f7a73ca18f66abd6f5ecf215219cdb3638edb" + url: "https://pub.dev" source: hosted version: "1.8.0" pedantic: dependency: transitive description: name: pedantic - url: "https://pub.dartlang.org" + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" source: hosted version: "1.11.1" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "05955e3de2683e1746222efd14b775df7131139e07695dc8e24650f6b4204504" + url: "https://pub.dev" source: hosted version: "1.5.0" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "59ed538734419e81f7fc18c98249ae72c3c7188bdd9dceff2840585227f79843" + url: "https://pub.dev" source: hosted version: "2.0.0" quiver: dependency: "direct main" description: name: quiver - url: "https://pub.dartlang.org" + sha256: "5e592c348a6c528fb8deb7cc7d85a7097ce65bf2349121ad004d1fc5d5905eaa" + url: "https://pub.dev" source: hosted version: "3.0.1" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: c240984c924796e055e831a0a36db23be8cb04f170b26df572931ab36418421d + url: "https://pub.dev" source: hosted version: "1.2.0" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.2" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" source: hosted - version: "0.2.9+2" + version: "1.1.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" source: hosted - version: "0.2.4+1" + version: "1.0.4" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "8c463326277f68a628abab20580047b419c2ff66756fd0affd451f73f9508c11" + url: "https://pub.dev" source: hosted version: "2.1.0" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "52de2200bb098de739794c82d09c41ac27b2e42fd7e23cce7b9c74bf653c7296" + url: "https://pub.dev" source: hosted version: "0.10.10" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: d5f89a9e52b36240a80282b3dc0667dd36e53459717bb17b8fb102d30496606a + url: "https://pub.dev" source: hosted version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: f8d9f247e2f9f90e32d1495ff32dac7e4ae34ffa7194c5ff8fcc0fd0e52df774 + url: "https://pub.dev" source: hosted version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: db47e4797198ee601990820437179bb90219f918962318d494ada2b4b11e6f6d + url: "https://pub.dev" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: dd11571b8a03f7cadcf91ec26a77e02bfbd6bbba2a512924d3116646b4198fc4 + url: "https://pub.dev" source: hosted version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a88162591b02c1f3a3db3af8ce1ea2b374bd75a7bb8d5e353bcfbdc79d719830 + url: "https://pub.dev" source: hosted version: "1.2.0" test: dependency: "direct dev" description: name: test - url: "https://pub.dartlang.org" + sha256: "3bd8a6983183bc6038791bccf2dd3f29638180896fee4e3b31ca62c1dab870c5" + url: "https://pub.dev" source: hosted - version: "1.16.5" + version: "1.17.10" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "299f2348a0106882f5f107541b0dbd491aa45b4bbdd008abe10b387a45b9afba" + url: "https://pub.dev" source: hosted - version: "0.2.19" + version: "0.4.2" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: "6b978970065e8980478dfddebc58673b45bd291a72bbf871b831ea084e6abcc8" + url: "https://pub.dev" source: hosted - version: "0.3.15" + version: "0.4.0" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "53bdf7e979cfbf3e28987552fd72f637e63f3c8724c9e56d9246942dc2fa36ee" + url: "https://pub.dev" source: hosted version: "1.3.0" uuid: dependency: "direct main" description: name: uuid - url: "https://pub.dartlang.org" + sha256: "0ea20bfc625477e17f08a92d112272a071609b275ce4ca10ad853e1426ca3758" + url: "https://pub.dev" source: hosted version: "3.0.4" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: "422eda09e2a50eb27fe9eca2c897d624cea7fa432a8442e1ea1a10d50a4321ab" + url: "https://pub.dev" source: hosted version: "6.2.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "68173f2fa67d241323a4123be7ed4e43424c54befa5505d71c8ad4b7baf8f71d" + url: "https://pub.dev" source: hosted version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "2.4.0" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "5adb6ab8ed14e22bb907aae7338f0c206ea21e7a27004e97664b16c120306f00" + url: "https://pub.dev" source: hosted version: "1.0.0" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "3cee79b1715110341012d27756d9bae38e650588acd38d3f3c610822e1337ace" + url: "https://pub.dev" source: hosted version: "3.1.0" sdks: - dart: ">=2.17.0-266.5.beta <3.0.0" + dart: ">=2.17.0 <4.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 81131f6..71ad671 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: Data dump of Dungeon World classes, moves, equipment, and more. Als version: 3.0.0 environment: - sdk: ">=2.17.0-266.5.beta <3.0.0" + sdk: ">=2.17.0-266.5.beta <4.0.0" dependencies: collection: ^1.15.0-nullsafety.4 @@ -17,3 +17,7 @@ dev_dependencies: dart_style: ^2.0.3 path: ^1.6.4 test: ^1.6.4 + +script_runner: + scripts: + - format: dart format --line-length 100