Skip to content

Commit 723dccf

Browse files
authored
Merge pull request #1 from AldenWangExis/feat/skill-creation-points
feat: 创建阶段技能点与战斗熟练追踪功能
2 parents 79b9f62 + de8c812 commit 723dccf

File tree

7 files changed

+321
-1
lines changed

7 files changed

+321
-1
lines changed

TheOneRing-CharacterCard.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,13 @@ <h2 class="feature-title-bar">
253253
<div class="info-item fellowship-points"><label for="fellowship_points">同盟点</label><input type="number" id="fellowship_points" name="fellowship_points" value="0"></div>
254254
</div>
255255

256+
<div class="points-row creation-points-row" id="creation_points_row">
257+
<div class="info-item creation-points-status">
258+
<span class="creation-points-label">创建点数</span>
259+
<span class="creation-points-figures">剩余 <span id="creation_points_remaining">10</span> / 10(已用 <span id="creation_points_spent">0</span></span>
260+
</div>
261+
</div>
262+
256263
<div class="header-extra">
257264
<div class="secondary-stats-container">
258265
<div class="diamond-box diamond-box-small square-box-small">
@@ -430,6 +437,7 @@ <h2>裁剪头像</h2>
430437
<script src="assets/js/data/gear.js" defer></script>
431438
<script src="assets/js/data/skills.js" defer></script>
432439
<script src="assets/js/modules/core.js" defer></script>
440+
<script src="assets/js/modules/creation.js" defer></script>
433441
<script src="assets/js/modules/rewards-virtues.js" defer></script>
434442
<script src="assets/js/modules/gear.js" defer></script>
435443
<script src="assets/js/modules/king-of-men.js" defer></script>

assets/css/styles.css

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
--text-color: #3a2d1d;
66
--background-color: #f7f3e9;
77
--input-underline-color: #d1c5b0;
8+
--prof-or-hint-bg: rgba(183, 67, 60, 0.12);
9+
--prof-or-hint-edge: rgba(183, 67, 60, 0.34);
810
}
911

1012
@font-face {
@@ -24,13 +26,15 @@
2426

2527
.character-sheet {
2628
width: calc(297mm - 30px);
27-
height: calc(210mm - 30px);
29+
min-height: calc(210mm - 30px);
30+
height: auto;
2831
margin: auto;
2932
border: 1px solid var(--border-color);
3033
padding: 15px;
3134
background: #faf0e6;
3235
box-shadow: var(--box-shadow);
3336
position: relative;
37+
box-sizing: border-box;
3438
}
3539

3640
.character-sheet::before {
@@ -333,6 +337,18 @@
333337
.header-right .points-row .info-item { flex: 1 1 0; min-width: 0; flex-direction: row; align-items: center; gap: 6px; }
334338
.header-right .points-row .info-item label { margin-bottom: 0; white-space: nowrap; }
335339
.header-right .points-row .info-item input[type="number"] { width: 38px; padding: 2px 6px; height: 28px; }
340+
.header-right .creation-points-row .creation-points-status {
341+
flex: 1 1 100%;
342+
font-size: 0.9em;
343+
line-height: 1.3;
344+
}
345+
.header-right .creation-points-row.creation-points-overspent .creation-points-figures {
346+
color: #a32;
347+
font-weight: 600;
348+
}
349+
.header-right .creation-points-row.creation-points-inactive {
350+
display: none;
351+
}
336352
.header-right .header-extra { display: flex; flex-direction: column; gap: 10px; align-items: stretch; flex: 1 1 auto; min-height: 0; }
337353
.header-right .travel-gear-item { flex-direction: column; align-items: stretch; flex: 1 1 auto; min-height: 0; }
338354
.header-right .travel-gear-item label { margin-bottom: 6px; font-size: 1em; border-bottom: 2px solid var(--border-color); padding-bottom: 4px; }
@@ -516,6 +532,13 @@
516532
}
517533

518534
.skill-ranks { display: flex; }
535+
.combat-proficiencies .skill-ranks.prof-or-hint {
536+
padding: 3px 5px;
537+
margin: -3px -5px;
538+
border-radius: 4px;
539+
background: var(--prof-or-hint-bg);
540+
box-shadow: inset 0 0 0 1px var(--prof-or-hint-edge);
541+
}
519542
.skill-ranks input[type="checkbox"] { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border: 1px solid var(--border-color); margin: 0 2px; cursor: pointer; position: relative; }
520543
.skill-ranks input[type="checkbox"]::before { content: ''; position: absolute; top: 50%; left: 50%; width: 12px; height: 12px; background-color: var(--border-color); transform: translate(-50%, -50%) scale(0); transition: transform 0.2s ease-in-out; }
521544
.skill-ranks input[type="checkbox"]:checked::before { transform: translate(-50%, -50%) scale(1); }
@@ -722,5 +745,6 @@
722745
}
723746
.buttons-section { display: none; }
724747
.gear-controls { display: none; }
748+
.creation-points-row { display: none !important; }
725749
}
726750

