First commit of group-ironmen-master directory.

This commit is contained in:
2025-10-27 08:25:16 +08:00
commit a8467389ef
26390 changed files with 35396 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
diary-dialog h2 {
color: var(--orange);
}
diary-dialog .dialog__container {
padding: 0;
cursor: auto;
}
.dialog__visible {
cursor: pointer;
}
.diary-dialog__scroll-container {
max-height: 100%;
overflow: auto;
}
.diary-dialog__section {
text-align: center;
}
.diary-dialog__task-complete,
.diary-dialog__requirement-met {
text-decoration: underline;
text-underline-offset: -40%;
text-decoration-skip-ink: none;
color: rgba(255, 255, 255, 0.6) !important;
}
.diary-dialog__task {
display: flex;
flex-wrap: wrap;
padding: 6px 0;
justify-content: center;
align-items: flex-end;
}
.diary-dialog__task:hover {
background: rgba(0, 0, 0, 0.15);
}
.diary-dialog__requirements span {
color: var(--invalid);
}
.diary-dialog__requirements img {
height: 16px;
}
.diary-dialog__requirement-met img {
opacity: 0.5;
}
.diary-dialog__header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: rgba(255, 255, 255, 0.05);
}
.dialog__close:hover {
filter: brightness(1.3);
}
.diary-dialog__tier-complete,
.diary-dialog__diary-complete .diary-dialog__header {
background: rgba(0, 200, 0, 0.1);
}
.diary-dialog__tier-complete h2,
.diary-dialog__diary-complete .diary-dialog__header h2 {
color: rgb(0, 200, 0);
}
.diary-dialog__section h2 {
text-decoration: underline;
}

View File

@@ -0,0 +1,27 @@
<div class="dialog dialog__visible">
<div class="dialog__container rsborder rsbackground">
<div class="diary-dialog__header rsborder-tiny">
<h2 class="diary-dialog__title">
Achievement Diary - ${this.diaryName} - ${this.playerName}
</h2>
<button class="dialog__close">
<img src="/ui/1731-0.png" alt="Close dialog" title="Close dialog" />
</button>
</div>
<div class="diary-dialog__scroll-container">
<div class="diary-dialog__section rsborder-tiny" diary-tier="Easy">
<h2>Easy</h2>
</div>
<div class="diary-dialog__section rsborder-tiny" diary-tier="Medium">
<h2>Medium</h2>
</div>
<div class="diary-dialog__section rsborder-tiny" diary-tier="Hard">
<h2>Hard</h2>
</div>
<div class="diary-dialog__section rsborder-tiny" diary-tier="Elite">
<h2>Elite</h2>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,124 @@
import { BaseElement } from "../base-element/base-element";
import { AchievementDiary } from "../data/diaries";
import { Skill } from "../data/skill";
export class DiaryDialog extends BaseElement {
constructor() {
super();
}
html() {
return `{{diary-dialog.html}}`;
}
connectedCallback() {
super.connectedCallback();
this.diaryName = this.getAttribute("diary-name");
this.playerName = this.getAttribute("player-name");
this.render();
this.background = this.querySelector(".dialog__visible");
this.subscribeOnce(`diaries:${this.playerName}`, this.handleDiaries.bind(this));
this.eventListener(this.querySelector(".dialog__close"), "click", this.close.bind(this));
this.eventListener(this.background, "click", this.closeIfBackgroundClick.bind(this));
}
disconnectedCallback() {
super.disconnectedCallback();
}
closeIfBackgroundClick(evt) {
if (evt.target === this.background) {
this.close();
}
}
close() {
this.remove();
}
handleDiaries(playerDiaries, player) {
const diary = AchievementDiary.diaries[this.diaryName];
let completeTiers = 0;
for (const [tierName, tasks] of Object.entries(diary)) {
const taskSection = document.createDocumentFragment();
const completionData = playerDiaries.completion[this.diaryName][tierName];
let complete = 0;
for (let i = 0; i < tasks.length; ++i) {
const task = tasks[i];
const completed = completionData[i];
const taskEl = document.createElement("div");
taskEl.classList.add("diary-dialog__task");
taskEl.innerText = task.task;
if (completed) {
taskEl.classList.add("diary-dialog__task-complete");
++complete;
}
const requirementsHtml = [];
const combatRequirement = task.requirements?.combat;
if (combatRequirement) {
const playerCombat = player.combatLevel;
const hasCombatRequirement = playerCombat >= combatRequirement;
requirementsHtml.push(`
<span class="${hasCombatRequirement ? "diary-dialog__requirement-met" : ""}">
${playerCombat}/${combatRequirement} Combat
</span>`);
}
const skillRequirements = task.requirements?.skills;
if (skillRequirements) {
for (const [skillName, level] of Object.entries(skillRequirements)) {
const playerLevel = player.skills[skillName].level;
const hasSkillRequirement = playerLevel >= level;
requirementsHtml.push(`
<span class="${hasSkillRequirement ? "diary-dialog__requirement-met" : ""}">
${playerLevel}/${level} <img title="${skillName}" alt="${skillName}" src="${Skill.getIcon(skillName)}" />
</span>
`);
}
}
const questRequirements = task.requirements?.quests;
if (questRequirements) {
for (const quest of questRequirements) {
const questComplete = player.hasQuestComplete(quest);
requirementsHtml.push(
`<span class="${questComplete ? "diary-dialog__requirement-met" : ""}">${quest}</span>`
);
}
}
if (requirementsHtml.length > 0) {
const requirementsEl = document.createElement("div");
requirementsEl.classList.add("diary-dialog__requirements");
requirementsEl.innerHTML = `&nbsp;(${requirementsHtml.join(",&nbsp;")})`;
taskEl.appendChild(requirementsEl);
}
taskSection.appendChild(taskEl);
}
const section = this.querySelector(`.diary-dialog__section[diary-tier="${tierName}"]`);
const header = section.querySelector("h2");
const sectionLink = `https://oldschool.runescape.wiki/w/${this.diaryName.replace(/ /g, "_")}_Diary#${tierName}`;
header.innerHTML = `<a href="${sectionLink}" target="_blank">${header.innerText} - ${complete} / ${tasks.length}</a>`;
if (complete === tasks.length) {
section.classList.add("diary-dialog__tier-complete");
++completeTiers;
}
section.appendChild(taskSection);
}
if (completeTiers === 4) {
this.classList.add("diary-dialog__diary-complete");
}
this.classList.add("dialog__visible");
}
}
customElements.define("diary-dialog", DiaryDialog);