commit 7c29335b0d27e5a9f65481e102bac6d02a423d6b Author: Tim Evans Date: Wed Jul 15 17:22:41 2026 +0100 Baseline: Delta Green official system v1.7.0 (MIT, TheLastScrub) Pristine copy of the installed deltagreen 1.7.0 release build. Co-Authored-By: Claude Fable 5 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..940a531 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,410 @@ +# Release/Patch Notes + +## Version 1.7.0 - 2026-06-20 + +> Thanks to [hknmtt](https://github.com/hknmtt) for updating the Brazilian translation. +> Thanks to [Sobran](https://github.com/SobranDM) for updating Delta Green for Foundry V14. + +### **Features:** + +- Update the system for basic Foundry v14 compatibility. +- [#296](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/296) - Remove adaptation checks if not adapted. +- [#281](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/281) - Add tooltips to checkboxes in adaptation area. +- [#211](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/211) - Move macros to System macros folder in compendium. +- [#283](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/283) - Added new actor sheet with left hand Sidebar RFC +- [#291](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/291) - Moving Luck button from three dots to left hand panel +- [#374](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/374) - Moving Age to Bio tab + +## Version 1.6.6 - 2026-04-15 + +### **Bug Fixes:** + +- [#382](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/382) - Fix rituals not respecting damage from learning. +- [#355](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/355) - Save the physical description of an agent. +- [#359](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/359) - Save the profession of an NPC. +- [#363](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/363) - First Aid misspelled in stat-parser-macro.js + +## Version 1.6.5 - 2026-02-17 + +### **Features:** + +- French translation updated by [Hrunh](https://github.com/hrunh) +- Spanish translation updated by [lozanoje](https://github.com/lozanoje) + +## Version 1.6.4 - 2026-02-12 + +> Thanks to [666f78](https://github.com/666f78) for adding the Ukrainian translation. + +### **Features:** + +- [#312](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/312) - Add tooltip to Breaking point. +- [#328](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/328) - Exclude Unnatural from Marked Failed Checks. +- [#338](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/338) - Remove checkbox for unnatural skill. + +### **Bug Fixes:** + +- [#316](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/316) - Remove the custom border from pressed, toggle and action buttons. +- [#340](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/340) - Allows to open a vehicle sheet without opening an agent first. + +## Version 1.6.3 - 2025-12-12 + +> Skips v1.6.2 due to a mistake in the release process. Oops. + +\--- + +> Thanks to [delgar89](https://github.com/delgar89) for updating the Polish translation. + +### **Features:** + +- [#258](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/258) - Added a keybind option for hovering tooltips and option to hide all. +- [#245](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/245) - Automate damage from STR score to melee and unarmed attacks for NPCs. Agents were already doing it. + +### **Bug Fixes:** + +- [#269](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/269) - Added calculation for max HP and max WP for unnatural and allow to edit them. +- [#274](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/274) - Automated fail marking now works after dice so nice resolve roll. +- [#268](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/268) - Removed unnecessary tooltips. +- [#278](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/278) - It shows the tooltip only once for skills without proficiency. +- [#281](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/281) - Add tooltips to adaptation area. +- [#298](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/298) - Don't add art skill in actor creation. +- [#301](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/301) - SAN doesn't zero out when player updates sheet and the sanity is private. +- [#272](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/272) - Fixed auto-marked skill failure rollbacks in chat bubbles. + +## Version 1.6.1 - 2025-09-09 + +> Thanks to the following new contributor: [Tobifroe](https://github.com/tobifroe). + +### **Features:** + +- [#255](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/255) - Added option to toggle display of tooltips per client. + +### **Bug Fixes:** + +- [#252](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/252) - Removed redundant lines in skill tooltip text. +- [#253](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/253) - Close "Automation Menu" & "Handler Settings" when settings are saved. +- [#259](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/259) - Fixed "Keep Sanity Private" setting in agent sheets. +- [#263](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/263) - Fixed inability to edit item descriptions. + +## Version 1.6.0 - 2025-09-04 + +> Thanks to the following new contributors: [reyzor](https://github.com/reyzor1991), [lozanoje](https://github.com/lozanoje), [dairefinn](https://github.com/dairefinn), [MrTheBino](https://github.com/MrTheBino), & [vonv](https://github.com/vonv). + +### **Features:** + +- [#194](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/194) - Created an unofficial and fan-made community development Discord server. +- [#204](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/204) - Organized system compendia into single Folder. +- [#206](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/206) - Clarified language regarding who can see Impossible Landscapes and Hypergeometry content. +- [#207](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/207) - Added option to automatically check skills upon a failed roll. +- [#216](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/216) - Added a new sheet template for NPCs who are set to limited visibility. +- [#219](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/219) - Organized some settings into new menus: Automation Settings and Handler Settings. +- [#230](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/230) - Added tooltips for each skill, keeping in the spirit of their descriptions in the book. +- [#247](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/247) - Lightly organized and updated the system's documentation; more documentation improvements to come. + +### **Bug Fixes:** + +- [#203](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/203) - Fixed default "Art (Painting)" custom skill from persisting despite deletion. +- [#229](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/229) - Fixed deprecation warning related to gridDistance and gridUnits. + +### **Localization:** + +- [#193](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/193) - Fixed various French translations. +- [#199](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/199) - Fixed various German translations. +- [#204](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/204) - Fixed several miscellaneous language issues. + +### **Backend Changes:** + +- [#217](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/217) - Converted Actor Sheets to Foundry's ApplicationV2 framework. +- [#224](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/224) - Converted all prompts/dialogs to Foundry's ApplicationV2 framework. +- [#228](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/pull/228) - Added contribution guidelines, issue templates, pull request templates, and tests. + +## Version 1.5.0 - 2025-05-17 (FOUNDRY V13 COMPATIBLE ONLY) + +- Fix/Enhancement [GitHub #186] - A bunch of adjustments to try to better work in Foundry v13. Some of these changes break compatibility with v12. +- Thanks to Achoobert for tweaking how the default actor vision and disposition are. +- Thanks to hknmtt for updating the Portuguese (BR) translation with some fixes. +- Thanks to vonv for updating the French translation with some fixes. + +## Version 1.4.13 - 2025-04-20 (FOUNDRY V12 COMPATIBLE ONLY) + +- Thanks to [delgar89](https://github.com/delgar89) for updating the Polish translation to match what is being sold in Poland at the moment. +- Thanks to [Hrunh](https://github.com/Hrunh) for updating the French translation to add some fixes. +- Thanks to [ryotai-trpg](https://github.com/ryotai-trpg) for creating a fix for sorting by column for the Japanese localization. + +## Version 1.4.12 - 2025-02-22 (FOUNDRY V12 COMPATIBLE ONLY) + +- Fix [GitHub #175] - Bug in column based sorting logic implemented in last update, hopefully fixed now. Also fixed the missed scrollbar color on the Agent's sheet. + +## Version 1.4.11 - 2025-02-16 (FOUNDRY V12 COMPATIBLE ONLY) + +- Enhancement [GitHub #153] - Have added some enhancements to the default Foundry UI to make it feel more Delta Green themed. Have left journal entries alone for now. +- Fix [GitHub #172] - Skills are now sorted according the locale/language selected by the GM for the world. +- Fix [GitHub #129] - Type/Custom Skills and Special Trainings are now sorted rather than being laid out as they are added. +- Fix [GitHub #118] - The Unnatural sheet's skills and training section should sort better now in column sort mode. +- Enhancement - Some layout improvements to the Agent and NPC sheets. Particularly related to column sorting of skills. + +## Version 1.4.10 - 2025-01-16 (FOUNDRY V12 COMPATIBLE ONLY) + +- Further French Language Fixes/Improvements by Hrunh, and updated contributor list. +- Thanks to ryotai-rpg for fixing up the Japanese localization. + +## Version 1.4.9 - 2024-12-08 (FOUNDRY V12 COMPATIBLE ONLY) + +- Fix/Enhancement [GitHub #161] - Hrunh has updated/fixed some of the French (FR) localization. +- Enhancement [GitHub #160] - Baixian-main has added a Chinese (CN) localization. + +## Version 1.4.8 - 2024-10-05 (FOUNDRY V12 COMPATIBLE ONLY) + +- Fix [GitHub #147] - Vehicle Actor sheet broken from last set of changes, should open again. +- Fix - Thanks to Iozanoje for fixing issue with Operation Code Name Generator macro. +- Enhancement [GitHub #144] - Thanks to Mojo-89 for a Swedish localization pack for the system. +- Fix [GitHub #148] - Fixed CSS issue with Ritual item sheet. May need to revisit rich text entry boxes on item sheets in general. +- Fix [GitHub #141] - Added SAN loss for learning a ritual to item sheet + +## Version 1.4.7 - 2024-08-04 (FOUNDRY V12 COMPATIBLE ONLY) + +- Enhancement [GitHub #131] - The items sheet is now re-orderable by drag drop. Or, you can click the sort button by each item section, and set it to order them alphabetically. The easiest way to drag is to click on the name of the item, although most of the non-rollable part of the item row works as well. +- Enhancement - As part of #131, to make dragging easier, and to provide a more intuitive user interface, all rollable values now have a clickable dice icon by them to indicate they trigger a roll. +- Enhancement [Loosely GitHub #73 and #132] - Improved the item macro (for the hotbar) so that it can be used without having a token selected, and now by default it will also automatically roll damage on a successful test (or double damage on a critical success). +- Enhancement - The custom modifier for the modify percentile roll dialogue (the popup you get from shift click or right click) is now persistent by character, so if you are commonly rolling +15% or something different than the normal ones like +/-20%, it will come up the same the next time you open the dialogue. +- Enhancement [GitHub #135] - Updated Special Training target to be more clear that it is a x5 test, rather than the raw skill. +- Enhancement [GitHub #107] - There are now item types for Tomes and Rituals (hypergeometry). These only show up for players if the Handler gives them at least one item of either type, or if the Handler sets a world setting that always shows it. These item sections always appear for the Handler. There are sections on the item sheets that are only visible to the Handler as well. Last, the "Ritual" invocation has been removed from the skills list, and moved to the Ritual item section instead. +- Fix - The stat block parser macro was supposed to show up as a button in the Actors section of the HUD, but it was not. +- Fix - Renamed repository to remove "Unofficial" from the repository name, which was the last vestige of the old 'unofficial' setup, but was left because it was in the system manifest and had other external links to it. + +## Version 1.4.6 - 2024-07-16 (FOUNDRY V12+ COMPATIBLE ONLY) + +- Enhancement [GitHub #104] - Exhaustion Checkbox and automation. Added a field on the Agent sheet to note "Exhaustion" and to set the check penalty for skill, x5 stat, and SAN tests that come with it. +- Fix [GitHub #120] - Character Sheet Localization Warning. If using a language that the system isn't translated to, you will get a warning popup every time you opened a character sheet. This has been changed to a less obtrusive console error. +- Fix [GitHub #121] - Duplicated Shotgun Item in Compendium (Thanks to andrewbeard for pull request) +- Enhancement [GitHub #124] - Added some quick roll options for the roll modifier dialogue for percentile rolls (such as +/-20 and +-40). Also spent some time to try to make it more clear in the chat card when modifiers are applied to a target. +- Enhancement [GitHub #127] - NPC stat block parser macro was non-function in Foundry v12, this should be fixed now. Also attempted to improve the parser, added some limited functionality to grab the armor and attacks an NPC has. Although due to how much variation there is how this is notated across the various Arc Dream and fan works, this will likely be somewhat unreliable. + +## Version 1.4.5 - 2024-06-17 (FOUNDRY V12+ COMPATIBLE ONLY) + +- Fix [GitHub #111] - v12 Compatibility. There are various issues that have arisen in the change to v12, the Agent sheet being broken being the most obvious. But several issues with rolls and with Dice So Nice were also fixed. +- Fix - Lethality toggle not updating properly. +- Enhancement [GitHib #113] - (On-going) Slight improvements to stat parser module. +- Fix [GitHub #116] - This was fixed as a side effect of fixing the v12 Dice So Nice issues, previously when rolling with Dice So Nice the sound of Foundry VTT dice was played, then the Dice So Nice sound effects played, and finally the roll would show. +- Enhancement - Better localization of new actor and item names. + +## Version 1.4.4 - 2024-04-14 + +- Fix [GitHub #109] - Typo in Disorder header +- Fix [GitHub #110] - Pregen Agents have wrong skill for "Unarmed Combat" attack, was using "Melee Weapons" instead of "Unarmed Combat". Also changed the expense on it from "Incidental" to "NA". + +## Version 1.4.3 - 2024-04-07 + +- Enhancement [Github #101] - Thanks to 16-Bits and jalensailen for putting together a way to change the sorting to be alphabetical by column instead of by row. Note - you must opt into this behavior by changing a setting for the system, the default is the original behavior that sorts by rows. Enabling the column sort option better matches the standard character sheet (although 'type' skills are still in their current position). +- Fix [Github #106] - A bug in the system would change the first 'type' skill's label to the localized version of 'Art - Painting' if it still had the original name that comes with a new character, regardless of it had been edited to something else entirely like 'Science - Physics' or whatnot. This bug unfortunately effected the import of all the 1001 pregenerated agents in the compendium pack, leading to in some cases even the most hardened Special Operator having near world class painting skills. The pregenerated agents were deleted and reformed to fix this. +- Enhancement [Github #106] while doing previous fix, changed agents so they had the profession stripped off their names ("NURSE-LastName, FirstName" now just "LastName, FirstName). This was originally done to make it easier to see in the compendium which agents were for which profession at a glance. But since compendium packs (and the Foundry VTT CLI) support folders natively now, they were instead sorted into folders matching their profession to make perusing them easier and to clean up the overall list, as picking through 1001 entries could be a bit challenging. + +## Version 1.4.2 - 2024-01-28 + +- Fix for issues around skills reverting to "Art - Painting". +- Added German Translation provided by KarstenW76. + +## Version 1.4.1 - 2023-12-13 + +- Fix [Github #99] - Last round of changes caused checkbox for improvement on type (Art - XXX) skills to disappear, fixed. +- Fix - Pointed out that since items default in with a lethality of 10%, they get a toggle to swap to this on the character sheet from whatever damage was set, and it isn't intuitive that you must set the lethality to 0% to hide this toggle. + +## Version 1.4.0 - 2023-12-10 + +- Feature [Github #70] - Added ability to track and roll Special Training. +- Enhancement - Slight restyle of Skill section of sheet, saving space. + +## Version 1.3.5 - 2023-11-20 + +- Working on improving the process for packing a new build, but some things have gone wrong. So no actual changes here, just iterating forward on the build to avoid some issues that cropped up. + +## Version 1.3.3 - 2023-10-17 + +- Fix [Github #93] - Custom target numbers for weapons can now be set correctly. + +## Version 1.3.2 - 2023-10-07 + +- Enhancement - When hitting a breakpoint, current SAN now turns bold and red, to help indicate you need to reset your breaking point. +- Fix [Github #86] - You can now right-click again to get the modify roll dialog, instead of just shift-click. +- Fix [Github #87] - SAN rolls are hidden properly again if GM chooses. +- Fix [Github #97] - Fixed broken tooltip on SAN that did not show current break point anymore. + +## Version 1.3.1 - 2023-09-23 + +- Enhancement - Changed pause icon to be Delta Green logo. + +## Version 1.3.0 - 2023-09-23 + +- Enhancement - Refactor roll system to make future changes easier. +- Enhancement - Slight restyle of roll chat messages. +- Enhancement - Restyled actor sheets to be more in-line with the core book's design. You can change back to the old style in the settings for the Delta Green system. +- Enhancement[GitHub #72] - Weapons can now have modifiers for their rolls built-in. +- Enhancement - Weapons can choose a custom target for their rolls. This can be used for unnatural creature attacks that may not line up with one of the skills. +- Fix - Damage rolls can now utilize math functions like base Foundry rolls. +- Enhancement - Hide untrained skills toggle turned into toggleable eye icon rather than a checkbox. + +## Version 1.2.6 - 2023-09-13 + +- Fix [Github #82] - New packaging workflow from @jalensailin will hopefully resolve issues with the Forge by deploying the v11 compendium packs directly. + +## Version 1.2.5 - 2023-09-09 + +- Fix - Removing more places where system still says 'Unofficial' at Arc Dream's request + +## Version 1.2.4 - 2023-08-03 + +The system is now officially recognized by Arc Dream! + +- Enhancement[GitHub #77] - Changed some English localization labels and the legalese, per Arc Dream's request. +- Fix - Fixed layout bug on bond sheet. +- Enhancement[GitHub #78] - Added checkbox to bonds on the Agent sheet that you can use to indicate if the bond has been damaged since the last home scene. Also added a button to allow clearing the checkbox on all bonds. +- Enhancement [GitHub #80] - Can now roll SAN Damage from unnatural sheet +- Enhancement [GitHub #81] - You can now hide the Impossible Landscapes specific fields from the Agent's sheet by changing a system setting. + +## Version 1.2.2 - 2023-07-20 + +- Enhancement [Github #76] - jalensailin added drag drop functionality to items. If you hold alt and drag, it will automatically delete the item from the original sheet. Otherwise, it will duplicate the item. +- Fix [Github #74] - jalensailin fixed issue with Portuguese (Brasil) translation. + +## Version 1.2.0 - 2023-06-28 [BREAKING CHANGE: THIS VERSION FORWARD COMPATIBLE WITH FOUNDRY V11 OR HIGHER ONLY!] + +- Fix [GitHub #71] - Fix for the update skill button does not work in Foundry V11. +- Fix - Dragging items from one sheet to another now does create the item on the other sheet, although it does not delete the item on the original character sheet. +- Enhancement - (Work in Progress) Added macro to parse a DG stat block. Currently only works for English, and only gets core attributes and skills. Call from a macro like: game.deltagreen.ParseDeltaGreenStatBlock() + +## Version 1.1.0 - 2022-09-11 [BREAKING CHANGE: THIS VERSION FORWARD COMPATIBLE WITH FOUNDRY V10 OR HIGHER ONLY!] + +- Enhancement - Update to new data model for Foundry V10. This breaks compatibility with older versions, but leaves the system in a better place for future updates. Thanks to Jailensailen for help with this effort. +- Enhancement [GitHub 39] - Jailensailen added a way to toggle lethality directly on the actor sheet without editing the item. There is now a toggle button beside the damage formula/lethality percentage. +- Enhancement [GitHub #56] - Added an actor sheet for Vehicles +- Fix [GitHub #66] - Dragging item macros to hot bar, as well as executing them seemed to be broken. +- Fix [GitHub #62] - Fixed issue with how weapon skill rolls are displayed in chat cards (incorrectly appended 'x5' to rolls that were not x5 rolls). +- Enhancement [GitHub #58] - Did not completely overhaul Agent sheet per request, but did implement some of the requested changes to make the Agent/NPC sheets shorter, so that they require less scrolling when on smaller screens. Thanks to wush3 for providing some of the CSS for this. +- Enhancement - Made a few improvements to improvements to layout for a few of the item and NPC sheets. + +## Version 1.0.6 - 2022-05-26 + +- Enhancement - IgorAK25 has submitted a Portuguese translation for the system. + +## Version 1.0.5 - 2022-03-20 + +- Enhancement [GitHub #53] - Added all physical attributes (on top of DEX) as options for the test for a weapon, to accomodate a special weapon in the Jack Frost module. +- Enhancement - Put a little dice icon next to the SAN label to make it more obvious that is how you roll a SAN test on the Agent's sheet. +- Enhancement - Added some buttons to the gear tab of the Agent's sheet that allow opening the compendiums for weapons or armor directly from the sheet. +- Enhancement - Made tabs in nav bar, look a little bit more obviously like tabs. +- Enhancement - Made it so that existing type skills are more editable now, to make using the pregens that have craft/language/science skills easier. +- Enhancement - Added some GM-only fields to the CV section of the Agent and NPC sheets that supports values recording in Impossible Landscapes + +## Version 1.0.4 - 2022-02-05 + +- Fix [GitHub #50] - The custom background images used on the Actor sheets was also showing up for other free-floating windows, such as when the encounter tracker is undocked. Because of the bright background, it was hard to read the text or see buttons, so have changed the CSS to try to exclude these windows from the custom background image. +- Fix [GitHub #43] - Bond Scores on Agent Pregens from u/jets_or_chasm fixed to correctly match charisma score of the agent. Also re-created the compendium using a newer version of the pregen sheet that has more + +## Version 1.0.3 - 2022-02-04 + +- Other - Update compatible version to v9 (Note - this update could potentially have some effects on older Foundry versions) +- Fix [GitHub #48] - The new system option to hide SAN score was not also hiding Ritual proficiency, making it trivial to back-calculate the SAN score for players that know the formula for the Ritual skill. +- Fix [GitHub #50] - In Foundry v9, seems like the sections below the nav were anchored to the bottom of the window, so as the window got bigger the section would float away from the nav leaving a big gap. Attempted to fix CSS for this by setting how the grid should flex more specifically. + +## Version 1.0.2 - 2021-11-04 + +- Fix - Pregen Agents were getting duplicated Unarmed Strike items added on creation. +- Fix - Unarmed Strike item in the compendium was using 'Melee Combat' instead of 'Unarmed Combat' as its skill. +- Enhancment - Added system option for a world to make SAN target and skill rolls hidden from non-GM players. SAN tests change to blind rolls for players who are not GM. + +## Version 1.0.1 - 2021-08-14 + +- Fix [GitHub #31] - Default Type Skill of Art-Painting that is added automatically when making a new agent should be localizable now. +- Enhancement - Added a separate Actor type and sheet for _Unnatural_ creatures and a similar sheet that for non-agent NPC characters. +- Enhancement - The system will try to automatically add an 'Unarmed Attack' item to a new agent when they are created to make it more obvious how this is handled within the system. [Update - accidentally had this disabled in logic when packaging system, will re-add later...] +- Enhancement - DEX x5 is now selectable as an option to roll for a weapon's skill test, which is useful for items like hand grenades that are rolled or thrown. +- Enhancement - Eduard Cot (trombonecot) submitted a Catalan language pack for the system. +- Enhancement - Added list of Pregen Agents (originaly from Reddit user u/jets_or_chasm, AKA jimstorch) as a compendium pack to allow a player to jump back in quickly after a death, or to make playing for the first time easier by presenting a list of agents of 24 professions. See for more information. +- Enhancement - Added some roll tables that allow making Fall of Delta Green-style Operation Code names (e.g. 'Operation Able Archer'). These tables are based on roll tables created by Reddit user u/Travern. Note - there is also a compendium with a macro that will randomly pick a combination of the tables, then draw from those tables to make a random 2-part operation name to send to the chat. + +## Version 1.0.0 - 2021-06-05 [BREAKING CHANGE: THIS VERSION FORWARD COMPATIBILE WITH FOUNDRY 0.8.6 OR HIGHER ONLY!!!] + +- Changes to support 0.8.6+ Foundry + + - Revamped data model for actor sheet. Note due to the changes, the new system is not backwards compatible with older versions of Foundry now. + - Rolls all asynchronous now. Should allow less work to be required in future versions when asynchronous rolls are required. + +- Enhancement - Roll Modifier Dialogues + + - Added option to choose roll mode in the roll modifier dialogue for both percentile/lethality tests and damage rolls. + - Can now SHIFT+CLICK to get the Roll Modifier Dialogue for LUCK rolls. Cannot seem to make it feasible to get the right-click option to work on the menu currently. + - Changed d100 Roll Modifier dialogue to have a +/- dropdown instead of needing to type it into the box. + +- Enhancement - Based on a character's strength, formula will automatically adjust for Melee and Unarmed damage rolls per the rules on page 55 of the Agent's Handbook (+1 for 13-16 STR, etc...). **NOTE** - Some adjustment to damage formulas on existing weapons may need to be made if it was manually added already. + +- Enhancement - Added a descriptor field 'Relationship' to bonds, so you can give a name, and then optionally the relationship (e.g. 'Mother', 'Friend') as two separate fields. Makes discerning who is who on the bonds sheet easier at a glance. + +- Enhancement - More CSS Improvements, mostly to Item Sheets. + - Cleaned up layout on bonds, armor, weapons, gear item sheets + - Made weapons, armor and gear Item Sheets slightly more uniform in how the same fields are laid out. + +## Version 0.9.9 - 2021-03-27 + +- Fix - [GitHub #23] - Localization mistake, had two spaces in between "Critical" and "Success" or "Failure" in chat cards. +- Fix - [GitHub #24] - The chat card that was generated from rolling a skill check by clicking on a weapon (e.g. Firearms for a pistol) was not being localized. Fixed this along with a related tooltip that wasn't being localized either. +- Fix - [GitHub #25] - The chat card for damage and lethality was not bolding those terms like it would for other skill or percentile rolls. +- Fix - [GitHub #26] - When clicking on the 'Roll Luck' button in the character sheet header, the resulting chat card was not being localized properly. +- Fix - [GitHub #27] - Using a language setting that did not have a full translation was breaking adding skills to the agent's actor sheet. Should not break quite so quickly now, but will likely need a better long term fix at some point. +- Fix - [GitHub #28] - Missing localization keys for break point tooltips added. +- Fix - Made Agent sheet default width a little wider so skills with longer names aren't getting clipped off. Also a few other alignment fixes in the CSS. + +- Enhancement - [GitHub #28] - Spanish language translation, many thanks to CthulhuRol for providing it! +- Enhancement - Added a macro that allows for rolling the skill check on a weapon, so there can be macro buttons for both the damage and the skill check if desired. + - Sample syntax: game.deltagreen.rollItemSkillCheckMacro("Combat Dagger"); +- Enhancement - Thanks to _Uriele_ - Added functionality from the Handler's Guide (page 188) for 'Inhuman' stat tests, test where the stat (e.g. CON) is 20 or higher, giving a x5 target of 100 or higher. In this event, the test auto succeeds on a roll of anything other than 100, and a roll lower than the stat value is a critical (along with regular critical logic). +- Enhancement - Added 'Ritual' skill, which is calculated and is equal to 99 - current sanity (thanks to _Uriele_ for mentioning it). See page 166 under 'Ritual Activation' for the full rules. +- Enhancement - Total protection rating of all _equipped_ armor now displayed by HP. + +- Font and Background Change and Configuration Options - _NOTE THIS CAN BE CHANGED IN THE SYSTEM SETTINGS BACK TO WHAT IT WAS!_ + - Enhancement - Added system setting for font choice, with a few options. For example you can set a world to use typewriter style font for an older feel. + - Enhancement - Added system setting for background image choice, with a few options. Changed default from normal Foundry parchment to a lighter, more moder looking paper. Also included option for old, used/crinkled paper for a more unsettling or hard-used look. + +## Version 0.9.7 + +- Enhancement - Can now click on the icon for armor/other gear to equip or unequip it. +- Enhancement - Changed so that players with the 'Limited' permission on an actor now only see the C.V. tab of the actor's character sheet, instead of the entire sheet. Previously the 'Limited' permission and the 'Observer' permission gave the same result. The 'Observer' permission is unchanged and still shows a read-only view of the entire sheet. +- Enhancement - Added ability to alter formula for damage rolls by either **right clicking** _or_ **holding shift and left clicking**. +- Enhancement - Added ability to alter targets for tests by either **right clicking** _or_ **holding shift and left clicking**. Applies to the following rolls: + - Skill tests + - Attribute tests + - Lethality tests +- Improved CSS on actor sheet in a few places. + - New Font (was previously in style sheet, but not properly applied). + - Nav bar alignment/border consistent across tabs for a cleaner look moving between sections. + - Gear sheet alignment cleaner with certain fields now being centered. + - CV sheet now has some padding on fields so things aren't so cramped looking. +- Fix - Thanks to @Hrunh for submitting update to localization in item sheet +- Fix - typo in Alertness skill (English locale), thanks to roestrei for report + +## Version 0.9.6 + +- Incremented Core Compatible Version after testing against release version of Foundry 0.7.5. +- Made the gear section a little less ugly by adding some nicer section dividers. +- Fixed some awkward tooltip wording. + +## Version 0.9.4 + +- Fix - Pharmacy and Surgery skills were missing. +- Fix - Accounting and Disguise base skill rating were 0%, should be 10%. +- Fix - Damage on medium pistol in compendium was wrong, also fixed some base range values that were off. +- Enhancement - Adding support for localization. Character sheet and items sheets (gear, bonds, etc.) should be localized now, but not the compendium packs. +- Workaround - The (current alpha) 7.2 Foundry release seems to have a bug where rolls without a leading number ('d100') do not work, so updated all skill checks to roll '1d100' instead to avoid the issue. +- Enhancement - Added support for Dice So Nice module, since moving to custom chat message broke out of the box compatibility with it. + +## Version 0.9.3 + +We will never speak of 0.9.1 or 0.9.2 ever again. + +## Version 0.9.1 + +Added a few compendium packs with some common armor and weapon choices for Agents to equip themselves with. + +Note that weapon/armor statistics are not covered by the Open Game License like the other rules used in the system, they are included as an exception with permission from Arc Dream publishing. + +## Version 0.9.0 + +Basic system functionality complete and submitted to Foundry VTT as an official system. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9eca1cf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,651 @@ +# Contributing + +> 👋 **Need Help**? +> +> This guide is meant to help you get started with contributing to this project. It provides links to many useful resources and you are encouraged to read them. Of course, there will still be questions. +> +> If you have any questions about contributing to this project, or are confused about a step in this guide, please visit [our Discord](https://discord.gg/QRK6a28692) for help. + +## Tooling + +**If you don't already know what a formatter and linter are, read the following guide, the sections "Formatters" and "Linters", especially: [Formatters, linters, and compilers: Oh my!](https://github.com/readme/guides/formatters-linters-compilers)** + +### Formatters + +- JavaScript, JSON, CSS: [Prettier](https://prettier.io/docs/install) +- Handlebars: [DJLint](https://djlint.com/docs/getting-started/) + +### Linters + +- JavaScript: [Eslint](https://eslint.org/docs/latest/use/getting-started) +- Markdown: [Markdownlint](https://github.com/markdownlint/markdownlint) +- Handlebars: DJLint (see above) +- CSS: VSCode Built-in + +### Misc + +- [EditorConfig](https://editorconfig.org/) - Used to standardize file configurations like tabs vs. spaces, end-of-line characters, etc. +- [FVTT CLI](https://github.com/foundryvtt/foundryvtt-cli) - Used to package document JSON files into LevelDB packs, and vice-versa. In simpler terms, this lets us convert documents in compendia into JSON files, OR turn those JSON files back into documents in the compendia. + +### VSCode Extensions + +These extensions will be auto-recommended to install. If you do not use VSCode, there are likely integrations with your code editor. + +- [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) +- [esbenp.prettier-vscode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [monosans.djlint](https://marketplace.visualstudio.com/items?itemName=monosans.djlint) +- [DavidAnson.vscode-markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) +- [EditorConfig.EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) + +## Setting up a Development Environment + +To test or develop for the system, you want a local environment where you can test and make your changes safely. This section will help you get everything set up. + +### 1. Install Git + +If you haven’t already, install [Git](https://git-scm.com/). It allows you to clone the repository and contribute code. + +In a terminal, navigate to the directory where you want to keep the repository. Then, clone the repository: + +- via HTTPS: + `git clone https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system.git` +- via SSH (preferred if you have SSH keys set up): + `git clone git@github.com:deltagreen-foundryvtt/delta-green-foundry-vtt-system.git` + +Then navigate into the cloned folder: + +```bash +cd delta-green-foundry-vtt-system +``` + +### 2. Install Node.js and NPM + +Download and install the [LTS version of Node.js](https://nodejs.org/en/download/), which includes `npm` (Node Package Manager). This is used to install dependencies and run project tooling like linters and formatters. + +Verify installation: + +```bash +node -v +npm -v +``` + +### 3. Install Project Dependencies + +1. Navigate to the project directory and run the following: + + ```bash + npm install + ``` + + This installs all required development packages, such as `prettier`, `eslint`, and the others listed in `package.json`. + +2. Install `djlint` (doesn't come through NPM). This requires `Python` and `pip`; instructions for installing these are specific to your operating system, and beyond the scope of this guide. + +### 4. Set Up Your Code Editor + +We recommend [Visual Studio Code](https://code.visualstudio.com/) for working on this project, but you're welcome to use any editor. The following extensions are **auto-recommended** by VSCode, but here they are again for special instructions, manual installation, or reference. + +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) – Code formatter +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) – JavaScript linter +- [DJLint](https://marketplace.visualstudio.com/items?itemName=monosans.djlint) – Handlebars linter/formatter + + - If you used a Python virtual environment to install DJLint, make sure to set the VSCode extension's setting `djlint.pythonPath` to the path to your virtual environment. For example: + + ```bash + # Windows + C:/Users//.virtualenvs/djlint/bin/python + + # Linux + /home//.virtualenvs/djlint/bin/python + ``` + +- [Markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) – Linter for Markdown +- [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) – Honors `.editorconfig` file rules + +Once these extensions are installed, your editor should automatically highlight formatting or linting issues. + +Your pull request will automatically be checked for linting and formatting via GitHub Actions. If your changes don't pass, they can't be merged (see [Branching and Pull Requests](#branching-commits-and-pull-requests)). + +### 5. Set Up a Local Foundry VTT Test Instance + +1. We **highly** recommend setting up a separate instance of Foundry from your main installation. This way you are not at risk of breaking things in live worlds. + + - There are several ways to do this, but the easiest is to download the NodeJS version of Foundry (make sure to replace `` in the following link): `https://foundryvtt.com/community//licenses` + - Follow the rest of the instructions in [this youtube video](https://youtu.be/B74ZAp3xx3o) to get it up and running (make sure to look at the csomment there by `@Makofueled` because Foundry's folder structure has changed slightly since the video was posted). + +2. [Symlink](https://en.wikipedia.org/wiki/Symbolic_link) the cloned system folder to Foundry’s `Data/systems` directory. + + - This is the folder you chose to store your data in the previous step. + - Otherwise, if you are not using the NodeJS version of Foundry, this directory is likely located at: + + - **Windows**: `%localappdata%/FoundryVTT/Data/systems/` + - **macOS**: `~/Library/Application Support/FoundryVTT/Data/systems/` + - **Linux**: `~/.local/share/FoundryVTT/Data/systems/` + + Symlinking allows developers to choose where to keep our system repos, while also allowing Foundry to see them. + + Example: + + ```bash + # Mac/Linux + ln -s /path/to/your/cloned/delta-green-foundry-vtt-system /path/to/FoundryVTT/Data/systems/deltagreen + ``` + + ```bash + # Windows (Command Prompt, requires admin privileges) + mklink /D "%localappdata%/FoundryVTT/Data/systems/deltagreen" "%cd%/delta-green-foundry-vtt-system" + ``` + +### 6. Start Developing + +- Use the developer console (`F12` in most browsers) to inspect logs and debug issues. +- Make changes to code and refresh the browser to see them take effect. + +## Branching, Commits, and Pull Requests + +### Git Branching Strategy + +Our branching strategy is related to our release process. To make a release, we also have to create a **_Tag_**, which is just a **named reference to a specific commit**. Whenever we feel that we are ready for release (either on `master`, or a `hotfix` branch), we make a release in Github, which will create a tag off of the latest commit on the appropriate branch. Although we mostly talk about "making a release" it is important to understand git tags, because a release is always associated with a tag (and they are typically created at the same time). + +#### Quick Summary + +- `master` is the main development branch. +- **Major and minor releases** are tagged directly from `master`. +- **Patch releases** are created from a `hotfix/vX.Y.Z` branch. +- Hotfix branches are created from the **most recent release tag**, not from `master`. +- After the patch release is tagged, the hotfix branch must be **merged back into `master`**. + +--- + +### Branch Roles + +#### `master` + +`master` is the primary development branch. It is where _most_ Pull Requests get merged to. + +Responsibilities: + +- Ongoing development +- Feature work +- Non-urgent bug fixes +- Source of **major and minor releases** + +All major/minor releases are tagged directly from this branch. + +--- + +#### `hotfix/vX.Y.Z` + +Hotfix branches are used **only for patch releases**. + +Naming convention: + +```sh +hotfix/v.. +``` + +Example: + +```sh +hotfix/v1.6.1 +``` + +Responsibilities: + +- Created from the **most recent release tag** +- Contains only targeted bug fixes +- Used to produce a patch release tag +- Merged back into `master` after release + +--- + +### Minor and Major Release Workflow + +This is the **_typical_** workflow when _not_ targeting a hotfix release. + +1. Create a feature branch from `master` (see [Branch Naming](#branch-naming)). +2. Apply feature work via Pull Requests to the `master` branch. +3. Merge the feature branch into `master`. +4. Repeat Steps 1-3 until ready for the release. +5. Create a release in Github, which includes making a Tag named `vX.Y.Z` (where `X` or `Y` is the number that should increment, and all following numbers turn back to `0`, i.e. `X.0.0` or `X.Y.0`). + +```mermaid +--- +config: + gitGraph: + mainBranchName: master +--- +gitGraph + commit id: "Commit A" + commit id: "Commit B" tag: "v1.6.0" + + branch a-feature-branch + + checkout a-feature-branch + commit id: "Commit C" + commit id: "Commit D" + + checkout master + merge a-feature-branch id: "Merge Commit 1" + commit id: "Update Changelog" tag: "v1.7.0" + + branch another-feature-branch + checkout another-feature-branch + commit id: "Commit E" + commit id: "Commit F" + + checkout master + merge another-feature-branch id: "Merge Commit 2" + commit id: "Update Changelog Again" tag: "v2.0.0" +``` + +### Patch Release Workflow + +When a production bug requires a patch release: + +1. Create a hotfix branch from the most recent release tag (see [Hotfix Branch Naming](#hotfix-branches)). +2. Apply the necessary bug fixes via Pull Requests to the hotfix branch. +3. Repeat Steps 1-2 until the hotfix branch is ready for release. +4. Create a release in Github, which includes making a Tag named `vX.Y.Z` (`Z` is the number that should increment, and all other numbers remain the same). +5. Merge the hotfix branch back into `master`. + +```mermaid +--- +config: + gitGraph: + mainBranchName: master +--- +gitGraph + commit id: "Feature A" + commit id: "Feature B" tag: "v1.6.0" + + branch hotfix/v1.6.1 + checkout hotfix/v1.6.1 + + branch fix-critical-bug + checkout fix-critical-bug + + commit id: "Fix bug" + + checkout hotfix/v1.6.1 + merge fix-critical-bug id: "Merge into Hotfix" tag: "v1.6.1" + + checkout master + + commit id: "Feature C" + + merge hotfix/v1.6.1 id: "Merge into Master" + + commit id: "Feature D" + commit id: "Feature E" tag: "v1.7.0" +``` + +#### Patch release example workflow + +Let's pretend the current release is `v1.6.0` and it has a bug. Our next release will be the hotfix `v1.6.1`. + +##### 1. Creating a hotfix branch + +```sh +# Start from the last release +git switch --detached v1.6.0 + +# Create hotfix branch +git switch --create hotfix/v1.6.1 +``` + +##### 2. Applying a bug fix to a new branch + +```sh +# Create a new branch from the hotfix branch +git switch --create fix-critical-bug + +# Apply fixes, push, and open a PR +git commit -am "Fix critical bug" && git push +``` + +##### 3. Creating a release + +> Note: This step is usually performed by a maintainer or a long-time dev. Feel free to ask a maintainer to do this step, or for help. + +Once all PRs to the hotfix branch are merged, and the branch is ready to go: + +1. In Github, navigate to the Releases page. +2. Create a new Release. +3. Title the Release with the version number, (e.g. `v1.6.1`, to use our example from above). +4. Create a tag of the same name (a required step during Release creation). +5. Include _this_ Release's changelog in the description. See past releases for examples. +6. Publish the Release. +7. Wait for the automatic Github Actions to finish. The Release will be prepared programmatically. +8. Finally, we need to update Foundry's Package Page. Currently, only @TheLastScrub can do this, so contact him or ask someone to contact him. + +##### 4. Merging the hotfix branch back into master + +1. In Github, open a pull request from the hotfix branch to master (e.g. from `hotfix/v1.6.1` to `master`). +2. Resolve any conflicts. There will almost certainly be conflicts, at the very least, in `CHANGELOG.md`. +3. Ask another dev to double-check your work and have them merge the Pull Request. + +This workflow ensures that patch releases remain **minimal and stable**, while ensuring all fixes are preserved in future development on `master`. + +### Putting It All Together + +This graph puts it all together, combining the major/minor and patch release workflows. Admittedly, this graph is kind of a doozy. I strongly encourage you to look at the simpler graphs above before trying to make sense of this one. Ultimately, it's not _that_ important that you understand this graph; it's more important that you read the rest of the document :). + +```mermaid +--- +config: + gitGraph: + mainBranchName: master +--- +gitGraph + commit id: "Commit A" tag: "v1.5.0" + commit id: "Commit B" + + branch a-feature-branch + + checkout a-feature-branch + commit id: "Commit C" + commit id: "Commit D" + + checkout master + merge a-feature-branch id: "Merge Commit" tag: "v1.6.0" + + branch hotfix/v1.6.1 + checkout hotfix/v1.6.1 + + branch fix-critical-bug + checkout fix-critical-bug + commit id: "Fix bug" + + checkout hotfix/v1.6.1 + merge fix-critical-bug id: "Merge into Hotfix" tag: "v1.6.1" + + branch hotfix/v1.6.2 + + checkout master + commit id: "Commit E" + + checkout hotfix/v1.6.2 + + branch another-critical-bugfix + checkout another-critical-bugfix + commit id: "Fix another bug" + + checkout hotfix/v1.6.2 + merge another-critical-bugfix id: "Merge into hotfix/v1.6.2" tag: "v1.6.2" + + + checkout master + merge hotfix/v1.6.1 id: "Merge Hotfix into Master" + + merge hotfix/v1.6.2 id: "Merge Hotfixx into Master" + + branch another-feature-branch + checkout another-feature-branch + commit id: "Commit F" + commit id: "Commit G" + + checkout master + merge another-feature-branch id: "Merge Commit 2" + commit id: "Update Changelog Again" tag: "v1.7.0" +``` + +### Branch Naming + +Work should always happen on a new branch, i.e., not `master`. + +Branch names should conform to the following format: + +`author-identifier/issue-number/short-description` + +The `author-identifier` could be your username, or your first name followed by your last initial, just try to keep it short but identifiable. + +Examples: + +- `jalenml/420/fix-sanity-rolls` +- `snake-eater/69/add-token-config` +- `tiff123/101/lint-pass` + +If there's no GitHub issue yet, you can omit the number: +`author-identifier/short-description` is acceptable. However, it is usually best to make a GitHub issue first to track its progress and leave it open for comment. + +#### Hotfix Branches + +If you are the one creating a Hotfix branch, it should be named like so: `hotfix/v..`. Any branches that open PRs _to_ the hotfix branch should follow the naming conventions above. + +### Commit Messages + +- Please try to follow [the Seven Rules of a Great Commit Messages](https://gist.github.com/julienbourdeau/e605e4b8b47da97c249a0f72598529c8) as much as possible. +- Slight deviations from the above are okay, but this is what we should be going for. + +### Keeping Your Branch Up-To-Date + +We prefer a **rebase** workflow to keep history clean and avoid merge commits. If changes have been made to `master` while you've been working: + +```bash +git checkout your-branch-name +git fetch origin +git rebase origin/master +``` + +If you’re new to rebasing, GitLab has a solid primer: +[About Git rebase](https://docs.gitlab.com/topics/git/git_rebase/) + +If you run into conflicts, Git will guide you through resolving them. After a successful rebase, you'll need to force-push: + +```bash + git push --force-with-lease +``` + +```text +⚠️ Never force-push to a shared branch without coordinating with the other contributor(s) to that branch. +``` + +### Before Opening a Pull Request + +Make sure your code is clean and ready: + +- ✅ You’ve manually tested your change in a local Foundry world. +- ✅ `npm run lint` shows no errors +- ✅ `npm run format:check` passes +- ✅ Your editor doesn’t show linting/formatting warnings. + +We use a GitHub Action to enforce code quality. If your code doesn’t meet the linting and formatting standards, your PR cannot be merged until those checks pass. + +Screenshots or gifs are **highly encouraged** for visual/UI changes! + +## Testing + +### Testing environment + +- If you have set up a development environment as described above, `git checkout` the `master` branch or a specific feature/bugfix branch and start testing. +- If you do not want (or don't feel technologically adept enough) to create a full development environment as described above, you can download the most recent build via the following manifest link: + +### How to test + +It is difficult to create a one-size-fits-all procedure for testing, because each issue or feature has its own requirements. However, the steps below attempt to provide a baseline you can follow for most changes. If a PR includes specific test instructions, follow those and then complete the general checks here. + +1. Prepare your environment + + - Test in a safe environment (**HIGHLY RECOMMENDED**): + - We highly recommend [setting up an installation of Foundry separate from your main instance](#5-set-up-a-local-foundry-vtt-test-instance). + - This way, you are never at risk of breaking anything in your main worlds. + - If you do not follow the above advice, be aware that opening your main world while you have an in-progress (non-release) version of the system installed **will almost certainly break things in a way that cannot be fixed**. To go back to the release version of the system, uninstall the test build, and reinstall from the in-Foundry system browser. + - Update to the target build: + - Development setup: `git checkout` the target branch (or `master` for merged work), then restart Foundry. + - No dev setup: Install or update the system from the dev manifest: + - **Note**: Testing a **hotfix** branch? Use the hotfix manifest instead: + - Use a clean test world: + - Create a fresh world + - Note, this is a good practice, but is not always strictly necessary. If you run into anything weird, a completely fresh world is always a good rule-out test. + - Disable third‑party modules unless: + - The PR explicitly mentions/involves them. + - They are extremely common, like Dice So Nice. + - Launch the world created above. + - Keep the browser's dev console (F12) open during testing, and note any errors (red text in the console), especially if they arise in response to something you did/tested. Screenshot errors rather than copy/pasting them. + +2. Quick test + + - Ensure there are no red errors on load. + - Create a new Agent (character) and open its sheet. Click through all tabs to ensure they render without errors. + - Create one of each relevant Item type used by the change (e.g., weapon, armor, equipment) and open their sheets. + - Open/close sheets, ensure changes to data persist. + - Refresh the page, ensure changes to data persist. + +3. Functional checks by area + + > You only need to test the subsets below which are relevant to the changes you are testing. When unsure or being particularly thorough, do the full pass. + + - Player (non-GM) Perspective Tests + + - Enable the "Hide Sanity from Players" Setting. + - Make sure Sanity on sheets and in rolls is obscured from players. + - Enable the "Hide Impossible Landscape content" Setting + - Make sure the Impossible Landscapes fields on the character sheet are not visible from a player's perspective. + + - Character basics + + - Create an Agent, fill in stats, skills, and add a couple of custom skills, special trainings, bonds, and pieces of equipment. + - Close, and reopen the sheet; confirm data persists and renders correctly. + + - Rolling and chat cards + + - Roll a few skills (with and without modifiers). Confirm success/failure logic and result styling. + - Perform a Sanity roll. + - Perform a Sanity damage roll (Unnatural sheet). + - Perform a Luck roll. + - Perform an attack roll from a Weapon. + - Perform a regular damage roll from a Weapon. + - Perform a lethality damage roll from a Weapon. + - Test modifying all above rolls (right-click or shift-click) and ensure the final result matches expectations. + + - Weapons and armor + + - Create a Weapon, add it to the Agent, and roll an attack; verify the damage roll and chat output. + - Equip armor; confirm that armor stat is calculated and displayed correctly (next to HP). + + - Items and drag/drop + + - Drag items from a compendium and sidebar into the Actor. Ensure sheets open and data is valid. + - Delete and re-add items to confirm no orphaned data or console errors. + + - Compendia integrity + + - Open compendia (e.g., pregens, equipment) and scan for missing images, broken icons, or malformed data. + - Drag entries into a world and open them; verify sheets render as expected. + - If you are actively editing packs, see “[Working with Compendia](#working-with-compendia)” below for FVTT CLI export/extract workflow. + + - System settings + + - Toggle/change each relevant setting to verify it works as expected. + - Confirm the setting takes effect immediately or after reload, as intended. + + - Localization + + - Switch Foundry’s language to a non-English language, refresh, and re-run a quick UI pass. + - Confirm no literal keys like “DG.Skills.\*” appear in UI or chat cards, and strings fall back to English where not translated. + + - Layout and styling + + - Look for inconsistent, inaccessible, or just plain ugly visual elements in styling that the system controls. + - Confirm icons load and are visually consistent. + - Toggle between Foundry's light and dark modes and check for visual inconsistencies. + - Change the base font size in Foundry's settings and verify sheets look good enough at various font sizes. + + - Everything else + - The above are guidelines, but are by no means exhaustive. + - Go through your regular workflow when actually using the system as a player or GM. Bring your particular perspective. + - Feel free to also get creative when testing, going beyond what one might expect and noting what you find. + +4. Cross-browser sanity (optional but helpful) + + - If possible, quickly verify in one Chromium-based browser (Chrome/Edge) and Firefox. + - Report any browser-specific issues you encounter. + +5. Record your results in a comment on the relevant PR or Issue. You may use the template below directly or as a guide. + + ```text + Foundry Version: | DG System Version: + Browser/OS: + + Scope tested: + - [ ] Character basics + - [ ] Rolling & chat cards + - [ ] Sanity mechanics + - [ ] Weapons & armor + - [ ] Items & drag/drop + - [ ] Compendia + - [ ] System settings + - [ ] Localization + - [ ] Layout & styling + - [ ] Cross-browser + + Notes: + - Steps: + - Expected: + - Actual: + - Console logs (if any): + - Screenshots (if UI-related): + + Result: Pass / Fail (with summary) + ``` + +## Working with Compendia + +1. Tell the FVTT CLI that we are working on our delta green package: `fvtt package workon fvtt package workon "deltagreen" --type "System"` +2. To **export** JSON files to a compendium pack: `fvtt package pack "armor" --in "packs/source/armor" --out "packs"` +3. To **extract** a compendium pack to JSON files: `fvtt package pack "armor" --in "packs" --out "packs/source/armor"` +4. Replace `armor` with the name of the compendium pack you are working on. +5. This allows you to make changes to either the JSON files themselves, OR to the in-game compendium packs, whichever makes most sense for the task. It also allows the developers to not have to commit binary LevelDB data to our repo, which is not adviced. + +## Localization + +We use [Foundry VTT’s built-in localization system](https://foundryvtt.com/article/localization/) to support multiple languages. + +### Best Practices + +- See this [Foundry VTT Community Wiki article](https://foundryvtt.wiki/en/development/guides/localization/localization-best-practices). + +### Where to Add Translations + +Localization files live in `lang/` as JSON files. **The `en.json` file is the source of truth.** If you are adding new strings, they must first appear in `en.json`. + +To translate, add the matching keys to the appropriate language file (e.g., `fr.json`, `de.json`) with the translated value. + +### How to Reference Localized Strings + +Do **not** hardcode text directly into HTML or JavaScript. Instead, use localization keys like so: + +- **Handlebars**: + + ```handlebars + {{localize "DG.Skills.accounting"}} + + {{localize "DG.FallbackText.newItem" type="TYPES.Item.weapon"}} + ``` + +- **JavaScript**: + + ```js + game.i18n.localize("DG.Skills.accounting"); + // Or for string interpolation: + game.i18n.format("DG.FallbackText.newItem", { + type: "TYPES.Item.weapon", + }); + ``` + +If you're unsure whether a string should be localized, it probably should be. + +## Bug Reports and Feature Requests + +If you're reporting a bug or requesting a feature: + +- Navigate to our [Issues](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues). +- Check that a similar issue has not already been opened. If one has, feel free to add an emoji to indicate that you would like it to be prioritized **OR** leave a comment **_only if_** you have context to add. +- [Choose an appropriate template](https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/issues/new/choose) and be sure to fill it out. You may delete parts/sections which do not apply. +- Be descriptive. Include screenshots, steps to reproduce, Foundry version, system version, and browser if applicable. + +--- + +**Disclaimer:** +This contribution guide was made with the partial help of ChatGPT, which assisted in the phrasing and formatting of some lines. This disclaimer is made in good faith and in the interest of being transparent about the usage of AI. diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 0000000..8aa58b6 --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,116 @@ +# Attributions, Other Licenses, and Shoutouts + +## System Template + +This system was built upon on Matt Smith's (AKA Asacolips) excellent Boilerplate System and corresponding tutorial. + + +## Delta Green Agent Pregen List + +Comes from a character generator created by jimstorch, who graciously posted the results on Reddit for all to use. See the GitHub page for more information: + +## Operation Code Name Generator + +The roll tables added to generate operation code names comes from Reddit user /u/Travern. + +## Localization + +- Portugese (BR) Translation submitted by [IgorAK25](https://github.com/IgorAK25) +- Spanish Translation submitted by [CthulhuRol](https://github.com/CthulhuRol) +- Catalonian Translation submitted by [trombonecot](https://github.com/trombonecot) +- French Translation submitted by [Hrunh](https://github.com/Hrunh) +- Japanese Translation submitted by [ryotai-trpg](https://github.com/ryotai-trpg) +- Polish Translation submitted by [delgar89](https://github.com/delgar89) + +## Fonts (Some in use, others that I would like to use at some point) + +### MARTEL FONT + +By Dan Reynolds (Principal Designer) + + +License: Open Font License. + + +### SPECIAL ELITE FONT + +By Astigmatic (Principal Design) + + +License: Apache License, Version 2.0 + + +### DIDACT GOTHIC FONT + +By Daniel Johnson and Cyreal + + +License: Open Font License. + + +### TYPEWRITER CONDENSED FONT + +By Volker Busse - F25 Digital Typeface Design +License: None given + + +### ANOTHER TYPEWRITER FONT + +By Johan Holmdahl +License: None given + + +### PUBLIC SANS FONT + +Designed by USWDS, Dan Williams, Pablo Impallari, Rodrigo Fuenzalida +License: Open Font License. + + +## Game Icons + +ICONS - + + +- Sawed-off shotgun icon by Delapouite under CC BY 3.0 +- Crosshair icon by Delapouite under CC BY 3.0 +- Two handed sword icon by Delapouite under CC BY 3.0 +- Katana icon by Delapouite under CC BY 3.0 +- Baseball bat icon by Delapouite under CC BY 3.0 +- Hatchet icon by Delapouite under CC BY 3.0 +- Wood axe icon by Delapouite under CC BY 3.0 +- Brass knuckles icon by Delapouite under CC BY 3.0 +- Flashlight icon by Delapouite under CC BY 3.0 +- Wire icon by Delapouite under CC BY 3.0 +- Gun stock icon by Delapouite under CC BY 3.0 +- AK47 icon by Skoll under CC BY 3.0 +- Switchblade icon by Skoll under CC BY 3.0 +- Desert Eagle iconby Skoll under CC BY 3.0 +- Colt M1911 icon by Skoll under CC BY 3.0 +- Revolver icon by Skoll under CC BY 3.0 +- Lee Enfield icon by Skoll under CC BY 3.0 +- FN FAL icon by Skoll under CC BY 3.0 +- Walther PPK icon by Skoll under CC BY 3.0 +- Kevlar vest icon by Skoll under CC BY 3.0 +- Spectre M4 icon by Skoll under CC BY 3.0 +- FN Fal icon by Skoll under CC BY 3.0 +- Telescopic baton icon by Skoll under CC BY 3.0 +- Baton icon by Skoll under CC BY 3.0 +- Bayonet icon by Skoll under CC BY 3.0 +- Jaws icon by Skoll under CC BY 3.0 +- Helmet icon by sbed under CC BY 3.0 +- Kevlar icon by sbed under CC BY 3.0 +- Bowie knife icon by Lorc under CC BY 3.0 +- Space suit icon by Lorc under CC BY 3.0 +- Grenade icon by Lorc under CC BY 3.0 +- Stiletto icon by Lorc under CC BY 3.0 +- Punch icon by Lorc under CC BY 3.0. +- Arrowhead icon by Lorc under CC BY 3.0 +- Claw Slashes icon by Lorc under CC BY 3.0 +- Magic Hand icon by Lorc under CC BY 3.0 +- Magic Shield icon by Lorc under CC BY 3.0 +- Sly icon by Lorc under CC BY 3.0 +- Swap Bag icon by Lorc under CC BY 3.0 +- Person icon by Delapouite under CC BY 3.0 +- Cowled icon by Lorc under CC BY 3.0 + +- Various more from Delapouite, John Colburn, Lorc, Pierre, Leducq, Sbed, and Skull. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..f2802cf --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 TheLastScrub (https://github.com/TheLastScrub) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..60ee88e --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# _Delta Green: The Role-Playing Game_ System for Foundry VTT + +Officially supported rules implementation for [Delta Green: The Role-Playing Game](https://www.deltagreen.com), based on the _Agent's Handbook_ rule set from Arc Dream Publishing, for [Foundry Virtual Tabletop](https://foundryvtt.com/). + +> ## Disclaimers +> +> ### Delta Green Community License +> +> Published by Arc Dream Publishing by arrangement with the Delta Green Partnership. The intellectual property known as Delta Green is a trademark and copyright owned by the Delta Green Parternship, who has licensed its use here. +> +> The contents of this system are licensed under the terms of the included [license](LICENSE.txt) file, excepting those elements that are components of the Delta Green intellectual property. +> +> **Please support Arc Dream by purchasing one of their publications:** +> +> - [All publications](https://www.delta-green.com/publications/) +> - [Agent's Handbook (Hardback)](https://shop.arcdream.com/collections/role-playing-games/products/delta-green-agents-handbook) +> - [Agent's Handbook (PDF)](https://www.drivethrurpg.com/product/181674/Delta-Green-Agents-Handbook) +> - [Agent's Handbook (with _The Complex_) **for Foundry VTT**](https://www.drivethrurpg.com/product/181674/Delta-Green-Agents-Handbook) +> +> --- +> +> ### Foundry VTT License +> +> This code uses the Foundry VTT and its API under the terms of the Limited License Agreement for Module Development. +> +> Foundry VTT is a Copyright of Foundry Gaming, LLC. + +## Installation Guide + +The system is included in the list of official Foundry VTT game systems, and as such can be installed directly from within Foundry. + +If there is a need to manually install the system, go to _Game Systems_ and click _Install System_. Then in the _Manifest URL_ input field, paste the following link. Finally, click _Install_: + + + +## System Documentation + +You may find documentation for the system in [this folder](https://github.com/TheLastScrub/delta-green-foundry-vtt-system/blob/master/documentation/home.md). diff --git a/assets/font/another-typewriter/Don't read this.txt b/assets/font/another-typewriter/Don't read this.txt new file mode 100644 index 0000000..9446007 --- /dev/null +++ b/assets/font/another-typewriter/Don't read this.txt @@ -0,0 +1,2 @@ +Another Typewriter. +Freeware by Johan Holmdahl 1999. \ No newline at end of file diff --git a/assets/font/another-typewriter/atwriter.ttf b/assets/font/another-typewriter/atwriter.ttf new file mode 100644 index 0000000..41f9c33 Binary files /dev/null and b/assets/font/another-typewriter/atwriter.ttf differ diff --git a/assets/font/public-sans/OFL.txt b/assets/font/public-sans/OFL.txt new file mode 100644 index 0000000..8ec2295 --- /dev/null +++ b/assets/font/public-sans/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2015 The Public Sans Project Authors (https://github.com/uswds/public-sans) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/assets/font/public-sans/PublicSans-Italic-VariableFont_wght.ttf b/assets/font/public-sans/PublicSans-Italic-VariableFont_wght.ttf new file mode 100644 index 0000000..3727ffe Binary files /dev/null and b/assets/font/public-sans/PublicSans-Italic-VariableFont_wght.ttf differ diff --git a/assets/font/public-sans/PublicSans-VariableFont_wght.ttf b/assets/font/public-sans/PublicSans-VariableFont_wght.ttf new file mode 100644 index 0000000..cc76414 Binary files /dev/null and b/assets/font/public-sans/PublicSans-VariableFont_wght.ttf differ diff --git a/assets/font/public-sans/README.txt b/assets/font/public-sans/README.txt new file mode 100644 index 0000000..c02e0c1 --- /dev/null +++ b/assets/font/public-sans/README.txt @@ -0,0 +1,81 @@ +Public Sans Variable Font +========================= + +This download contains Public Sans as both variable fonts and static fonts. + +Public Sans is a variable font with this axis: + wght + +This means all the styles are contained in these files: + PublicSans-VariableFont_wght.ttf + PublicSans-Italic-VariableFont_wght.ttf + +If your app fully supports variable fonts, you can now pick intermediate styles +that aren’t available as static fonts. Not all apps support variable fonts, and +in those cases you can use the static font files for Public Sans: + static/PublicSans-Thin.ttf + static/PublicSans-ExtraLight.ttf + static/PublicSans-Light.ttf + static/PublicSans-Regular.ttf + static/PublicSans-Medium.ttf + static/PublicSans-SemiBold.ttf + static/PublicSans-Bold.ttf + static/PublicSans-ExtraBold.ttf + static/PublicSans-Black.ttf + static/PublicSans-ThinItalic.ttf + static/PublicSans-ExtraLightItalic.ttf + static/PublicSans-LightItalic.ttf + static/PublicSans-Italic.ttf + static/PublicSans-MediumItalic.ttf + static/PublicSans-SemiBoldItalic.ttf + static/PublicSans-BoldItalic.ttf + static/PublicSans-ExtraBoldItalic.ttf + static/PublicSans-BlackItalic.ttf + +Get started +----------- + +1. Install the font files you want to use + +2. Use your app's font picker to view the font family and all the +available styles + +Learn more about variable fonts +------------------------------- + + https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts + https://variablefonts.typenetwork.com + https://medium.com/variable-fonts + +In desktop apps + + https://theblog.adobe.com/can-variable-fonts-illustrator-cc + https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts + +Online + + https://developers.google.com/fonts/docs/getting_started + https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide + https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts + +Installing fonts + + MacOS: https://support.apple.com/en-us/HT201749 + Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux + Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows + +Android Apps + + https://developers.google.com/fonts/docs/android + https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts + +License +------- +Please read the full license text (OFL.txt) to understand the permissions, +restrictions and requirements for usage, redistribution, and modification. + +You can use them in your products & projects – print or digital, +commercial or otherwise. + +This isn't legal advice, please consider consulting a lawyer and see the full +license for all details. diff --git a/assets/font/public-sans/static/PublicSans-Black.ttf b/assets/font/public-sans/static/PublicSans-Black.ttf new file mode 100644 index 0000000..8c9e8ec Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Black.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-BlackItalic.ttf b/assets/font/public-sans/static/PublicSans-BlackItalic.ttf new file mode 100644 index 0000000..98cde4b Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-BlackItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Bold.ttf b/assets/font/public-sans/static/PublicSans-Bold.ttf new file mode 100644 index 0000000..7a14109 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Bold.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-BoldItalic.ttf b/assets/font/public-sans/static/PublicSans-BoldItalic.ttf new file mode 100644 index 0000000..505553b Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-BoldItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-ExtraBold.ttf b/assets/font/public-sans/static/PublicSans-ExtraBold.ttf new file mode 100644 index 0000000..148fee4 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-ExtraBold.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-ExtraBoldItalic.ttf b/assets/font/public-sans/static/PublicSans-ExtraBoldItalic.ttf new file mode 100644 index 0000000..433e2b8 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-ExtraBoldItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-ExtraLight.ttf b/assets/font/public-sans/static/PublicSans-ExtraLight.ttf new file mode 100644 index 0000000..ccad63c Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-ExtraLight.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-ExtraLightItalic.ttf b/assets/font/public-sans/static/PublicSans-ExtraLightItalic.ttf new file mode 100644 index 0000000..8c573f5 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-ExtraLightItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Italic.ttf b/assets/font/public-sans/static/PublicSans-Italic.ttf new file mode 100644 index 0000000..7315d65 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Italic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Light.ttf b/assets/font/public-sans/static/PublicSans-Light.ttf new file mode 100644 index 0000000..286bb3a Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Light.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-LightItalic.ttf b/assets/font/public-sans/static/PublicSans-LightItalic.ttf new file mode 100644 index 0000000..d2c621a Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-LightItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Medium.ttf b/assets/font/public-sans/static/PublicSans-Medium.ttf new file mode 100644 index 0000000..1421f42 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Medium.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-MediumItalic.ttf b/assets/font/public-sans/static/PublicSans-MediumItalic.ttf new file mode 100644 index 0000000..1144923 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-MediumItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Regular.ttf b/assets/font/public-sans/static/PublicSans-Regular.ttf new file mode 100644 index 0000000..7f55dba Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Regular.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-SemiBold.ttf b/assets/font/public-sans/static/PublicSans-SemiBold.ttf new file mode 100644 index 0000000..c7a1944 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-SemiBold.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-SemiBoldItalic.ttf b/assets/font/public-sans/static/PublicSans-SemiBoldItalic.ttf new file mode 100644 index 0000000..49780a6 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-SemiBoldItalic.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-Thin.ttf b/assets/font/public-sans/static/PublicSans-Thin.ttf new file mode 100644 index 0000000..3d45ec8 Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-Thin.ttf differ diff --git a/assets/font/public-sans/static/PublicSans-ThinItalic.ttf b/assets/font/public-sans/static/PublicSans-ThinItalic.ttf new file mode 100644 index 0000000..293ad1d Binary files /dev/null and b/assets/font/public-sans/static/PublicSans-ThinItalic.ttf differ diff --git a/assets/font/special_elite/LICENSE.txt b/assets/font/special_elite/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/assets/font/special_elite/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/assets/font/special_elite/SpecialElite-Regular.ttf b/assets/font/special_elite/SpecialElite-Regular.ttf new file mode 100644 index 0000000..a645a5e Binary files /dev/null and b/assets/font/special_elite/SpecialElite-Regular.ttf differ diff --git a/assets/font/typewriter-condensed/typewcond_bold.otf b/assets/font/typewriter-condensed/typewcond_bold.otf new file mode 100644 index 0000000..b4afb34 Binary files /dev/null and b/assets/font/typewriter-condensed/typewcond_bold.otf differ diff --git a/assets/font/typewriter-condensed/typewcond_demi.otf b/assets/font/typewriter-condensed/typewcond_demi.otf new file mode 100644 index 0000000..af39b61 Binary files /dev/null and b/assets/font/typewriter-condensed/typewcond_demi.otf differ diff --git a/assets/font/typewriter-condensed/typewcond_regular.otf b/assets/font/typewriter-condensed/typewcond_regular.otf new file mode 100644 index 0000000..b7b6f55 Binary files /dev/null and b/assets/font/typewriter-condensed/typewcond_regular.otf differ diff --git a/assets/icons/3d-printer.svg b/assets/icons/3d-printer.svg new file mode 100644 index 0000000..c6ab5aa --- /dev/null +++ b/assets/icons/3d-printer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/acid.svg b/assets/icons/acid.svg new file mode 100644 index 0000000..d4fbe8c --- /dev/null +++ b/assets/icons/acid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/acog.svg b/assets/icons/acog.svg new file mode 100644 index 0000000..2b61265 --- /dev/null +++ b/assets/icons/acog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/ak47.svg b/assets/icons/ak47.svg new file mode 100644 index 0000000..95997f0 --- /dev/null +++ b/assets/icons/ak47.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/anfo.svg b/assets/icons/anfo.svg new file mode 100644 index 0000000..79342cc --- /dev/null +++ b/assets/icons/anfo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/arrowhead.svg b/assets/icons/arrowhead.svg new file mode 100644 index 0000000..613acc6 --- /dev/null +++ b/assets/icons/arrowhead.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/artillery.svg b/assets/icons/artillery.svg new file mode 100644 index 0000000..c05b65d --- /dev/null +++ b/assets/icons/artillery.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/autocannon.svg b/assets/icons/autocannon.svg new file mode 100644 index 0000000..2480a3b --- /dev/null +++ b/assets/icons/autocannon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/baseball-bat.svg b/assets/icons/baseball-bat.svg new file mode 100644 index 0000000..dd820fe --- /dev/null +++ b/assets/icons/baseball-bat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/baton.svg b/assets/icons/baton.svg new file mode 100644 index 0000000..f142d08 --- /dev/null +++ b/assets/icons/baton.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bayonet.svg b/assets/icons/bayonet.svg new file mode 100644 index 0000000..bf4b9ef --- /dev/null +++ b/assets/icons/bayonet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/binoculars.svg b/assets/icons/binoculars.svg new file mode 100644 index 0000000..35550c6 --- /dev/null +++ b/assets/icons/binoculars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bomb-suit.svg b/assets/icons/bomb-suit.svg new file mode 100644 index 0000000..694bcb5 --- /dev/null +++ b/assets/icons/bomb-suit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/book-cover.svg b/assets/icons/book-cover.svg new file mode 100644 index 0000000..2c168af --- /dev/null +++ b/assets/icons/book-cover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/book-pile.svg b/assets/icons/book-pile.svg new file mode 100644 index 0000000..2beecb2 --- /dev/null +++ b/assets/icons/book-pile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bookmarklet.svg b/assets/icons/bookmarklet.svg new file mode 100644 index 0000000..9265773 --- /dev/null +++ b/assets/icons/bookmarklet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bowie-knife.svg b/assets/icons/bowie-knife.svg new file mode 100644 index 0000000..f5b9ce1 --- /dev/null +++ b/assets/icons/bowie-knife.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/brass-knuckles.svg b/assets/icons/brass-knuckles.svg new file mode 100644 index 0000000..df97197 --- /dev/null +++ b/assets/icons/brass-knuckles.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bug-detector.svg b/assets/icons/bug-detector.svg new file mode 100644 index 0000000..a15c4ef --- /dev/null +++ b/assets/icons/bug-detector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/bullet-impacts.svg b/assets/icons/bullet-impacts.svg new file mode 100644 index 0000000..f7b511b --- /dev/null +++ b/assets/icons/bullet-impacts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/c4.svg b/assets/icons/c4.svg new file mode 100644 index 0000000..17de038 --- /dev/null +++ b/assets/icons/c4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/camping-gear.svg b/assets/icons/camping-gear.svg new file mode 100644 index 0000000..8003fcd --- /dev/null +++ b/assets/icons/camping-gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/claw-slashes.svg b/assets/icons/claw-slashes.svg new file mode 100644 index 0000000..5ef6ca9 --- /dev/null +++ b/assets/icons/claw-slashes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/colt-m1911.svg b/assets/icons/colt-m1911.svg new file mode 100644 index 0000000..a8a4c1f --- /dev/null +++ b/assets/icons/colt-m1911.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/combat-knife.svg b/assets/icons/combat-knife.svg new file mode 100644 index 0000000..d2dc36a --- /dev/null +++ b/assets/icons/combat-knife.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/computer.svg b/assets/icons/computer.svg new file mode 100644 index 0000000..931be86 --- /dev/null +++ b/assets/icons/computer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/cowled.svg b/assets/icons/cowled.svg new file mode 100644 index 0000000..2e89550 --- /dev/null +++ b/assets/icons/cowled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/crosshair.svg b/assets/icons/crosshair.svg new file mode 100644 index 0000000..5d472fa --- /dev/null +++ b/assets/icons/crosshair.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/cruise-missile.svg b/assets/icons/cruise-missile.svg new file mode 100644 index 0000000..83ed7c8 --- /dev/null +++ b/assets/icons/cruise-missile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/desert-eagle.svg b/assets/icons/desert-eagle.svg new file mode 100644 index 0000000..7aa7a43 --- /dev/null +++ b/assets/icons/desert-eagle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/drone.svg b/assets/icons/drone.svg new file mode 100644 index 0000000..d762ae7 --- /dev/null +++ b/assets/icons/drone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/electroshock.svg b/assets/icons/electroshock.svg new file mode 100644 index 0000000..076abea --- /dev/null +++ b/assets/icons/electroshock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/envelope.svg b/assets/icons/envelope.svg new file mode 100644 index 0000000..44b2679 --- /dev/null +++ b/assets/icons/envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/fangs.svg b/assets/icons/fangs.svg new file mode 100644 index 0000000..0ad3250 --- /dev/null +++ b/assets/icons/fangs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/fire-extinguisher.svg b/assets/icons/fire-extinguisher.svg new file mode 100644 index 0000000..1013c50 --- /dev/null +++ b/assets/icons/fire-extinguisher.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/first-aid-kit.svg b/assets/icons/first-aid-kit.svg new file mode 100644 index 0000000..fbac239 --- /dev/null +++ b/assets/icons/first-aid-kit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/flamethrower.svg b/assets/icons/flamethrower.svg new file mode 100644 index 0000000..021fdd3 --- /dev/null +++ b/assets/icons/flamethrower.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/flash-bang-grenade.svg b/assets/icons/flash-bang-grenade.svg new file mode 100644 index 0000000..b08b4b8 --- /dev/null +++ b/assets/icons/flash-bang-grenade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/flashlight.svg b/assets/icons/flashlight.svg new file mode 100644 index 0000000..f271431 --- /dev/null +++ b/assets/icons/flashlight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/flexible-cuffs.svg b/assets/icons/flexible-cuffs.svg new file mode 100644 index 0000000..812d718 --- /dev/null +++ b/assets/icons/flexible-cuffs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/fn-fal.svg b/assets/icons/fn-fal.svg new file mode 100644 index 0000000..02482c1 --- /dev/null +++ b/assets/icons/fn-fal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/forcible-entry-tool.svg b/assets/icons/forcible-entry-tool.svg new file mode 100644 index 0000000..9d27c5c --- /dev/null +++ b/assets/icons/forcible-entry-tool.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/gas-mask.svg b/assets/icons/gas-mask.svg new file mode 100644 index 0000000..b5009f7 --- /dev/null +++ b/assets/icons/gas-mask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/general-purpose-bomb.svg b/assets/icons/general-purpose-bomb.svg new file mode 100644 index 0000000..10d60ac --- /dev/null +++ b/assets/icons/general-purpose-bomb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/glock.svg b/assets/icons/glock.svg new file mode 100644 index 0000000..426f39b --- /dev/null +++ b/assets/icons/glock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/goggles.svg b/assets/icons/goggles.svg new file mode 100644 index 0000000..76d8d55 --- /dev/null +++ b/assets/icons/goggles.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/gps-tracking.svg b/assets/icons/gps-tracking.svg new file mode 100644 index 0000000..a7bf504 --- /dev/null +++ b/assets/icons/gps-tracking.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/grenade.svg b/assets/icons/grenade.svg new file mode 100644 index 0000000..358b666 --- /dev/null +++ b/assets/icons/grenade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/ground-penetrating-radar.svg b/assets/icons/ground-penetrating-radar.svg new file mode 100644 index 0000000..6e55a18 --- /dev/null +++ b/assets/icons/ground-penetrating-radar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/gun-stock.svg b/assets/icons/gun-stock.svg new file mode 100644 index 0000000..ce8a918 --- /dev/null +++ b/assets/icons/gun-stock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/handcuffs.svg b/assets/icons/handcuffs.svg new file mode 100644 index 0000000..162a963 --- /dev/null +++ b/assets/icons/handcuffs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/handheld-gps.svg b/assets/icons/handheld-gps.svg new file mode 100644 index 0000000..1303d2b --- /dev/null +++ b/assets/icons/handheld-gps.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/hatchet.svg b/assets/icons/hatchet.svg new file mode 100644 index 0000000..e964d21 --- /dev/null +++ b/assets/icons/hatchet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/hazmat-suit.svg b/assets/icons/hazmat-suit.svg new file mode 100644 index 0000000..f38456a --- /dev/null +++ b/assets/icons/hazmat-suit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/helmet.svg b/assets/icons/helmet.svg new file mode 100644 index 0000000..06842c3 --- /dev/null +++ b/assets/icons/helmet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/holographic-sight.svg b/assets/icons/holographic-sight.svg new file mode 100644 index 0000000..31c0301 --- /dev/null +++ b/assets/icons/holographic-sight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/ied.svg b/assets/icons/ied.svg new file mode 100644 index 0000000..fda6336 --- /dev/null +++ b/assets/icons/ied.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/imsi-catcher.svg b/assets/icons/imsi-catcher.svg new file mode 100644 index 0000000..48810ec --- /dev/null +++ b/assets/icons/imsi-catcher.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/jammer.svg b/assets/icons/jammer.svg new file mode 100644 index 0000000..060ba23 --- /dev/null +++ b/assets/icons/jammer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/jawbone.svg b/assets/icons/jawbone.svg new file mode 100644 index 0000000..c30f73c --- /dev/null +++ b/assets/icons/jawbone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/katana.svg b/assets/icons/katana.svg new file mode 100644 index 0000000..d3586d1 --- /dev/null +++ b/assets/icons/katana.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/kevlar-vest.svg b/assets/icons/kevlar-vest.svg new file mode 100644 index 0000000..a60e37f --- /dev/null +++ b/assets/icons/kevlar-vest.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/kevlar.svg b/assets/icons/kevlar.svg new file mode 100644 index 0000000..182b10e --- /dev/null +++ b/assets/icons/kevlar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/knife.svg b/assets/icons/knife.svg new file mode 100644 index 0000000..bc8fa0d --- /dev/null +++ b/assets/icons/knife.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/laser.svg b/assets/icons/laser.svg new file mode 100644 index 0000000..fbc3012 --- /dev/null +++ b/assets/icons/laser.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/lee-enfield.svg b/assets/icons/lee-enfield.svg new file mode 100644 index 0000000..6db3cad --- /dev/null +++ b/assets/icons/lee-enfield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/lockpick-gun.svg b/assets/icons/lockpick-gun.svg new file mode 100644 index 0000000..1494968 --- /dev/null +++ b/assets/icons/lockpick-gun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/lockpick-kit.svg b/assets/icons/lockpick-kit.svg new file mode 100644 index 0000000..55968cb --- /dev/null +++ b/assets/icons/lockpick-kit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/long-sword.svg b/assets/icons/long-sword.svg new file mode 100644 index 0000000..7aa97b7 --- /dev/null +++ b/assets/icons/long-sword.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/machine-gun.svg b/assets/icons/machine-gun.svg new file mode 100644 index 0000000..d7da0a1 --- /dev/null +++ b/assets/icons/machine-gun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/magic-palm.svg b/assets/icons/magic-palm.svg new file mode 100644 index 0000000..45c0911 --- /dev/null +++ b/assets/icons/magic-palm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/magic-shield.svg b/assets/icons/magic-shield.svg new file mode 100644 index 0000000..60f95bb --- /dev/null +++ b/assets/icons/magic-shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/microphone.svg b/assets/icons/microphone.svg new file mode 100644 index 0000000..2290499 --- /dev/null +++ b/assets/icons/microphone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/minigun.svg b/assets/icons/minigun.svg new file mode 100644 index 0000000..da9a46d --- /dev/null +++ b/assets/icons/minigun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mortar.svg b/assets/icons/mortar.svg new file mode 100644 index 0000000..1395837 --- /dev/null +++ b/assets/icons/mortar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/optics.svg b/assets/icons/optics.svg new file mode 100644 index 0000000..5fbb056 --- /dev/null +++ b/assets/icons/optics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/papers.svg b/assets/icons/papers.svg new file mode 100644 index 0000000..a40b450 --- /dev/null +++ b/assets/icons/papers.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/penetrator-mine.svg b/assets/icons/penetrator-mine.svg new file mode 100644 index 0000000..741269d --- /dev/null +++ b/assets/icons/penetrator-mine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/pepper-spray-can.svg b/assets/icons/pepper-spray-can.svg new file mode 100644 index 0000000..59f36a3 --- /dev/null +++ b/assets/icons/pepper-spray-can.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/pepper-spray-keychain.svg b/assets/icons/pepper-spray-keychain.svg new file mode 100644 index 0000000..ffaf798 --- /dev/null +++ b/assets/icons/pepper-spray-keychain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/person-black-bg.svg b/assets/icons/person-black-bg.svg new file mode 100644 index 0000000..6715680 --- /dev/null +++ b/assets/icons/person-black-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/phone.svg b/assets/icons/phone.svg new file mode 100644 index 0000000..f9489c8 --- /dev/null +++ b/assets/icons/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/pistol.svg b/assets/icons/pistol.svg new file mode 100644 index 0000000..10d3099 --- /dev/null +++ b/assets/icons/pistol.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/ppe.svg b/assets/icons/ppe.svg new file mode 100644 index 0000000..727af31 --- /dev/null +++ b/assets/icons/ppe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/punch.svg b/assets/icons/punch.svg new file mode 100644 index 0000000..8b00c2b --- /dev/null +++ b/assets/icons/punch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/revolver.svg b/assets/icons/revolver.svg new file mode 100644 index 0000000..58f8d21 --- /dev/null +++ b/assets/icons/revolver.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/rifle.svg b/assets/icons/rifle.svg new file mode 100644 index 0000000..e6e5764 --- /dev/null +++ b/assets/icons/rifle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/rocket.svg b/assets/icons/rocket.svg new file mode 100644 index 0000000..126be1b --- /dev/null +++ b/assets/icons/rocket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/rope.svg b/assets/icons/rope.svg new file mode 100644 index 0000000..922bbea --- /dev/null +++ b/assets/icons/rope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/satellite-phone.svg b/assets/icons/satellite-phone.svg new file mode 100644 index 0000000..9ccf21a --- /dev/null +++ b/assets/icons/satellite-phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/sawed-off-shotgun.svg b/assets/icons/sawed-off-shotgun.svg new file mode 100644 index 0000000..43195f7 --- /dev/null +++ b/assets/icons/sawed-off-shotgun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/scuba-gear.svg b/assets/icons/scuba-gear.svg new file mode 100644 index 0000000..47cbc0a --- /dev/null +++ b/assets/icons/scuba-gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/shotgun.svg b/assets/icons/shotgun.svg new file mode 100644 index 0000000..5776cfe --- /dev/null +++ b/assets/icons/shotgun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/sly.svg b/assets/icons/sly.svg new file mode 100644 index 0000000..6a7ad13 --- /dev/null +++ b/assets/icons/sly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/smg.svg b/assets/icons/smg.svg new file mode 100644 index 0000000..82388ec --- /dev/null +++ b/assets/icons/smg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/software.svg b/assets/icons/software.svg new file mode 100644 index 0000000..226b926 --- /dev/null +++ b/assets/icons/software.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/sound.svg b/assets/icons/sound.svg new file mode 100644 index 0000000..2056647 --- /dev/null +++ b/assets/icons/sound.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/space-suit.svg b/assets/icons/space-suit.svg new file mode 100644 index 0000000..a22019b --- /dev/null +++ b/assets/icons/space-suit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/spectre-m4.svg b/assets/icons/spectre-m4.svg new file mode 100644 index 0000000..ea31bc6 --- /dev/null +++ b/assets/icons/spectre-m4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/stick-grenade.svg b/assets/icons/stick-grenade.svg new file mode 100644 index 0000000..3689770 --- /dev/null +++ b/assets/icons/stick-grenade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/stiletto.svg b/assets/icons/stiletto.svg new file mode 100644 index 0000000..0407724 --- /dev/null +++ b/assets/icons/stiletto.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/supersonic-bullet.svg b/assets/icons/supersonic-bullet.svg new file mode 100644 index 0000000..2c23b6f --- /dev/null +++ b/assets/icons/supersonic-bullet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/suppressor.svg b/assets/icons/suppressor.svg new file mode 100644 index 0000000..a13111c --- /dev/null +++ b/assets/icons/suppressor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/swap-bag-black-bg.svg b/assets/icons/swap-bag-black-bg.svg new file mode 100644 index 0000000..1d0902e --- /dev/null +++ b/assets/icons/swap-bag-black-bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/switchblade.svg b/assets/icons/switchblade.svg new file mode 100644 index 0000000..95e0200 --- /dev/null +++ b/assets/icons/switchblade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/tablet.svg b/assets/icons/tablet.svg new file mode 100644 index 0000000..7304dd2 --- /dev/null +++ b/assets/icons/tablet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/tactical-body-armor.svg b/assets/icons/tactical-body-armor.svg new file mode 100644 index 0000000..e4c0887 --- /dev/null +++ b/assets/icons/tactical-body-armor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/tear-gas-grenade.svg b/assets/icons/tear-gas-grenade.svg new file mode 100644 index 0000000..2067d5b --- /dev/null +++ b/assets/icons/tear-gas-grenade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/tec-9.svg b/assets/icons/tec-9.svg new file mode 100644 index 0000000..d8b7c5f --- /dev/null +++ b/assets/icons/tec-9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/telescope.svg b/assets/icons/telescope.svg new file mode 100644 index 0000000..629f404 --- /dev/null +++ b/assets/icons/telescope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/telescopic-baton.svg b/assets/icons/telescopic-baton.svg new file mode 100644 index 0000000..4700a62 --- /dev/null +++ b/assets/icons/telescopic-baton.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/telescopic-sight.svg b/assets/icons/telescopic-sight.svg new file mode 100644 index 0000000..e0a4dd8 --- /dev/null +++ b/assets/icons/telescopic-sight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/thompson-m1.svg b/assets/icons/thompson-m1.svg new file mode 100644 index 0000000..d8d7be0 --- /dev/null +++ b/assets/icons/thompson-m1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/tomahawk.svg b/assets/icons/tomahawk.svg new file mode 100644 index 0000000..c4fd12f --- /dev/null +++ b/assets/icons/tomahawk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/trench-body-armor.svg b/assets/icons/trench-body-armor.svg new file mode 100644 index 0000000..033efa5 --- /dev/null +++ b/assets/icons/trench-body-armor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/two-handed-sword.svg b/assets/icons/two-handed-sword.svg new file mode 100644 index 0000000..e0b7e65 --- /dev/null +++ b/assets/icons/two-handed-sword.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/unarmed.svg b/assets/icons/unarmed.svg new file mode 100644 index 0000000..d96fcf4 --- /dev/null +++ b/assets/icons/unarmed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/walkie-talkie.svg b/assets/icons/walkie-talkie.svg new file mode 100644 index 0000000..c5ede79 --- /dev/null +++ b/assets/icons/walkie-talkie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/walther-ppk.svg b/assets/icons/walther-ppk.svg new file mode 100644 index 0000000..1317f33 --- /dev/null +++ b/assets/icons/walther-ppk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/wire-coil.svg b/assets/icons/wire-coil.svg new file mode 100644 index 0000000..6711ada --- /dev/null +++ b/assets/icons/wire-coil.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/wood-axe.svg b/assets/icons/wood-axe.svg new file mode 100644 index 0000000..e2d31a6 --- /dev/null +++ b/assets/icons/wood-axe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/CrumpledPlainPaper10.webp b/assets/img/CrumpledPlainPaper10.webp new file mode 100644 index 0000000..21028a7 Binary files /dev/null and b/assets/img/CrumpledPlainPaper10.webp differ diff --git a/assets/img/DG_Pause_Icon.webp b/assets/img/DG_Pause_Icon.webp new file mode 100644 index 0000000..f6aa7c6 Binary files /dev/null and b/assets/img/DG_Pause_Icon.webp differ diff --git a/assets/img/Delta_Green_Logo.webp b/assets/img/Delta_Green_Logo.webp new file mode 100644 index 0000000..039b59f Binary files /dev/null and b/assets/img/Delta_Green_Logo.webp differ diff --git a/assets/img/StainedPlainPaper10.webp b/assets/img/StainedPlainPaper10.webp new file mode 100644 index 0000000..d6dcd49 Binary files /dev/null and b/assets/img/StainedPlainPaper10.webp differ diff --git a/assets/img/StainedPlainPaper10a.webp b/assets/img/StainedPlainPaper10a.webp new file mode 100644 index 0000000..3420463 Binary files /dev/null and b/assets/img/StainedPlainPaper10a.webp differ diff --git a/assets/img/StainedPlainPaper10b.webp b/assets/img/StainedPlainPaper10b.webp new file mode 100644 index 0000000..7939da7 Binary files /dev/null and b/assets/img/StainedPlainPaper10b.webp differ diff --git a/assets/img/burned_delta_green_logo_on_form_splash_page.webp b/assets/img/burned_delta_green_logo_on_form_splash_page.webp new file mode 100644 index 0000000..144f9e5 Binary files /dev/null and b/assets/img/burned_delta_green_logo_on_form_splash_page.webp differ diff --git a/assets/img/green_delta_splash_page.webp b/assets/img/green_delta_splash_page.webp new file mode 100644 index 0000000..7474fb0 Binary files /dev/null and b/assets/img/green_delta_splash_page.webp differ diff --git a/assets/img/ivory-off-white-paper-texture.jpg b/assets/img/ivory-off-white-paper-texture.jpg new file mode 100644 index 0000000..9ef14c3 Binary files /dev/null and b/assets/img/ivory-off-white-paper-texture.jpg differ diff --git a/assets/img/ivory-off-white-paper-texture.webp b/assets/img/ivory-off-white-paper-texture.webp new file mode 100644 index 0000000..5dc79bd Binary files /dev/null and b/assets/img/ivory-off-white-paper-texture.webp differ diff --git a/css/deltagreen.css b/css/deltagreen.css new file mode 100644 index 0000000..c4f44a8 --- /dev/null +++ b/css/deltagreen.css @@ -0,0 +1,1470 @@ +@import url("https://fonts.googleapis.com/css2?family=Martel:wght@400;800&family=Roboto:wght@300;400;500&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Didact+Gothic"); + +@font-face { + font-family: "atwriter"; + src: url("../assets/font/another-typewriter/atwriter.ttf") format("truetype"); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */ +} + +@font-face { + font-family: TypeWriterCondensed; + src: url("../assets/font/typewriter-condensed/typewcond_regular.otf") + format("opentype"); +} + +@font-face { + font-family: TypeWriterCondensed; + font-weight: bold; + src: url("../assets/font/typewriter-condensed/typewcond_bold.otf") + format("opentype"); +} + +@font-face { + font-family: TypeWriterCondensed; + font-weight: 600; + src: url("../assets/font/typewriter-condensed/typewcond_demi.otf") + format("opentype"); +} + +@font-face { + font-family: "SpecialElite"; + src: url("../assets/font/special_elite/SpecialElite-Regular.ttf") + format("truetype"); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */ +} + +@font-face { + font-family: "PublicSans"; + src: url("../assets/font/public-sans/PublicSans-VariableFont_wght.ttf") + format("truetype"); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */ +} + +/* Global styles */ + +.deltagreen section.window-content { + scrollbar-color: #215112 #111 !important; + padding: 0.5rem; + color: black; /* Override for when in Foundry's dark mode */ + + input[type="checkbox"]:checked::before { + color: black; /* Override for when in Foundry's dark mode */ + } + + input[type="text"], + input[type="number"], + input[type="password"] { + height: unset; + line-height: 1.5rem; + } +} + +/* Character Sheet Style Options */ + +.window-content.outlaw-style, +.window-content.cowboy-style { + background: url("../assets/img/StainedPlainPaper10b.webp") !important; + background-size: 100% !important; +} + +.window-content.program-style { + background: url("../assets/img/StainedPlainPaper10a.webp") !important; + background-size: 100% !important; +} + +.cowboy-style { + font-family: "SpecialElite", sans-serif !important; +} + +.outlaw-style, +.program-style { + font-family: "PublicSans", sans-serif !important; +} + +.outlaw-style .cowboy-style .tabs [data-action="tab"] { + background: rgba(173, 151, 101, 0.3); +} + +.program-style .tabs [data-action="tab"] { + background: rgba(138, 136, 133, 0.3); +} + +.old-paper-background { + background: url("../assets/img/StainedPlainPaper10.webp") !important; +} + +.default-parchment-background { + background: url("/ui/parchment.jpg") repeat !important; +} + +.typewriter-condensed-font { + font-family: "TypeWriterCondensed", sans-serif !important; +} + +.martel-font { + font-family: "Martel", sans-serif !important; +} + +.signika-font { + font-family: "Signika", sans-serif !important; +} + +.atwriter-font { + font-family: "atwriter", sans-serif !important; +} + +.special-elite-font { + font-family: "SpecialElite", sans-serif !important; +} + +.public-sans-font { + font-family: "PublicSans", sans-serif !important; +} + +.rollable:hover, +.rollable:focus { + color: #000; + text-shadow: 0 0 5px #374e13; + cursor: pointer; +} + +.not-rollable { + color: #999999; +} + +input.breaking-point-hit { + color: rgb(255, 255, 255); + background-color: rgb(117, 0, 0); + font-weight: bold; +} + +.dg-red { + color: rgb(117, 0, 0); +} + +.bottom-margin-5px { + margin-bottom: 5px !important; +} + +.grid-1col { + display: grid; + grid-column: span 1 / span 1; + gap: 3px; +} + +.grid, +.grid-2col { + display: grid; + grid-column: span 2 / span 2; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 3px; + margin: 0px 0; + padding: 0; +} + +.grid-3col { + grid-column: span 3 / span 3; + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.grid-4col { + grid-column: span 4 / span 4; + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.grid-5col { + grid-column: span 5 / span 5; + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.grid-6col { + grid-column: span 5 / span 5; + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.grid-7col { + grid-column: span 7 / span 7; + grid-template-columns: repeat(7, minmax(0, 1fr)); +} + +.grid-8col { + grid-column: span 8 / span 8; + grid-template-columns: repeat(8, minmax(0, 1fr)); +} + +.grid-9col { + grid-column: span 9 / span 9; + grid-template-columns: repeat(9, minmax(0, 1fr)); +} + +.grid-10col { + grid-column: span 10 / span 10; + grid-template-columns: repeat(10, minmax(0, 1fr)); +} + +.grid-11col { + grid-column: span 11 / span 11; + grid-template-columns: repeat(11, minmax(0, 1fr)); +} + +.grid-12col { + grid-column: span 12 / span 12; + grid-template-columns: repeat(12, minmax(0, 1fr)); +} + +/* If the user wishes to sort skills by column, we need to +explicitly define a number of rows, rather than columns. */ +.grid-13row { + grid-template-rows: repeat(13, minmax(0, auto)) !important; + grid-template-columns: repeat(auto-fit, minmax(0, 1fr)) !important; + grid-auto-flow: column !important; +} + +.flex-group-center, +.flex-group-left, +.flex-group-right { + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + text-align: center; + padding: 2px; +} + +.flex-thin-border { + border: 1px solid #999; + border-radius: 2px; + border-left-color: darkslategray; + border-left-width: 4px; +} + +/* Make sure Special Training boxes are the same height + as all other skill boxes */ +.flex-thin-border.special-training-box { + min-height: 27px; +} + +.flex-mid-border { + border: 1.5px solid rgb(0, 0, 0); + border-radius: 2px; +} + +.flex-group-left { + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + text-align: left; + padding: 0; +} + +.flex-group-right { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + text-align: right; +} + +.flex-center { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; +} + +.flex-between { + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.horizontal-flex-column { + display: flex; + flex-direction: column; +} + +.flex-left { + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + text-align: left; +} + +.deltagreen .sheet-header { + -webkit-box-flex: 0; + -ms-flex: 0 0 400px; + flex: 0 0 auto; + overflow: hidden; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + margin-bottom: 8px; +} + +.deltagreen .sheet-header .profile-img { + height: 100px; + flex: 0 0 100px; + -webkit-box-flex: 0; + -ms-flex: 0 0 100px; + + cursor: var(--cursor-pointer); /* Variable name from Foundry */ + + border: 1px solid black; + margin-right: 5px; +} + +.deltagreen .sheet-header .header-fields { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.deltagreen .sheet-header h1.charname { + height: 55px; + font-family: inherit; + font-size: 2rem; + padding: 0px; + border-bottom: 0; + margin-bottom: 0; +} + +.deltagreen .sheet-header h1.charname input { + width: 100%; + height: 100%; + margin: 0; +} + +.deltagreen .resource-label { + font-weight: bold; +} + +.sheet nav.sheet-tabs { + border-bottom: transparent !important; + border-top: transparent !important; +} + +.deltagreen .tabs { + height: 1.5rem; + line-height: 1.5rem; + text-align: center; + vertical-align: middle; + margin-bottom: 0px !important; + padding-bottom: 0px !important; +} + +.deltagreen .tabs [data-action="tab"] { + font-weight: bold; + color: inherit; + vertical-align: middle !important; + height: inherit; + line-height: inherit; + padding-inline: 5px; + border-radius: 5px 5px 0px 0px; + border-color: #000; + border: gray; + border-width: 1px 1px 0px 1px; + border-style: solid; +} + +.deltagreen .tabs [data-action="tab"].active { + text-shadow: none; + font-style: italic; + border: #000; + border-width: 2px 2px 0px 2px; + border-style: solid; +} + +.deltagreen .tab { + height: 100%; + overflow-y: auto; + + border-color: #000; + border-width: 2px; + border-style: solid; + border-radius: 3px; + + padding: 5px; +} + +.deltagreen .program-style .tabs [data-action="tab"].active { + background-color: #000000; + color: #ffffff; +} + +.deltagreen .cowboy-style .tabs [data-action="tab"].active { + background-color: rgba(156, 115, 18, 0.3); + color: #000000; +} + +.deltagreen .items-list { + list-style: none; + /*margin: 7px 0; */ + padding: 0; + overflow-y: auto; +} + +.deltagreen .items-list .item-header { + font-weight: bold; + display: flex; + justify-content: center; + align-items: center; +} + +.deltagreen .items-list .item { + min-height: 30px; + line-height: 24px; + padding: 3px 0; + border-bottom: 1px solid #bbb; +} + +.deltagreen .items-list .item .item-image { + -webkit-box-flex: 0; + -ms-flex: 0 0 24px; + flex: 0 0 24px; + margin-right: 5px; +} + +.deltagreen .items-list .item .item-bond-damage { + -webkit-box-flex: 0; + -ms-flex: 0 0 24px; + flex: 0 0 24px; + margin: 0; + align-self: center; + justify-self: center; +} + +.deltagreen .items-list .item img { + display: block; +} + +.deltagreen .items-list .item-name { + display: flex; + align-content: center; + + word-wrap: break-word; + + margin: 0; +} + +.deltagreen .items-list .item-controls { + -webkit-box-flex: 0; + -ms-flex: 0 0 86px; + flex: 0 0 86px; + text-align: right; +} + +.deltagreen .skill-and-training-controls { + flex: 0 0 35px; +} + +.deltagreen .action-pill { + padding: 2px; + border-radius: 2.5px; + font-size: 0.8rem; + font-weight: bold; + background-color: rgba(0, 0, 0, 0.185); +} + +.deltagreen[id^="dg-settings"] { + .window-content > div.flexcol { + gap: 1rem; + } + + .form-group label { + flex: unset; + } +} + +a.btn-tiny { + height: 26px; + margin-left: 5px; + margin-right: 5px; + font-size: 13px; + padding-top: 1px; + padding-bottom: 1px; + padding-right: 5px; + padding-left: 5px; + + text-decoration: none; + background-color: #eeeeee; + color: #333333; + + border-radius: 4px; + line-height: 25px; + border: 1px solid #333333; + min-width: 20px; + text-align: center; +} + +span.left-aligned-label { + justify-content: left; + margin-left: 5px; +} + +span.max-attribute-value-label { + border: 1px solid rgb(122, 121, 113); + border-radius: 3px; + padding-top: 3px; + padding-bottom: 1px; + padding-left: 3px; + padding-right: 3px; + height: 26px; +} + +.deltagreen .skill-label { + margin: 2px; + align-content: flex-start; +} + +.deltagreen .skill-type-label { + margin: 2px; +} + +input.percentile-skill-input { + flex: 0 0 40px; + margin: 0 5px; + height: 1.2rem; + align-self: center; + text-align: center; +} + +input.checkbox-skill-input { + flex: 0 0 20px; + line-height: 10px; + width: 1px; +} + +input.checkbox-skill-input:disabled { + visibility: hidden; +} + +.deltagreen .sheet-header .header-top { + margin-bottom: 5px; +} + +.deltagreen .sheet-header .charname input { + /* font-family: "SpecialElite", sans-serif; */ +} + +.deltagreen .sheet-header h2.profession { + font-family: inherit; + font-size: 1.5rem; + border-bottom: 0; + margin-top: 5px; + margin-bottom: 0; +} + +.deltagreen .sheet-header h2.profession input { + width: 100%; + height: 40px; + margin: 0; +} + +div .simple-centered-flex-div { + display: flex; + align-items: center; +} + +div input.fill-remaining-space { + flex: 1; + margin: 1px; + text-align: left; +} + +div span.bio-grid-label { + margin: 1px; + text-align: left; +} + +.bio-grid-2col { + display: grid; + grid-template-columns: 100px auto; + align-items: center; + padding-bottom: 10px; + row-gap: 10px; +} + +.bio-grid-top-border { + border-top: 0px solid #aaa; + padding-top: 10px; +} + +.bio-grid-5col { + display: grid; + grid-template-columns: 100px 100px 20px 120px auto; + align-items: center; + padding-bottom: 10px; +} + +.bonds-grid-3col { + display: grid; + grid-template-columns: auto 50px max-content; + align-items: center; + padding-bottom: 10px; +} + +.centered { + text-align: center !important; +} + +.breaking-point-grid-3col { + display: grid; + grid-template-columns: 20% 70px 65px; + border-top: 0px solid #aaa; + margin-bottom: 10px; + border-bottom: 1px solid #aaa; + align-content: center; + justify-content: left; + align-items: center; + padding-bottom: 10px; + padding-top: 10px; +} + +.adaptation-grid-5col { + display: grid; + grid-template-columns: 30% 50px 50px 50px 200px; + margin-top: 10px; + margin-bottom: 10px; + align-content: center; + justify-content: left; + align-items: center; + padding-bottom: 5px; + border-bottom: 0px solid #aaa; +} + +.adapted-label { + font-weight: bold; + font-style: italic; + color: rgb(139, 0, 0); +} + +.weapon-grid-2col { + display: grid; + grid-template-columns: 48% 48%; + margin-top: 10px; + margin-bottom: 5px; + justify-content: left; + align-items: flex-end; + padding: 0px; + column-gap: 4%; +} + +.centered-item-property { + text-align: center; +} + +.bolded-label { + font-weight: bold; +} + +.resource .labeled-resource-checkbox { + vertical-align: middle; + margin-bottom: 0; +} + +.resource .first-aid-label { + vertical-align: bottom; +} + +div .motivation-section { + border-bottom: 1px solid #aaa; + margin-bottom: 10px; +} + +div .bottom-left-justified-resource { + vertical-align: bottom; + text-align: left; +} + +div .first-aid-received-section { + display: grid; + grid-template-columns: 40% 70px; + border-bottom: 1px solid #aaa; + margin-bottom: 10px; +} + +div .exhausted-section { + display: grid; + grid-template-columns: 40% 70px; + border-bottom: 1px solid #aaa; + margin-bottom: 10px; +} + +.exhausted-section input[type="number"] { + width: 75px; + + color: rgb(139, 0, 0); + text-align: center; + + background-color: rgba(0, 0, 0, 0.05); + + border: 1px solid rgb(122, 121, 113); + border-radius: 3px; + margin-left: 10px; + margin-bottom: 5px; +} + +.resource .exhaustion-label { + vertical-align: middle; +} + +.bonds-section-header { + /* border-top: 1px solid #AAA; */ + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 5px; +} + +.about-section-header { + border-top: 1px solid #aaa; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 5px; +} + +.tab.about { + .dg-about-links { + gap: 0.5rem; + margin-bottom: 1rem; + + a { + display: inline-flex; + align-items: center; + gap: 0.5rem; + width: fit-content; + max-width: 100%; + + i { + flex: 0 0 auto; + } + + span { + flex: 1 1 auto; + line-height: 1.4; + text-align: left; + } + } + } + + .dg-about-legal { + p { + margin: 0.5rem 0; + } + } +} + +textarea.wounds { + resize: none; + height: 100px; + width: 100%; +} + +.resource-inner-grid-3col { + display: grid; + grid-template-columns: 35% 30% 35%; + align-items: center; + text-align: center; +} + +.resource-outer-grid-1col { + display: grid; + grid-template-columns: 100%; + align-items: center; + justify-content: center; + border: 1.5px solid #000000; + padding: 5px; + grid-gap: 3px; + text-align: center; + border-radius: 2px; +} + +div.max-resource-value { + border: 1px solid rgb(122, 121, 113); + border-radius: 3px; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.physical-stats-outer-grid-3col { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + align-items: center; + justify-content: center; + text-align: center; + padding: 5px; + grid-gap: 5px; +} + +.physical-stats-and-feature { + border-radius: 2px; + border: 1.5px solid #000000; +} + +.attributes-wrapper { + margin-block-end: 12px; +} + +div.horizontal-bar-section-divider { + display: grid; + grid-template-columns: 100%; + justify-content: center; + align-items: center; + text-align: center; + + margin-bottom: 3px; + + background: #000; + color: #fff; + height: 30px; + + border-radius: 3px 3px 3px 3px; +} + +div.horizontal-bar-section-divider.skills-header { + display: grid; + grid-template-columns: repeat(3, 1fr); + justify-content: center; + align-items: center; + text-align: center; + + margin-bottom: 3px; + + background: #000; + color: #fff; + height: 30px; + + border-radius: 3px 3px 3px 3px; +} + +.horizontal-bar-section-divider .skills-header-title { + grid-column: 2; +} + +.horizontal-bar-section-divider .toggle-untrained { + grid-column: 3; + padding-right: 0.5rem; + justify-self: end; +} + +div.horizontal-bar-section-header { + display: grid; + grid-template-columns: 100%; + justify-content: center; + align-items: center; + text-align: center; + + margin-bottom: 3px; + + background: #000; + color: #fff; + height: 50px; +} + +.physical-description-label { + font-weight: bold; +} + +.notes-wrapper { + height: 100%; + margin-block-start: 12px; +} + +div.motivation-editor-container div.editor { + height: 400px; + min-height: 100% !important; +} + +.deltagreen .editor-host { + align-items: stretch; + height: 100%; +} + +.deltagreen .editor-host .editor { + height: 100% !important; +} + +.deltagreen .editor .editor-container { + height: 100% !important; +} + +/* I think all the stuff below is now obsolete +.editor-host .tox .tox-editor-container { + background: none !important; +} + +.deltagreen .editor-host .tox { + height: 100% !important; + display: block; +} + +.deltagreen .editor-host .tox-tinymce { + height: 100% !important; + display: block; +} + +.deltagreen .editor-host .tox .tox-edit-area { + position: inherit; + min-height: 20px; + height: 300px; +} + +.deltagreen .tox-editor-header { + background: none !important; +} + +.deltagreen .tox .tox-edit-area { + padding: 0 8px; +} +*/ + +/* + Item Sheet Common CSS +*/ + +.item-img { + -webkit-box-flex: 0; + -ms-flex: 0 0 100px; + flex: 0 0 100px; + height: 100px; + border: 0px solid black; +} + +input.item-sheet-short-input { + width: 75px; + margin-right: 5px; + margin-left: 5px; + text-align: center !important; +} + +.item-grid-button-row { + vertical-align: middle !important; + line-height: inherit; + padding: 5px 0px 0px 10px; +} + +/* + Bonds Item Sheet +*/ + +.bond-sheet-grid-2col { + display: grid; + grid-template-columns: 25% 75%; + align-items: center; + justify-content: center; + text-align: center; + padding-left: 5px; + grid-gap: 5px; +} + +.bond-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 150px auto; + align-items: center; + text-align: left; + padding-bottom: 10px; + column-gap: 10px; + row-gap: 10px; + padding-right: 5px; +} + +/* + Motivation Item Sheet +*/ + +.motivation-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 50% 50%; + align-items: center; + justify-content: center; + text-align: left; + padding-left: 5px; + grid-gap: 5px; +} + +/* + Armor Item Sheet +*/ + +.armor-sheet-grid-2col { + display: grid; + grid-template-columns: 25% 75%; + align-items: center; + justify-content: center; + text-align: center; + grid-gap: 5px; + padding-bottom: 10px; + padding-left: 5px; +} + +.armor-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 100px auto; + align-items: center; + text-align: left; + column-gap: 10px; + row-gap: 10px; + padding-bottom: 10px; + padding-right: 5px; +} + +.armor-sheet-secondary-grid-2col { + display: grid; + grid-template-columns: 25% 75%; + align-items: center; + justify-content: left; + text-align: left; + grid-gap: 5px; + padding-bottom: 10px; +} + +/* + Gear Item Sheet +*/ + +.gear-sheet-grid-2col { + display: grid; + grid-template-columns: 25% 75%; + align-items: center; + justify-content: center; + text-align: center; + grid-gap: 5px; + padding-left: 5px; +} + +.gear-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 100px auto; + align-items: center; + text-align: left; + column-gap: 10px; + row-gap: 10px; + padding-bottom: 10px; + padding-right: 5px; +} + +/* + Weapon Item Sheet +*/ + +.weapon-sheet-grid-2col { + display: grid; + grid-template-columns: 25% 75%; + align-items: center; + justify-content: center; + text-align: center; + grid-gap: 5px; + padding-left: 5px; +} + +.weapon-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 100px auto; + align-items: center; + text-align: left; + column-gap: 10px; + row-gap: 10px; + padding-bottom: 10px; + padding-right: 5px; +} + +.weapon-sheet-outer-grid-2col { + display: grid; + grid-template-columns: 60% 40%; + align-items: center; + justify-content: center; + text-align: center; + padding-left: 5px; + padding-right: 5px; + column-gap: 10px; + row-gap: 5px; +} + +.weapon-sheet-horizontal-grid-left-2col { + display: grid; + grid-template-columns: 50% 50%; + align-items: center; + text-align: left; + padding-bottom: 10px; + column-gap: 10px; + row-gap: 10px; + padding-right: 10px; +} + +.weapon-sheet-horizontal-grid-right-2col { + display: grid; + grid-template-columns: 60% 40%; + align-items: center; + text-align: left; + padding-bottom: 10px; + column-gap: 10px; + row-gap: 10px; + padding-right: 10px; +} + +.weapon-sheet-secondary-grid-2col { + display: grid; + grid-template-columns: 40% 60%; + align-items: center; + justify-content: left; + text-align: left; + grid-gap: 5px; + padding-right: 5px; +} + +/* + Tome Item Sheet +*/ + +.tome-sheet-horizontal-grid-2col { + display: grid; + grid-template-columns: 100px auto; + align-items: center; + text-align: left; + column-gap: 10px; + row-gap: 10px; + padding-bottom: 10px; + padding-right: 5px; +} + +.tome-sheet-handler-info-horizontal-grid-2col { + display: grid; + grid-template-columns: max-content auto; + align-items: center; + text-align: left; + column-gap: 10px; + row-gap: 10px; + padding-bottom: 10px; + padding-right: 5px; +} + +/* + Unnatural Character Sheet Specific Classes +*/ + +.unnatural-notes-section { + display: grid; + grid-template-columns: 100%; + align-items: left; + justify-content: left; + border: 1px solid #999; + padding: 5px; + grid-gap: 3px; + text-align: left; +} + +.skill-util-buttons { + margin: 5px; + + .typed-skill-add { + margin-right: 5px; + } +} + +a[data-action="applySkillImprovements"] { + float: right; +} + +.yellow-king { + color: #a0912f; +} + +.yellow-sign { + font-weight: bold; + text-shadow: 1px 1px #313a00; +} + +.yellow-king-rotate1 { + transform: rotate(3deg); +} + +.yellow-king-rotate4 { + transform: rotate(4deg); +} + +.yellow-king-rotate2 { + transform: rotate(-1deg); +} + +.yellow-king-rotate3 { + transform: rotate(5deg); +} + +.yellow-king-grid-9col { + display: grid; + grid-template-columns: max-content 5px max-content max-content 20px max-content max-content 10px 35px; + align-items: center; + padding-bottom: 10px; +} + +.yellow-king-grid-5col { + display: grid; + grid-template-columns: min-content 275px 20px min-content auto; + align-items: center; + padding-bottom: 10px; +} + +.yellow-king-label { + margin-right: 10px; +} + +.yellow-king input, +.yellow-king select, +.yellow-king textarea { + color: #a0912f; + font-weight: bold; +} + +.yellow-king textarea:focus, +.yellow-king input:focus { + color: #a0912f; +} + +.top-div-border { + border-top: 1px solid #aaa; + margin-bottom: 10px; + padding-bottom: 10px; + padding-top: 10px; +} + +.stat-block-input { + min-height: 300px; + resize: none; +} + +.weapon-name-flexcontainer { + display: flex; + justify-content: flex-start; + flex-direction: row; + column-gap: 10px; +} + +.weapon-name-flexitem { + flex: content; + align-self: flex-start; + text-align: left; +} + +.armor-piercing-chat-card-img { + border-radius: 10%; + height: 20px !important; + width: 20px !important; + margin: 0px; + vertical-align: text-bottom; +} + +/* + Custom UI Styling Elements +*/ +:root :not(.no-theme) { + --color-shadow-primary: #374e13; + --color-shadow-highlight: #406539; + --color-border-highlight: #406539; + --color-border-highlight-alt: #374e13; + --color-underline-header: #406539; + --color-text-dark-header: #406539; + scrollbar-color: var(--color-text-dark-header) #111; +} + +#pause img { + content: url(../assets/img/DG_Pause_Icon.webp); +} + +#interface:not(.no-theme) * { + --color-shadow-primary: #215112 !important; + --color-shadow-highlight: #215112 !important; + --color-border-highlight: #215112 !important; + --color-border-highlight-alt: #215112 !important; + --color-underline-header: #215112 !important; + --color-text-dark-header: #215112 !important; + scrollbar-color: var(--color-text-dark-header) #111 !important; +} + +#interface:not(.theme-light) * { + --control-border-color: #215112; + --control-hover-border-color: #215112; +} + +/* The logo is defunct as of v13 */ +#logo { + content: url("../assets/img/Delta_Green_Logo.webp"); + width: 90px; + height: auto; + padding-top: 10px; + padding-bottom: 10px; +} + +.target-proficiency-mod { + color: #247c14; +} + +.rollback-section { + order: 99; + display: flex; + margin-top: 5px; + align-items: center; + justify-content: center; + + > i { + margin: 5px; + } +} + +[data-action="rollback-skill-failure-state"] { + align-items: center; + display: inline-flex; + justify-content: center; + min-height: unset; + width: 20px; + height: 20px; + margin-left: 5px; + font-size: 12px; +} + +.strike { + text-decoration: line-through; +} + +.actor-sheet-v2 { + .window-content { + display: grid; + grid-template-columns: 220px 1fr; + grid-template-rows: auto; + width: 100%; + height: 100%; + } + + .left-bar { + grid-column: 1; + grid-row: 1 / -1; + padding: 10px; + } + + .window-content > :not(.left-bar) { + grid-column: 2; + grid-row: 1; + width: 100%; + box-sizing: border-box; + padding-right: 0; + margin-right: 0; + } + + .profile-img { + width: 100%; + height: auto; + } + + .physical-stats-outer-grid-3col { + display: contents; + } + + .physical-stats-outer-grid-3col, + .resources { + font-size: 12px; + } + + .resource-inner-grid-3col input { + padding: 1px; + } + + .tab.active { + padding-top: 20px; + } + + .breaking-point { + justify-content: space-between; + display: flex; + align-items: center; + + input { + width: 40px; + } + } + + .stats { + input { + margin: 1px; + } + } + + .luck { + margin-top: 5px; + } + + .horizontal-bar-section-divider.skills-header { + display: flex; + } +} + +.stats-wrapper { + position: relative; +} + +/* Edit icon */ +.stats-edit-btn { + position: absolute; + top: -10px; + right: 0; + + width: 24px; + height: 24px; + + display: flex; + align-items: center; + justify-content: center; + + border-radius: 50%; + background: var(--color-border-dark, #444); + color: #fff; + + font-size: 12px; + + cursor: pointer; + opacity: 0; + transition: + opacity 0.15s ease, + transform 0.15s ease; +} + +/* Show on hover of whole stats block */ +.stats-wrapper:hover .stats-edit-btn { + opacity: 1; + transform: scale(1.05); +} + +/* Hover feedback */ +.stats-edit-btn:hover { + background: var(--color-border-highlight, #c9a227); +} + +.edit-stat-form { + label { + color: var(--color-text-primary); + } +} + +.physical-stats-outer-grid-2col { + display: grid; + grid-template-columns: 1fr 1fr; + align-items: center; + justify-content: center; + text-align: center; + padding: 5px; + grid-gap: 5px; +} diff --git a/css/dialogue.css b/css/dialogue.css new file mode 100644 index 0000000..f654ff1 --- /dev/null +++ b/css/dialogue.css @@ -0,0 +1,52 @@ +.skill-modify-grid { + display: grid; + grid-template-columns: auto auto; + align-content: left; + justify-content: left; + align-items: left; + padding: 10px; + grid-gap: 10px 15px; +} + +.plusMinusNumberFieldBox { + display: flex; + gap: 10px; + + select[name="plusOrMinus"] { + flex: 1; + } + + .numeric-label-field { + flex: 1; + text-align: center !important; + } +} + +.damage-modify-label-grid { + display: grid; + grid-template-columns: auto auto; + align-content: left; + justify-content: left; + align-items: left; + padding: 10px; + grid-gap: 10px 15px; +} + +.damage-modify-formula-modify-grid { + display: grid; + grid-template-columns: auto auto auto auto auto auto; + align-content: left; + justify-content: left; + align-items: left; + padding: 10px; + grid-gap: 10px 15px; +} + +.damage-roll-formula-part { + min-width: 100px !important; + text-align: center !important; +} + +.damage-modify-roll-mode { + padding: 10px; +} diff --git a/css/editor.css b/css/editor.css new file mode 100644 index 0000000..b4a32ee --- /dev/null +++ b/css/editor.css @@ -0,0 +1,37 @@ +@font-face { + font-family: "SpecialElite"; + src: url("../assets/font/special_elite/SpecialElite-Regular.ttf") + format("truetype"); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */ +} + +.special-elite-font { + font-family: "SpecialElite", sans-serif !important; +} + +.editor-content { + font-family: "SpecialElite", sans-serif !important; +} + +.tox .tox-editor-container { + font-family: "SpecialElite", sans-serif !important; +} + +.tox .tox-edit-area { + font-family: "SpecialElite", sans-serif !important; +} + +.editor-host .editor { + font-family: "SpecialElite", sans-serif !important; +} + +.editor-host .tox { + font-family: "SpecialElite", sans-serif !important; +} + +.editor-host .tox-tinymce { + font-family: "SpecialElite", sans-serif !important; +} + +.editor-host .tox .tox-edit-area { + font-family: "SpecialElite", sans-serif !important; +} diff --git a/documentation/agent_sheet_sample.md b/documentation/agent_sheet_sample.md new file mode 100644 index 0000000..1a81ef2 --- /dev/null +++ b/documentation/agent_sheet_sample.md @@ -0,0 +1,41 @@ +# Sample Agent Sheet Screenshots + +**Note** - You can control the overall 'style' of the sheets by adjusting the system setting shown below: + +![Config Screenshot](./images/system-settings.webp) + +The "Cowboys" setting gives the oldest feel, with a typewriter font and an weathered paper. "Outlaw" is the middle option, with weathered paper, but a more modern font. "Program" is the default, and gives a cleaner and brighter paper and a modern font. + +## Skills + +### Cowboy Setting + +![Character Sheet Screenshot - Cowboys - Skills](./images/agent_sheet_cowboys_skills_tab.webp) + +### Outlaw Setting + +![Character Sheet Screenshot - Outlaws - Skills](./images/agent_sheet_outlaws_skills_tab.webp) + +### Program Setting + +![Character Sheet Screenshot - Program - Skills](./images/agent_sheet_program_skills_tab.webp) + +## Physical + +![Character Sheet Screenshot](./images/agent_sheet_program_statistics_tab.webp) + +## Mental + +![Character Sheet Screenshot](./images/agent_sheet_program_psychological_tab.webp) + +## Gear + +![Character Sheet Screenshot](./images/agent_sheet_program_equipment_tab.webp) + +## CV + +![Character Sheet Screenshot](./images/agent_sheet_program_personal_tab.webp) + +## Contacts + +![Character Sheet Screenshot](./images/agent_sheet_program_bonds_tab.webp) diff --git a/documentation/faqs.md b/documentation/faqs.md new file mode 100644 index 0000000..c348d72 --- /dev/null +++ b/documentation/faqs.md @@ -0,0 +1,60 @@ + + +# Frequently Asked Questions + +## Key + +- [Type Skills Such as Art or Piloting](#type-skills) +- [Lethality Rolls and Damage](#lethality) +- [Breaking Point](#breaking-point) +- [Inhuman Rules (Stat Tests Over 100%)](#inhuman-rules) +- [Ritual Skill](#ritual-skill) +- [Protection Rating (e.g. the Shield Icon)](#protection-rating-calculation) + + + +## Where are the Specialized Skills Like 'Science' and 'Pilot'? + +Only one 'Typed' skill is shown for an Agent by default, that being Art (Painting), and it is _below_ all the other skills. It can be removed by clicking the trash icon inside the box for the skill. Likewise, new typed skills can be added by clicking the _+_ button just above the section. + +This allows adding any number of skills as needed, without having dead space for unused skills. + +![Type Skills Section](./images/type_skill_example.webp) + + + +## Why Does the 'Lethality' Roll Show Damage Even on a Success? + +For Lethality, the D100 test against the target lethality threshold is evaluated like a normal skill test. But regardless of the outcome, the damage associated with a non-lethal roll (2D10) is also displayed in paretheses as lethality does not affect some creatures. + +Note - the Lethality roll does not currently take into account the changes that rolling a critical on the associated attack roll involves. For example, on a critical _Firearms_ check with a weapon with a lethality of 10%, the threshold doubles to 20%, and if that check fails the resulting damage doubles as well. + + + +## Where is an Agent's Breaking Point Shown? + +It is under the _Mental_ tab, as are the boxes to tick for _Incidents of Sanity Loss Without Going Insane_ and an Agents _Motivations_ and _Disorders_. Clicking the _Reset_ button will automatically change it to current SAN - POW. + + + +## "Inhuman Rules" - Why are Results for x5 Tests Different for Creatures with a x5 that is Greater than 100%? + +Per the rules in the Handler's Guide, if a creature has a physical attribute that is 20 or above (giving a x5 of 100% or higher), it is considered "inhuman" and all rolls that are not a 100 automatically succeed. Furthermore, any roll that is **below the attribute score** is a critical (on top of the normal critical rules). For example, if a monster had a strength of 25, giving a x5 of 125, that monster could score a critical not only by rolling a 33, but also by rolling anything 25 or under. + + + +## What is the Ritual Skill? + +Per the rules in the Handler's Guide, the ritual skill is used (primarily) to activate rituals. It is calculated as 100 - SAN. E.g., the lower one's sanity, the easier ritual activation becomes. Like Unnatural, it cannot be improved through failure like other skills. + + + +## What is the Shield Icon by Health? + +This represents the total protection value of all equipped armor (click on the x or checkmark to toggle if armor is equipped or not). This is how much damage should be subtracted from incoming attacks, assuming the incoming damage has no armor penetration. + +Note there are a few limitations of this calculation. For instance the system is unaware of certain pieces that should not stack, such as wearing multiple helmets. Or wearing a kevlar helmet with armor that includes a helmet already (such as a bomb suit). + +In the example below, the vest is equipped but the helmet is not. As such total armor is only 4 rather than 5. Note that currently only 'Armor' type items can increase the calculated protection value. + +![Armor Calculation](./images/equipped_armor.webp) diff --git a/documentation/home.md b/documentation/home.md new file mode 100644 index 0000000..8e2cbd4 --- /dev/null +++ b/documentation/home.md @@ -0,0 +1,77 @@ +# System Documentation: Delta Green for Foundry VTT + +## Table of Contents + +1. [Agent Sheeet](#agent-sheet) +2. [Rolls](#rolls) +3. [Compendia](#compendia) +4. [Item Macros](#item-macros) +5. [Frequently Asked Questions](./faqs.md) + +## Agent Sheet + +The Agent sheet is divided into several tabs. For more information on the Agent sheet and examples of each tab, [see here](./agent_sheet_sample.md). + +![Character Sheet Skills Section Screenshot](./images/agent_sheet_program_skills_tab.webp) + +The system automates most of the calculations on the sheet such as maximum HP/WP/SAN. Recalculating break points can be done by clicking a button. + +### Sheet Themes + +There is a system setting that controls the styling of the sheets. The current default is "Program" which gives a more modern look. To look more like the way the system looked prior to v1.3.0, choose the 'Cowboys' option. + +![Config Screenshot](./images/system-settings.webp) + +## Rolls + +Clicking on labels for skills, sanity, x5 skill tests or weapon damage/lethality will automatically roll those tests or damage. + +![Example Rolls In Chat Window](./images/chat_rolls.webp) + +### Modifying Rolls + +Right-clicking or shift-clicking on a field will bring up a dialogue to modify that roll (default: +20%). + +![Modify Roll Window](./images/modify_roll_dialogue.webp) + +### Types of Rolls + +- Click on _SAN_ (label above current/max sanity) to roll a Sanity check. +- Click on any of the skill labels (such as _Accounting_) to roll a skill test. +- Click on the name of a physical statistic (such as _STR_, on the _Physical_ tab) to roll a test. +- Click on a weapon name (on the _Gear_ tab) to roll the skill test associated with it (e.g. _Firearms_). +- Click on the Damage/Lethality associated with a weapon to roll it. + +![Sanity Roll](./images/sanity_roll.webp) + +## Compendia + +There is a compendium with numerous sample agents (parsed from the work of _jets_or_chasm_ and _morlock_) of all the professions. These can be used to get players started quickly if they do not wish to build an Agent themselves, or quickly need a replacement: + +![Pregenerated Agent Compendium](./images/pregen-compendium.webp) + +There are also compendia which contain some of the more commonly used Items. These Items can be dragged directly onto a character sheet (and then be modified as necessary). + +![Available Compendium Items](./images/compendiums.webp) + +## Item Macros + +Currently there are two built-in item macros, that allow rolling the associated skill check or damage roll for a weapon. Dragging a weapon (try clicking on 'Armor Piercing' to avoid rolling) onto the macro bar results in a macro like this that will roll damage: + +```javascript +game.deltagreen.rollItemMacro("Combat Dagger"); +``` + +![Armor Calculation](./images/item_damage_macro.webp) + +You can get a macro that rolls the appropriate skill check instead however with this command: + +```javascript +game.deltagreen.rollItemSkillCheckMacro("Combat Dagger"); +``` + +**Note:** Both of these macros search **_the currently selected token_** for the first instance of an Item matching the indicated name passed to the function. + +## Frequently Asked Questions + +[FAQs](./faqs.md) diff --git a/documentation/images/agent_sheet_cowboys_skills_tab.webp b/documentation/images/agent_sheet_cowboys_skills_tab.webp new file mode 100644 index 0000000..cb47433 Binary files /dev/null and b/documentation/images/agent_sheet_cowboys_skills_tab.webp differ diff --git a/documentation/images/agent_sheet_outlaws_skills_tab.webp b/documentation/images/agent_sheet_outlaws_skills_tab.webp new file mode 100644 index 0000000..ee155a1 Binary files /dev/null and b/documentation/images/agent_sheet_outlaws_skills_tab.webp differ diff --git a/documentation/images/agent_sheet_program_bonds_tab.webp b/documentation/images/agent_sheet_program_bonds_tab.webp new file mode 100644 index 0000000..0ed12fd Binary files /dev/null and b/documentation/images/agent_sheet_program_bonds_tab.webp differ diff --git a/documentation/images/agent_sheet_program_equipment_tab.webp b/documentation/images/agent_sheet_program_equipment_tab.webp new file mode 100644 index 0000000..0089cdb Binary files /dev/null and b/documentation/images/agent_sheet_program_equipment_tab.webp differ diff --git a/documentation/images/agent_sheet_program_personal_tab.webp b/documentation/images/agent_sheet_program_personal_tab.webp new file mode 100644 index 0000000..fa25024 Binary files /dev/null and b/documentation/images/agent_sheet_program_personal_tab.webp differ diff --git a/documentation/images/agent_sheet_program_psychological_tab.webp b/documentation/images/agent_sheet_program_psychological_tab.webp new file mode 100644 index 0000000..b81e0bc Binary files /dev/null and b/documentation/images/agent_sheet_program_psychological_tab.webp differ diff --git a/documentation/images/agent_sheet_program_skills_tab.webp b/documentation/images/agent_sheet_program_skills_tab.webp new file mode 100644 index 0000000..c0199b6 Binary files /dev/null and b/documentation/images/agent_sheet_program_skills_tab.webp differ diff --git a/documentation/images/agent_sheet_program_statistics_tab.webp b/documentation/images/agent_sheet_program_statistics_tab.webp new file mode 100644 index 0000000..f270ab0 Binary files /dev/null and b/documentation/images/agent_sheet_program_statistics_tab.webp differ diff --git a/documentation/images/chat_rolls.webp b/documentation/images/chat_rolls.webp new file mode 100644 index 0000000..ad3a061 Binary files /dev/null and b/documentation/images/chat_rolls.webp differ diff --git a/documentation/images/compendiums.webp b/documentation/images/compendiums.webp new file mode 100644 index 0000000..532c6fe Binary files /dev/null and b/documentation/images/compendiums.webp differ diff --git a/documentation/images/equipped_armor.webp b/documentation/images/equipped_armor.webp new file mode 100644 index 0000000..a322dd8 Binary files /dev/null and b/documentation/images/equipped_armor.webp differ diff --git a/documentation/images/item_damage_macro.webp b/documentation/images/item_damage_macro.webp new file mode 100644 index 0000000..0e6495f Binary files /dev/null and b/documentation/images/item_damage_macro.webp differ diff --git a/documentation/images/modify_roll_dialogue.webp b/documentation/images/modify_roll_dialogue.webp new file mode 100644 index 0000000..922f88d Binary files /dev/null and b/documentation/images/modify_roll_dialogue.webp differ diff --git a/documentation/images/pregen-compendium.webp b/documentation/images/pregen-compendium.webp new file mode 100644 index 0000000..550387e Binary files /dev/null and b/documentation/images/pregen-compendium.webp differ diff --git a/documentation/images/sanity_roll.webp b/documentation/images/sanity_roll.webp new file mode 100644 index 0000000..ec43c13 Binary files /dev/null and b/documentation/images/sanity_roll.webp differ diff --git a/documentation/images/system-settings.webp b/documentation/images/system-settings.webp new file mode 100644 index 0000000..898a656 Binary files /dev/null and b/documentation/images/system-settings.webp differ diff --git a/documentation/images/type_skill_example.webp b/documentation/images/type_skill_example.webp new file mode 100644 index 0000000..c645164 Binary files /dev/null and b/documentation/images/type_skill_example.webp differ diff --git a/lang/ca.json b/lang/ca.json new file mode 100644 index 0000000..53045db --- /dev/null +++ b/lang/ca.json @@ -0,0 +1,278 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "COGNOM, NOM (ALIES O NOM EN CLAU EN CAS DE SER NECESSARI)", + "DG.RollLuck": "Tira sort", + "DG.Luck": "Sort", + + "DG.FallbackText.ProfessionAndOrRank": "Professió (Rang si aplica)", + + "DG.Skills.accounting": "Comptabilitat", + "DG.Skills.alertness": "Alerta", + "DG.Skills.anthropology": "Antropologia", + "DG.Skills.archeology": "Arqueologia", + "DG.Skills.artillery": "Artilleria", + "DG.Skills.athletics": "Atletisme", + "DG.Skills.bureaucracy": "Burocràcia", + "DG.Skills.computer_science": "Informàtica", + "DG.Skills.criminology": "Criminologia", + "DG.Skills.demolitions": "Demolicions", + "DG.Skills.disguise": "Disfressar-se", + "DG.Skills.dodge": "Esquivar", + "DG.Skills.drive": "Conduir", + "DG.Skills.firearms": "Armes de foc", + "DG.Skills.first_aid": "Primers auxilis", + "DG.Skills.forensics": "Ciència forense", + "DG.Skills.heavy_machiner": "Maquinària pesada", + "DG.Skills.heavy_weapons": "Armes pesades", + "DG.Skills.history": "Història", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Dret", + "DG.Skills.medicine": "Medicina", + "DG.Skills.melee_weapons": "Armes cos a cos", + "DG.Skills.navigate": "Orientar-se", + "DG.Skills.occult": "Ocultisme", + "DG.Skills.persuade": "Persuadir", + "DG.Skills.pharmacy": "Farmàcia", + "DG.Skills.psychotherapy": "Psicoteràpia", + "DG.Skills.ride": "Equitació", + "DG.Skills.search": "Cercar", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Sigil/Camuflar", + "DG.Skills.surgery": "Cirurgia", + "DG.Skills.survival": "Supervivència", + "DG.Skills.swim": "Nedar", + "DG.Skills.unarmed_combat": "Combat sense armes", + "DG.Skills.unnatural": "Sobrenatural", + "DG.Skills.flight": "Flight", + + "DG.Skills.AddTypedOrCustomSkill": "Afegir tipus o habilitat personalitzada", + "DG.Skills.AddSkill": "Afegir habilitat", + "DG.Skills.EditTypedOrCustomSkill": "Edit Typed or Custom Skill", + "DG.Skills.EditSkill": "Edit Skill", + "DG.Skills.SkillGroup": "Habilitat grupal", + "DG.Skills.SkillName": "Nom de l'habilitat", + + "DG.TypeSkills.Art": "Art", + "DG.TypeSkills.Craft": "Ofici", + "DG.TypeSkills.ForeignLanguage": "Idioma", + "DG.TypeSkills.MilitaryScience": "Ciència militar", + "DG.TypeSkills.Pilot": "Pilotar", + "DG.TypeSkills.Science": "Ciència", + "DG.TypeSkills.Other": "Altre", + + "DG.Attributes.HP": "PV", + "DG.Attributes.WP": "PVOL", + "DG.Attributes.SAN": "SENY", + "DG.Attributes.str": "FOR", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DES", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POD", + "DG.Attributes.cha": "CAR", + + "DG.Navigation.Skills": "Habilitats", + "DG.Navigation.Physical": "Físic", + "DG.Navigation.Mental": "Mental", + "DG.Navigation.Gear": "Equip", + "DG.Navigation.CV": "C.V.", + "DG.Navigation.Contacts": "Contactes", + + "DG.About.OnlineHelp": "Documentació del sistema oberta en (EN LÍNEA)", + "DG.About.OnlineHelpTooltip": "Inicia el navegador amb ajuda en línea de Github", + "DG.About.OnlineBugTracker": "Preguntes, informes d'errors o sol·licituts de funcions (EN LÍNEA)", + "DG.About.OnlineBugTrackerTooltip": "Inicia el navegador el rastrejador d'errors de Github. ", + + "DG.Roll.Rolling": "Tirant", + "DG.Roll.Target": "Objectiu: ", + "DG.Roll.Success": "Èxit", + "DG.Roll.Failure": "Fallada", + "DG.Roll.Critical": "Crític", + "DG.Roll.Lethality": "Letalitat", + "DG.Roll.Lethal": "Letal", + "DG.Roll.For": "Per", + "DG.Roll.Damage": "Dany", + "DG.Roll.RollingDamageFor": "Tirant dany per", + "DG.Roll.Or": "O", + "DG.Roll.Roll": "Tirar", + + "DG.Physical.Wounds": "Ferides", + "DG.Physical.FirstAidLabel": "Primers auxilis ja aplicats: ", + "DG.Physical.Exhausted": "Exhausted:", + "DG.Physical.ExhaustionPenalty": "Penalty:", + + "DG.Generic.AddButtonLabel": "Afegir", + + "DG.Mental.BreakingPoint": "Punt de trencament: ", + "DG.Mental.Reset": "Esborrar", + "DG.Mental.SanityLossIncidentsLabel": "Incidents o pèrdua de SENY sense embogir", + "DG.Mental.Violence": "Violència", + "DG.Mental.Helplessness": "Indefensió", + "DG.Mental.AdaptedToViolence": "Adaptat a la violència", + "DG.Mental.AdaptedToHelplessness": "Adaptat a la impotència", + "DG.Mental.Motivations": "Motivacions", + "DG.Mental.Disorders": "Desordres", + + "DG.Gear.Weapons": "ARMES", + "DG.Gear.Armor": "ARMADURA", + "DG.Gear.OtherGear": "ALTRE EQUIP", + "DG.Gear.Name": "Nom", + "DG.Gear.DamageOrLethality": "Dany/Letalitat", + "DG.Gear.ArmorPiercing": "Perforació d'armadura", + "DG.Gear.ArmorRating": "Classificació d'armadura", + "DG.Gear.Equipped": "Equipat", + + "DG.CV.Sex": "Sexe", + "DG.CV.SexPlaceholder": "Sexe", + "DG.CV.AgeAndDoB": "Edat y D.D.N.", + "DG.CV.AgeAndDoBPlaceholder": "Edat & Data de naixement", + "DG.CV.Employer": "Organització", + "DG.CV.EmployerPlaceholder": "Historial laboral", + "DG.CV.Nationality": "Nacionalitat", + "DG.CV.NationalityPlaceholder": "Nacionalitat", + "DG.CV.Education": "Educació", + "DG.CV.EducationPlaceholder": "Educació o entrenament", + + "DG.Bonds.Bond": "Vincle", + "DG.Bonds.Name": "Nom", + "DG.Bonds.Score": "Puntuació", + "DG.Bonds.NewBond": "Nou vincle", + + "DG.Attributes.Tooltip.HP": "Punts de vida, un personatge cau inconscient ales 2 PV i mor amb 0 PV.", + "DG.Tooltip.MaximumHP": "La salut màxima és el promig de FOR + CON, arrodonint avall.", + "DG.Attributes.Tooltip.WP": "Els punts de voluntat són el combustible mental. Els necessiten per tirar endavant tot i l'esgotament o le situacions mentals greus. Consulta la pàgina 47 del manual de l'agent per més detalls.", + "DG.Tooltip.MaximumWP": "Els punts de voluntat màxims equivalen al POD.", + "DG.Attributes.Tooltip.SAN": "Clica per fer una tirada de seny.", + "DG.Tooltip.CurrentSanityPartOne": "Seny actual, el punt de trencament actual és ", + "DG.Tooltip.CurrentSanityPartTwo": ", fes clic a l'etiqueta de SENY anterior per realitzar una tirada de SENY.", + "DG.Tooltip.MaximumSanity": "El seny màxim és igual a 99 - l'habilitat antinatural.", + "DG.Tooltip.SkillLabel": "Clica per fer una tirada d'habilitat.", + "DG.Tooltip.CannotRollSkillLabel": "No es pot utilitzar una habilitat la 0%. Consulta la pàgina 28 del manual de l'agent.", + "DG.Tooltip.SkillFailCheckbox": "Després de fallar una prova sobre aquesta habilitat (si el domini és al menys 1%), marca aquesta casella. Al final de la sessió afageix 1D4-1 a l'habilitat i desmarca la casella. No s'aplica a l'habilitat antinatural. Consulta la pàgina 29 del manual de l'agent.", + "DG.Tooltip.DistinguishingFeature": "Caracteristica Distintiva (marca si la puntuació és de 13 o superior, o 8 o inferior).", + "DG.Tooltip.x5AttributeLabel": "Clica per una tirada de 5x.", + "DG.Tooltip.FirstAidAttempted": "Quan un agent rep primers auxilis, no es pot tornar a aplicar fins que rebi dany d'una font diferent.", + "DG.Tooltip.AdaptedToViolence": "Adaptar-se a la violència significa que l'empatia de l'agent rep al ser testimoni de tanta violència. Perd permanentment 1d6 CAR i la mateixa quantitat de cadascún dels seus vincles.", + "DG.Tooltip.AdaptedToHelplessness": "Estar adaptat a la impotència significa que l'impuls personal de l'agent s'allunya del món que el rodeja. Perd permanentement 1D6 POD. ", + "DG.Tooltip.ToggleEquippedState": "Fes click per alternar si aquest item està equipat o no. ", + "DG.Tooltip.Exhaustion": "An Agent who works too long or faces extreme danger and injury without resting becomes exhausted. When this comes into play is up to the Handler, but a good rule of thumb is that going a night without sleep or refusing to rest after losing SAN or Hit Points leads to exhaustion.", + + "DG.Gear.Expense.NA": "N/A", + "DG.Gear.Expense.Incidental": "Accidental", + "DG.Gear.Expense.Standard": "Estàndar", + "DG.Gear.Expense.Unusual": "Inusual", + "DG.Gear.Expense.Major": "Destacat", + "DG.Gear.Expense.Extreme": "Extrem", + + "DG.ItemWindow.Bonds.Description": "Descripció / Desenvolupament ", + "DG.ItemWindow.Bonds.ScoreTooltip": "Una puntuació més alta representa una relació més forta entre l'agente i el vincle. ", + + "DG.ItemWindow.Motivations.Attributes": "Atributs", + "DG.ItemWindow.Motivations.Motivation": "Motivació", + "DG.ItemWindow.Motivations.Description": "Descripció / Notes", + "DG.ItemWindow.Motivations.Disorder": "Trastorn", + "DG.ItemWindow.Motivations.IsDisorder": "És trastorn", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Alguna cosa que impulsa el personatge. ", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Un trastorn substitueix una motivació després d'arribar al punt de trencament.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Marca aquesta opció si afageix un trastorn o si ha perdut una motivació.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "El trastorn s'ha curat.", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un èxito crític en una tirada de sort terapèutica pot curar un trastorn. Tot i així, pot tornar la pròxima vegada que s'arribi a un punt de ruptura. ", + + "DG.ItemWindow.Gear.Attributes": "Atributs", + "DG.ItemWindow.Gear.Description": "Descripció", + "DG.ItemWindow.Gear.NamePlaceholder": "Nom", + "DG.ItemWindow.Gear.Expense": "Despesa", + "DG.ItemWindow.Gear.Equipped": "Equipat", + + "DG.ItemWindow.Armor.Description": "Descripció", + "DG.ItemWindow.Armor.NamePlaceholder": "Nom", + "DG.ItemWindow.Armor.ArmorRating": "Nivell armadura", + "DG.ItemWindow.Armor.Expense": "Despesa", + "DG.ItemWindow.Armor.Equipped": "Equipat", + + "DG.ItemWindow.Weapons.Description": "Descripció", + "DG.ItemWindow.Weapons.NamePlaceholder": "Nom", + "DG.ItemWindow.Weapons.Skill": "Habilitat", + "DG.ItemWindow.Weapons.Expense": "Despesa", + "DG.ItemWindow.Weapons.Damage": "Dany", + "DG.ItemWindow.Weapons.Lethality": "Letalitat", + "DG.ItemWindow.Weapons.IsLethality": "És letal", + "DG.ItemWindow.Weapons.LethalityTooltip": "Una arma letal té l'oportunitat de matar instantàniament un objectiu. Tira 1d100 enlloc del dany. Si no és letal, el dany és dalcula tirant 2d10, on el primer d10 és iugal a 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Marca si l'arma té un % de letalitat associat.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Perforació d'armadures", + "DG.ItemWindow.Weapons.Ammo": "Munició (Quantitat/Tipus)", + "DG.ItemWindow.Weapons.Range": "Abast", + "DG.ItemWindow.Weapons.KillRadius": "Radi de mort", + + "DG.ModifySkillRollDialogue.Title": "Modificar tirada", + "DG.ModifySkillRollDialogue.Test": "Test:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Objectiu original:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modificar objectiu:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Donar un modificador positiu o negatiu aquí per sumar o restar al objectiu en la tirada d'habilitats.", + + "DG.ModifyDamageRollDialogue.Weapon": "Arma:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Utilitza aquest camp per modificar la fòrmula, com duplicar el resultat.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Utilitza aquest camp per afegir un modificar com +1 o un altre terma com +1d4.", + + "DG.Roll.Inhuman": "Inhumà", + "DG.Tooltip.BreakPoint": "El punt de trencament actual, actualitzar quan el seny actual sigui igual a aquest valor. El punt de trencament inciial és SENY - POD.", + "DG.Tooltip.BreakPointReset": "Actualitzar el punt de trencament al valor actual de SENY - PVOL.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Modo rollo", + "DG.Bonds.Relationship": "Relació", + + "DG.TypeSkills.Subskills.Painting": "Pintar", + + "DG.Sheet.BlockHeaders.Attributes": "ATTRIBUTES", + "DG.Sheet.BlockHeaders.Statistics": "STATISTICS", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "Descripció física/notes", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "SKILLS AND TRAINING", + "DG.Sheet.BlockHeaders.Injuries": "INJURIES", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "BREAKING POINT AND ADAPTATIONS", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONS AND DISORDERS", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "PERSONAL INFORMATION / CV", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "BONDS / RELATIONSHIPS / CONTACTS", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Amagar habilitats no entrenades", + "DG.UnnaturalSheet.NotesLabel": "Notes", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "Descripció de la criatura o tipus de criatura", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Habilitats i notes", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Atacs i equipament", + "DG.NPCSheet.BreakPointAbbreviation": "PT", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "I HAVE SEEN THE", + "DG.ImpossibleLanscapes.YellowSign": "YELLOW SIGN", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Corrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "tion", + "DG.ImpossibleLanscapes.Gift": "Gift", + "DG.ImpossibleLanscapes.Insight": "Insight", + + "DG.VehicleSheet.NotesTabName": "Notes", + "DG.VehicleSheet.GearTabName": "Gear", + "DG.VehicleSheet.NotesLabel": "NOTES", + "DG.VehicleSheet.DescriptionPlaceHolder": "Vehicle Description", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Check a damaged Bond's box until the next Home Scene ends.", + "DG.Generic.ClearAll": "Clear All", + + "DG.Generic.SanDamage": "SAN Damage", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Target", + "DG.ItemWindow.Weapons.SkillModifier": "Skill Modifier", + "DG.ItemWindow.Custom": "Custom", + + "TYPES.Item.weapon": "Arma", + "TYPES.Item.armor": "Armadura", + "TYPES.Item.motivation": "Motivació", + "TYPES.Item.bond": "Vincle", + "TYPES.Item.gear": "Equip", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Activation SAN Damage", + "DG.ItemWindow.Ritual.ActivationTime": "Activation Time", + "DG.ItemWindow.Ritual.ActivationCosts": "Activation Costs", + "DG.ItemWindow.Ritual.StudyTime": "Study Time", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Learn SAN Damage", + + "DG.Messages.Skillsmark.Marked": "Aquesta habilitat està marcada", + "DG.Messages.Skillsmark.Tooltip": "Vegeu la p. 29 del Manual de l'agent" +} diff --git a/lang/cn.json b/lang/cn.json new file mode 100644 index 0000000..a630732 --- /dev/null +++ b/lang/cn.json @@ -0,0 +1,316 @@ +{ + "DG.SystemName": "绿色三角洲", + "DG.AgentNameFieldTooltip": "姓氏, 名字 (如适用则包括别名)", + "DG.RollLuck": "幸运检定", + "DG.Luck": "幸运", + + "DG.FallbackText.ProfessionAndOrRank": "职业(如适用则包括职位)", + + "DG.Skills.accounting": "会计", + "DG.Skills.alertness": "警觉", + "DG.Skills.anthropology": "人类学", + "DG.Skills.archeology": "考古学", + "DG.Skills.artillery": "炮术", + "DG.Skills.athletics": "运动", + "DG.Skills.bureaucracy": "行政", + "DG.Skills.computer_science": "计算机科学", + "DG.Skills.criminology": "犯罪学", + "DG.Skills.demolitions": "爆破", + "DG.Skills.disguise": "乔装", + "DG.Skills.dodge": "闪避", + "DG.Skills.drive": "机动车驾驶", + "DG.Skills.firearms": "射击", + "DG.Skills.first_aid": "急救", + "DG.Skills.forensics": "法证学", + "DG.Skills.heavy_machiner": "重型机械", + "DG.Skills.heavy_weapons": "重型武器", + "DG.Skills.history": "历史", + "DG.Skills.humint": "人源情报", + "DG.Skills.law": "法律", + "DG.Skills.medicine": "医学", + "DG.Skills.melee_weapons": "近战武器", + "DG.Skills.navigate": "导航", + "DG.Skills.occult": "神秘学", + "DG.Skills.persuade": "说服", + "DG.Skills.pharmacy": "药学", + "DG.Skills.psychotherapy": "精神治疗", + "DG.Skills.ride": "骑术", + "DG.Skills.search": "搜寻", + "DG.Skills.sigint": "信号情报", + "DG.Skills.stealth": "潜藏", + "DG.Skills.surgery": "手术", + "DG.Skills.survival": "生存", + "DG.Skills.swim": "游泳", + "DG.Skills.unarmed_combat": "徒手搏斗", + "DG.Skills.unnatural": "非自然知识", + "DG.Skills.flight": "飞机", + "DG.TypeSkills.Subskills.Painting": "绘画", + + "DG.Skills.AddTypedOrCustomSkill": "Add Typed/Custom Skill", + "DG.Skills.AddSkill": "Add Skill", + "DG.Skills.Apply": "Apply", + "DG.Skills.ApplySkillImprovements": "添加类型/自定义技能", + "DG.Skills.ApplySkillImprovementsChatFlavor": "应用技能成长", + "DG.Skills.ApplySkillImprovementsDialogLabel": "按以下公式进行技能成长:", + "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "影响一下技能:", + "DG.Skills.ApplySkillImprovementsWarning": "没有失败过的技能可以成长.", + "DG.Skills.EditTypedOrCustomSkill": "编辑类型或自定义技能", + "DG.Skills.EditSkill": "编辑技能", + "DG.Skills.SkillGroup": "技能组别", + "DG.Skills.SkillName": "技能名称", + + "DG.TypeSkills.Art": "艺术", + "DG.TypeSkills.Craft": "工艺", + "DG.TypeSkills.ForeignLanguage": "外语", + "DG.TypeSkills.MilitaryScience": "军事科学", + "DG.TypeSkills.Pilot": "特种载具", + "DG.TypeSkills.Science": "科学", + "DG.TypeSkills.Other": "其他", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "添加特训", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Custom自定义/类别 技能", + "DG.SpecialTraining.Dialog.DropDown.Skills": "技能", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "统计", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "编辑特训", + "DG.SpecialTraining.Dialog.NameLabel": "名称", + "DG.SpecialTraining.Dialog.SkillLabel": "技能货属性", + "DG.SpecialTraining.Dialog.Title": "创建/编辑特训", + + "DG.Attributes.HP": "HP", + "DG.Attributes.WP": "WP", + "DG.Attributes.SAN": "理智", + "DG.Attributes.str": "力量", + "DG.Attributes.con": "体质", + "DG.Attributes.dex": "敏捷", + "DG.Attributes.int": "智力", + "DG.Attributes.pow": "意志", + "DG.Attributes.cha": "魅力", + + "DG.Navigation.Skills": "技能", + "DG.Navigation.Physical": "健康", + "DG.Navigation.Mental": "精神", + "DG.Navigation.Gear": "装备", + "DG.Navigation.CV": "个人情况", + "DG.Navigation.Contacts": "重要关系", + + "DG.About.OnlineHelp": "System Documentation on (ONLINE)", + "DG.About.OnlineHelpTooltip": "Launch browser with online GitHub help.", + "DG.About.OnlineBugTracker": "Questions, Bug Reports or Feature Requests (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Launch browser with GitHub issue tracker.", + + "DG.Roll.Rolling": "正在掷骰", + "DG.Roll.Target": "需求: ", + "DG.Roll.Success": "成功", + "DG.Roll.Failure": "失败", + "DG.Roll.Critical": "大成功", + "DG.Roll.Lethality": "致死等级", + "DG.Roll.Lethal": "致死", + "DG.Roll.For": "目标", + "DG.Roll.Damage": "伤害", + "DG.Roll.RollingDamageFor": "正在为以下目标掷伤害骰", + "DG.Roll.Or": "或", + "DG.Roll.Roll": "掷骰", + + "DG.Physical.Wounds": "伤口", + "DG.Physical.FirstAidLabel": "已尝试急救: ", + "DG.Physical.Exhausted": "精疲力尽:", + "DG.Physical.ExhaustionPenalty": "惩罚:", + + "DG.Generic.AddButtonLabel": "添加", + + "DG.Mental.BreakingPoint": "崩溃点: ", + "DG.Mental.Reset": "重置", + "DG.Mental.SanityLossIncidentsLabel": "未陷入疯狂的理智损失事件", + "DG.Mental.Violence": "暴力行为", + "DG.Mental.Helplessness": "无力感", + "DG.Mental.AdaptedToViolence": "适应暴力行为", + "DG.Mental.AdaptedToHelplessness": "适应无力感", + "DG.Mental.Motivations": "人生动力", + "DG.Mental.Disorders": "Disorder", + + "DG.Gear.Weapons": "武器", + "DG.Gear.Armor": "护甲", + "DG.Gear.OtherGear": "其他装备", + "DG.Gear.Name": "名称", + "DG.Gear.DamageOrLethality": "伤害/致死", + "DG.Gear.ArmorPiercing": "护甲开销", + "DG.Gear.ArmorRating": "护甲等级", + "DG.Gear.Equipped": "已装备", + + "DG.CV.Sex": "性别", + "DG.CV.SexPlaceholder": "性别", + "DG.CV.AgeAndDoB": "年龄和出生日期.", + "DG.CV.AgeAndDoBPlaceholder": "年龄和出生日期.", + "DG.CV.Employer": "雇主", + "DG.CV.EmployerPlaceholder": "雇主或工作历史", + "DG.CV.Nationality": "国籍", + "DG.CV.NationalityPlaceholder": "国籍", + "DG.CV.Education": "教育", + "DG.CV.EducationPlaceholder": "教育或培训", + + "DG.Bonds.Bond": "重要关系", + "DG.Bonds.Name": "名称", + "DG.Bonds.Score": "关系值", + "DG.Bonds.NewBond": "新关系", + + "DG.Attributes.Tooltip.HP": "体力,体力降到2点时,你的特工会陷入昏迷。体力降到0点时,你的特工会死亡。", + "DG.Tooltip.MaximumHP": "体力等于力量加上体质,除以二并向上取整。", + "DG.Attributes.Tooltip.WP": "毅力(WP):毅力代表精神耐受度。特工需要毅力来克服疲劳或精神消耗的情况。(详见47页的毅力一节)", + "DG.Tooltip.MaximumWP": "最大毅力等于意志。", + "DG.Attributes.Tooltip.SAN": "点击进行理智检定", + "DG.Tooltip.CurrentSanityPartOne": "当前理智, 当前崩溃点是 ", + "DG.Tooltip.CurrentSanityPartTwo": ", 点击上方的SAN标签进行理智检定。", + "DG.Tooltip.MaximumSanity": "最大理智等于99减去非自然知识技能.", + "DG.Tooltip.SkillLabel": "点击进行技能检定。", + "DG.Tooltip.CannotRollSkillLabel": "特工不能使用一个0%的技能。详见《特工手册》第28页。", + "DG.Tooltip.SkillFailCheckbox": "在这个技能检定失败后(如果熟练度至少为1%),勾选此框。在会话结束时,为该技能增加1D4百分点并取消勾选。不适用于非自然知识或仪式技能。详见《特工手册》第29页", + "DG.Tooltip.DistinguishingFeature": "特征 (如果属性小于9或高于12则填写).", + "DG.Tooltip.x5AttributeLabel": "点击进行一次X5的检定", + "DG.Tooltip.FirstAidAttempted": "当你的特工受到急救后,无论成功失败,直到他下次受到伤害前该特工都无法再次被急救。", + "DG.Tooltip.AdaptedToViolence": ",适应暴力行为意味着你的特工的共情能力受到损伤。这导致魅力永久损失1D6点,同时所有重要关系损失等量的关系值。", + "DG.Tooltip.AdaptedToHelplessness": "适应无力感意味着你的特工做事的动力受到了损伤。这导致意志永久损失1D6点。", + "DG.Tooltip.ToggleEquippedState": "点击切换此物品是否已装备。", + "DG.Tooltip.Exhaustion": "一名特工在工作太长时间后,或是面临极端的危险或受伤却没有得到休息后,将变得精疲力尽。其适用的时机取决于掌局者,但彻夜不眠,或是在损失理智或体力后拒绝休息,应当导致精疲力尽。", + + "DG.Gear.Expense.NA": "N/A or None", + "DG.Gear.Expense.Incidental": "细微开销", + "DG.Gear.Expense.Standard": "常规开销", + "DG.Gear.Expense.Unusual": "显著开销", + "DG.Gear.Expense.Major": "重大开销", + "DG.Gear.Expense.Extreme": "极端开销", + + "DG.ItemWindow.Bonds.Description": "描述/发展", + "DG.ItemWindow.Bonds.ScoreTooltip": "A更高的关系值代表特工与重要关系之间的联系更强。", + + "DG.ItemWindow.Motivations.Attributes": "属性", + "DG.ItemWindow.Motivations.Motivation": "人生动机", + "DG.ItemWindow.Motivations.Description": "描述/笔记", + "DG.ItemWindow.Motivations.Disorder": "精神疾病", + "DG.ItemWindow.Motivations.IsDisorder": "是 精神疾病", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "驱动角色的东西。", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "一项精神障碍在达到崩溃点后取代一项动机.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "如果添加精神疾病,或现有动机因获得精神障碍而失去,请勾选此项。", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "精神疾病已被 \"治愈\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "心理治疗幸运骰的大成功可以 '治愈' 精神疾病。但它可能在下次达到崩溃点时再次出现。参见《特工手册》第78-79页的心理治疗部分", + + "DG.ItemWindow.Gear.Attributes": "属性", + "DG.ItemWindow.Gear.Description": "描述", + "DG.ItemWindow.Gear.NamePlaceholder": "名称", + "DG.ItemWindow.Gear.Expense": "开销", + "DG.ItemWindow.Gear.Equipped": "已装备", + + "DG.ItemWindow.Armor.Description": "描述", + "DG.ItemWindow.Armor.NamePlaceholder": "名称", + "DG.ItemWindow.Armor.ArmorRating": "护甲等级", + "DG.ItemWindow.Armor.Expense": "开销", + "DG.ItemWindow.Armor.Equipped": "已装备", + + "DG.ItemWindow.Weapons.Description": "描述", + "DG.ItemWindow.Weapons.NamePlaceholder": "名称", + "DG.ItemWindow.Weapons.Skill": "技能", + "DG.ItemWindow.Weapons.Expense": "开销", + "DG.ItemWindow.Weapons.Damage": "伤害", + "DG.ItemWindow.Weapons.Lethality": "致死等级", + "DG.ItemWindow.Weapons.IsLethality": "是否致死", + "DG.ItemWindow.Weapons.LethalityTooltip": "致死武器有机会立即杀死目标。掷D100而不是伤害骰。如果不致死,则造成伤害,就像结果是2d10掷骰一样,第一个d10上的'00'等于10", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "如果武器有致死等级 % 与之相关,请勾选此项", + "DG.ItemWindow.Weapons.ArmorPiercing": "穿甲", + "DG.ItemWindow.Weapons.Ammo": "弹药 (数量/类别)", + "DG.ItemWindow.Weapons.Range": "射程", + "DG.ItemWindow.Weapons.KillRadius": "击杀半径", + + "DG.ModifySkillRollDialogue.Title": "修改掷骰", + "DG.ModifySkillRollDialogue.Test": "测试:", + "DG.ModifySkillRollDialogue.OriginalTarget": "初始目标:", + "DG.ModifySkillRollDialogue.TargetModifier": "修改目标:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "在这里给出正面或负面修正,以增加/减少技能检定的目标值。", + + "DG.ModifyDamageRollDialogue.Weapon": "武器:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "使用此字段修改公式的外部部分,例如将结果加倍。", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "使用此字段添加固定修正值,如'+1'或另一个骰子项,如'+1d4'。", + + "DG.Roll.Inhuman": "非人类", + "DG.Tooltip.BreakPoint": "当前崩溃点,当当前理智降至或低于此值时重置。初始崩溃点等于初始理智减去意志。", + "DG.Tooltip.BreakPointReset": "将崩溃点重置为新的理智减去意志。", + "DG.Skills.ritual": "仪式", + + "DG.RollMode": "掷骰模式", + "DG.Bonds.Relationship": "关系", + + "DG.Sheet.BlockHeaders.Attributes": "属性", + "DG.Sheet.BlockHeaders.Statistics": "统计", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "外貌描述 / 笔记", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "技能与特训", + "DG.Sheet.BlockHeaders.Injuries": "伤害", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "崩溃点和适应", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "动机和精神疾病", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "个人信息 / 简历", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "重要关系 / 关系 / 联系人", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "隐藏未训练技能", + "DG.UnnaturalSheet.NotesLabel": "笔记", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "生物或生物类型的描述", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "显示未训练技能", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "技能 & 笔记", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "攻击 & 能力", + "DG.NPCSheet.BreakPointAbbreviation": "BP", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "我看见祂了", + "DG.ImpossibleLanscapes.YellowSign": "黄印", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "腐化", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "tion", + "DG.ImpossibleLanscapes.Gift": "天赋", + "DG.ImpossibleLanscapes.Insight": "洞察", + + "DG.VehicleSheet.NotesTabName": "笔记", + "DG.VehicleSheet.GearTabName": "装备", + "DG.VehicleSheet.NotesLabel": "笔记", + "DG.VehicleSheet.DescriptionPlaceHolder": "载具描述", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Check a damaged Bond's box until the next Home Scene ends.", + "DG.Generic.ClearAll": "Clear Checks", + + "DG.Generic.SanDamage": "理智损失", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "目标", + "DG.ItemWindow.Weapons.SkillModifier": "技能修正", + "DG.ItemWindow.Custom": "自定义", + + "TYPES.Actor.agent": "特工", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "非自然", + "TYPES.Actor.vehicle": "载具", + + "TYPES.Item.armor": "护甲", + "TYPES.Item.bond": "重要关系", + "TYPES.Item.gear": "装备", + "TYPES.Item.motivation": "人生动机", + "TYPES.Item.weapon": "武器", + "TYPES.Item.tome": "典籍", + "TYPES.Item.ritual": "仪式", + + "DG.Gear.Tomes": "典籍", + "DG.Gear.Rituals": "仪式", + + "DG.Tomes.Name": "名称", + "DG.Ritual.Name": "名称", + + "DG.Tome.Name": "名称", + "DG.ItemWindow.Tome.Description": "描述", + "DG.ItemWindow.Tome.LanguagePlaceholder": "语言", + "DG.ItemWindow.Tome.StudyTime": "学习时长", + "DG.ItemWindow.Tome.OccultIncrease": "神秘学技能增加", + "DG.ItemWindow.Tome.UnnaturalIncrease": "非自然知识技能增加", + "DG.ItemWindow.Tome.StudySanityDamage": "学习的理智损失", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "仅掌局者可见", + "DG.ItemWindow.Tome.HandlerNotes": "掌局者笔记", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "激活造成的理智损失", + "DG.ItemWindow.Ritual.ActivationTime": "激活耗时", + "DG.ItemWindow.Ritual.ActivationCosts": "激活代价", + "DG.ItemWindow.Ritual.StudyTime": "学习时长", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "学习造成的理智损失", + + "DG.Messages.Skillsmark.Marked": "此技能被标记", + "DG.Messages.Skillsmark.Tooltip": "参见第 29 页《代理人手册》" +} diff --git a/lang/de.json b/lang/de.json new file mode 100644 index 0000000..972e302 --- /dev/null +++ b/lang/de.json @@ -0,0 +1,296 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "NACHNAME, VORNAME (UND GGF. ALIAS)", + "DG.RollLuck": "Glücksprobe ausführen", + "DG.Luck": "Glück", + + "DG.FallbackText.ProfessionAndOrRank": "BERUF (RANG, FALLS ZUTREFFEND)", + + "DG.Skills.accounting": "Buchführung", + "DG.Skills.alertness": "Wachsamkeit", + "DG.Skills.anthropology": "Anthropologie", + "DG.Skills.archeology": "Archäologie", + "DG.Skills.artillery": "Artillerie", + "DG.Skills.athletics": "Athletik", + "DG.Skills.bureaucracy": "Bürokratie", + "DG.Skills.computer_science": "Computerwissen.", + "DG.Skills.criminology": "Kriminologie", + "DG.Skills.demolitions": "Sprengstoffe", + "DG.Skills.disguise": "Verkleiden", + "DG.Skills.dodge": "Ausweichen", + "DG.Skills.drive": "Auto fahren", + "DG.Skills.firearms": "Schusswaffen", + "DG.Skills.first_aid": "Erste Hilfe", + "DG.Skills.forensics": "Forensik", + "DG.Skills.heavy_machiner": "Schwere Maschinen", + "DG.Skills.heavy_weapons": "Schwere Waffen", + "DG.Skills.history": "Geschichte", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Gesetze", + "DG.Skills.medicine": "Medizin", + "DG.Skills.melee_weapons": "Nahkampfwaffen", + "DG.Skills.navigate": "Navigation", + "DG.Skills.occult": "Okkultismus", + "DG.Skills.persuade": "Überreden", + "DG.Skills.pharmacy": "Pharmazie", + "DG.Skills.psychotherapy": "Psychotherapie", + "DG.Skills.ride": "Reiten", + "DG.Skills.search": "Erkunden", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Heimlichkeit", + "DG.Skills.surgery": "Chirurgie", + "DG.Skills.survival": "Überleben", + "DG.Skills.swim": "Schwimmen", + "DG.Skills.unarmed_combat": "Waffenloser Kampf", + "DG.Skills.unnatural": "Mythos", + "DG.Skills.flight": "Flight", + + "DG.Skills.AddTypedOrCustomSkill": "Eigene Fertigkeit hinzufügen", + "DG.Skills.AddSkill": "Fertigkeit hinzufügen", + "DG.Skills.Apply": "Anwenden", + "DG.Skills.ApplySkillImprovements": "Verbesserungen der Fertigkeiten anwenden", + "DG.Skills.ApplySkillImprovementsChatFlavor": "Die folgenden Fertigkeiten wurden verbessert um", + "DG.Skills.ApplySkillImprovementsDialogLabel": "Verbessere Fertigkeiten nach folgender Formel:", + "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "Wirkt sich auf folgende Fertigkeiten aus:", + "DG.Skills.ApplySkillImprovementsWarning": "Keine Fertigkeiten aufgrund misslungener Versuche zu verbessern.", + "DG.Skills.EditTypedOrCustomSkill": "Benutzerdefinierte Fertigkeit bearbeiten", + "DG.Skills.EditSkill": "Fertigkeit bearbeiten", + "DG.Skills.SkillGroup": "Fertigkeiten-Gruppe", + "DG.Skills.SkillName": "Fertigkeit Name", + + "DG.TypeSkills.Art": "Kunst", + "DG.TypeSkills.Craft": "Handwerk", + "DG.TypeSkills.ForeignLanguage": "Fremdsprache", + "DG.TypeSkills.MilitaryScience": "Militärwissenschaft", + "DG.TypeSkills.Pilot": "Pilot", + "DG.TypeSkills.Science": "Wissenschaft", + "DG.TypeSkills.Other": "Andere", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Besondere Ausbildung hinzufügen", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Eigene Fertigkeiten", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Fertigkeiten", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Statistik", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Besondere Ausbildung bearbeiten", + "DG.SpecialTraining.Dialog.NameLabel": "Name", + "DG.SpecialTraining.Dialog.SkillLabel": "Fertigkeit oder Attribut", + "DG.SpecialTraining.Dialog.Title": "Spezialausbildung erstellen/ bearbeiten", + + "DG.Attributes.HP": "Gesundheit", + "DG.Attributes.WP": "Wille", + "DG.Attributes.SAN": "Stabilität", + "DG.Attributes.str": "STR", + "DG.Attributes.con": "KON", + "DG.Attributes.dex": "GES", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "MAC", + "DG.Attributes.cha": "CHA", + + "DG.Navigation.Skills": "Fertigkeiten", + "DG.Navigation.Physical": "Körperlich", + "DG.Navigation.Mental": "Geistig", + "DG.Navigation.Gear": "Ausrüstung", + "DG.Navigation.CV": "Persönlich", + "DG.Navigation.Contacts": "Bindungen", + + "DG.About.OnlineHelp": "Systemdokumentation auf (ONLINE)", + "DG.About.OnlineHelpTooltip": "Starten des Browsers mit der Online-Hilfe von GitHub.", + "DG.About.OnlineBugTracker": "Fragen, Fehlerberichte oder Funktionsanfragen (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Browser mit GitHub-Problem-Tracker starten.", + + "DG.Roll.Rolling": "Probe", + "DG.Roll.Target": "Ziel: ", + "DG.Roll.Success": "Erfolg", + "DG.Roll.Failure": "Fehlschlag", + "DG.Roll.Critical": "Kritisch", + "DG.Roll.Lethality": "Tödlichkeit", + "DG.Roll.Lethal": "Tödlich", + "DG.Roll.For": "Für", + "DG.Roll.Damage": "Schaden", + "DG.Roll.RollingDamageFor": "SCHADEN würfeln für", + "DG.Roll.Or": "Oder", + "DG.Roll.Roll": "Probe", + + "DG.Physical.Wounds": "Verletzungen", + "DG.Physical.FirstAidLabel": "Erste Hilfe bereits geleistet: ", + "DG.Physical.Exhausted": "Exhausted:", + "DG.Physical.ExhaustionPenalty": "Penalty:", + + "DG.Generic.AddButtonLabel": "Hinzufügen", + + "DG.Mental.BreakingPoint": "Schwelle: ", + "DG.Mental.Reset": "Reset", + "DG.Mental.SanityLossIncidentsLabel": "Vorfälle von Stabilitäts-Verlust, ohne verrückt zu werden", + "DG.Mental.Violence": "Gewalt", + "DG.Mental.Helplessness": "Hilflosigkeit", + "DG.Mental.AdaptedToViolence": "An Gewalt gewöhnt", + "DG.Mental.AdaptedToHelplessness": "An Hilflosigkeit gewöhnt", + "DG.Mental.Motivations": "Motivation", + "DG.Mental.Disorders": "Störung", + + "DG.Gear.Weapons": "WAFFEN", + "DG.Gear.Armor": "RÜSTUNG", + "DG.Gear.OtherGear": "ANDERE AUSRÜSTUNG", + "DG.Gear.Name": "Name", + "DG.Gear.DamageOrLethality": "Schaden/ Tödlichkeit", + "DG.Gear.ArmorPiercing": "Rüstungsdurchdringung", + "DG.Gear.ArmorRating": "Rüstungsschutz", + "DG.Gear.Equipped": "Ausgerüstet", + + "DG.CV.Sex": "Geschlecht", + "DG.CV.SexPlaceholder": "Geschlecht", + "DG.CV.AgeAndDoB": "Alter und Geb.", + "DG.CV.AgeAndDoBPlaceholder": "Alter und Geburtsdatum", + "DG.CV.Employer": "Arbeitgeber", + "DG.CV.EmployerPlaceholder": "Arbeitgeber oder Berufserfahrung", + "DG.CV.Nationality": "Nationalität", + "DG.CV.NationalityPlaceholder": "Nationalität", + "DG.CV.Education": "Bildung", + "DG.CV.EducationPlaceholder": "Bildung oder Training", + + "DG.Bonds.Bond": "Bindung", + "DG.Bonds.Name": "Name", + "DG.Bonds.Score": "Wert", + "DG.Bonds.NewBond": "Neue Bindung", + + "DG.Attributes.Tooltip.HP": "Gesundheit. Ein Charakter wird bei 2 Gesundheit bewusstlos und stirbt bei 0 Gesundheit.", + "DG.Tooltip.MaximumHP": "Die maximale Gesundheit ist der Durchschnitt von STR + KON, aufgerundet.", + + "DG.Attributes.Tooltip.WP": "Die Punkte in WILLE sind mentaler Treibstoff. Agenten brauchen WILLE, um trotz Erschöpfung oder geistig anstrengender Situationen weiterzumachen. Auf Seite 47 des Agentenhandbuchs findest du weitere Informationen ('Willpower').", + "DG.Tooltip.MaximumWP": "Der maximale WILLE ist gleich MAC.", + "DG.Attributes.Tooltip.SAN": "Klicken, um eine Stabilitäts-Probe durchzuführen...", + + "DG.Tooltip.CurrentSanityPartOne": "Die aktuelle Grenze der Stabilität. Die aktuelle Belastungsschwelle ist ", + "DG.Tooltip.CurrentSanityPartTwo": ", Klicke oben auf STABILITÄT, um eine Stabilitäts-Probe durchzuführen.", + "DG.Tooltip.MaximumSanity": "Die maximale Stabilität ist gleich 99 abzüglich der Fähigkeit 'Mythos'.", + "DG.Tooltip.SkillLabel": "Klicke, um eine Fertigkeitsprobe durchzuführen.", + "DG.Tooltip.CannotRollSkillLabel": "Eine Fertigkeit mit Wert 0% kann nicht verwendet werden. Siehe Seite 28 des Agentenhandbuchs.", + "DG.Tooltip.SkillFailCheckbox": "Wenn dir eine Probe auf diese Fertigkeit misslingt (sofern die Fertigkeit mindestens 1% beträgt), markiere dieses Kästchen. Am Ende der Sitzung fügst du 1D4 Prozentpunkte zu der Fertigkeit hinzu und deaktivierst das Kästchen. Gilt nicht für die Fertigkeiten 'Mythos' und 'Ritual'. Siehe Seite 29 des Agentenhandbuchs (Skills: 'Unnatural' & 'Ritual').", + "DG.Tooltip.DistinguishingFeature": "Alleinstellungsmerkmal (ausfüllen, wenn die Punktzahl 13 oder höher bzw. 8 oder niedriger ist).", + "DG.Tooltip.x5AttributeLabel": "Klicke, um eine x5 Probe durchzuführen.", + "DG.Tooltip.FirstAidAttempted": "Sobald ein Agent 'Erste Hilfe' erhalten hat, kann er sie erst wieder in Anspruch nehmen, wenn er weiteren Schaden aus einer anderen Quelle erleidet.", + "DG.Tooltip.AdaptedToViolence": "Die 'Gewöhnung an Gewalt' ('Adapted to Violence') bedeutet, dass das Einfühlungsvermögen deines Agenten leidet, da er Gewalt nur als ein weiteres Werkzeug ansieht, das er einsetzen kann. Der Agent verliert dauerhaft 1D6 CHA und den gleichen Betrag von jedem seiner Bindungen.", + "DG.Tooltip.AdaptedToHelplessness": "Die 'Gewöhnung an Hilflosigkeit' ('Adapted to Helplessness') bedeutet, dass der persönliche Antrieb deines Agenten leidet, da er sich von der Welt um ihn herum zurückzieht. Sobald dein Agent an die Hilflosigkeit gewöhnt ist, verliert er dauerhaft 1D6 MAC.", + "DG.Tooltip.ToggleEquippedState": "Klicke hier, um umzuschalten, ob dieser Gegenstand ausgerüstet ist oder nicht.", + "DG.Tooltip.Exhaustion": "An Agent who works too long or faces extreme danger and injury without resting becomes exhausted. When this comes into play is up to the Handler, but a good rule of thumb is that going a night without sleep or refusing to rest after losing SAN or Hit Points leads to exhaustion.", + + "DG.Gear.Expense.NA": "N/A bzw Keine", + "DG.Gear.Expense.Incidental": "Zufällig", + "DG.Gear.Expense.Standard": "Standard", + "DG.Gear.Expense.Unusual": "Ungewöhnlich", + "DG.Gear.Expense.Major": "Schwierig", + "DG.Gear.Expense.Extreme": "Extrem", + + "DG.ItemWindow.Bonds.Description": "Beschreibung/ Entwicklungen", + "DG.ItemWindow.Bonds.ScoreTooltip": "Eine höhere Punktzahl steht für eine stärkere Beziehung zwischen dem Agenten und seiner Bindung.", + + "DG.ItemWindow.Motivations.Attributes": "Attribute", + "DG.ItemWindow.Motivations.Motivation": "Motivation", + "DG.ItemWindow.Motivations.Description": "Beschreibung/ Notizen", + "DG.ItemWindow.Motivations.Disorder": "Störung", + "DG.ItemWindow.Motivations.IsDisorder": "Ist Störung", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Etwas, was den Charakter antreibt.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Eine Störung ersetzt eine Motivation, nachdem du eine Belastungsschwelle erreicht hast.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Prüfe dies, wenn du eine Störung hinzufügst oder wenn eine bestehende Motivation durch den Erwerb einer Störung verloren gegangen ist.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Störung wurde \"Geheilt\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Ein kritischer Erfolg bei einer Therapie-Glücksprobe kann eine Störung 'heilen'. Die Störung kann jedoch beim nächsten Mal zurückkehren, wenn eine Belastungsschwelle erreicht wird. Siehe den Abschnitt Therapie auf den Seiten 78-79 des Agentenhandbuchs. (siehe 'Therapy')", + + "DG.ItemWindow.Gear.Attributes": "Attribute", + "DG.ItemWindow.Gear.Description": "Beschreibung", + "DG.ItemWindow.Gear.NamePlaceholder": "Name", + "DG.ItemWindow.Gear.Expense": "Ausgaben", + "DG.ItemWindow.Gear.Equipped": "Ausgerüstet", + + "DG.ItemWindow.Armor.Description": "Beschreibung", + "DG.ItemWindow.Armor.NamePlaceholder": "Name", + "DG.ItemWindow.Armor.ArmorRating": "Rüstungsschutz", + "DG.ItemWindow.Armor.Expense": "Ausgaben", + "DG.ItemWindow.Armor.Equipped": "Ausgerüstet", + + "DG.ItemWindow.Weapons.Description": "Beschreibung", + "DG.ItemWindow.Weapons.NamePlaceholder": "Name", + "DG.ItemWindow.Weapons.Skill": "Fertigkeit", + "DG.ItemWindow.Weapons.Expense": "Ausgaben", + "DG.ItemWindow.Weapons.Damage": "Schaden", + "DG.ItemWindow.Weapons.Lethality": "Tödlichkeit", + "DG.ItemWindow.Weapons.IsLethality": "Ist tödlich", + "DG.ItemWindow.Weapons.LethalityTooltip": "Eine tödliche Waffe hat eine Chance, ein Ziel sofort zu töten. Wirf einen D100 statt eines Schadenswürfels. Wenn sie nicht tödlich ist, wird der Schaden stattdessen wie bei einer 2d10-Probe berechnet, wobei eine '00' auf dem ersten d10 einer 10 entspricht.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Prüfe dies, wenn die Waffe eine Tödlichkeit in % hat.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Rüstungsdurchdringung", + "DG.ItemWindow.Weapons.Ammo": "Munition (Menge/Typ)", + "DG.ItemWindow.Weapons.Range": "Reichweite", + "DG.ItemWindow.Weapons.KillRadius": "Tötungsradius", + + "DG.ModifySkillRollDialogue.Title": "Probe modifizieren", + "DG.ModifySkillRollDialogue.Test": "Probe:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Ursprüngliches Ziel:", + "DG.ModifySkillRollDialogue.TargetModifier": "Ziel modifizieren (+/-):", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Gib hier einen positiven oder negativen Modifikator an, der zum Ziel für die Fertigkeitsprobe addiert/ abgezogen wird.", + + "DG.ModifyDamageRollDialogue.Weapon": "Waffe:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Verwende dieses Feld, um den äußeren Teil der Formel zu ändern, z. B. um das Ergebnis zu verdoppeln.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Verwende dieses Feld, um einen Modifikator wie '+1' oder einen anderen Würfelbegriff wie '+1d4' hinzuzufügen.", + + "DG.Roll.Inhuman": "Nicht-Menschlich", + "DG.Tooltip.BreakPoint": "Die aktuelle Belastungsschwelle, die zurückgesetzt wird, wenn die aktuelle Stabilität auf oder unter diesen Wert fällt. Die Belastungsschwelle zu Beginn ist STABILITÄT abzüglich MAC.", + "DG.Tooltip.BreakPointReset": "Belastungsschwelle zurücksetzen auf aktuelle MAC abzüglich WILLE.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Probe-Modus", + "DG.Bonds.Relationship": "Beziehung", + + "DG.TypeSkills.Subskills.Painting": "Malerei", + + "DG.Sheet.BlockHeaders.Attributes": "ATTRIBUTE", + "DG.Sheet.BlockHeaders.Statistics": "STATISTIK", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "PHYSISCHE BESCHREIBUNG / ANMERKUNGEN", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "FERTIGKEITEN UND TRAINING", + "DG.Sheet.BlockHeaders.Injuries": "VERLETZUNGEN", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "BELASTUNGSSCHWELLE UND GEWÖHNUNGEN", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONEN UND STÖRUNGEN", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "PERSÖNLICHE INFORMATIONEN / LEBENSLAUF", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "BINDUNGEN / BEZIEHUNGEN / KONTAKTE", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Untrainierte ausblenden", + "DG.UnnaturalSheet.NotesLabel": "Notizen", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "Beschreibung der Kreatur oder Kreaturenart", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Untrainierte einblenden", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Fertigkeiten & Notizen", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Angriffe & Fähigkeiten", + "DG.NPCSheet.BreakPointAbbreviation": "BS", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "ICH HABE GESEHEN:", + "DG.ImpossibleLanscapes.YellowSign": "DAS GELBE ZEICHEN", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Korrum", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "piert", + "DG.ImpossibleLanscapes.Gift": "Gabe", + "DG.ImpossibleLanscapes.Insight": "Erkenntnis", + + "DG.VehicleSheet.NotesTabName": "Notizen", + "DG.VehicleSheet.GearTabName": "Ausrüstung", + "DG.VehicleSheet.NotesLabel": "NOTIZEN", + "DG.VehicleSheet.DescriptionPlaceHolder": "Fahrzeugbeschreibung", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Prüfe das Kästchen einer beschädigten Bindung, bis die nächste Heimszene endet.", + "DG.Generic.ClearAll": "Proben löschen", + + "DG.Generic.SanDamage": "Stabilitäts-Verlust", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Ziel", + "DG.ItemWindow.Weapons.SkillModifier": "Fertigkeitsmodifikator", + "DG.ItemWindow.Custom": "Benutzerdefiniert", + + "TYPES.Item.weapon": "Waffe", + "TYPES.Item.armor": "Rüstung", + "TYPES.Item.motivation": "Motivation", + "TYPES.Item.bond": "Bindung", + "TYPES.Item.gear": "Ausrüstung", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Activation SAN Damage", + "DG.ItemWindow.Ritual.ActivationTime": "Activation Time", + "DG.ItemWindow.Ritual.ActivationCosts": "Activation Costs", + "DG.ItemWindow.Ritual.StudyTime": "Study Time", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Learn SAN Damage", + + "DG.Messages.Skillsmark.Marked": "Diese Fähigkeit ist gekennzeichnet.", + "DG.Messages.Skillsmark.Tooltip": "Siehe S. 29 des Agentenhandbuchs" +} diff --git a/lang/en.json b/lang/en.json new file mode 100644 index 0000000..94b9363 --- /dev/null +++ b/lang/en.json @@ -0,0 +1,433 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "LAST NAME, FIRST NAME (AND ALIAS IF APPLICABLE)", + "DG.RollLuck": "Roll Luck", + "DG.Luck": "Luck", + + "DG.FallbackText.newItem": "New {type}", + + "DG.Skills.accounting": "Accounting", + "DG.Skills.alertness": "Alertness", + "DG.Skills.anthropology": "Anthropology", + "DG.Skills.archeology": "Archeology", + "DG.Skills.artillery": "Artillery", + "DG.Skills.athletics": "Athletics", + "DG.Skills.bureaucracy": "Bureaucracy", + "DG.Skills.computer_science": "Computer Science", + "DG.Skills.criminology": "Criminology", + "DG.Skills.demolitions": "Demolitions", + "DG.Skills.disguise": "Disguise", + "DG.Skills.dodge": "Dodge", + "DG.Skills.drive": "Drive", + "DG.Skills.firearms": "Firearms", + "DG.Skills.first_aid": "First Aid", + "DG.Skills.forensics": "Forensics", + "DG.Skills.heavy_machiner": "Heavy Machinery", + "DG.Skills.heavy_weapons": "Heavy Weapons", + "DG.Skills.history": "History", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Law", + "DG.Skills.medicine": "Medicine", + "DG.Skills.melee_weapons": "Melee Weapons", + "DG.Skills.navigate": "Navigate", + "DG.Skills.occult": "Occult", + "DG.Skills.persuade": "Persuade", + "DG.Skills.pharmacy": "Pharmacy", + "DG.Skills.psychotherapy": "Psychotherapy", + "DG.Skills.ride": "Ride", + "DG.Skills.search": "Search", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Stealth", + "DG.Skills.surgery": "Surgery", + "DG.Skills.survival": "Survival", + "DG.Skills.swim": "Swim", + "DG.Skills.unarmed_combat": "Unarmed Combat", + "DG.Skills.unnatural": "Unnatural", + "DG.Skills.flight": "Flight", + + "DG.Skills.Tooltip.accounting": "Spot financial red flags like hidden assets, shell companies, or embezzlement.", + "DG.Skills.Tooltip.alertness": "Notice hidden dangers, subtle movements, or quiet sounds before they become threats.", + "DG.Skills.Tooltip.anthropology": "Understand the beliefs, behaviors, and taboos of living cultures and societies.", + "DG.Skills.Tooltip.archeology": "Analyze ancient artifacts and ruins to interpret long-dead civilizations.", + "DG.Skills.Tooltip.artillery": "Operate heavy weapons like mortars or tank cannons with precision.", + "DG.Skills.Tooltip.athletics": "Run, climb, jump, and throw with trained strength and agility.", + "DG.Skills.Tooltip.bureaucracy": "Navigate red tape, cut deals with officials, and get access to restricted resources.", + "DG.Skills.Tooltip.computer_science": "Hack, protect, or manipulate computer systems and recover deleted data.", + "DG.Skills.Tooltip.criminology": "Profile criminal behavior and analyze conspiracies or patterns of illicit activity.", + "DG.Skills.Tooltip.demolitions": "Safely set, disarm, or analyze explosive devices.", + "DG.Skills.Tooltip.disguise": "Alter your appearance and mannerisms to avoid recognition.", + "DG.Skills.Tooltip.dodge": "Evade incoming attacks or scramble to cover.", + "DG.Skills.Tooltip.drive": "Handle vehicles under pressure, including chases and rough terrain.", + "DG.Skills.Tooltip.firearms": "Shoot accurately under pressure with pistols, rifles, and other small arms.", + "DG.Skills.Tooltip.first_aid": "Stabilize injuries and restore HP in the short term.", + "DG.Skills.Tooltip.forensics": "Analyze crime scenes for hidden evidence using forensic methods—or conceal traces of a crime to mislead investigators.", + "DG.Skills.Tooltip.heavy_machiner": "Operate large equipment like cranes, bulldozers, or tanks in high-stress situations.", + "DG.Skills.Tooltip.heavy_weapons": "Use portable heavy arms like LMGs or rocket launchers in combat.", + "DG.Skills.Tooltip.history": "Recall historical facts, obscure references, or find buried knowledge.", + "DG.Skills.Tooltip.humint": "Read people, detect deception, and uncover hidden motives through interaction.", + "DG.Skills.Tooltip.law": "Apply or exploit legal knowledge to win court cases or avoid prosecution.", + "DG.Skills.Tooltip.medicine": "Diagnose and treat injuries or illnesses for long-term care and recovery.", + "DG.Skills.Tooltip.melee_weapons": "Fight effectively in close quarters using knives, clubs, or improvised handheld weapons.", + "DG.Skills.Tooltip.navigate": "Use maps, instruments, or intuition to find your way in unfamiliar terrain.", + "DG.Skills.Tooltip.occult": "Identify myths, rituals, and fringe beliefs—but not separate truth from superstition.", + "DG.Skills.Tooltip.persuade": "Convince others to change their mind or take actions they normally wouldn’t.", + "DG.Skills.Tooltip.pharmacy": "Identify, produce, or misuse drugs, antidotes, and poisons.", + "DG.Skills.Tooltip.psychotherapy": "Diagnose and treat mental disorders; calm or support others under psychological strain.", + "DG.Skills.Tooltip.ride": "Control and care for mounts like horses or camels.", + "DG.Skills.Tooltip.search": "Thoroughly locate concealed objects, traps, or clues in an area.", + "DG.Skills.Tooltip.sigint": "Intercept, encrypt, or manipulate electronic communications and surveillance systems.", + "DG.Skills.Tooltip.stealth": "Avoid detection or hide objects and actions from view.", + "DG.Skills.Tooltip.surgery": "Perform invasive procedures to save lives or repair critical injuries.", + "DG.Skills.Tooltip.survival": "Track, hunt, and stay alive in the wilderness by finding food, shelter, and signs of danger.", + "DG.Skills.Tooltip.swim": "Survive in water under duress—rescue others, escape, or endure hazards.", + "DG.Skills.Tooltip.unarmed_combat": "Subdue or injure opponents using fists, grapples, kicks, and other hand-to-hand techniques.", + "DG.Skills.Tooltip.unnatural": "Recognize, research, or recall truths about entities and forces beyond human understanding.", + + "DG.Skills.AddTypedOrCustomSkill": "Add Typed/Custom Skill", + "DG.Skills.AddSkill": "Add Skill", + "DG.Skills.Apply": "Apply", + "DG.Skills.ApplySkillImprovements.Title": "Apply Skill Improvements", + "DG.Skills.ApplySkillImprovements.ChatFlavor": "Improved the following skills by {formula}:", + "DG.Skills.ApplySkillImprovements.DialogLabel": "Improve skills by the following formula: {formula}", + "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing": "Effects the following skills: {skillList}", + "DG.Skills.ApplySkillImprovements.Warning": "No failed skills to improve.", + "DG.Skills.EditTypedOrCustomSkill": "Edit Typed or Custom Skill", + "DG.Skills.EditSkill": "Edit Skill", + "DG.Skills.SkillGroup": "Skill Group", + "DG.Skills.SkillName": "Skill Name", + + "DG.TypeSkills.Art": "Art", + "DG.TypeSkills.Craft": "Craft", + "DG.TypeSkills.ForeignLanguage": "Foreign Language", + "DG.TypeSkills.MilitaryScience": "Military Science", + "DG.TypeSkills.Pilot": "Pilot", + "DG.TypeSkills.Science": "Science", + "DG.TypeSkills.Other": "Other", + + "DG.TypeSkills.Tooltip.Art": "Create or appraise artistic works, and spot forgeries in a given field.", + "DG.TypeSkills.Tooltip.Craft": "Build, fix, or sabotage specialized tools or systems like engines, locks, or wiring.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Speak, read, and understand a specific language.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Interpret battlefield conditions, tactics, or military behavior in land, sea, or air combat.", + "DG.TypeSkills.Tooltip.Pilot": "Control and navigate air, sea, or space vehicles in critical situations or conditions.", + "DG.TypeSkills.Tooltip.Science": "Apply specialized scientific knowledge to interpret or investigate the physical world.", + "DG.TypeSkills.Tooltip.Other": "Other", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Add Special Training", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Custom/Typed Skills", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Skills", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Statistics", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Edit Special Training", + "DG.SpecialTraining.Dialog.NameLabel": "Name", + "DG.SpecialTraining.Dialog.SkillLabel": "Skill or Stat", + "DG.SpecialTraining.Dialog.Title": "Create/Edit Special Training", + + "DG.Attributes.HP": "HP", + "DG.Attributes.WP": "WP", + "DG.Attributes.SAN": "SAN", + "DG.Attributes.str": "STR", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DEX", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POW", + "DG.Attributes.cha": "CHA", + + "DG.Attributes.Tooltip.HP": "Hit Points (HP) indicate physical health, a character becomes unconsious at 2 HP, and dies at 0 HP.", + "DG.Attributes.Tooltip.WP": "Willpower Points (WP) indicate mental fortitude and drive. Agents require Willpower Points to keep going despite exhaustion or mentally taxing situations. See Page 47 of the Agent's Handbook for more detail.", + "DG.Attributes.Tooltip.SAN": "Sanity Points (SAN) indicate a connection with humanity and reality as most people perceive it. Click to roll a SAN test", + "DG.Attributes.Tooltip.str": "See Page 19 of the Agent's Handbook - Strength", + "DG.Attributes.Tooltip.con": "See Page 19 of the Agent's Handbook - Constitution", + "DG.Attributes.Tooltip.dex": "See Page 19 of the Agent's Handbook - Dexterity", + "DG.Attributes.Tooltip.int": "See Page 19 of the Agent's Handbook - Intelligence", + "DG.Attributes.Tooltip.pow": "See Page 19 of the Agent's Handbook - Power", + "DG.Attributes.Tooltip.cha": "See Page 19 of the Agent's Handbook - Charisma", + + "DG.Navigation.Agent.skills": "Skills", + "DG.Navigation.Agent.physical": "Statistics", + "DG.Navigation.Agent.motivations": "Psychological", + "DG.Navigation.Agent.gear": "Equipment", + "DG.Navigation.Agent.bio": "Bio", + "DG.Navigation.Agent.bonds": "Bonds", + "DG.Navigation.NPC.skills": "Skills & Training", + "DG.Navigation.NPC.gear": "Attacks & Abilities", + "DG.Navigation.Vehicle.gear": "Gear", + "DG.Navigation.Vehicle.notes": "Notes", + + "DG.About.Changelog": "CHANGELOG (ONLINE)", + "DG.About.Copyright": "Published by Arc Dream Publishing by arrangement with the Delta Green Partnership. The intellectual property known as Delta Green is a trademark and copyright owned by the Delta Green Partnership, who has licensed its use here.", + "DG.About.License": "The contents of this system are licensed per the terms of the included license file, excepting those elements that are components of the Delta Green intellectual property.", + "DG.About.OnlineHelp": "System Documentation on (ONLINE)", + "DG.About.OnlineHelpTooltip": "Launch browser with online GitHub help.", + "DG.About.OnlineBugTracker": "Questions, Bug Reports or Feature Requests (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Launch browser with GitHub issue tracker.", + + "DG.Roll.Rolling": "Rolling", + "DG.Roll.Target": "Target: ", + "DG.Roll.Success": "Success", + "DG.Roll.Failure": "Failure", + "DG.Roll.CriticalSuccess": "Critical Success!", + "DG.Roll.CriticalFailure": "Critical Failure!", + "DG.Roll.Lethality": "Lethality", + "DG.Roll.Lethal": "Lethal", + "DG.Roll.For": "For", + "DG.Roll.Damage": "Damage", + "DG.Roll.RollingDamageFor": "Rolling DAMAGE for", + "DG.Roll.Or": "Or", + "DG.Roll.Roll": "Roll", + + "DG.Physical.Wounds": "Wounds", + "DG.Physical.FirstAidLabel": "First Aid Has Already Been Attempted: ", + "DG.Physical.Exhausted": "Exhausted:", + "DG.Physical.ExhaustionPenalty": "Penalty:", + + "DG.Generic.AddButtonLabel": "Add", + + "DG.Mental.BreakingPoint": "Breaking Point: ", + "DG.Mental.Tooltip.BreakingPoint": "When SAN falls to or below this number, Agent gains a long-term mental disorder; set a new Breaking Point to current SAN - POW. Disorders remain even if SAN later rises above a previous Breaking Point.", + "DG.Mental.Reset": "Reset", + "DG.Mental.SanityLossIncidentsLabel": "Incidents of SAN Loss Without Going Insane", + "DG.Mental.Violence": "Violence", + "DG.Mental.Tooltip.Violence": "Adapting to Violence: After losing SAN to violence three times without going insane, you become hardened to it. You automatically succeed SAN rolls against violence, but permanently lose 1D6 CHA and that much from each Bond. Agents Handbook Page 73.", + "DG.Mental.Tooltip.Checkbox.Violence": "When you lose SAN due to violence and without going temporarily insane or hitting your breaking point, increase until adapted. Agents Handbook Page 73.", + "DG.Mental.Helplessness": "Helplessness", + "DG.Mental.Tooltip.Helplessness": "Adapting to Helplessness: After losing SAN to helplessness three times without going insane, you become hardened to it. You automatically succeed SAN rolls against helplessness, but permanently lose 1D6 POW. Agents handbook page 73.", + "DG.Mental.Tooltip.Checkbox.Helplessness": "When you lose SAN due to helplessness and without going temporarily insane or hitting your breaking point, increase until adapted. Agents Handbook Page 73.", + "DG.Mental.AdaptedToViolence": "Adapted to Violence", + "DG.Mental.AdaptedToHelplessness": "Adapted to Helplessness", + "DG.Mental.Motivations": "Motivation", + "DG.Mental.Disorders": "Disorder", + + "DG.Gear.WeaponTypes.Firearms": "Firearms", + "DG.Gear.WeaponTypes.Melee": "Melee", + "DG.Gear.Weapons": "WEAPONS", + "DG.Gear.Armor": "ARMOR", + "DG.Gear.OtherGear": "OTHER GEAR", + "DG.Gear.Name": "Name", + "DG.Gear.DamageOrLethality": "Damage/Lethality", + "DG.Gear.ArmorPiercing": "Armor Piercing", + "DG.Gear.ArmorRating": "Armor Rating", + "DG.Gear.Equipped": "Equipped", + + "DG.CV.Sex": "Sex", + "DG.CV.SexPlaceholder": "Sex", + "DG.CV.AgeAndDoB": "Age and D.O.B.", + "DG.CV.AgeAndDoBPlaceholder": "Age & Date of Birth", + "DG.CV.Employer": "Employer", + "DG.CV.EmployerPlaceholder": "Employer or Work History", + "DG.CV.Nationality": "Nationality", + "DG.CV.NationalityPlaceholder": "Nationality", + "DG.CV.Education": "Education", + "DG.CV.EducationPlaceholder": "Education or Training", + + "DG.Bonds.Bond": "Bond", + "DG.Bonds.Name": "Name", + "DG.Bonds.Score": "Score", + "DG.Bonds.NewBond": "New Bond", + + "DG.Tooltip.MaximumHP": "Maximum health is the average of STR + CON, rounded UP.", + "DG.Tooltip.MaximumWP": "Maximum WP is equal to POW.", + "DG.Tooltip.CurrentSanityPartOne": "Current sanity, current breaking point is ", + "DG.Tooltip.CurrentSanityPartTwo": ", click the SAN label above to roll a sanity check.", + "DG.Tooltip.MaximumSanity": "Maximum sanity is equal to 99 - the Unnatural skill.", + "DG.Tooltip.SkillLabel": "Click to roll a skill check.", + "DG.Tooltip.CannotRollSkillLabel": "A skill at 0% cannot be used. See page 28 of the Agent's Handbook.", + "DG.Tooltip.SkillFailCheckbox": "After failing a test on this skill (if proficiency is at least 1%), check this box. At the end of the session, add 1D4 percentage points to the skill and uncheck the box. Does not apply to the Unnatural or Ritual skill. See Page 29 of the Agent's Handbook.", + "DG.Tooltip.DistinguishingFeature": "Distinguishing Feature (fill out if score is 13 or higher, or 8 or lower).", + "DG.Tooltip.x5AttributeLabel": "Click to roll a x5 check.", + "DG.Tooltip.FirstAidAttempted": "Once an agent receives first aid, they cannot benefit from it again until they receive further damage from a different source.", + "DG.Tooltip.AdaptedToViolence": "Being adapted to violence means your Agent’s empathy suffers as they come to view violence as nothing but another tool to be wielded. Agent permanently loses 1D6 CHA and the same amount from each of their Bonds.", + "DG.Tooltip.AdaptedToHelplessness": "Being adapted to helplessness means your Agent’s personal drive suffers as they pull back from the world around them. As soon as your Agent becomes adapted to helplessness, agent permanently loses 1D6 POW.", + "DG.Tooltip.ToggleEquippedState": "Click to toggle whether this item is equipped or not.", + "DG.Tooltip.Exhaustion": "An Agent who works too long or faces extreme danger and injury without resting becomes exhausted. When this comes into play is up to the Handler, but a good rule of thumb is that going a night without sleep or refusing to rest after losing SAN or Hit Points leads to exhaustion.", + + "DG.Gear.Expense.NA": "N/A or None", + "DG.Gear.Expense.Incidental": "Incidental", + "DG.Gear.Expense.Standard": "Standard", + "DG.Gear.Expense.Unusual": "Unusual", + "DG.Gear.Expense.Major": "Major", + "DG.Gear.Expense.Extreme": "Extreme", + + "DG.ItemWindow.Bonds.Description": "Description/Developments", + "DG.ItemWindow.Bonds.ScoreTooltip": "A higher score represents a stronger relationship between the agent and the bond.", + + "DG.ItemWindow.Motivations.Attributes": "Attributes", + "DG.ItemWindow.Motivations.Motivation": "Motivation", + "DG.ItemWindow.Motivations.Description": "Description/Notes", + "DG.ItemWindow.Motivations.Disorder": "Disorder", + "DG.ItemWindow.Motivations.IsDisorder": "Is Disorder", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Something that drives the character.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "A disorder replaces a motivation after hitting a break point.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Check this if adding a disorder, or if an existing motivation has been lost due to gaining a disorder.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Disorder Has Been \"Cured\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "A critical success on a therapy luck roll can 'cure' a disorder. It may return the next time a breaking point is hit however. See Pages 78-79 of the Agent's Handbook - Therapy.", + + "DG.ItemWindow.Gear.Attributes": "Attributes", + "DG.ItemWindow.Gear.Description": "Description", + "DG.ItemWindow.Gear.NamePlaceholder": "Name", + "DG.ItemWindow.Gear.Expense": "Expense", + "DG.ItemWindow.Gear.Equipped": "Equipped", + + "DG.ItemWindow.Armor.Description": "Description", + "DG.ItemWindow.Armor.NamePlaceholder": "Name", + "DG.ItemWindow.Armor.ArmorRating": "Armor Rating", + "DG.ItemWindow.Armor.Expense": "Expense", + "DG.ItemWindow.Armor.Equipped": "Equipped", + + "DG.ItemWindow.Weapons.Description": "Description", + "DG.ItemWindow.Weapons.NamePlaceholder": "Name", + "DG.ItemWindow.Weapons.Skill": "Skill", + "DG.ItemWindow.Weapons.Expense": "Expense", + "DG.ItemWindow.Weapons.Damage": "Damage", + "DG.ItemWindow.Weapons.Lethality": "Lethality", + "DG.ItemWindow.Weapons.IsLethality": "Is Lethal", + "DG.ItemWindow.Weapons.LethalityTooltip": "A lethal weapon has a chance to instantly kill a target. Roll a D100 instead of damage die. If it is not lethal, damage is dealt instead as if the result was a 2d10 roll, with a '00' on the first d10 equaling a 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Check this if the weapon has a lethality % associated with it.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Armor Piercing", + "DG.ItemWindow.Weapons.Ammo": "Ammo (Amount/Type)", + "DG.ItemWindow.Weapons.Range": "Range", + "DG.ItemWindow.Weapons.KillRadius": "Kill Radius", + + "DG.ModifySkillRollDialogue.Title": "Modify Roll", + "DG.ModifySkillRollDialogue.Test": "Test:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Original Target:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modify Target:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Give a positive or negative modifier here to add/subtract from the target for the skill check.", + + "DG.ModifyDamageRollDialogue.Weapon": "Weapon:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Use this field to modify the outer part of the formula, such as to double the result.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Use this field to add a flat modifier such as '+1' or another dice term such as '+1d4'.", + + "DG.Roll.Inhuman": "Inhuman", + "DG.Tooltip.BreakPoint": "The current breaking point, reset when current sanity falls to or below this value. The starting breaking point is SAN - POW.", + "DG.Tooltip.BreakPointReset": "Reset breaking point to be current SAN - WP.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Roll Mode", + "DG.Bonds.Relationship": "Relationship", + + "DG.TypeSkills.Subskills.Painting": "Painting", + + "DG.Sheet.BlockHeaders.Attributes": "ATTRIBUTES", + "DG.Sheet.BlockHeaders.Statistics": "STATISTICS", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "PHYSICAL DESCRIPTION / NOTES", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "SKILLS AND TRAINING", + "DG.Sheet.BlockHeaders.Injuries": "INJURIES", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "BREAKING POINT AND ADAPTATIONS", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONS AND DISORDERS", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "PERSONAL INFORMATION / CV", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "BONDS / RELATIONSHIPS / CONTACTS", + + "DG.AgentSheet.ProfessionPlaceholder": "PROFESSION (RANK IF APPLICABLE)", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Hide Untrained", + "DG.UnnaturalSheet.NotesLabel": "Notes", + "DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Description of creature or creature type", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Show Untrained", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Skills & Notes", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Attacks & Abilities", + "DG.NPCSheet.BreakPointAbbreviation": "BP", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "I HAVE SEEN THE", + "DG.ImpossibleLanscapes.YellowSign": "YELLOW SIGN", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Corrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "tion", + "DG.ImpossibleLanscapes.Gift": "Gift", + "DG.ImpossibleLanscapes.Insight": "Insight", + + "DG.VehicleSheet.NotesTabName": "Notes", + "DG.VehicleSheet.GearTabName": "Gear", + "DG.VehicleSheet.NotesLabel": "NOTES", + "DG.VehicleSheet.DescriptionPlaceHolder": "Vehicle Description", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Check a damaged Bond's box until the next Home Scene ends.", + "DG.Generic.ClearAll": "Clear Checks", + + "DG.Generic.SanDamage": "SAN Damage", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Target", + "DG.ItemWindow.Weapons.SkillModifier": "Skill Modifier", + "DG.ItemWindow.Custom": "Custom", + + "DG.Sheet.class.item": "Item Sheet", + "DG.Sheet.class.agent": "Agent Sheet", + "DG.Sheet.class.npc": "NPC Sheet", + "DG.Sheet.class.unnatural": "Unnatural Sheet", + "DG.Sheet.class.vehicle": "Vehicle Sheet", + + "TYPES.Actor.agent": "Agent", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "Unnatural", + "TYPES.Actor.vehicle": "Vehicle", + + "TYPES.Item.armor": "Armor", + "TYPES.Item.bond": "Bond", + "TYPES.Item.gear": "Gear", + "TYPES.Item.motivation": "Motivation", + "TYPES.Item.weapon": "Weapon", + "TYPES.Item.tome": "Tome", + "TYPES.Item.ritual": "Ritual", + + "DG.Gear.Tomes": "TOMES", + "DG.Gear.Rituals": "RITUALS", + + "DG.Tomes.Name": "Name", + "DG.Ritual.Name": "Name", + + "DG.Tome.Name": "Name", + "DG.Tome.Language": "Language", + "DG.Tome.StudyTime": "Study Time", + "DG.ItemWindow.Tome.Description": "Description", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Language", + "DG.ItemWindow.Tome.StudyTime": "Study Time", + "DG.ItemWindow.Tome.OccultIncrease": "Occult Skill Increase", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Unnatural Skill Increase", + "DG.ItemWindow.Tome.StudySanityDamage": "Study Sanity Damage", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Handler Only", + "DG.ItemWindow.Tome.HandlerNotes": "Handler Notes", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Activation SAN Damage", + "DG.ItemWindow.Ritual.ActivationTime": "Activation Time", + "DG.ItemWindow.Ritual.ActivationCosts": "Activation Costs", + "DG.ItemWindow.Ritual.StudyTime": "Study Time", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Learn SAN Damage", + + "DG.MissionPaused": "Mission Paused", + + "DG.Settings.charactersheet.name": "Character Sheet Style", + "DG.Settings.charactersheet.hint": "Choose how actor sheets should be styled. 'Program' is a more modern government style, where 'Cowboy/Outlaw' is an older, grittier looking typewriter style.", + "DG.Settings.charactersheet.cowboys": "The Cowboys", + "DG.Settings.charactersheet.outlaws": "The Outlaws", + "DG.Settings.charactersheet.program": "The Program", + "DG.Settings.sortskills.name": "Sort Skills By Column?", + "DG.Settings.sortskills.hint": "Checked sorts by column. Unchecked sorts by row.", + "DG.Settings.skillTooltipDisplay.name": "Display tooltips", + "DG.Settings.skillTooltipDisplay.hint": "Choose when to display skill tooltips in Agent sheets.", + "DG.Settings.skillTooltipDisplay.hover": "On hover (default)", + "DG.Settings.skillTooltipDisplay.never": "Never", + "DG.Settings.skillTooltipDisplay.hoverShift": "On hover + Shift", + "DG.Settings.keepSanityPrivate.name": "Keep Sanity Private", + "DG.Settings.keepSanityPrivate.hint": "Hide sanity from players in both Agent sheets and rolls.", + "DG.Settings.skillImprovementFormula.name": "Default Skill Improvement Roll", + "DG.Settings.skillImprovementFormula.hint": " Default 1d4. There have been multiple errata on this, choose which fits best for the pace of your game.", + "DG.Settings.skillImprovementFormula.1": "Flat +1%", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Show Hypergeometry Section", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Always show Hypergeometry item section (i.e., Rituals and Tomes) on Agent sheets, even if the Agent has no items of those types.", + "DG.Settings.showImpossibleLandscapesContent.name": "Show Impossible Landscapes Content", + "DG.Settings.showImpossibleLandscapesContent.hint": "Show Impossible Landscapes-specific fields in Agent sheets. These fields are only ever visible to the Handler, even if this setting is checked.", + "DG.Settings.skillFailure.name": "Auto-mark Skill Failure", + "DG.Settings.skillFailure.hint": "Activate this setting to always mark a failure checkbox upon failing a skill. The Handler can undo the action from the chat message for the roll.", + "DG.Settings.Saved": "The current settings have been saved.", + + "DG.SettingsMenu.automation.name": "Automation Menu", + "DG.SettingsMenu.automation.label": "Automation Menu", + "DG.SettingsMenu.automation.title": "Automation Settings", + + "DG.SettingsMenu.handler.name": "Handler Settings", + "DG.SettingsMenu.handler.label": "Handler Settings", + "DG.SettingsMenu.handler.title": "Handler-only Settings", + + "DG.Messages.Skillsmark.Marked": "This skill is marked", + "DG.Messages.Skillsmark.Tooltip": "See p. 29 Agent's Handbook" +} diff --git a/lang/es.json b/lang/es.json new file mode 100644 index 0000000..45c1f36 --- /dev/null +++ b/lang/es.json @@ -0,0 +1,431 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "Apellido, nombre, alias o nombre en código", + "DG.RollLuck": "Tira Suerte", + "DG.Luck": "Suerte", + + "DG.FallbackText.newItem": "Nuevo {type}", + + "DG.Skills.accounting": "Contabilidad", + "DG.Skills.alertness": "Alerta", + "DG.Skills.anthropology": "Antropología", + "DG.Skills.archeology": "Arqueología", + "DG.Skills.artillery": "Artillería", + "DG.Skills.athletics": "Atletismo", + "DG.Skills.bureaucracy": "Burocracia", + "DG.Skills.computer_science": "Informática", + "DG.Skills.criminology": "Criminología", + "DG.Skills.demolitions": "Demoliciones", + "DG.Skills.disguise": "Disfraz", + "DG.Skills.dodge": "Esquiva", + "DG.Skills.drive": "Conducción", + "DG.Skills.firearms": "Armas de fuego", + "DG.Skills.first_aid": "Primeros auxilios", + "DG.Skills.forensics": "Ciencia forense", + "DG.Skills.heavy_machiner": "Maquinaria pesada", + "DG.Skills.heavy_weapons": "Armas pesadas", + "DG.Skills.history": "Historia", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Derecho", + "DG.Skills.medicine": "Medicina", + "DG.Skills.melee_weapons": "Armas cuerpo a cuerpo", + "DG.Skills.navigate": "Orientación", + "DG.Skills.occult": "Ocultismo", + "DG.Skills.persuade": "Persuasión", + "DG.Skills.pharmacy": "Farmacia", + "DG.Skills.psychotherapy": "Psicoterapia", + "DG.Skills.ride": "Montar", + "DG.Skills.search": "Búsqueda", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Sigilo", + "DG.Skills.surgery": "Cirugía", + "DG.Skills.survival": "Supervivencia", + "DG.Skills.swim": "Nadar", + "DG.Skills.unarmed_combat": "Combate sin armas", + "DG.Skills.unnatural": "Antinatural", + "DG.Skills.flight": "Volar", + + "DG.Skills.Tooltip.accounting": "El estudio de las finanzas y los negocios. Úsala para localizar anomalías en informes financieros como, por ejemplo, una cuenta bancaria oculta o blanqueo de dinero.", + "DG.Skills.Tooltip.alertness": "La Alerta detecta el peligro. Úsala para escuchar cómo se quita el seguro de un arma, para entender los balbuceos al otro lado de una pared, para detectar el bulto de una pistola debajo de una chaqueta o para atrapar a alguien que está intentando escabullirse mediante Sigilo.", + "DG.Skills.Tooltip.anthropology": "El estudio de las culturas humanas vivas. Úsala para entender valores morales, creencias religiosas y costumbres, y para identificar (pero no traducir) idiomas desconocidos. Mientras que la Historia trata sobre el pasado y la Arqueología estudia los restos físicos, la Antropología trata sobre el comportamiento de las culturas vivas, cómo se relacionan con el resto y su punto de vista acerca de las otras y del pasado.", + "DG.Skills.Tooltip.archeology": "El estudio de los restos físicos de culturas humanas. Úsala para analizar el modo de vida de los pueblos a través de las ruinas, para determinar la antigüedad de un artefacto, para distinguir un artefacto genuino de uno falso y para identificar (pero no traducir) idiomas humanos. Mientras que la Antropología trata sobre las culturas vivas y la Historia es el estudio del pasado, la Arqueología descifra el significado de los restos físicos de pueblos que murieron hace ya tiempo.", + "DG.Skills.Tooltip.artillery": "Uso seguro y preciso de morteros, misiles, obuses, cañones de tanque y otros tipos de armas pesadas. Úsala para destruir tropas o una estructura reforzada en batalla.", + "DG.Skills.Tooltip.athletics": "Tu Agente se entrena para sacar el máximo partido a su fuerza y agilidad. Las características Fuerza y Destreza cubren la potencia física y la pericia manual, mientras que la habilidad Atletismo representa el entrenamiento constante practicando actividades como correr, saltar, escalar y arrojar objetos.
Usa el Atletismo para:
» Dejar atrás a alguien mientras corres (ver PRUEBAS OPUESTAS en la página 45).
» Escalar durante una crisis.
» Aterrizar de manera segura tras una caída de hasta tres metros.
» Acertar en el objetivo lanzando un cuchillo o arrojar una granada exactamente sobre el objetivo.
» Atrapar algo sin previo aviso; por ejemplo, interceptar una granada en el aire.", + "DG.Skills.Tooltip.bureaucracy": "Manipulación de las reglas y personalidades que rigen una organización. Úsala para localizar y obtener suministros, convencer a un oficial de que te proporcione información o recursos, conseguir las credenciales que dan acceso a una zona restringida o evitar que en el hospital se esfuercen demasiado en querer descubrir el origen de tus lesiones.", + "DG.Skills.Tooltip.computer_science": "Conocimiento profundo de ordenadores, sistemas informáticos y los programas que hacen que funcionen. Úsala para recuperar datos borrados o encriptados, proteger documentos, implantar un programa que piratee un sistema de seguridad, clonar una tarjeta SIM de un teléfono, identificar fallos en un sistema de seguridad, suplantar a otros usuarios o falsificar datos. Se suele complementar con SIGINT y con habilidades de Oficio como Electricista o Microelectrónica.", + "DG.Skills.Tooltip.criminology": "Conocimiento del comportamiento delictivo y conspiratorio. Úsala para identificar y predecir un comportamiento delictivo, deducir qué relación tienen varios miembros en una conspiración, analizar actividad delictiva, examinar declaraciones de testigos o saber con quién hablar en los bajos fondos.", + "DG.Skills.Tooltip.demolitions": "Uso seguro de explosivos durante una crisis. Úsala para desactivar una bomba, preparar una carga para destruir un objetivo en remoto, fabricar un explosivo con los suministros de una ferretería o analizar una explosión para determinar qué la causó exactamente. El fracaso al manipular una bomba significa que tu Agente necesita más tiempo. Si está en una crisis que requiere una tirada, una pifia significa que se produce una explosión accidental.", + "DG.Skills.Tooltip.disguise": "Capacidad de tu Agente para alterar su apariencia física, su voz, su postura, su lenguaje corporal y sus gestos para evitar que le reconozcan o pasar sin llamar la atención.", + "DG.Skills.Tooltip.dodge": "Capacidad de evadir el peligro y los ataques a través del instinto y los reflejos. Contra armas de fuego y explosivos, Esquiva puede hacer que un Agente se cubra antes de que lluevan las balas o la metralla (consulta ESQUIVAR ATAQUES A DISTANCIA en la página 54).", + "DG.Skills.Tooltip.drive": "Manejar un automóvil o una motocicleta de manera segura durante una crisis. A no ser que el Supervisor diga lo contrario, todos los Agentes disponen de carné de conducir y pueden conducir un coche de manera segura en condiciones normales. Usa esta habilidad para mantener un vehículo de una pieza durante una persecución a toda velocidad o en terreno peligroso.", + "DG.Skills.Tooltip.firearms": "Permite disparar con armas de fuego personales cortas y largas durante un combate. Úsala para dar en el blanco a pesar de que la adrenalina, el pánico y la conmoción causada por la violencia intenten interferir en la coordinación entre tus manos y tus ojos.", + "DG.Skills.Tooltip.first_aid": "Tratamiento inicial y estabilización de lesiones. Úsala para ayudar a un personaje a recuperar puntos de Salud. En comparación, la Cirugía corrige una herida severa y la Medicina asegura una recuperación a largo plazo (consulta CURACIÓN en la página 55).", + "DG.Skills.Tooltip.forensics": "Recabar información y pruebas detalladas mediante el uso de equipo forense. Úsala para recoger datos biomé- tricos, determinar los detalles sobre el arma usada en una situación o el acelerante empleado para empezar un incendio, percatarse de pistas cruciales que un investigador ordinario no reconocería, limpiar una escena de pruebas incriminatorias u obtener, analizar y comparar huellas dactilares y muestras de ADN.", + "DG.Skills.Tooltip.heavy_machiner": "Manejo seguro de tractores, grúas, excavadoras, tanques, camiones pesados o cualquier otro tipo de máquina grande durante una crisis.", + "DG.Skills.Tooltip.heavy_weapons": "Manejo seguro y preciso de artillería pesada portátil como pueden ser las ametralladoras o los lanzacohetes. Úsala para eliminar enemigos o destruir un vehículo durante un combate.", + "DG.Skills.Tooltip.history": "Descubrir hechos y teorías acerca del pasado de la raza humana. Úsala para recordar o encontrar un hecho clave sobre el pasado lejano, reconocer una referencia incierta, o indagar en una base de datos o biblioteca en busca de información que nadie sin tu extensa educación podría encontrar. Mientras que la Antropología se basa en las culturas vivas y la Arqueología estudia el significado de reliquias antiguas, la Historia es un estudio amplio de la humanidad.", + "DG.Skills.Tooltip.humint": "Inteligencia humana. Esta habilidad obtiene información de un sujeto (especialmente información que el sujeto querría ocultar) a través de la observación, la conversación o el estudio de patrones de comportamiento y relaciones. Usa HUMINT para reconocer señales de falsedad en expresiones verbales o lenguaje corporal, valorar una actitud o unas intenciones, cultivar fuentes de información acerca de un sujeto, determinar qué haría falta para que un sujeto coopere o reconocer pistas de lo que un sujeto está tratando de ocultar. HUMINT puede detectar signos de enfermedad mental, pero haría falta la Psicoterapia para diagnosticar y tratar una dolencia concreta. Si tu Agente también dispone de Criminología, se puede usar HUMINT para trazar un perfil psicológico que ayude a dar con un sujeto. Un sujeto que esté tratando de engañar a tu Agente deliberadamente puede hacer una prueba de Persuasión para oponerse al HUMINT de tu Agente (consulta PRUEBAS OPUESTAS en la página 45).", + "DG.Skills.Tooltip.law": "Usar leyes y juzgados en favor de tu Agente. Úsala para hacer que tu Agente se salga con la suya ante un tribunal, determinar los procedimientos correctos a la hora de manipular pruebas durante un juicio o un proceso legal (y saber cómo invalidarlas), conseguir que tu Agente se libre de problemas legales o minimizar los riesgos legales. La habilidad Derecho se aplica al país de origen de tu Agente; usarla con las leyes de otro país requiere formación especial (consulta la página 30).", + "DG.Skills.Tooltip.medicine": "El estudio y tratamiento de heridas y enfermedades. Úsala para determinar la causa de una lesión, una enfermedad o un envenenamiento; identificar anormalidades como toxinas o enfermedades; identificar la causa y hora aproximada de una muerte; identificar el tipo de arma que se usó para asesinar a una víctima; identificar lo último que comió una persona o recetar el remedio adecuado a largo plazo. En comparación, Primeros auxilios mantiene a un paciente con vida hasta que se le pueda aplicar cirugía, y Cirugía sana una herida severa (consulta CURACIÓN en la página 55).", + "DG.Skills.Tooltip.melee_weapons": "Uso letal de armas cuerpo a cuerpo en combate. Úsala para herir o acabar con un oponente mediante un cuchillo, un hacha, un garrote o cualquier otra arma cuerpo a cuerpo.", + "DG.Skills.Tooltip.navigate": "Situarte rápidamente mediante el uso de mapas, cartas de navegación y tablas o instrumentos, ya sea mientras tratas de orientarte o mientras te desplazas a ciegas basándote en tu instinto.", + "DG.Skills.Tooltip.occult": "El estudio de lo sobrenatural tal y como es concebido por las tradiciones humanas; incluye las teorías de la conspiración, el ocultismo tradicional, la ciencia marginal y la criptozoología. Usa el Ocultismo para examinar y deducir las intenciones de un ritual o para identificar tradiciones, grupos, grimorios, herramientas, símbolos o leyendas de naturaleza mística. El Ocultismo nunca puede distinguir la superstición o la mitología de lo auténticamente antinatural; de eso se ocupa la habilidad Antinatural.", + "DG.Skills.Tooltip.persuade": "Cambiar una decisión firme o un deseo en otra persona. Usa Persuasión cuando tu Agente quiera salirse con la suya ante un sujeto tan terco, conseguir algo tan valioso o tener éxito con un engaño tan flagrante que no baste con el Carisma. Con Persuasión tu Agente podría convencer a una testigo de que lo que vio era inocuo y no antinatural, engatusar a un detective para que le ayude a encubrir pruebas por un bien mayor, u obtener información útil de un sujeto que no quiere colaborar. Esta habilidad también permite que tu Agente oponga resistencia a la persuasión y el interrogatorio con una tirada opuesta de Persuasión (consulta TIRADAS OPUESTAS en la página 45).", + "DG.Skills.Tooltip.pharmacy": "Conocimientos sobre drogas, desde sus ingredientes y elaboración, hasta sus efectos y usos, tanto correctos como incorrectos. Úsala para identificar y producir medicinas y antídotos, así como venenos. Identificar una droga requiere al menos un 20% en la habilidad. Preparar de manera segura una droga especialmente potente (como podría ser una con efectos psicoactivos) requiere al menos un 40% en la habilidad o una tirada con éxito. Usar Farmacia de manera incorrecta es un modo rápido de acabar con un paciente (ver VENENOS Y ENFERMEDADES en la página 60).", + "DG.Skills.Tooltip.psychotherapy": "Diagnóstico y tratamiento de enfermedades mentales. Úsala para identificar un trastorno psicológico, ayudar a que un paciente se recupere, calmar a alguien cuando empiece a mostrar síntomas de un trastorno o tratar una enfermedad mental a largo plazo. No puedes usar la Psicoterapia sobre ti mismo. Usar la Psicoterapia para ayudar a alguien que ha sufrido exposición a fuerzas antinaturales podría costar COR al terapeuta (consulta AMENAZAS A LA CORDURA en la página 67).", + "DG.Skills.Tooltip.ride": "Manejar, adiestrar y montar en caballos, burros, camellos y otras bestias. Las monturas exóticas podrían requerir formación especial (consultar página 30). Usa Montar para permanecer sobre una montura durante una crisis y para mantener a los animales sanos y tranquilos.", + "DG.Skills.Tooltip.search": "Capacidad de encontrar a primera vista cosas ocultas o escondidas. Registrar una escena podría no requerir la habilidad Búsqueda, solo tiempo y esfuerzo o una INT lo suficientemente alta. Usa Búsqueda para encontrar un objeto que fue escondido mediante la habilidad Sigilo, o que esté a tan buen recaudo que sea necesario un experto. El Supervisor podría hacer la tirada de Búsqueda de manera que no sepas si tu Agente ha tenido éxito o ha fracasado.", + "DG.Skills.Tooltip.sigint": "Inteligencia de las señales. Abarca la encriptación, la inteligencia de las comunicaciones, la inteligencia electrónica, los sistemas de seguridad electrónicos, la estrecha vigilancia de comunicaciones de radio o digitales y la creación y descifrado de códigos. Úsala para instalar micrófonos ocultos o para encontrarlos y desactivarlos, para comunicarte en código Morse, para manejar equipo de vigilancia, etc.", + "DG.Skills.Tooltip.stealth": "Ocultar tu presencia o tus actividades. Úsala para esconder una pistola, camuflar una posición, ocultar un micrófono, soltar un sobre en una entrega sin que nadie se percate, robar la cartera a alguien, moverte en silencio, seguir a alguien sin que te descubran o fundirte en una multitud. Un Agente que intenta usar Sigilo solo puede ser detectado por una prueba opuesta de Búsqueda o Alerta (consulta PRUEBAS OPUESTAS en la página 45).", + "DG.Skills.Tooltip.surgery": "El tratamiento de una lesión o anormalidad a través de métodos invasivos. En comparación, Primeros auxilios mantiene a un paciente con vida hasta que la cirugía sea posible y Medicina asegura la recuperación a largo plazo (consultar CURACIÓN en la página 55).", + "DG.Skills.Tooltip.survival": "Conocimiento del mundo natural. Úsala para encontrar rastros y senderos, planear una expedición, predecir el clima, reconocer flora o fauna fuera de lo común, valerte del entorno para reunir información o encontrar comida, agua y refugio.", + "DG.Skills.Tooltip.swim": "La mayoría de los Agentes saben nadar como pasatiempo. Usa la habilidad Natación durante una crisis peligrosa: recorrer una larga distancia en aguas movidas, evitar que alguien se ahogue o subirte a un barco antes de que la cosa con tentáculos de ahí debajo te agarre.", + "DG.Skills.Tooltip.unarmed_combat": "Autodefensa. Una pelea entre combatientes no entrenados a menudo implica más empujones y gritos que violencia real. Usa el Combate sin armas para lastimar o matar a un oponente con las manos de tu Agente (o los pies, codos, dientes o cabeza).", + "DG.Skills.Tooltip.unnatural": "Conocimiento acerca de los secretos más fundamentales y desgarradores del universo. Úsala para recordar, reconocer o investigar hechos sobre todo aquello que los humanos consideran antinatural. Esto va mucho más allá del ocultismo, porque la habilidad Antinatural representa cosas que existen de verdad. Utilízala para poder filtrar información de los confines más oscuros de los mitos y el folclore y reconocer qué partes son ciertas. El valor de COR de tu Agente nunca puede ser superior a 99 menos su valor de habilidad Antinatural.", + + "DG.Skills.AddTypedOrCustomSkill": "Añadir tipo o habilidad personalizada", + "DG.Skills.AddSkill": "Añadir habilidad", + "DG.Skills.Apply": "Aplicar", + "DG.Skills.ApplySkillImprovements.Title": "Aplicar mejoras de habilidad", + "DG.Skills.ApplySkillImprovements.ChatFlavor": "Mejoradas las siguientes habilidades en {formula}:", + "DG.Skills.ApplySkillImprovements.DialogLabel": "Mejorar habilidades según la formula siguiente: {formula}", + "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing": "Afecta a las habilidades siguientes: {skillList}", + "DG.Skills.ApplySkillImprovements.Warning": "No hay habilidades falladas que mejorar.", + "DG.Skills.EditTypedOrCustomSkill": "Editar habilidad personalizada o de tipo", + "DG.Skills.EditSkill": "Editar habilidad", + "DG.Skills.SkillGroup": "Habilidad de grupo", + "DG.Skills.SkillName": "Nombre de la habilidad", + + "DG.TypeSkills.Art": "Arte", + "DG.TypeSkills.Craft": "Oficio", + "DG.TypeSkills.ForeignLanguage": "Idioma extranjero", + "DG.TypeSkills.MilitaryScience": "Ciencias militares", + "DG.TypeSkills.Pilot": "Pilotar", + "DG.TypeSkills.Science": "Ciencia", + "DG.TypeSkills.Other": "Otra", + + "DG.TypeSkills.Tooltip.Art": "Pericia en la creación o representación de una obra que genera emoción y opinión. También incluye el conocimiento de técnicas y tendencias en tu campo, y la capacidad de distinguir las piezas reales de las falsas de un creador concreto. Cualquiera puede dibujar un boceto, pero la habilidad Arte refleja conocimiento, práctica y talento. Cada tipo de Arte es una habilidad independiente: Actuación, Canto, Danza, Escritura creativa, Escritura de guiones, Escultura, Falsificación, Flauta, Guitarra, Pintura, Poesía, Violín, etc.", + "DG.TypeSkills.Tooltip.Craft": "Creación y reparación de herramientas y estructuras sofisticadas. Un trabajo que la mayoría de gente podría averiguar cómo se hace no requiere la habilidad Oficio, solo una prueba de INT o DES. Usa Oficio para el trabajo especializado que requiere formación: Oficio (Electricista) para cambiar el cableado a una casa, hacer el puente a un vehículo con rapidez, intervenir un teléfono o una línea de datos o identificar señales de sabotaje eléctrico; Oficio (Mecánica) para ensamblar apresuradamente una máquina o hacer que un motor averiado vuelva a funcionar… o para sabotear uno de manera que no se pueda volver a reparar; Oficio (Cerrajería) para abrir una cerradura sin la llave; Oficio (Armería) para reparar un arma de fuego estropeada. El Supervisor decide si una tarea concreta requiere un Oficio o no. Cada tipo de Oficio es una habilidad independiente: Armería, Arquitectura, Carpintería, Cerrajería, Electricista, Fontanería, Mecánica, Microelectrónica, etc.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Soltura con otro idioma. Cada idioma extranjero es una habilidad independiente. Tener un 20% permite comunicar ideas sencillas; al llegar a 50%, tu Agente habla y lee como un nativo. Cuanto mayor es el valor de tu habilidad, mayor es la complejidad de información que tu Agente comprende y menor el tiempo que necesita para ello. No necesitas tirar los dados a no ser que el Supervisor diga que la situación es excepcionalmente difícil. A discreción del Supervisor, tener formación especial podría permitir el uso de la misma habilidad con un idioma de la misma familia.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Conocimiento de la cultura militar, sus técnicas y sus regulaciones. Úsala para identificar amenazas en un campo de batalla, determinar alcances precisos, reconocer puntos débiles en una fortificación, deducir el nivel de entrenamiento de un soldado o una unidad, reconstruir los sucesos de una batalla o desplegar fuerzas de manera ventajosa en combate. Cada tipo de Ciencia militar es una habilidad independiente. Los tipos más comunes son Tierra, Mar y Aire.", + "DG.TypeSkills.Tooltip.Pilot": "Pilotar, manejar y capitanear vehículos marítimos, aéreos o espaciales. Úsala para mantener una nave a salvo en una crisis como, por ejemplo, una tormenta o una persecución peligrosa. Cada tipo de nave es una habilidad independiente: Avión, Dron, Helicóptero, Barca, Barco, Lanzadera espacial, etc. A discreción del Supervisor, la habilidad con un tipo de nave podría permitir pilotar otro tipo de nave relacionado.", + "DG.TypeSkills.Tooltip.Science": "El estudio profundo de los procesos que rigen nuestro mundo. Esta habilidad implica más que la educación común del colegio: cualquier persona puede hacer una prueba de INT para recordar algo de una clase del instituto. La Ciencia se usa para dar con un conocimiento clave sobre el modo en que funciona el universo… o, al menos, el modo en que debería funcionar. Cada Ciencia es una habilidad independiente: Astronomía, Biología, Botánica, Ciencias Planetarias, Física, Genética, Geología, Ingeniería, Matemáticas, Meteorología, Química, Zoología, etc.", + "DG.TypeSkills.Tooltip.Other": "Otra", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Añadir entrenamiento especial", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Habilidades personalizadas/de tipo", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Habilidades", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Características", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Editar entrenamiento especial", + "DG.SpecialTraining.Dialog.NameLabel": "Nombre", + "DG.SpecialTraining.Dialog.SkillLabel": "Habilidad o característica", + "DG.SpecialTraining.Dialog.Title": "Crear/editar entrenamiento especial", + + "DG.Attributes.HP": "Puntos de salud (PS)", + "DG.Attributes.WP": "Puntos de voluntad (PV)", + "DG.Attributes.SAN": "Puntos de Cordura (COR)", + "DG.Attributes.str": "FUE", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DES", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POD", + "DG.Attributes.cha": "CAR", + + "DG.Attributes.Tooltip.HP": "Los puntos de Salud representan la cantidad de daño que tu Agente puede soportar. Cuando resulte herido, resta el daño de sus PS. Cuando tu Agente llegue a 2 PS, queda inconsciente. Cuando tu Agente llegue a 0 PS, muere. Los puntos de Salud se pueden recuperar mediante reposo y atención médica.", + "DG.Attributes.Tooltip.WP": "Los puntos de Voluntad representan la fortaleza mental, y disminuyen cuando tu Agente trata de suprimir los síntomas de las enfermedades mentales (consulta RESISTIRSE A LA DEMENCIA en la página 73), cuando acaba agotado (consulta AGOTAMIENTO en la página 47), cuando intenta resistir contra la persuasión (consulta INTERROGATORIO en la página 168), cuando acaba quemado a nivel emocional (consulta PIFIA en la página 44) o cuando trata de avivar fenómenos antinaturales. Cuando tu Agente llegue a 2 PV, sufre un colapso emocional transitorio. Cuando tu Agente llegue a 0 PV, queda inconsciente. Los puntos de Voluntad se pueden recuperar mediante el reposo (consulta PUNTOS DE VOLUNTAD en la página 47).", + "DG.Attributes.Tooltip.SAN": "Los puntos de Cordura representan la salud mental o, dicho de otra manera, la cantidad de traumas psicológicos o exposición a lo Antinatural que tu Agente puede soportar antes de caer en la demencia. En los momentos de trauma psicológico, tu Agente debe hacer una prueba de Cordura buscando un resultado igual o inferior a su COR con 1D100. Si la tirada falla, tu Agente pierde COR (consulta CORDURA en la página 64). Los puntos de Cordura se pueden recuperar mediante terapia psiquiátrica o la neutralización de amenazas antinaturales. Cuando tu Agente baje hasta los 0 puntos de Cordura, entra en un estado de demencia irreversible y se convierte en un PNJ de manera permanente bajo el control del Supervisor.", + "DG.Attributes.Tooltip.str": "Potencia física, tamaño y musculatura.", + "DG.Attributes.Tooltip.con": "Salud y resiliencia física.", + "DG.Attributes.Tooltip.dex": "Agilidad, coordinación y ligereza.", + "DG.Attributes.Tooltip.int": "La capacidad de un Agente para recordar, conectar o darse cuenta de las cosas. Junto a su profesión, indica su educación y brillantez en general.", + "DG.Attributes.Tooltip.pow": "Fuerza de personalidad, motivación y resiliencia física.", + "DG.Attributes.Tooltip.cha": "Encanto, liderazgo y atractivo personal. Podría indicar atractivo físico.", + + "DG.Navigation.Agent.skills": "Habilidades", + "DG.Navigation.Agent.physical": "Características", + "DG.Navigation.Agent.motivations": "Salud mental", + "DG.Navigation.Agent.gear": "Equipo", + "DG.Navigation.Agent.bio": "Trasfondo", + "DG.Navigation.Agent.bonds": "Lazos", + "DG.Navigation.NPC.skills": "Habilidades y entrenamiento", + "DG.Navigation.NPC.gear": "Ataques y atributos", + "DG.Navigation.Vehicle.gear": "Equipo", + "DG.Navigation.Vehicle.notes": "Notas", + + "DG.About.Changelog": "Registro de cambios (en línea)", + "DG.About.Copyright": "Publicado por Arc Dream Publishing de acuerdo a la Delta Green Partnership. La propiedad intelectual conocida como Delta Green es una marca comercial y derechos de autor de la Delta Green Partnership, que ha licenciado su uso en este sistema.", + "DG.About.License": "Los contenidos de este sistema están licenciados según los términos incluidos en este documento, excepto aquellos elementos que son parte de la propiedad intelectual de Delta Green.", + "DG.About.OnlineHelp": "Documentación del sistema", + "DG.About.OnlineHelpTooltip": "Abre la página de GitHub en el navegador con la página de ayuda.", + "DG.About.OnlineBugTracker": "Preguntas, errores y petición de nuevas funcionalidades.", + "DG.About.OnlineBugTrackerTooltip": "Abre la página de GitHub en el navegador con la página de notificación de errores.", + + "DG.Roll.Rolling": "Tirando", + "DG.Roll.Target": "Objetivo: ", + "DG.Roll.Success": "Éxito", + "DG.Roll.Failure": "Fallo", + "DG.Roll.CriticalSuccess": "¡Crítico!", + "DG.Roll.CriticalFailure": "¡Pífia!", + "DG.Roll.Lethality": "Letalidad", + "DG.Roll.Lethal": "Letal", + "DG.Roll.For": "Para", + "DG.Roll.Damage": "Daño", + "DG.Roll.RollingDamageFor": "Tirando daño para", + "DG.Roll.Or": "O", + "DG.Roll.Roll": "Tirar", + + "DG.Physical.Wounds": "Heridas", + "DG.Physical.FirstAidLabel": "Ya se han aplicado primeros auxilios: ", + "DG.Physical.Exhausted": "Exhausto:", + "DG.Physical.ExhaustionPenalty": "Penalizador:", + + "DG.Generic.AddButtonLabel": "Añadir", + + "DG.Mental.BreakingPoint": "Punto de ruptura: ", + "DG.Mental.Tooltip.BreakingPoint": "Cuando se falla una tirada de COR y la tirada es igual o está por debajo de este valor, el Agente gana un nuevo trastorno mental; ajusta el nuevo punto de ruptura a la COR actual - POD. Los trastornos se mantienen incluso si la COR vuelve a subir por encima del punto de ruptura anterior.", + "DG.Mental.Reset": "Borrar", + "DG.Mental.SanityLossIncidentsLabel": "Incidentes de perdida de COR sin llegar a la demencia", + "DG.Mental.Violence": "Violencia", + "DG.Mental.Tooltip.Violence": "Adaptándose a la violencia: tras perder COR tres veces debido a la violencia sin volverte loco te endureces. Tienes éxito automáticamente en las tiradas de COR por violencia, pero pierdes permanentemente 1D6 CAR y la misma cantidad de cada Lazo. Manual del agente, página 73.", + "DG.Mental.Helplessness": "Indefensión", + "DG.Mental.Tooltip.Helplessness": "Adaptándose a la indefensión: tras perder COR tres veces debido a la indefensión sin volverte loco te endureces. Tienes éxito automáticamente en las tiradas de COR por indefensión, pero pierdes permanentemente 1D6 POD. Manual del agente, página 73.", + "DG.Mental.AdaptedToViolence": "Adaptado a la violencia", + "DG.Mental.AdaptedToHelplessness": "Adaptado a la indefensión", + "DG.Mental.Motivations": "Motivaciones", + "DG.Mental.Disorders": "Desórdenes", + + "DG.Gear.WeaponTypes.Firearms": "Armas de fuego", + "DG.Gear.WeaponTypes.Melee": "Cuerpo a cuerpo", + "DG.Gear.Weapons": "ARMAS", + "DG.Gear.Armor": "ARMADURA", + "DG.Gear.OtherGear": "OTRO EQUIPO", + "DG.Gear.Name": "Nombre", + "DG.Gear.DamageOrLethality": "Daño/letalidad", + "DG.Gear.ArmorPiercing": "Perforación de armadura", + "DG.Gear.ArmorRating": "Clasificación de armadura", + "DG.Gear.Equipped": "Equipado", + + "DG.CV.Sex": "Género", + "DG.CV.SexPlaceholder": "Género", + "DG.CV.AgeAndDoB": "Edad y f. de nac.", + "DG.CV.AgeAndDoBPlaceholder": "Edad y fecha de nacimiento", + "DG.CV.Employer": "Empleador", + "DG.CV.EmployerPlaceholder": "Empleador y vida laboral", + "DG.CV.Nationality": "Nacionalidad", + "DG.CV.NationalityPlaceholder": "Nacionalidad", + "DG.CV.Education": "Educación", + "DG.CV.EducationPlaceholder": "Educación y entrenamiento", + + "DG.Bonds.Bond": "Lazo", + "DG.Bonds.Name": "Nombre", + "DG.Bonds.Score": "Valor", + "DG.Bonds.NewBond": "Nuevo lazo", + + "DG.Tooltip.MaximumHP": "La salud máxima es el promedio de FUE + CON, redondeado hacia arriba.", + "DG.Tooltip.MaximumWP": "Los puntos de voluntad máximos son iguales al POD.", + "DG.Tooltip.CurrentSanityPartOne": "Cordura actual, el punto de ruptura actual es ", + "DG.Tooltip.CurrentSanityPartTwo": ", haga clic en la etiqueta COR anterior para realizar una tirada de Cordura.", + "DG.Tooltip.MaximumSanity": "La cordura máxima es igual a 99 - la habilidad Antinatural.", + "DG.Tooltip.SkillLabel": "Clic para hacer una tirada de habilidad.", + "DG.Tooltip.CannotRollSkillLabel": "No se puede usar una habilidad al 0%. Consulte la página 28 del Manual del Agente.", + "DG.Tooltip.SkillFailCheckbox": "Después de fallar una prueba de esta habilidad (si el dominio es de al menos 1%), marque esta casilla. Al final de la sesión, sume 1D4-1 puntos porcentuales a la habilidad y desmarque la casilla. No se aplica a la habilidad Antinatural. Consulte la página 29 del Manual del Agente.", + "DG.Tooltip.DistinguishingFeature": "Característica distintiva (rellene si la puntuación es 13 o superior, u 8 o inferior).", + "DG.Tooltip.x5AttributeLabel": "Clic para una tirada x5.", + "DG.Tooltip.FirstAidAttempted": "Una vez que un agente recibe primeros auxilios, no puede beneficiarse de él de nuevo hasta que reciba más daños de una fuente diferente.", + "DG.Tooltip.AdaptedToViolence": "Adaptarse a la violencia significa que la empatía de su agente sufre al ser testigo de tanta violencia. Pierde permanentemente 1D6 CAR y la misma cantidad de cada uno de sus lazos.", + "DG.Tooltip.AdaptedToHelplessness": "Estar adaptado a la indefensión significa que el impulso personal de su Agente sufre cuando se aleja del mundo que lo rodea. Tan pronto como su Agente se adapte a la indefensión, perderá permanentemente 1D6 POD.", + "DG.Tooltip.ToggleEquippedState": "Haga clic para alternar si este artículo está equipado o no.", + "DG.Tooltip.Exhaustion": "Un Agente que trabaja demasiado o se enfrenta a peligros extremos sin descansar queda exhausto. El que ocurra o no queda a criterio del Controlador, pero como guía, cualquiera que permanezca despierto toda la noche sin dormir o no descanse tras haber perdido COR o puntos de vida quedará exhausto.", + + "DG.Gear.Expense.NA": "N/A o ninguno", + "DG.Gear.Expense.Incidental": "Imprevisto", + "DG.Gear.Expense.Standard": "Corriente", + "DG.Gear.Expense.Unusual": "Extraordinario", + "DG.Gear.Expense.Major": "Considerable", + "DG.Gear.Expense.Extreme": "Extremo", + + "DG.ItemWindow.Bonds.Description": "Descripción/desarrollo", + "DG.ItemWindow.Bonds.ScoreTooltip": "Una puntuación más alta representa una relación más fuerte entre el agente y el lazo.", + + "DG.ItemWindow.Motivations.Attributes": "Atributos", + "DG.ItemWindow.Motivations.Motivation": "Motivación", + "DG.ItemWindow.Motivations.Description": "Descripción/notas", + "DG.ItemWindow.Motivations.Disorder": "Trastorno", + "DG.ItemWindow.Motivations.IsDisorder": "Trastorno", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Algo que impulsa al personaje.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Un trastorno reemplaza una motivación después de llegar al punto de ruptura.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Marque esta opción si agrega un trastorno o si se ha perdido una motivación existente debido a la adquisición de un trastorno.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "El trastorno ha sido curado.", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un éxito crítico en una tirada de suerte terapéutica puede 'curar' un trastorno. Sin embargo, puede regresar la próxima vez que se alcance un punto de ruptura. Consulte la sección Ir a terapia en las páginas 78-79 del Manual del Agente.", + + "DG.ItemWindow.Gear.Attributes": "Atributos", + "DG.ItemWindow.Gear.Description": "Descripción", + "DG.ItemWindow.Gear.NamePlaceholder": "Nombre", + "DG.ItemWindow.Gear.Expense": "Gasto", + "DG.ItemWindow.Gear.Equipped": "Equipado", + + "DG.ItemWindow.Armor.Description": "Descripción", + "DG.ItemWindow.Armor.NamePlaceholder": "Nombre", + "DG.ItemWindow.Armor.ArmorRating": "Armadura", + "DG.ItemWindow.Armor.Expense": "Gasto", + "DG.ItemWindow.Armor.Equipped": "Equipado", + + "DG.ItemWindow.Weapons.Description": "Descripción", + "DG.ItemWindow.Weapons.NamePlaceholder": "Nombre", + "DG.ItemWindow.Weapons.Skill": "Habilidad", + "DG.ItemWindow.Weapons.Expense": "Gasto", + "DG.ItemWindow.Weapons.Damage": "Daño", + "DG.ItemWindow.Weapons.Lethality": "Letalidad", + "DG.ItemWindow.Weapons.IsLethality": "Letal", + "DG.ItemWindow.Weapons.LethalityTooltip": "Un arma letal tiene la oportunidad de matar instantáneamente a un objetivo. Tira 1D100 en lugar de un dado de daño. Si no es letal, el daño se calcula en su lugar tirando 2d10, donde un '00' en el primer d10 es igual a 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Marca si el arma tiene un % de letalidad asociada.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Perforación", + "DG.ItemWindow.Weapons.Ammo": "Munición (cantidad/tipo)", + "DG.ItemWindow.Weapons.Range": "Alcance", + "DG.ItemWindow.Weapons.KillRadius": "Radio muerte", + + "DG.ModifySkillRollDialogue.Title": "Modificar tirada", + "DG.ModifySkillRollDialogue.Test": "Tirada", + "DG.ModifySkillRollDialogue.OriginalTarget": "Valor original", + "DG.ModifySkillRollDialogue.TargetModifier": "Modificador", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Dar un modificador positivo o negativo aquí para sumar o restar al objetivo en la chequeo de habilidades.", + + "DG.ModifyDamageRollDialogue.Weapon": "Arma:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Utilice este campo para modificar la fórmula, como duplicar el resultado.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Utilice este campo para añadir un modificador como '+1' u otro término como '+1d4'.", + + "DG.Roll.Inhuman": "Inhumano", + "DG.Tooltip.BreakPoint": "El punto de ruptura actual, actualizar cuando la Cordura actual sea igual o inferior a este valor. El punto de ruptura inicial es COR - POD.", + "DG.Tooltip.BreakPointReset": "Actualizar el Punto de Ruptura al valor actual de COR - PVol.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Modo de tirada", + "DG.Bonds.Relationship": "Relación", + + "DG.TypeSkills.Subskills.Painting": "Pintar", + + "DG.Sheet.BlockHeaders.Attributes": "ATRIBUTOS", + "DG.Sheet.BlockHeaders.Statistics": "CARACTERÍSTICAS", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "DESCRIPCIÓN FÍSICA Y NOTAS", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "HABILIDADES Y ENTRENAMIENTO", + "DG.Sheet.BlockHeaders.Injuries": "HERIDAS", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "PUNTO DE RUPTURA Y ADAPTACIONES", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVACIONES Y TRANSTORNOS MENTALES", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "INFORMACIÓN PERSONAL Y CURRÍCULO", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "LAZOS, RELACIONES Y CONTACTOS", + + "DG.AgentSheet.ProfessionPlaceholder": "Profesión (rango, si es necesario)", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Ocultar habilidades no entrenadas", + "DG.UnnaturalSheet.NotesLabel": "Notas", + "DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Descripción de la criatura o tipo", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Mostrar no entrenadas", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Habilidades & notas", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Ataques & habilidades", + "DG.NPCSheet.BreakPointAbbreviation": "PR", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "He visto el ", + "DG.ImpossibleLanscapes.YellowSign": "Signo Amarillo", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Corrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "ción", + "DG.ImpossibleLanscapes.Gift": "Don", + "DG.ImpossibleLanscapes.Insight": "Visión", + + "DG.VehicleSheet.NotesTabName": "Notas", + "DG.VehicleSheet.GearTabName": "Equipo", + "DG.VehicleSheet.NotesLabel": "Notas", + "DG.VehicleSheet.DescriptionPlaceHolder": "Descripción del vehículo", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Marca el cuadro de comprobación de lazo dañado hasta que termine la próxima escena de hogar.", + "DG.Generic.ClearAll": "Borrar todo", + + "DG.Generic.SanDamage": "Daño COR", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Objetivo", + "DG.ItemWindow.Weapons.SkillModifier": "Mod. habilidad", + "DG.ItemWindow.Custom": "Personalizado", + + "DG.Sheet.class.item": "Hoja de objeto", + "DG.Sheet.class.agent": "Hoja de agente", + "DG.Sheet.class.npc": "Hoja de PNJ", + "DG.Sheet.class.unnatural": "Hoja de antinatural", + "DG.Sheet.class.vehicle": "Hoja de vehículo", + + "TYPES.Actor.agent": "Agente", + "TYPES.Actor.npc": "PNJ", + "TYPES.Actor.unnatural": "Antinatural", + "TYPES.Actor.vehicle": "Vehículo", + + "TYPES.Item.armor": "Armadura", + "TYPES.Item.bond": "Lazo", + "TYPES.Item.gear": "Equipo", + "TYPES.Item.motivation": "Motivación", + "TYPES.Item.weapon": "Arma", + "TYPES.Item.tome": "Tomo", + "TYPES.Item.ritual": "Ritual", + + "DG.Gear.Tomes": "TOMOS", + "DG.Gear.Rituals": "RITUALES", + + "DG.Tomes.Name": "Nombre", + "DG.Ritual.Name": "Nombre", + + "DG.Tome.Name": "Nombre", + "DG.Tome.Language": "Idioma", + "DG.Tome.StudyTime": "Tiempo de estudio", + "DG.ItemWindow.Tome.Description": "Descripción", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Idioma", + "DG.ItemWindow.Tome.StudyTime": "Tiempo de estudio", + "DG.ItemWindow.Tome.OccultIncrease": "Incremento de % ocultismo", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Incremento de % sobrenatural", + "DG.ItemWindow.Tome.StudySanityDamage": "Pérdida de Cordura al estudiarlo", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Datos | Controlador", + "DG.ItemWindow.Tome.HandlerNotes": "Notas | Controlador", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "COR activación", + "DG.ItemWindow.Ritual.ActivationTime": "Tiempo de activación", + "DG.ItemWindow.Ritual.ActivationCosts": "Coste de activación", + "DG.ItemWindow.Ritual.StudyTime": "Tiempo de estudio", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "COR aprendizaje", + + "DG.MissionPaused": "Misión en pausa", + + "DG.Settings.charactersheet.name": "Estilo de hoja de personaje", + "DG.Settings.charactersheet.hint": "Elegir el estilo de las hojas de personaje. 'Programa' se ajusta a una agencia gubernamental moderna, mientras que 'Vaquero/Forajido' es antiguo, crudo, estilo vieja máquina de escribir.", + "DG.Settings.charactersheet.cowboys": "Los vaqueros", + "DG.Settings.charactersheet.outlaws": "Los forajidos", + "DG.Settings.charactersheet.program": "El programa", + "DG.Settings.sortskills.name": "Ordenar habilidades por columna", + "DG.Settings.sortskills.hint": "Si se habilita, se ordena por columna. Si no, se ordena por fila.", + "DG.Settings.skillTooltipDisplay.name": "Mostrar burbujas informativas", + "DG.Settings.skillTooltipDisplay.hint": "Escoge cuando mostrar las burbujas informativas de las habilidades en las hojas de Agentes.", + "DG.Settings.skillTooltipDisplay.hover": "Al pasar el ratón (por defecto)", + "DG.Settings.skillTooltipDisplay.never": "Nunca", + "DG.Settings.skillTooltipDisplay.hoverShift": "Al pasar el ratón + Mayús", + "DG.Settings.keepSanityPrivate.name": "Mantener COR privada", + "DG.Settings.keepSanityPrivate.hint": "Ocultar la COR a los jugadores, tanto en la hoja de personaje como en las tiradas.", + "DG.Settings.skillImprovementFormula.name": "Tirada de mejora de habilidad", + "DG.Settings.skillImprovementFormula.hint": " Por defecto 1d4. Debe haber varias erratas al respecto, escoje el dado que vaya mejor con el ritmo de tu partida.", + "DG.Settings.skillImprovementFormula.1": "+1 simple", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Mostrar sección de hipergeometría", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Siempre mostrar la sección de objetos de hipergeometría, incluso si no se tienen objetos de este tipo.", + "DG.Settings.showImpossibleLandscapesContent.name": "Mostrar Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Mostrar los campos específicos de Impossible Landscapes en las hojas de personaje.", + "DG.Settings.skillFailure.name": "Marcar automáticamente fallo en habilidad", + "DG.Settings.skillFailure.hint": "Active este ajuste para activar la casilla al fallar una habilidad. El Supervisor puede deshacer esta acción desde la tarjeta del chat de la tirada.", + "DG.Settings.Saved": "Los ajustes han sido guardados.", + + "DG.SettingsMenu.automation.name": "Menú de automatización", + "DG.SettingsMenu.automation.label": "Menú de automatización", + "DG.SettingsMenu.automation.title": "Menú de ajustes", + + "DG.SettingsMenu.handler.name": "Ajustes del Supervisor", + "DG.SettingsMenu.handler.label": "Ajustes del Supervisor", + "DG.SettingsMenu.handler.title": "Ajustes solo para el Supervisor", + + "DG.Messages.Skillsmark.Marked": "Habilidad marcada", + "DG.Messages.Skillsmark.Tooltip": "Consulte la página 29 del Manual del Agente" +} diff --git a/lang/fr.json b/lang/fr.json new file mode 100644 index 0000000..0bd6768 --- /dev/null +++ b/lang/fr.json @@ -0,0 +1,431 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "NOM, PRÉNOM, INITIALES", + "DG.RollLuck": "Jet de Chance", + "DG.Luck": "Chance", + + "DG.FallbackText.newItem": "Nouveau/el/elle {type}", + + "DG.Skills.accounting": "Comptabilité", + "DG.Skills.alertness": "Vigilance", + "DG.Skills.anthropology": "Anthropologie", + "DG.Skills.archeology": "Archéologie", + "DG.Skills.artillery": "Artillerie", + "DG.Skills.athletics": "Athlétisme", + "DG.Skills.bureaucracy": "Bureaucratie", + "DG.Skills.computer_science": "Informatique", + "DG.Skills.criminology": "Criminologie", + "DG.Skills.demolitions": "Explosifs", + "DG.Skills.disguise": "Déguisement", + "DG.Skills.dodge": "Esquive", + "DG.Skills.drive": "Conduite", + "DG.Skills.firearms": "Armes à feu", + "DG.Skills.first_aid": "Premiers secours", + "DG.Skills.forensics": "Criminalistique", + "DG.Skills.heavy_machiner": "Engins lourds", + "DG.Skills.heavy_weapons": "Armes lourdes", + "DG.Skills.history": "Histoire", + "DG.Skills.humint": "ROHUM", + "DG.Skills.law": "Droit", + "DG.Skills.medicine": "Médecine", + "DG.Skills.melee_weapons": "Armes de mêlée", + "DG.Skills.navigate": "Orientation", + "DG.Skills.occult": "Occultisme", + "DG.Skills.persuade": "Persuasion", + "DG.Skills.pharmacy": "Pharmacologie", + "DG.Skills.psychotherapy": "Psychothérapie", + "DG.Skills.ride": "Équitation", + "DG.Skills.search": "Recherche", + "DG.Skills.sigint": "ROEM", + "DG.Skills.stealth": "Discrétion", + "DG.Skills.surgery": "Chirurgie", + "DG.Skills.survival": "Survie", + "DG.Skills.swim": "Natation", + "DG.Skills.unarmed_combat": "Cbt à mains nues", + "DG.Skills.unnatural": "Inconcevable", + "DG.Skills.flight": "Voler", + + "DG.Skills.Tooltip.accounting": "Repérez les signaux d'alerte financiers tels que les actifs cachés, les sociétés écrans ou les détournements de fonds.", + "DG.Skills.Tooltip.alertness": "Remarquez les dangers cachés, les mouvements subtils ou les sons discrets avant qu'ils ne deviennent des menaces.", + "DG.Skills.Tooltip.anthropology": "Comprendre la moralité, les croyances religieuses, les coutumes et les moeurs, ainsi qu’à identifier (mais pas à traduire) les langues obscures", + "DG.Skills.Tooltip.archeology": "Analyser le mode de vie d’un peuple à partir de ses ruines, à déterminer l’âge d’une relique, à distinguer un véritable vestige d’un faux et à identifier (mais pas à traduire) les langues humaines.", + "DG.Skills.Tooltip.artillery": "Usage sûr et précis des mortiers, missiles, canons de tank et autres armes d’artillerie lourde.", + "DG.Skills.Tooltip.athletics": "Courez, grimpez, sautez et lancez avec une force et une agilité entraînées.", + "DG.Skills.Tooltip.bureaucracy": "Manipuler les règles et les individus qui dirigent une organisation.", + "DG.Skills.Tooltip.computer_science": "Connaissance approfondie des ordinateurs, des systèmes informatiques et des programmes qui les régissent.", + "DG.Skills.Tooltip.criminology": "Connaissance du comportement des criminels et conspirateurs.", + "DG.Skills.Tooltip.demolitions": "Manipulation sans danger des explosifs en situation de crise.", + "DG.Skills.Tooltip.disguise": "Consiste à altérer l’apparence, la voix, la posture, la gestuelle et les manières de votre Agent pour éviter qu’on le reconnaisse, le tout sans attirer l ’attention.", + "DG.Skills.Tooltip.dodge": "Échapper au danger et aux attaques grâce à l’instinct et aux réflexes.", + "DG.Skills.Tooltip.drive": "Piloter une automobile ou une moto sans danger en situation de crise.", + "DG.Skills.Tooltip.firearms": "Tirer avec précision, en toute sécurité, à l’aide de petites armes à feu lors d’un combat.", + "DG.Skills.Tooltip.first_aid": "Traitement initial et stabilisation des blessures.", + "DG.Skills.Tooltip.forensics": "Permet de réunir des informations et des preuves au moyen d’un équipement approprié.", + "DG.Skills.Tooltip.heavy_machiner": "Manoeuvrer en toute sécurité un tracteur, une grue, un bulldozer, un tank, un poids lourd ou une autre machine volumineuse en situation de crise.", + "DG.Skills.Tooltip.heavy_weapons": "Employer avec sécurité et précision des armes lourdes portatives telles que des mitrailleuses et des lance-roquettes.", + "DG.Skills.Tooltip.history": "Dévoiler des faits et des théories relatives au passé de l’humanité.", + "DG.Skills.Tooltip.humint": "Cette compétence procure des informations sur un sujet grâce à l’observation, la conversation ou l’examen du comportement et des relations.", + "DG.Skills.Tooltip.law": "Exploiter les lois et les tribunaux au profit de votre Agent.", + "DG.Skills.Tooltip.medicine": "Étude et traitement des blessures et maladies. Sert à diagnostiquer la cause d’une blessure, d’une maladie ou d’une intoxication.", + "DG.Skills.Tooltip.melee_weapons": "Usage létal des armes rapprochées au combat.", + "DG.Skills.Tooltip.navigate": "Permet de rapidement retrouver son chemin grâce à des plans, des cartes et des tableaux, des méthodes d’orientation, des instruments ou en naviguant à l’estime.", + "DG.Skills.Tooltip.occult": "L’étude de l’inconcevable sous l’angle des traditions humaines, ce qui comprend des domaines comme les théories conspirationnistes, l’occultisme traditionnel, les sciences parallèles et la cryptozoologie.", + "DG.Skills.Tooltip.persuade": "Altérer une décision ou un désir solide chez autrui.", + "DG.Skills.Tooltip.pharmacy": "Connaissance des médicaments, de leurs ingrédients et de leur mode de fabrication, de leurs effets, de la posologie et des contre-indications.", + "DG.Skills.Tooltip.psychotherapy": "Diagnostic et traitement des maladies mentales.", + "DG.Skills.Tooltip.ride": "Gérer, dresser et monter des chevaux, ânes, chameaux et autres animaux de ce genre.", + "DG.Skills.Tooltip.search": "Retrouver des objets cachés ou placés à l’abri des regards.", + "DG.Skills.Tooltip.sigint": "Renseignements issus des transmissions. Comprend le cryptage, la surveillance des communications et de l’électronique, les systèmes de sécurité électroniques, la surveillance des communications radio et numérique, ainsi que l’élaboration et le déchiffrement de codes.", + "DG.Skills.Tooltip.stealth": "Dissimuler votre présence ou vos activités.", + "DG.Skills.Tooltip.surgery": "Traitement d’une blessure ou d’une anomalie par des moyens invasifs.", + "DG.Skills.Tooltip.survival": "Sert à trouver des pistes et des traces, à planifier une expédition, à prévoir le temps qu’il fait, à reconnaître les caractères inhabituels de la faune ou de la flore, à exploiter l’environnement pour glaner des informations ainsi qu’à trouver de la nourriture, de l’eau et des abris.", + "DG.Skills.Tooltip.swim": "Pour la plupart des Agents, la natation est un loisir. Servez-vous de la compétence Natation lors des situations de crise.", + "DG.Skills.Tooltip.unarmed_combat": "Autodéfense. Servez-vous de Combat à mains nues pour blesser ou tuer un adversaire avec vos seuls poings (ainsi que vos pieds, vos coudes, vos dents et votre tête).", + "DG.Skills.Tooltip.unnatural": "Connaissance des secrets fondamentaux de l’univers, propres à provoquer la folie.", + + "DG.Skills.AddTypedOrCustomSkill": "Ajouter une compétence personnalisée", + "DG.Skills.AddSkill": "Ajout Compétence", + "DG.Skills.Apply": "Appliquer", + "DG.Skills.ApplySkillImprovements": "Appliquer l'augmentation d'EXP", + "DG.Skills.ApplySkillImprovementsChatFlavor": "Améliorer les compétences suivantes de", + "DG.Skills.ApplySkillImprovementsDialogLabel": "Améliorer les compétences via la formule suivante:", + "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "Affecte les compétences suivantes:", + "DG.Skills.ApplySkillImprovementsWarning": "Pas de compétence en échec à améliorer", + "DG.Skills.EditTypedOrCustomSkill": "Éditer une compétence personnalisée", + "DG.Skills.EditSkill": "Éditer compétence", + "DG.Skills.SkillGroup": "Groupe de compétence", + "DG.Skills.SkillName": "Nom de la compétence", + + "DG.TypeSkills.Art": "Art", + "DG.TypeSkills.Craft": "Artisanat", + "DG.TypeSkills.ForeignLanguage": "Langues étrangères", + "DG.TypeSkills.MilitaryScience": "Sciences militaires", + "DG.TypeSkills.Pilot": "Pilotage", + "DG.TypeSkills.Science": "Science", + "DG.TypeSkills.Other": "Autre", + + "DG.TypeSkills.Tooltip.Art": "Maîtrise de la création ou de l’exécution d’une oeuvre capable d’altérer les émotions et les opinions.", + "DG.TypeSkills.Tooltip.Craft": "Fabriquer et réparer des outils et structures sophistiqués.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Parler couramment une autre langue. Chaque langue étrangère représente une compétence distincte.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Connaissance de la culture, des techniques et des réglementations militaires.", + "DG.TypeSkills.Tooltip.Pilot": "Piloter, diriger et naviguer avec des véhicules aquatiques, aériens ou aérospatiaux.", + "DG.TypeSkills.Tooltip.Science": "Étude approfondie des phénomènes qui nous entourent.", + "DG.TypeSkills.Tooltip.Other": "Autre", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Ajouter un Entraînement Spécial", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Compétences Personnalisées/Typées", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Compétences", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Statistiques", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Éditer l'Entraînement Spécial", + "DG.SpecialTraining.Dialog.NameLabel": "Nom", + "DG.SpecialTraining.Dialog.SkillLabel": "Compétence ou Statistique", + "DG.SpecialTraining.Dialog.Title": "Créer/Éditer un Entraînement Spécial", + + "DG.Attributes.HP": "PV", + "DG.Attributes.WP": "VOL", + "DG.Attributes.SAN": "SAN", + "DG.Attributes.str": "FOR", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DEX", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POU", + "DG.Attributes.cha": "CHA", + + "DG.Attributes.Tooltip.HP": "Points de vie, un personnage devient inconscient à 2PV et meurt à 0PV", + "DG.Attributes.Tooltip.WP": "Les Points de Volonté (VOL) sont le carburant psychologique. Les Agents ont besoin de Points de Volonté pour continuer à travailler malgré l'épuisement ou les situations mentalement éprouvantes. Voir la page 47 du Manuel de l'agent pour plus de détails", + "DG.Attributes.Tooltip.SAN": "Les points de santé mentale (SAN) indiquent un lien avec l'humanité et la réalité telles que la plupart des gens les perçoivent. Cliquer pour effectuer un jet de SAN.", + "DG.Attributes.Tooltip.str": "Voir Page 19 du Manuel de l'Agent - Force", + "DG.Attributes.Tooltip.con": "Voir Page 19 du Manuel de l'Agent - Constitution", + "DG.Attributes.Tooltip.dex": "Voir Page 19 du Manuel de l'Agent - Dexterité", + "DG.Attributes.Tooltip.int": "Voir Page 19 du Manuel de l'Agent - Intelligence", + "DG.Attributes.Tooltip.pow": "Voir Page 19 du Manuel de l'Agent - Pouvoir", + "DG.Attributes.Tooltip.cha": "Voir Page 19 du Manuel de l'Agent - Charisme", + + "DG.Navigation.Agent.skills": "Compétences", + "DG.Navigation.Agent.physical": "Statistiques", + "DG.Navigation.Agent.motivations": "Psychologie", + "DG.Navigation.Agent.gear": "Équipement", + "DG.Navigation.Agent.bio": "Biographie", + "DG.Navigation.Agent.bonds": "Attaches", + "DG.Navigation.NPC.skills": "Compétences & Formation", + "DG.Navigation.NPC.gear": "Attaques & Capacités", + "DG.Navigation.Vehicle.gear": "Équipement", + "DG.Navigation.Vehicle.notes": "Notes", + + "DG.About.Changelog": "CHANGELOG (ONLINE)", + "DG.About.Copyright": "Publié par Arc Dream Publishing en accord avec Delta Green Partnership. La propriété intellectuelle connue sous le nom de Delta Green est une marque déposée et protégée par les droits d'auteur appartenant à Delta Green Partnership, qui en a autorisé l'utilisation ici.", + "DG.About.License": "Le contenu de ce système est concédé sous licence conformément aux conditions générales incluses dans le fichier licence, à l'exception des éléments qui font partie de la propriété intellectuelle de Delta Green.", + "DG.About.OnlineHelp": "Documentation du système sur (ONLINE)", + "DG.About.OnlineHelpTooltip": "Lancer le navigateur avec l'aide GitHub en ligne.", + "DG.About.OnlineBugTracker": "Questions, rapports de bug ou demandes de fonctionnalités (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Lancer le navigateur avec le suivi des problèmes GitHub.", + + "DG.Roll.Rolling": "Jet de dés", + "DG.Roll.Target": "Cible: ", + "DG.Roll.Success": "Succés", + "DG.Roll.Failure": "Échec", + "DG.Roll.CriticalSuccess": "Succés critique!", + "DG.Roll.CriticalFailure": "Échec critique!", + "DG.Roll.Lethality": "Létalité", + "DG.Roll.Lethal": "Létal", + "DG.Roll.For": "Pour", + "DG.Roll.Damage": "Dégâts", + "DG.Roll.RollingDamageFor": "Jets de dégâts pour", + "DG.Roll.Or": "Ou", + "DG.Roll.Roll": "Lancer", + + "DG.Physical.Wounds": "Blessures", + "DG.Physical.FirstAidLabel": "Jet de Premiers Secours depuis sa dernière blessure: ", + "DG.Physical.Exhausted": "Épuisé:", + "DG.Physical.ExhaustionPenalty": "Pénalité:", + + "DG.Generic.AddButtonLabel": "Ajouter", + + "DG.Mental.BreakingPoint": "Seuil de Rupture: ", + "DG.Mental.Tooltip.BreakingPoint": "le Seuil de Rupture est le point à partir duquel la perte de SAN déclenche des troubles psychiques à long terme. Dès que la SAN de l’Agent atteint le Seuil de Rupture, il reçoit un trouble. Réinitialisez le Seuil de Rupture : il est désormais égal à la nouvelle valeur de SAN moins POU", + "DG.Mental.Reset": "Réinit.", + "DG.Mental.SanityLossIncidentsLabel": "Perte de SAN n'ayant pas entrainé la folie", + "DG.Mental.Violence": "Violence", + "DG.Mental.Tooltip.Violence": "ACCOUTUMÉ À LA VIOLENCE : Lorsque votre Agent perd de la SAN à cause de la violence par 3 occasions sans developper de folie, son empathie en prend un coup. Il perd 1D6 CHA permanents et diminue le score de chaque Attache d’un montant équivalent. Manuel de l'Agent page 73", + "DG.Mental.Helplessness": "Impuissance", + "DG.Mental.Tooltip.Helplessness": "ACCOUTUMÉ À L’IMPUISSANCE : Lorsque votre Agent perd de la SAN à cause de l'impuissance par 3 occasions sans developper de folie, sa motivation en pâtit, et il perd 1D6 POU de façon permanente. Manuel de l'Agent page 73.", + "DG.Mental.AdaptedToViolence": "Accoutumée à la violence", + "DG.Mental.AdaptedToHelplessness": "Accoutumée à l'impuissance", + "DG.Mental.Motivations": "Motivations", + "DG.Mental.Disorders": "Troubles psychiques", + + "DG.Gear.WeaponTypes.Firearms": "Armes à feu", + "DG.Gear.WeaponTypes.Melee": "Mêlée", + "DG.Gear.Weapons": "ARMES", + "DG.Gear.Armor": "ARMURE ET MATÉRIEL", + "DG.Gear.OtherGear": "AUTRES ÉQUIPEMENTS", + "DG.Gear.Name": "Nom", + "DG.Gear.DamageOrLethality": "Dégâts/Létalité", + "DG.Gear.ArmorPiercing": "Perforant", + "DG.Gear.ArmorRating": "Niveau d'Armure", + "DG.Gear.Equipped": "Équipé", + + "DG.CV.Sex": "Sexe", + "DG.CV.SexPlaceholder": "Sexe", + "DG.CV.AgeAndDoB": "Âge et Date de Naissance", + "DG.CV.AgeAndDoBPlaceholder": "Âge et Date de Naissance", + "DG.CV.Employer": "Employeur", + "DG.CV.EmployerPlaceholder": "Employeur ou Historique de Travail", + "DG.CV.Nationality": "Nationalité", + "DG.CV.NationalityPlaceholder": "Nationalité", + "DG.CV.Education": "Études et Carrière", + "DG.CV.EducationPlaceholder": "Études et Carrière", + + "DG.Bonds.Bond": "Attaches", + "DG.Bonds.Name": "Nom", + "DG.Bonds.Score": "Score", + "DG.Bonds.NewBond": "Nouvelle Attache", + + "DG.Tooltip.MaximumHP": "La Santé maximum est la moyenne de FOR+CON, arrondi au supérieur", + "DG.Tooltip.MaximumWP": "La Volonté maximum est égale au POUVOIR", + "DG.Tooltip.CurrentSanityPartOne": "Santé Mentale actuelle, le seuil de rupture actuel est ", + "DG.Tooltip.CurrentSanityPartTwo": ", cliquez sur SAN ci-dessus pour effectuer un jet de santé mentale", + "DG.Tooltip.MaximumSanity": "La Santé Mentale maximum est égale à 99 moins la compétence Paranaturel", + "DG.Tooltip.SkillLabel": "Cliquer pour utiliser la compétence", + "DG.Tooltip.CannotRollSkillLabel": "Une compétence à 0% ne peut pas être utilisée. Voir page 28 du Manuel de l'Agent", + "DG.Tooltip.SkillFailCheckbox": "Cochez une case quand vous échouez à un jet de compétence (si celle-ci est d'au moins 1%). Après la partie, ajoutez 1d4 à chaque compétence cochée et effacez tous les coches. Ne s'applique pas à la compétence Inconcevable. Voir la page 29 du Manuel de l'Agent", + "DG.Tooltip.DistinguishingFeature": "Traits distinctifs (à remplir si la valeur est de 12 ou plus, ou de 8 ou moins)", + "DG.Tooltip.x5AttributeLabel": "Cliquer pour effectuer un jet de % (valeur x5)", + "DG.Tooltip.FirstAidAttempted": "Dés qu'un Agent reçoit les premiers soins, il ne peut plus en bénéficier tant qu'il n'a pas reçu de nouveaux dégâts d'une autre source", + "DG.Tooltip.AdaptedToViolence": "Être adapté à la violence signifie que l'empathie de votre Agent souffre lorsqu'il en vient à considérer la violence comme un outil de plus à manier. Il ou elle perd définitivement 1D6 CHA et le même montant dans chacun de ses Liens", + "DG.Tooltip.AdaptedToHelplessness": "Être adapté à l'impuissance signifie que la motivation personnelle de votre agent souffre lorsqu'il se retire du monde qui l'entoure. Dès que votre agent s'adapte à l'impuissance, il ou elle perd définitivement 1D6 POU", + "DG.Tooltip.ToggleEquippedState": "Cliquez pour indiquer si cet élément est équipé ou non", + "DG.Tooltip.Exhaustion": "Un agent qui travaille trop longtemps, qui fait face à un danger extrême ou des blessures sans repos devient épuisé", + + "DG.Gear.Expense.NA": "N/A ou Aucun", + "DG.Gear.Expense.Incidental": "Courante", + "DG.Gear.Expense.Standard": "Standard", + "DG.Gear.Expense.Unusual": "Importante", + "DG.Gear.Expense.Major": "Substantielle", + "DG.Gear.Expense.Extreme": "Considérable", + + "DG.ItemWindow.Bonds.Description": "Description/développements", + "DG.ItemWindow.Bonds.ScoreTooltip": "Un score plus élevé représente une relation plus forte entre l'Agent et l'Attache", + + "DG.ItemWindow.Motivations.Attributes": "Caractéristiques", + "DG.ItemWindow.Motivations.Motivation": "Motivation", + "DG.ItemWindow.Motivations.Description": "Description/Notes", + "DG.ItemWindow.Motivations.Disorder": "Trouble psychique", + "DG.ItemWindow.Motivations.IsDisorder": "Est un trouble psychique", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Quelque chose qui anime le personnage", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Un trouble psychique remplace une motivation après avoir atteint un seuil de rupture", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Cochez cette case si vous ajoutez un trouble psychique, ou si une motivation existante a été perdue en raison de l'acquisition d'un trouble", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Le trouble psychique a été \"Soigné\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Un succès critique sur un jet de chance peut guérir un trouble psychique. Il peut cependant réapparaître la prochaine fois qu'un seuil de rupture est atteint", + + "DG.ItemWindow.Gear.Attributes": "Caractéristiques", + "DG.ItemWindow.Gear.Description": "Description", + "DG.ItemWindow.Gear.NamePlaceholder": "Nom", + "DG.ItemWindow.Gear.Expense": "Dépense", + "DG.ItemWindow.Gear.Equipped": "Équipé", + + "DG.ItemWindow.Armor.Description": "Description", + "DG.ItemWindow.Armor.NamePlaceholder": "Nom", + "DG.ItemWindow.Armor.ArmorRating": "Valeur d'Armure", + "DG.ItemWindow.Armor.Expense": "Dépense", + "DG.ItemWindow.Armor.Equipped": "Équipé", + + "DG.ItemWindow.Weapons.Description": "Description", + "DG.ItemWindow.Weapons.NamePlaceholder": "Nom", + "DG.ItemWindow.Weapons.Skill": "Compétence", + "DG.ItemWindow.Weapons.Expense": "Dépense", + "DG.ItemWindow.Weapons.Damage": "Dégâts", + "DG.ItemWindow.Weapons.Lethality": "Létalité", + "DG.ItemWindow.Weapons.IsLethality": "Est Létal", + "DG.ItemWindow.Weapons.LethalityTooltip": "Une arme létale a une chance de tuer instantanément une cible. Lancer un D100 au lieu d'un jet de dégâts. En cas d'échec, la cible subit des dommages égaux aux 2d10 associés", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Cochez cette case si l'arme est associée à un pourcentage de Létalité", + "DG.ItemWindow.Weapons.ArmorPiercing": "Perforant", + "DG.ItemWindow.Weapons.Ammo": "Munitions (Nombre/Type)", + "DG.ItemWindow.Weapons.Range": "Portée", + "DG.ItemWindow.Weapons.KillRadius": "Rayon de mortalité", + + "DG.ModifySkillRollDialogue.Title": "Modifier le Lancer", + "DG.ModifySkillRollDialogue.Test": "Test de:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Niveau actuel:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modificateur (+/-):", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Donnez ici un modificateur positif ou négatif à ajouter/soustraire à la cible pour le test de compétence.", + + "DG.ModifyDamageRollDialogue.Weapon": "Arme:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Utilisez ce champ pour modifier la partie extérieure de la formule, par exemple pour doubler le résultat.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Utilisez ce champ pour ajouter un modificateur fixe tel que '+1' ou un autre terme de dé tel que '+1d4'.", + + "DG.Roll.Inhuman": "Non humain", + "DG.Tooltip.BreakPoint": "Le seuil de rupture actuel, réinitialisé lorsque la santé mentale actuelle tombe à cette valeur ou en dessous. Le seuil de rupture de départ est SAN - POU", + "DG.Tooltip.BreakPointReset": "Le seuil de rupture est réinitialisé à la valeur actuelle SAN - POU", + "DG.Skills.ritual": "Rituel", + + "DG.RollMode": "Mode de Jet", + "DG.Bonds.Relationship": "Type d'Attache", + + "DG.TypeSkills.Subskills.Painting": "Peinture", + + "DG.Sheet.BlockHeaders.Attributes": "CARACTÉRISTIQUES", + "DG.Sheet.BlockHeaders.Statistics": "STATISTIQUES", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "DESCRIPTION PHYSIQUE / NOTES", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "COMPÉTENCES ET FORMATION", + "DG.Sheet.BlockHeaders.Injuries": "BLESSURES ET MALADIES", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "SEUIL DE RUPTURE ET ADAPTATIONS", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONS ET TROUBLES PSYCHIQUES", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "DÉTAILS PERSONNELS ET NOTES", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "ATTACHES, RELATIONS ET CONTACTS", + + "DG.AgentSheet.ProfessionPlaceholder": "PROFESSION (RANG LE CAS ÉCHÉANT)", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Cacher compétences inconnues", + "DG.UnnaturalSheet.NotesLabel": "Notes", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "Description de créature ou du type de créature", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Voir compétences inconnues", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Compétences & Notes", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Attaques & Capacités", + "DG.NPCSheet.BreakPointAbbreviation": "SR", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "J'AI VU LE", + "DG.ImpossibleLanscapes.YellowSign": "SIGNE JAUNE", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Corrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "tion", + "DG.ImpossibleLanscapes.Gift": "Don", + "DG.ImpossibleLanscapes.Insight": "Intuition", + + "DG.VehicleSheet.NotesTabName": "Notes", + "DG.VehicleSheet.GearTabName": "Équipement", + "DG.VehicleSheet.NotesLabel": "NOTES", + "DG.VehicleSheet.DescriptionPlaceHolder": "Description du Véhicule", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Quand une Attache est endommagée, cochez sa case jusqu'à la fin de la prochaine scène privée.", + "DG.Generic.ClearAll": "Supprimer les coches", + + "DG.Generic.SanDamage": "Perte de SAN", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Cible", + "DG.ItemWindow.Weapons.SkillModifier": "Modificateur de compétence", + "DG.ItemWindow.Custom": "Personnalisé", + + "DG.Sheet.class.item": "Feuille d'Équipement", + "DG.Sheet.class.agent": "Feuille d'Agent", + "DG.Sheet.class.npc": "Feuille de PNJ", + "DG.Sheet.class.unnatural": "Feuille d'Inconcevable", + "DG.Sheet.class.vehicle": "Feuille de Véhicule", + + "TYPES.Actor.agent": "Agent", + "TYPES.Actor.npc": "PNJ", + "TYPES.Actor.unnatural": "Inconcevable", + "TYPES.Actor.vehicle": "Véhicule", + + "TYPES.Item.armor": "Armure", + "TYPES.Item.bond": "Lien", + "TYPES.Item.gear": "Équipement", + "TYPES.Item.motivation": "Motivation", + "TYPES.Item.weapon": "Arme", + "TYPES.Item.tome": "Ouvrage", + "TYPES.Item.ritual": "Rituel", + + "DG.Gear.Tomes": "OUVRAGES", + "DG.Gear.Rituals": "RITUELS", + + "DG.Tomes.Name": "Titre", + "DG.Ritual.Name": "Nom", + + "DG.Tome.Name": "Titre", + "DG.Tome.Language": "Langage", + "DG.Tome.StudyTime": "Temps d'Étude", + "DG.ItemWindow.Tome.Description": "Description", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Langage", + "DG.ItemWindow.Tome.StudyTime": "Temps d'Étude", + "DG.ItemWindow.Tome.OccultIncrease": "Augmentation en Occultisme", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Augmentation en Inconcevable", + "DG.ItemWindow.Tome.StudySanityDamage": "Perte de SAN dûe à l'étude", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Officier Uniquement", + "DG.ItemWindow.Tome.HandlerNotes": "Notes de l'Officier", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Dégâts SAN Activation", + "DG.ItemWindow.Ritual.ActivationTime": "Temp d'Activation", + "DG.ItemWindow.Ritual.ActivationCosts": "Coût d'Activation", + "DG.ItemWindow.Ritual.StudyTime": "Temps d'étude", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Dégâts SAN Étude", + + "DG.MissionPaused": "Mission en pause", + + "DG.Settings.charactersheet.name": "Style de Feuille de Personnage", + "DG.Settings.charactersheet.hint": "Choisissez le style des fiches de Personnage. Le Programme est un style gouvernemental plus moderne, tandis que Les Cowboys et les Hors-la-loi ont un style machine à écrire plus ancien et plus brut.", + "DG.Settings.charactersheet.cowboys": "Les Cowboys", + "DG.Settings.charactersheet.outlaws": "Les Hors-la-loi", + "DG.Settings.charactersheet.program": "Le Programme", + "DG.Settings.sortskills.name": "Trier les comp. par colonne?", + "DG.Settings.sortskills.hint": "Coché: tri par colonne. Non coché: tri par ligne.", + "DG.Settings.skillTooltipDisplay.name": "Affichage des infobulles de compétences", + "DG.Settings.skillTooltipDisplay.hint": "Choisissez comment afficher les infobulles de compétences sur les feuilles de personnages des Agents.", + "DG.Settings.skillTooltipDisplay.hover": "Au survol (par défaut)", + "DG.Settings.skillTooltipDisplay.never": "Jamais", + "DG.Settings.skillTooltipDisplay.hoverShift": "Au survol + Shift", + "DG.Settings.keepSanityPrivate.name": "Gardez la SAN privée", + "DG.Settings.keepSanityPrivate.hint": "Masquer la santé mentale des joueurs dans les fiches d'agent et les jets de dés associés.", + "DG.Settings.skillImprovementFormula.name": "Jet d'amélioration des compétences par défaut", + "DG.Settings.skillImprovementFormula.hint": " Par défaut, 1d4. Il y a eu plusieurs errata à ce sujet, choisissez celui qui correspond le mieux au rythme de votre partie.", + "DG.Settings.skillImprovementFormula.1": "+1%", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Afficher la section Hypergéométrie", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Afficher toujours la section des objets hypergéométriques (c'est-à-dire les rituels et les grimoires) sur les fiches des agents, même si l'agent ne possède aucun objet de ce type.", + "DG.Settings.showImpossibleLandscapesContent.name": "Aficher le contenu Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Afficher les champs spécifiques à Impossible Landscapes dans les fiches d'agent. Ces champs ne sont visibles que par le MJ, même si ce paramètre est coché.", + "DG.Settings.skillFailure.name": "Marquer automatiquement l'échec d'une compétence", + "DG.Settings.skillFailure.hint": "Activez ce paramètre pour toujours cocher la case « Échec » en cas d'échec d'une compétence. Le MJ peut annuler l'action à partir du message du jet dans le chat.", + "DG.Settings.Saved": "Les paramètres actuels ont été enregistrés.", + + "DG.SettingsMenu.automation.name": "Menu Automatisaton", + "DG.SettingsMenu.automation.label": "Menu Automatisaton", + "DG.SettingsMenu.automation.title": "Config. Automatisation", + + "DG.SettingsMenu.handler.name": "Config. Officier Traitant", + "DG.SettingsMenu.handler.label": "Config. Officier Traitant", + "DG.SettingsMenu.handler.title": "Config. Officier Traitant seulement", + + "DG.Messages.Skillsmark.Marked": "Cette compétence est marquée.", + "DG.Messages.Skillsmark.Tooltip": "Voir p. 29 du Manuel de l'agent." +} diff --git a/lang/ja.json b/lang/ja.json new file mode 100644 index 0000000..54107ca --- /dev/null +++ b/lang/ja.json @@ -0,0 +1,359 @@ +{ + "DG.SystemName": "デルタグリーン", + "DG.AgentNameFieldTooltip": "姓, 名 (必要に応じ通称)", + "DG.RollLuck": "幸運ロール", + "DG.Luck": "幸運", + + "DG.FallbackText.ProfessionAndOrRank": "職業 (必要に応じ役職)", + "DG.FallbackText.newItem": "新規{type}", + + "DG.Skills.accounting": "経理", + "DG.Skills.alertness": "警戒", + "DG.Skills.anthropology": "人類学", + "DG.Skills.archeology": "考古学", + "DG.Skills.artillery": "砲", + "DG.Skills.athletics": "運動", + "DG.Skills.bureaucracy": "官僚", + "DG.Skills.computer_science": "コンピューター", + "DG.Skills.criminology": "犯罪学", + "DG.Skills.demolitions": "爆破", + "DG.Skills.disguise": "変装", + "DG.Skills.dodge": "回避", + "DG.Skills.drive": "運転", + "DG.Skills.firearms": "射撃", + "DG.Skills.first_aid": "応急手当", + "DG.Skills.forensics": "法医学", + "DG.Skills.heavy_machiner": "重機械操作", + "DG.Skills.heavy_weapons": "重火器", + "DG.Skills.history": "歴史", + "DG.Skills.humint": "諜報", + "DG.Skills.law": "法律", + "DG.Skills.medicine": "医学", + "DG.Skills.melee_weapons": "近接武器", + "DG.Skills.navigate": "ナビゲート", + "DG.Skills.occult": "オカルト", + "DG.Skills.persuade": "説得", + "DG.Skills.pharmacy": "薬学", + "DG.Skills.psychotherapy": "心理療法", + "DG.Skills.ride": "乗馬", + "DG.Skills.search": "捜索", + "DG.Skills.sigint": "シギント", + "DG.Skills.stealth": "隠密", + "DG.Skills.surgery": "手術", + "DG.Skills.survival": "サバイバル", + "DG.Skills.swim": "水泳", + "DG.Skills.unarmed_combat": "徒手格闘", + "DG.Skills.unnatural": "非自然", + "DG.Skills.flight": "飛行", + + "DG.Skills.AddTypedOrCustomSkill": "類型/カスタム技能を追加", + "DG.Skills.AddSkill": "技能を追加", + "DG.Skills.Apply": "適用", + "DG.Skills.ApplySkillImprovements": "技能上達を適用", + "DG.Skills.ApplySkillImprovementsChatFlavor": "以下の技能が次式で成長した", + "DG.Skills.ApplySkillImprovementsDialogLabel": "次の式により技能を上達する:", + "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "以下の技能に影響する:", + "DG.Skills.ApplySkillImprovementsWarning": "上達する失敗した技能がありません", + "DG.Skills.EditTypedOrCustomSkill": "類型/カスタム技能を編集", + "DG.Skills.EditSkill": "技能を編集", + "DG.Skills.SkillGroup": "技能グループ", + "DG.Skills.SkillName": "技能の名前", + + "DG.TypeSkills.Art": "芸術", + "DG.TypeSkills.Craft": "製作", + "DG.TypeSkills.ForeignLanguage": "ほかの言語", + "DG.TypeSkills.MilitaryScience": "軍事科学", + "DG.TypeSkills.Pilot": "操縦", + "DG.TypeSkills.Science": "科学", + "DG.TypeSkills.Other": "その他", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "特殊訓練を追加", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "カスタム/類型技能", + "DG.SpecialTraining.Dialog.DropDown.Skills": "技能", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "能力値", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "特殊訓練を編集", + "DG.SpecialTraining.Dialog.NameLabel": "名前", + "DG.SpecialTraining.Dialog.SkillLabel": "技能/能力値", + "DG.SpecialTraining.Dialog.Title": "特殊訓練の作成/編集", + + "DG.Attributes.HP": "HP", + "DG.Attributes.WP": "WP", + "DG.Attributes.SAN": "SAN", + "DG.Attributes.str": "STR", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DEX", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POW", + "DG.Attributes.cha": "CHA", + + "DG.Navigation.Skills": "技能", + "DG.Navigation.Physical": "能力値", + "DG.Navigation.Mental": "精神", + "DG.Navigation.Gear": "装備", + "DG.Navigation.CV": "経歴", + "DG.Navigation.Contacts": "絆", + + "DG.About.OnlineHelp": "システムドキュメンテーション(オンライン)", + "DG.About.OnlineHelpTooltip": "オンラインGitHubヘルプをブラウザで開く。", + "DG.About.OnlineBugTracker": "質問、バグ報告、機能リクエスト(オンライン)", + "DG.About.OnlineBugTrackerTooltip": "オンラインGitHubのissueトラッカーをブラウザで開く。", + + "DG.Roll.Rolling": "ローリング", + "DG.Roll.Target": "目標値: ", + "DG.Roll.Success": "成功", + "DG.Roll.Failure": "失敗", + "DG.Roll.Critical": "クリティカル", + "DG.Roll.Lethality": "致命率", + "DG.Roll.Lethal": "致命傷", + "DG.Roll.For": " : ", + "DG.Roll.Damage": "ダメージ", + "DG.Roll.RollingDamageFor": "ダメージロール: ", + "DG.Roll.Or": " / ", + "DG.Roll.Roll": "ロール", + + "DG.Physical.Wounds": "傷跡", + "DG.Physical.FirstAidLabel": "応急手当済: ", + "DG.Physical.Exhausted": "疲労:", + "DG.Physical.ExhaustionPenalty": "ペナルティ:", + + "DG.Generic.AddButtonLabel": "追加", + + "DG.Mental.BreakingPoint": "限界点: ", + "DG.Mental.Reset": "リセット", + "DG.Mental.SanityLossIncidentsLabel": "SANを失ったが正気を保った出来事", + "DG.Mental.Violence": "暴力", + "DG.Mental.Helplessness": "無力", + "DG.Mental.AdaptedToViolence": "暴力への慣れ", + "DG.Mental.AdaptedToHelplessness": "無力への慣れ", + "DG.Mental.Motivations": "モチベーション", + "DG.Mental.Disorders": "精神障害", + + "DG.Gear.Weapons": "武器", + "DG.Gear.Armor": "防具", + "DG.Gear.OtherGear": "他の装備", + "DG.Gear.Name": "名前", + "DG.Gear.DamageOrLethality": "ダメージ/致命率", + "DG.Gear.ArmorPiercing": "装甲貫通", + "DG.Gear.ArmorRating": "装甲値", + "DG.Gear.Equipped": "装備", + + "DG.CV.Sex": "性別", + "DG.CV.SexPlaceholder": "性別", + "DG.CV.AgeAndDoB": "年齢・誕生日", + "DG.CV.AgeAndDoBPlaceholder": "年齢と誕生日", + "DG.CV.Employer": "雇用者", + "DG.CV.EmployerPlaceholder": "雇用者と職歴", + "DG.CV.Nationality": "国籍", + "DG.CV.NationalityPlaceholder": "国籍", + "DG.CV.Education": "教育", + "DG.CV.EducationPlaceholder": "教育と訓練", + + "DG.Bonds.Bond": "絆", + "DG.Bonds.Name": "名前", + "DG.Bonds.Score": "スコア", + "DG.Bonds.NewBond": "新規絆", + + "DG.Attributes.Tooltip.HP": "ヒットポイント、HPが2になるとエージェントは意識を失い、HPが0で死亡する。", + "DG.Tooltip.MaximumHP": "最大HPはSTRとCONの平均(切り上げ)。", + "DG.Attributes.Tooltip.WP": "意志力ポイント(WP)は精神的な燃料。エージェントは、疲労や精神的に負担のかかる状況下でも活動を続けるために、WPを必要とする。詳細はAgent's Handbook 47ページ参照。", + "DG.Tooltip.MaximumWP": "最大WPはPOWに等しい。", + "DG.Attributes.Tooltip.SAN": "クリックで、SANテストをロール...", + "DG.Tooltip.CurrentSanityPartOne": "現在正気度、現在の限界点は", + "DG.Tooltip.CurrentSanityPartTwo": "、上のSANラベルをクリックで正気度チェックをロール。", + "DG.Tooltip.MaximumSanity": "最大SANは99-非自然技能に等しい。", + "DG.Tooltip.SkillLabel": "クリックで技能チェックをロール。", + "DG.Tooltip.CannotRollSkillLabel": "0%の技能は使用できない、Agent's Handbook 28ページ参照。", + "DG.Tooltip.SkillFailCheckbox": "技能テストに失敗したら(習熟度が少なくとも1%の場合)、このボックスにチェックを入れる。セッションの終了時に、この技能に1D4%ポイントを加え、ボックスのチェックを外す。非自然または儀式技能には適用されない。Agent's Handbook 29ページ参照。", + "DG.Tooltip.DistinguishingFeature": "際立った特徴 (スコアが13以上または8以下の場合、記入する)。", + "DG.Tooltip.x5AttributeLabel": "クリックでx5のテストをロール。", + "DG.Tooltip.FirstAidAttempted": "エージェントが一度応急手当を受けると、別の原因でさらなるダメージを受けるまでは、それ以上の恩恵を受けることはできない。", + "DG.Tooltip.AdaptedToViolence": "暴力に慣れるということは、暴力を行使すべき単なるもう一つの手段と見なすようになり、エージェントの共感が損なわれることを意味する。エージェントはCHAと各絆から1D6を永久的に失う。", + "DG.Tooltip.AdaptedToHelplessness": "無力に慣れるということは、彼らが周囲の世界から身を引くことによって、エージェントの個人的な意欲が損なわれることを意味する。無力に慣れるとすぐに、エージェントは1D6のPOWを永久的に失う。", + "DG.Tooltip.ToggleEquippedState": "クリックでこのアイテムの装備の有無を切り替え。", + "DG.Tooltip.Exhaustion": "長時間働きすぎたり、休息を取らずに極度の危険や負傷に直面したりすると、エージェントは疲労する。 これが起こるのはハンドラー次第だが、目安として、一晩眠らずに過ごしたり、SANやHPを失った後に休息を拒否したりすると、疲労につながる。", + + "DG.Gear.Expense.NA": "N/A", + "DG.Gear.Expense.Incidental": "付帯費用", + "DG.Gear.Expense.Standard": "標準", + "DG.Gear.Expense.Unusual": "特別", + "DG.Gear.Expense.Major": "高額", + "DG.Gear.Expense.Extreme": "極高額", + + "DG.ItemWindow.Bonds.Description": "説明/進展", + "DG.ItemWindow.Bonds.ScoreTooltip": "スコアが高いほど、エージェントと絆の関係性が強いことを示す。", + + "DG.ItemWindow.Motivations.Attributes": "能力値", + "DG.ItemWindow.Motivations.Motivation": "モチベーション", + "DG.ItemWindow.Motivations.Description": "説明とノート", + "DG.ItemWindow.Motivations.Disorder": "精神障害", + "DG.ItemWindow.Motivations.IsDisorder": "精神障害か?", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "キャラクターの原動力になるようなもの", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "限界点に達すると精神障害がモチベーションに取って代わる。", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "精神障害である場合このボックスをチェックする", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "精神障害は\"治癒\"した", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "セラピーでの幸運ロールでクリティカル成功をすると、精神障害を「治療」することができる。しかし、限界点に達した場合それが次回に再発する可能性がある。Agent's Handbook 78~79ページの「Go To Therapy」を参照。", + + "DG.ItemWindow.Gear.Attributes": "能力値", + "DG.ItemWindow.Gear.Description": "説明", + "DG.ItemWindow.Gear.NamePlaceholder": "名前", + "DG.ItemWindow.Gear.Expense": "費用", + "DG.ItemWindow.Gear.Equipped": "装備", + + "DG.ItemWindow.Armor.Description": "説明", + "DG.ItemWindow.Armor.NamePlaceholder": "名前", + "DG.ItemWindow.Armor.ArmorRating": "装甲値", + "DG.ItemWindow.Armor.Expense": "費用", + "DG.ItemWindow.Armor.Equipped": "装備", + + "DG.ItemWindow.Weapons.Description": "説明", + "DG.ItemWindow.Weapons.NamePlaceholder": "名前", + "DG.ItemWindow.Weapons.Skill": "技能", + "DG.ItemWindow.Weapons.Expense": "費用", + "DG.ItemWindow.Weapons.Damage": "ダメージ", + "DG.ItemWindow.Weapons.Lethality": "致命率", + "DG.ItemWindow.Weapons.IsLethality": "致命的", + "DG.ItemWindow.Weapons.LethalityTooltip": "致命武器は、対象を即死させる可能性がある。ダメージダイスではなく、D100をロールする。致命でない場合、ダメージは2d10をロールした結果となる。最初のd10の「00」は10として扱う。", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "致命率のある武器なら、ここにチェックする", + "DG.ItemWindow.Weapons.ArmorPiercing": "装甲貫通", + "DG.ItemWindow.Weapons.Ammo": "弾 (数量/種類)", + "DG.ItemWindow.Weapons.Range": "射程", + "DG.ItemWindow.Weapons.KillRadius": "致命半径", + + "DG.ModifySkillRollDialogue.Title": "ロールの修正", + "DG.ModifySkillRollDialogue.Test": "テスト:", + "DG.ModifySkillRollDialogue.OriginalTarget": "元の目標値:", + "DG.ModifySkillRollDialogue.TargetModifier": "目標値修正:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "技能チェックの目標値にプラスまたはマイナスの修正を加える。", + + "DG.ModifyDamageRollDialogue.Weapon": "武器:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "ここでダイスの式の外を変えられる、結果を2倍にするために使われる。", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "ここでダイスの式の内側を変えられる、結果を「+1」とか、「+1d4」とかにするために使われる。", + + "DG.Roll.Inhuman": "人ならざるもの", + "DG.Tooltip.BreakPoint": "現在の限界点、現在SANがこの値以下に低下した場合にリセットする。初期値はSAN - POW。", + "DG.Tooltip.BreakPointReset": "限界点を現在SAN - WPにリセットする。", + "DG.Skills.ritual": "儀式", + + "DG.RollMode": "ロールモード", + "DG.Bonds.Relationship": "関係", + + "DG.TypeSkills.Subskills.Painting": "絵画", + + "DG.Sheet.BlockHeaders.Attributes": "能力値", + "DG.Sheet.BlockHeaders.Statistics": "能力値", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "身体的特徴とメモ", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "技能と訓練", + "DG.Sheet.BlockHeaders.Injuries": "負傷", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "限界点と慣れ", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "モチベーションと精神障害", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "個人情報 / 経歴", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "絆 / 関係 / 協力者", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "初期値の技能を非表示", + "DG.UnnaturalSheet.NotesLabel": "ノート", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "怪物や種類の説明", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "全ての技能を表示", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "技能・ノート", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "攻撃・能力", + "DG.NPCSheet.BreakPointAbbreviation": "限界点", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "目撃: ", + "DG.ImpossibleLanscapes.YellowSign": "黄色の印", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "腐", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "敗", + "DG.ImpossibleLanscapes.Gift": "ギフト", + "DG.ImpossibleLanscapes.Insight": "ひらめき", + + "DG.VehicleSheet.NotesTabName": "ノート", + "DG.VehicleSheet.GearTabName": "装備", + "DG.VehicleSheet.NotesLabel": "ノート", + "DG.VehicleSheet.DescriptionPlaceHolder": "車両の説明", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "次のホームシーンが終了するまで、ダメージを負った絆のボックスにチェックを入れる。", + "DG.Generic.ClearAll": "全てのチェックを消す", + + "DG.Generic.SanDamage": "SANダメージ", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "目標値", + "DG.ItemWindow.Weapons.SkillModifier": "技能修正", + "DG.ItemWindow.Custom": "カスタム", + + "TYPES.Actor.agent": "エージェント", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "非自然", + "TYPES.Actor.vehicle": "車両", + + "TYPES.Item.armor": "防具", + "TYPES.Item.bond": "絆", + "TYPES.Item.gear": "装備", + "TYPES.Item.motivation": "モチベーション", + "TYPES.Item.weapon": "武器", + "TYPES.Item.tome": "魔道書", + "TYPES.Item.ritual": "儀式", + + "DG.Gear.Tomes": "魔道書", + "DG.Gear.Rituals": "儀式", + + "DG.Tomes.Name": "名前", + "DG.Ritual.Name": "名前", + + "DG.Tome.Name": "名前", + "DG.Tome.Language": "言語", + "DG.Tome.StudyTime": "研究期間", + "DG.ItemWindow.Tome.Description": "説明", + "DG.ItemWindow.Tome.LanguagePlaceholder": "言語", + "DG.ItemWindow.Tome.StudyTime": "研究期間", + "DG.ItemWindow.Tome.OccultIncrease": "オカルト技能増加", + "DG.ItemWindow.Tome.UnnaturalIncrease": "非自然技能増加", + "DG.ItemWindow.Tome.StudySanityDamage": "研究時SANダメージ", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "ハンドラー限定", + "DG.ItemWindow.Tome.HandlerNotes": "ハンドラーノート", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "実行時SANダメージ", + "DG.ItemWindow.Ritual.ActivationTime": "実行時間", + "DG.ItemWindow.Ritual.ActivationCosts": "実行コスト", + "DG.ItemWindow.Ritual.StudyTime": "研究期間", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "習得時SANダメージ", + + "DG.Skills.ruby.accounting": "けいり", + "DG.Skills.ruby.alertness": "けいかい", + "DG.Skills.ruby.anthropology": "じんるいがく", + "DG.Skills.ruby.archeology": "こうこがく", + "DG.Skills.ruby.artillery": "ほう", + "DG.Skills.ruby.athletics": "うんどう", + "DG.Skills.ruby.bureaucracy": "かんりょう", + "DG.Skills.ruby.computer_science": "こんぴゅーたー", + "DG.Skills.ruby.criminology": "はんざいがく", + "DG.Skills.ruby.demolitions": "ばくは", + "DG.Skills.ruby.disguise": "へんそう", + "DG.Skills.ruby.dodge": "かいひ", + "DG.Skills.ruby.drive": "うんてん", + "DG.Skills.ruby.firearms": "しゃげき", + "DG.Skills.ruby.first_aid": "おうきゅうてあて", + "DG.Skills.ruby.forensics": "ほういがく", + "DG.Skills.ruby.heavy_machiner": "じゅうきかいそうさ", + "DG.Skills.ruby.heavy_weapons": "じゅうかき", + "DG.Skills.ruby.history": "れきし", + "DG.Skills.ruby.humint": "ちょうほう", + "DG.Skills.ruby.law": "ほうりつ", + "DG.Skills.ruby.medicine": "いがく", + "DG.Skills.ruby.melee_weapons": "きんせつぶき", + "DG.Skills.ruby.navigate": "なびげーと", + "DG.Skills.ruby.occult": "おかると", + "DG.Skills.ruby.persuade": "せっとく", + "DG.Skills.ruby.pharmacy": "やくがく", + "DG.Skills.ruby.psychotherapy": "しんりりょうほう", + "DG.Skills.ruby.ride": "じょうば", + "DG.Skills.ruby.search": "そうさく", + "DG.Skills.ruby.sigint": "しぎんと", + "DG.Skills.ruby.stealth": "おんみつ", + "DG.Skills.ruby.surgery": "しゅじゅつ", + "DG.Skills.ruby.survival": "さばいばる", + "DG.Skills.ruby.swim": "すいえい", + "DG.Skills.ruby.unarmed_combat": "としゅかくとう", + "DG.Skills.ruby.unnatural": "ひしぜん", + "DG.Skills.ruby.flight": "ひこう", + + "DG.Messages.Skillsmark.Marked": "このスキルはマークされています", + "DG.Messages.Skillsmark.Tooltip": "エージェントハンドブック29ページ参照" +} diff --git a/lang/pl.json b/lang/pl.json new file mode 100644 index 0000000..c0bbc59 --- /dev/null +++ b/lang/pl.json @@ -0,0 +1,426 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "NAZWISKO, IMIE (PSEUDONIM/KRYPTONIM, JESLI DOTYCZY)", + "DG.RollLuck": "Test Szczęścia", + "DG.Luck": "Szczęście", + + "DG.FallbackText.newItem": "Nowy {type}", + + "DG.Skills.accounting": "Księgowość", + "DG.Skills.alertness": "Czujność", + "DG.Skills.anthropology": "Antropologia", + "DG.Skills.archeology": "Archeologia", + "DG.Skills.artillery": "Broń Artyleryjska", + "DG.Skills.athletics": "Atletyka", + "DG.Skills.bureaucracy": "Biurokracja", + "DG.Skills.computer_science": "Informatyka", + "DG.Skills.criminology": "Kryminologia", + "DG.Skills.demolitions": "Materiały Wybuchowe", + "DG.Skills.disguise": "Charakteryzacja", + "DG.Skills.dodge": "Unik", + "DG.Skills.drive": "Prowadzenie Pojazdów", + "DG.Skills.firearms": "Broń Palna", + "DG.Skills.first_aid": "Pierwsza pomoc", + "DG.Skills.forensics": "Kryminalistyka", + "DG.Skills.heavy_machiner": "Obsługa Ciężkich Maszyn", + "DG.Skills.heavy_weapons": "Broń Ciężka", + "DG.Skills.history": "Historia", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Prawo", + "DG.Skills.medicine": "Medycyna", + "DG.Skills.melee_weapons": "Broń Biała", + "DG.Skills.navigate": "Nawigacja", + "DG.Skills.occult": "Okultyzm", + "DG.Skills.persuade": "Perswazja", + "DG.Skills.pharmacy": "Farmacja", + "DG.Skills.psychotherapy": "Psychoterapia", + "DG.Skills.ride": "Jeżdziectwo", + "DG.Skills.search": "Przeszukiwanie", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Ukrywanie", + "DG.Skills.surgery": "Chirurgia", + "DG.Skills.survival": "Sztuka Przetrwania", + "DG.Skills.swim": "Pływanie", + "DG.Skills.unarmed_combat": "Walka Bez Broni", + "DG.Skills.unnatural": "Zjawiska Nadnaturalne", + "DG.Skills.flight": "Latanie", + + "DG.Skills.Tooltip.accounting": "Wykrywanie finansowych sygnałów ostrzegawczych, takich jak ukryte aktywa, firmy fasadowe lub defraudacje.", + "DG.Skills.Tooltip.alertness": "Dostrzegaj ukryte zagrożenia, subtelne ruchy lub ciche dźwięki, zanim staną się one niebezpieczeństwem.", + "DG.Skills.Tooltip.anthropology": "Zrozumienie przekonań, zachowań i tematów tabu w współczesnych kulturach i społeczeństwach.", + "DG.Skills.Tooltip.archeology": "Analiza starożytnych artefaktów i ruin w celu interpretacji dawno wymarłych cywilizacji.", + "DG.Skills.Tooltip.artillery": "Precyzyjna obsługa broni ciężkiej, takiej jak moździerze czy działa czołgowe.", + "DG.Skills.Tooltip.athletics": "Biegaj, wspinaj się, skacz i rzucaj z wyćwiczoną siłą i zwinnością.", + "DG.Skills.Tooltip.bureaucracy": "Poruszaj się po biurokracji, zawieraj umowy z urzędnikami i uzyskaj dostęp do ograniczonych zasobów.", + "DG.Skills.Tooltip.computer_science": "Hakowanie, ochrona lub manipulowanie systemami komputerowymi i odzyskiwanie usuniętych danych.", + "DG.Skills.Tooltip.criminology": "Profilowanie zachowań przestępczych i analizowanie spisków lub wzorców nielegalnej działalności.", + "DG.Skills.Tooltip.demolitions": "Bezpieczne ustawianie, rozbrajanie lub analizowanie urządzeń wybuchowych.", + "DG.Skills.Tooltip.disguise": "Zmień swój wygląd i maniery, aby uniknąć rozpoznania.", + "DG.Skills.Tooltip.dodge": "Unikaj nadchodzących ataków lub ukrywaj się.", + "DG.Skills.Tooltip.drive": "Obsługa pojazdów pod presją, w tym pościgi i trudnym terenie.", + "DG.Skills.Tooltip.firearms": "Celne strzelanie pod presją z pistoletów, karabinów i innej broni strzeleckiej.", + "DG.Skills.Tooltip.first_aid": "Stabilizacja urazów i przywrócenie HP w krótkim okresie.", + "DG.Skills.Tooltip.forensics": "Analizowanie miejsc zbrodni pod kątem ukrytych dowodów przy użyciu metod kryminalistycznych - lub ukrywanie śladów przestępstwa w celu zmylenia śledczych.", + "DG.Skills.Tooltip.heavy_machiner": "Obsługa dużego sprzętu, takiego jak dźwigi, buldożery lub cysterny w sytuacjach wysokiego stresu.", + "DG.Skills.Tooltip.heavy_weapons": "Używaj w walce przenośnej broni ciężkiej, takiej jak karabiny maszynowe lub wyrzutnie rakiet.", + "DG.Skills.Tooltip.history": "Przypomnij sobie fakty historyczne, niejasne odniesienia lub znajdź ukrytą wiedzę.", + "DG.Skills.Tooltip.humint": "Czytaj ludzi, wykrywaj oszustwa i odkrywaj ukryte motywy poprzez interakcję.", + "DG.Skills.Tooltip.law": "Stosowanie lub wykorzystywanie wiedzy prawniczej w celu wygrania spraw sądowych lub uniknięcia oskarżenia.", + "DG.Skills.Tooltip.medicine": "Diagnozowanie i leczenie urazów lub chorób w celu zapewnienia długoterminowej opieki i powrotu do zdrowia.", + "DG.Skills.Tooltip.melee_weapons": "Skuteczna walka w zwarciu przy użyciu noży, pałek lub improwizowanej broni ręcznej.", + "DG.Skills.Tooltip.navigate": "Korzystaj z map, przyrządów lub intuicji, aby znaleźć drogę w nieznanym terenie.", + "DG.Skills.Tooltip.occult": "Zidentyfikuj mity, rytuały i poboczne wierzenia - ale nie oddzielaj prawdy od przesądów.", + "DG.Skills.Tooltip.persuade": "Przekonaj innych do zmiany zdania lub podjęcia działań, których normalnie by nie podjęli.", + "DG.Skills.Tooltip.pharmacy": "Identyfikacja, produkcja lub niewłaściwe użycie narkotyków, odtrutek i trucizn.", + "DG.Skills.Tooltip.psychotherapy": "Diagnozowanie i leczenie zaburzeń psychicznych; uspokajanie lub wspieranie innych w sytuacjach napięcia psychicznego.", + "DG.Skills.Tooltip.ride": "Kontrola i opieka nad wierzchowcami, takimi jak konie czy wielbłądy.", + "DG.Skills.Tooltip.search": "Dokładnie zlokalizuj ukryte przedmioty, pułapki lub wskazówki na danym obszarze.", + "DG.Skills.Tooltip.sigint": "Przechwytywanie, szyfrowanie lub manipulowanie łącznością elektroniczną i systemami nadzoru.", + "DG.Skills.Tooltip.stealth": "Unikaj wykrywania lub ukrywaj obiekty i działania przed wzrokiem.", + "DG.Skills.Tooltip.surgery": "Wykonywanie procedur inwazyjnych w celu ratowania życia lub naprawy krytycznych obrażeń.", + "DG.Skills.Tooltip.survival": "Trop, poluj i przeżyj w dziczy, znajdując pożywienie, schronienie i oznaki niebezpieczeństwa.", + "DG.Skills.Tooltip.swim": "Przetrwanie w wodzie pod przymusem - ratowanie innych, ucieczka lub znoszenie niebezpieczeństw.", + "DG.Skills.Tooltip.unarmed_combat": "Poskromienie lub zranienie przeciwników przy użyciu pięści, chwytów, kopnięć i innych technik walki wręcz.", + "DG.Skills.Tooltip.unnatural": "Rozpoznawanie, badanie lub przypominanie sobie prawd o bytach i siłach wykraczających poza ludzkie zrozumienie.", + + "DG.Skills.AddTypedOrCustomSkill": "Dodaj Typową/Niestandardową Umiejętność", + "DG.Skills.AddSkill": "Dodaj Umiejętność", + "DG.Skills.Apply": "Zastosuj", + "DG.Skills.ApplySkillImprovements.Title": "Zastosuj ulepszenia umiejętności", + "DG.Skills.ApplySkillImprovements.ChatFlavor": "Ulepszono następujące umiejętności o {formula}:", + "DG.Skills.ApplySkillImprovements.DialogLabel": "Ulepsz umiejętności według następującego wzoru: {formula}", + "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing": "Wpływa na następujące umiejętności: {skillList}", + "DG.Skills.ApplySkillImprovements.Warning": "Brak nieudanych umiejętności do ulepszenia.", + "DG.Skills.EditTypedOrCustomSkill": "Edytuj Umiejętność Typowaną/Niestandardową", + "DG.Skills.EditSkill": "Edytuj Umiejętność", + "DG.Skills.SkillGroup": "Grupa Umiejętności", + "DG.Skills.SkillName": "Nazwa Umiejętności", + + "DG.TypeSkills.Art": "Sztuka", + "DG.TypeSkills.Craft": "Rzemiosło", + "DG.TypeSkills.ForeignLanguage": "Język Obcy", + "DG.TypeSkills.MilitaryScience": "Wojskowość", + "DG.TypeSkills.Pilot": "Pilotowanie", + "DG.TypeSkills.Science": "Nauka", + "DG.TypeSkills.Other": "Inne", + + "DG.TypeSkills.Tooltip.Art": "Twórz lub oceniaj dzieła artystyczne i wykrywaj fałszerstwa w danej dziedzinie.", + "DG.TypeSkills.Tooltip.Craft": "Budowanie, naprawianie lub sabotowanie specjalistycznych narzędzi lub systemów, takich jak silniki, zamki lub okablowanie.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Mówisz, czytasz i rozumiesz dany język.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Interpretowanie warunków na polu bitwy, taktyki lub zachowań wojskowych w walce lądowej, morskiej lub powietrznej.", + "DG.TypeSkills.Tooltip.Pilot": "Kontrolowanie i nawigowanie pojazdami powietrznymi, morskimi lub kosmicznymi w krytycznych sytuacjach lub warunkach.", + "DG.TypeSkills.Tooltip.Science": "Zastosowanie specjalistycznej wiedzy naukowej do interpretacji lub badania świata fizycznego.", + "DG.TypeSkills.Tooltip.Other": "Inne", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Dodaj Dodatkowe Szkolenie", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Niestandardowe Umiejętności", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Umiejętności", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Statystyki", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Edytuj Dodatkowe Szkolenie", + "DG.SpecialTraining.Dialog.NameLabel": "Nazwa", + "DG.SpecialTraining.Dialog.SkillLabel": "Umiejętność lub Statystyka", + "DG.SpecialTraining.Dialog.Title": "Stwórz/Edytuj Dodatkowe Szkolenie", + + "DG.Attributes.HP": "PW", + "DG.Attributes.WP": "PSW", + "DG.Attributes.SAN": "PP", + "DG.Attributes.str": "S", + "DG.Attributes.con": "KON", + "DG.Attributes.dex": "ZR", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "MOC", + "DG.Attributes.cha": "CHA", + + "DG.Attributes.Tooltip.HP": "Punkty Wytrzymałości, postać traci przytomność przy 2 PW i umiera przy 0 PW.", + "DG.Attributes.Tooltip.WP": "Punkty Siły Woli to paliwo mentalne. Agenci potrzebują Punktów Siły Woli, aby kontynuować mimo wyczerpania lub mentalnych trudności. Zobacz stronę 47 w Podręczniku Agenta po więcej szczegółów.", + "DG.Attributes.Tooltip.SAN": "Kliknij, aby wykonać test na Poczytalność...", + "DG.Attributes.Tooltip.str": "Zobacz stronę 19 Podręcznika Agenta – Siła", + "DG.Attributes.Tooltip.con": "Zobacz stronę 19 Podręcznika Agenta – Kondycja", + "DG.Attributes.Tooltip.dex": "Zobacz stronę 19 Podręcznika Agenta – Zręczność", + "DG.Attributes.Tooltip.int": "Zobacz stronę 19 Podręcznika Agenta – Inteligencja", + "DG.Attributes.Tooltip.pow": "Zobacz stronę 19 Podręcznika Agenta – Siła Woli", + "DG.Attributes.Tooltip.cha": "Zobacz stronę 19 Podręcznika Agenta – Charyzma", + + "DG.Navigation.Agent.skills": "Umiejętności", + "DG.Navigation.Agent.physical": "Statystyki", + "DG.Navigation.Agent.motivations": "Psychika", + "DG.Navigation.Agent.gear": "Wyposażenie", + "DG.Navigation.Agent.bio": "Osobiste", + "DG.Navigation.Agent.bonds": "Więzi", + "DG.Navigation.NPC.skills": "Umiejętności i szkolenia", + "DG.Navigation.NPC.gear": "Ataki i Zdolności", + "DG.Navigation.Vehicle.gear": "Wyposażenie", + "DG.Navigation.Vehicle.notes": "Uwagi", + + "DG.About.Changelog": "DZIENNIK ZMIAN (ONLINE)", + "DG.About.Copyright": "Opublikowano przez Arc Dream Publishing na mocy umowy z Delta Green Partnership. Własność intelektualna znana jako Delta Green jest znakiem towarowym i prawem autorskim należącym do Delta Green Partnership, które udzieliło tutaj licencji na jej wykorzystanie.", + "DG.About.License": "Zawartość tego systemu jest licencjonowana zgodnie z warunkami dołączonego pliku licencyjnego, z wyjątkiem tych elementów, które są składnikami własności intelektualnej Delta Green.", + "DG.About.OnlineHelp": "Dokumentacja systemu (ONLINE)", + "DG.About.OnlineHelpTooltip": "Uruchom przeglądarkę z dokumentacją online na GitHubie.", + "DG.About.OnlineBugTracker": "Pytania, zgłoszenia błędów lub prośby o funkcje (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Uruchom przeglądarkę z trackerem błędów na GitHubie.", + + "DG.Roll.Rolling": "Rzut na", + "DG.Roll.Target": "Cel: ", + "DG.Roll.Success": "Sukces", + "DG.Roll.Failure": "Porażka", + "DG.Roll.CriticalSuccess": "Krytyczny sukces!", + "DG.Roll.CriticalFailure": "Krytyczna porażka!", + "DG.Roll.Lethality": "Śmiertelność", + "DG.Roll.Lethal": "Śmiertelny", + "DG.Roll.For": "Dla", + "DG.Roll.Damage": "Obrażenia", + "DG.Roll.RollingDamageFor": "Rzut na Obrażenia", + "DG.Roll.Or": "Lub", + "DG.Roll.Roll": "Rzuć", + + "DG.Physical.Wounds": "Rany", + "DG.Physical.FirstAidLabel": "Pierwsza pomoc została już podjęta: ", + "DG.Physical.Exhausted": "Wyczerpany:", + "DG.Physical.ExhaustionPenalty": "Kara:", + + "DG.Generic.AddButtonLabel": "Dodaj", + + "DG.Mental.BreakingPoint": "Punkt Załamania: ", + "DG.Mental.Tooltip.BreakingPoint": "Punkt Załamania to dokładna wartość Poczytalności, przy której Twój Agent został wystarczająco wyczerpany traumą, by rozwinąć nową, długotrwałą chorobę psychiczną. Jeśli Poczytalność osiągnie ten punkt lub spadnie poniżej niego, odejmij Siłę Woli Agenta od nowej Poczytalności. To będzie nowy Punkt Załamania Twojego Agenta.", + "DG.Mental.Reset": "Reset", + "DG.Mental.SanityLossIncidentsLabel": "Utrata PP (Bez Niepoczytalności)", + "DG.Mental.Violence": "Przemoc", + "DG.Mental.Helplessness": "Bezsilność", + "DG.Mental.AdaptedToViolence": "Adaptacja do przemocy", + "DG.Mental.AdaptedToHelplessness": "Adaptacja do bezsilności", + "DG.Mental.Motivations": "Motywacje", + "DG.Mental.Disorders": "Zaburzenia", + + "DG.Gear.WeaponTypes.Firearms": "Broń Palna", + "DG.Gear.WeaponTypes.Melee": "Walka wręcz", + "DG.Gear.Weapons": "Broń", + "DG.Gear.Armor": "Pancerz", + "DG.Gear.OtherGear": "Inny Sprzęt", + "DG.Gear.Name": "Nazwa", + "DG.Gear.DamageOrLethality": "Obrażenia/Śmiertelność", + "DG.Gear.ArmorPiercing": "Przebicie Pancerza", + "DG.Gear.ArmorRating": "Siła Pancerza", + "DG.Gear.Equipped": "Wyposażony", + + "DG.CV.Sex": "Płeć", + "DG.CV.SexPlaceholder": "Płeć", + "DG.CV.AgeAndDoB": "Wiek i Data Ur.", + "DG.CV.AgeAndDoBPlaceholder": "Wiek i Data Urodzenia", + "DG.CV.Employer": "Pracodawca", + "DG.CV.EmployerPlaceholder": "Pracodawca lub Historia Zatrudnienia", + "DG.CV.Nationality": "Narodowość", + "DG.CV.NationalityPlaceholder": "Narodowość", + "DG.CV.Education": "Edukacja", + "DG.CV.EducationPlaceholder": "Edukacja lub Szkolenie", + + "DG.Bonds.Bond": "Więź", + "DG.Bonds.Name": "Nazwa", + "DG.Bonds.Score": "Wynik", + "DG.Bonds.NewBond": "Nowa Więź", + + "DG.Tooltip.MaximumHP": "Maksymalne Punkty Wytrzymałości to średnia STR + CON, zaokrąglona w górę.", + "DG.Tooltip.MaximumWP": "Maksymalne PSW to wartość MOC.", + "DG.Tooltip.CurrentSanityPartOne": "Aktualne PP, aktualny punkt załamania to ", + "DG.Tooltip.CurrentSanityPartTwo": ", kliknij powyższą etykietę PP, aby wykonać test poczytalności.", + "DG.Tooltip.MaximumSanity": "Maksymalne PP to 99 - umiejętność Nadnaturalne.", + "DG.Tooltip.SkillLabel": "Kliknij, aby wykonać test umiejętności.", + "DG.Tooltip.CannotRollSkillLabel": "Umiejętność na poziomie 0% nie może zostać użyta. Zobacz stronę 28 w Podręczniku Agenta.", + "DG.Tooltip.SkillFailCheckbox": "Po niepowodzeniu w teście tej umiejętności (jeśli biegłość wynosi co najmniej 1%), zaznacz to pole. Na końcu sesji dodaj 1D4 punkty procentowe do umiejętności i odznacz pole. Nie dotyczy umiejętności Nienaturalne lub Rituału. Zobacz stronę 29 w Podręczniku Agenta.", + "DG.Tooltip.DistinguishingFeature": "Cechy wyróżniające (wypełnij, jeśli wynik wynosi 13 lub więcej, lub 8 lub mniej).", + "DG.Tooltip.x5AttributeLabel": "Kliknij, aby wykonać test x5.", + "DG.Tooltip.FirstAidAttempted": "Po udzieleniu pierwszej pomocy agent nie może skorzystać z niej ponownie, dopóki nie otrzyma dalszych obrażeń od innego źródła.", + "DG.Tooltip.AdaptedToViolence": "Zaadaptowanie do przemocy oznacza, że empatia agenta cierpi, gdy zaczyna postrzegać przemoc jako narzędzie do wykorzystania. Agent trwale traci 1D6 CHA oraz tę samą wartość ze swoich Więzi.", + "DG.Tooltip.AdaptedToHelplessness": "Zaadaptowanie do bezsilności oznacza, że motywacja agenta cierpi, gdy wycofuje się z otaczającego go świata. Gdy tylko agent dostosuje się do bezsilności, trwale traci 1D6 MOC.", + "DG.Tooltip.ToggleEquippedState": "Kliknij, aby przełączyć stan wyposażenia.", + "DG.Tooltip.Exhaustion": "Agent, który pracuje zbyt długo lub stawia czoła ekstremalnemu niebezpieczeństwu i obrażeniom bez odpoczynku, staje się wyczerpany. Kiedy to nastąpi, zależy od Oficera Prowadzącego, ale dobrą zasadą jest, że nieprzespana noc lub odmowa odpoczynku po utracie PP lub Punktów Wytrzymałości prowadzi do wyczerpania.", + + "DG.Gear.Expense.NA": "N/A albo Brak", + "DG.Gear.Expense.Incidental": "Drobny", + "DG.Gear.Expense.Standard": "Standardowy", + "DG.Gear.Expense.Unusual": "Niezwykły", + "DG.Gear.Expense.Major": "Poważny", + "DG.Gear.Expense.Extreme": "Ekstremalny", + + "DG.ItemWindow.Bonds.Description": "Opis/Rozwój", + "DG.ItemWindow.Bonds.ScoreTooltip": "Wyższy wynik oznacza silniejszą relację między agentem a więzią.", + + "DG.ItemWindow.Motivations.Attributes": "Atrybuty", + "DG.ItemWindow.Motivations.Motivation": "Motywacja", + "DG.ItemWindow.Motivations.Description": "Opis/Uwagi", + "DG.ItemWindow.Motivations.Disorder": "Zaburzenie", + "DG.ItemWindow.Motivations.IsDisorder": "To Zaburzenie", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Coś, co napędza postać.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Zaburzenie zastępuje motywację po osiągnięciu punktu złamania.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Zaznacz to, jeśli dodajesz zaburzenie, lub jeśli istniejąca motywacja została utracona na skutek zyskania zaburzenia.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Zaburzenie zostało \"wyleczone\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Krytyczny sukces w teście terapii może 'wyleczyć' zaburzenie. Może ono powrócić przy następnym osiągnięciu punktu złamania. Zobacz sekcję Terapia na stronach 78-79 Podręcznika Agenta.", + + "DG.ItemWindow.Gear.Attributes": "Atrybuty", + "DG.ItemWindow.Gear.Description": "Opis", + "DG.ItemWindow.Gear.NamePlaceholder": "Nazwa", + "DG.ItemWindow.Gear.Expense": "Koszt", + "DG.ItemWindow.Gear.Equipped": "Wyposażony", + + "DG.ItemWindow.Armor.Description": "Opis", + "DG.ItemWindow.Armor.NamePlaceholder": "Nazwa", + "DG.ItemWindow.Armor.ArmorRating": "Siła Pancerza", + "DG.ItemWindow.Armor.Expense": "Koszt", + "DG.ItemWindow.Armor.Equipped": "Wyposażony", + + "DG.ItemWindow.Weapons.Description": "Opis", + "DG.ItemWindow.Weapons.NamePlaceholder": "Nazwa", + "DG.ItemWindow.Weapons.Skill": "Umiejętność", + "DG.ItemWindow.Weapons.Expense": "Koszt", + "DG.ItemWindow.Weapons.Damage": "Obrażenia", + "DG.ItemWindow.Weapons.Lethality": "Śmiertelność", + "DG.ItemWindow.Weapons.IsLethality": "Jest Śmiertelny", + "DG.ItemWindow.Weapons.LethalityTooltip": "Broń śmiertelna ma szansę natychmiastowo zabić cel. Rzuć D100 zamiast kości obrażeń. Jeśli nie jest śmiertelna, obrażenia są traktowane jakby wynik był rzutem 2d10, z '00' na pierwszym d10 traktowanym jak 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Zaznacz to, jeśli broń ma procentową wartość śmiertelności.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Przebicie Pancerza", + "DG.ItemWindow.Weapons.Ammo": "Amunicja (Ilość/Typ)", + "DG.ItemWindow.Weapons.Range": "Zasięg", + "DG.ItemWindow.Weapons.KillRadius": "Zasięg Śmierci", + + "DG.ModifySkillRollDialogue.Title": "Modyfikuj Rzut", + "DG.ModifySkillRollDialogue.Test": "Test:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Oryginalny Cel:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modyfikator Celu:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Podaj dodatni lub ujemny modyfikator, aby dodać/odjąć od celu dla testu umiejętności.", + + "DG.ModifyDamageRollDialogue.Weapon": "Broń:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Użyj tego pola, aby zmodyfikować zewnętrzną część formuły, na przykład aby podwoić wynik.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Użyj tego pola, aby dodać modyfikator stały, np. '+1' lub inną jednostkową kostkę, np. '+1d4'.", + + "DG.Roll.Inhuman": "Nieludzki", + "DG.Tooltip.BreakPoint": "Aktualny Punkt Załamania, resetowany, gdy aktualne PP spada do tego punktu lub poniżej. Początkowy punkt złamania to PP - MOC.", + "DG.Tooltip.BreakPointReset": "Zresetuj Punkt Załamania, aby wynosił aktualne PP - PSW.", + "DG.Skills.ritual": "Rytuał", + + "DG.RollMode": "Tryb Rzutu", + "DG.Bonds.Relationship": "Relacja", + + "DG.TypeSkills.Subskills.Painting": "Malarstwo", + + "DG.Sheet.BlockHeaders.Attributes": "ATRYBUTY", + "DG.Sheet.BlockHeaders.Statistics": "STATYSTYKI", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "OPIS FIZYCZNY / UWAGI", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "UMIEJĘTNOŚCI I SZKOLENIE", + "DG.Sheet.BlockHeaders.Injuries": "URAZY", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "PUNKT ZŁAMANIA I ADAPTACJE", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTYWACJE I ZABURZENIA", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "DANE OSOBOWE / CV", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "WIĘZI / RELACJE / KONTAKTY", + + "DG.AgentSheet.ProfessionPlaceholder": "ZAWÓD (RANGA, JEŚLI DOTYCZY)", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Ukryj Niewyuczone", + "DG.UnnaturalSheet.NotesLabel": "Uwagi", + "DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Opis stworzenia lub typu stworzenia", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Pokaż Niewyuczone", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Umiejętności i Uwagi", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Ataki i Zdolności", + "DG.NPCSheet.BreakPointAbbreviation": "BP", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "WIDZIAŁEM", + "DG.ImpossibleLanscapes.YellowSign": "ŻÓŁTY ZNAK", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Zepsu", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "cie", + "DG.ImpossibleLanscapes.Gift": "Dar", + "DG.ImpossibleLanscapes.Insight": "Wgląd", + + "DG.VehicleSheet.NotesTabName": "Uwagi", + "DG.VehicleSheet.GearTabName": "Wyposażenie", + "DG.VehicleSheet.NotesLabel": "UWAGI", + "DG.VehicleSheet.DescriptionPlaceHolder": "Opis pojazdu", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Zaznacz pole uszkodzonej więzi, dopóki kolejna scena w domu się nie skończy.", + "DG.Generic.ClearAll": "Wyczyść zaznaczenia", + + "DG.Generic.SanDamage": "Utrata PP", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Cel", + "DG.ItemWindow.Weapons.SkillModifier": "Modyfikator Umiejętności", + "DG.ItemWindow.Custom": "Niestandardowy", + + "DG.Sheet.class.item": "Karta Przedmiotu", + "DG.Sheet.class.agent": "Karta Agenta", + "DG.Sheet.class.npc": "Karta NPC", + "DG.Sheet.class.unnatural": "Karta Nadnaturalnego", + "DG.Sheet.class.vehicle": "Karta Pojazdu", + + "TYPES.Actor.agent": "Agent", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "Nadnaturalne", + "TYPES.Actor.vehicle": "Pojazd", + + "TYPES.Item.armor": "Pancerz", + "TYPES.Item.bond": "Więź", + "TYPES.Item.gear": "Wyposażenie", + "TYPES.Item.motivation": "Motywacja", + "TYPES.Item.weapon": "Broń", + "TYPES.Item.tome": "Księga", + "TYPES.Item.ritual": "Rytuał", + + "DG.Gear.Tomes": "KSIĘGI", + "DG.Gear.Rituals": "RYTUAŁY", + + "DG.Tomes.Name": "Nazwa", + "DG.Ritual.Name": "Nazwa", + + "DG.Tome.Name": "Nazwa", + "DG.Tome.Language": "Język", + "DG.Tome.StudyTime": "Czas Nauki", + "DG.ItemWindow.Tome.Description": "Opis", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Język", + "DG.ItemWindow.Tome.StudyTime": "Czas Nauki", + "DG.ItemWindow.Tome.OccultIncrease": "Zwiększenie Umiejętności Okultyzm", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Zwiększenie Umiejętności Nadnaturalne", + "DG.ItemWindow.Tome.StudySanityDamage": "Uszkodzenie PP po Studiowaniu", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Tylko dla Oficera Prowadzącego", + "DG.ItemWindow.Tome.HandlerNotes": "Uwagi dla Oficera Prowadzącego", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Utrata PP przy Aktywacji", + "DG.ItemWindow.Ritual.ActivationTime": "Czas Aktywacji", + "DG.ItemWindow.Ritual.ActivationCosts": "Koszt Aktywacji", + "DG.ItemWindow.Ritual.StudyTime": "Czas Nauki", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Utrata PP po Nauce", + + "DG.MissionPaused": "Misja wstrzymana", + + "DG.Settings.charactersheet.name": "Styl karty postaci", + "DG.Settings.charactersheet.hint": "Wybierz styl kart postaci. „Program” to nowocześniejszy, rządowy styl, natomiast „Kowboj/Banita” to starszy, bardziej surowy styl przypominający maszynę do pisania.", + "DG.Settings.charactersheet.cowboys": "Kowboje", + "DG.Settings.charactersheet.outlaws": "The Outlaws", + "DG.Settings.charactersheet.program": "Program", + "DG.Settings.sortskills.name": "Sortowanie umiejętności według kolumn?", + "DG.Settings.sortskills.hint": "Zaznaczone sortuje według kolumny. Niezaznaczone sortuje według wierszy.", + "DG.Settings.hideSkillTooltips.name": "Ukryj podpowiedzi umiejętności", + "DG.Settings.hideSkillTooltips.hint": "Nie wyświetlaj podpowiedzi umiejętności na kartach Agenta.", + "DG.Settings.keepSanityPrivate.name": "Ukryj Poczytalność", + "DG.Settings.keepSanityPrivate.hint": "Ukryj Poczytalność przed graczami zarówno na kartach Agentów, jak i w rzutach.", + "DG.Settings.skillImprovementFormula.name": "Domyślny rzut na rozwój umiejętności", + "DG.Settings.skillImprovementFormula.hint": "Domyślnie 1k4. Istniało kilka errat w tej kwestii — wybierz tę opcję, która najlepiej pasuje do tempa twojej gry.", + "DG.Settings.skillImprovementFormula.1": "Stałe +1%", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Pokaż sekcję Hipergeometrii", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Zawsze pokazuj sekcję przedmiotów z Hipergeometrii (np. Rytuały i Tomy) na kartach Agentów, nawet jeśli Agent nie posiada żadnych przedmiotów tego typu.", + "DG.Settings.showImpossibleLandscapesContent.name": "Pokaż zawartość Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Pokaż pola specyficzne dla Impossible Landscapes na kartach Agentów. Pola te są zawsze widoczne tylko dla Oficera prowadzącego, nawet jeśli ta opcja jest zaznaczona.", + "DG.Settings.skillFailure.name": "Automatyczne zaznaczanie niepowodzenia w umiejętności", + "DG.Settings.skillFailure.hint": "Aktywuj tę opcję, aby zawsze zaznaczać pole niepowodzenia po nieudanym teście umiejętności. Oficer prowadzący może cofnąć tę akcję z wiadomości na czacie dotyczącej rzutu.", + "DG.Settings.Saved": "Bieżące ustawienia zostały zapisane.", + + "DG.SettingsMenu.automation.name": "Menu automatyzacji", + "DG.SettingsMenu.automation.label": "Menu automatyzacji", + "DG.SettingsMenu.automation.title": "Ustawienia automatyzacji", + + "DG.SettingsMenu.handler.name": "Ustawienia Oficera Prowadzącego", + "DG.SettingsMenu.handler.label": "Ustawienia Oficera Prowadzącego", + "DG.SettingsMenu.handler.title": "Ustawienia tylko dla Oficera prowadzącego", + + "DG.Messages.Skillsmark.Marked": "Ta umiejętność jest oznaczona.", + "DG.Messages.Skillsmark.Tooltip": "Zobacz str. 29 Podręcznika Agenta." +} diff --git a/lang/pt-BR.json b/lang/pt-BR.json new file mode 100644 index 0000000..3bd7a9f --- /dev/null +++ b/lang/pt-BR.json @@ -0,0 +1,440 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "SOBRENOME, NOME (OU PSEUDÔNIMO)", + "DG.RollLuck": "Rolar Sorte", + "DG.Luck": "Sorte", + + "DG.FallbackText.newItem": "Novo {type}", + + "DG.Skills.accounting": "Contabilidade", + "DG.Skills.alertness": "Prontidão", + "DG.Skills.anthropology": "Antropologia", + "DG.Skills.archeology": "Arqueologia", + "DG.Skills.artillery": "Artilharia", + "DG.Skills.athletics": "Atleticismo", + "DG.Skills.bureaucracy": "Burocracia", + "DG.Skills.computer_science": "Ciências da Computação", + "DG.Skills.criminology": "Criminologia", + "DG.Skills.demolitions": "Demolição", + "DG.Skills.disguise": "Disfarce", + "DG.Skills.dodge": "Esquiva", + "DG.Skills.drive": "Direção", + "DG.Skills.firearms": "Armas de Fogo", + "DG.Skills.first_aid": "Primeiros Socorros", + "DG.Skills.forensics": "Ciência Forense", + "DG.Skills.heavy_machiner": "Maquinario Pesado", + "DG.Skills.heavy_weapons": "Armamento Pesado", + "DG.Skills.history": "História", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Direito", + "DG.Skills.medicine": "Medicina", + "DG.Skills.melee_weapons": "Armas Corpo a Corpo", + "DG.Skills.navigate": "Navegação", + "DG.Skills.occult": "Ocultismo", + "DG.Skills.persuade": "Persuasão", + "DG.Skills.pharmacy": "Farmácia", + "DG.Skills.psychotherapy": "Psicoterapia", + "DG.Skills.ride": "Equitação", + "DG.Skills.search": "Busca", + "DG.Skills.sigint": "SIGINT", + "DG.Skills.stealth": "Furtividade", + "DG.Skills.surgery": "Cirurgia", + "DG.Skills.survival": "Sobrevivência", + "DG.Skills.swim": "Natação", + "DG.Skills.unarmed_combat": "Combate Desarmado", + "DG.Skills.unnatural": "Antinatural", + "DG.Skills.flight": "Pilotagem", + + "DG.Skills.Tooltip.accounting": "Identificar irregularidades financeiras como ativos ocultos, empresas de fachada ou desvio de recursos.", + "DG.Skills.Tooltip.alertness": "Perceber perigos ocultos, movimentos sutis ou sons discretos antes que se tornem ameaças.", + "DG.Skills.Tooltip.anthropology": "Compreender crenças, comportamentos e tabus de culturas e sociedades vivas.", + "DG.Skills.Tooltip.archeology": "Analisar artefatos antigos e ruínas para interpretar civilizações extintas.", + "DG.Skills.Tooltip.artillery": "Operar armas pesadas como morteiros ou canhões de tanque com precisão.", + "DG.Skills.Tooltip.athletics": "Correr, escalar, saltar e arremessar com força e agilidade treinadas.", + "DG.Skills.Tooltip.bureaucracy": "Navegar pela burocracia, negociar com autoridades e obter acesso a recursos restritos.", + "DG.Skills.Tooltip.computer_science": "Invadir, proteger ou manipular sistemas computacionais e recuperar dados apagados.", + "DG.Skills.Tooltip.criminology": "Analisar comportamentos criminosos e identificar conspirações ou padrões de atividade ilícita.", + "DG.Skills.Tooltip.demolitions": "Instalar, desarmar ou analisar dispositivos explosivos com segurança.", + "DG.Skills.Tooltip.disguise": "Alterar aparência e comportamento para evitar reconhecimento.", + "DG.Skills.Tooltip.dodge": "Evitar ataques iminentes ou se mover rapidamente para cobertura.", + "DG.Skills.Tooltip.drive": "Conduzir veículos sob pressão, incluindo perseguições e terrenos difíceis.", + "DG.Skills.Tooltip.firearms": "Atirar com precisão sob pressão usando pistolas, rifles e outras armas leves.", + "DG.Skills.Tooltip.first_aid": "Estabilizar ferimentos e recuperar PV no curto prazo.", + "DG.Skills.Tooltip.forensics": "Analisar cenas de crime em busca de evidências ocultas usando métodos forenses — ou ocultar vestígios para enganar investigadores.", + "DG.Skills.Tooltip.heavy_machiner": "Operar equipamentos de grande porte como guindastes, tratores ou tanques em situações de alto estresse.", + "DG.Skills.Tooltip.heavy_weapons": "Utilizar armamentos pesados portáteis como metralhadoras leves ou lança-foguetes.", + "DG.Skills.Tooltip.history": "Recordar fatos históricos, referências obscuras ou localizar conhecimentos esquecidos.", + "DG.Skills.Tooltip.humint": "Interpretar pessoas, detectar mentiras e revelar motivações ocultas por meio da interação.", + "DG.Skills.Tooltip.law": "Aplicar ou explorar conhecimentos jurídicos para vencer processos ou evitar acusações.", + "DG.Skills.Tooltip.medicine": "Diagnosticar e tratar ferimentos ou doenças para cuidados e recuperação de longo prazo.", + "DG.Skills.Tooltip.melee_weapons": "Combater com eficiência em curta distância usando facas, bastões ou armas improvisadas.", + "DG.Skills.Tooltip.navigate": "Usar mapas, instrumentos ou intuição para se orientar em terrenos desconhecidos.", + "DG.Skills.Tooltip.occult": "Identificar mitos, rituais e crenças marginais — sem distinguir verdade de superstição.", + "DG.Skills.Tooltip.persuade": "Convencer outras pessoas a mudar de opinião ou agir de formas que normalmente não fariam.", + "DG.Skills.Tooltip.pharmacy": "Identificar, produzir ou utilizar medicamentos, antídotos e venenos.", + "DG.Skills.Tooltip.psychotherapy": "Diagnosticar e tratar transtornos mentais; acalmar ou apoiar outros sob estresse psicológico.", + "DG.Skills.Tooltip.ride": "Controlar e cuidar de montarias como cavalos ou camelos.", + "DG.Skills.Tooltip.search": "Localizar minuciosamente objetos ocultos, armadilhas ou pistas em uma área.", + "DG.Skills.Tooltip.sigint": "Interceptar, criptografar ou manipular comunicações eletrônicas e sistemas de vigilância.", + "DG.Skills.Tooltip.stealth": "Evitar detecção ou ocultar objetos e ações da observação.", + "DG.Skills.Tooltip.surgery": "Realizar procedimentos invasivos para salvar vidas ou reparar ferimentos críticos.", + "DG.Skills.Tooltip.survival": "Rastrear, caçar e sobreviver em ambientes hostis, encontrando alimento, abrigo e sinais de perigo.", + "DG.Skills.Tooltip.swim": "Sobreviver na água sob condições adversas — resgatar outros, escapar ou suportar riscos.", + "DG.Skills.Tooltip.unarmed_combat": "Imobilizar ou ferir oponentes usando socos, agarrões, chutes e outras técnicas de combate corporal.", + "DG.Skills.Tooltip.unnatural": "Reconhecer, pesquisar ou recordar verdades sobre entidades e forças além da compreensão humana.", + + "DG.Skills.AddTypedOrCustomSkill": "Adicionar Habilidade Personalizada", + "DG.Skills.AddSkill": "Adicionar Habilidade", + "DG.Skills.Apply": "Aplicar", + "DG.Skills.ApplySkillImprovements.Title": "Aplicar Melhorias", + "DG.Skills.ApplySkillImprovements.ChatFlavor": "Melhorou as seguintes habilidades em", + "DG.Skills.ApplySkillImprovements.DialogLabel": "Melhorar habilidades pela seguinte fórmula:", + "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing": "Afeta as seguintes habilidades:", + "DG.Skills.ApplySkillImprovements.Warning": "Nenhuma habilidade falhada para melhorar.", + "DG.Skills.EditTypedOrCustomSkill": "Editar Habilidade Personalizada", + "DG.Skills.EditSkill": "Editar Habilidade", + "DG.Skills.SkillGroup": "Grupo de Habilidade", + "DG.Skills.SkillName": "Nome da Habilidade", + + "DG.TypeSkills.Art": "Arte", + "DG.TypeSkills.Craft": "Ofício", + "DG.TypeSkills.ForeignLanguage": "Idioma Estrangeiro", + "DG.TypeSkills.MilitaryScience": "Ciência Militar", + "DG.TypeSkills.Pilot": "Pilotar", + "DG.TypeSkills.Science": "Ciência", + "DG.TypeSkills.Other": "Outros", + + "DG.TypeSkills.Tooltip.Art": "Criar ou avaliar obras artísticas e identificar falsificações em uma área específica.", + "DG.TypeSkills.Tooltip.Craft": "Construir, consertar ou sabotar ferramentas ou sistemas especializados, como motores, fechaduras ou fiação.", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Falar, ler e compreender um idioma específico.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Interpretar condições de combate, táticas ou comportamentos militares em operações terrestres, navais ou aéreas.", + "DG.TypeSkills.Tooltip.Pilot": "Controlar e navegar veículos aéreos, marítimos ou espaciais em situações ou condições críticas.", + "DG.TypeSkills.Tooltip.Science": "Aplicar conhecimento científico especializado para interpretar ou investigar o mundo físico.", + "DG.TypeSkills.Tooltip.Other": "Outros.", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Adicionar Treinamento Especial", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Habilidades Personalizadas", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Habilidades", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Estatísticas", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Editar Treinamento Especial", + "DG.SpecialTraining.Dialog.NameLabel": "Nome", + "DG.SpecialTraining.Dialog.SkillLabel": "Habilidade ou Estatística", + "DG.SpecialTraining.Dialog.Title": "Criar/Editar Treinamento Especial", + + "DG.Attributes.HP": "PV", + "DG.Attributes.WP": "FV", + "DG.Attributes.SAN": "SAN", + "DG.Attributes.str": "FOR", + "DG.Attributes.con": "CON", + "DG.Attributes.dex": "DES", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "POD", + "DG.Attributes.cha": "CAR", + + "DG.Attributes.Tooltip.HP": "Pontos de Vida (PV) indicam a saúde física. Um personagem fica inconsciente com 2 PV e morre ao chegar a 0 PV.", + "DG.Attributes.Tooltip.WP": "Pontos de Força de Vontade (FV) indicam a resistência mental e a determinação. Agentes precisam de FV para continuar apesar do cansaço ou de situações mentalmente extenuantes. Veja a página 47 do Manual do Agente para mais detalhes.", + "DG.Attributes.Tooltip.SAN": "Pontos de Sanidade (SAN) indicam a conexão com a humanidade e com a realidade como a maioria das pessoas a percebe. Clique para rolar um teste de SAN.", + "DG.Attributes.Tooltip.str": "Veja a página 19 do Manual do Agente — Força.", + "DG.Attributes.Tooltip.con": "Veja a página 19 do Manual do Agente — Constituição.", + "DG.Attributes.Tooltip.dex": "Veja a página 19 do Manual do Agente — Destreza.", + "DG.Attributes.Tooltip.int": "Veja a página 19 do Manual do Agente — Inteligência.", + "DG.Attributes.Tooltip.pow": "Veja a página 19 do Manual do Agente — Poder.", + "DG.Attributes.Tooltip.cha": "Veja a página 19 do Manual do Agente — Carisma.", + + "DG.Navigation.Agent.skills": "Habilidades", + "DG.Navigation.Agent.physical": "Estatísticas", + "DG.Navigation.Agent.motivations": "Mental", + "DG.Navigation.Agent.gear": "Equipamento", + "DG.Navigation.Agent.bio": "Pessoal", + "DG.Navigation.Agent.bonds": "Laços", + "DG.Navigation.NPC.skills": "Habilidades & Treinamento", + "DG.Navigation.NPC.gear": "Ataques & Habilidades", + "DG.Navigation.Vehicle.gear": "Equipamento", + "DG.Navigation.Vehicle.notes": "Notas", + + "DG.About.Changelog": "CHANGELOG (ONLINE)", + "DG.About.Copyright": "Publicado pela Arc Dream Publishing por meio de acordo com a Delta Green Partnership. A propriedade intelectual conhecida como Delta Green é uma marca registrada e protegida por direitos autorais pertencente à Delta Green Partnership, que licenciou seu uso neste material.", + "DG.About.License": "O conteúdo deste sistema é licenciado de acordo com os termos do arquivo de licença incluído, com exceção dos elementos que fazem parte da propriedade intelectual de Delta Green.", + "DG.About.OnlineHelp": "Abrir Documentação do Sistema em (ONLINE)", + "DG.About.OnlineHelpTooltip": "Abrir navegador com ajuda online GitHub", + "DG.About.OnlineBugTracker": "Dúvidas, Relatos de Erros ou Solicitações de Funcionalides (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Abrir navegador com rastreador de erros GitHub", + + "DG.Roll.Rolling": "Rolando", + "DG.Roll.Target": "Alvo: ", + "DG.Roll.Success": "Sucesso", + "DG.Roll.Failure": "Falha", + "DG.Roll.CriticalSuccess": "Sucesso Crítico!", + "DG.Roll.CriticalFailure": "Falha Crítica!", + "DG.Roll.Lethality": "Letalidade", + "DG.Roll.Lethal": "Letal", + "DG.Roll.For": "Para", + "DG.Roll.Damage": "Dano", + "DG.Roll.RollingDamageFor": "Rolando DANO para", + "DG.Roll.Or": "Ou", + "DG.Roll.Roll": "Rolar", + + "DG.Physical.Wounds": "Ferimentos", + "DG.Physical.FirstAidLabel": "Já houve tentativa de Primeiro Socorros: ", + "DG.Physical.Exhausted": "Exausto(a):", + "DG.Physical.ExhaustionPenalty": "Penalidade:", + + "DG.Generic.AddButtonLabel": "Adicionar", + + "DG.Mental.BreakingPoint": "Ponto de Ruptura: ", + "DG.Mental.Tooltip.BreakingPoint": "O Ponto de Ruptura é o valor exato de SAN no qual seu Agente foi suficientemente desgastado pelo trauma a ponto de desenvolver um novo distúrbio mental de longo prazo. Se a SAN atingir esse valor ou menos, subtraia o POD do Agente da nova SAN. Esse resultado passa a ser o novo Ponto de Ruptura do Agente.", + "DG.Mental.Reset": "Resetar", + "DG.Mental.SanityLossIncidentsLabel": "Perdas de Sanidade sem enlouquecer", + "DG.Mental.Violence": "Violência", + "DG.Mental.Tooltip.Violence": "Adaptação à Violência: após perder SAN por violência três vezes sem enlouquecer, você se torna endurecido a ela. Você passa a ter sucesso automático em testes de SAN contra violência, mas perde permanentemente 1D6 de CAR e o mesmo valor de cada Vínculo. Manual do Agente, página 73.", + "DG.Mental.Helplessness": "Desamparo", + "DG.Mental.Tooltip.Helplessness": "Adaptação ao Desamparo: após perder SAN por desamparo três vezes sem enlouquecer, você se torna endurecido a ele. Você passa a ter sucesso automático em testes de SAN contra desamparo, mas perde permanentemente 1D6 de POD. Manual do Agente, página 73.", + "DG.Mental.AdaptedToViolence": "Adaptado à Violência", + "DG.Mental.AdaptedToHelplessness": "Adaptado ao Desamparo", + "DG.Mental.Motivations": "Motivações", + "DG.Mental.Disorders": "Distúrbios", + + "DG.Gear.Weapons": "Armas", + "DG.Gear.WeaponTypes.Firearms": "Armas de Fogo", + "DG.Gear.WeaponTypes.Melee": "Armas Corpo a Corpo", + "DG.Gear.Armor": "ARMADURA", + "DG.Gear.OtherGear": "OUTROS EQUIPAMENTOS", + "DG.Gear.Name": "Nome", + "DG.Gear.DamageOrLethality": "Dano/Letalidade", + "DG.Gear.ArmorPiercing": "Perfuração de Armadura", + "DG.Gear.ArmorRating": "Categoria de Armadura", + "DG.Gear.Equipped": "Equipado", + + "DG.CV.Sex": "Sexo", + "DG.CV.SexPlaceholder": "Sexo", + "DG.CV.AgeAndDoB": "Idade e Data de Nascimento", + "DG.CV.AgeAndDoBPlaceholder": "Idade e Data de Nascimento", + "DG.CV.Employer": "Empregador", + "DG.CV.EmployerPlaceholder": "Empregador ou Histórico de Trabalho", + "DG.CV.Nationality": "Nacionalidade", + "DG.CV.NationalityPlaceholder": "Nacionalidade", + "DG.CV.Education": "Educação", + "DG.CV.EducationPlaceholder": "Educação ou Treinamento", + + "DG.Bonds.Bond": "Laço", + "DG.Bonds.Name": "Nome", + "DG.Bonds.Score": "Valor", + "DG.Bonds.NewBond": "Novo Laço", + + "DG.Tooltip.MaximumHP": "A Vida máxima é a média de FOR + CON, arredondado para CIMA.", + "DG.Tooltip.MaximumWP": "FV máximo é igual a POD.", + "DG.Tooltip.CurrentSanityPartOne": "Sanidade atual, atual ponto de ruptura é ", + "DG.Tooltip.CurrentSanityPartTwo": ", clique o botão de SAN acima para rolar sanidade.", + "DG.Tooltip.MaximumSanity": "A sanidade máxima é igual a 99 - a habilidade Antinatural.", + "DG.Tooltip.SkillLabel": "Clique para rolar um teste de habilidade.", + "DG.Tooltip.CannotRollSkillLabel": "Uma habilidade com 0% não pode ser usada.", + "DG.Tooltip.SkillFailCheckbox": "Depois de falhar em um teste nesta habilidade (se a proficiência for de pelo menos 1%), marque esta caixa. No final da sessão, adicione 1D4 pontos percentuais à habilidade e desmarque a caixa. Não se aplica à perícia Antinatural ou Ritual. Consulte a página 29 do Manual do Agente.", + "DG.Tooltip.DistinguishingFeature": "Característica Distintiva (preencha se a pontuação for 13 ou superior, ou 8 ou inferior).", + "DG.Tooltip.x5AttributeLabel": "Clique para rolar um cheque x5.", + "DG.Tooltip.FirstAidAttempted": "Uma vez que um agente recebe os primeiros socorros, ele não pode se beneficiar novamente até receber mais danos de uma fonte diferente.", + "DG.Tooltip.AdaptedToViolence": "Estar adaptado à violência significa que a empatia do seu agente sofre quando eles veem a violência como nada além de outra ferramenta a ser usada. O agente perde permanentemente 1D6 CAR e a mesma quantia de cada um de seus vínculos.", + "DG.Tooltip.AdaptedToHelplessness": "Estar adaptado ao desamparo significa que a motivação pessoal do seu agente sofre à medida que ele se afasta do mundo ao seu redor. Assim que seu Agente se adaptar ao desamparo, o agente perde permanentemente 1D6 de POD.", + "DG.Tooltip.ToggleEquippedState": "Clique para alternar se este item está equipado ou não.", + "DG.Tooltip.Exhaustion": "Um agente que trabalha por muito tempo ou enfrenta perigo extremo e ferimentos sem descansar fica exausto. Quando isso entra em jogo depende do Handler, mas uma boa regra é que passar uma noite sem dormir ou se recusar a descansar após perder SAN ou PV leva à exaustão.", + + "DG.Gear.Expense.NA": "N/A", + "DG.Gear.Expense.Incidental": "Incidental", + "DG.Gear.Expense.Standard": "Padrão", + "DG.Gear.Expense.Unusual": "Incomum", + "DG.Gear.Expense.Major": "Maior", + "DG.Gear.Expense.Extreme": "Extremo", + + "DG.ItemWindow.Bonds.Description": "Descrição/Desenvolvimentos", + "DG.ItemWindow.Bonds.ScoreTooltip": "Uma pontuação mais alta representa uma relação mais forte entre o agente e o vínculo.", + + "DG.ItemWindow.Motivations.Attributes": "Atributos", + "DG.ItemWindow.Motivations.Motivation": "Motivação", + "DG.ItemWindow.Motivations.Description": "Descrição/Notas", + "DG.ItemWindow.Motivations.Disorder": "Distúrbio", + "DG.ItemWindow.Motivations.IsDisorder": "É um Distúrbio", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Algo que impulsiona o personagem.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Um distúrbio substitui uma motivação depois de atingir um ponto de ruptura.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Marque isso se adicionar um distúrbio ou se uma motivação existente foi perdida devido ao ganho de um distúrbio.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Distúrbio foi \"Curado\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Um sucesso crítico em um teste de sorte na terapia pode 'curar' um distúrbio. No entanto, pode retornar na próxima vez que um ponto de ruptura for atingido. Consulte a seção Terapia nas páginas 78-79 do Manual do Agente.", + + "DG.ItemWindow.Gear.Attributes": "Atributos", + "DG.ItemWindow.Gear.Description": "Descrição", + "DG.ItemWindow.Gear.NamePlaceholder": "Nome", + "DG.ItemWindow.Gear.Expense": "Custo", + "DG.ItemWindow.Gear.Equipped": "Equipado", + + "DG.ItemWindow.Armor.Description": "Descrição", + "DG.ItemWindow.Armor.NamePlaceholder": "Nome", + "DG.ItemWindow.Armor.ArmorRating": "Categoria de Armadura", + "DG.ItemWindow.Armor.Expense": "Custo", + "DG.ItemWindow.Armor.Equipped": "Equipado", + + "DG.ItemWindow.Weapons.Description": "Descrição", + "DG.ItemWindow.Weapons.NamePlaceholder": "Nome", + "DG.ItemWindow.Weapons.Skill": "Habilidade", + "DG.ItemWindow.Weapons.Expense": "Custo", + "DG.ItemWindow.Weapons.Damage": "Dano", + "DG.ItemWindow.Weapons.Lethality": "Letalide", + "DG.ItemWindow.Weapons.IsLethality": "É Letal", + "DG.ItemWindow.Weapons.LethalityTooltip": "Uma arma letal tem a chance de matar instantaneamente um alvo. Role um D100 em vez de um dado de dano. Se não for letal, o dano é causado como se o resultado fosse uma rolagem de 2d10, com um '00' no primeiro d10 igual a 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Marque isso se a arma tiver uma % de letalidade associada a ela.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Perfuração de Armadura", + "DG.ItemWindow.Weapons.Ammo": "Munição (quantidade/tipo)", + "DG.ItemWindow.Weapons.Range": "Alcance", + "DG.ItemWindow.Weapons.KillRadius": "Raio de Morte", + + "DG.ModifySkillRollDialogue.Title": "Modificar Rolagem", + "DG.ModifySkillRollDialogue.Test": "Teste:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Alvo Original:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modificar Alvo (+/-):", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Dê um modificador positivo ou negativo aqui para adicionar/subtrair do alvo para o teste de perícia.", + + "DG.ModifyDamageRollDialogue.Weapon": "Arma:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Use este campo para modificar a parte externa da fórmula, como dobrar o resultado.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Use este campo para adicionar um modificador simples como '+1' ou outro termo de dados como '+1d4'.", + + "DG.Roll.Inhuman": "Desumano", + "DG.Tooltip.BreakPoint": "O ponto de ruptura atual, redefinido quando a sanidade atual cair para ou abaixo desse valor. O ponto de ruptura inicial é SAN - POW.", + "DG.Tooltip.BreakPointReset": "Redefina o ponto de ruptura para ser SAN - FV.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Modo de Rolagem", + "DG.Bonds.Relationship": "Relacionamento", + + "DG.TypeSkills.Subskills.Painting": "Pintura", + + "DG.Sheet.BlockHeaders.Attributes": "ATRIBUTOS", + "DG.Sheet.BlockHeaders.Statistics": "ESTATÍSTICAS", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "Descrição Física/Notas", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "HABILIDADES E TREINAMENTO", + "DG.Sheet.BlockHeaders.Injuries": "FERIMENTOS", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "PONTO DE RUPTURA E ADAPTAÇÕES", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVAÇÕES E DISTÚRBIOS", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "INFORMAÇÕES PESSOAIS / C.V.", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "LAÇOS / RELACIONAMENTOS / CONTATOS", + + "DG.AgentSheet.ProfessionPlaceholder": "PROFISSÂO", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Esconder Habilidades não Treinadas", + "DG.UnnaturalSheet.NotesLabel": "Notas", + "DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Descrição de Criatura ou Tipo de Criatura", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Mostrar Habilidades não Treinadas", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Habilidades & Notas", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Ataques & Habilidades", + + "DG.NPCSheet.BreakPointAbbreviation": "PR", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "EU JÁ VI O", + "DG.ImpossibleLanscapes.YellowSign": "SÍMBOLO AMARELO", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Corrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "ção", + "DG.ImpossibleLanscapes.Gift": "Dom", + "DG.ImpossibleLanscapes.Insight": "Intuição", + + "DG.VehicleSheet.NotesTabName": "Notas", + "DG.VehicleSheet.GearTabName": "Equipamentos", + "DG.VehicleSheet.NotesLabel": "NOTAS", + "DG.VehicleSheet.DescriptionPlaceHolder": "Descrição do Veículo", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Marcar Vínculos Danificados até a Próxima Cena em Casa", + "DG.Generic.ClearAll": "Limpar Tudo", + + "DG.Generic.SanDamage": "Dano de SAN", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Alvo", + "DG.ItemWindow.Weapons.SkillModifier": "Modificador de Habilidade", + "DG.ItemWindow.Custom": "Personalizado", + + "DG.Sheet.class.item": "Ficha de item", + "DG.Sheet.class.agent": "Ficha de Agente", + "DG.Sheet.class.npc": "Ficha de PNJ", + "DG.Sheet.class.unnatural": "Ficha de Antinatural", + "DG.Sheet.class.vehicle": "Ficha de Veículo", + + "TYPES.Actor.agent": "Agente", + "TYPES.Actor.npc": "PNJ", + "TYPES.Actor.unnatural": "Antinatural", + "TYPES.Actor.vehicle": "Veículo", + + "TYPES.Item.armor": "Armadura", + "TYPES.Item.bond": "Vinculo", + "TYPES.Item.gear": "Equipamento", + "TYPES.Item.motivation": "Motivação", + "TYPES.Item.weapon": "Arma", + "TYPES.Item.tome": "Tomo", + "TYPES.Item.ritual": "Ritual", + + "DG.Gear.Tomes": "TOMOS", + "DG.Gear.Rituals": "RITUAIS", + + "DG.Tomes.Name": "Nome", + "DG.Ritual.Name": "Nome", + + "DG.Tome.Name": "Nome", + "DG.Tome.Language": "Idioma", + "DG.Tome.StudyTime": "Tempo de Estudo", + "DG.ItemWindow.Tome.Description": "Descrição", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Idioma", + "DG.ItemWindow.Tome.StudyTime": "Tempo de Estudo", + "DG.ItemWindow.Tome.OccultIncrease": "Aumento da Habilidade Ocultismo", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Aumento da Habilidade Sobrenatural", + "DG.ItemWindow.Tome.StudySanityDamage": "Dano de SAN ao Estudar", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Chefe Somente", + "DG.ItemWindow.Tome.HandlerNotes": "Notas do Chefe", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Dano de SAN na Ativação", + "DG.ItemWindow.Ritual.ActivationTime": "Tempo de Ativação", + "DG.ItemWindow.Ritual.ActivationCosts": "Custos de Ativação", + "DG.ItemWindow.Ritual.StudyTime": "Tempo de Estudo", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Dano de SAN ao Aprender", + + "DG.MissionPaused": "Operação Pausada", + + "DG.Settings.charactersheet.name": "Estilo da Ficha de Personagem", + "DG.Settings.charactersheet.hint": "Escolha como as fichas devem ser estilizadas. Programa tem um visual governamental moderno, enquanto Caubois/Fora-da-lei remete a um estilo mais antigo e áspero, como datilografado.", + "DG.Settings.charactersheet.cowboys": "Os Caubois", + "DG.Settings.charactersheet.outlaws": "Os Fora-da-lei", + "DG.Settings.charactersheet.program": "O Programa", + + "DG.Settings.sortskills.name": "Ordenar Perícias por Coluna?", + "DG.Settings.sortskills.hint": "Marcado: ordena por coluna. Desmarcado: ordena por linha.", + + "DG.Settings.skillTooltipDisplay.name": "Exibir dicas (tooltips)", + "DG.Settings.skillTooltipDisplay.hint": "Escolha quando exibir as dicas das perícias nas fichas dos Agentes.", + "DG.Settings.skillTooltipDisplay.hover": "Ao passar o mouse (padrão)", + "DG.Settings.skillTooltipDisplay.never": "Nunca", + "DG.Settings.skillTooltipDisplay.hoverShift": "Ao passar o mouse + Shift", + + "DG.Settings.keepSanityPrivate.name": "Manter Sanidade Privada", + "DG.Settings.keepSanityPrivate.hint": "Oculta a Sanidade dos jogadores tanto nas fichas quanto nas rolagens.", + + "DG.Settings.skillImprovementFormula.name": "Rolagem Padrão de Aprimoramento de Perícia", + "DG.Settings.skillImprovementFormula.hint": "Padrão: 1d4. Houve múltiplas erratas sobre isso; escolha a opção que melhor se adequa ao ritmo do seu jogo.", + "DG.Settings.skillImprovementFormula.1": "+1% Fixo", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Exibir Seção de Hipergeometria", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Sempre exibe a seção de itens de Hipergeometria (ex.: Rituais e Tomos) nas fichas dos Agentes, mesmo que o Agente não possua itens desse tipo.", + + "DG.Settings.showImpossibleLandscapesContent.name": "Exibir Conteúdo de Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Exibe campos específicos de Impossible Landscapes nas fichas dos Agentes. Esses campos são sempre visíveis apenas para o Chefe, mesmo com esta opção ativada.", + + "DG.Settings.skillFailure.name": "Marcar Falha de Perícia Automaticamente", + "DG.Settings.skillFailure.hint": "Ative esta opção para marcar automaticamente a caixa de falha ao falhar em uma perícia. O Chefe pode desfazer a ação a partir da mensagem de chat da rolagem.", + + "DG.Settings.Saved": "As configurações atuais foram salvas.", + + "DG.SettingsMenu.automation.name": "Menu de Automação", + "DG.SettingsMenu.automation.label": "Menu de Automação", + "DG.SettingsMenu.automation.title": "Configurações de Automação", + + "DG.SettingsMenu.handler.name": "Configurações do Chefe", + "DG.SettingsMenu.handler.label": "Configurações do Chefe", + "DG.SettingsMenu.handler.title": "Configurações Exclusivas do Chefe", + + "DG.Messages.Skillsmark.Marked": "Esta perícia é marcada", + "DG.Messages.Skillsmark.Tooltip": "Veja pág. 29 do Manual do Agente" +} diff --git a/lang/sv.json b/lang/sv.json new file mode 100644 index 0000000..c87f62a --- /dev/null +++ b/lang/sv.json @@ -0,0 +1,318 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "EFTERNAMN, FÖRNAMN (OCH ALIAS OM RELEVANT)", + "DG.RollLuck": "Turkast", + "DG.Luck": "Tur", + + "DG.FallbackText.ProfessionAndOrRank": "YRKE", + "DG.FallbackText.newItem": "Ny {type}", + + "DG.Skills.accounting": "Bokföring", + "DG.Skills.alertness": "Vaksamhet", + "DG.Skills.anthropology": "Antropologi", + "DG.Skills.archeology": "Arkeologi", + "DG.Skills.artillery": "Artilleri", + "DG.Skills.athletics": "Gymnastik", + "DG.Skills.bureaucracy": "Byråkrati", + "DG.Skills.computer_science": "Datavetenskap", + "DG.Skills.criminology": "Kriminologi", + "DG.Skills.demolitions": "Sprängämnen", + "DG.Skills.disguise": "Förklädnad", + "DG.Skills.dodge": "Undvika", + "DG.Skills.drive": "Framföra Fordon", + "DG.Skills.firearms": "Skjutvapen", + "DG.Skills.first_aid": "Första Hjälpen", + "DG.Skills.forensics": "Kriminalteknik", + "DG.Skills.heavy_machiner": "Tunga Maskiner", + "DG.Skills.heavy_weapons": "Tunga Vapen", + "DG.Skills.history": "Historia", + "DG.Skills.humint": "HUMINT", + "DG.Skills.law": "Juridik", + "DG.Skills.medicine": "Rättsmedicin", + "DG.Skills.melee_weapons": "Närstridsvapen", + "DG.Skills.navigate": "Navigera", + "DG.Skills.occult": "Ockultism", + "DG.Skills.persuade": "Övertala", + "DG.Skills.pharmacy": "Läkemedel", + "DG.Skills.psychotherapy": "Psykoterapi", + "DG.Skills.ride": "Rida", + "DG.Skills.search": "Söka", + "DG.Skills.sigint": "Signalspaning", + "DG.Skills.stealth": "Smyga", + "DG.Skills.surgery": "Kirurgi", + "DG.Skills.survival": "Överlevnadsteknik", + "DG.Skills.swim": "Simma", + "DG.Skills.unarmed_combat": "Slagsmål", + "DG.Skills.unnatural": "Onaturligt", + "DG.Skills.flight": "Flyg", + + "DG.Skills.AddTypedOrCustomSkill": "Lägg till anpassad färdighet", + "DG.Skills.AddSkill": "Lägg till färdighet", + "DG.Skills.Apply": "Tillämpa", + "DG.Skills.ApplySkillImprovements": "Förbättra ibockade färdigheter ", + "DG.Skills.ApplySkillImprovementsChatFlavor": "Förbättrade följande färdigheter med", + "DG.Skills.ApplySkillImprovementsDialogLabel": "Förbättra färdigheter enligt följande formel:", + "DG.Skills.ApplySkillImprovementsDialogEffectsFollowing": "Påverkar följande färdigheter:", + "DG.Skills.ApplySkillImprovementsWarning": "Inga misslyckade slag, inga färdigheter att förbättra.", + "DG.Skills.EditTypedOrCustomSkill": "Redigera anpassad färdighet", + "DG.Skills.EditSkill": "Redigera färdighet", + "DG.Skills.SkillGroup": "Färdighetsgrupp", + "DG.Skills.SkillName": "Färdighetsnamn", + + "DG.TypeSkills.Art": "Konst", + "DG.TypeSkills.Craft": "Hantverk", + "DG.TypeSkills.ForeignLanguage": "Främmande språk", + "DG.TypeSkills.MilitaryScience": "Militärvetenskap", + "DG.TypeSkills.Pilot": "Pilot", + "DG.TypeSkills.Science": "Vetenskap", + "DG.TypeSkills.Other": "Annat", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Lägg till specialträning", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Anpassade färdigheter", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Färdigheter", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Statistik", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Redigera specialträning", + "DG.SpecialTraining.Dialog.NameLabel": "Namn", + "DG.SpecialTraining.Dialog.SkillLabel": "Färdighet eller statistik", + "DG.SpecialTraining.Dialog.Title": "Skapa/Redigera specialträning", + + "DG.Attributes.HP": "HP", + "DG.Attributes.WP": "VP", + "DG.Attributes.SAN": "PSY", + "DG.Attributes.str": "STY", + "DG.Attributes.con": "FYS", + "DG.Attributes.dex": "SMI", + "DG.Attributes.int": "INT", + "DG.Attributes.pow": "VIL", + "DG.Attributes.cha": "KAR", + + "DG.Navigation.Skills": "Färdigheter", + "DG.Navigation.Physical": "Statistik", + "DG.Navigation.Mental": "Psykologi", + "DG.Navigation.Gear": "Utrustning", + "DG.Navigation.CV": "Personligt", + "DG.Navigation.Contacts": "Kontakter", + + "DG.About.OnlineHelp": "Systemdokumentation på (ONLINE)", + "DG.About.OnlineHelpTooltip": "Starta webbläsare med online GitHub-hjälp.", + "DG.About.OnlineBugTracker": "Frågor, buggrapporter eller funktionsförfrågningar (ONLINE)", + "DG.About.OnlineBugTrackerTooltip": "Starta webbläsare med GitHub-issue tracker.", + + "DG.Roll.Rolling": "Slår för", + "DG.Roll.Target": "Mål: ", + "DG.Roll.Success": "Träff", + "DG.Roll.Failure": "Miss", + "DG.Roll.Critical": "Kritisk", + "DG.Roll.Lethality": "Dödlighet", + "DG.Roll.Lethal": "Dödlig", + "DG.Roll.For": "för", + "DG.Roll.Damage": "Skada", + "DG.Roll.RollingDamageFor": "Slår SKADA för", + "DG.Roll.Or": "Eller", + "DG.Roll.Roll": "Slå", + + "DG.Physical.Wounds": "Sår", + "DG.Physical.FirstAidLabel": "Första hjälpen har redan försökts: ", + "DG.Physical.Exhausted": "Utmattad:", + "DG.Physical.ExhaustionPenalty": "Nedsättning:", + + "DG.Generic.AddButtonLabel": "Lägg till", + + "DG.Mental.BreakingPoint": "Brytpunkt: ", + "DG.Mental.Reset": "Reset", + "DG.Mental.SanityLossIncidentsLabel": "Episoder av PSY-förlust utan att bli galen", + "DG.Mental.Violence": "Våld", + "DG.Mental.Helplessness": "Hjälplöshet", + "DG.Mental.AdaptedToViolence": "Anpassad till Våld", + "DG.Mental.AdaptedToHelplessness": "Anpassad till hjälplöshet", + "DG.Mental.Motivations": "Motivation", + "DG.Mental.Disorders": "Störningar", + + "DG.Gear.Weapons": "Vapen", + "DG.Gear.Armor": "Kroppskydd", + "DG.Gear.OtherGear": "Annan utrustning", + "DG.Gear.Name": "Namn", + "DG.Gear.DamageOrLethality": "Skada/Dödlighet", + "DG.Gear.ArmorPiercing": "Genomträngande", + "DG.Gear.ArmorRating": "Skyddsnivå", + "DG.Gear.Equipped": "Utrustad", + + "DG.CV.Sex": "Kön", + "DG.CV.SexPlaceholder": "Kön", + "DG.CV.AgeAndDoB": "Ålder och födelsedatum", + "DG.CV.AgeAndDoBPlaceholder": "Ålder & födelsedatum", + "DG.CV.Employer": "Arbetsgivare", + "DG.CV.EmployerPlaceholder": "Arbetsgivare eller arbetshistorik", + "DG.CV.Nationality": "Nationalitet", + "DG.CV.NationalityPlaceholder": "Nationalitet", + "DG.CV.Education": "Utbildning", + "DG.CV.EducationPlaceholder": "Utbildning eller skola", + + "DG.Bonds.Bond": "Kamrat", + "DG.Bonds.Name": "Namn", + "DG.Bonds.Score": "Poäng", + "DG.Bonds.NewBond": "Ny Kamrat", + + "DG.Attributes.Tooltip.HP": "Hälsopoäng, en karaktär blir medvetslös vid 2 HP och dör vid 0 HP.", + "DG.Tooltip.MaximumHP": "Maximala hälsopoäng är hälften av STY + FYS, avrundat UPP.", + "DG.Attributes.Tooltip.WP": "Viljepoäng är mentalt bränsle. Agenter behöver viljepoäng för att fortsätta trots utmattning eller mentalt påfrestande situationer. Se sidan 47 i Agenthandboken för mer detaljer.", + "DG.Tooltip.MaximumWP": "Maximal VP är lika med VIL.", + "DG.Attributes.Tooltip.SAN": "Klicka för att slå för PSYKE och ser hur Stabil du är.", + "DG.Tooltip.CurrentSanityPartOne": "Nuvarande stabilitet, nuvarande brytpunkt är ", + "DG.Tooltip.CurrentSanityPartTwo": ", klicka på texten PSY ovan för att slå för Stabilitet.", + "DG.Tooltip.MaximumSanity": "Maximal Stabilitet är lika med 99 minus färdigheten Onaturligt.", + "DG.Tooltip.SkillLabel": "Klicka för att kasta tärning.", + "DG.Tooltip.CannotRollSkillLabel": "En färdighet på 0% kan inte användas.", + "DG.Tooltip.SkillFailCheckbox": "Efter att ha misslyckats med ett kast mot denna färdighet (om den är minst 1%), kryssa i denna ruta. Vid sessionens slut, lägg till 1D4 procentenheter till färdigheten och avmarkera rutan. Gäller inte för färdigheterna Onaturligt eller Ritual.", + "DG.Tooltip.DistinguishingFeature": "Utmärkande drag (fyll i om poängen är 13 och över, eller 8 och lägre).", + "DG.Tooltip.x5AttributeLabel": "Klicka för att slå ett x5-slag.", + "DG.Tooltip.FirstAidAttempted": "När en agent redan har fått första hjälpen en gång har de ingen nytta av det igen, om de inte får ytterligare skador.", + "DG.Tooltip.AdaptedToViolence": "Att vara anpassad till våld innebär att din agent förlorat empati och börjat se våld som ett vardagligt verktyg. Agenten förlorar permanent 1D6 KAR och samma mängd från varje Kamrat.", + "DG.Tooltip.AdaptedToHelplessness": "Att vara anpassad till hjälplöshet innebär att din agent förlorat sin personliga drivkraft och drar sig tillbaka från världen omkring dem. När din agent är anpassad till hjälplöshet förlorar agenten permanent 1D6 VIL.", + "DG.Tooltip.ToggleEquippedState": "Klicka för att välja om din agent har saken med sig eller ej.", + "DG.Tooltip.Exhaustion": "En agent som arbetat för länge eller varit under press länge utan sömn blir utmattad.", + + "DG.Gear.Expense.NA": "Ingen", + "DG.Gear.Expense.Incidental": "Småsak", + "DG.Gear.Expense.Standard": "Standard", + "DG.Gear.Expense.Unusual": "Ovanlig", + "DG.Gear.Expense.Major": "Stor", + "DG.Gear.Expense.Extreme": "Extrem", + + "DG.ItemWindow.Bonds.Description": "Beskrivning/Utvecklingar", + "DG.ItemWindow.Bonds.ScoreTooltip": "Högre poäng representerar ett starkare förhållande mellan agenten och Kamraten.", + + "DG.ItemWindow.Motivations.Attributes": "Egenskaper", + "DG.ItemWindow.Motivations.Motivation": "Motivation", + "DG.ItemWindow.Motivations.Description": "Beskrivning/Anteckningar", + "DG.ItemWindow.Motivations.Disorder": "Störning", + "DG.ItemWindow.Motivations.IsDisorder": "Är en Störning", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Något som driver karaktären.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "En störning ersätter en motivation efter att en brytpunkt har nåtts.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Kryssa i detta om du lägger till en störning, eller om en befintlig motivation har förlorats på grund av att du fått en störning.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Störning har blivit \"botad\"", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "En kritisk framgång på ett terapi-turkast kan 'bota' en störning. Den kan dock återkomma nästa gång en brytpunkt nås. Se Terapisektionen på sidorna 78-79 i Agenthandboken.", + + "DG.ItemWindow.Gear.Attributes": "Egenskaper", + "DG.ItemWindow.Gear.Description": "Beskrivning", + "DG.ItemWindow.Gear.NamePlaceholder": "Namn", + "DG.ItemWindow.Gear.Expense": "Kostnad", + "DG.ItemWindow.Gear.Equipped": "Utrustad", + + "DG.ItemWindow.Armor.Description": "Beskrivning", + "DG.ItemWindow.Armor.NamePlaceholder": "Namn", + "DG.ItemWindow.Armor.ArmorRating": "Skyddsnivå", + "DG.ItemWindow.Armor.Expense": "Kostnad", + "DG.ItemWindow.Armor.Equipped": "Utrustad", + + "DG.ItemWindow.Weapons.Description": "Beskrivning", + "DG.ItemWindow.Weapons.NamePlaceholder": "Namn", + "DG.ItemWindow.Weapons.Skill": "Färdighet", + "DG.ItemWindow.Weapons.Expense": "Kostnad", + "DG.ItemWindow.Weapons.Damage": "Skada", + "DG.ItemWindow.Weapons.Lethality": "Dödlighet", + "DG.ItemWindow.Weapons.IsLethality": "Dödlig", + "DG.ItemWindow.Weapons.LethalityTooltip": "Ett dödligt vapen har en chans att omedelbart döda ett mål. Slå en D100 istället för skadetärningen. Om det inte är dödligt tolkas resultatet som om det var 2 enskilda d10or skada, där en '00' på den första d10an motsvarar 10 skada.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Kryssa i detta om vapnet är dödligt.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Genomträngande", + "DG.ItemWindow.Weapons.Ammo": "Ammo (Mängd/Typ)", + "DG.ItemWindow.Weapons.Range": "Räckvidd", + "DG.ItemWindow.Weapons.KillRadius": "Dödsradie", + + "DG.ModifySkillRollDialogue.Title": "Modifiera kast", + "DG.ModifySkillRollDialogue.Test": "Slag:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Ursprungligt mål:", + "DG.ModifySkillRollDialogue.TargetModifier": "Modifiera mål:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Ange en positiv eller negativ modifiering här.", + + "DG.ModifyDamageRollDialogue.Weapon": "Vapen:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Använd detta fält för att modifiera den yttre delen av formeln, som att dubbla resultatet.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Använd detta fält för att lägga till en platt modifierare såsom '+1' eller en annan tärningsterm såsom '+1d4'.", + + "DG.Roll.Inhuman": "Omänsklig", + "DG.Tooltip.BreakPoint": "Den nuvarande brytpunkten, återställs när nuvarande Stabilitet faller till eller under detta värde. Startvärdet på brytpunkten är PSY minus VIL.", + "DG.Tooltip.BreakPointReset": "Återställ brytpunkten till att vara nuvarande PSY minus VP.", + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Tärningskast-läge", + "DG.Bonds.Relationship": "Relation", + + "DG.TypeSkills.Subskills.Painting": "Målning", + + "DG.Sheet.BlockHeaders.Attributes": "EGENSKAPER", + "DG.Sheet.BlockHeaders.Statistics": "STATISTIK", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "ANTECKNINGAR", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "FÄRDIGHETER OCH TRÄNING", + "DG.Sheet.BlockHeaders.Injuries": "SKADOR", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "BRYTPUNKT OCH ANPASSNINGAR", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "MOTIVATIONER OCH STÖRNINGAR", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "PERSONLIG INFORMATION", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "KAMRATER OCH RELATIONER", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Dölj otränade färdigheter", + "DG.UnnaturalSheet.NotesLabel": "Anteckningar", + "DG.UnnaturalSheet.ShortDescriptionFallbackText": "Beskrivning av varelse", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Visa otränade färdigheter", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Färdigheter & Anteckningar", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Attacker & Förmågor", + "DG.NPCSheet.BreakPointAbbreviation": "BP", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "JAG HAR SETT", + "DG.ImpossibleLanscapes.YellowSign": "DET GULA MÄRKET", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Korrup", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "tion", + "DG.ImpossibleLanscapes.Gift": "Gåva", + "DG.ImpossibleLanscapes.Insight": "Insikt", + + "DG.VehicleSheet.NotesTabName": "Anteckningar", + "DG.VehicleSheet.GearTabName": "Utrustning", + "DG.VehicleSheet.NotesLabel": "ANTECKNINGAR", + "DG.VehicleSheet.DescriptionPlaceHolder": "Beskrivning av fordon", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Bocka i rutan om ett förhållande är skadat för att komma ihåg det under Hem-scenerna.", + "DG.Generic.ClearAll": "Rensa alla", + + "DG.Generic.SanDamage": "PSY-Skada", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Mål", + "DG.ItemWindow.Weapons.SkillModifier": "Färdighetsmod", + "DG.ItemWindow.Custom": "Anpassad", + + "TYPES.Actor.agent": "Agent", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "Onaturligt", + "TYPES.Actor.vehicle": "Fordon", + + "TYPES.Item.armor": "Kroppskydd", + "TYPES.Item.bond": "Kamrat", + "TYPES.Item.gear": "Utrustning", + "TYPES.Item.motivation": "Motivation", + "TYPES.Item.weapon": "Vapen", + "TYPES.Item.tome": "Trollbok", + "TYPES.Item.ritual": "Ritual", + + "DG.Gear.Tomes": "Trollböcker", + "DG.Gear.Rituals": "Ritualer", + + "DG.Tomes.Name": "Namn", + "DG.Ritual.Name": "Namn", + + "DG.Tome.Name": "Namn", + "DG.ItemWindow.Tome.Description": "Beskrivning", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Språk", + "DG.ItemWindow.Tome.StudyTime": "Studietid", + "DG.ItemWindow.Tome.OccultIncrease": "Öka ockult färdighet", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Öka onaturlig färdighet", + "DG.ItemWindow.Tome.StudySanityDamage": "Skada på Stabilitet att läsa", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Endast Handledaren", + "DG.ItemWindow.Tome.HandlerNotes": "Handledarens anteckningar", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "PSY-Skada för aktivering", + "DG.ItemWindow.Ritual.ActivationTime": "Aktiveringstid", + "DG.ItemWindow.Ritual.ActivationCosts": "Aktiveringskostnader", + "DG.ItemWindow.Ritual.StudyTime": "Studietid", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Learn SAN Damage", + + "DG.Messages.Skillsmark.Marked": "Denna färdighet är markerad", + "DG.Messages.Skillsmark.Tooltip": "Se s. 29 Agenthandbok" +} diff --git a/lang/uk.json b/lang/uk.json new file mode 100644 index 0000000..4e3e12c --- /dev/null +++ b/lang/uk.json @@ -0,0 +1,431 @@ +{ + "DG.SystemName": "Delta Green", + "DG.AgentNameFieldTooltip": "ПРІЗВИЩЕ, ІМ’Я (ТА ПСЕВДОНІМ, ЯКЩО Є)", + "DG.RollLuck": "Кинути Удачу", + "DG.Luck": "Удача", + + "DG.FallbackText.newItem": "Новий(а) {type}", + + "DG.Skills.accounting": "Бухгалтерія", + "DG.Skills.alertness": "Пильність", + "DG.Skills.anthropology": "Антропологія", + "DG.Skills.archeology": "Археологія", + "DG.Skills.artillery": "Артилерія", + "DG.Skills.athletics": "Атлетика", + "DG.Skills.bureaucracy": "Бюрократія", + "DG.Skills.computer_science": "Інформаційні технології", + "DG.Skills.criminology": "Кримінологія", + "DG.Skills.demolitions": "Інженерно-саперна справа", + "DG.Skills.disguise": "Маскування", + "DG.Skills.dodge": "Ухилення", + "DG.Skills.drive": "Водіння", + "DG.Skills.firearms": "Вогнепальна зброя", + "DG.Skills.first_aid": "Перша допомога", + "DG.Skills.forensics": "Судова експертиза", + "DG.Skills.heavy_machiner": "Важка техніка", + "DG.Skills.heavy_weapons": "Важка зброя", + "DG.Skills.history": "Історія", + "DG.Skills.humint": "Агентурна розвідка (HUMINT)", + "DG.Skills.law": "Правознавство", + "DG.Skills.medicine": "Медицина", + "DG.Skills.melee_weapons": "Холодна зброя", + "DG.Skills.navigate": "Навігація", + "DG.Skills.occult": "Окультизм", + "DG.Skills.persuade": "Переконливість", + "DG.Skills.pharmacy": "Фармацевтика", + "DG.Skills.psychotherapy": "Психотерапія", + "DG.Skills.ride": "Їзда верхи", + "DG.Skills.search": "Пошук", + "DG.Skills.sigint": "Радіоелектронна розвідка (SIGINT)", + "DG.Skills.stealth": "Непомітність", + "DG.Skills.surgery": "Хірургія", + "DG.Skills.survival": "Виживання", + "DG.Skills.swim": "Плавання", + "DG.Skills.unarmed_combat": "Рукопашний бій", + "DG.Skills.unnatural": "Протиприродне", + "DG.Skills.flight": "Пілотування", + + "DG.Skills.Tooltip.accounting": "Помічати фінансові «червоні прапорці»: приховані активи, фірми-«прокладки» або розкрадання.", + "DG.Skills.Tooltip.alertness": "Помічати приховані загрози, ледь помітні рухи або тихі звуки, доки вони не стали небезпекою.", + "DG.Skills.Tooltip.anthropology": "Розуміти вірування, поведінку та табу живих культур і суспільств.", + "DG.Skills.Tooltip.archeology": "Аналізувати давні артефакти та руїни, щоб тлумачити давно загиблі цивілізації.", + "DG.Skills.Tooltip.artillery": "Керувати важким озброєнням (міномети, танкові гармати тощо) з точністю.", + "DG.Skills.Tooltip.athletics": "Бігати, лазити, стрибати й метати з тренованою силою та спритністю.", + "DG.Skills.Tooltip.bureaucracy": "Проходити бюрократію, домовлятися з посадовцями та отримувати доступ до обмежених ресурсів.", + "DG.Skills.Tooltip.computer_science": "Зламувати, захищати або змінювати комп’ютерні системи та відновлювати видалені дані.", + "DG.Skills.Tooltip.criminology": "Профілювати злочинну поведінку та аналізувати змови або закономірності незаконної діяльності.", + "DG.Skills.Tooltip.demolitions": "Безпечно встановлювати, знешкоджувати або аналізувати вибухові пристрої.", + "DG.Skills.Tooltip.disguise": "Змінювати зовнішність і манери, щоб уникнути впізнавання.", + "DG.Skills.Tooltip.dodge": "Ухилятися від атак або ривком займати укриття.", + "DG.Skills.Tooltip.drive": "Керувати транспортом під тиском, включно з погонями та бездоріжжям.", + "DG.Skills.Tooltip.firearms": "Точно стріляти під тиском з пістолетів, гвинтівок та іншої стрілецької зброї.", + "DG.Skills.Tooltip.first_aid": "Стабілізувати поранення та відновити ПЗ на короткий час.", + "DG.Skills.Tooltip.forensics": "Аналізувати місця злочину криміналістичними методами — або приховувати сліди, щоб ввести розслідування в оману.", + "DG.Skills.Tooltip.heavy_machiner": "Керувати важкою технікою (крани, бульдозери, танки) у стресових ситуаціях.", + "DG.Skills.Tooltip.heavy_weapons": "Застосовувати переносне важке озброєння (кулемети, РПГ тощо) у бою.", + "DG.Skills.Tooltip.history": "Пригадувати історичні факти, маловідомі посилання або знаходити приховані знання.", + "DG.Skills.Tooltip.humint": "«Читати» людей, виявляти брехню та приховані мотиви під час взаємодії.", + "DG.Skills.Tooltip.law": "Застосовувати або використати правові знання, щоб вигравати справи чи уникати переслідування.", + "DG.Skills.Tooltip.medicine": "Діагностувати та лікувати травми або хвороби для довготривалої допомоги й відновлення.", + "DG.Skills.Tooltip.melee_weapons": "Ефективно битися на ближній дистанції ножами, кийками або імпровізованою зброєю.", + "DG.Skills.Tooltip.navigate": "Користуватися мапами, приладами або інтуїцією, щоб не заблукати на незнайомій місцевості.", + "DG.Skills.Tooltip.occult": "Розпізнавати міфи, ритуали та маргінальні вірування — але не відрізняти правду від забобонів.", + "DG.Skills.Tooltip.persuade": "Переконувати інших змінити думку або зробити те, чого вони зазвичай не зробили б.", + "DG.Skills.Tooltip.pharmacy": "Розпізнавати, виготовляти або неправильно застосовувати ліки, антидоти та отрути.", + "DG.Skills.Tooltip.psychotherapy": "Діагностувати та лікувати психічні розлади; заспокоювати або підтримувати інших під психологічним тиском.", + "DG.Skills.Tooltip.ride": "Керувати та доглядати верхових тварин (коней тощо).", + "DG.Skills.Tooltip.search": "Ретельно знаходити приховані предмети, пастки або зачіпки в зоні пошуку.", + "DG.Skills.Tooltip.sigint": "Перехоплювати, шифрувати або підміняти електронні комунікації та системи спостереження.", + "DG.Skills.Tooltip.stealth": "Уникати виявлення або приховувати предмети й дії від сторонніх очей.", + "DG.Skills.Tooltip.surgery": "Проводити інвазивні процедури, щоб врятувати життя або усунути критичні ушкодження.", + "DG.Skills.Tooltip.survival": "Вистежувати, полювати та виживати в дикій місцевості: їжа, укриття й ознаки небезпеки.", + "DG.Skills.Tooltip.swim": "Виживати у воді під тиском: рятувати, тікати або витримувати загрози.", + "DG.Skills.Tooltip.unarmed_combat": "Знешкоджувати або травмувати супротивника ударами, захватами та прийомами рукопашного бою.", + "DG.Skills.Tooltip.unnatural": "Розпізнавати, досліджувати або пригадувати істини про сили, що виходять за межі людського розуміння.", + + "DG.Skills.AddTypedOrCustomSkill": "Додати типізовану/власну навичку", + "DG.Skills.AddSkill": "Додати навичку", + "DG.Skills.Apply": "Застосувати", + "DG.Skills.ApplySkillImprovements.Title": "Застосувати покращення навичок", + "DG.Skills.ApplySkillImprovements.ChatFlavor": "Покращено такі навички за формулою {formula}:", + "DG.Skills.ApplySkillImprovements.DialogLabel": "Покращити навички за формулою: {formula}", + "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing": "Впливає на такі навички: {skillList}", + "DG.Skills.ApplySkillImprovements.Warning": "Немає провалених навичок для покращення.", + "DG.Skills.EditTypedOrCustomSkill": "Редагувати типізовану або власну навичку", + "DG.Skills.EditSkill": "Редагувати навичку", + "DG.Skills.SkillGroup": "Група навичок", + "DG.Skills.SkillName": "Назва навички", + + "DG.TypeSkills.Art": "Мистецтво", + "DG.TypeSkills.Craft": "Ремесло", + "DG.TypeSkills.ForeignLanguage": "Іноземна мова", + "DG.TypeSkills.MilitaryScience": "Військова справа", + "DG.TypeSkills.Pilot": "Пілотування", + "DG.TypeSkills.Science": "Наука", + "DG.TypeSkills.Other": "Інше", + + "DG.TypeSkills.Tooltip.Art": "Створювати або оцінювати мистецькі роботи та помічати підробки у вибраній сфері.", + "DG.TypeSkills.Tooltip.Craft": "Будувати, лагодити або саботувати спеціалізовані інструменти чи системи (двигуни, замки, проводка).", + "DG.TypeSkills.Tooltip.ForeignLanguage": "Говорити, читати й розуміти конкретну мову.", + "DG.TypeSkills.Tooltip.MilitaryScience": "Тлумачити умови бою, тактику та військову поведінку на суші, морі або в повітрі.", + "DG.TypeSkills.Tooltip.Pilot": "Керувати та навігувати повітряні/морські/космічні апарати в критичних умовах.", + "DG.TypeSkills.Tooltip.Science": "Застосовувати спеціалізовані наукові знання для тлумачення або дослідження фізичного світу.", + "DG.TypeSkills.Tooltip.Other": "Інше", + + "DG.SpecialTraining.Dialog.CreateSpecialTraining": "Додати спеціальну підготовку", + "DG.SpecialTraining.Dialog.DropDown.CustomSkills": "Власні/типізовані навички", + "DG.SpecialTraining.Dialog.DropDown.Skills": "Навички", + "DG.SpecialTraining.Dialog.DropDown.Statistics": "Характеристики", + "DG.SpecialTraining.Dialog.EditSpecialTraining": "Редагувати спеціальну підготовку", + "DG.SpecialTraining.Dialog.NameLabel": "Назва", + "DG.SpecialTraining.Dialog.SkillLabel": "Навичка або атрибут", + "DG.SpecialTraining.Dialog.Title": "Створити/Редагувати спеціальну підготовку", + + "DG.Attributes.HP": "ПЗ", + "DG.Attributes.WP": "ПВ", + "DG.Attributes.SAN": "ГЗД", + "DG.Attributes.str": "СИЛ", + "DG.Attributes.con": "СТА", + "DG.Attributes.dex": "СПР", + "DG.Attributes.int": "ІНТ", + "DG.Attributes.pow": "НЕП", + "DG.Attributes.cha": "ХАР", + + "DG.Attributes.Tooltip.HP": "Пункти Здоров’я (ПЗ) показують фізичний стан. Персонаж непритомніє при 2 ПЗ і помирає при 0 ПЗ.", + "DG.Attributes.Tooltip.WP": "Пункти Волі (ПВ) показують психічну витримку та внутрішній ресурс. Агентам потрібні ПВ, щоб діяти попри виснаження або ментально важкі ситуації. Див. стор. 47 в Agent's Handbook.", + "DG.Attributes.Tooltip.SAN": "Пункти Глузду (ГЗД) показують зв’язок із людяністю та реальністю, як її сприймає більшість людей. Натисни, щоб кинути тест ГЗД.", + "DG.Attributes.Tooltip.str": "Див. стор. 19 в Agent's Handbook — Strength (Сила)", + "DG.Attributes.Tooltip.con": "Див. стор. 19 в Agent's Handbook — Constitution (Статура)", + "DG.Attributes.Tooltip.dex": "Див. стор. 19 в Agent's Handbook — Dexterity (Спритність)", + "DG.Attributes.Tooltip.int": "Див. стор. 19 в Agent's Handbook — Intelligence (Інтелект)", + "DG.Attributes.Tooltip.pow": "Див. стор. 19 в Agent's Handbook — Power (Непохитність)", + "DG.Attributes.Tooltip.cha": "Див. стор. 19 в Agent's Handbook — Charisma (Харизма)", + + "DG.Navigation.Agent.skills": "Навички", + "DG.Navigation.Agent.physical": "Статистика", + "DG.Navigation.Agent.motivations": "Психологія", + "DG.Navigation.Agent.gear": "Спорядження", + "DG.Navigation.Agent.bio": "Особисте", + "DG.Navigation.Agent.bonds": "Зв’язки", + "DG.Navigation.NPC.skills": "Навички та підготовка", + "DG.Navigation.NPC.gear": "Атаки та здібності", + "DG.Navigation.Vehicle.gear": "Спорядження", + "DG.Navigation.Vehicle.notes": "Нотатки", + + "DG.About.Changelog": "СПИСОК ЗМІН (ОНЛАЙН)", + "DG.About.Copyright": "Опубліковано Arc Dream Publishing за домовленістю з Delta Green Partnership. Інтелектуальна власність під назвою Delta Green є торговельною маркою та об’єктом авторського права Delta Green Partnership, яка ліцензувала її використання тут.", + "DG.About.License": "Вміст цієї системи ліцензовано згідно з умовами файлу license, за винятком елементів, які належать до інтелектуальної власності Delta Green.", + "DG.About.OnlineHelp": "Документація системи (ОНЛАЙН)", + "DG.About.OnlineHelpTooltip": "Відкрити браузер з онлайн-довідкою GitHub.", + "DG.About.OnlineBugTracker": "Запитання, баг-репорти або пропозиції (ОНЛАЙН)", + "DG.About.OnlineBugTrackerTooltip": "Відкрити браузер з трекером задач GitHub.", + + "DG.Roll.Rolling": "Кидаємо...", + "DG.Roll.Target": "Ціль: ", + "DG.Roll.Success": "Успіх", + "DG.Roll.Failure": "Провал", + "DG.Roll.CriticalSuccess": "Критичний успіх!", + "DG.Roll.CriticalFailure": "Критичний провал!", + "DG.Roll.Lethality": "Летальність", + "DG.Roll.Lethal": "Летально", + "DG.Roll.For": "Для", + "DG.Roll.Damage": "Шкода", + "DG.Roll.RollingDamageFor": "Кидок ШКОДИ для", + "DG.Roll.Or": "Або", + "DG.Roll.Roll": "Кинути", + + "DG.Physical.Wounds": "Поранення", + "DG.Physical.FirstAidLabel": "Перша допомога вже була застосована: ", + "DG.Physical.Exhausted": "Виснаження:", + "DG.Physical.ExhaustionPenalty": "Штраф:", + + "DG.Generic.AddButtonLabel": "Додати", + + "DG.Mental.BreakingPoint": "Точка зламу (ТЗ): ", + "DG.Mental.Tooltip.BreakingPoint": "Точка зламу — це конкретне значення ГЗД, на якому Агент настільки виснажений травмою, що отримує новий довготривалий психічний розлад. Якщо ГЗД падає до цього значення або нижче, відніми НЕП (POW) від нового ГЗД. Це і є нова Точка зламу.", + "DG.Mental.Reset": "Скинути", + "DG.Mental.SanityLossIncidentsLabel": "Випадки втрати ГЗД без божевілля", + "DG.Mental.Violence": "Насильство", + "DG.Mental.Tooltip.Violence": "Адаптація до насильства: після втрати ГЗД від насильства тричі без божевілля ти стаєш загартованим. Ти автоматично проходиш кидки ГЗД проти насильства, але назавжди втрачаєш 1D6 ХАР (CHA) і стільки ж з кожного Зв’язку. Agent's Handbook, стор. 73.", + "DG.Mental.Helplessness": "Безпорадність", + "DG.Mental.Tooltip.Helplessness": "Адаптація до безпорадності: після втрати ГЗД від безпорадності тричі без божевілля ти стаєш загартованим. Ти автоматично проходиш кидки ГЗД проти безпорадності, але назавжди втрачаєш 1D6 НЕП (POW). Agent's Handbook, стор. 73.", + "DG.Mental.AdaptedToViolence": "Адаптований до насильства", + "DG.Mental.AdaptedToHelplessness": "Адаптований до безпорадності", + "DG.Mental.Motivations": "Мотивації", + "DG.Mental.Disorders": "Розлади", + + "DG.Gear.WeaponTypes.Firearms": "Вогнепальна", + "DG.Gear.WeaponTypes.Melee": "Холодна", + "DG.Gear.Weapons": "ЗБРОЯ", + "DG.Gear.Armor": "БРОНЯ", + "DG.Gear.OtherGear": "ІНШЕ СПОРЯДЖЕННЯ", + "DG.Gear.Name": "Назва", + "DG.Gear.DamageOrLethality": "Шкода/Летальність", + "DG.Gear.ArmorPiercing": "Бронепробиття", + "DG.Gear.ArmorRating": "Рейтинг броні", + "DG.Gear.Equipped": "Екіпіровано", + + "DG.CV.Sex": "Стать", + "DG.CV.SexPlaceholder": "Стать", + "DG.CV.AgeAndDoB": "Вік і дата народження", + "DG.CV.AgeAndDoBPlaceholder": "Вік і дата народження", + "DG.CV.Employer": "Роботодавець", + "DG.CV.EmployerPlaceholder": "Роботодавець або трудова історія", + "DG.CV.Nationality": "Національність", + "DG.CV.NationalityPlaceholder": "Національність", + "DG.CV.Education": "Освіта", + "DG.CV.EducationPlaceholder": "Освіта або підготовка", + + "DG.Bonds.Bond": "Зв’язок", + "DG.Bonds.Name": "Ім’я", + "DG.Bonds.Score": "Рівень", + "DG.Bonds.NewBond": "Новий зв’язок", + + "DG.Tooltip.MaximumHP": "Максимальні ПЗ — це середнє значення (СИЛ + СТА), округлене ВГОРУ.", + "DG.Tooltip.MaximumWP": "Максимальні ПВ дорівнюють НЕП.", + "DG.Tooltip.CurrentSanityPartOne": "Поточний ГЗД, поточна Точка зламу: ", + "DG.Tooltip.CurrentSanityPartTwo": ". Натисни «ГЗД» вище, щоб кинути перевірку глузду.", + "DG.Tooltip.MaximumSanity": "Максимальний ГЗД дорівнює 99 − навичка «Протиприродне».", + "DG.Tooltip.SkillLabel": "Натисни, щоб кинути перевірку навички.", + "DG.Tooltip.CannotRollSkillLabel": "Навичку з 0% використовувати не можна. Див. стор. 28 в Agent's Handbook.", + "DG.Tooltip.SkillFailCheckbox": "Після провалу перевірки цієї навички (якщо значення хоча б 1%) постав позначку. Наприкінці сесії додай 1D4% до навички й зніми позначку. Не застосовується до «Протиприродне» або «Ритуал». Див. стор. 29 в Agent's Handbook.", + "DG.Tooltip.DistinguishingFeature": "Виразна риса (заповнюється, якщо ХАР 13+ або 8 і нижче).", + "DG.Tooltip.x5AttributeLabel": "Натисни, щоб кинути перевірку x5.", + "DG.Tooltip.FirstAidAttempted": "Після отримання першої допомоги Агент не може знову отримати з неї користь, доки не зазнає нових ушкоджень з іншого джерела.", + "DG.Tooltip.AdaptedToViolence": "Адаптація до насильства означає, що емпатія Агента страждає: насильство стає просто інструментом. Агент назавжди втрачає 1D6 ХАР і стільки ж з кожного Зв’язку.", + "DG.Tooltip.AdaptedToHelplessness": "Адаптація до безпорадності означає, що внутрішній драйв Агента згасає. Щойно Агент адаптується, він назавжди втрачає 1D6 НЕП.", + "DG.Tooltip.ToggleEquippedState": "Натисни, щоб перемкнути стан «Екіпіровано».", + "DG.Tooltip.Exhaustion": "Агент, який працює надто довго або стикається з крайнім ризиком і травмами без відпочинку, виснажується. Коли це настає — вирішує Handler, але хороше правило: ніч без сну або відмова від відпочинку після втрати ГЗД чи ПЗ веде до виснаження.", + + "DG.Gear.Expense.NA": "Н/Д або немає", + "DG.Gear.Expense.Incidental": "Дрібне", + "DG.Gear.Expense.Standard": "Стандартне", + "DG.Gear.Expense.Unusual": "Незвичне", + "DG.Gear.Expense.Major": "Значне", + "DG.Gear.Expense.Extreme": "Екстремальне", + + "DG.ItemWindow.Bonds.Description": "Опис/розвиток", + "DG.ItemWindow.Bonds.ScoreTooltip": "Вищий рівень означає сильніший зв’язок між Агентом і цією людиною.", + + "DG.ItemWindow.Motivations.Attributes": "Атрибути", + "DG.ItemWindow.Motivations.Motivation": "Мотивація", + "DG.ItemWindow.Motivations.Description": "Опис/нотатки", + "DG.ItemWindow.Motivations.Disorder": "Розлад", + "DG.ItemWindow.Motivations.IsDisorder": "Це розлад", + "DG.ItemWindow.Motivations.MotivationNameTooltip": "Те, що рухає персонажа вперед.", + "DG.ItemWindow.Motivations.DisorderNameTooltip": "Розлад замінює мотивацію після досягнення точки зламу.", + "DG.ItemWindow.Motivations.IsDisorderTooltip": "Познач, якщо додаєш розлад або якщо мотивацію втрачено через отримання розладу.", + "DG.ItemWindow.Motivations.DisorderHasBeenCured": "Розлад було «вилікувано»", + "DG.ItemWindow.Motivations.DisorderHasBeenCuredTooltip": "Критичний успіх на терапевтичному кидку Удачі може «вилікувати» розлад. Втім, він може повернутися наступного разу, коли буде досягнуто точки зламу. Див. стор. 78–79 в Agent's Handbook — Therapy.", + + "DG.ItemWindow.Gear.Attributes": "Атрибути", + "DG.ItemWindow.Gear.Description": "Опис", + "DG.ItemWindow.Gear.NamePlaceholder": "Назва", + "DG.ItemWindow.Gear.Expense": "Вартість", + "DG.ItemWindow.Gear.Equipped": "Екіпіровано", + + "DG.ItemWindow.Armor.Description": "Опис", + "DG.ItemWindow.Armor.NamePlaceholder": "Назва", + "DG.ItemWindow.Armor.ArmorRating": "Рейтинг броні", + "DG.ItemWindow.Armor.Expense": "Вартість", + "DG.ItemWindow.Armor.Equipped": "Екіпіровано", + + "DG.ItemWindow.Weapons.Description": "Опис", + "DG.ItemWindow.Weapons.NamePlaceholder": "Назва", + "DG.ItemWindow.Weapons.Skill": "Навичка", + "DG.ItemWindow.Weapons.Expense": "Вартість", + "DG.ItemWindow.Weapons.Damage": "Шкода", + "DG.ItemWindow.Weapons.Lethality": "Летальність", + "DG.ItemWindow.Weapons.IsLethality": "Летальна", + "DG.ItemWindow.Weapons.LethalityTooltip": "Летальна зброя має шанс миттєво вбити ціль. Замість кубів шкоди кидай D100. Якщо результат НЕ летальний, тоді шкода рахується так, ніби випало 2d10, де «00» на першому d10 дорівнює 10.", + "DG.ItemWindow.Weapons.IsLethalityTooltip": "Познач, якщо зброя має відсоток летальності.", + "DG.ItemWindow.Weapons.ArmorPiercing": "Бронепробиття", + "DG.ItemWindow.Weapons.Ammo": "Набої (кількість/тип)", + "DG.ItemWindow.Weapons.Range": "Дальність", + "DG.ItemWindow.Weapons.KillRadius": "Радіус ураження", + + "DG.ModifySkillRollDialogue.Title": "Змінити кидок", + "DG.ModifySkillRollDialogue.Test": "Тест:", + "DG.ModifySkillRollDialogue.OriginalTarget": "Початкова ціль:", + "DG.ModifySkillRollDialogue.TargetModifier": "Змінити ціль:", + "DG.ModifySkillRollDialogue.ModifierTooltip": "Вкажи позитивний або негативний модифікатор, щоб додати/відняти від цілі для перевірки навички.", + + "DG.ModifyDamageRollDialogue.Weapon": "Зброя:", + "DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Це поле змінює зовнішню частину формули, наприклад, щоб подвоїти результат.", + "DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Це поле додає фіксований модифікатор (наприклад, «+1») або інший кістковий термін (наприклад, «+1d4»).", + + "DG.Roll.Inhuman": "Нелюдське", + "DG.Tooltip.BreakPoint": "Поточна точка зламу. Скидається, коли поточний ГЗД падає до цього значення або нижче. Початкова точка зламу: ГЗД − НЕП.", + "DG.Tooltip.BreakPointReset": "Скинути точку зламу до «поточний ГЗД − ПВ».", + "DG.Skills.ritual": "Ритуал", + + "DG.RollMode": "Режим кидка", + "DG.Bonds.Relationship": "Стосунки", + + "DG.TypeSkills.Subskills.Painting": "Живопис", + + "DG.Sheet.BlockHeaders.Attributes": "АТРИБУТИ", + "DG.Sheet.BlockHeaders.Statistics": "СТАТИСТИКА", + "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes": "ФІЗИЧНИЙ ОПИС / НОТАТКИ", + "DG.Sheet.BlockHeaders.SkillsAndTraining": "НАВИЧКИ ТА ПІДГОТОВКА", + "DG.Sheet.BlockHeaders.Injuries": "ТРАВМИ", + "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations": "ТОЧКА ЗЛАМУ ТА АДАПТАЦІЇ", + "DG.Sheet.BlockHeaders.MotivationsAndDisorders": "МОТИВАЦІЇ ТА РОЗЛАДИ", + "DG.Sheet.BlockHeaders.PersonalInfoCV": "ОСОБИСТІ ДАНІ / РЕЗЮМЕ", + "DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "ЗВ’ЯЗКИ / СТОСУНКИ / КОНТАКТИ", + + "DG.AgentSheet.ProfessionPlaceholder": "ПРОФЕСІЯ (ЗВАННЯ, ЯКЩО Є)", + + "DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Приховати нетреновані", + "DG.UnnaturalSheet.NotesLabel": "Нотатки", + "DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Опис істоти або типу істоти", + "DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Показати нетреновані", + "DG.UnnaturalSheet.Tabs.NotesTabLabel": "Навички та нотатки", + "DG.UnnaturalSheet.Tabs.ItemsTabLabel": "Атаки та здібності", + "DG.NPCSheet.BreakPointAbbreviation": "ТЗ", + + "DG.ImpossibleLanscapes.IHaveSeenThe": "Я БАЧИВ", + "DG.ImpossibleLanscapes.YellowSign": "ЖОВТИЙ ЗНАК", + "DG.ImpossibleLanscapes.CorruptionFirstHalf": "Розк", + "DG.ImpossibleLanscapes.CorruptionSecondHalf": "лад", + "DG.ImpossibleLanscapes.Gift": "Дар", + "DG.ImpossibleLanscapes.Insight": "Осяяння", + + "DG.VehicleSheet.NotesTabName": "Нотатки", + "DG.VehicleSheet.GearTabName": "Спорядження", + "DG.VehicleSheet.NotesLabel": "НОТАТКИ", + "DG.VehicleSheet.DescriptionPlaceHolder": "Опис транспорту", + + "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene": "Познач пошкоджений Зв’язок до завершення наступної Домашньої сцени.", + "DG.Generic.ClearAll": "Очистити позначки", + + "DG.Generic.SanDamage": "Втрата ГЗД", + + "DG.ItemWindow.Weapons.CustomSkillTarget": "Ціль", + "DG.ItemWindow.Weapons.SkillModifier": "Модифікатор навички", + "DG.ItemWindow.Custom": "Власне", + + "DG.Sheet.class.item": "Аркуш предмета", + "DG.Sheet.class.agent": "Аркуш агента", + "DG.Sheet.class.npc": "Аркуш NPC", + "DG.Sheet.class.unnatural": "Аркуш протиприродного", + "DG.Sheet.class.vehicle": "Аркуш транспорту", + + "TYPES.Actor.agent": "Агент", + "TYPES.Actor.npc": "NPC", + "TYPES.Actor.unnatural": "Протиприродне", + "TYPES.Actor.vehicle": "Транспорт", + + "TYPES.Item.armor": "Броня", + "TYPES.Item.bond": "Зв’язок", + "TYPES.Item.gear": "Спорядження", + "TYPES.Item.motivation": "Мотивація", + "TYPES.Item.weapon": "Зброя", + "TYPES.Item.tome": "Том", + "TYPES.Item.ritual": "Ритуал", + + "DG.Gear.Tomes": "ТОМИ", + "DG.Gear.Rituals": "РИТУАЛИ", + + "DG.Tomes.Name": "Назва", + "DG.Ritual.Name": "Назва", + + "DG.Tome.Name": "Назва", + "DG.Tome.Language": "Мова", + "DG.Tome.StudyTime": "Час вивчення", + "DG.ItemWindow.Tome.Description": "Опис", + "DG.ItemWindow.Tome.LanguagePlaceholder": "Мова", + "DG.ItemWindow.Tome.StudyTime": "Час вивчення", + "DG.ItemWindow.Tome.OccultIncrease": "Підвищення «Окультизм»", + "DG.ItemWindow.Tome.UnnaturalIncrease": "Підвищення «Протиприродне»", + "DG.ItemWindow.Tome.StudySanityDamage": "Втрата ГЗД від вивчення", + "DG.ItemWindow.Tome.HandlerOnlyTabHeader": "Лише для Handler", + "DG.ItemWindow.Tome.HandlerNotes": "Нотатки для Handler", + + "DG.ItemWindow.Ritual.ActivationSanityDamage": "Втрата ГЗД при активації", + "DG.ItemWindow.Ritual.ActivationTime": "Час активації", + "DG.ItemWindow.Ritual.ActivationCosts": "Вартість активації", + "DG.ItemWindow.Ritual.StudyTime": "Час вивчення", + "DG.ItemWindow.Ritual.LearnedSanityDamage": "Втрата ГЗД при вивченні", + + "DG.MissionPaused": "Місію призупинено", + + "DG.Settings.charactersheet.name": "Стиль аркуша персонажа", + "DG.Settings.charactersheet.hint": "Обери стиль відображення аркушів. «Програма» — більш сучасний «урядовий» стиль. «Ковбої/Поза законом» — старіший, грубіший «друкарська машинка».", + "DG.Settings.charactersheet.cowboys": "Ковбої", + "DG.Settings.charactersheet.outlaws": "Поза законом", + "DG.Settings.charactersheet.program": "Програма", + "DG.Settings.sortskills.name": "Сортувати навички за колонками?", + "DG.Settings.sortskills.hint": "Увімкнено — сортування за колонками. Вимкнено — сортування за рядками.", + "DG.Settings.skillTooltipDisplay.name": "Показувати підказки", + "DG.Settings.skillTooltipDisplay.hint": "Обери, коли показувати підказки до навичок на аркуші Агента.", + "DG.Settings.skillTooltipDisplay.hover": "При наведенні (типово)", + "DG.Settings.skillTooltipDisplay.never": "Ніколи", + "DG.Settings.skillTooltipDisplay.hoverShift": "При наведенні + Shift", + "DG.Settings.keepSanityPrivate.name": "Приховувати ГЗД", + "DG.Settings.keepSanityPrivate.hint": "Приховує ГЗД від гравців і на аркушах, і в кидках.", + "DG.Settings.skillImprovementFormula.name": "Формула покращення навичок за замовчуванням", + "DG.Settings.skillImprovementFormula.hint": "Типово 1d4. Є кілька варіантів еррати — обери той, що підходить під темп твоєї гри.", + "DG.Settings.skillImprovementFormula.1": "Фіксовано +1%", + "DG.Settings.skillImprovementFormula.2": "+1D3%", + "DG.Settings.skillImprovementFormula.3": "+1D4%", + "DG.Settings.skillImprovementFormula.4": "+1D4-1%", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.name": "Показувати розділ «Гіпергеометрія»", + "DG.Settings.alwaysShowHypergeometrySectionForPlayers.hint": "Завжди показувати розділ гіпергеометрії (тобто Ритуали й Томи) на аркуші Агента, навіть якщо в Агента немає таких предметів.", + "DG.Settings.showImpossibleLandscapesContent.name": "Показувати контент Impossible Landscapes", + "DG.Settings.showImpossibleLandscapesContent.hint": "Показує поля, специфічні для Impossible Landscapes, на аркушах Агентів. Ці поля завжди видимі лише Handler, навіть якщо налаштування увімкнено.", + "DG.Settings.skillFailure.name": "Авто-позначка «Провал» для навички", + "DG.Settings.skillFailure.hint": "Автоматично ставить позначку провалу при невдалій перевірці навички. Handler може скасувати дію з повідомлення кидка в чаті.", + "DG.Settings.Saved": "Налаштування збережено.", + + "DG.SettingsMenu.automation.name": "Меню автоматизації", + "DG.SettingsMenu.automation.label": "Меню автоматизації", + "DG.SettingsMenu.automation.title": "Налаштування автоматизації", + + "DG.SettingsMenu.handler.name": "Налаштування Handler", + "DG.SettingsMenu.handler.label": "Налаштування Handler", + "DG.SettingsMenu.handler.title": "Налаштування лише для Handler", + + "DG.Messages.Skillsmark.Marked": "Цю навичку позначено", + "DG.Messages.Skillsmark.Tooltip": "Див. стор. 29 Agent's Handbook" +} diff --git a/module/actor/actor.js b/module/actor/actor.js new file mode 100644 index 0000000..fc1690d --- /dev/null +++ b/module/actor/actor.js @@ -0,0 +1,453 @@ +/** + * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. + * @extends {Actor} + */ +export default class DeltaGreenActor extends Actor { + /** + * Augment the basic actor data with additional dynamic data. + */ + prepareData() { + super.prepareData(); + + const actorData = this; + + // console.log('actor.js prepareData'); + // console.log(this); + + // Make separate methods for each Actor type (character, npc, etc.) to keep + // things organized. + if (actorData.type === "agent") { + this._prepareAgentData(this); + } else if (actorData.type === "unnatural") { + this._prepareUnnaturalData(this); + } else if (actorData.type === "npc") { + this._prepareNpcData(this); + } else if (actorData.type === "vehicle") { + this._prepareVehicleData(this); + } + } + + /** + * + * @param {*} agent + */ + + _prepareVehicleData(actor) { + const actorData = actor; + + // calculate total armor rating + let protection = 0; + for (const i of actor.items) { + if (i.type === "armor") { + if (i.system.equipped === true) { + protection += i.system.protection; + } + } + } + + actorData.system.health.protection = protection; + + // console.log(actor); + } + + _prepareNpcData(actor) { + const { system } = actor; + + // Loop through ability scores, and add their modifiers to our sheet output. + for (const statistic of Object.values(system.statistics)) { + // the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile + statistic.x5 = statistic.value * 5; + } + + // initialize sanity, don't set these afterwards, as they need to be manually edited + if (system.sanity.value >= 100) { + system.sanity.value = system.statistics.pow.x5; + system.sanity.currentBreakingPoint = + system.sanity.value - system.statistics.pow.value; + } + + system.sanity.max = 99 - system.skills.unnatural.proficiency; + + system.wp.max = system.statistics.pow.value; + + try { + system.health.max = Math.ceil( + (system.statistics.con.value + system.statistics.str.value) / 2, + ); + } catch { + system.health.max = 10; + } + + const strength = system.statistics.str; + system.statistics.str.meleeDamageBonusFormula = + this._calculateMeleeDamageBonusFormula(strength.value); + + try { + delete system.skills.ritual; // try to remove legacy skill for ritual if it exists + } catch { + // do nothing + } + + system.sanity.ritual = 99 - system.sanity.value; + + if (system.sanity.ritual > 99) { + system.sanity.ritual = 99; + } else if (system.sanity.ritual < 1) { + system.sanity.ritual = 1; + } + + // calculate total armor rating + let protection = 0; + for (const i of actor.items) { + if (i.type === "armor") { + if (i.system.equipped === true) { + protection += i.system.protection; + } + } + } + + system.health.protection = protection; + + for (const skill of Object.values(system.skills)) { + skill.targetProficiency = skill.proficiency; + } + } + + /** + * + * @param {*} agent + */ + _prepareUnnaturalData(actor) { + const { system } = actor; + + // Loop through ability scores, and add their modifiers to our sheet output. + for (const statistic of Object.values(system.statistics)) { + // the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile + statistic.x5 = statistic.value * 5; + } + + if (system.wp.maxNeedsUpdate) { + system.wp.max = system.statistics.pow.value; + } + + if (system.health.maxNeedsUpdate) { + try { + system.health.max = Math.ceil( + (system.statistics.con.value + system.statistics.str.value) / 2, + ); + } catch { + system.health.max = 10; + } + } + + // calculate total armor rating + let protection = 0; + for (const i of actor.items) { + if (i.type === "armor") { + if (i.system.equipped === true) { + protection += i.system.protection; + } + } + } + + system.health.protection = protection; + + for (const skill of Object.values(system.skills)) { + skill.targetProficiency = skill.proficiency; + } + } + + /** + * Prepare Agent type specific data + */ + _prepareAgentData(agent) { + const { system } = agent; + + // Make modifications to data here. For example: + + // Loop through ability scores, and add their modifiers to our sheet output. + for (const statistic of Object.values(system.statistics)) { + // the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile + statistic.x5 = statistic.value * 5; + } + + try { + delete system.skills.ritual; // try to remove legacy skill for ritual if it exists + } catch { + // do nothing + } + + system.sanity.ritual = 99 - system.sanity.value; + + if (system.sanity.ritual > 99) { + system.sanity.ritual = 99; + } else if (system.sanity.ritual < 1) { + system.sanity.ritual = 1; + } + + // The unnatural skill is sort of special + // It cannot be improved via failure, so add in a special property to reflect this + // Mostly to make it easy to deactivate the failure checkbox in the GUI + for (const [key, skill] of Object.entries(system.skills)) { + if (key === "unnatural") { + skill.cannotBeImprovedByFailure = true; + } else if (key === "luck") { + skill.cannotBeImprovedByFailure = true; + } else if (key === "ritual") { + skill.cannotBeImprovedByFailure = true; + } else { + skill.cannotBeImprovedByFailure = false; + } + + // For ritual skill, it's calculated, so add some logic to turn off changing that entirely. + if (key === "ritual") { + skill.isCalculatedValue = true; + } else { + skill.isCalculatedValue = false; + } + + // Add field for calculation + skill.targetProficiency = skill.proficiency; + } + + system.wp.max = system.statistics.pow.value; + + system.health.max = Math.ceil( + (system.statistics.con.value + system.statistics.str.value) / 2, + ); + + // initialize sanity, don't set these afterwards, as they need to be manually edited + if (system.sanity.value >= 100) { + system.sanity.value = system.statistics.pow.x5; + system.sanity.currentBreakingPoint = + system.sanity.value - system.statistics.pow.value; + } + + system.sanity.max = 99 - system.skills.unnatural.proficiency; + + // Sanity Loss Adaptations Logic + const { adaptations } = system.sanity; + + if ( + adaptations.violence.incident1 && + adaptations.violence.incident2 && + adaptations.violence.incident3 + ) { + system.sanity.adaptations.violence.isAdapted = true; + } else { + system.sanity.adaptations.violence.isAdapted = false; + } + + if ( + adaptations.helplessness.incident1 && + adaptations.helplessness.incident2 && + adaptations.helplessness.incident3 + ) { + system.sanity.adaptations.helplessness.isAdapted = true; + } else { + system.sanity.adaptations.helplessness.isAdapted = false; + } + + if (system.sanity.value <= system.sanity.currentBreakingPoint) { + system.sanity.breakingPointHit = true; + } else { + system.sanity.breakingPointHit = false; + } + + // calculate total armor rating + let protection = 0; + for (const i of agent.items) { + if (i.type === "armor") { + if (i.system.equipped === true) { + protection += i.system.protection; + } + } + } + + system.health.protection = protection; + + const strength = system.statistics.str; + system.statistics.str.meleeDamageBonusFormula = + this._calculateMeleeDamageBonusFormula(strength.value); + + if (system.physical.exhaustedPenalty > 0) { + system.physical.exhaustedPenalty = + -1 * Math.abs(system.physical.exhaustedPenalty); + } + } + + // Returns Bonus From Strength in Hand-to-hand Combat (melee/unarmed) + _calculateMeleeDamageBonusFormula(strengthValue) { + if (strengthValue < 5) { + return "-2"; + } + if (strengthValue < 9) { + return "-1"; + } + if (strengthValue > 12 && strengthValue < 17) { + return "+1"; + } + if (strengthValue > 16) { + return "+2"; + } + return ""; + } + + /** @override */ + static async create(data, options = {}) { + data.prototypeToken = data.prototypeToken || {}; + if (data.type === "agent") { + foundry.utils.mergeObject( + data.prototypeToken, + { + actorLink: true, // this will make the 'Link Actor Data' option for a token is checked by default. So changes to the token sheet will reflect to the actor sheet. + sight: { enabled: true }, + disposition: 1, // friendly, this is a dangerous assumption to make in the agency + }, + { overwrite: false }, + ); + } + return super.create(data, options); + } + + async AddUnarmedAttackItemIfMissing() { + try { + let alreadyAdded = false; + + for (const item of this.items) { + const flag = await item.getFlag("deltagreen", "SystemName"); + + if (flag === "unarmed-attack" || item.name === "Unarmed Attack") { + alreadyAdded = true; + break; + } + } + + if (alreadyAdded === true) { + return; + } + + const handToHandPack = await game.packs.get( + "deltagreen.hand-to-hand-weapons", + ); + const itemIndex = await handToHandPack.getIndex(); + const toAdd = []; // createEmbeddedDocument expects an array + + for (const idx of itemIndex) { + const _temp = await handToHandPack.getDocument(idx._id); + + if (_temp.name === "Unarmed Attack") { + toAdd.push(_temp); + } + } + + const newItems = await this.createEmbeddedDocuments("Item", toAdd); + + for (const item of newItems) { + await item.setFlag("deltagreen", "AutoAdded", true); + + if (item.name === "Unarmed Attack") { + await item.setFlag("deltagreen", "SystemName", "unarmed-attack"); + } + } + } catch (ex) { + console.log("Error adding unarmed strike item to Actor."); + console.log(ex); + } + } + + async AddBaseVehicleItemsIfMissing() { + try { + const flag = await this.getFlag("deltagreen", "DefaultVehicleArmorAdded"); + + if (flag !== null && flag !== undefined && flag !== true) { + console.log("found a flag"); + console.log(flag); + } else { + // mark the actor so that we don't accidently do this again later, or if we want to fix/change something on it in the future + this.setFlag("deltagreen", "DefaultVehicleArmorAdded", true); + + const toAdd = []; // createEmbeddedDocument expects an array + + const armor = await Item.create({ + type: "armor", + name: "Vehicle Frame", + }); + + // this is the current default, but set it anyways in case it gets changed later. + armor.system.protection = 3; + + toAdd.push(armor); + + // create the item on the actor + const newItems = await this.createEmbeddedDocuments("Item", toAdd); + + for (const item of newItems) { + await item.setFlag("deltagreen", "AutoAdded", true); + } + } + } catch (ex) { + console.log(ex); + } + } + + async AddArmorItemToSheet( + name, + description, + protection, + isEquipped, + expense = "NA", + ) { + const armorData = { + type: "armor", + name, + system: { + description, + protection, + equipped: isEquipped, + expense, + }, + }; + + await this.createEmbeddedDocuments("Item", [armorData]); + } + + async AddWeaponItemToSheet( + name, + description, + damage, + skill = "custom", + skillModifier = 0, + customSkillTarget = 50, + armorPiercing = 0, + lethality = 0, + isLethal = false, + range = "10M", + killRadius = "N/A", + ammo = "", + expense = "NA", + equipped = true, + ) { + const weaponData = { + type: "weapon", + name, + system: { + description, + skill, // custom + skillModifier, + customSkillTarget, + range, + damage, + armorPiercing, + lethality, + isLethal, + killRadius, + ammo, + expense, + equipped, + }, + }; + + await this.createEmbeddedDocuments("Item", [weaponData]); + } +} diff --git a/module/config.js b/module/config.js new file mode 100644 index 0000000..7d0c7a4 --- /dev/null +++ b/module/config.js @@ -0,0 +1,69 @@ +/** + * In config.js we can create constants that may be used all around the code base. + * I tried to get some of these values from `game.system` but it seems they + * aren't loaded yet when this is called. Oh well, this shouldn't really ever + * change. + */ + +const DG = /** @type {const} */ ({ + ID: "deltagreen", + + // All the base skills + skills: [ + "accounting", + "alertness", + "anthropology", + "archeology", + "artillery", + "athletics", + "bureaucracy", + "computer_science", + "criminology", + "demolitions", + "disguise", + "dodge", + "drive", + "firearms", + "first_aid", + "forensics", + "heavy_machiner", + "heavy_weapons", + "history", + "humint", + "law", + "medicine", + "melee_weapons", + "navigate", + "occult", + "persuade", + "pharmacy", + "psychotherapy", + "ride", + "search", + "sigint", + "stealth", + "surgery", + "survival", + "swim", + "unarmed_combat", + "unnatural", + "ritual", + ], + + skillImprovementFormulas: { + // If choices are defined, the resulting setting will be a select menu + 1: "DG.Settings.skillImprovementFormula.1", + d3: "DG.Settings.skillImprovementFormula.2", + d4: "DG.Settings.skillImprovementFormula.3", + "d4-1": "DG.Settings.skillImprovementFormula.4", + }, + + // All the base rollable stats. + statistics: ["str", "con", "dex", "int", "pow", "cha"], +}); + +// Set base template path for single source of truth for hbs locations. +const BASE_TEMPLATE_PATH = /** @type {const} */ (`systems/${DG.ID}/templates`); + +export default DG; +export { BASE_TEMPLATE_PATH }; diff --git a/module/data/actor/agent.js b/module/data/actor/agent.js new file mode 100644 index 0000000..a3b1fc8 --- /dev/null +++ b/module/data/actor/agent.js @@ -0,0 +1,58 @@ +import HumanSkillsActorData from "./base/human-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = + foundry.data.fields; + +export default class AgentData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...HumanSkillsActorData.defineSchema(), + schemaVersion: new NumberField({ initial: 1.0 }), + sanity: new SchemaField({ + value: new NumberField({ initial: 100 }), + currentBreakingPoint: new NumberField({ initial: 101 }), + adaptations: new SchemaField({ + violence: new SchemaField({ + incident1: new BooleanField({ initial: false }), + incident2: new BooleanField({ initial: false }), + incident3: new BooleanField({ initial: false }), + }), + helplessness: new SchemaField({ + incident1: new BooleanField({ initial: false }), + incident2: new BooleanField({ initial: false }), + incident3: new BooleanField({ initial: false }), + }), + }), + }), + physical: new SchemaField({ + description: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + wounds: new StringField({ initial: "" }), + firstAidAttempted: new BooleanField({ initial: false }), + exhausted: new BooleanField({ initial: false }), + exhaustedPenalty: new NumberField({ initial: -20 }), + }), + biography: new SchemaField({ + profession: new StringField({ initial: "" }), + employer: new StringField({ initial: "" }), + nationality: new StringField({ initial: "" }), + sex: new StringField({ initial: "" }), + age: new StringField({ initial: "" }), + education: new StringField({ initial: "" }), + }), + corruption: new SchemaField({ + value: new NumberField({ initial: 0 }), + haveSeenTheYellowSign: new BooleanField({ initial: false }), + gift: new StringField({ initial: "" }), + insight: new StringField({ initial: "" }), + }), + }; + } +} diff --git a/module/data/actor/base/base-actor.js b/module/data/actor/base/base-actor.js new file mode 100644 index 0000000..e47ffe0 --- /dev/null +++ b/module/data/actor/base/base-actor.js @@ -0,0 +1,20 @@ +import { resourceField, statisticsField } from "./general.js"; + +const { SchemaField } = foundry.data.fields; + +export default class BaseActorData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + health: resourceField(10, 10), + wp: resourceField(10, 10), + statistics: new SchemaField({ + str: statisticsField(10), + con: statisticsField(10), + dex: statisticsField(10), + int: statisticsField(10), + pow: statisticsField(10), + cha: statisticsField(10), + }), + }; + } +} diff --git a/module/data/actor/base/character.js b/module/data/actor/base/character.js new file mode 100644 index 0000000..fe3636d --- /dev/null +++ b/module/data/actor/base/character.js @@ -0,0 +1,11 @@ +import BaseActorData from "./base-actor.js"; +import SheetSettingsActorData from "./sheet-settings.js"; + +export default class CharacterData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...BaseActorData.defineSchema(), + ...SheetSettingsActorData.defineSchema(), + }; + } +} diff --git a/module/data/actor/base/general.js b/module/data/actor/base/general.js new file mode 100644 index 0000000..0d702bf --- /dev/null +++ b/module/data/actor/base/general.js @@ -0,0 +1,25 @@ +const { SchemaField, NumberField, StringField, BooleanField } = + foundry.data.fields; + +export function skillField(initialValue, label) { + return new SchemaField({ + proficiency: new NumberField({ initial: initialValue }), + label: new StringField({ initial: label }), + failure: new BooleanField({ initial: false }), + }); +} + +export function resourceField(initialValue, initialMax) { + return new SchemaField({ + min: new NumberField({ initial: 0 }), + value: new NumberField({ initial: initialValue }), + max: new NumberField({ initial: initialMax }), + }); +} + +export function statisticsField(initialValue) { + return new SchemaField({ + value: new NumberField({ initial: initialValue }), + distinguishing_feature: new StringField({ initial: "" }), + }); +} diff --git a/module/data/actor/base/human-skills.js b/module/data/actor/base/human-skills.js new file mode 100644 index 0000000..9e5bf7c --- /dev/null +++ b/module/data/actor/base/human-skills.js @@ -0,0 +1,62 @@ +import { skillField } from "./general.js"; + +const { SchemaField, NumberField, StringField, ArrayField, ObjectField } = + foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class HumanSkillsActorData extends TypeDataModel { + static defineSchema() { + return { + skills: new SchemaField({ + accounting: skillField(10, "Accounting"), + alertness: skillField(20, "Alertness"), + anthropology: skillField(0, "Anthropology"), + archeology: skillField(0, "Archeology"), + artillery: skillField(0, "Artillery"), + athletics: skillField(30, "Athletics"), + bureaucracy: skillField(10, "Bureaucracy"), + computer_science: skillField(0, "Computer Science"), + criminology: skillField(10, "Criminology"), + demolitions: skillField(0, "Demolitions"), + disguise: skillField(10, "Disguise"), + dodge: skillField(30, "Dodge"), + drive: skillField(20, "Drive"), + firearms: skillField(20, "Firearms"), + first_aid: skillField(10, "First Aid"), + forensics: skillField(0, "Forensics"), + heavy_machiner: skillField(10, "Heavy Machinery"), + heavy_weapons: skillField(0, "Heavy Weapons"), + history: skillField(10, "History"), + humint: skillField(10, "HUMINT"), + law: skillField(0, "Law"), + medicine: skillField(0, "Medicine"), + melee_weapons: skillField(30, "Melee Weapons"), + navigate: skillField(10, "Navigate"), + occult: skillField(10, "Occult"), + persuade: skillField(20, "Persuade"), + pharmacy: skillField(0, "Pharmacy"), + psychotherapy: skillField(10, "Psychotherapy"), + ride: skillField(10, "Ride"), + search: skillField(20, "Search"), + sigint: skillField(0, "SIGINT"), + stealth: skillField(10, "Stealth"), + surgery: skillField(0, "Surgery"), + survival: skillField(10, "Survival"), + swim: skillField(20, "Swim"), + unarmed_combat: skillField(40, "Unarmed Combat"), + unnatural: new SchemaField({ + proficiency: new NumberField({ initial: 0 }), + label: new StringField({ initial: "Unnatural" }), + }), + }), + typedSkills: new ObjectField({}), + specialTraining: new ArrayField( + new SchemaField({ + attribute: new StringField(), + id: new StringField(), + name: new StringField(), + }), + ), + }; + } +} diff --git a/module/data/actor/base/sheet-settings.js b/module/data/actor/base/sheet-settings.js new file mode 100644 index 0000000..0ebfc87 --- /dev/null +++ b/module/data/actor/base/sheet-settings.js @@ -0,0 +1,21 @@ +const { SchemaField, NumberField, BooleanField } = foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class SheetSettingsActorData extends TypeDataModel { + static defineSchema() { + return { + settings: new SchemaField({ + sorting: new SchemaField({ + weaponSortAlphabetical: new BooleanField({ initial: false }), + armorSortAlphabetical: new BooleanField({ initial: false }), + gearSortAlphabetical: new BooleanField({ initial: false }), + tomeSortAlphabetical: new BooleanField({ initial: false }), + ritualSortAlphabetical: new BooleanField({ initial: false }), + }), + rolling: new SchemaField({ + defaultPercentileModifier: new NumberField({ initial: 20 }), + }), + }), + }; + } +} diff --git a/module/data/actor/base/unnatural-skills.js b/module/data/actor/base/unnatural-skills.js new file mode 100644 index 0000000..5278f52 --- /dev/null +++ b/module/data/actor/base/unnatural-skills.js @@ -0,0 +1,62 @@ +import { skillField } from "./general.js"; + +const { SchemaField, NumberField, StringField, ArrayField, ObjectField } = + foundry.data.fields; +const { TypeDataModel } = foundry.abstract; + +export default class UnnaturalSkillsActorData extends TypeDataModel { + static defineSchema() { + return { + skills: new SchemaField({ + accounting: skillField(0, "Accounting"), + alertness: skillField(50, "Alertness"), + anthropology: skillField(0, "Anthropology"), + archeology: skillField(0, "Archeology"), + artillery: skillField(0, "Artillery"), + athletics: skillField(50, "Athletics"), + bureaucracy: skillField(0, "Bureaucracy"), + computer_science: skillField(0, "Computer Science"), + criminology: skillField(0, "Criminology"), + demolitions: skillField(0, "Demolitions"), + disguise: skillField(0, "Disguise"), + dodge: skillField(50, "Dodge"), + drive: skillField(0, "Drive"), + firearms: skillField(0, "Firearms"), + first_aid: skillField(0, "First Aid"), + forensics: skillField(0, "Forensics"), + heavy_machiner: skillField(0, "Heavy Machinery"), + heavy_weapons: skillField(0, "Heavy Weapons"), + history: skillField(0, "History"), + humint: skillField(0, "HUMINT"), + law: skillField(0, "Law"), + medicine: skillField(0, "Medicine"), + melee_weapons: skillField(50, "Melee Weapons"), + navigate: skillField(0, "Navigate"), + occult: skillField(0, "Occult"), + persuade: skillField(0, "Persuade"), + pharmacy: skillField(0, "Pharmacy"), + psychotherapy: skillField(0, "Psychotherapy"), + ride: skillField(0, "Ride"), + search: skillField(0, "Search"), + sigint: skillField(0, "SIGINT"), + stealth: skillField(50, "Stealth"), + surgery: skillField(0, "Surgery"), + survival: skillField(0, "Survival"), + swim: skillField(0, "Swim"), + unarmed_combat: skillField(50, "Unarmed Combat"), + unnatural: new SchemaField({ + proficiency: new NumberField({ initial: 0 }), + label: new StringField({ initial: "Unnatural" }), + }), + }), + typedSkills: new ObjectField({}), + specialTraining: new ArrayField( + new SchemaField({ + attribute: new StringField(), + id: new StringField(), + name: new StringField(), + }), + ), + }; + } +} diff --git a/module/data/actor/npc.js b/module/data/actor/npc.js new file mode 100644 index 0000000..412cfc1 --- /dev/null +++ b/module/data/actor/npc.js @@ -0,0 +1,27 @@ +import HumanSkillsActorData from "./base/human-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = + foundry.data.fields; + +export default class NPCData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...HumanSkillsActorData.defineSchema(), + schemaVersion: new NumberField({ initial: 1.0 }), + sanity: new SchemaField({ + value: new NumberField({ initial: 100 }), + currentBreakingPoint: new NumberField({ initial: 101 }), + }), + biography: new SchemaField({ + profession: new StringField({ initial: "" }), + }), + notes: new HTMLField({ initial: "", blank: true, textSearch: true }), + shortDescription: new StringField({ initial: "" }), + showUntrainedSkills: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/data/actor/unnatural.js b/module/data/actor/unnatural.js new file mode 100644 index 0000000..7e293b6 --- /dev/null +++ b/module/data/actor/unnatural.js @@ -0,0 +1,30 @@ +import UnnaturalSkillsActorData from "./base/unnatural-skills.js"; +import CharacterData from "./base/character.js"; + +const { SchemaField, NumberField, StringField, BooleanField, HTMLField } = + foundry.data.fields; + +export default class UnnaturalData extends CharacterData { + static defineSchema() { + const superData = super.defineSchema(); + + return { + ...superData, + ...UnnaturalSkillsActorData.defineSchema(), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D4" }), + successLoss: new StringField({ initial: "1" }), + }), + schemaVersion: new NumberField({ initial: 1.0 }), + notes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + allowColor: true, + }), + shortDescription: new StringField({ initial: "" }), + showUntrainedSkills: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/data/actor/vehicle.js b/module/data/actor/vehicle.js new file mode 100644 index 0000000..e6e75e3 --- /dev/null +++ b/module/data/actor/vehicle.js @@ -0,0 +1,27 @@ +import SheetSettingsActorData from "./base/sheet-settings.js"; + +const { SchemaField, NumberField, StringField, ArrayField, HTMLField } = + foundry.data.fields; + +export default class VehicleData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...SheetSettingsActorData.defineSchema(), + name: new StringField({ initial: "" }), + description: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + shortDescription: new StringField({ initial: "" }), + health: new SchemaField({ + value: new NumberField({ initial: 10 }), + min: new NumberField({ initial: 0 }), + max: new NumberField({ initial: 10 }), + }), + speed: new StringField({ initial: "" }), + expense: new StringField({ initial: "Standard" }), + passengers: new ArrayField(new StringField()), + }; + } +} diff --git a/module/data/item/armor.js b/module/data/item/armor.js new file mode 100644 index 0000000..58e47ef --- /dev/null +++ b/module/data/item/armor.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class ArmorItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + protection: new NumberField({ initial: 3, integer: true }), + equipped: new BooleanField({ initial: true }), + expense: new StringField({ initial: "Standard" }), + }; + } +} diff --git a/module/data/item/base-fields.js b/module/data/item/base-fields.js new file mode 100644 index 0000000..896b518 --- /dev/null +++ b/module/data/item/base-fields.js @@ -0,0 +1,11 @@ +const { HTMLField } = foundry.data.fields; + +/** + * Shared system fields for all Delta Green item types (from legacy template base). + * Item display name lives on the document (`Item#name`), not in system. + */ +export default function defineBaseItemSystemFields() { + return { + description: new HTMLField({ initial: "", blank: true, textSearch: true }), + }; +} diff --git a/module/data/item/bond.js b/module/data/item/bond.js new file mode 100644 index 0000000..81ff8df --- /dev/null +++ b/module/data/item/bond.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class BondItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + score: new NumberField({ initial: 10, integer: true }), + relationship: new StringField({ initial: "" }), + hasBeenDamagedSinceLastHomeScene: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/gear.js b/module/data/item/gear.js new file mode 100644 index 0000000..8d54208 --- /dev/null +++ b/module/data/item/gear.js @@ -0,0 +1,13 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { StringField, BooleanField } = foundry.data.fields; + +export default class GearItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + equipped: new BooleanField({ initial: true }), + expense: new StringField({ initial: "Standard" }), + }; + } +} diff --git a/module/data/item/motivation.js b/module/data/item/motivation.js new file mode 100644 index 0000000..5d0831f --- /dev/null +++ b/module/data/item/motivation.js @@ -0,0 +1,14 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { StringField, BooleanField } = foundry.data.fields; + +export default class MotivationItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + disorder: new StringField({ initial: "" }), + crossedOut: new BooleanField({ initial: false }), + disorderCured: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/ritual.js b/module/data/item/ritual.js new file mode 100644 index 0000000..7386cf8 --- /dev/null +++ b/module/data/item/ritual.js @@ -0,0 +1,33 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField, SchemaField, HTMLField } = + foundry.data.fields; + +export default class RitualItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + studyTime: new StringField({ initial: "" }), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D10" }), + successLoss: new StringField({ initial: "0" }), + }), + learnedSanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D10" }), + successLoss: new StringField({ initial: "0" }), + }), + unnaturalSkillIncrease: new NumberField({ initial: 1, integer: true }), + activationCosts: new StringField({ initial: "" }), + activationTime: new StringField({ initial: "" }), + complexity: new StringField({ initial: "Simple" }), + handlerNotes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + revealed: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/tome.js b/module/data/item/tome.js new file mode 100644 index 0000000..2673153 --- /dev/null +++ b/module/data/item/tome.js @@ -0,0 +1,27 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField, SchemaField, HTMLField } = + foundry.data.fields; + +export default class TomeItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + language: new StringField({ initial: "" }), + studyTime: new StringField({ initial: "" }), + unnaturalSkillIncrease: new NumberField({ initial: 5, integer: true }), + occultSkillIncrease: new NumberField({ initial: 3, integer: true }), + sanity: new SchemaField({ + notes: new StringField({ initial: "" }), + failedLoss: new StringField({ initial: "1D6" }), + successLoss: new StringField({ initial: "1D4" }), + }), + handlerNotes: new HTMLField({ + initial: "", + blank: true, + textSearch: true, + }), + revealed: new BooleanField({ initial: false }), + }; + } +} diff --git a/module/data/item/weapon.js b/module/data/item/weapon.js new file mode 100644 index 0000000..11777a2 --- /dev/null +++ b/module/data/item/weapon.js @@ -0,0 +1,23 @@ +import defineBaseItemSystemFields from "./base-fields.js"; + +const { NumberField, StringField, BooleanField } = foundry.data.fields; + +export default class WeaponItemData extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + ...defineBaseItemSystemFields(), + skill: new StringField({ initial: "" }), + skillModifier: new NumberField({ initial: 0, integer: true }), + customSkillTarget: new NumberField({ initial: 50, integer: true }), + range: new StringField({ initial: "10M" }), + damage: new StringField({ initial: "1D8" }), + armorPiercing: new NumberField({ initial: 0, integer: true }), + lethality: new NumberField({ initial: 0, integer: true }), + isLethal: new BooleanField({ initial: false }), + killRadius: new StringField({ initial: "N/A" }), + ammo: new StringField({ initial: "" }), + expense: new StringField({ initial: "Standard" }), + equipped: new BooleanField({ initial: true }), + }; + } +} diff --git a/module/deltagreen.js b/module/deltagreen.js new file mode 100644 index 0000000..5f7aad5 --- /dev/null +++ b/module/deltagreen.js @@ -0,0 +1,251 @@ +// Import Modules +import DG from "./config.js"; +import DeltaGreenActor from "./actor/actor.js"; +import DGAgentSheet from "./sheets/agent-sheet.js"; +import DeltaGreenItem from "./item/item.js"; +import DeltaGreenItemSheet from "./item/item-sheet.js"; +import * as DGRolls from "./roll/roll.js"; +import registerSystemSettings from "./settings.js"; +import preloadHandlebarsTemplates from "./templates.js"; +import registerHandlebarsHelpers from "./other/register-helpers.js"; +import ParseDeltaGreenStatBlock from "./other/stat-parser-macro.js"; +import { + createDeltaGreenMacro, + rollItemMacro, + rollItemSkillCheckMacro, + rollSkillMacro, + rollSkillTestAndDamageForOwnedItem, +} from "./other/macro-functions.js"; +import { handleInlineActions } from "./other/inline.js"; +import DGNPCSheet from "./sheets/npc-sheet.js"; +import DGUnnaturalSheet from "./sheets/unnatural-sheet.js"; +import DGVehicleSheet from "./sheets/vehicle-sheet.js"; +import DGAgentSheetV2 from "./sheets/agent-sheet-v2.js"; +import AgentData from "./data/actor/agent.js"; +import UnnaturalData from "./data/actor/unnatural.js"; +import NPCData from "./data/actor/npc.js"; +import VehicleData from "./data/actor/vehicle.js"; +import WeaponItemData from "./data/item/weapon.js"; +import ArmorItemData from "./data/item/armor.js"; +import MotivationItemData from "./data/item/motivation.js"; +import BondItemData from "./data/item/bond.js"; +import GearItemData from "./data/item/gear.js"; +import TomeItemData from "./data/item/tome.js"; +import RitualItemData from "./data/item/ritual.js"; + +const { Actors, Items } = foundry.documents.collections; + +Hooks.once("init", async () => { + Object.assign(CONFIG.Actor.dataModels, { + // The keys are the types defined in system.json documentTypes.Actor + agent: AgentData, + unnatural: UnnaturalData, + npc: NPCData, + vehicle: VehicleData, + }); + + Object.assign(CONFIG.Item.dataModels, { + weapon: WeaponItemData, + armor: ArmorItemData, + motivation: MotivationItemData, + bond: BondItemData, + gear: GearItemData, + tome: TomeItemData, + ritual: RitualItemData, + }); + + game.deltagreen = { + DeltaGreenActor, + DeltaGreenItem, + rollItemMacro, + rollItemSkillCheckMacro, + rollSkillMacro, + ParseDeltaGreenStatBlock, + rollSkillTestAndDamageForOwnedItem, + }; + + /** + * Set an initiative formula for the system + * @type {String} + */ + CONFIG.Combat.initiative = { + formula: "@statistics.dex.value", + decimals: 0, + }; + + // Register custom dice rolls + Object.values(DGRolls).forEach((cls) => CONFIG.Dice.rolls.push(cls)); + + // Register System Settings + registerSystemSettings(); + + // Define custom Entity classes + CONFIG.Actor.documentClass = DeltaGreenActor; + CONFIG.Item.documentClass = DeltaGreenItem; + + // Unregister core sheets. + Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet); + Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet); + + // Register all actor sheets. + const sheetClassMap = { + agent: DGAgentSheet, + npc: DGNPCSheet, + unnatural: DGUnnaturalSheet, + vehicle: DGVehicleSheet, + }; + Object.entries(sheetClassMap).forEach(([actorType, SheetClass]) => { + Actors.registerSheet(DG.ID, SheetClass, { + makeDefault: true, + themes: null, + label: `DG.Sheet.class.${actorType}`, + types: [actorType], + }); + }); + + // Don't register new sheet yet. + // Actors.registerSheet(DG.ID, DGAgentSheetV2, { + // makeDefault: false, + // themes: null, + // label: `Agent Sheet V2`, + // types: ["agent"], + // }); + + // Register item sheet. + Items.registerSheet(DG.ID, DeltaGreenItemSheet, { + makeDefault: true, + label: "DG.Sheet.class.item", + themes: null, + }); + + // Preload Handlebars Templates + preloadHandlebarsTemplates(); + + // Add Handlebars helpers + registerHandlebarsHelpers(); +}); + +Hooks.once("ready", async () => { + // Wait to register hotbar drop hook on ready so that modules could register earlier if they want to + // TODO: Fix eslint issue on next line + // eslint-disable-next-line consistent-return + Hooks.on("hotbarDrop", (bar, data, slot) => { + // note - if we don't limit this logic to just items, we'll break re-ording macros on the bar + if (data.type === "Item") { + // this is async!! + createDeltaGreenMacro(data, slot); + // this must return false here! This stops the default logic on item drop from occuring, + // which is a macro to open an item sheet + return false; + } + }); +}); + +Hooks.on("preCreateItem", (item) => { + if (item.img === "icons/svg/item-bag.svg") { + if (item.type === "bond") { + item.updateSource({ + img: "systems/deltagreen/assets/icons/person-black-bg.svg", + }); + } else if (item.type === "tome") { + item.updateSource({ + img: "systems/deltagreen/assets/icons/book-cover.svg", + }); + } else if (item.type === "ritual") { + item.updateSource({ + img: "systems/deltagreen/assets/icons/bookmarklet.svg", + }); + } else { + item.updateSource({ + img: "systems/deltagreen/assets/icons/swap-bag-black-bg.svg", + }); + } + } +}); + +// Hook into the render call for the Actors Directory to add an extra button +Hooks.on("renderActorDirectory", (app, html, data) => { + if (!game.user.isGM) { + return; + } + + if (html.querySelector("#statParserButton")) { + return; + } + + const button = document.createElement("button"); + button.id = "statParserButton"; + + const icon = document.createElement("i"); + + icon.classList.add("fas", "fa-file-import"); + + button.appendChild(icon); + button.append("Delta Green Stat Block Parser"); + + html.querySelector(".directory-footer").appendChild(button); + + if (button) { + button.addEventListener("click", function (event) { + ParseDeltaGreenStatBlock(); + }); + } +}); + +// Note - this event is fired on ALL connected clients... +Hooks.on("createActor", async (actor, options, userId) => { + try { + // use this to trap on if this hook is firing for the same user that triggered the create + // can put logic specific to a particular user session below + if (userId !== game.user.id) return; + if (actor === null) return; + + if (actor.type === "agent") { + // throw on an unarmed strike item for convenience + actor.AddUnarmedAttackItemIfMissing(); + } else if (actor.type === "vehicle") { + actor.AddBaseVehicleItemsIfMissing(); + } + } catch (ex) { + console.log(ex); + } +}); + +Hooks.on("renderGamePause", function (_, html, options) { + if (options.cssClass !== "paused") return; + + try { + const gamePausedOverrideText = game.i18n.translations.DG.MissionPaused; + + if (typeof gamePausedOverrideText === "undefined") { + return; + } + + html.querySelector("figcaption").textContent = gamePausedOverrideText; + html.querySelector("img").classList.remove("fa-spin"); // I don't like the logo spinning personally + } catch { + // noop + } +}); + +function addEventListenerToChatMessage(element) { + element.addEventListener("click", (event) => { + const btnWithAction = event.target.closest("button[data-action]"); + const message = event.target.closest("li[data-message-id]"); + + const { messageId } = message?.dataset || {}; + if (btnWithAction && messageId) { + handleInlineActions(btnWithAction, messageId); + } + }); +} + +Hooks.on("renderChatLog", async (app, element) => { + addEventListenerToChatMessage(element); +}); + +Hooks.on("renderChatMessageHTML", async (app, element, context) => { + // ignore non chat card notifications + if (!context.canClose) return; + addEventListenerToChatMessage(element); +}); diff --git a/module/item/item-sheet.js b/module/item/item-sheet.js new file mode 100644 index 0000000..dd2d011 --- /dev/null +++ b/module/item/item-sheet.js @@ -0,0 +1,196 @@ +import { + DGPercentileRoll, + DGLethalityRoll, + DGDamageRoll, + DGSanityDamageRoll, +} from "../roll/roll.js"; + +/** + * Extend the basic ItemSheet with some very simple modifications + * @extends {ItemSheet} + */ +export default class DeltaGreenItemSheet extends foundry.appv1.sheets + .ItemSheet { + /** @override */ + static get defaultOptions() { + return foundry.utils.mergeObject(super.defaultOptions, { + classes: ["deltagreen", "sheet", "item"], + width: 520, + height: 600, + tabs: [ + { + navSelector: ".sheet-tabs", + contentSelector: ".sheet-body", + initial: "attributes", + }, + ], + }); + } + + /** @override */ + get template() { + const path = "systems/deltagreen/templates/item"; + + // unique item sheet by type, like `weapon-sheet.html`. + return `${path}/item-${this.item.type}-sheet.html`; + } + + /* -------------------------------------------- */ + + /** @override */ + async getData() { + const data = super.getData(); + + data.enrichedDescription = + await foundry.applications.ux.TextEditor.implementation.enrichHTML( + this.object.system.description, + { async: true }, + ); + + if (data.item.type === "tome" || data.item.type === "ritual") { + data.enrichedHandlerNotes = + await foundry.applications.ux.TextEditor.implementation.enrichHTML( + this.object.system.handlerNotes, + { async: true }, + ); + } + + return data; + } + + /* -------------------------------------------- */ + + /** @override */ + setPosition(options = {}) { + const position = super.setPosition(options); + const sheetBody = this.element.find(".sheet-body"); + const bodyHeight = position.height - 192; + sheetBody.css("height", bodyHeight); + return position; + } + + /* -------------------------------------------- */ + + /** @override */ + activateListeners(html) { + super.activateListeners(html); + + // Everything below here is only needed if the sheet is editable + // eslint-disable-next-line no-useless-return + if (!this.options.editable) return; + + // Rollable abilities - bind to everything with the 'Rollable' class + html.find(".rollable").click(this._onRoll.bind(this)); + html.find(".rollable").contextmenu(this._onRoll.bind(this)); // this is for right-click, which triggers the roll modifier dialogue for most rolls + + // toggle whether information is shown to a player for a tome or not + html.find(".tome-show-hide-info").click((event) => { + event.preventDefault(); + + this.item.system.revealed = !this.item.system.revealed; + + this.item.update({ "system.revealed": this.item.system.revealed }); + }); + } + + /** + * Handle clickable rolls. + * + * @param {Event} event The originating click event + * @async + * @private + */ + async _onRoll(event) { + event.preventDefault(); + const element = event.currentTarget; + const { dataset } = element; + + if (event && event.which === 2) { + // probably don't want rolls to trigger from a middle mouse click so just kill it here + return; + } + + // const item = this.actor.items.get(dataset.iid); + const rollOptions = { + rollType: dataset.rolltype, + key: dataset.key, + // actor: this, + specialTrainingName: dataset?.name || null, // Only applies to Special Training Rolls + item: this.item, + }; + + // Create a default 1d100 roll just in case. + let roll = new Roll("1d100", {}); + switch (dataset.rolltype) { + case "stat": + case "skill": + case "sanity": + case "special-training": + case "weapon": + roll = new DGPercentileRoll("1D100", {}, rollOptions); + break; + case "lethality": + roll = new DGLethalityRoll("1D100", {}, rollOptions); + break; + case "damage": { + let diceFormula = this.item.system.damage; + const { skill } = this.item.system; + if ( + (this.actor.type === "agent" || this.actor.type === "npc") && + (skill === "unarmed_combat" || skill === "melee_weapons") + ) { + diceFormula += + this.actor.system.statistics.str.meleeDamageBonusFormula; + } + roll = new DGDamageRoll(diceFormula, {}, rollOptions); + break; + } + case "sanity-damage": { + // Applies only to rituals, as far as Jalen can tell. Tomes have "study damage", but it just uses `sanity`. + const isLearntDamage = element.hasAttribute("data-san-on-learn"); + + const { successLoss, failedLoss } = isLearntDamage + ? this.item.system.learnedSanity + : this.item.system.sanity; + const combinedFormula = `{${successLoss}, ${failedLoss}}`; + + roll = new DGSanityDamageRoll(combinedFormula, {}, rollOptions); + break; + } + default: + break; + } + this.processRoll(event, roll, rollOptions); + } + + /** + * Show a dialog for the roll and then send to chat. + * Broke this logic out from `_onRoll()` so that other files can call it, + * namely the macro logic. + * + * TODO: Move this logic to the roll.js. + * + * @param {Event} event The originating click event + * @param {Event} roll The roll to show a dialog for and then send to chat. + * @async + */ + async processRoll(event, roll) { + // Open dialog if user requests it (no dialog for Sanity Damage rolls) + if ( + (event.shiftKey || event.which === 3) && + !(roll instanceof DGSanityDamageRoll) + ) { + const dialogData = await roll.showDialog(); + if (!dialogData) return; + if (dialogData.newFormula) { + roll = new DGDamageRoll(dialogData.newFormula, {}, roll.options); + } + roll.modifier += dialogData.targetModifier; + roll.options.rollMode = dialogData.rollMode; + } + // Evaluate the roll. + await roll.evaluate(); + // Send the roll to chat. + roll.toChat(); + } +} diff --git a/module/item/item.js b/module/item/item.js new file mode 100644 index 0000000..1beafa7 --- /dev/null +++ b/module/item/item.js @@ -0,0 +1,59 @@ +import { DGDamageRoll, DGLethalityRoll } from "../roll/roll.js"; + +/** + * Extend the basic Item with some very simple modifications. + * @extends {Item} + */ +export default class DeltaGreenItem extends Item { + /** + * Augment the basic Item data model with additional dynamic data. + */ + prepareData() { + super.prepareData(); + + // Get the Item's data + const itemData = this; + const actorData = this.actor || {}; + const { system } = itemData; + } + + /** + * Handle clickable rolls. + * @param {Event} event The originating click event + * @private + */ + async roll(isCrit = false) { + // Basic template rendering data + const item = this; + const { actor } = this; + const actorSystemData = this.actor.system || {}; + + let roll; + if (item.system.isLethal) { + roll = new DGLethalityRoll( + "1D100", + {}, + { rollType: "lethality", actor, item }, + ); + } else { + // regular damage roll + let diceFormula = item.system.damage; + const skillType = item.system.skill; + + if (skillType === "unarmed_combat" || skillType === "melee_weapons") { + diceFormula += actorSystemData.statistics.str.meleeDamageBonusFormula; + } + + if (isCrit) { + diceFormula = `2*(${diceFormula})`; + } + + roll = new DGDamageRoll( + diceFormula, + {}, + { rollType: "damage", actor, item }, + ); + } + return actor.sheet.processRoll({}, roll); + } +} diff --git a/module/other/inline.js b/module/other/inline.js new file mode 100644 index 0000000..2d8ee9a --- /dev/null +++ b/module/other/inline.js @@ -0,0 +1,36 @@ +/* eslint-disable import/prefer-default-export */ + +export async function handleInlineActions(btnWithAction, messageId) { + const action = btnWithAction.dataset?.action; + const message = game.messages.get(messageId); + const actor = message?.speakerActor; + if (!actor) return; + + if (action === "rollback-skill-failure-state") { + const rollbackFlag = message.getFlag("deltagreen", "rollbacks"); + await actor.update(foundry.utils.deepClone(rollbackFlag)); + + // eslint-disable-next-line no-use-before-define + toggleAllSkillFailures(rollbackFlag); + + const label = btnWithAction + .closest(".rollback-section") + ?.querySelector("label"); + const oldHtml = label.outerHTML; + label.classList.toggle("strike"); + + message.update({ + [`flags.deltagreen.rollbacks`]: rollbackFlag, + content: message.content.replace(oldHtml, label.outerHTML), + }); + } +} + +function toggleAllSkillFailures(data) { + for (const skill of Object.values(data.system?.skills || {})) { + skill.failure = !skill.failure; + } + for (const skill of Object.values(data.system?.typedSkills || {})) { + skill.failure = !skill.failure; + } +} diff --git a/module/other/macro-functions.js b/module/other/macro-functions.js new file mode 100644 index 0000000..4e8e707 --- /dev/null +++ b/module/other/macro-functions.js @@ -0,0 +1,189 @@ +import * as DGRolls from "../roll/roll.js"; + +const { fromUuid } = foundry.utils; + +/* -------------------------------------------- */ +/* Hotbar Macros */ +/* -------------------------------------------- */ + +/** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {Object} data The dropped data + * @param {number} slot The hotbar slot to use + * @returns {Promise} + */ +export async function createDeltaGreenMacro(data, slot) { + if (data.type !== "Item") { + return; + } + + if (!data.uuid.includes("Actor.") && !data.uuid.includes("Token.")) { + ui.notifications.warn("You can only create macro buttons for owned Items"); + return; + } + + const item = await fromUuid(data.uuid); + + if (item === null || typeof item === "undefined") { + ui.notifications.warn("Bad item passed to macro hotbar."); + return; + } + + let command = ""; + if (item.type !== "weapon") { + // this should just open the item sheet for this item + command = `(await fromUuid("${data.uuid}")).sheet.render(true)`; + } else { + command = + "// If a damage roll on a successful attack should not be automatically rolled, change the last argument from 'true' to 'false':"; + command += `\ngame.deltagreen.rollSkillTestAndDamageForOwnedItem("${data.uuid}", true);`; + } + + // Create the weapon macro command + const macro = await Macro.create({ + name: item.name, + type: "script", + img: item.img, + thumbnail: item.img, + command, + flags: { "deltagreen.itemMacro": true }, + }); + + await game.user.assignHotbarMacro(macro, slot); +} + +/** + * Create a Macro from an Item drop. + * Get an existing item macro if one exists, otherwise create a new one. + * @param {string} itemName + * @return {Promise} + */ +export async function rollItemMacro(itemId) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if (speaker.token) actor = game.actors.tokens[speaker.token]; + if (!actor) actor = game.actors.get(speaker.actor); + + if (!actor) + return ui.notifications.warn("Must have an Actor selected first."); + + let item = actor ? actor.items.find((i) => i._id === itemId) : null; + + // for backwards compatibility with older macros, where I unwisely set it to use name instead of id + if (!item) { + item = actor ? actor.items.find((i) => i.name === itemId) : null; + } + + if (!item) + return ui.notifications.warn( + `Your controlled Actor does not have an item named ${itemId}`, + ); + + // Trigger the item roll + const r = await item.roll(); + + return r; +} + +export function rollItemSkillCheckMacro(itemId) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if (speaker.token) actor = game.actors.tokens[speaker.token]; + if (!actor) actor = game.actors.get(speaker.actor); + + if (!actor) + return ui.notifications.warn("Must have an Actor selected first."); + + let item = actor ? actor.items.find((i) => i._id === itemId) : null; + + // for backwards compatibility with older macros, where I unwisely set it to use name instead of id + if (!item) { + item = actor ? actor.items.find((i) => i.name === itemId) : null; + } + + if (!item) + return ui.notifications.warn( + `Your controlled Actor does not have an item '${item.name}'`, + ); + + const skillName = item.system.skill.toString(); + + const roll = new DGRolls.DGPercentileRoll( + "1D100", + {}, + { rollType: "weapon", key: skillName, actor, item }, + ); + return actor.sheet.processRoll({}, roll); +} + +export function rollSkillMacro(skillName) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if (speaker.token) actor = game.actors.tokens[speaker.token]; + if (!actor) actor = game.actors.get(speaker.actor); + + if (!actor) + return ui.notifications.warn("Must have an Actor selected first."); + + const skill = actor.system.skills[skillName]; + + if (!skill) return ui.notifications.warn("Bad skill name passed to macro."); + + const roll = new DGRolls.DGPercentileRoll( + "1D100", + {}, + { rollType: "skill", key: skillName, actor }, + ); + return actor.sheet.processRoll({}, roll); + // sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency); +} + +/** + * Roll a skill check for an item that is owned by a specific actor. + * @param {*} itemId + * @param {*} actorId + * @returns {null|Boolean} + */ +export async function rollSkillTestAndDamageForOwnedItem( + itemUuId, + rollDamageOnSuccess, +) { + let item; + + try { + item = await fromUuid(itemUuId); + + if (item == null) { + return ui.notifications.warn("Invalid item targeted in macro."); + } + + if (item.type !== "weapon") { + return ui.notifications.warn( + "Can only roll weapons/attacks as item macros.", + ); + } + } catch { + return ui.notifications.warn("Invalid item targeted in macro."); + } + + const rollOptions = { + rollType: "weapon", + key: item.system.skill, + actor: item.parent, + specialTrainingName: null, // Only applies to Special Training Rolls + item, + }; + + const roll = new DGRolls.DGPercentileRoll("1D100", {}, rollOptions); + + await roll.evaluate(); + + roll.toChat(); + + if (roll.isSuccess && rollDamageOnSuccess) { + item.roll(roll.isCritical); + } + + return roll.isSuccess; +} diff --git a/module/other/register-helpers.js b/module/other/register-helpers.js new file mode 100644 index 0000000..1356dde --- /dev/null +++ b/module/other/register-helpers.js @@ -0,0 +1,257 @@ +import DGUtils from "./utility-functions.js"; + +export default function registerHandlebarsHelpers() { + // Add Handlebars helpers + Handlebars.registerHelper("localizeWithFallback", (value, fallbackValue) => { + return DGUtils.localizeWithFallback(value, fallbackValue); + }); + + Handlebars.registerHelper("concat", (...args) => { + let outStr = ""; + for (const arg in args) { + if (typeof args[arg] !== "object") { + outStr += args[arg]; + } + } + return outStr; + }); + + Handlebars.registerHelper("toLowerCase", (str) => { + try { + return str.toLowerCase(); + } catch (error) { + return ""; + } + }); + + Handlebars.registerHelper("toUpperCase", (str) => { + try { + return str.toUpperCase(); + } catch (error) { + return ""; + } + }); + + Handlebars.registerHelper("if_eq", (a, b, opts) => { + if (a === b) { + return opts.fn(this); + } + return opts.inverse(this); + }); + + Handlebars.registerHelper("if_not_eq", (a, b, opts) => { + if (a !== b) { + return opts.fn(this); + } + return opts.inverse(this); + }); + + Handlebars.registerHelper("if_gt", (a, b, trueVal, falseVal) => { + if (a > b) { + return trueVal; + } + return falseVal; + }); + + Handlebars.registerHelper("cite_ahb", (page) => { + return `See page ${page} of the Agent's Handbook.`; + }); + + Handlebars.registerHelper("formatLethality", (lethality) => { + if (lethality > 0) { + return `${lethality.toString()}%`; + } + return ""; + }); + + // Is this used anywhere? + Handlebars.registerHelper( + "getActorSkillProp", + (actorData, skillName, prop) => { + try { + if (skillName !== "" && prop !== "") { + const { skills } = actorData.data; + const skill = skills[skillName]; + const propVal = skill[prop]; + return propVal; + } + return ""; + } catch (ex) { + console.log(ex); + return ""; + } + }, + ); + + Handlebars.registerHelper("getAvailableRollModes", () => { + try { + return CONFIG.Dice.rollModes; + } catch (error) { + return console.log(error); + } + }); + + Handlebars.registerHelper("getDefaultRollMode", () => { + try { + return game.settings.get("core", "rollMode"); + } catch (error) { + return console.log(error); + } + }); + + Handlebars.registerHelper( + "calculateHandToHandCombatDamageFormulaBonus", + (strength) => { + try { + let bonus = ""; + + if (strength.value < 5) { + bonus = " - 2"; + } else if (strength.value < 9) { + bonus = " - 1"; + } else if (strength.value > 12 && strength < 17) { + bonus = " + 1"; + } else if (strength.value > 16) { + bonus = " + 2"; + } + + return bonus; + } catch (error) { + return console.log(error); + } + }, + ); + + Handlebars.registerHelper("localizeWeaponSkill", (skill) => { + let label = skill; + + try { + if (skill === "dex") { + label = game.i18n.localize("DG.Attributes.dex"); + } + if (skill === "DG.Skills.custom") { + label = game.i18n.localize("DG.ItemWindow.Custom"); + } else { + label = game.i18n.localize(`DG.Skills.${skill}`); + } + } catch (error) { + console.log(error); + } + + return label; + }); + + Handlebars.registerHelper( + "hideSkillBasedOnProficiencyAndUserChoice", + (hideUntrainedSkills, proficiency) => { + let showValue = true; + + try { + if (hideUntrainedSkills === false) { + showValue = true; + } else if (proficiency > 0) { + showValue = true; + } else { + showValue = false; + } + } catch (error) { + console.log(error); + } + + return showValue; + }, + ); + + // looks at system setting for what font to use and returns the class that is then used in the handlebars template that + // generates the character sheet. + Handlebars.registerHelper("getFontFamilySystemSettingClass", () => { + const setting = game.settings.get("deltagreen", "characterSheetFont"); + + const characterSheetStyle = game.settings.get( + "deltagreen", + "characterSheetStyle", + ); + + /* + if(setting === "TypeWriterCondensed"){ + return "typewriter-condensed-font"; + } + else if(setting === "Martel"){ + return "martel-font"; + } + else if(setting === "Signika"){ + return "signika-font"; + } + else if(setting === "atwriter"){ + return "atwriter-font"; + } + else if(setting === "SpecialElite"){ + return "special-elite-font"; + } + else if(setting === "PublicSans"){ + return "public-sans-font"; + } + else{ + return "martel-font"; + } + */ + + /* + if(characterSheetStyle === "cowboy"){ + return "special-elite-font"; + } + else{ + return "public-sans-font"; + } + */ + }); + + Handlebars.registerHelper("getCharacterSheetStyle", () => { + const characterSheetStyle = game.settings.get( + "deltagreen", + "characterSheetStyle", + ); + + if (characterSheetStyle === "cowboy") { + return "cowboy-style"; + } + if (characterSheetStyle === "outlaw") { + return "outlaw-style"; + } + return "program-style"; + }); + + Handlebars.registerHelper("keepSanityPrivate", () => { + let setting = false; + + try { + setting = game.settings.get("deltagreen", "keepSanityPrivate"); + + if (game.user.isGM) { + setting = false; + } + } catch (ex) { + setting = false; + } + + return setting; + }); + + Handlebars.registerHelper("playerHasGamemasterPrivileges", () => { + return game.user.isGM; + }); + + Handlebars.registerHelper("showImpossibleLandscapesContent", () => { + let result = false; + const setting = game.settings.get( + "deltagreen", + "showImpossibleLandscapesContent", + ); + + if (game.user.isGM === true && setting === true) { + result = true; + } + + return result; + }); +} diff --git a/module/other/stat-parser-macro.js b/module/other/stat-parser-macro.js new file mode 100644 index 0000000..cdbf909 --- /dev/null +++ b/module/other/stat-parser-macro.js @@ -0,0 +1,683 @@ +function GetAttacksFromInput(inputText) { + const attacks = []; + try { + // some attacks split onto multiple lines, usually separated by semicolons, + // try to get these back on the same line before splitting... + const lines = inputText + .replace("; \r\n", ";") + .replace(";\r\n", ";") + .replace(";\n", ";") + .replace("; \n", ";") + .split(/\r?\n/); + + let isInAttackSection = false; + + if (lines !== null && lines.length > 0) { + for (let i = 0; i < lines.length; i++) { + if (lines[i].toString().toUpperCase().indexOf("ATTACKS:") >= 0) { + isInAttackSection = true; + } else if ( + isInAttackSection && + lines[i].toString().toUpperCase().indexOf(":") > 0 + ) { + isInAttackSection = false; + } + + if (isInAttackSection) { + const attackLine = lines[i] + .toString() + .toUpperCase() + .replace("ATTACKS:", ""); + + console.log(attackLine); + + const weaponData = { + type: "weapon", + name: "New Attack", + description: attackLine, + system: { + skill: "custom", + skillModifier: 0, + customSkillTarget: 0, + range: "0M", + damage: "1D10", + armorPiercing: 0, + lethality: 0, + isLethal: false, + killRadius: "N/A", + ammo: "N/A", + expense: "NA", + equipped: true, + }, + }; + + // try to determine if it's a lethality attack, as those will have two % values in them + if (attackLine.indexOf("LETHALITY") >= 0) { + weaponData.isLethal = true; + + const lethalityMatchStr = "(\\w.*?)(\\d\\d?%)"; // test with 'Black box 50%, Lethality 40% (see BLACK BOX).' + const re = new RegExp(lethalityMatchStr, "i"); + const lethalityResults = attackLine.match(re); + + if ( + lethalityResults !== null && + lethalityResults.length > 0 && + lethalityResults[1] !== null && + lethalityResults[1] !== undefined + ) { + weaponData.name = lethalityResults[1].toString().trim(); + + weaponData.lethality = parseInt( + lethalityResults[2] + .toString() + .replace("%", "") + .replace(";", ""), + ); + } + } else { + // assume only percent value will be the skill test associated with it + const skillMatchStr = `(\\w.*?)(\\d?\\d%)([\\S\\s]*?damage\\s.*?)?(\\d?d\\d?\\d?\\d([\\+\\-]\\d+)?)?`; // test with 'SIG Sauer P228 pistol 94%, damage 1D10.' + const re1 = new RegExp(skillMatchStr, "i"); + const skillResults = attackLine.match(re1); + + if ( + skillResults !== null && + skillResults.length > 0 && + skillResults[1] !== null && + skillResults[1] !== undefined + ) { + weaponData.name = skillResults[1].toString().trim(); + + if ( + skillResults.length > 2 && + skillResults[2] !== null && + skillResults[2] !== undefined + ) { + weaponData.customSkillTarget = parseInt( + skillResults[2].toString().replace("%", "").replace(";", ""), + ); + } + + // have to be careful, some unnatural attacks don't actually deal damage, they just grab or something. + // don't have a great way to indicate that in the system, so just set it to zero if we can't find it. + if ( + skillResults.length > 4 && + skillResults[4] !== null && + skillResults[4] !== undefined + ) { + weaponData.damage = skillResults[4].toString().replace(";", ""); + } else { + weaponData.damage = 0; + } + } + + // look for armor piercing + if (attackLine.indexOf("ARMOR PIERCING") >= 0) { + // TODO: This should do something. + } + } + + if (weaponData.customSkillTarget > 0 || weaponData.isLethal) { + attacks.push(weaponData); + } + } + } + } + } catch (ex) { + console.log("GetAttacksFromInput Error"); + console.log(ex); + } + + return attacks; +} + +function GetNotesFromInput(inputText) { + const matchStr = "(?:ATTACKS:[\\S\\s]*?\\.\\n)([\\S\\s]*)"; + const re = new RegExp(matchStr, "gi"); + const results = inputText.match(re); + let notes = ""; + + try { + if (results != null && results.length > 0) { + let output = ""; + + const lines = results[0].split(/\r?\n/); + + for (let i = 0; i < lines.length; i++) { + output += `${lines[i]}
`; + } + + notes = output; + } + } catch (ex) { + console.log("GetNotesFromInput Error"); + console.log(ex); + } + + return [notes]; +} + +function GetArmorFromInput(inputText) { + try { + const armor = { name: "Armor", description: "", armor: 0 }; + + const lines = inputText.split(/\r?\n/); + + if (lines !== null && lines.length > 0) { + for (let i = 0; i < lines.length; i++) { + if (lines[i].toString().toUpperCase().indexOf("ARMOR:") >= 0) { + armor.description = lines[i] + .replace("Armor:", "") + .replace("ARMOR:", "") + .trim(); + + const matchStr = `(\\d\\d?)`; + const re = new RegExp(matchStr, "i"); + const results = lines[i].match(re); + + try { + if (results != null && results.length > 0) { + armor.armor = parseInt(results[0]); + + armor.name = armor.description + .replace(`(Armor ${armor.armor})`, "") + .trim(); + + armor.name = armor.name + .replace(`${armor.armor} points of`, "") + .replace(`${armor.armor} point of`, "") + .replace(".", "") + .trim(); + } + } catch (ex) { + console.log("GetArmorFromInput Error"); + console.log(ex); + } + + return armor; + } + } + } + } catch (ex) { + console.log("GetArmorFromInput Error"); + console.log(ex); + } + return null; +} + +// this is the main stat call, it's exposed as part of the system itself for users to access +// call this within a world as: game.deltagreen.ParseDeltaGreenStatBlock() +function GetTypeSkillRatingsFromInput(inputText) { + const matchStr = + "(Art|Craft|Foreign Language|Native Language|Military Science|Pilot|Science)\\s?\\((\\w.*?)\\)\\s?(\\d?\\d)%"; + + inputText = inputText.replace(/[\n\r]/g, " "); + + const re = new RegExp(matchStr, "gi"); + + const matches = []; + let match; + + try { + // This is probably one of the few times where its recommended to assign within a while loop. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec + // eslint-disable-next-line no-cond-assign + while ((match = re.exec(inputText))) { + matches.push({ + group: match[1], + label: match[2], + proficiency: parseInt(match[3]), + failure: false, + }); + } + } catch (ex) { + console.log("GetAttributeFromInput Error"); + console.log(ex); + } + + return matches; +} + +function GetAttributeFromInput(inputText, attribute) { + const matchStr = `(?:${attribute}\\s)(\\d\\d?)`; + const re = new RegExp(matchStr, "i"); + const results = inputText.match(re); + let attributeScore = 10; + + try { + if (results != null && results.length > 1) { + attributeScore = parseInt(results[1]); + } else { + attributeScore = 0; + } + } catch (ex) { + console.log("GetAttributeFromInput Error"); + console.log(ex); + } + + return attributeScore; +} + +function GetSkillRatingsFromInput(inputText, skill) { + const matchStr = `(?:${skill}\\n?\\s?\\n?)(\\d\\d?)`; + const re = new RegExp(matchStr, "i"); + const results = inputText.match(re); + let skillValue = 0; + + try { + if (results != null && results.length > 1) { + skillValue = parseInt(results[1]); + } + } catch (ex) { + console.log("GetAttributeFromInput Error"); + console.log(ex); + } + + return skillValue; +} + +async function RegexParseNpcStatBlock(inputStr, actorType) { + const actorData = {}; + + let shortDescription = ""; + + actorData.type = actorType; + actorData.system = {}; + actorData.system.statistics = {}; + actorData.system.skills = {}; + actorData.system.typedSkills = {}; + actorData.system.physical = {}; + + actorData.system.health = { value: 10, min: 0, max: 10 }; + actorData.system.wp = { value: 10, min: 0, max: 10 }; + + let tempStr = ""; + let arr = []; + + tempStr = inputStr.split(/\r?\n/); + + if (tempStr.length > 0) { + [actorData.name] = tempStr; + + // set the alternate description/profession/etc. + // if this doesn't exist, the next line should be the attributes starting with strength + // so if the second line starts with "STR" then just leave it be. + if ( + tempStr.length > 1 && + tempStr[1].substring(0, 3) !== "STR" && + tempStr[1].substring(0, 3) !== "CON" && + tempStr[1].substring(0, 3) !== "DEX" && + tempStr[1].substring(0, 3) !== "INT" && + tempStr[1].substring(0, 3) !== "POW" && + tempStr[1].substring(0, 3) !== "CHA" + ) { + [, shortDescription] = tempStr; + } + } else { + actorData.name = "Unknown"; + } + + const armor = GetArmorFromInput(inputStr); + + const attacks = GetAttacksFromInput(inputStr); + + if (armor !== null) { + console.log(armor); + } + + if (actorType === "agent") { + actorData.system.physical = { + description: shortDescription, + wounds: "", + firstAidAttempted: false, + }; + } else if (actorType === "npc" || actorType === "unnatural") { + actorData.system.shortDescription = shortDescription; + } + + actorData.system.statistics.str = { + value: GetAttributeFromInput(inputStr, "STR"), + distinguishing_feature: "", + }; + actorData.system.statistics.con = { + value: GetAttributeFromInput(inputStr, "CON"), + distinguishing_feature: "", + }; + actorData.system.statistics.dex = { + value: GetAttributeFromInput(inputStr, "DEX"), + distinguishing_feature: "", + }; + actorData.system.statistics.int = { + value: GetAttributeFromInput(inputStr, "INT"), + distinguishing_feature: "", + }; + actorData.system.statistics.pow = { + value: GetAttributeFromInput(inputStr, "POW"), + distinguishing_feature: "", + }; + actorData.system.statistics.cha = { + value: GetAttributeFromInput(inputStr, "CHA"), + distinguishing_feature: "", + }; + + if (actorType === "npc" || actorType === "unnatural") { + // don't want to try to set HP/SAN for player characters + actorData.system.health = { + min: 0, + max: GetAttributeFromInput(inputStr, "HP"), + value: GetAttributeFromInput(inputStr, "HP"), + }; + actorData.system.sanity = { + max: actorData.system.statistics.pow.value * 5, + value: GetAttributeFromInput(inputStr, "SAN"), + currentBreakingPoint: GetAttributeFromInput(inputStr, "BREAKING POINT"), + }; + actorData.system.wp = { + max: actorData.system.statistics.pow.value, + value: GetAttributeFromInput(inputStr, "WP"), + min: 0, + }; + } + + actorData.system.skills.accounting = { + label: "Accounting", + proficiency: GetSkillRatingsFromInput(inputStr, "ACCOUNTING"), + failure: false, + }; + actorData.system.skills.alertness = { + label: "Alertness", + proficiency: GetSkillRatingsFromInput(inputStr, "ALERTNESS"), + failure: false, + }; + actorData.system.skills.anthropology = { + label: "Anthropology", + proficiency: GetSkillRatingsFromInput(inputStr, "ANTHROPOLOGY"), + failure: false, + }; + actorData.system.skills.archeology = { + label: "Archeology", + proficiency: GetSkillRatingsFromInput(inputStr, "ARCHEOLOGY|ARCHAEOLOGY"), + failure: false, + }; // damn you british spellings + actorData.system.skills.artillery = { + label: "Artillery", + proficiency: GetSkillRatingsFromInput(inputStr, "ARTILLERY"), + failure: false, + }; + actorData.system.skills.athletics = { + label: "Athletics", + proficiency: GetSkillRatingsFromInput(inputStr, "ATHLETICS"), + failure: false, + }; + actorData.system.skills.bureaucracy = { + label: "Bureaucracy", + proficiency: GetSkillRatingsFromInput(inputStr, "BUREAUCRACY"), + failure: false, + }; + actorData.system.skills.computer_science = { + label: "Computer Science", + proficiency: GetSkillRatingsFromInput(inputStr, "COMPUTER SCIENCE"), + failure: false, + }; + actorData.system.skills.criminology = { + label: "Criminology", + proficiency: GetSkillRatingsFromInput(inputStr, "CRIMINOLOGY"), + failure: false, + }; + actorData.system.skills.demolitions = { + label: "Demolitions", + proficiency: GetSkillRatingsFromInput(inputStr, "DEMOLITIONS"), + failure: false, + }; + actorData.system.skills.disguise = { + label: "Disguise", + proficiency: GetSkillRatingsFromInput(inputStr, "DISGUISE"), + failure: false, + }; + actorData.system.skills.dodge = { + label: "Dodge", + proficiency: GetSkillRatingsFromInput(inputStr, "DODGE"), + failure: false, + }; + actorData.system.skills.drive = { + label: "Drive", + proficiency: GetSkillRatingsFromInput(inputStr, "DRIVE"), + failure: false, + }; + + // Impossible Landscapes seems to favor 'Driving' as the name for this instead for some reason + if (actorData.system.skills.drive.proficiency === 0) { + actorData.system.skills.drive = { + label: "Drive", + proficiency: GetSkillRatingsFromInput(inputStr, "DRIVING"), + failure: false, + }; + } + + actorData.system.skills.firearms = { + label: "Firearms", + proficiency: GetSkillRatingsFromInput(inputStr, "FIREARMS"), + failure: false, + }; + actorData.system.skills.first_aid = { + label: "First Aid", + proficiency: GetSkillRatingsFromInput(inputStr, "FIRST AID"), + failure: false, + }; + actorData.system.skills.forensics = { + label: "Forensics", + proficiency: GetSkillRatingsFromInput(inputStr, "FORENSICS"), + failure: false, + }; + actorData.system.skills.heavy_machinery = { + label: "Heavy Machinery", + proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY MACHINERY"), + failure: false, + }; // template.json has typo on heavy machinery... + actorData.system.skills.heavy_weapons = { + label: "Heavy Weapons", + proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY WEAPONS"), + failure: false, + }; + actorData.system.skills.history = { + label: "History", + proficiency: GetSkillRatingsFromInput(inputStr, "HISTORY"), + failure: false, + }; + actorData.system.skills.humint = { + label: "HUMINT", + proficiency: GetSkillRatingsFromInput(inputStr, "HUMINT"), + failure: false, + }; + actorData.system.skills.law = { + label: "Law", + proficiency: GetSkillRatingsFromInput(inputStr, "LAW"), + failure: false, + }; + actorData.system.skills.medicine = { + label: "Medicine", + proficiency: GetSkillRatingsFromInput(inputStr, "MEDICINE"), + failure: false, + }; + actorData.system.skills.melee_weapons = { + label: "Melee Weapons", + proficiency: GetSkillRatingsFromInput(inputStr, "MELEE WEAPONS"), + failure: false, + }; + actorData.system.skills.navigate = { + label: "Navigate", + proficiency: GetSkillRatingsFromInput(inputStr, "NAVIGATE"), + failure: false, + }; + actorData.system.skills.occult = { + label: "Occult", + proficiency: GetSkillRatingsFromInput(inputStr, "OCCULT"), + failure: false, + }; + actorData.system.skills.persuade = { + label: "Persuade", + proficiency: GetSkillRatingsFromInput(inputStr, "PERSUADE"), + failure: false, + }; + actorData.system.skills.pharmacy = { + label: "Pharmacy", + proficiency: GetSkillRatingsFromInput(inputStr, "PHARMACY"), + failure: false, + }; + actorData.system.skills.psychotherapy = { + label: "Psychotherapy", + proficiency: GetSkillRatingsFromInput(inputStr, "PSYCHOTHERAPY"), + failure: false, + }; + actorData.system.skills.ride = { + label: "Ride", + proficiency: GetSkillRatingsFromInput(inputStr, "RIDE"), + failure: false, + }; + actorData.system.skills.search = { + label: "Search", + proficiency: GetSkillRatingsFromInput(inputStr, "SEARCH"), + failure: false, + }; + actorData.system.skills.sigint = { + label: "SIGINT", + proficiency: GetSkillRatingsFromInput(inputStr, "SIGINT"), + failure: false, + }; + actorData.system.skills.stealth = { + label: "Stealth", + proficiency: GetSkillRatingsFromInput(inputStr, "STEALTH"), + failure: false, + }; + actorData.system.skills.surgery = { + label: "Surgery", + proficiency: GetSkillRatingsFromInput(inputStr, "SURGERY"), + failure: false, + }; + actorData.system.skills.survival = { + label: "Survival", + proficiency: GetSkillRatingsFromInput(inputStr, "SURVIVAL"), + failure: false, + }; + actorData.system.skills.swim = { + label: "Swim", + proficiency: GetSkillRatingsFromInput(inputStr, "SWIM"), + failure: false, + }; + actorData.system.skills.unarmed_combat = { + label: "Unarmed Combat", + proficiency: GetSkillRatingsFromInput(inputStr, "UNARMED COMBAT"), + failure: false, + }; + actorData.system.skills.unnatural = { + label: "Unnatural", + proficiency: GetSkillRatingsFromInput(inputStr, "UNNATURAL"), + failure: false, + }; + + // some npcs/unnatural have other skills + if (GetSkillRatingsFromInput(inputStr, "FLIGHT") > 0) { + actorData.system.skills.flight = { + label: "Flight", + proficiency: GetSkillRatingsFromInput(inputStr, "FLIGHT"), + failure: false, + }; + } + + arr = GetTypeSkillRatingsFromInput(inputStr); + + for (let index = 0; index < arr.length; index += 1) { + const element = arr[index]; + actorData.system.typedSkills[`tskill_${index.toString()}`] = element; + } + + if (actorType === "npc" || actorType === "unnatural") { + actorData.system.notes = GetNotesFromInput(inputStr); + } + + console.log(actorData); + + const newActors = await Actor.createDocuments([actorData]); + + if (armor !== null) { + if (armor.description === null || armor.description.trim() === "") { + armor.description = "Armor"; + } + + await newActors[0].AddArmorItemToSheet( + armor.name, + armor.description, + armor.armor, + true, + ); + } + + if (attacks !== null && attacks.length > 0) { + for (const a of attacks) { + await newActors[0].AddWeaponItemToSheet( + a.name, + a.description, + a.damage, + a.skill, + a.skillModifier, + a.customSkillTarget, + a.armorPiercing, + a.lethality, + a.isLethal, + a.range, + a.killRadius, + a.ammo, + a.expense, + a.equipped, + ); + } + } + + newActors[0].sheet.render(true); +} + +async function GetUserInput() { + const content = `
+
+ +
+ +
+
+
+ +
+
+ +
+
+
`; + + new foundry.applications.api.DialogV2({ + window: { title: "Stat Block Parser" }, + content, + buttons: [ + { + label: "PARSE", + action: "roll", + callback: (event, button, dialog) => { + const textInput = + dialog.element.querySelector("[name=parse-input]")?.value; + + const actorType = + dialog.element.querySelector("[name=actor-type]")?.value; + + RegexParseNpcStatBlock(textInput, actorType); + }, + }, + ], + }).render(true); +} + +export default async function ParseDeltaGreenStatBlock() { + GetUserInput(); +} diff --git a/module/other/utility-functions.js b/module/other/utility-functions.js new file mode 100644 index 0000000..dabf602 --- /dev/null +++ b/module/other/utility-functions.js @@ -0,0 +1,36 @@ +export default class DGUtils { + /** + * Attempt to localize a keyword, and gracefully fallback to something else if the key does not exist. + * This way people using incomplete translations will not as many crashes or bugs when playing against a newly updated system. + * + * @param {String} key - localization key + * @param {String} fallback - string to fall back to if translation does not exist for key + * @returns + */ + static localizeWithFallback(key, fallback) { + try { + const translatedValue = game.i18n.localize(key); + if (translatedValue !== key) { + return translatedValue; + } + console.warn(`Untranslated localization key '${key}'.`); + // can't have single quotes in a handlebars string literal input, so sort of hack in an escape character for them. + fallback = fallback.replace("'", "'"); + return fallback; + } catch (ex) { + console.warn(ex); + return fallback; + } + } + + /** + * Format a number with a leading plus. + * + * @param {Number} number + * @returns {String} - the stringified number with a leading plus if applicable + * + */ + static formatStringWithLeadingPlus(number) { + return number > 0 ? `+${number}` : number.toString(); + } +} diff --git a/module/roll/roll.js b/module/roll/roll.js new file mode 100644 index 0000000..db002e4 --- /dev/null +++ b/module/roll/roll.js @@ -0,0 +1,847 @@ +/* eslint-disable max-classes-per-file */ +import DGUtils from "../other/utility-functions.js"; +import DG from "../config.js"; + +const { renderTemplate } = foundry.applications.handlebars; +const { DialogV2 } = foundry.applications.api; + +export class DGRoll extends Roll { + /** + * NOTE: This class will rarely be called on its own. It should generally be extended. Look to DGPercentileRoll as an example. + * + * Customize our roll with some useful information, passed in the `options` Object. + * + * @param {string} formula Unused - The string formula to parse (from Foundry) + * @param {Object} data Unused - The data object against which to parse attributes within the formula + * @param {Object} [options] Additional data which is preserved in the database + * @param {Number} [options.rollType] The type of roll (stat, skill, sanity, damage, etc). + * @param {String} [options.key] The key of the skill, stat, etc. to use as a basis for this roll. + * @param {DeltaGreenActor} [options.actor] The actor that this roll originates from. + * @param {DeltaGreenItem} [options.item] Optional - The item from which the roll originates. + */ + constructor(formula, data = {}, options = {}) { + super(formula, data, options); + const { rollType, key, actor, item } = options; + this.type = rollType; + this.key = key; + this.actor = actor; + this.item = item; + this.modifier = 0; + } + + /** + * Simple function that actually creates the message and sends it to chat. + * We override this to have a little more control over certain aspects of the message, + * right now, its `speaker` and `rollMode`. + * + * @override + * The following `@param` descriptions comes from the Foundry VTT code. + * @param {object} messageData The data object to use when creating the message + * @param {options} [options] Additional options which modify the created message. + * @param {string} [options.rollMode] The template roll mode to use for the message from CONFIG.Dice.rollModes + * @param {boolean} [options.create=true] Whether to automatically create the chat message, or only return the + * prepared chatData object. + * @returns {Promise} A promise which resolves to the created ChatMessage document if create is + * true, or the Object of prepared chatData otherwise. + */ + async toMessage(messageData = {}, { rollMode, create = true } = {}) { + // eslint-disable-next-line no-param-reassign + messageData.speaker = ChatMessage.getSpeaker({ actor: this.actor }); + return super.toMessage(messageData, { + rollMode: this.options.rollMode || rollMode, + create, + }); + } +} + +export class DGPercentileRoll extends DGRoll { + /** + * Creates D100 rolls, the base die of the system. + * + * This constructor embeds the following info into the roll: + * 1. Target number that the roll needs to beat. + * 2. Localized name for the roll. + * + * Note: In order for all of our custom data to persist, our constructor must use the same parameters as its parent class. + * So, even though percentile rolls will always have a formula of "1d100" and we don't use the `data` object, + * we still have to keep them as parameters. + * + * @param {string} formula Unused - The string formula to parse (from Foundry) - Always "1d100" for percentile rolls. + * @param {Object} data Unused - The data object against which to parse attributes within the formula + * @param {Object} [options] Additional data which is preserved in the database + * @param {Number} [options.rollType] The type of roll (stat, skill, sanity, etc). + * @param {String} [options.key] The key of the skill, stat, etc. to use as a basis for this roll. + * @param {DeltaGreenActor} [options.actor] The actor that this roll originates from. + * @param {DeltaGreenItem} [options.item] Optional - The item from which the roll originates. + * @param {DeltaGreenItem} [options.specialTrainingName] Optional - Special training rolls have names that are different from the roll key. + */ + // eslint-disable-next-line default-param-last, no-unused-vars + constructor(formula = "1D100", data = {}, options) { + super("1D100", {}, options); + + // Set roll info for Skill, Stat, Typed Skill, and non-custom Weapon Percentile rolls. + const { target, localizedKey, skillPath } = this.getRollInfoFromKey( + this.key, + this.actor.system, + ); + this.target = target; + this.localizedKey = localizedKey; + this.skillPath = skillPath; + + // Set roll info for other Percentile rolls + switch (this.type) { + case "special-training": + this.specialTrainingName = options.specialTrainingName; + this.localizedKey = `${this.specialTrainingName} - (${this.localizedKey})`; + break; + case "weapon": + // If this weapon uses a custom target for rolls, we set that explicitly. + if (this.key === "custom") { + this.target = this.item.system.customSkillTarget; + this.localizedKey = game.i18n.localize("DG.ItemWindow.Custom"); + } + // Add a the weapon's internal modifier. + this.modifier += this.item.system.skillModifier; + break; + case "sanity": + this.target = this.actor.system.sanity.value; + this.localizedKey = game.i18n.localize("DG.Attributes.SAN"); + break; + case "luck": + this.target = 50; + this.localizedKey = game.i18n.localize("DG.Luck"); + break; + default: + break; + } + } + + /** + * Shows a dialog that can modify the roll. + * + * @returns {Promise} - the results of the dialog. + */ + async showDialog() { + const privateSanSetting = game.settings.get( + "deltagreen", + "keepSanityPrivate", + ); + + let hideSanTarget = false; + if ( + privateSanSetting && + (this.type === "sanity" || this.key === "ritual") && + !game.user.isGM + ) { + hideSanTarget = true; + } + + let customModifierTarget = 20; + + if (this.actor != null) { + try { + customModifierTarget = parseInt( + this.actor.system.settings.rolling.defaultPercentileModifier, + ); + } catch { + // do nothing + } + } + + const backingData = { + data: { + label: this.localizedKey, + originalTarget: this.target, + targetModifier: customModifierTarget, + hideTarget: hideSanTarget, + }, + }; + + const template = + "systems/deltagreen/templates/dialog/modify-percentile-roll.html"; + const content = await renderTemplate(template, backingData); + return new Promise((resolve, reject) => { + const modButtons = [-40, -20, 20, 40].map((mod) => { + const sign = mod > 0 ? "Positive" : "Negative"; + return { + action: `roll${Math.abs(mod)}${sign}`, + label: String(mod), + callback: (event, button, dialog) => { + try { + const rollMode = + dialog.element.querySelector("[name='rollMode']")?.value; + resolve({ targetModifier: mod, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }; + }); + + new DialogV2({ + content, + window: { + title: DGUtils.localizeWithFallback( + "DG.ModifySkillRollDialogue.Title", + "Modify Roll", + ), + }, + buttons: [ + { + default: true, + action: "roll", + label: DGUtils.localizeWithFallback("DG.Roll.Roll", "Roll"), + callback: (event, button, dialog) => { + try { + let targetModifier = dialog.element.querySelector( + "[name='targetModifier']", + )?.value; // this is text as a heads up + + const rollMode = + dialog.element.querySelector("[name='rollMode']")?.value; + + const plusMinus = dialog.element.querySelector( + "[name='plusOrMinus']", + )?.value; + + if ( + targetModifier.trim() !== "" && + !Number.isNaN(targetModifier) + ) { + targetModifier = Math.abs(parseInt(targetModifier)); + + if (plusMinus === "-") { + targetModifier *= -1; + } + + // update the custom target modifier so it 'persists' between dialogs + if (this.actor != null) { + this.actor.update({ + "system.settings.rolling.defaultPercentileModifier": + targetModifier, + }); + } + } + resolve({ targetModifier, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, + ...modButtons, + ], + }).render(true); + }); + } + + /** + * Prepares data for a chat message and then passes that data + * to a method that actually creates a ChatMessage. + * + * Lays out and styles message based on outcome of the roll. + * + * @returns {Promise} - the created chat message. + */ + async toChat() { + // if using private san rolls, must hide any SAN roll unless user is a GM + const privateSanSetting = game.settings.get( + "deltagreen", + "keepSanityPrivate", + ); + if ( + privateSanSetting && + (this.type === "sanity" || this.key === "ritual") && + !game.user.isGM + ) { + this.options.rollMode = "blindroll"; + } + + const diceSoNice = + game.modules.has("dice-so-nice") && + game.modules.get("dice-so-nice").active; + + const label = this.createLabel(); + + let resultString = ""; + let styleOverride = ""; + + if (this.isSuccess) { + if (this.isCritical) { + resultString = `${game.i18n.localize("DG.Roll.CriticalSuccess")}`; + resultString = `${resultString.toUpperCase()}`; + styleOverride = "color: green"; + } else { + resultString = `${game.i18n.localize("DG.Roll.Success")}`; + } + } else if (this.isCritical) { + resultString = `${game.i18n.localize("DG.Roll.CriticalFailure")}`; + resultString = `${resultString.toUpperCase()}`; + styleOverride = "color: red"; + } else { + resultString = `${game.i18n.localize("DG.Roll.Failure")}`; + } + + const failureMark = + this.actor?.type === "agent" && + !this.isSuccess && + this.skillPath && + this.key !== "unnatural" && + !foundry.utils.getProperty(this.actor, `${this.skillPath}.failure`) && + game.settings.get(DG.ID, "skillFailure"); + + const html = await renderTemplate( + "systems/deltagreen/templates/roll/percentile-roll.hbs", + { + styleOverride, + resultString, + formula: this.formula, + total: this.total, + failureMark, + }, + ); + + // TODO: add setting for it? + if (failureMark) { + const keyForUpdate = `${this.skillPath}.failure`; + + const message = await this.toMessage({ + flags: { + deltagreen: { + rollbacks: { + [keyForUpdate]: false, + }, + }, + }, + content: html, + flavor: label, + }); + + if (diceSoNice) { + await game.dice3d.waitFor3DAnimationByMessageID(message.id); + } + + // TODO: auto-update actor or post icon with manual apply + await this.actor.update({ + [keyForUpdate]: true, + }); + + return message; + } + + return this.toMessage({ content: html, flavor: label }); + } + + /** + * Utility function, called in the DGPercentileRoll constructor. + * If this roll key corresponds to a stat, skill, + * or typedSkill, get pertinent info. + * + * This is used for Stat, Skill, Typed Skill, Weapon, and Special Training Rolls. + * + * @returns {Object} - Contains the roll target and localized version of the key. + */ + getRollInfoFromKey() { + const actorData = this.actor.system; + const skillKeys = Object.keys(actorData.skills); + const typedSkillKeys = Object.keys(actorData.typedSkills); + const statKeys = Object.keys(actorData.statistics); + + let target = null; + let localizedKey = null; + let skillPath = null; // For optimization of failure checks + if (statKeys.includes(this.key)) { + target = actorData.statistics[this.key].x5; + localizedKey = game.i18n.localize(`DG.Attributes.${this.key}`); + } + if (skillKeys.includes(this.key)) { + // use calculated target proficiency (effects and etc like aim + 20%) + target = + actorData.skills[this.key].targetProficiency || + actorData.skills[this.key].proficiency; + localizedKey = game.i18n.localize(`DG.Skills.${this.key}`); + skillPath = `system.skills.${this.key}`; + } + if (typedSkillKeys.includes(this.key)) { + const skill = actorData.typedSkills[this.key]; + target = skill.proficiency; + localizedKey = `${skill.group} (${skill.label})`; + skillPath = `system.typedSkills.${this.key}`; + } + if (this.key === "ritual") { + target = actorData.sanity.ritual; + localizedKey = game.i18n.localize(`DG.Skills.ritual`); + } + return { target, localizedKey, skillPath }; + } + + /** + * Create label based on result of roll + * + * todo: do we want make isInhuman more similar to base label? + * + * @returns {string} + */ + createLabel() { + const startOfLabel = `${game.i18n.localize("DG.Roll.Rolling")} ${ + this.localizedKey + }`; + const endOfLabel = `${game.i18n.localize("DG.Roll.Target")} ${ + this.effectiveTarget + }`; + + let label = this.isInhuman + ? // "Inhuman" stat being rolled. See function for details. + `${startOfLabel} [${game.i18n + .localize("DG.Roll.Inhuman") + .toUpperCase()}] ${endOfLabel}` + : `${startOfLabel}
${endOfLabel}%`; + + const { isExhausted, exhaustedCheckPenalty } = this.exhausted; + + if (this.modifier || isExhausted) { + label += ` (${this.target}%`; + + if (this.modifier) { + label += `${DGUtils.formatStringWithLeadingPlus(this.modifier)}%`; + } + + if (isExhausted) { + label += `${DGUtils.formatStringWithLeadingPlus( + exhaustedCheckPenalty, + )}%`; + } + + label += `)`; + } + + return label; + } + + get exhausted() { + let isExhausted = false; + let exhaustedCheckPenalty = -20; + + try { + // I suspect (but am not entirely certain) that being tired doesn't make you less lucky) + if (this.type !== "luck") { + isExhausted = this.actor.system.physical.exhausted; + exhaustedCheckPenalty = this.actor.system.physical.exhaustedPenalty; + exhaustedCheckPenalty = -1 * Math.abs(exhaustedCheckPenalty); + } + } catch { + isExhausted = false; + exhaustedCheckPenalty = -20; + } + + return { isExhausted, exhaustedCheckPenalty }; + } + + /** + * "Inhuman" stat being rolled, logic is different per page 188 of the Handler's Guide. + * Note - originally implemented by Uriele, but my attempt at merging conficts went poorly, so re-implementing. + * For an inhuman check, the roll succeeds except on a roll of 100 which fails AND fumbles. + * If the roll is a matching digit roll, it is a critical as normal. + * Also, if the roll is below the regular (non-x5) value of the stat, it is a critical. E.g. a CON of 25, a d100 roll of 21 would be a critical. + * + * @returns {Boolean} + */ + get isInhuman() { + /* + Changing this to only consider the base x5 stat target for whether something is 'inhuman' + because I do not think the intent was an Agent with a high strength getting a +40% bonus to be considered 'inhuman' + and therefore benefit from the increased crit threshold, although could be wrong about this. + */ + if (this.target > 99 && this.type === "stat") { + return true; + } + return false; + } + + /** + * Determines if a roll result is critical. + * If roll has not been evaluated, return null. + * + * @returns {null|Boolean} + */ + get isCritical() { + // If roll isn't evaluated, return null. + if (!this.total) { + return null; + } + let isCritical = false; + + // 1, 100, or any matching dice are a crit, i.e. 11, 22, 33...99. + if (this.total === 1 || this.total === 100 || this.total % 11 === 0) { + // really good, or reeaaaally bad + isCritical = true; + } + + // If inhuman and the roll is below the regular (non-x5) value of the stat, it is a critical. + // E.g. a CON of 25, a d100 roll of 21 would be a critical. + if (this.isInhuman && this.total <= this.target / 5) { + isCritical = true; + } + + return isCritical; + } + + /** + * Determines if a roll succeeded. + * If roll has not been evaluated, return null. + * + * @returns {null|Boolean} + */ + get isSuccess() { + // If roll isn't evaluated, return null. + if (!this.total) { + return null; + } + + // A roll of 100 always (critically) fails, even for inhuman rolls. + if (this.total === 100) return false; + return this.total <= this.effectiveTarget; + } + + /** + * Actual target for the roll accounting for modifier if present. + * Floored to 1 if a negative modifier would bring it below 1. + * Capped at 99 unless it is an inhuman stat test. + * Also worth noting, per page 47 of the Agent's Handbook, Exhaustion penalties + * affect not only skill and stat tests, but SAN tests as well... + * + * @returns {null|integer} + */ + get effectiveTarget() { + let target = 1; + + const { isExhausted, exhaustedCheckPenalty } = this.exhausted; + + if (!this.target || Number.isNaN(this.target)) { + return null; + } + + target = parseInt(this.target); + + if (isExhausted) { + target += exhaustedCheckPenalty; + } + + if (this.modifier && !Number.isNaN(this.modifier)) { + const modifier = parseInt(this.modifier); + + target += modifier; + + // per agent's handbook (pg.43), a negative modifier can't lower a target below 1% + target = Math.max(target, 1); + } + + // an 'inhuman' stat test can exceed 99% as a target, but skill tests otherwise cannot (agents handbook pg.43) + if (!this.isInhuman) { + target = Math.min(target, 99); + } + + return target; + } +} + +export class DGLethalityRoll extends DGPercentileRoll { + /** + * See constructor for DGPercentileRoll. This theoretically could be done in the parent class' + * constructor, but since Lethality rolls needs its own class for custom methods anyway, + * we will set the target and localized key here. + * + * @param {String} formula + * @param {Object} data + * @param {Object} options + */ + constructor(formula, data, options) { + super(formula, data, options); + this.target = options.item.system.lethality; + this.localizedKey = game.i18n.localize("DG.ItemWindow.Weapons.Lethality"); + } + + /** + * Prepares data for a chat message and then passes that data + * to a method that actually creates a ChatMessage. + * + * Lays out and styles message based on outcome of the roll. + * + * Overrides `DGPercentileRoll.toChat()` + * + * @returns {Promise} - the created chat message. + * @override + */ + async toChat() { + let resultString = ""; + let styleOverride = ""; + if (this.total <= this.target) { + resultString = `${game.i18n.localize("DG.Roll.Lethal").toUpperCase()}`; + styleOverride = "color: red"; + } else { + resultString = `${game.i18n.localize("DG.Roll.Failure")}`; + } + + const { nonLethalDamage } = this; + let label = `${game.i18n.localize("DG.Roll.Rolling")} ${game.i18n + .localize("DG.Roll.Lethality") + .toUpperCase()} ${game.i18n.localize( + "DG.Roll.For", + )} ${this.item.name.toUpperCase()} ${game.i18n.localize( + "DG.Roll.Target", + )} ${this.target + this.modifier}`; + if (this.modifier) { + label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`; + } + + let html = ""; + html += `
`; + html += `
`; + html += `
${resultString}
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += ` `; + html += ` d100`; + html += ` `; + html += ` `; + html += ` ${this.total}`; + html += ` `; + html += `
`; + html += `
    `; + html += `
  1. ${this.total}`; + html += `
`; + html += `
`; + html += `
`; + html += ` `; + html += ` 2d10 (d10 + d10)`; + html += ` `; + html += ` `; + html += ` ${nonLethalDamage.total}`; + html += ` `; + html += `
`; + html += `
    `; + html += `
  1. ${nonLethalDamage.die1}
  2. `; + html += `
  3. ${nonLethalDamage.die2}
  4. `; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `

${this.total} (${ + nonLethalDamage.total + } ${game.i18n.localize("DG.Roll.Damage")})

`; + html += `
`; + html += `
`; + + return this.toMessage({ content: html, flavor: label }); + } + + /** + * Calculates the damage for when a lethality roll fails. + * If roll has not been evaluated, return null. + * + * See full rules on page 57 of agent's handbook. + * + * Note, this getter does not actually care if the roll has failed. + * + * @returns {null|Object} - return data about the non-lethal damage. + */ + get nonLethalDamage() { + if (!this.total) { + return null; + } + + // Try to determine what the d100 result would be as if it was two d10's being rolled. + const totalString = this.total.toString(); + const digits = totalString.length; + let die1; + let die2; + switch (digits) { + case 1: + // If one digit in the result, one die is a 10, and the other is the result. + [die1, die2] = [10, this.total]; + break; + case 2: + // If two digits in the result, each die is the value of one of the digits. If one of those digits is 0, make it 10. + [die1, die2] = totalString + .split("") + .map((digit) => parseInt(digit)) + .map((digit) => digit || 10); + break; + case 3: + // If three digits in the result (aka result === 100), each die is a 10. + [die1, die2] = [10, 10]; + break; + default: + break; + } + + const total = die1 + die2; + return { die1, die2, total }; + } +} + +export class DGDamageRoll extends DGRoll { + /** + * Prepares data for a chat message and then passes that data + * to a method that actually creates a ChatMessage. + * + * @returns {Promise} - the created chat message. + * @override + */ + async toChat() { + let label = this.formula; + try { + label = `${game.i18n.localize("DG.Roll.Rolling")} ${game.i18n + .localize("DG.Roll.Damage") + .toUpperCase()} ${game.i18n.localize("DG.Roll.For")} ${ + this.item.name + } (${ + this.item.system.armorPiercing + } armor penetration)`; + } catch (ex) { + // console.log(ex); + label = `Rolling DAMAGE for ${label.toUpperCase()}`; + } + return this.toMessage({ content: this.total, flavor: label }); + } + + async showDialog() { + const template = + "systems/deltagreen/templates/dialog/modify-damage-roll.html"; + const backingData = { + data: { + label: this.item?.name, + originalFormula: this.formula, + outerModifier: "2 * ", + innerModifier: "+ 0", + }, + }; + + const content = await renderTemplate(template, backingData); + return new Promise((resolve, reject) => { + new DialogV2({ + content, + window: { + title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"), + }, + buttons: [ + { + default: true, + label: game.i18n.translations.DG.Roll.Roll, + action: "roll", + callback: (event, button, dialog) => { + try { + const outerModifier = dialog.element.querySelector( + "[name='outerModifier']", + )?.value; // this is text as a heads up + let innerModifier = dialog.element.querySelector( + "[name='innerModifier']", + )?.value; // this is text as a heads up + const modifiedBaseRoll = dialog.element.querySelector( + "[name='originalFormula']", + )?.value; // this is text as a heads up + const rollMode = dialog.element.querySelector( + "[name='targetRollMode']", + )?.value; + + if (innerModifier.replace(" ", "") === "+0") { + innerModifier = ""; + } + + let newFormula = ""; + if (outerModifier.trim() !== "") { + newFormula += `${outerModifier}(${modifiedBaseRoll}${innerModifier.trim()})`; + } else { + newFormula += modifiedBaseRoll + innerModifier.trim(); + } + + resolve({ newFormula, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, + ], + }).render(true); + }); + } +} + +export class DGSanityDamageRoll extends DGRoll { + /** + * Prepares data for a chat message and then passes that data + * to a method that actually creates a ChatMessage. + * + * @returns {Promise} - the created chat message. + * @override + */ + async toChat() { + const [lowDie, highDie] = this.terms[0].terms.map((formula) => { + return Roll.parse(formula)[0] || { faces: parseInt(formula), number: 1 }; + }); + + const [lowResult, highResult] = this.damageResults; + + const flavor = `Rolling ${DGUtils.localizeWithFallback( + "DG.Generic.SanDamage", + "SAN DAMAGE", + )} For ${lowDie.formula} / ${highDie.formula}`; + + let html = ""; + html += `
`; + html += `
`; + html += `
${lowDie.formula} / ${highDie.formula}
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += ` `; + html += ` ${lowDie.formula}`; + html += ` `; + html += ` `; + html += ` ${lowResult}`; + html += ` `; + html += `
`; + html += `
    `; + html += `
  1. ${lowResult}`; + html += `
`; + html += `
`; + html += `
`; + html += ` `; + html += ` ${highDie.formula}`; + html += ` `; + html += ` `; + html += ` ${highResult}`; + html += ` `; + html += `
`; + html += `
    `; + html += `
  1. ${highResult}
  2. `; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `
`; + html += `

${lowResult} / ${highResult}

`; + html += `
`; + html += `
`; + return this.toMessage({ content: html, flavor }); + } + + /** + * Returns the two results for a sanity damage roll. + * + * Returns null if the roll has not been evaluated. + * + * @returns {null|Array} - Array of result numbers + */ + get damageResults() { + if (!this.total) return null; + + const [lowResult, highResult] = this.terms[0].results; + return [lowResult?.result, highResult?.result]; + } +} diff --git a/module/settings.js b/module/settings.js new file mode 100644 index 0000000..2e3ad25 --- /dev/null +++ b/module/settings.js @@ -0,0 +1,382 @@ +/* eslint-disable max-classes-per-file */ +import DG, { BASE_TEMPLATE_PATH } from "./config.js"; +import DGActorSheet from "./sheets/base-actor-sheet.js"; + +const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; + +/** + * Base class for all setting forms. + * + * Note: This class is abstract and should not be instantiated directly. + * + * @extends {ApplicationV2} + */ +const SettingForm = class extends HandlebarsApplicationMixin(ApplicationV2) { + /** @type {"automation"|"handler"|null} */ + static _namespace = null; + + /** + * The namespace for the settings defined by this class. This is necessary + * to register the settings with the game. + * + * @returns {string} + */ + static get namespace() { + return this._namespace; + } + + /** + * A getter that returns an object with all the settings defined by the subclass. + * Used to register settings with the game. + * + * @abstract + * @returns {object} An object with all the settings defined by the subclass + * @throws Will throw an error if this method is not defined by a subclass. + */ + static get settings() { + throw new Error("This static getter must be defined by a subclass"); + } + + /** + * Registers the settings for each defined SettingForm subclass. + * @returns {void} + */ + static register() { + const { settings } = this; + for (const [settingID, setting] of Object.entries(settings)) { + game.settings.register(DG.ID, settingID, { + scope: "world", + config: false, + name: game.i18n.localize(`DG.Settings.${settingID}.name`), + hint: game.i18n.localize(`DG.Settings.${settingID}.hint`), + ...setting, + }); + } + } + + /** @override */ + static DEFAULT_OPTIONS = { + tag: "form", + id: "dg-settings", + classes: [DG.ID, "settings-menu"], + window: { contentClasses: ["standard-form"], resizable: true }, + position: { width: 500, height: "auto" }, + actions: {}, + form: { + handler: this.onSubmit, + submitOnChange: false, + closeOnSubmit: true, + }, + }; + + /** @override */ + static PARTS = { + footer: { template: `${BASE_TEMPLATE_PATH}/save.hbs` }, + }; + + /** @override */ + static async onSubmit(event, form, formData) { + event.preventDefault(); + // Get form data into a standard object. + const data = foundry.utils.expandObject(formData.object); + + const settingsPromises = []; + // Set each setting with the new value, if any. + for (const [key, value] of Object.entries(data[DG.ID])) { + settingsPromises.push(game.settings.set(DG.ID, key, value)); + } + + // Once all promises resolve, show a notification. + Promise.allSettled(settingsPromises).then((values) => { + ui.notifications.info(game.i18n.localize("DG.Settings.Saved")); + }); + } + + /** @override */ + _onFirstRender(options) { + super._onFirstRender(options); + + this._attachFormGroupHTML(); + } + + /** + * Populate the window content section with form groups representing the settings. + * @returns {void} + */ + _attachFormGroupHTML() { + const windowContent = this.element.querySelector("section.window-content"); + const formGroupString = this._prepareFormGroupElements() + .map((formGroup) => formGroup.outerHTML) + .join(""); + + // Create a div element whose inner html is the form groups (as a string of HTML), + // and prepend it to the window content. + const div = document.createElement("div"); + div.classList.add("flexcol"); + div.innerHTML = formGroupString; + windowContent.prepend(div); + } + + /** + * Generates an array of form groups, each corresponding to a setting in a menu. + * @returns {HTMLDivElement[]} An array of form group HTML elements. + */ + _prepareFormGroupElements() { + // Get Foundry's built-in input creation functions. + const { + createCheckboxInput, + createNumberInput, + createSelectInput, + createTextInput, + createFormGroup, + } = foundry.applications.fields; + const formGroups = []; + + // Iterate over each setting and create the appropriate input element. + const { settings } = this.constructor; + for (const settingID of Object.keys(settings)) { + // The setting config object, not the value of the setting itself. + const settingConfig = game.settings.settings.get(`${DG.ID}.${settingID}`); + + // Default input settings. + const inputConfig = { + name: `${DG.ID}.${settingID}`, + value: game.settings.get(DG.ID, settingID), // The value that the setting is currently set to. + label: settingConfig.name, + }; + + // Use Foundry's built-in /`; + + if (currentGroup === game.i18n.translations.DG?.TypeSkills?.Art ?? "Art") { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.Craft ?? + "Craft" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ?? + "Foreign Language" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.MilitaryScience ?? + "Military Science" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.Pilot ?? + "Pilot" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.Science ?? + "Science" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + if ( + currentGroup === game.i18n.translations.DG?.TypeSkills?.Other ?? + "Other" + ) { + htmlContent += ` `; + } else { + htmlContent += ` `; + } + + htmlContent += ` `; + htmlContent += ``; + + htmlContent += `
`; + htmlContent += ` `; + htmlContent += ` `; + htmlContent += `
`; + + new DialogV2({ + content: htmlContent, + window: { + title: + game.i18n.translations.DG?.Skills?.EditTypedOrCustomSkill ?? + "Edit Typed or Custom Skill", + }, + buttons: [ + { + default: true, + action: "add", + label: game.i18n.translations.DG?.Skills?.EditSkill ?? "Edit Skill", + callback: (event, button, dialog) => { + const newTypeSkillLabel = dialog.element.querySelector( + "[name='new-type-skill-label']", + )?.value; + const newTypeSkillGroup = dialog.element.querySelector( + "[name='new-type-skill-group']", + )?.value; + this._updateTypedSkill( + targetSkill, + newTypeSkillLabel, + newTypeSkillGroup, + ); + }, + }, + ], + }).render(true); + } + + _showNewTypeSkillDialog() { + let htmlContent = ""; + + htmlContent += `
`; + htmlContent += ` `; + htmlContent += ` `; + htmlContent += `
`; + + htmlContent += `
`; + htmlContent += ` `; + htmlContent += ` `; + htmlContent += `
`; + + new DialogV2({ + content: htmlContent, + window: { + title: + game.i18n.translations.DG?.Skills?.AddTypedOrCustomSkill ?? + "Add Typed or Custom Skill", + }, + default: "add", + buttons: [ + { + default: true, + action: "add", + label: game.i18n.translations.DG?.Skills?.AddSkill ?? "Add Skill", + callback: (event, button, dialog) => { + const newTypeSkillLabel = dialog.element.querySelector( + "[name='new-type-skill-label']", + )?.value; + const newTypeSkillGroup = dialog.element.querySelector( + "[name='new-type-skill-group']", + )?.value; + this._addNewTypedSkill(newTypeSkillLabel, newTypeSkillGroup); + }, + }, + ], + }).render(true); + } + + _addNewTypedSkill(newSkillLabel, newSkillGroup) { + const updatedData = foundry.utils.duplicate(this.actor.system); + const { typedSkills } = updatedData; + + const d = new Date(); + + const newSkillPropertyName = + d.getFullYear().toString() + + (d.getMonth() + 1).toString() + + d.getDate().toString() + + d.getHours().toString() + + d.getMinutes().toString() + + d.getSeconds().toString(); + // console.log(newSkillPropertyName); + typedSkills[newSkillPropertyName] = { + label: newSkillLabel, + group: newSkillGroup, + proficiency: 10, + failure: false, + }; + + updatedData.typedSkills = typedSkills; + + this.actor.update({ system: updatedData }); + } + + _updateTypedSkill(targetSkill, newSkillLabel, newSkillGroup) { + if ( + newSkillLabel !== null && + newSkillLabel !== "" && + newSkillGroup !== null && + newSkillGroup !== "" + ) { + const updatedData = foundry.utils.duplicate(this.actor.system); + + updatedData.typedSkills[targetSkill].label = newSkillLabel; + updatedData.typedSkills[targetSkill].group = newSkillGroup; + + this.actor.update({ system: updatedData }); + } + } + + static _onSpecialTrainingAction(event, target) { + const { actionType, id } = target.dataset; + switch (actionType) { + case "delete": + { + const specialTrainingArray = foundry.utils.duplicate( + this.actor.system.specialTraining, + ); + + // Get the index of the training to be deleted + const index = specialTrainingArray.findIndex( + (training) => training.id === id, + ); + + specialTrainingArray.splice(index, 1); + this.actor.update({ "system.specialTraining": specialTrainingArray }); + } + break; + default: + this._showSpecialTrainingDialog(actionType, id); + break; + } + } + + async _showSpecialTrainingDialog(action, targetID) { + const specialTraining = this.actor.system.specialTraining.find( + (training) => training.id === targetID, + ); + + // Define the option groups for our drop-down menu. + const optionGroups = { + stats: game.i18n.localize( + "DG.SpecialTraining.Dialog.DropDown.Statistics", + ), + skills: game.i18n.localize("DG.SpecialTraining.Dialog.DropDown.Skills"), + typedSkills: game.i18n.localize( + "DG.SpecialTraining.Dialog.DropDown.CustomSkills", + ), + }; + + // Prepare simplified stat list + const statList = Object.entries(this.actor.system.statistics).map( + ([key, stat]) => ({ + value: key, + group: optionGroups.stats, + label: game.i18n.localize(`DG.Attributes.${key}`), + targetNumber: stat.value * 5, + }), + ); + + // Prepare simplified skill list + const skillList = Object.entries(this.actor.system.skills).map( + ([key, skill]) => ({ + value: key, + group: optionGroups.skills, + label: game.i18n.localize(`DG.Skills.${key}`), + targetNumber: skill.proficiency, + }), + ); + + // Prepare simplified typed/custom skill list + const typedSkillList = Object.entries(this.actor.system.typedSkills).map( + ([key, skill]) => ({ + value: key, + group: optionGroups.typedSkills, + label: `${game.i18n.localize(`DG.TypeSkills.${skill.group}`)} (${ + skill.label + })`, + targetNumber: skill.proficiency, + }), + ); + + // Prepare the Select element + const selectElement = foundry.applications.fields.createSelectInput({ + name: "special-training-skill", + options: [...statList, ...skillList, ...typedSkillList], + groups: Object.values(optionGroups), + }).outerHTML; + + // Prepare the template to feed to Dialog. + const { renderTemplate } = foundry.applications.handlebars; + const content = await renderTemplate( + "systems/deltagreen/templates/dialog/special-training.html", + { + name: specialTraining?.name || "", + selectElement, + currentAttribute: specialTraining?.attribute || "", + statList, + skillList, + typedSkillList, + }, + ); + + const buttonLabel = game.i18n.localize( + `DG.SpecialTraining.Dialog.${action.capitalize()}SpecialTraining`, + ); + + // Prepare and render dialog with above template. + new DialogV2({ + content, + window: { + title: game.i18n.localize("DG.SpecialTraining.Dialog.Title"), + }, + default: "confirm", + buttons: [ + { + default: true, + action: "confirm", + label: buttonLabel, + callback: (event, button, dialog) => { + const specialTrainingLabel = dialog.element.querySelector( + "[name='special-training-label']", + )?.value; + const specialTrainingAttribute = dialog.element.querySelector( + "[name='special-training-skill']", + )?.value; + if (action === "create") + this._createSpecialTraining( + specialTrainingLabel, + specialTrainingAttribute, + ); + if (action === "edit") + this._editSpecialTraining( + specialTrainingLabel, + specialTrainingAttribute, + targetID, + ); + }, + }, + ], + }).render(true); + } + + _createSpecialTraining(label, attribute) { + const specialTrainingArray = foundry.utils.duplicate( + this.actor.system.specialTraining, + ); + specialTrainingArray.push({ + name: label, + attribute, + id: foundry.utils.randomID(), + }); + this.actor.update({ "system.specialTraining": specialTrainingArray }); + } + + _editSpecialTraining(label, attribute, id) { + const specialTrainingArray = foundry.utils.duplicate( + this.actor.system.specialTraining, + ); + const specialTraining = specialTrainingArray.find( + (training) => training.id === id, + ); + specialTraining.name = label; + specialTraining.attribute = attribute; + this.actor.update({ "system.specialTraining": specialTrainingArray }); + } + + /** + * Handle clickable rolls. + * + * @param {Event} event The originating click event + * @async + * @private + */ + static async _onRoll(event, target) { + if (target.classList.contains("not-rollable") || event.which === 2) return; + + const { dataset } = target; + const item = this.actor.items.get(dataset.iid); + const rollOptions = { + rollType: dataset.rolltype, + key: dataset.key, + actor: this.actor, + specialTrainingName: dataset?.name || null, // Only applies to Special Training Rolls + item, + }; + + // Create a default 1d100 roll just in case. + let roll = new Roll("1d100", {}); + switch (dataset.rolltype) { + case "stat": + case "skill": + case "sanity": + case "special-training": + case "weapon": + roll = new DGPercentileRoll("1D100", {}, rollOptions); + break; + case "lethality": + roll = new DGLethalityRoll("1D100", {}, rollOptions); + break; + case "damage": { + let diceFormula = item.system.damage; + const { skill } = item.system; + if ( + (this.actor.type === "agent" || this.actor.type === "npc") && + (skill === "unarmed_combat" || skill === "melee_weapons") + ) { + diceFormula += + this.actor.system.statistics.str.meleeDamageBonusFormula; + } + roll = new DGDamageRoll(diceFormula, {}, rollOptions); + break; + } + case "sanity-damage": { + const { successLoss, failedLoss } = this.actor.system.sanity; + const combinedFormula = `{${successLoss}, ${failedLoss}}`; + roll = new DGSanityDamageRoll(combinedFormula, {}, rollOptions); + break; + } + default: + break; + } + this.processRoll(event, roll, rollOptions); + } + + // This only exists to give a chance to activate the modifier dialogue if desired + // Cannot seem to trigger the event on a right-click, so unfortunately only applies to a shift-click currently. + static async _onRollLuck(event) { + // probably don't want rolls to trigger from a middle mouse click so just kill it here + if (event.which === 2) return; + + const rollOptions = { + rollType: "luck", + key: "luck", + actor: this.actor, + }; + + // Create a default 1d100 roll just in case. + const roll = new DGPercentileRoll("1D100", {}, rollOptions); + // Open dialog if user requests it. + if (event.shiftKey || event.which === 3) { + const dialogData = await roll.showDialog(); + if (!dialogData) return; + roll.modifier += dialogData.targetModifier; + roll.options.rollMode = dialogData.rollMode; + } + // Evaluate the roll. + await roll.evaluate(); + // Send the roll to chat. + roll.toChat(); + } + + /** + * Show a dialog for the roll and then send to chat. + * Broke this logic out from `_onRoll()` so that other files can call it, + * namely the macro logic. + * + * TODO: Move this logic to the roll.js. + * + * @param {Event} event The originating click event + * @param {Event} roll The roll to show a dialog for and then send to chat. + * @async + */ + async processRoll(event, roll) { + // Open dialog if user requests it (no dialog for Sanity Damage rolls) + if ( + (event.shiftKey || event.which === 3) && + !(roll instanceof DGSanityDamageRoll) + ) { + const dialogData = await roll.showDialog(); + if (!dialogData) return; + if (dialogData.newFormula) { + roll = new DGDamageRoll(dialogData.newFormula, {}, roll.options); + } + roll.modifier += dialogData.targetModifier; + roll.options.rollMode = dialogData.rollMode; + } + // Evaluate the roll. + await roll.evaluate(); + // Send the roll to chat. + roll.toChat(); + } + + /** Handler for generic toggle events */ + static _toggleGeneric(event, target) { + const { prop } = target.dataset; + const itemId = target.closest("[data-item-id]")?.dataset.itemId; + this.toggle(prop, itemId); + } + + /** Handler for item-sort-mode toggle events */ + static _toggleItemSortMode(event, target) { + const itemType = target.dataset.gearType; + const propString = `${itemType}SortAlphabetical`; + const targetProp = `system.settings.sorting.${propString}`; + this.toggle(targetProp); + } + + static _browsePack(event, target) { + const { packType } = target.dataset; + switch (packType) { + case "weapon": { + new DialogV2({ + window: { title: "Select Compendium" }, + buttons: [ + { + action: "firearms", + label: game.i18n.localize("DG.Gear.WeaponTypes.Firearms"), + icon: '', + callback: () => + game.packs + .find((k) => k.collection === "deltagreen.firearms") + .render(true), + }, + { + action: "melee", + label: game.i18n.localize("DG.Gear.WeaponTypes.Melee"), + icon: '', + callback: () => + game.packs + .find( + (k) => k.collection === "deltagreen.hand-to-hand-weapons", + ) + .render(true), + }, + ], + }).render(true); + break; + } + default: + game.packs + .find((k) => k.collection === `deltagreen.${packType}`) + .render(true); + break; + } + } + + /** + * Toggle a boolean property on an item or actor. + * + * @param {string} prop The property to toggle. + * @param {string} [itemId] The ID of item on which to apply toggle, if it exists. + */ + toggle(prop, itemId) { + const item = this.actor.items.get(itemId); + const targetDoc = item ?? this.actor; + + const currentVal = foundry.utils.getProperty(targetDoc, prop); + targetDoc.update({ [prop]: !currentVal }); + } + + /** + * Require Shift while hovering to show tooltips. + * Supports either data-tooltip (preferred, may contain HTML) or title (plain text). + */ + _tooltipsSettings(root) { + const mode = game.settings.get("deltagreen", "skillTooltipDisplay"); + + // If not explicitly hoverShift or never, do nothing. + if (mode !== "hoverShift" && mode !== "never") return; + + // Query elements with either data-tooltip OR title + const nodes = root.querySelectorAll("[data-tooltip],[title]"); + + // If mode is "never": strip native attributes so no tooltips (native or custom) can appear. + if (mode === "never") { + nodes.forEach((el) => { + if (el.dataset.shiftTooltipInstalled === "true") return; + el.removeAttribute("data-tooltip"); + el.removeAttribute("title"); + el.dataset.shiftTooltipInstalled = "true"; + }); + return; + } + + // mode === "hoverShift": install Shift-to-show behavior using Foundry's tooltip + nodes.forEach((el) => { + if (el.dataset.shiftTooltipInstalled === "true") return; + + // Prefer data-tooltip, else use title + let html = el.getAttribute("data-tooltip"); + let isHtml = true; + + if (!html) { + const title = el.getAttribute("title"); + if (title) { + html = foundry.utils.escapeHTML(title); // treat title as plain text + isHtml = false; + } + } + + if (!html) return; // nothing usable + + // Remove native attributes so default tooltips don’t trigger + el.removeAttribute("data-tooltip"); + el.removeAttribute("title"); + el.dataset.shiftTooltipInstalled = "true"; + + // Always pass through { html } so
etc. render + const opts = isHtml ? { html } : { text: html }; + + const show = () => game.tooltip.activate(el, opts); + const hide = () => game.tooltip.deactivate(); + + const onKey = (ev) => { + if (ev.key !== "Shift") return; + if (!document.body.contains(el)) { + window.removeEventListener("keydown", onKey); + window.removeEventListener("keyup", onKey); + return; + } + if (ev.type === "keydown") show(); + else hide(); + }; + + const onEnter = (ev) => { + if (ev.shiftKey) show(); + window.addEventListener("keydown", onKey); + window.addEventListener("keyup", onKey); + }; + + const onLeave = () => { + hide(); + window.removeEventListener("keydown", onKey); + window.removeEventListener("keyup", onKey); + }; + + el.addEventListener("pointerenter", onEnter, { passive: true }); + el.addEventListener("pointerleave", onLeave, { passive: true }); + }); + } +} diff --git a/module/sheets/base-sheet.js b/module/sheets/base-sheet.js new file mode 100644 index 0000000..f4de812 --- /dev/null +++ b/module/sheets/base-sheet.js @@ -0,0 +1,69 @@ +import DG, { BASE_TEMPLATE_PATH } from "../config.js"; + +const HbsAppMixin = foundry.applications.api.HandlebarsApplicationMixin; + +const DGSheetMixin = (Base) => { + return class DGDocumentSheet extends HbsAppMixin(Base) { + /** @inheritdoc */ + static DEFAULT_OPTIONS = /** @type {const} */ ({ + window: { resizable: true }, + classes: [DG.ID, "sheet"], + form: { submitOnChange: true }, + }); + + static TEMPLATE_PATH = BASE_TEMPLATE_PATH; + + static get THEME() { + return game.settings.get(DG.ID, "characterSheetStyle"); + } + + get THEME() { + return this.constructor.THEME; + } + + /** @inheritdoc */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + const docName = this.document.documentName.toLowerCase(); + + // Add the document to the context under a descriptive name (i.e. "actor", "item") + context[docName] = this.document; + + return context; + } + /** @inheritdoc */ + + async _onFirstRender(context, options) { + await super._onFirstRender(context, options); + + const html = this.element; + html + .querySelector(".window-content") + .classList.add(`${this.THEME}-style`); + } + + /** @inheritdoc */ + async _onRender(context, options) { + await super._onRender(context, options); + + const html = this.element; + + // Double-click resize handle to reset sheet to original size. + html + .querySelector(".window-resize-handle") + .addEventListener("dblclick", () => { + this.resetPosition(); + }); + } + + /** + * Resets the window's position to its default, as specified in the Sheet's options. + * @returns {void} + */ + resetPosition() { + this.setPosition(this.options.position); + } + }; +}; + +export default DGSheetMixin; diff --git a/module/sheets/edit-stats.js b/module/sheets/edit-stats.js new file mode 100644 index 0000000..1b1eb5e --- /dev/null +++ b/module/sheets/edit-stats.js @@ -0,0 +1,44 @@ +import DG, { BASE_TEMPLATE_PATH } from "../config.js"; + +export default class ActorEditStatForm extends foundry.applications.api.HandlebarsApplicationMixin( + foundry.applications.api.ApplicationV2, +) { + constructor(params) { + super(); + this.actor = params.actor; + } + + /** @override */ + static DEFAULT_OPTIONS = { + tag: "form", + classes: [DG.ID, "edit-stat-form"], + window: { title: "Edit statistics form", resizable: true }, + position: { width: 400, height: 200 }, + actions: {}, + form: { + handler: this.formHandler, + submitOnChange: true, + closeOnSubmit: false, + }, + }; + + static PARTS = /** @type {const} */ ({ + stats: { + template: `${BASE_TEMPLATE_PATH}/actor/edit-stats.html`, + }, + }); + + /** @override */ + async _prepareContext(options) { + return { + ...(await super._prepareContext(options)), + actor: this.actor, + }; + } + + static async formHandler(event, form, formData) { + const data = formData.object; + + await this.actor.update(data); + } +} diff --git a/module/sheets/npc-sheet.js b/module/sheets/npc-sheet.js new file mode 100644 index 0000000..fe8418b --- /dev/null +++ b/module/sheets/npc-sheet.js @@ -0,0 +1,43 @@ +import DGActorSheet from "./base-actor-sheet.js"; + +/** @extends {DGActorSheet} */ +export default class DGNPCSheet extends DGActorSheet { + /** @override */ + static TABS = /** @type {const} */ ({ + primary: { + initial: "skills", + labelPrefix: "DG.Navigation.NPC", + tabs: [ + { id: "skills" }, + { id: "gear" }, + { id: "about", icon: "fas fa-question-circle", label: "" }, + ], + }, + }); + + /** @override */ + static PARTS = /** @type {const} */ ({ + header: this.BASE_PARTS.header, + statistics: { + template: `${this.TEMPLATE_PATH}/partials/attributes-grid-partial.html`, + }, + tabs: this.BASE_PARTS.tabs, + skills: this.BASE_PARTS.skills, + gear: this.BASE_PARTS.gear, + about: this.BASE_PARTS.about, + }); + + /* -------------------------------------------- */ + + /** @override */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + + // Override physical attribute title. + context.physicalAttributesTitle = game.i18n.localize( + "DG.Sheet.BlockHeaders.Statistics", + ); + + return context; + } +} diff --git a/module/sheets/unnatural-sheet.js b/module/sheets/unnatural-sheet.js new file mode 100644 index 0000000..7ad7ce1 --- /dev/null +++ b/module/sheets/unnatural-sheet.js @@ -0,0 +1,23 @@ +import DGNPCSheet from "./npc-sheet.js"; + +/** @extends {DGNPCSheet} */ +export default class DGUnnaturalSheet extends DGNPCSheet { + /** @override */ + async _processSubmitData(event, form, submitData, options) { + const submittedData = foundry.utils.expandObject(submitData); + + // we need to update max WP if POW has changed (only for unnatural, but doesn't hurt others) + submittedData.system.wp.maxNeedsUpdate = + submittedData.system?.statistics.pow.value !== + this.actor.system.statistics.pow.value; + + // we need to update max HP if STR or CON have changed (only for unnatural, but doesn't hurt others) + submittedData.system.health.maxNeedsUpdate = + submittedData.system?.statistics.str.value !== + this.actor.system.statistics.str.value || + submittedData.system?.statistics.con.value !== + this.actor.system.statistics.con.value; + + return super._processSubmitData(event, form, submittedData, options); + } +} diff --git a/module/sheets/vehicle-sheet.js b/module/sheets/vehicle-sheet.js new file mode 100644 index 0000000..89e1b4b --- /dev/null +++ b/module/sheets/vehicle-sheet.js @@ -0,0 +1,29 @@ +import DGActorSheet from "./base-actor-sheet.js"; + +/** @extends {DGSheetMixin(ActorSheetV2)} */ +export default class DGVehicleSheet extends DGActorSheet { + /** @override */ + static TABS = /** @type {const} */ ({ + primary: { + initial: "gear", + labelPrefix: "DG.Navigation.Vehicle", + tabs: [ + { id: "notes" }, + { id: "gear" }, + { id: "about", icon: "fas fa-question-circle", label: "" }, + ], + }, + }); + + /** @override */ + static PARTS = /** @type {const} */ ({ + header: this.BASE_PARTS.header, + tabs: this.BASE_PARTS.tabs, + notes: { + template: `${this.TEMPLATE_PATH}/parts/notes-tab.html`, + templates: [`${this.TEMPLATE_PATH}/partials/notes-partial.html`], + }, + gear: this.BASE_PARTS.gear, + about: this.BASE_PARTS.about, + }); +} diff --git a/module/templates.js b/module/templates.js new file mode 100644 index 0000000..dbc6613 --- /dev/null +++ b/module/templates.js @@ -0,0 +1,10 @@ +/** + * Define a set of template paths to pre-load + * Pre-loaded templates are compiled and cached for fast access when rendering + * @return {Promise} + */ +export default async function preloadHandlebarsTemplates() { + return foundry.applications.handlebars.loadTemplates([ + "systems/deltagreen/templates/dialog/modify-percentile-roll.html", + ]); +} diff --git a/packs/armor/000005.ldb b/packs/armor/000005.ldb new file mode 100644 index 0000000..acccb8e Binary files /dev/null and b/packs/armor/000005.ldb differ diff --git a/packs/armor/000007.log b/packs/armor/000007.log new file mode 100644 index 0000000..f1183c5 Binary files /dev/null and b/packs/armor/000007.log differ diff --git a/packs/armor/CURRENT b/packs/armor/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/armor/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/armor/LOCK b/packs/armor/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/armor/LOG b/packs/armor/LOG new file mode 100644 index 0000000..b99dbfd --- /dev/null +++ b/packs/armor/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.182364 173763000 Recovering log #4 +2026/07/15-17:16:33.183075 173763000 Delete type=0 #4 +2026/07/15-17:16:33.183123 173763000 Delete type=3 #2 diff --git a/packs/armor/LOG.old b/packs/armor/LOG.old new file mode 100644 index 0000000..4debf34 --- /dev/null +++ b/packs/armor/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:17.045433 7f49837fe6c0 Delete type=3 #1 +2026/06/20-04:43:17.048040 7f49827fc6c0 Level-0 table #5: started +2026/06/20-04:43:17.048698 7f49827fc6c0 Level-0 table #5: 1038 bytes OK +2026/06/20-04:43:17.049101 7f49827fc6c0 Delete type=0 #3 +2026/06/20-04:43:17.049169 7f49827fc6c0 Manual compaction at level-0 from '!items!0iBS0OdEMPN6WTsu' @ 72057594037927935 : 1 .. '!items!oYJsYalfaNchDt34' @ 0 : 0; will stop at (end) diff --git a/packs/armor/MANIFEST-000006 b/packs/armor/MANIFEST-000006 new file mode 100644 index 0000000..44b5ca3 Binary files /dev/null and b/packs/armor/MANIFEST-000006 differ diff --git a/packs/firearms/000005.ldb b/packs/firearms/000005.ldb new file mode 100644 index 0000000..2b2a50a Binary files /dev/null and b/packs/firearms/000005.ldb differ diff --git a/packs/firearms/000007.log b/packs/firearms/000007.log new file mode 100644 index 0000000..9afd11d Binary files /dev/null and b/packs/firearms/000007.log differ diff --git a/packs/firearms/CURRENT b/packs/firearms/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/firearms/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/firearms/LOCK b/packs/firearms/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/firearms/LOG b/packs/firearms/LOG new file mode 100644 index 0000000..41f7393 --- /dev/null +++ b/packs/firearms/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.179019 173763000 Recovering log #4 +2026/07/15-17:16:33.179771 173763000 Delete type=0 #4 +2026/07/15-17:16:33.179810 173763000 Delete type=3 #2 diff --git a/packs/firearms/LOG.old b/packs/firearms/LOG.old new file mode 100644 index 0000000..35539e7 --- /dev/null +++ b/packs/firearms/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:17.431494 7fd185fbd6c0 Delete type=3 #1 +2026/06/20-04:43:17.434071 7fd167fff6c0 Level-0 table #5: started +2026/06/20-04:43:17.434675 7fd167fff6c0 Level-0 table #5: 2610 bytes OK +2026/06/20-04:43:17.434956 7fd167fff6c0 Delete type=0 #3 +2026/06/20-04:43:17.435050 7fd167fff6c0 Manual compaction at level-0 from '!items!0Gz1jcY28Psezqrv' @ 72057594037927935 : 1 .. '!items!xb73X4SjsbuYs4D7' @ 0 : 0; will stop at (end) diff --git a/packs/firearms/MANIFEST-000006 b/packs/firearms/MANIFEST-000006 new file mode 100644 index 0000000..975a0e0 Binary files /dev/null and b/packs/firearms/MANIFEST-000006 differ diff --git a/packs/hand-to-hand-weapons/000005.ldb b/packs/hand-to-hand-weapons/000005.ldb new file mode 100644 index 0000000..689551f Binary files /dev/null and b/packs/hand-to-hand-weapons/000005.ldb differ diff --git a/packs/hand-to-hand-weapons/000007.log b/packs/hand-to-hand-weapons/000007.log new file mode 100644 index 0000000..8d2ee15 Binary files /dev/null and b/packs/hand-to-hand-weapons/000007.log differ diff --git a/packs/hand-to-hand-weapons/CURRENT b/packs/hand-to-hand-weapons/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/hand-to-hand-weapons/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/hand-to-hand-weapons/LOCK b/packs/hand-to-hand-weapons/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/hand-to-hand-weapons/LOG b/packs/hand-to-hand-weapons/LOG new file mode 100644 index 0000000..cf77388 --- /dev/null +++ b/packs/hand-to-hand-weapons/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.184870 173763000 Recovering log #4 +2026/07/15-17:16:33.185825 173763000 Delete type=0 #4 +2026/07/15-17:16:33.185872 173763000 Delete type=3 #2 diff --git a/packs/hand-to-hand-weapons/LOG.old b/packs/hand-to-hand-weapons/LOG.old new file mode 100644 index 0000000..1be102c --- /dev/null +++ b/packs/hand-to-hand-weapons/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:17.816191 7febb77be6c0 Delete type=3 #1 +2026/06/20-04:43:17.819388 7febb67bc6c0 Level-0 table #5: started +2026/06/20-04:43:17.819927 7febb67bc6c0 Level-0 table #5: 2410 bytes OK +2026/06/20-04:43:17.820228 7febb67bc6c0 Delete type=0 #3 +2026/06/20-04:43:17.820303 7febb67bc6c0 Manual compaction at level-0 from '!items!0gCwBTqSAbG9J20Y' @ 72057594037927935 : 1 .. '!items!u5fnrg385Z79DUK6' @ 0 : 0; will stop at (end) diff --git a/packs/hand-to-hand-weapons/MANIFEST-000006 b/packs/hand-to-hand-weapons/MANIFEST-000006 new file mode 100644 index 0000000..565c540 Binary files /dev/null and b/packs/hand-to-hand-weapons/MANIFEST-000006 differ diff --git a/packs/operation-code-name-generator-macro/000005.ldb b/packs/operation-code-name-generator-macro/000005.ldb new file mode 100644 index 0000000..d5c5b79 Binary files /dev/null and b/packs/operation-code-name-generator-macro/000005.ldb differ diff --git a/packs/operation-code-name-generator-macro/000007.log b/packs/operation-code-name-generator-macro/000007.log new file mode 100644 index 0000000..d04dcb0 Binary files /dev/null and b/packs/operation-code-name-generator-macro/000007.log differ diff --git a/packs/operation-code-name-generator-macro/CURRENT b/packs/operation-code-name-generator-macro/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/operation-code-name-generator-macro/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/operation-code-name-generator-macro/LOCK b/packs/operation-code-name-generator-macro/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/operation-code-name-generator-macro/LOG b/packs/operation-code-name-generator-macro/LOG new file mode 100644 index 0000000..7ee665d --- /dev/null +++ b/packs/operation-code-name-generator-macro/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.212425 171f3f000 Recovering log #4 +2026/07/15-17:16:33.213043 171f3f000 Delete type=0 #4 +2026/07/15-17:16:33.213097 171f3f000 Delete type=3 #2 diff --git a/packs/operation-code-name-generator-macro/LOG.old b/packs/operation-code-name-generator-macro/LOG.old new file mode 100644 index 0000000..6cec6ea --- /dev/null +++ b/packs/operation-code-name-generator-macro/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:18.581581 7f41e8bfd6c0 Delete type=3 #1 +2026/06/20-04:43:18.584042 7f41db7fe6c0 Level-0 table #5: started +2026/06/20-04:43:18.584617 7f41db7fe6c0 Level-0 table #5: 1073 bytes OK +2026/06/20-04:43:18.584947 7f41db7fe6c0 Delete type=0 #3 +2026/06/20-04:43:18.585037 7f41db7fe6c0 Manual compaction at level-0 from '!macros!YWm6lbQwW2la81fc' @ 72057594037927935 : 1 .. '!macros!YWm6lbQwW2la81fc' @ 0 : 0; will stop at (end) diff --git a/packs/operation-code-name-generator-macro/MANIFEST-000006 b/packs/operation-code-name-generator-macro/MANIFEST-000006 new file mode 100644 index 0000000..4b2f03c Binary files /dev/null and b/packs/operation-code-name-generator-macro/MANIFEST-000006 differ diff --git a/packs/operation-code-name-generator/000005.ldb b/packs/operation-code-name-generator/000005.ldb new file mode 100644 index 0000000..cd9ce59 Binary files /dev/null and b/packs/operation-code-name-generator/000005.ldb differ diff --git a/packs/operation-code-name-generator/000007.log b/packs/operation-code-name-generator/000007.log new file mode 100644 index 0000000..d09b042 Binary files /dev/null and b/packs/operation-code-name-generator/000007.log differ diff --git a/packs/operation-code-name-generator/CURRENT b/packs/operation-code-name-generator/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/operation-code-name-generator/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/operation-code-name-generator/LOCK b/packs/operation-code-name-generator/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/operation-code-name-generator/LOG b/packs/operation-code-name-generator/LOG new file mode 100644 index 0000000..476a993 --- /dev/null +++ b/packs/operation-code-name-generator/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.208946 171f3f000 Recovering log #4 +2026/07/15-17:16:33.209957 171f3f000 Delete type=0 #4 +2026/07/15-17:16:33.210012 171f3f000 Delete type=3 #2 diff --git a/packs/operation-code-name-generator/LOG.old b/packs/operation-code-name-generator/LOG.old new file mode 100644 index 0000000..7eca505 --- /dev/null +++ b/packs/operation-code-name-generator/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:18.210637 7fdb517be6c0 Delete type=3 #1 +2026/06/20-04:43:18.213441 7fdb33fff6c0 Level-0 table #5: started +2026/06/20-04:43:18.214301 7fdb33fff6c0 Level-0 table #5: 21954 bytes OK +2026/06/20-04:43:18.214579 7fdb33fff6c0 Delete type=0 #3 +2026/06/20-04:43:18.214657 7fdb33fff6c0 Manual compaction at level-0 from '!tables!E5pMC6z88h7oJb9n' @ 72057594037927935 : 1 .. '!tables.results!z1U4mer6RZi2XE9J.ys6PlfT6lxFv1tQR' @ 0 : 0; will stop at (end) diff --git a/packs/operation-code-name-generator/MANIFEST-000006 b/packs/operation-code-name-generator/MANIFEST-000006 new file mode 100644 index 0000000..c7a993c Binary files /dev/null and b/packs/operation-code-name-generator/MANIFEST-000006 differ diff --git a/packs/pregens/000005.ldb b/packs/pregens/000005.ldb new file mode 100644 index 0000000..eed1756 Binary files /dev/null and b/packs/pregens/000005.ldb differ diff --git a/packs/pregens/000007.log b/packs/pregens/000007.log new file mode 100644 index 0000000..bdd022a Binary files /dev/null and b/packs/pregens/000007.log differ diff --git a/packs/pregens/CURRENT b/packs/pregens/CURRENT new file mode 100644 index 0000000..f7753e2 --- /dev/null +++ b/packs/pregens/CURRENT @@ -0,0 +1 @@ +MANIFEST-000006 diff --git a/packs/pregens/LOCK b/packs/pregens/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/pregens/LOG b/packs/pregens/LOG new file mode 100644 index 0000000..f76cf8f --- /dev/null +++ b/packs/pregens/LOG @@ -0,0 +1,3 @@ +2026/07/15-17:16:33.187355 173763000 Recovering log #4 +2026/07/15-17:16:33.188084 173763000 Delete type=0 #4 +2026/07/15-17:16:33.188124 173763000 Delete type=3 #2 diff --git a/packs/pregens/LOG.old b/packs/pregens/LOG.old new file mode 100644 index 0000000..4854235 --- /dev/null +++ b/packs/pregens/LOG.old @@ -0,0 +1,5 @@ +2026/06/20-04:43:19.368556 7fcf3cfbd6c0 Delete type=3 #1 +2026/06/20-04:43:19.402199 7fcf2f7fe6c0 Level-0 table #5: started +2026/06/20-04:43:19.424182 7fcf2f7fe6c0 Level-0 table #5: 3125375 bytes OK +2026/06/20-04:43:19.424756 7fcf2f7fe6c0 Delete type=0 #3 +2026/06/20-04:43:19.425889 7fcf2f7fe6c0 Manual compaction at level-0 from '!actors!02uQjuR9EWKHVnMm' @ 72057594037927935 : 1 .. '!folders!w3IlJRYnQRCVCyhK' @ 0 : 0; will stop at (end) diff --git a/packs/pregens/MANIFEST-000006 b/packs/pregens/MANIFEST-000006 new file mode 100644 index 0000000..aabe54e Binary files /dev/null and b/packs/pregens/MANIFEST-000006 differ diff --git a/system.json b/system.json new file mode 100644 index 0000000..1d8af4c --- /dev/null +++ b/system.json @@ -0,0 +1,269 @@ +{ + "id": "deltagreen", + "title": "Delta Green: The Role-Playing Game", + "description": "Fan-made Foundry VTT system for Delta Green: The Role-Playing Game. Based on the rules in the Agent's Handbook (https://www.drivethrurpg.com/product/181674/Delta-Green-Agents-Handbook) [*NOT* Call of Cthulu]. Made with the permission of but neither affiliated with nor endorsed by Arc Dream Publishing or the Delta Green Partnership.", + "url": "https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system", + "license": "LICENSE.txt", + "background": "systems/deltagreen/assets/img/burned_delta_green_logo_on_form_splash_page.webp", + "authors": [ + { + "name": "TheLastScrub", + "discord": "TheLastScrub" + }, + { + "name": "jalensailin", + "discord": "jalensailin" + } + ], + "version": "1.7.0", + "compatibility": { + "minimum": "13", + "verified": "14", + "maximum": "14" + }, + "flags": "", + "esmodules": [ + "module/deltagreen.js" + ], + "styles": [ + "css/deltagreen.css", + "css/dialogue.css" + ], + "languages": [ + { + "lang": "en", + "name": "English", + "path": "lang/en.json", + "flags": {} + }, + { + "lang": "ja", + "name": "日本語", + "path": "lang/ja.json", + "flags": {} + }, + { + "lang": "es", + "name": "Español", + "path": "lang/es.json", + "flags": {} + }, + { + "lang": "ca", + "name": "Català", + "path": "lang/ca.json", + "flags": {} + }, + { + "lang": "fr", + "name": "Français", + "path": "lang/fr.json", + "flags": {} + }, + { + "lang": "pt-BR", + "name": "Português (Brasil)", + "path": "lang/pt-BR.json", + "flags": {} + }, + { + "lang": "de", + "name": "Deutsch", + "path": "lang/de.json", + "flags": {} + }, + { + "lang": "sv", + "name": "Svenska", + "path": "lang/sv.json", + "flags": {} + }, + { + "lang": "cn", + "name": "中文", + "path": "lang/cn.json", + "flags": {} + }, + { + "lang": "pl", + "name": "polski", + "path": "lang/pl.json", + "flags": {} + }, + { + "lang": "uk", + "name": "Українська", + "path": "lang/uk.json", + "flags": {} + } + ], + "packFolders": [ + { + "name": "Delta Green", + "sorting": "a", + "color": "#556b2f", + "packs": [ + "firearms", + "armor", + "hand-to-hand-weapons", + "agent-pregens", + "operation-code-name-generator-tables" + ], + "folders": [ + { + "name": "System macros", + "sorting": "a", + "color": "#67b1e0", + "packs": [ + "operation-code-name-generator-macro" + ] + } + ] + } + ], + "packs": [ + { + "name": "firearms", + "label": "Firearms", + "system": "deltagreen", + "path": "packs/firearms", + "type": "Item", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "armor", + "label": "Armor", + "system": "deltagreen", + "path": "packs/armor", + "type": "Item", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "hand-to-hand-weapons", + "label": "Hand-to-Hand Weapons", + "system": "deltagreen", + "path": "packs/hand-to-hand-weapons", + "type": "Item", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "agent-pregens", + "label": "Agent Pregens", + "system": "deltagreen", + "path": "packs/pregens", + "type": "Actor", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "operation-code-name-generator-tables", + "label": "Operation Code Name Generator Tables", + "system": "deltagreen", + "path": "packs/operation-code-name-generator", + "type": "RollTable", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "operation-code-name-generator-macro", + "label": "Operation Code Name Generator Macro", + "system": "deltagreen", + "path": "packs/operation-code-name-generator-macro", + "type": "Macro", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + } + ], + "manifest": "https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/releases/latest/download/system.json", + "download": "https://github.com/deltagreen-foundryvtt/delta-green-foundry-vtt-system/releases/download/v1.7.0/deltagreen.zip", + "grid": { + "distance": 1, + "units": "m" + }, + "primaryTokenAttribute": "health", + "secondaryTokenAttribute": "wp", + "documentTypes": { + "Actor": { + "agent": { + "htmlFields": [ + "physical.description" + ] + }, + "unnatural": { + "htmlFields": [ + "notes" + ] + }, + "npc": { + "htmlFields": [ + "notes" + ] + }, + "vehicle": { + "htmlFields": [ + "description" + ] + } + }, + "Item": { + "weapon": { + "htmlFields": [ + "description" + ] + }, + "armor": { + "htmlFields": [ + "description" + ] + }, + "motivation": { + "htmlFields": [ + "description" + ] + }, + "bond": { + "htmlFields": [ + "description" + ] + }, + "gear": { + "htmlFields": [ + "description" + ] + }, + "tome": { + "htmlFields": [ + "description", + "handlerNotes" + ] + }, + "ritual": { + "htmlFields": [ + "description", + "handlerNotes" + ] + } + } + } +} \ No newline at end of file diff --git a/templates/actor/edit-stats.html b/templates/actor/edit-stats.html new file mode 100644 index 0000000..4c0fe54 --- /dev/null +++ b/templates/actor/edit-stats.html @@ -0,0 +1,26 @@ +
+ {{#each actor.system.statistics as |statistic key| }} +
+
+
+ + +
+
+ +
+
+
+ {{/each}} +
diff --git a/templates/actor/partials/attributes-grid-partial.html b/templates/actor/partials/attributes-grid-partial.html new file mode 100644 index 0000000..6d9a53c --- /dev/null +++ b/templates/actor/partials/attributes-grid-partial.html @@ -0,0 +1,40 @@ +
+
+ {{physicalAttributesTitle}} +
+
+ {{#each actor.system.statistics as |statistic key| }} +
+
+
+ + + ({{numberFormat statistic.x5 decimals=0 sign=false}}% ) +
+
+ +
+
+
+ {{/each}} +
+
diff --git a/templates/actor/partials/custom-skills-partial.html b/templates/actor/partials/custom-skills-partial.html new file mode 100644 index 0000000..002a57f --- /dev/null +++ b/templates/actor/partials/custom-skills-partial.html @@ -0,0 +1,141 @@ + +
+ + {{#each actor.system.sortedCustomSkills as |skill| }} + {{#if_eq type "typeSkill" }} + +
+
+ + + + {{#if_eq skill.actorType "agent" }} + + {{/if_eq}} +
+ +
+ + {{/if_eq}} + + {{#if_eq type "training" }} + +
+
+ {{#if_not_eq (localize (concat 'DG.Attributes.' skill.key)) (concat "DG.Attributes." skill.key) }} + + {{else}} + {{#if_not_eq (localize (concat 'DG.Skills.' skill.key)) (concat "DG.Skills." skill.key) }} + + {{else}} + + {{/if_not_eq}} + {{/if_not_eq}} + +
+ + +
+
+
+ + {{/if_eq}} + + {{/each}} +
diff --git a/templates/actor/partials/health-partial.html b/templates/actor/partials/health-partial.html new file mode 100644 index 0000000..d03ec45 --- /dev/null +++ b/templates/actor/partials/health-partial.html @@ -0,0 +1,28 @@ +
+ +
+ + / + {{#if (ne actor.type "unnatural") }} +
+
{{numberFormat actor.system.health.max decimals=0 sign=false}}
+
+ {{else}} + + {{/if}} +
+
diff --git a/templates/actor/partials/notes-partial.html b/templates/actor/partials/notes-partial.html new file mode 100644 index 0000000..922f6d7 --- /dev/null +++ b/templates/actor/partials/notes-partial.html @@ -0,0 +1,6 @@ +
+
+ {{localize "DG.Sheet.BlockHeaders.PhysicalDescriptionNotes"}} +
+
{{{enrichedDescription}}}
+
diff --git a/templates/actor/partials/sanity-agent.html b/templates/actor/partials/sanity-agent.html new file mode 100644 index 0000000..22b585d --- /dev/null +++ b/templates/actor/partials/sanity-agent.html @@ -0,0 +1,24 @@ +{{#if (keepSanityPrivate) }} +
+
???
+
+ / +
+
???
+
+{{else}} + + / +
+
{{numberFormat actor.system.sanity.max decimals=0 sign=false}}
+
+{{/if}} diff --git a/templates/actor/partials/sanity-npc.html b/templates/actor/partials/sanity-npc.html new file mode 100644 index 0000000..861cda8 --- /dev/null +++ b/templates/actor/partials/sanity-npc.html @@ -0,0 +1,13 @@ + +{{localize 'DG.NPCSheet.BreakPointAbbreviation'}}: + diff --git a/templates/actor/partials/sanity-partial.html b/templates/actor/partials/sanity-partial.html new file mode 100644 index 0000000..9c72bdc --- /dev/null +++ b/templates/actor/partials/sanity-partial.html @@ -0,0 +1,14 @@ +
+ +
{{{ sanityInputs }}}
+
diff --git a/templates/actor/partials/sanity-unnatural.html b/templates/actor/partials/sanity-unnatural.html new file mode 100644 index 0000000..852a9cf --- /dev/null +++ b/templates/actor/partials/sanity-unnatural.html @@ -0,0 +1,9 @@ + +/ + diff --git a/templates/actor/partials/willpower-partial.html b/templates/actor/partials/willpower-partial.html new file mode 100644 index 0000000..0830429 --- /dev/null +++ b/templates/actor/partials/willpower-partial.html @@ -0,0 +1,28 @@ +
+ +
+ + / + {{#if (ne actor.type "unnatural") }} +
+
{{numberFormat actor.system.wp.max decimals=0 sign=false}}
+
+ {{else}} + + {{/if}} +
+
diff --git a/templates/actor/parts/about-tab.html b/templates/actor/parts/about-tab.html new file mode 100644 index 0000000..607354c --- /dev/null +++ b/templates/actor/parts/about-tab.html @@ -0,0 +1,34 @@ +
+
+ + + + +
diff --git a/templates/actor/parts/bio-tab-v2.html b/templates/actor/parts/bio-tab-v2.html new file mode 100644 index 0000000..222cfe1 --- /dev/null +++ b/templates/actor/parts/bio-tab-v2.html @@ -0,0 +1,98 @@ +{{!-- djlint:off H020 --}} + +{{!-- PERSONAL (Biography) Tab --}} +
+
+ {{localize "DG.Sheet.BlockHeaders.PersonalInfoCV"}} +
+
+ {{localize 'DG.CV.Sex'}} + + + {{localize 'DG.CV.AgeAndDoB'}} + +
+ +
+ + {{localize 'DG.CV.Employer'}} + + + {{localize 'DG.CV.Nationality'}} + + +
+ +
+ {{localize 'DG.CV.Education'}} + +
+ + {{#if (showImpossibleLandscapesContent) }} + +
+ {{localize 'DG.ImpossibleLanscapes.IHaveSeenThe'}} + + {{localize 'DG.ImpossibleLanscapes.YellowSign'}} + + + {{localize 'DG.ImpossibleLanscapes.CorruptionFirstHalf'}} + {{localize 'DG.ImpossibleLanscapes.CorruptionSecondHalf'}} + + +
+ +
+ {{localize 'DG.ImpossibleLanscapes.Gift'}} + + + {{localize 'DG.ImpossibleLanscapes.Insight'}} + +
+ + {{/if}} + + {{> "systems/deltagreen/templates/actor/partials/notes-partial.html"}} +
diff --git a/templates/actor/parts/bio-tab.html b/templates/actor/parts/bio-tab.html new file mode 100644 index 0000000..222cfe1 --- /dev/null +++ b/templates/actor/parts/bio-tab.html @@ -0,0 +1,98 @@ +{{!-- djlint:off H020 --}} + +{{!-- PERSONAL (Biography) Tab --}} +
+
+ {{localize "DG.Sheet.BlockHeaders.PersonalInfoCV"}} +
+
+ {{localize 'DG.CV.Sex'}} + + + {{localize 'DG.CV.AgeAndDoB'}} + +
+ +
+ + {{localize 'DG.CV.Employer'}} + + + {{localize 'DG.CV.Nationality'}} + + +
+ +
+ {{localize 'DG.CV.Education'}} + +
+ + {{#if (showImpossibleLandscapesContent) }} + +
+ {{localize 'DG.ImpossibleLanscapes.IHaveSeenThe'}} + + {{localize 'DG.ImpossibleLanscapes.YellowSign'}} + + + {{localize 'DG.ImpossibleLanscapes.CorruptionFirstHalf'}} + {{localize 'DG.ImpossibleLanscapes.CorruptionSecondHalf'}} + + +
+ +
+ {{localize 'DG.ImpossibleLanscapes.Gift'}} + + + {{localize 'DG.ImpossibleLanscapes.Insight'}} + +
+ + {{/if}} + + {{> "systems/deltagreen/templates/actor/partials/notes-partial.html"}} +
diff --git a/templates/actor/parts/bonds-tab.html b/templates/actor/parts/bonds-tab.html new file mode 100644 index 0000000..eb347f7 --- /dev/null +++ b/templates/actor/parts/bonds-tab.html @@ -0,0 +1,73 @@ +
+
+ {{localize "DG.Sheet.BlockHeaders.BondsRelationshipsContacts"}} +
+ +
+
    +
  1. + +
    + +
    +
    +
    {{localize 'DG.Bonds.Name'}}
    +
    {{localize 'DG.Bonds.Relationship'}}
    +
    {{localize 'DG.Bonds.Score'}}
    + +
  2. + + {{#each actor.items as |item id| }} + {{#if_eq item.type "bond" }} + +
  3. + +
    + +
    + {{item.name}} + {{item.system.relationship}} + {{item.system.score}} + +
  4. + + {{/if_eq}} + {{/each}} +
+ +
+ {{localizeWithFallback "DG.Generic.CheckDamagedBondsBoxUntilNextHomeScene" "Check a damaged Bond's box until the next Home scene ends." }} +
+ +
+
diff --git a/templates/actor/parts/gear-tab.html b/templates/actor/parts/gear-tab.html new file mode 100644 index 0000000..39e290a --- /dev/null +++ b/templates/actor/parts/gear-tab.html @@ -0,0 +1,455 @@ +{{!-- EQUIPMENT/ATTACKS/ABILITES SECTION USED ON ALL ACTOR SHEETS --}} +{{!-- WEAPONS/ATTACKS --}} +
+ +
+
+ {{localize 'DG.Gear.Weapons'}} +
+ +
    +
  1. +
    + {{#if actor.system.settings.sorting.weaponSortAlphabetical }} + + + + {{else}} + + + + {{/if}} +
    + + + {{localize 'DG.Gear.Name'}} + + + {{localize 'DG.Gear.DamageOrLethality'}} + {{localize 'DG.Gear.ArmorPiercing'}} + +
  2. + + {{#each actor.weapons as |item id| }} +
  3. +
    + + + {{item.name}} + + + + +
    + + + {{#if item.system.lethality }} + {{#if item.system.isLethal }} + + + + {{else}} + + + + {{/if}} + {{/if}} + + {{#unless item.system.isLethal}} + + {{toUpperCase item.system.damage}} + {{#if_eq item.system.skill 'unarmed_combat' }} + {{actor.system.statistics.str.meleeDamageBonusFormula}} + {{/if_eq}} + {{#if_eq item.system.skill 'melee_weapons' }} + {{actor.system.statistics.str.meleeDamageBonusFormula}} + {{/if_eq}} + + + {{/unless}} + + {{#if item.system.isLethal }} + + {{item.system.lethality}}% + + + {{/if}} + + + + {{item.system.armorPiercing}} + + +
  4. + {{/each}} +
+
+ + {{!-- ARMOR/DEFENSE --}} +
+
+ {{localize 'DG.Gear.Armor'}} +
+
    +
  1. + +
    + {{#if actor.system.settings.sorting.armorSortAlphabetical }} + + + + {{else}} + + + + {{/if}} +
    +
    + {{localize 'DG.Gear.Name'}} +
    + {{localize 'DG.Gear.ArmorRating'}} + {{localize 'DG.Gear.Equipped'}} + + +
  2. + + {{#each actor.armor as |item id| }} + +
  3. + +
    + +
    + + {{item.name}} + + {{item.system.protection}} + + + {{#if item.system.equipped }} + + {{else}} + + {{/if}} + + + +
  4. + {{/each}} +
+
+ + {{!-- OTHER GEAR/MISC --}} + +
+
+ {{localize 'DG.Gear.OtherGear'}} +
+ +
    +
  1. +
    + {{#if actor.system.settings.sorting.gearSortAlphabetical }} + + + + {{else}} + + + + {{/if}} +
    + +
    {{localize 'DG.Gear.Name'}}
    + + {{localize 'DG.Gear.Equipped'}} + + +
  2. + + {{#each actor.gear as |item id| }} +
  3. +
    + +
    + + {{item.name}} + + + {{#if item.system.equipped }} + + {{else}} + + {{/if}} + + + +
  4. + {{/each}} +
+
+ + {{#if showHyperGeometrySection }} + {{!-- TOMES --}} +
+ +
+ {{localize 'DG.Gear.Tomes'}} +
+ +
    + +
  1. + +
    + {{#if actor.system.settings.sorting.tomeSortAlphabetical }} + + + + + {{else}} + + + + + {{/if}} +
    + +
    {{localize 'DG.Tomes.Name'}}
    + + + +
  2. + + {{#each actor.tomes as |item id| }} + +
  3. + +
    + +
    + + + {{#if item.system.revealed }} + {{item.name}} + {{else}} + ??? + {{#if (playerHasGamemasterPrivileges) }} + ({{item.name}}) + {{/if}} + {{/if}} + + + + +
  4. + + {{/each}} + +
+ +
+ + {{!-- RITUALS --}} +
+ +
+ + {{localize 'DG.Gear.Rituals'}} + + + + +
+ +
    + +
  1. + +
    + {{#if actor.system.settings.sorting.ritualSortAlphabetical }} + + + + {{else}} + + + + {{/if}} +
    + +
    {{localize 'DG.Ritual.Name'}}
    + + + +
  2. + + {{#each actor.rituals as |item id| }} + +
  3. + +
    + +
    + + + {{#if item.system.revealed }} + {{item.name}} + {{else}} + ??? + {{#if (playerHasGamemasterPrivileges) }} + ({{item.name}}) + {{/if}} + {{/if}} + + + + +
  4. + + {{/each}} + +
+ +
+ {{/if}} +
diff --git a/templates/actor/parts/header.html b/templates/actor/parts/header.html new file mode 100644 index 0000000..d20d777 --- /dev/null +++ b/templates/actor/parts/header.html @@ -0,0 +1,42 @@ +
+
+ {{!-- Name, Profession, Portrait --}} +
+ {{actor.name}} +
+
+

+ +

+
+
+

+ +

+
+
+
+
+ {{!-- HP --}} + {{> "systems/deltagreen/templates/actor/partials/health-partial.html" }} + {{#if (ne actor.type "vehicle") }} + {{!-- WP --}} + {{> "systems/deltagreen/templates/actor/partials/willpower-partial.html" }} + {{!-- Sanity --}} + {{> "systems/deltagreen/templates/actor/partials/sanity-partial.html" }} + {{/if}} +
+
+
diff --git a/templates/actor/parts/left-bar.html b/templates/actor/parts/left-bar.html new file mode 100644 index 0000000..b583ced --- /dev/null +++ b/templates/actor/parts/left-bar.html @@ -0,0 +1,122 @@ +
+
+ +
+ + +
+
+ +
+ + + + +
+ {{#each actor.system.statistics as |statistic key| }} +
+
+
+ + +
+
+
+ {{/each}} +
+
+ +
+ +
+ {{!-- HP --}} +
+ +
+ + / +
+
{{numberFormat actor.system.health.max decimals=0 sign=false}}
+
+
+
+ {{#if (ne actor.type "vehicle") }} + {{!-- WP --}} +
+ +
+ + / +
+
{{numberFormat actor.system.wp.max decimals=0 sign=false}}
+
+
+
+ {{!-- Sanity --}} + {{> "systems/deltagreen/templates/actor/partials/sanity-partial.html" }} + {{/if}} +
+ +
+ +
+ + + +
+ +
+ + +
+ +
diff --git a/templates/actor/parts/motivations-tab-v2.html b/templates/actor/parts/motivations-tab-v2.html new file mode 100644 index 0000000..1572866 --- /dev/null +++ b/templates/actor/parts/motivations-tab-v2.html @@ -0,0 +1,122 @@ +{{!-- Psychological Tab (formerly 'Mental', formerly 'Motivations') --}} +
+
+ {{localize "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations"}} +
+
+
+ +
+ + + + + + + + + + + + + + + +
+
+
+ +
+ {{localize "DG.Sheet.BlockHeaders.MotivationsAndDisorders"}} +
+ +
+
    + +
  1. +
    {{localize 'DG.Mental.Motivations'}}
    +
    {{localize 'DG.Mental.Disorders'}}
    + +
  2. + + {{#each actor.items as |item id| }} + {{#if_eq item.type 'motivation' }} + +
  3. + + {{item.name}} + + + {{#if item.system.crossedOut }} + {{item.system.disorder}} + {{/if}} + + +
  4. + + {{/if_eq}} + {{/each}} +
+
+
diff --git a/templates/actor/parts/motivations-tab.html b/templates/actor/parts/motivations-tab.html new file mode 100644 index 0000000..c734c2a --- /dev/null +++ b/templates/actor/parts/motivations-tab.html @@ -0,0 +1,149 @@ +{{!-- Psychological Tab (formerly 'Mental', formerly 'Motivations') --}} +
+
+ {{localize "DG.Sheet.BlockHeaders.BreakingPointAndAdaptations"}} +
+
+
+ + + {{localize 'DG.Mental.Reset'}} +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+
+ +
+ {{localize "DG.Sheet.BlockHeaders.MotivationsAndDisorders"}} +
+ +
+
    + +
  1. +
    {{localize 'DG.Mental.Motivations'}}
    +
    {{localize 'DG.Mental.Disorders'}}
    + +
  2. + + {{#each actor.items as |item id| }} + {{#if_eq item.type 'motivation' }} + +
  3. + + {{item.name}} + + + {{#if item.system.crossedOut }} + {{item.system.disorder}} + {{/if}} + + +
  4. + + {{/if_eq}} + {{/each}} +
+
+
diff --git a/templates/actor/parts/notes-tab.html b/templates/actor/parts/notes-tab.html new file mode 100644 index 0000000..7a7a299 --- /dev/null +++ b/templates/actor/parts/notes-tab.html @@ -0,0 +1,6 @@ +
+ {{!-- This document is a wrapper around the notes partial. --}} + {{> "systems/deltagreen/templates/actor/partials/notes-partial.html" }} +
diff --git a/templates/actor/parts/physical-tab-v2.html b/templates/actor/parts/physical-tab-v2.html new file mode 100644 index 0000000..60757bc --- /dev/null +++ b/templates/actor/parts/physical-tab-v2.html @@ -0,0 +1,59 @@ +{{!-- Physical Statistics like STR, CON, etc. --}} +
+ +
+ {{localize "DG.Sheet.BlockHeaders.Injuries"}} +
+ +
+
+ + +
+
+ + + + + {{#if actor.system.physical.exhausted }} + + + + + {{/if}} +
+
+ + + + +
+
+
diff --git a/templates/actor/parts/physical-tab.html b/templates/actor/parts/physical-tab.html new file mode 100644 index 0000000..4024cc8 --- /dev/null +++ b/templates/actor/parts/physical-tab.html @@ -0,0 +1,61 @@ +{{!-- Physical Statistics like STR, CON, etc. --}} +
+ + {{> "systems/deltagreen/templates/actor/partials/attributes-grid-partial.html"}} + +
+ {{localize "DG.Sheet.BlockHeaders.Injuries"}} +
+ +
+
+ + +
+
+ + + + + {{#if actor.system.physical.exhausted }} + + + + + {{/if}} +
+
+ + + + +
+
+
diff --git a/templates/actor/parts/right-bar.html b/templates/actor/parts/right-bar.html new file mode 100644 index 0000000..301c144 --- /dev/null +++ b/templates/actor/parts/right-bar.html @@ -0,0 +1,9 @@ +
+ {{> "systems/deltagreen/templates/actor/parts/skills-tab.html" }} + {{> "systems/deltagreen/templates/actor/parts/physical-tab-v2.html" }} + {{> "systems/deltagreen/templates/actor/parts/motivations-tab-v2.html" }} + {{> "systems/deltagreen/templates/actor/parts/gear-tab.html" }} + {{> "systems/deltagreen/templates/actor/parts/bio-tab-v2.html" }} + {{> "systems/deltagreen/templates/actor/parts/bonds-tab.html" }} + {{> "systems/deltagreen/templates/actor/parts/about-tab.html" }} +
diff --git a/templates/actor/parts/skills-tab.html b/templates/actor/parts/skills-tab.html new file mode 100644 index 0000000..5ef1b96 --- /dev/null +++ b/templates/actor/parts/skills-tab.html @@ -0,0 +1,58 @@ +
+
+ {{localize "DG.Sheet.BlockHeaders.SkillsAndTraining"}} + {{#if (ne actor.type "agent") }} + {{!-- Checkbox to hide/show skills that are at zero --}} + + {{localize (concat 'DG.UnnaturalSheet.' (ifThen actor.system.showUntrainedSkills 'Show' 'Hide') 'UntrainedSkillsLabel')}} + {{!-- djlint:off --}} + + {{!-- djlint:on --}} + + {{/if}} +
+ +
+ {{#each actor.system.sortedSkills as |skill key| }} +
+ + + + {{#if (eq ../actor.type "agent") }} + + {{/if}} +
+ {{/each}} +
+ + {{!-- Custom Skills and Special Training --}} +
{{> "systems/deltagreen/templates/actor/partials/custom-skills-partial.html" }}
+ + {{#if showNotesInSkills }} + {{> "systems/deltagreen/templates/actor/partials/notes-partial.html"}} + {{/if}} +
diff --git a/templates/dialog/apply-skill-improvements.html b/templates/dialog/apply-skill-improvements.html new file mode 100644 index 0000000..213281f --- /dev/null +++ b/templates/dialog/apply-skill-improvements.html @@ -0,0 +1,7 @@ +
+ +
+ + {{{localize "DG.Skills.ApplySkillImprovements.DialogEffectsFollowing" skillList=failedSkillNames}}} + +
diff --git a/templates/dialog/modify-damage-roll.html b/templates/dialog/modify-damage-roll.html new file mode 100644 index 0000000..91b7f14 --- /dev/null +++ b/templates/dialog/modify-damage-roll.html @@ -0,0 +1,19 @@ +
+
+ {{localize 'DG.ModifyDamageRollDialogue.Weapon'}} + {{data.label}} +
+
+ + ( + + + ) +
+
+ + +
+
\ No newline at end of file diff --git a/templates/dialog/modify-percentile-roll.html b/templates/dialog/modify-percentile-roll.html new file mode 100644 index 0000000..8df5c75 --- /dev/null +++ b/templates/dialog/modify-percentile-roll.html @@ -0,0 +1,32 @@ +
+
+ {{localize 'DG.ModifySkillRollDialogue.Test'}} + + {{data.label}} + + {{localize 'DG.ModifySkillRollDialogue.OriginalTarget'}} + + {{#if data.hideTarget}} + + {{/if}} + + {{#unless data.hideTarget}} + + {{/unless}} + + + {{localize 'DG.ModifySkillRollDialogue.TargetModifier'}} +
+ + +
+ + + +
+
\ No newline at end of file diff --git a/templates/dialog/special-training.html b/templates/dialog/special-training.html new file mode 100644 index 0000000..d1fd2f5 --- /dev/null +++ b/templates/dialog/special-training.html @@ -0,0 +1,14 @@ +
+
+ + +
+
+ + {{{selectElement}}} +
+
\ No newline at end of file diff --git a/templates/item/item-armor-sheet.html b/templates/item/item-armor-sheet.html new file mode 100644 index 0000000..b7a7f33 --- /dev/null +++ b/templates/item/item-armor-sheet.html @@ -0,0 +1,50 @@ +
+
+
+ + + +
+ + {{localize 'DG.Bonds.Name'}}: + + + {{localize 'DG.ItemWindow.Armor.Expense'}}: + + + {{localize 'DG.ItemWindow.Armor.Equipped'}}: + + +
+
+ +
+ {{localize 'DG.ItemWindow.Armor.ArmorRating'}}: + +
+ +
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+
diff --git a/templates/item/item-bond-sheet.html b/templates/item/item-bond-sheet.html new file mode 100644 index 0000000..23b59f7 --- /dev/null +++ b/templates/item/item-bond-sheet.html @@ -0,0 +1,35 @@ +
+
+
+ +
+ + {{localize 'DG.Bonds.Name'}}: + + + {{localize 'DG.Bonds.Score'}}: + + + {{localize 'DG.Bonds.Relationship'}}: + + +
+
+
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+
diff --git a/templates/item/item-gear-sheet.html b/templates/item/item-gear-sheet.html new file mode 100644 index 0000000..f656bf9 --- /dev/null +++ b/templates/item/item-gear-sheet.html @@ -0,0 +1,47 @@ +
+
+
+ + + +
+ + {{localize 'DG.Bonds.Name'}}: + + + + {{localize 'DG.ItemWindow.Gear.Expense'}}: + + + {{localize 'DG.ItemWindow.Gear.Equipped'}}: + + +
+
+ +
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+
diff --git a/templates/item/item-motivation-sheet.html b/templates/item/item-motivation-sheet.html new file mode 100644 index 0000000..6bcbc20 --- /dev/null +++ b/templates/item/item-motivation-sheet.html @@ -0,0 +1,66 @@ +
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body motivation-sheet-horizontal-grid-2col --}} +
+ +
+ +
+ {{localize 'DG.ItemWindow.Motivations.IsDisorder'}}: + + {{localize 'DG.ItemWindow.Motivations.Motivation'}}: + + {{!-- Only Show the Disorders Section if Motivation Lost Checked --}} + {{#if item.system.crossedOut }} + + {{localize 'DG.ItemWindow.Motivations.Disorder'}}: + + {{localize 'DG.ItemWindow.Motivations.DisorderHasBeenCured'}}: + + {{/if}} + +
+
+ +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+ +
+ +
diff --git a/templates/item/item-ritual-sheet.html b/templates/item/item-ritual-sheet.html new file mode 100644 index 0000000..50f49cc --- /dev/null +++ b/templates/item/item-ritual-sheet.html @@ -0,0 +1,113 @@ +
+
+
+ + +
+ {{#if item.system.revealed}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + + + {{localize 'DG.ItemWindow.Ritual.StudyTime'}}: + + + {{localize 'DG.ItemWindow.Ritual.ActivationTime'}}: + + + {{localize 'DG.ItemWindow.Ritual.ActivationCosts'}}: + + {{else}} + {{#if (playerHasGamemasterPrivileges)}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + + + {{localize 'DG.ItemWindow.Ritual.StudyTime'}}: + + + {{localize 'DG.ItemWindow.Ritual.ActivationTime'}}: + + + {{localize 'DG.ItemWindow.Ritual.ActivationCosts'}}: + + {{else}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + ??? + + {{localize 'DG.ItemWindow.Ritual.StudyTime'}}: + ??? + + {{localize 'DG.ItemWindow.Ritual.ActivationTime'}}: + ??? + + {{localize 'DG.ItemWindow.Ritual.ActivationCosts'}}: + ??? + {{/if}} + {{/if}} +
+ +
+ +
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+ + {{!-- Handler Notes Tab --}} + {{#if (playerHasGamemasterPrivileges)}} +
+
+ {{localize 'DG.ItemWindow.Tome.UnnaturalIncrease'}}: + + + {{localize 'DG.ItemWindow.Ritual.LearnedSanityDamage'}}: + + + / + + + + + {{localize 'DG.ItemWindow.Ritual.ActivationSanityDamage'}}: + + + / + + + +
+ + {{localize 'DG.ItemWindow.Tome.HandlerNotes'}}: + +
+
+ {{editor enrichedHandlerNotes target="system.handlerNotes" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+ {{/if}} +
+
diff --git a/templates/item/item-tome-sheet.html b/templates/item/item-tome-sheet.html new file mode 100644 index 0000000..b85bccd --- /dev/null +++ b/templates/item/item-tome-sheet.html @@ -0,0 +1,99 @@ +
+
+
+ + +
+ {{#if item.system.revealed}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + + + {{localize 'DG.Tome.Language'}}: + + + {{localize 'DG.Tome.StudyTime'}}: + + {{else}} + {{#if (playerHasGamemasterPrivileges)}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + + + {{localize 'DG.Tome.Language'}}: + + + {{localize 'DG.Tome.StudyTime'}}: + + {{else}} + + {{#if (playerHasGamemasterPrivileges)}}{{/if}} + {{localize 'DG.Tome.Name'}}: + + ??? + + {{localize 'DG.Tome.Language'}}: + ??? + + {{localize 'DG.Tome.StudyTime'}}: + ??? + {{/if}} + {{/if}} +
+ +
+ +
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+ + {{!-- Handler Notes Tab --}} + {{#if (playerHasGamemasterPrivileges)}} +
+
+ {{localize 'DG.ItemWindow.Tome.UnnaturalIncrease'}}: + + + {{localize 'DG.ItemWindow.Tome.OccultIncrease'}}: + + + {{localize 'DG.ItemWindow.Tome.StudySanityDamage'}}: + + + / + + + +
+ + {{localize 'DG.ItemWindow.Tome.HandlerNotes'}}: + +
+
+ {{editor enrichedHandlerNotes target="system.handlerNotes" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+ {{/if}} +
+
diff --git a/templates/item/item-weapon-sheet.html b/templates/item/item-weapon-sheet.html new file mode 100644 index 0000000..cc03669 --- /dev/null +++ b/templates/item/item-weapon-sheet.html @@ -0,0 +1,127 @@ +
+
+
+ + + +
+ + {{localize 'DG.Bonds.Name'}}: + + + {{localize 'DG.ItemWindow.Weapons.Expense'}}: + + + {{localize 'DG.ItemWindow.Gear.Equipped'}}: + + +
+
+ +
+ +
+ + {{localize 'DG.ItemWindow.Weapons.Skill'}}: + +
+ +
+ {{#if_eq item.system.skill 'custom'}} + {{localize 'DG.ItemWindow.Weapons.CustomSkillTarget'}}: + + {{/if_eq}} +
+ + +
+ + {{localize 'DG.ItemWindow.Weapons.ArmorPiercing'}}: + + + {{localize 'DG.ItemWindow.Weapons.SkillModifier'}}: + + + {{localize 'DG.ItemWindow.Weapons.IsLethality'}}: + + +
+ + +
+ + {{localize 'DG.ItemWindow.Weapons.Range'}}: + + + {{localize 'DG.ItemWindow.Weapons.KillRadius'}}: + + + {{!-- If a weapon is 'Lethal', need to show the d100% Lethality input, otherwise only show the regular Damage formula (e.g. 1D6, 1D4+2, etc...) --}} + + {{#unless item.system.isLethal}} + + {{localize 'DG.ItemWindow.Weapons.Damage'}}: + + + {{/unless}} + + {{#if item.system.isLethal}} + + {{localize 'DG.ItemWindow.Weapons.Lethality'}} %: + + + {{/if}} + +
+ +
+ +
+ {{localize 'DG.ItemWindow.Weapons.Ammo'}}: + +
+
+
+ + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+ + {{!-- Description Tab --}} +
+
+ {{editor enrichedDescription target="system.description" engine="prosemirror" button=true owner=owner editable=editable}} +
+
+
+
diff --git a/templates/roll/percentile-roll.hbs b/templates/roll/percentile-roll.hbs new file mode 100644 index 0000000..cef8a41 --- /dev/null +++ b/templates/roll/percentile-roll.hbs @@ -0,0 +1,32 @@ +
+
+
{{resultString}}
+
+
+
+
+
+ {{formula}} + {{total}} +
+
    +
  1. {{total}}
  2. +
+
+
+
+
+

{{total}}

+
+ + {{#if failureMark}} +
+ + + +
+ {{/if}} + +
diff --git a/templates/save.hbs b/templates/save.hbs new file mode 100644 index 0000000..781165a --- /dev/null +++ b/templates/save.hbs @@ -0,0 +1,3 @@ + \ No newline at end of file