assets/js/data/skills.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
/** 战斗熟练四类(与人物卡 prof_* 容器 id 一致)。 */
2+
const proficiencyRankContainers = [
3+
'prof_axes',
4+
'prof_bows',
5+
'prof_spears',
6+
'prof_swords'
7+
];
8+
9+
/**
10+
* 「弓类或剑类 2」等:两项战斗熟练 id,由玩家在二者之一上点满 2 级(不预填默认项)。
11+
*/
12+
const cultureCombatProficiencyOrPair = {
13+
"巴德一族的人类": ["prof_bows", "prof_swords"],
14+
"都林一族的矮人": ["prof_axes", "prof_swords"],
15+
"林顿的精灵": ["prof_bows", "prof_spears"],
16+
"夏尔的霍比特人": ["prof_bows", "prof_swords"],
17+
"布理的人类": ["prof_axes", "prof_spears"],
18+
"北方的游民": ["prof_spears", "prof_swords"]
19+
};
20+
121
const skillRankContainers = [
222
'skill_awe',
323
'skill_athletics',

assets/js/main.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ document.addEventListener('DOMContentLoaded', function() {
55
kingOfMenBonusAppliedTo: null,
66
currentProtectiveSlot: null,
77
currentCombatGearRow: null,
8+
creationBaseRanks: {},
89
baseTN: 20,
910
isRestoring: false,
1011
autoSaveKey: 'tor_character_autosave',
@@ -131,6 +132,13 @@ document.addEventListener('DOMContentLoaded', function() {
131132
];
132133
skillContainers.forEach(id => app.core.createRankCheckboxes(id));
133134

135+
if (app.creation && app.creation.init) {
136+
app.creation.init();
137+
}
138+
if (app.core && app.core.updateProficiencyOrHints) {
139+
app.core.updateProficiencyOrHints();
140+
}
141+
134142
document.getElementById('save-btn').addEventListener('click', app.storage.exportCharacter);
135143
document.getElementById('load-btn').addEventListener('click', app.storage.importCharacter);
136144
document.getElementById('export-btn').addEventListener('click', () => {
@@ -210,6 +218,9 @@ document.addEventListener('DOMContentLoaded', function() {
210218
app.core.updateAttributes();
211219
app.king.updateKingOfMenUI();
212220
app.gear.updateTotalLoad();
221+
if (app.creation && app.creation.reset) {
222+
app.creation.reset();
223+
}
213224
localStorage.removeItem(app.state.autoSaveKey);
214225
alert('人物卡已重置。');
215226
}

assets/js/modules/core.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,38 @@
1818
if (i >= currentIndex) checkboxes[i].checked = false;
1919
}
2020
}
21+
if (app.creation && app.creation.updateCreationPointsUI) {
22+
app.creation.updateCreationPointsUI();
23+
}
24+
updateProficiencyOrHints();
25+
}
26+
27+
function getProficiencyRank(containerId) {
28+
const container = document.getElementById(containerId);
29+
if (!container) return 0;
30+
return container.querySelectorAll('input:checked').length;
31+
}
32+
33+
/** 「或」类 2 级未点满前,在两项熟练格上显示浅色提示(与 creation 点数无关)。 */
34+
function updateProficiencyOrHints() {
35+
proficiencyRankContainers.forEach((id) => {
36+
const el = document.getElementById(id);
37+
if (el) el.classList.remove('prof-or-hint');
38+
});
39+
if (app.state.isRestoring) return;
40+
const cultureEl = document.getElementById('heroic_culture');
41+
const culture = cultureEl ? cultureEl.value : '';
42+
const pair = cultureCombatProficiencyOrPair[culture];
43+
if (!pair) return;
44+
const [a, b] = pair;
45+
const ra = getProficiencyRank(a);
46+
const rb = getProficiencyRank(b);
47+
const orResolved = (ra >= 2 && rb <= 1) || (rb >= 2 && ra <= 1);
48+
if (orResolved) return;
49+
const elA = document.getElementById(a);
50+
const elB = document.getElementById(b);
51+
if (elA) elA.classList.add('prof-or-hint');
52+
if (elB) elB.classList.add('prof-or-hint');
2153
}
2254

2355
function createRankCheckboxes(containerId, count = 5) {
@@ -52,6 +84,11 @@
5284
const rank = Object.prototype.hasOwnProperty.call(ranks, containerId) ? ranks[containerId] : 0;
5385
setSkillRanks(containerId, rank);
5486
});
87+
proficiencyRankContainers.forEach((id) => setSkillRanks(id, 0));
88+
if (app.creation && app.creation.snapshotBaseRanksAfterCulture) {
89+
app.creation.snapshotBaseRanksAfterCulture();
90+
}
91+
updateProficiencyOrHints();
5592
}
5693

5794
function handleModeChange() {
@@ -248,6 +285,7 @@
248285
createRankCheckboxes,
249286
setSkillRanks,
250287
applyCultureSkillRanks,
288+
updateProficiencyOrHints,
251289
handleModeChange,
252290
updateAttributes,
253291
updateFromTN,

0 commit comments

Comments
 (0)