diff --git a/changelog.md b/changelog.md
index 541184d64..2e2745c0c 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,7 +2,15 @@
Release 0.17.16
-- Feature: Multiple actor import. Import multiple GCS and GCA files with one command.
+- Feature: Multiple actor import. Import multiple GCS and GCA files with one command. #1994
+- Bugfix: Errors occurring when users drop damage onto mooks/NPCs #2024
+- Bugfix: Larger Fonts Hides "skills" in tabbed view till window is pulled open further #2015
+- Bugfix: Attack mixup if weapon name differs only in a postfix #2025
+- Bugfix: Damage dropping not working as intended #2007
+- Bugfix: Duplicating the specialization name to other skills #2035
+- Feature: Remove the homebrew rules from the modifier bucket, and add MA maneuvers to the bucket. #2023
+- Bugfix: Slam calculator appears not to be working #2022
+- Bugfix: Importing a Character Causes Endless Error Loop #2019
Release 0.17.15 10/31/2024
diff --git a/lang/de.json b/lang/de.json
index 76577c674..ed4735bac 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -1,19 +1,32 @@
{
"__NOTE TO TRANSLATOR__": "If a given text is the same as the English (en.json), there is no need to include it here. It will fallback to en.json.",
- "GURPS.changelog": "LIESMICH",
- "GURPS.DontShowAgain": "Zeige LIESMICH nicht noch einmal",
+ "gurps": {
+ "changelog": {
+ "readme": "LIESMICH",
+ "dontShowAgain": "Zeige LIESMICH nicht noch einmal"
+ },
+ "sheet": {
+ "personal": {
+ "tab": "Persönlich",
+ "portrait": "Portrait",
+ "identity": "Identität",
+ "name": "Name",
+ "player": "Spieler",
+ "title": "Titel",
+ "miscellaneous": "Sonstiges",
+ "created": "Erstellt",
+ "modified": "Modifiziert",
+ "options": "Optionen"
+ }
+ },
+ "modifiers": {
+ "determinedAttack": "Entschlossener Angriff"
+ }
+ },
"__Char Sheet__": "=========",
- "GURPS.personalTab": "Persönlich",
"GURPS.resourcesModsTab": "Ressourcen und Modifikatoren",
"__Character Sheet Identity__": "=========",
- "GURPS.identity": "Identität",
- "GURPS.identityPlayer": "Spieler",
- "GURPS.identityTitle": "Titel",
"__Character Sheet Miscellaneous__": "=========",
- "GURPS.miscellaneous": "Sonstiges",
- "GURPS.miscellaneousCreated": "Erstellt",
- "GURPS.miscellaneousModified": "Modifiziert",
- "GURPS.miscellaneousOptions": "Optionen",
"__Character Description__": "=========",
"GURPS.description": "Beschreibung",
"GURPS.descriptionAge": "Alter",
@@ -455,7 +468,7 @@
"GURPS.modifierQuality": "Ausrüstungs Qualität",
"GURPS.modifierQualityBest": "Best Mögliche",
"GURPS.modifierQualityFine": "Ausgezeichnete Qualität (Kosten ×20)",
- "GURPS.modifierQualityGood": "Gute Qualität (Kosten ×5",
+ "GURPS.modifierQualityGood": "Gute Qualität (Kosten ×5)",
"GURPS.modifierQualityImprovised": "Improvisiert",
"GURPS.modifierQualityImprovTech": "Improvisiert (technologisch)",
"GURPS.modifierQualityMissing": "Fehlende/Beschädigte Ausrüstung",
@@ -944,4 +957,4 @@
"GURPS.effectModNoTokenSelected": "Kein Token ausgewählt",
"GURPS.settingActiveEffects": "Aktive Effekte einschalten",
"GURPS.settingHintActiveEffects": "Erlaubt der SL, Aktive Effekte zu erstellen und anzuwenden"
-}
\ No newline at end of file
+}
diff --git a/lang/en.json b/lang/en.json
index 597b41b1e..af5e8830c 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -1,23 +1,143 @@
{
- "GURPS.title": "GURPS",
- "GURPS.changelog": "README",
- "GURPS.DontShowAgain": "Don't show README again",
- "GURPS.copyrightGURPS": "GURPS is a trademark of Steve Jackson Games, and its rules and art are copyrighted by Steve Jackson Games. All rights are reserved by Steve Jackson Games. This game aid is the original creation of Chris Normand/Nose66 and is released for free distribution, and not for resale, under the permissions granted by http://www.sjgames.com/general/online_policy.html",
- "GURPS.copyrightGCS": "GCS is copyrighted 1998-2020 by Richard A. Wilkes. All rights reserved ",
+ "gurps": {
+ "copyright": "GURPS is a trademark of Steve Jackson Games, and its rules and art are copyrighted by Steve Jackson Games. All rights are reserved by Steve Jackson Games. This game aid is the original creation of Chris Normand/Nose66 and is released for free distribution, and not for resale, under the permissions granted by http://www.sjgames.com/general/online_policy.html",
+ "changelog": {
+ "readme": "README",
+ "title": "GURPS",
+ "dontShowAgain": "Don't show README again"
+ },
+ "sheet": {
+ "personal": {
+ "tab": "Personal",
+ "portrait": "Portrait",
+ "identity": "Identity",
+ "name": "Name",
+ "player": "Player",
+ "title": "Title",
+ "miscellaneous": "Miscellaneous",
+ "created": "Created",
+ "modified": "Modified",
+ "options": "Options"
+ },
+ "gcs": {
+ "copyright": "GCS is copyrighted 1998-2024 by Richard A. Wilkes. All rights reserved."
+ }
+ },
+ "modifiers": {
+ "aim": "to hit (Aim)",
+ "allOutAim": "to Aiming (All-Out Aim)",
+ "allOutAimBraced": "to Aiming (All-Out Aim: Braced)",
+ "aoaDetermined": "to hit (AoA: Determined)",
+ "aoaRanged": "to hit (AoA: Ranged)",
+ "aoaRangedDetermined": "to hit (AoA: Determined)",
+ "aoaStrong": "damage (AoA: Strong)",
+ "aodIncreased": "to defense (AoD: Increased)",
+ "blockRetreat": "to Block/Parry (Retreat)",
+ "committedAim": "to Aiming (Committed Aim)",
+ "committedAimBraced": "to Aiming (Committed Aim: Braced)",
+ "committedAimDefense": "to defense (Committed Aim)",
+ "committedAttackRanged": "to hit (Committed Attack (Ranged))",
+ "committedDetermined": "to hit (Committed: Determined)",
+ "committedRanged": "to hit (Committed: Ranged)",
+ "committedStrong": "damage (Committed: Strong)",
+ "deceptive": "to hit (Deceptive Attack)",
+ "deceptiveDefense": "to defense (Deceptive Attack)",
+ "defenseSide": "to defense (attacked from side)",
+ "defensive": "damage (Defensive Attack)",
+ "defensiveDefense": "to Parry/Block (Defensive)",
+ "dodgeAcrobatic": "to Dodge (Acrobatic, success)",
+ "dodgeAcrobaticFail": "to Dodge (Acrobatic, fail)",
+ "dodgeAndDrop": "to Dodge (Dodge and Drop)",
+ "dodgeRetreat": "to Dodge (Retreat)",
+ "extraEffort": "Extra Effort",
+ "fencingRetreat": "to Parry (Fencing, etc. Retreat)",
+ "feverishDefense": "to defense (Feverish)",
+ "heroicCharge": "Heroic Charge",
+ "mightyBlow": "damage (Mighty Blow)",
+ "moveAndAttack": "to hit (Move and Attack)",
+ "onTargetAiming": "On Target",
+ "popup": "to hit (Popup Attack)",
+ "rapidStrike": "to hit (Rapid Strike)",
+ "riposte": "to attack or defense (Riposte)",
+ "shieldDB": "to defense (Shield DB)",
+ "telegraphic": "to hit (Telegraphic Attack)",
+ "pdf": {
+ "aim": "B364",
+ "allOutAim": "PY77:25",
+ "allOutAimBraced": "PY77:25",
+ "aoaDetermined": "B365",
+ "aoaRanged": "PY77:26",
+ "aoaRangedDetermined": "B365",
+ "aoaStrong": "B365",
+ "aodIncreased": "B366",
+ "blockRetreat": "B377",
+ "committedAim": "PY77:25",
+ "committedAimBraced": "PY77:25",
+ "committedAimDefense": "PY77:25",
+ "committedAttackRanged": "PY77:26",
+ "committedDetermined": "MA99",
+ "committedRanged": "PY77:26",
+ "committedStrong": "MA99",
+ "deceptive": "B369",
+ "deceptiveDefense": "B369",
+ "defenseSide": "B390",
+ "defensive": "MA100",
+ "defensiveDefense": "MA100",
+ "dodgeAcrobatic": "B374",
+ "dodgeAcrobaticFail": "B374",
+ "dodgeAndDrop": "B377",
+ "dodgeRetreat": "B377",
+ "extraEffort": "B357",
+ "fencingRetreat": "B377",
+ "feverishDefense": "B357",
+ "heroicCharge": "MA131",
+ "mightyBlow": "MA131",
+ "moveAndAttack": "B365",
+ "parryRear": "B390",
+ "popup": "B390",
+ "rapidStrike": "B370",
+ "riposte": "MA124",
+ "shieldDB": "B374",
+ "telegraphic": "MA113"
+ }
+ }
+ },
+ "GURPS.aim": "Aim",
+ "GURPS.aiming": "Aiming",
+ "GURPS.allOutDefense": "All-Out Defense",
+ "GURPS.modifierAimAllOutAim": "to Aiming rolls (All-Out Aim)",
+ "GURPS.modifierAimAllOutAimBraced": "to Aiming rolls if braced (All-Out Aim)",
+ "GURPS.modifierAimCommittedAim": "to Aiming rolls (Committed Aim)",
+ "GURPS.modifierAimCommittedAimBraced": "to Aiming rolls if braced (Committed Aim)",
+ "GURPS.modifierAllOutAttackRanged": "to hit (All-Out Attack (Ranged))",
+ "GURPS.modifierBlockRetreat": "to Block/Parry (retreat)",
+ "GURPS.modifierCommittedAttackRanged": "to hit (Committed Attack (Ranged))",
+ "GURPS.modifierDeceptiveAttack": "to hit (Deceptive Attack)",
+ "GURPS.modifierDefDeceptiveAttack": "to defenses due to Deceptive attack",
+ "GURPS.modifierDefenseCommittedAim": "to defenses due to Committed Aim",
+ "GURPS.modifierDefenseCommittedAttackRanged": "to defenses due to Committed Attack (Ranged)",
+ "GURPS.modifierDeterminedAttack": "to hit (Determined Attack)",
+ "GURPS.modifierDodgeAcrobatic": "to Dodge (Acrobatics, success)",
+ "GURPS.modifierDodgeDive": "to Dodge (dodge and drop)",
+ "GURPS.modifierDodgeFailedAcro": "to Dodge (Acrobatics, failed)",
+ "GURPS.modifierDodgeRear": "to Dodge (attacked from rear)",
+ "GURPS.modifierDodgeRetreat": "to Dodge (retreat)",
+ "GURPS.modifierDodgeSide": "to Dodge (attacked from side)",
+ "GURPS.modifierExtraEffort": "Extra Effort",
+ "GURPS.modifierFeverishDef": "Feverish Defense",
+ "GURPS.modifierHeroicCharge": "Heroic Charge",
+ "GURPS.modifierMaintainConcentration": "to Will Check, to maintain concentration",
+ "GURPS.modifierMightyBlow": "damage (Mighty Blow)",
+ "GURPS.modifierMoveAttack": "to hit (Move and Attack)",
+ "GURPS.modifierShieldDB": "to Dodge (Shield DB)",
+ "GURPS.modifierStrongAttack": "damage (Strong Attack)",
+ "GURPS.modifierTelegraphicAttack": "to hit (Telegraphic Attack)",
+ "GURPS.modifierWillCheck": "WILL check to maintain Aim",
+
"__Char Sheet__": "=========",
- "GURPS.portrait": "Portrait",
- "GURPS.personalTab": "Personal",
"GURPS.resourcesModsTab": "Resources and Modifiers",
"__Character Sheet Identity__": "=========",
- "GURPS.identity": "Identity",
- "GURPS.identityName": "Name",
- "GURPS.identityPlayer": "Player",
- "GURPS.identityTitle": "Title",
"__Character Sheet Miscellaneous__": "=========",
- "GURPS.miscellaneous": "Miscellaneous",
- "GURPS.miscellaneousCreated": "Created",
- "GURPS.miscellaneousModified": "Modified",
- "GURPS.miscellaneousOptions": "Options",
"__Character Description__": "=========",
"GURPS.description": "Description",
"GURPS.descriptionAge": "Age",
@@ -446,11 +566,6 @@
"GURPS.modifierRangeMHExtremeDesc": "Rival difficult to even see; sniper range",
"GURPS.modifierAddRangeRuler": "Bucket: Add Range Ruler modifier",
"GURPS.modifierAddRangeRulerHint": "If checked, the system will automatically add the last measured Range modifier to the Modifier Bucket.",
- "GURPS.modifierAimAllOutAim": "to Aiming rolls (All-Out Aim)",
- "GURPS.modifierAimAllOutAimBraced": "to Aiming rolls if braced (All-Out Aim)",
- "GURPS.modifierAimCommittedAim": "to Aiming rolls (Committed Aim)",
- "GURPS.modifierAimCommittedAimBraced": "to Aiming rolls if braced (Committed Aim)",
- "GURPS.modifierAllOutAttackRanged": "to hit (All-Out Attack (Ranged))",
"GURPS.modifierAffliction": "Afflictions",
"GURPS.modifierAfflictionCough": "-3 to DX checks (Coughing)",
"GURPS.modifierAfflictionCoughIQ": "-1 to IQ checks (Coughing)",
@@ -473,9 +588,7 @@
"GURPS.modifierAutomatic": "Automatic",
"GURPS.modifierBlindAttack": "-10 to hit (Blind)",
"GURPS.modifierBlindDefend": "-4 to dodge (Blind -- cannot see attacker)",
- "GURPS.modifierBlockRetreat": "to Block/Parry (retreat)",
"GURPS.modifierClickToAdd": "Click on modifiers above and to the right to add to your next roll.",
- "GURPS.modifierCommittedAttackRanged": "to hit (Committed Attack (Ranged))",
"GURPS.modifierCommon": "Common Modifiers",
"GURPS.modifierCover": "Cover",
"GURPS.modifierCoverBehindFigure": "-4 to hit (Behind same-sized figure)",
@@ -492,28 +605,13 @@
"GURPS.modifierCurrentEffects": "Current Effects",
"GURPS.modifierCurrentModifiers": "Current Modifiers",
"GURPS.modifierDangerous": "Dangerous",
- "GURPS.modifierDeceptiveAttack": "to hit (Deceptive Attack)",
- "GURPS.modifierDeterminedAttack": "to hit (Determined Attack)",
- "GURPS.modifierDodgeAcrobatic": "to Dodge (Acrobatics, success)",
- "GURPS.modifierDodgeDive": "to Dodge (dodge and drop)",
- "GURPS.modifierDodgeFailedAcro": "to Dodge (Acrobatics, failed)",
- "GURPS.modifierDodgeRear": "to Dodge (attacked from rear)",
- "GURPS.modifierDodgeRetreat": "to Dodge (retreat)",
- "GURPS.modifierDodgeSide": "to Dodge (attacked from side)",
"GURPS.modifierEasy": "Easy",
- "GURPS.modifierExtraEffort": "Extra Effort",
"GURPS.modifierFavorable": "Favorable",
- "GURPS.modifierFeverishDef": "Feverish Defense",
- "GURPS.modifierDefDeceptiveAttack": "to defenses due to Deceptive attack",
- "GURPS.modifierDefenseCommittedAim": "to defenses due to Committed Aim",
- "GURPS.modifierDefenseCommittedAttackRanged": "to defenses due to Committed Attack (Ranged)",
- "GURPS.modifierMaintainConcentration": "to Will Check, to maintain concentration",
"GURPS.modifierGrappling": "-4 to DX and DX-based skills (Grappled)",
"GURPS.modifierGMBlessed": "GM blessed",
"GURPS.modifierGMDontTry": "GM don't try it",
"GURPS.modifierGMSaidSo": "GM said so",
"GURPS.modifierHard": "Hard",
- "GURPS.modifierHeroicCharge": "Heroic Charge",
"GURPS.modifierHitLocation": "Hit Locations (if miss by 1, then *)",
"GURPS.modifier3d6Image": "Bucket: Change 3d6 Image",
"GURPS.modifier3d6ImageHint": "Select the image to display in the Modifier Bucket for the 3d6 button.",
@@ -532,8 +630,6 @@
"GURPS.modifierLightStarlightClouds": "Starlight through clouds",
"GURPS.modifierLightTwilight": "Twilight / gaslight / flashlight",
"GURPS.modifierLightDeepTwilight": "Deep twilight / candlelight",
- "GURPS.modifierMightyBlow": "damage (Mighty Blow)",
- "GURPS.modifierMoveAttack": "to hit (Move and Attack)",
"GURPS.modifierOthers": "Other Modifiers",
"GURPS.modifierPosition": "Bucket: Change Position",
"GURPS.modifierPositionHint": "Select the position of the Modifier Bucket.",
@@ -567,7 +663,6 @@
"GURPS.modifierSelectJournalsHint": "Select the Journal entries to display in the Modifier Bucket.",
"GURPS.modifierSelectJournalsTitle": "Select Modifier Bucket Journals",
"GURPS.modifierSendTo": "Send Modifier Bucket to:",
- "GURPS.modifierShieldDB": "to Dodge (Shield DB)",
"GURPS.modifierShowOnMouseOver": "Bucket: Show on mouse over",
"GURPS.modifierShowOnMouseOverHint": "If checked, the Modifier window displays like a tooltip: when the mouse hovers over the Modifier Bucket. If this is turned off, you can bring up the Tooltip by Left Clicking on the Modifier Bucket. You must restart Foundry for this setting to take effect.",
"GURPS.modifierSize": "Size Modifier",
@@ -580,10 +675,8 @@
"GURPS.modifierStatusShock3": "-3 to IQ/DX checks (Shock 3)",
"GURPS.modifierStatusShock4": "-4 to IQ/DX checks (Shock 4)",
"GURPS.modifierStatusStunned": "-4 to active defenses (Stunned)",
- "GURPS.modifierStrongAttack": "damage (Strong Attack)",
"GURPS.modifierTabAside": "Use System Settings to define Journal Entries to display here.",
"GURPS.modifierTaskDifficulty": "Task Difficulty",
- "GURPS.modifierTelegraphicAttack": "to hit (Telegraphic Attack)",
"GURPS.modifierToHit": "to hit",
"GURPS.modifierTrivial": "Trivial",
"GURPS.modifierUnfavorable": "Unfavorable",
@@ -594,7 +687,6 @@
"GURPS.modifierVeryUnfavorable": "Very Unfavorable",
"GURPS.modifierViewScale": "Bucket: Scale Factor",
"GURPS.modifierViewScaleHint": "Use this to scale up or down the size of the Modifier Bucket.",
- "GURPS.modifierWillCheck": "WILL check to maintain Aim",
"__PDF References__": "=========",
"GURPS.pdfAllOutAim": "PY77:25",
"GURPS.pdfAllOutAttackRanged": "PY77:26",
@@ -998,8 +1090,6 @@
"GURPS.sortContentsAscending": "Sort Contents (Ascending)",
"GURPS.sortContentsDescending": "Sort Contents (Descending)",
"GURPS.sortDescending": "Sort Descending",
- "GURPS.actions": "Actions",
- "GURPS.aiming": "Aiming",
"GURPS.addAdvantage": "Add an Advantage",
"GURPS.addMeleeAttack": "Add a Melee Attack",
"GURPS.addRangedAttack": "Add a Ranged Attack",
@@ -1008,10 +1098,8 @@
"GURPS.addSpell": "Add a Spell",
"GURPS.advantage": "Advantage",
"GURPS.advantages": "Advantages",
- "GURPS.advantagesTab": "Advantages and Disadvantages",
- "GURPS.aim": "Aim",
+ "GURPS.advantagesTab": "Traits",
"GURPS.allDamage": "ALL DAMAGE",
- "GURPS.allOutDefense": "All-Out Defense",
"GURPS.allTheDamage": "ALL THE DAMAGE!!",
"GURPS.applyAllToTarget": "Apply All to {name}",
"GURPS.basic": "Basic",
diff --git a/lang/fr.json b/lang/fr.json
index 153ae513f..e238c3a52 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -1,23 +1,31 @@
{
- "GURPS.title": "GURPS",
- "GURPS.changelog": "LISEZ-MOI",
- "GURPS.DontShowAgain": "Ne plus montrer le Lisez-moi",
- "GURPS.copyrightGURPS": "GURPS est une marque déposée de Steve Jackson Games, et ses règles et illustrations sont protégées par leurs droits d'auteur. Tous les droits sont réservés à Steve Jackson Games. Cette aide de jeu est la création originale de Chris Normand/Nose66 et est distribuée gratuitement et non revendable, avec la permission gracieuse de http://www.sjgames.com/general/online_policy.html",
- "GURPS.copyrightGCS": "GCS is une marque déposée (1998-2020) par Richard A. Wilkes. Tous droits réservés",
+ "gurps": {
+ "copyright": "GURPS est une marque déposée de Steve Jackson Games, et ses règles et illustrations sont protégées par leurs droits d'auteur. Tous les droits sont réservés à Steve Jackson Games. Cette aide de jeu est la création originale de Chris Normand/Nose66 et est distribuée gratuitement et non revendable, avec la permission gracieuse de http://www.sjgames.com/general/online_policy.html",
+ "changelog": {
+ "readme": "LISEZ-MOI",
+ "dontShowAgain": "Ne plus montrer le Lisez-moi"
+ },
+ "sheet": {
+ "personal": {
+ "tab": "Personnel",
+ "identity": "Identité",
+ "name": "Nom",
+ "player": "Joueur",
+ "title": "Titre",
+ "miscellaneous": "Divers",
+ "created": "Créé",
+ "modified": "Modifié"
+ },
+ "gcs": {
+ "copyright": "GCS is une marque déposée (1998-2024) par Richard A. Wilkes. Tous droits réservés."
+ }
+ }
+ },
+
"__Char Sheet__": "=========",
- "GURPS.portrait": "Portrait",
- "GURPS.personalTab": "Personnel",
"GURPS.resourcesModsTab": "Ressources et Modificateurs",
"__Character Sheet Identity__": "=========",
- "GURPS.identity": "Identité",
- "GURPS.identityName": "Nom",
- "GURPS.identityPlayer": "Joueur",
- "GURPS.identityTitle": "Titre",
"__Character Sheet Miscellaneous__": "=========",
- "GURPS.miscellaneous": "Divers",
- "GURPS.miscellaneousCreated": "Créé",
- "GURPS.miscellaneousModified": "Modifié",
- "GURPS.miscellaneousOptions": "Options",
"__Character Description__": "=========",
"GURPS.description": "Description",
"GURPS.descriptionAge": "Age",
@@ -1125,4 +1133,4 @@
"GURPS.parentItemTooltip": "De {type}: {name}",
"GURPS.cannotDropItemAlreadyExists": "Vous avez déjà cet objet.",
"GURPS.droppingItemNotification": "{actorName} reçoit {itemName}"
-}
\ No newline at end of file
+}
diff --git a/lang/pt_br.json b/lang/pt_br.json
index cbd135943..53a60806f 100644
--- a/lang/pt_br.json
+++ b/lang/pt_br.json
@@ -1,24 +1,33 @@
{
"__NOTE TO TRANSLATOR__": "If a given text is the same as the English (en.json), there is no need to include it here. It will fallback to en.json.",
- "GURPS.title": "GURPS",
- "GURPS.changelog": "LEIA-ME",
- "GURPS.DontShowAgain": "Não exibir LEIA-ME novamente",
- "GURPS.copyrightGURPS": "GURPS é marca registrada da Steve Jackson Games, que também detém direitos autorais sobre suas regras e arte. Todos os direitos reservados pela Steve Jackson Games. Este auxílio de jogo é criação original de Chris Normand/Nose66 e é distribuído gratuitamente, sendo vetada a venda, ver permissões em http://www.sjgames.com/general/online_policy.html",
- "GURPS.copyrightGCS": "GCS© Todos os Direitos Reservados 1998-2020 Richard A. Wilkes.",
+ "gurps": {
+ "copyright": "GURPS é marca registrada da Steve Jackson Games, que também detém direitos autorais sobre suas regras e arte. Todos os direitos reservados pela Steve Jackson Games. Este auxílio de jogo é criação original de Chris Normand/Nose66 e é distribuído gratuitamente, sendo vetada a venda, ver permissões em http://www.sjgames.com/general/online_policy.html",
+ "changelog": {
+ "readme": "LEIA-ME",
+ "dontShowAgain": "Não exibir LEIA-ME novamente"
+ },
+ "sheet": {
+ "personal": {
+ "tab": "Pessoal",
+ "portrait": "Retrato",
+ "identity": "Identidade",
+ "name": "Nome",
+ "player": "Jogador(a)",
+ "title": "Título",
+ "miscellaneous": "Diversos",
+ "created": "Criação",
+ "modified": "Modificação",
+ "options": "Opções"
+ },
+ "gcs": {
+ "copyright": "GCS© Todos os Direitos Reservados 1998-2024 Richard A. Wilkes."
+ }
+ }
+ },
"__Char Sheet__": "=========",
- "GURPS.portrait": "Retrato",
- "GURPS.personalTab": "Pessoal",
"GURPS.resourcesModsTab": "Recursos e Modificadores",
"__Character Sheet Identity__": "=========",
- "GURPS.identity": "Identidade",
- "GURPS.identityName": "Nome",
- "GURPS.identityPlayer": "Jogador(a)",
- "GURPS.identityTitle": "Título",
"__Character Sheet Miscellaneous__": "=========",
- "GURPS.miscellaneous": "Diversos",
- "GURPS.miscellaneousCreated": "Criação",
- "GURPS.miscellaneousModified": "Modificação",
- "GURPS.miscellaneousOptions": "Opções",
"__Character Description__": "=========",
"GURPS.description": "Descrição",
"GURPS.descriptionAge": "Idade",
@@ -1203,4 +1212,4 @@
"GURPS.rollMissedBy": "Margem de fracasso {margin}.",
"GURPS.rollTotalHits": "{rofrcl} acertos possíveis ({link})
devido à CdT ({rof}) e o RCO ({rcl}).",
"GURPS.rollTotal": "Resultado da rolagem ({rolls}) = {rtotal}."
-}
\ No newline at end of file
+}
diff --git a/lang/ru.json b/lang/ru.json
index 8b3226218..5fb38caaa 100644
--- a/lang/ru.json
+++ b/lang/ru.json
@@ -1,21 +1,34 @@
{
"__NOTE TO TRANSLATOR__": "If a given text is the same as the English (en.json), there is no need to include it here. It will fallback to en.json.",
- "GURPS.DontShowAgain": "Не показывать README снова",
- "GURPS.copyrightGCS": "Права на GCS принадлежат Richard A. Wilkes, 1998-2020. Все права защищены",
+ "gurps": {
+ "copyright": "GURPS is a trademark of Steve Jackson Games, and its rules and art are copyrighted by Steve Jackson Games. All rights are reserved by Steve Jackson Games. This game aid is the original creation of Chris Normand/Nose66 and is released for free distribution, and not for resale, under the permissions granted by http://www.sjgames.com/general/online_policy.html",
+ "changelog": {
+ "dontShowAgain": "Не показывать README сноваn",
+ "readme": "README",
+ "title": "GURPS"
+ },
+ "sheet": {
+ "personal": {
+ "tab": "Личное",
+ "portrait": "Изображение",
+ "identity": "Личность",
+ "name": "Имя",
+ "player": "Игрок",
+ "title": "Статус",
+ "miscellaneous": "Разное",
+ "created": "Создан",
+ "modified": "Изменён",
+ "options": "Настройки"
+ },
+ "gcs": {
+ "copyright": "Права на GCS принадлежат Richard A. Wilkes, 1998-2024. Все права защищены."
+ }
+ }
+ },
"__Char Sheet__": "=========",
- "GURPS.portrait": "Изображение",
- "GURPS.personalTab": "Личное",
"GURPS.resourcesModsTab": "Ресурсы и Модификаторы",
"__Character Sheet Identity__": "=========",
- "GURPS.identity": "Личность",
- "GURPS.identityName": "Имя",
- "GURPS.identityTitle": "Статус",
- "GURPS.identityPlayer": "Игрок",
"__Character Sheet Miscellaneous__": "=========",
- "GURPS.miscellaneous": "Разное",
- "GURPS.miscellaneousCreated": "Создан",
- "GURPS.miscellaneousModified": "Изменён",
- "GURPS.miscellaneousOptions": "Настройки",
"__Character Description__": "=========",
"GURPS.description": "Описание",
"GURPS.descriptionGender": "Пол",
diff --git a/lib/change-log.js b/lib/change-log.js
index 7e8255ee6..66490be02 100755
--- a/lib/change-log.js
+++ b/lib/change-log.js
@@ -21,7 +21,7 @@ export class ChangeLogWindow extends FormApplication {
}
get title() {
- return `${game.i18n.localize('GURPS.title')} ~ ${game.i18n.localize('GURPS.changelog')}`
+ return `${game.i18n.localize('gurps.changelog.title')} ~ ${game.i18n.localize('gurps.changelog.readme')}`
}
async getData() {
diff --git a/module/actor/actor-importer.js b/module/actor/actor-importer.js
index 4a34449b4..29d759435 100644
--- a/module/actor/actor-importer.js
+++ b/module/actor/actor-importer.js
@@ -262,8 +262,8 @@ export class ActorImporter {
if (!suppressMessage) ui.notifications?.info(i18n_f('GURPS.importSuccessful', { name: nm }))
console.log(
'Done importing (' +
- Math.round(performance.now() - starttime) +
- 'ms.) You can inspect the character data below:'
+ Math.round(performance.now() - starttime) +
+ 'ms.) You can inspect the character data below:'
)
console.log(this)
importResult = true
@@ -299,7 +299,7 @@ export class ActorImporter {
title: game.i18n.format('GURPS.importSheetTitle', { generator }),
content: `
${game.i18n.format('GURPS.importSheetHint', { name, generator })}
`, buttons: {}, - close: () => { }, + close: () => {}, }, { width: 400, @@ -510,8 +510,8 @@ export class ActorImporter { if (!suppressMessage) ui.notifications?.info(i18n_f('GURPS.importSuccessful', { name: nm })) console.log( 'Done importing (' + - Math.round(performance.now() - starttime) + - 'ms.) You can inspect the character data below:' + Math.round(performance.now() - starttime) + + 'ms.) You can inspect the character data below:' ) console.log(this) importResult = true @@ -1764,7 +1764,7 @@ export class ActorImporter { name += addition + ')' } let s = new Skill(name, '') - s.originalName = i.name + s.originalName = name s.pageRef(i.reference || '') s.uuid = i.id s.parentuuid = p @@ -2427,13 +2427,16 @@ export class ActorImporter { */ _findElementIn(list, uuid, name = '', mode = '') { var foundkey - let foundLength = Number.MAX_VALUE + let foundLength = Number.MAX_VALUE let l = foundry.utils.getProperty(this.actor, 'system.' + list) recurselist(l, (e, k, _d) => { - if ((uuid && e.uuid == uuid) || (!!e.name && e.name.startsWith(name) && e.name.length < foundLength && e.mode == mode)) { + if ( + (uuid && e.uuid == uuid) || + (!!e.name && e.name.startsWith(name) && e.name.length < foundLength && e.mode == mode) + ) { foundkey = k foundLength = !!e.name ? e.name.length : foundLength - } + } }) return foundkey == null ? foundkey : foundry.utils.getProperty(this.actor, 'system.' + list + '.' + foundkey) } @@ -2502,7 +2505,7 @@ export class ActorImporter { let oldotf = oldobj[objkey] newobj[objkey] = oldotf var notes, newotf - ;[notes, newotf] = this._removeOtf(otfkey, newobj.notes || '') + ;[notes, newotf] = this._removeOtf(otfkey, newobj.notes || '') if (!!newotf) newobj[objkey] = newotf newobj.notes = notes.trim() } diff --git a/module/actor/actor.js b/module/actor/actor.js index ed672a268..3efbcc5a0 100644 --- a/module/actor/actor.js +++ b/module/actor/actor.js @@ -259,7 +259,8 @@ export class GurpsActor extends Actor { if (!this.system.equippedblock) this.system.equippedblock = this.getEquippedBlock() // Catch for older actors that may not have these values set. if (!this.system.currentmove) this.system.currentmove = parseInt(this.system.basicmove.value.toString()) - if (!this.system.currentdodge && this.system.dodge.value) this.system.currentdodge = parseInt(this.system.dodge.value.toString()) + if (!this.system.currentdodge && this.system.dodge.value) + this.system.currentdodge = parseInt(this.system.dodge.value.toString()) if (!this.system.currentflight) this.system.currentflight = parseFloat(this.system.basicspeed.value.toString()) * 2 // Look for Defense bonuses. @@ -612,7 +613,7 @@ export class GurpsActor extends Actor { let inCombat = false try { inCombat = !!game.combat?.combatants.filter(c => c.actorId == this.id) - } catch (err) { } // During game startup, an exception is being thrown trying to access 'game.combat' + } catch (err) {} // During game startup, an exception is being thrown trying to access 'game.combat' let updateMove = game.settings.get(settings.SYSTEM_NAME, settings.SETTING_MANEUVER_UPDATES_MOVE) && inCombat let maneuver = this._getMoveAdjustedForManeuver(move, threshold) @@ -639,9 +640,9 @@ export class GurpsActor extends Actor { return !!adjustment ? adjustment : { - move: Math.max(1, Math.floor(move * threshold)), - text: i18n('GURPS.moveFull'), - } + move: Math.max(1, Math.floor(move * threshold)), + text: i18n('GURPS.moveFull'), + } } _adjustMove(move, threshold, value, reason) { @@ -711,9 +712,9 @@ export class GurpsActor extends Actor { return !!adjustment ? adjustment : { - move: Math.max(1, Math.floor(move * threshold)), - text: i18n('GURPS.moveFull'), - } + move: Math.max(1, Math.floor(move * threshold)), + text: i18n('GURPS.moveFull'), + } } _calculateRangedRanges() { @@ -880,6 +881,27 @@ export class GurpsActor extends Actor { await this.update(data, ctx) } + async toggleStatusEffect(statusId, { active, overlay = false } = {}) { + const status = CONFIG.statusEffects.find(e => e.id === statusId) + if (!status) throw new Error(`Invalid status ID "${statusId}" provided to Actor#toggleStatusEffect`) + + if (foundry.utils.getProperty(status, 'flags.gurps.effect.type') === 'posture') { + let existing = this.getAllActivePostureEffects() + existing = existing.filter(e => e.statuses.find(s => s !== statusId)) + + for (const it of existing) { + console.log(it) + await super.toggleStatusEffect(it.statuses.first()) + } + } + + await super.toggleStatusEffect(statusId, { active, overlay }) + } + + getAllActivePostureEffects() { + return this.effects.filter(e => e.getFlag('gurps', 'effect.type') === 'posture') + } + /** * This method is called when "system.conditions.maneuver" changes on the actor (via the update method) * @param {string} maneuverText @@ -894,7 +916,7 @@ export class GurpsActor extends Actor { if (tokens) for (const t of tokens) { let id = changeData === GURPS.StatusEffectStanding ? this.system.conditions.posture : changeData - await t.toggleEffect(GURPS.StatusEffect.lookup(id)) + await this.toggleStatusEffect(id) } } @@ -1030,7 +1052,9 @@ export class GurpsActor extends Actor { */ async setResourceTrackers() { // find those with non-blank slots - let templates = ResourceTrackerManager.getAllTemplates().filter(it => !!it.slot) + let templates = ResourceTrackerManager.getAllTemplates() + .filter(it => !!it.slot) + .filter(it => it.slot !== 'none') for (const template of templates) { // find the matching data on this actor @@ -1206,8 +1230,10 @@ export class GurpsActor extends Actor { // add a new entry at the end. let empty = Object.values(moveData).length === 0 GURPS.put(move, { - mode: mode, basic: basic ?? this.system.basicmove.value * 2, - enhanced: enhanced, default: empty || isDefault + mode: mode, + basic: basic ?? this.system.basicmove.value * 2, + enhanced: enhanced, + default: empty || isDefault, }) // remove existing entries @@ -2658,8 +2684,9 @@ export class GurpsActor extends Actor { // Exclude than rewrite the hitlocations on Actor await this.internalUpdate({ 'system.-=hitlocations': null }) await this.update({ 'system.hitlocations': actorLocations }) - const msg = `${this.name}: DR ${drFormula} applied to ${affectedLocations.length > 0 ? affectedLocations.join(', ') : 'all locations' - }` + const msg = `${this.name}: DR ${drFormula} applied to ${ + affectedLocations.length > 0 ? affectedLocations.join(', ') : 'all locations' + }` return { changed, msg, info: msg } } } diff --git a/module/actor/multiple-import-app.js b/module/actor/multiple-import-app.js index 7b18fad08..1642c2cfd 100644 --- a/module/actor/multiple-import-app.js +++ b/module/actor/multiple-import-app.js @@ -105,7 +105,7 @@ class MultipleImportApp extends Application { this.data.files[index].selected = isChecked return this.render(true) - case 'import': + case 'import': { // Import the selected files const selectedFiles = this.data.files.filter(it => it.selected) if (selectedFiles.length === 0) { @@ -113,6 +113,7 @@ class MultipleImportApp extends Application { } this._importFiles(selectedFiles) return this.close() + } case 'cancel': this.close() diff --git a/module/chat/slam-calc.js b/module/chat/slam-calc.js index 310fbe6f4..ca5991637 100644 --- a/module/chat/slam-calc.js +++ b/module/chat/slam-calc.js @@ -87,7 +87,7 @@ export class SlamCalculator { } let attackerRoll = Roll.create(diceToFormula(attackerDice, `[Slam Attacker's roll]`, true)) - await attackerRoll.evaluate({ async: true }) + await attackerRoll.evaluate() let attackerMin = false let attackerResult = attackerRoll.total + attackerAdds @@ -97,7 +97,7 @@ export class SlamCalculator { } let targetRoll = Roll.create(diceToFormula(targetDice, `[Slam Defender's roll]`, true)) - await targetRoll.evaluate({ async: true }) + await targetRoll.evaluate() let targetMin = false let targetResult = targetRoll.total + targetAdds if (targetResult < 1) { @@ -263,7 +263,7 @@ export class SlamCalculator { if (!!isAoAStrong) explanation += ` + 2 (${i18n('GURPS.slamAOAStrong')})` let sign = shieldDB >= 0 ? '+' : '-' - if (!!shieldDB) explanation += ` ${sign} ${math.abs(shieldDB)} (${i18n('GURPS.slamShieldDB')})` + if (!!shieldDB) explanation += ` ${sign} ${Math.abs(shieldDB)} (${i18n('GURPS.slamShieldDB')})` if (!!velocity) explanation += ` + ${velocity} ${i18n('GURPS.slamRelativeVelocity')}` if (min) explanation += ` (${i18n('GURPS.minimum')} 1)` return explanation diff --git a/module/damage/damagechat.js b/module/damage/damagechat.js index 21602f047..def86f2fa 100755 --- a/module/damage/damagechat.js +++ b/module/damage/damagechat.js @@ -83,32 +83,20 @@ export default class DamageChat { */ static async _dropCanvasData(canvas, dropData) { if (dropData.type === 'damageItem' || dropData.type === 'Item' || dropData.type === 'equipment') { - let oldselection = new Set(game.user.targets) // remember current targets (so we can reselect them afterwards) - let grid_size = canvas.scene?.grid.size - canvas.tokens?.targetObjects( - { - x: dropData.x - grid_size / 2, - y: dropData.y - grid_size / 2, - height: grid_size, - width: grid_size, - }, - { releaseOthers: true } - ) - let targets = [...game.user.targets] - - // Now that we have the list of targets, reset the target selection back to whatever the user had - for (let t of game.user.targets) { - t.setTarget(false, { releaseOthers: false, groupSelection: true }) - } - oldselection.forEach(t => { - t.setTarget(true, { releaseOthers: false, groupSelection: true }) + // Find all tokens under the drop point. + const targets = canvas.tokens.placeables.filter(token => { + return ( + dropData.x >= token.bounds.x && + dropData.x <= token.bounds.x + token.bounds.width && + dropData.y >= token.bounds.y && + dropData.y <= token.bounds.y + token.bounds.height + ) }) let handle = (/** @type {GurpsActor} */ actor) => actor.handleDamageDrop(dropData.payload) if (dropData.type === 'Item') handle = actor => actor.handleItemDrop(dropData) if (dropData.type === 'equipment') handle = actor => actor.handleEquipmentDrop(dropData) - // actual targets are stored in game.user.targets if (targets.length === 0) return false if (targets.length === 1) { handle(targets[0].actor) diff --git a/module/effects/active-effect.js b/module/effects/active-effect.js index 41f5647b3..0cceb6f2f 100644 --- a/module/effects/active-effect.js +++ b/module/effects/active-effect.js @@ -51,10 +51,9 @@ export default class GurpsActiveEffect extends ActiveEffect { * @param {*} _options * @param {*} _user */ - static async _apply(actor, change, _options, _user) { + static _apply(actor, change, _options, _user) { if (change.key === 'system.conditions.maneuver') actor.replaceManeuver(change.value) else if (change.key === 'system.conditions.posture') actor.replacePosture(change) - // else if (change.key === 'chat') change.effect.chat(actor, JSON.parse(change.value)) else console.debug(change) } @@ -76,7 +75,7 @@ export default class GurpsActiveEffect extends ActiveEffect { * @param {*} _userId */ static _delete(_effect, _data, _userId) { - console.debug('delete ' + _effect) + // console.debug('delete ' + _effect) } /** @@ -117,8 +116,21 @@ export default class GurpsActiveEffect extends ActiveEffect { this.context = context this.chatmessages = [] + } + + /** @inheritDoc */ + _onCreate(data, options, userId) { + super._onCreate(data, options, userId) + + if (game.users.get(userId).isSelf) { + if (!this.getFlag('gurps', 'duration')) this.setFlag('gurps', 'duration', { delaySeconds: null }) + } + } - if (!this.getFlag('gurps', 'duration')) this.setFlag('gurps', 'duration', { delaySeconds: null }) + async _preCreate(data, options, user) { + if (user.isSelf) { + console.log('preCreate', data, options, user) + } } get endCondition() { diff --git a/module/effects/effects.js b/module/effects/effects.js index 32b911c92..cd228df36 100644 --- a/module/effects/effects.js +++ b/module/effects/effects.js @@ -50,7 +50,7 @@ export class StatusEffect { }) Hooks.on('createActiveEffect', args => { - console.log(args) + // console.log(args) }) } diff --git a/module/gurps.js b/module/gurps.js index b3be4984f..673b6f4a9 100644 --- a/module/gurps.js +++ b/module/gurps.js @@ -2104,7 +2104,6 @@ if (!globalThis.GURPS) { // html.find('.directory-footer').append(button) - // we need a special case to handle the markdown editor module because it changes the chat textarea with an EasyMDEContainer const hasMeme = game.modules.get('markdown-editor')?.active const chat = html[0]?.querySelector(hasMeme ? '.EasyMDEContainer' : '#chat-message') @@ -2254,7 +2253,7 @@ if (!globalThis.GURPS) {