diff --git a/_core/lib/sw2.0/edit-chara.pl b/_core/lib/sw2.0/edit-chara.pl
index 2abc3f8a8..bb723f25c 100644
--- a/_core/lib/sw2.0/edit-chara.pl
+++ b/_core/lib/sw2.0/edit-chara.pl
@@ -1347,6 +1347,33 @@ sub classInputBox {
+
+ 魔晶石
+
+
+ | 点数
+ | 所持数
+ | 一時的増減
+ |
+ |
+
+HTML
+foreach my $point (1 .. 20) {
+ my $key = $point < 10 ? ('0' . $point) : $point;
+ print <<"HTML";
+
+ | ${point}点
+ | @{[input "manaGem${key}Quantity",'number',"calcManaGem(${point})",'min="0"']}
+ | @{[input "manaGem${key}Offset",'number',"calcManaGem(${point})"]}
+ | =個
+ |
+HTML
+}
+print <<"HTML";
+
+
+
+
マテリアルカード
diff --git a/_core/lib/sw2/edit-chara.js b/_core/lib/sw2/edit-chara.js
index 2cb6dc37d..3a1412d5e 100644
--- a/_core/lib/sw2/edit-chara.js
+++ b/_core/lib/sw2/edit-chara.js
@@ -89,6 +89,7 @@ window.onload = function() {
calcHonor();
calcDishonor();
calcCommonClass();
+ calcManaGems();
checkEffectAll();
setupBracketInputCompletion();
@@ -2503,6 +2504,85 @@ function delPart(){
delRow('partNum', '#parts tbody tr:last-of-type');
calcParts();
}
+// 魔晶石 ----------------------------------------
+function calcManaGems() {
+ for (let point = 1; point <= 20; point++) {
+ calcManaGem(point);
+ }
+}
+/**
+ * @param {int} point
+ */
+function calcManaGem(point) {
+ const tr = document.querySelector(`#mana-gems table tr[data-point="${point}"]`);
+
+ const quantity = parseInt(tr.querySelector('.quantity input').value);
+ const offset = parseInt(tr.querySelector('.offset input').value);
+
+ const total = (isNaN(quantity) ? 0 : quantity) + (isNaN(offset) ? 0 : offset);
+
+ const valueElement = tr.querySelector('.total .value');
+ valueElement.textContent = commify(total);
+ valueElement.classList.toggle('zero', total === 0);
+ valueElement.classList.toggle('minus', total < 0);
+
+ switchManaGemClearingOffButton();
+}
+function switchManaGemClearingOffButton() {
+ let hasOffset = false;
+
+ for (let point = 1; point <= 20; point++) {
+ const offset = parseInt(document.querySelector(`#mana-gems table tr[data-point="${point}"] .offset input`).value);
+
+ if (!isNaN(offset) && offset !== 0) {
+ hasOffset = true;
+ break;
+ }
+ }
+
+ document.getElementById('clearing-off-mana-gems-offset').disabled = !hasOffset;
+}
+function clearOffManaGemsOffset() {
+ /** @var {Array} */
+ const clearingFunctions = [];
+
+ for (let point = 1; point <= 20; point++) {
+ const tr = document.querySelector(`#mana-gems table tr[data-point="${point}"]`);
+
+ const quantityInput = tr.querySelector('.quantity input');
+ const offsetInput = tr.querySelector('.offset input');
+
+ const offset = parseInt(offsetInput.value);
+
+ if (isNaN(offset) || offset === 0) {
+ continue;
+ }
+
+ const quantity = quantityInput.value !== '' ? parseInt(quantityInput.value) : 0;
+ const clearedQuantity = quantity + offset;
+
+ if (clearedQuantity < 0) {
+ alert(`魔晶石(${point}点)の減少量が元の所持数より大きいため清算できません。`);
+ return;
+ }
+
+ clearingFunctions.push(((quantityInput, offsetInput, clearedQuantity) => {
+ return () => {
+ quantityInput.value = clearedQuantity.toString();
+ offsetInput.value = '';
+
+ for (const input of [quantityInput, quantityInput]) {
+ input.dispatchEvent(new Event('input'));
+ input.dispatchEvent(new Event('change'));
+ }
+ };
+ })(quantityInput, offsetInput, clearedQuantity));
+ }
+
+ clearingFunctions.forEach(x => x.call());
+
+ switchManaGemClearingOffButton();
+}
// 名誉アイテム欄 ----------------------------------------
// 追加
function addHonorItems(){
diff --git a/_core/lib/sw2/edit-chara.pl b/_core/lib/sw2/edit-chara.pl
index 3bc3f9d23..3b8dc7d4b 100644
--- a/_core/lib/sw2/edit-chara.pl
+++ b/_core/lib/sw2/edit-chara.pl
@@ -1348,6 +1348,33 @@ sub classInputBox {
+
+ 魔晶石
+
+
+ | 点数
+ | 所持数
+ | 一時的増減
+ |
+ |
+
+HTML
+foreach my $point (1 .. 20) {
+ my $key = $point < 10 ? ('0' . $point) : $point;
+ print <<"HTML";
+
+ | ${point}点
+ | @{[input "manaGem${key}Quantity",'number',"calcManaGem(${point})",'min="0"']}
+ | @{[input "manaGem${key}Offset",'number',"calcManaGem(${point})"]}
+ | =個
+ |
+HTML
+}
+print <<"HTML";
+
+
+
+
マテリアルカード
diff --git a/_core/lib/sw2/subroutine-sw2.pl b/_core/lib/sw2/subroutine-sw2.pl
index d54f9de23..8e445f561 100644
--- a/_core/lib/sw2/subroutine-sw2.pl
+++ b/_core/lib/sw2/subroutine-sw2.pl
@@ -87,6 +87,19 @@ sub createUnitStatus {
}
push(@unitStatus, { '陣気' => '0' }) if $pc{lvWar};
}
+
+ foreach my $point (1 .. 20) {
+ my $key = $point < 10 ? ('0' . $point) : $point;
+ my $quantity = $pc{"manaGem${key}Quantity"} // 0;
+ next if $quantity == 0;
+
+ sub encloseNumeric {
+ my $num = shift;
+ return ('①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳')[$num - 1];
+ }
+
+ push(@unitStatus, { '魔晶石' . encloseNumeric($point) => $quantity });
+ }
}
foreach my $key (split ',', $pc{unitStatusNotOutput}){
diff --git a/_core/lib/sw2/view-chara.pl b/_core/lib/sw2/view-chara.pl
index 8b94e9e22..dfcb77c03 100644
--- a/_core/lib/sw2/view-chara.pl
+++ b/_core/lib/sw2/view-chara.pl
@@ -979,6 +979,45 @@ sub replaceModificationNotation {
$SHEET->param(Parts => \@row);
}
+### 魔晶石 --------------------------------------------------
+my @manaGems = ();
+{
+ my $lastColumn = 0;
+ my $row;
+
+ foreach my $point (1 .. 20) {
+ my $key = $point < 10 ? ('0' . $point) : $point;
+
+ my $quantity = $pc{"manaGem${key}Quantity"} // 0;
+ my $offset = $pc{"manaGem${key}Offset"} // 0;
+
+ my $total = $quantity + $offset;
+ next if $total == 0;
+
+ my $startColumn = $point < 10 ? 1 : 4;
+
+ if ($startColumn > $lastColumn) {
+ $row = 1;
+ $lastColumn = $startColumn;
+ }
+ else {
+ $row++;
+ }
+
+ push(
+ @manaGems,
+ {
+ POINT => $point,
+ TOTAL => commify($total),
+ ROW => $row,
+ POINT_COLUMN => $startColumn,
+ TOTAL_COLUMN => $startColumn + 1,
+ }
+ );
+ }
+}
+$SHEET->param(ManaGems => \@manaGems);
+
### 履歴 --------------------------------------------------
$pc{history0Grow} .= '器用'.$pc{sttPreGrowA} if $pc{sttPreGrowA};
diff --git a/_core/skin/sw2.0/sheet-chara.html b/_core/skin/sw2.0/sheet-chara.html
index e64c41c4b..64b62aed9 100644
--- a/_core/skin/sw2.0/sheet-chara.html
+++ b/_core/skin/sw2.0/sheet-chara.html
@@ -523,6 +523,17 @@ 所持品
+
+ 魔晶石
+
+
+ -
+ 点
+
-
+ ×個
+
+
+
マテリアルカード
diff --git a/_core/skin/sw2/css/chara.css b/_core/skin/sw2/css/chara.css
index dedaf1ef2..d2acf0298 100644
--- a/_core/skin/sw2/css/chara.css
+++ b/_core/skin/sw2/css/chara.css
@@ -1023,6 +1023,90 @@ dl#level {
}
}
+/* 魔晶石 */
+#mana-gems {
+ table {
+ .point {
+ width: 3em;
+ }
+
+ td.total {
+ display: grid;
+ grid-template-columns: max-content 1fr max-content;
+ padding: 0 0.25em;
+ text-wrap: nowrap;
+ word-break: keep-all;
+ white-space: nowrap;
+
+ &:has(.value.zero) {
+ color: gray;
+ opacity: 0.8;
+ }
+
+ &:has(.value.minus) {
+ color: #e70;
+ }
+
+ .value {
+ display: inline-block;
+ text-wrap: nowrap;
+ word-break: keep-all;
+ white-space: nowrap;
+ text-align: right;
+ }
+
+ .unit {
+ display: flex;
+ flex-flow: row;
+ align-items: flex-end;
+ font-size: smaller;
+ font-style: normal;
+ }
+ }
+ }
+
+ #clearing-off-mana-gems-offset {
+ margin: 0.25em;
+
+ &[disabled] {
+ pointer-events: none;
+ opacity: 0.5;
+ }
+ }
+
+ dl {
+ display: grid;
+ grid-template-columns: repeat(2, max-content max-content 1fr);
+ padding: 0 0.5em;
+
+ .point {
+ text-align: right;
+ }
+
+ .total {
+ i {
+ font-style: normal;
+ }
+
+ text-align: right;
+ padding-left: 0.5em;
+
+ .mark {
+ float: left;
+ }
+
+ .value {
+ display: inline-block;
+ text-align: right;
+ }
+
+ .unit {
+ font-size: smaller;
+ }
+ }
+ }
+}
+
/* MaterialCard */
#material-cards table {
& tr > * {
diff --git a/_core/skin/sw2/sheet-chara.html b/_core/skin/sw2/sheet-chara.html
index 1fdf4fe41..928e89f3a 100644
--- a/_core/skin/sw2/sheet-chara.html
+++ b/_core/skin/sw2/sheet-chara.html
@@ -522,6 +522,19 @@ 所持品
+
+
+ 魔晶石
+
+
+ -
+ 点
+
-
+ ×個
+
+
+
+