MediaWiki:Gadget-test.js
Jump to navigation
Jump to search
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
// Global variables
let skillLevels = {};
let skillsByClass = {};
let maxJobLevels = {};
let slot = 1;
document.addEventListener('DOMContentLoaded', () => {
loadStateFromLocalStorage();
});
// Function to read a local JSON file
function loadLocalJSONFile(file, callback) {
const xhr = new XMLHttpRequest();
xhr.overrideMimeType('application/json');
xhr.open('GET', file, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
callback(xhr.responseText);
}
};
xhr.send(null);
}
function updateClassHeader(className) {
const classHeading = document.querySelector(`h2[data-class-name="${className}"]`);
if (classHeading) {
// Calculate the total skill points for this class
const totalSkillPoints = Object.values(skillLevels[className] || {}).reduce((sum, level) => sum + level, 0);
const maxLevel = maxJobLevels[className];
classHeading.textContent = `${className} (${totalSkillPoints} / ${maxLevel})`;
}
}
// Function to display JSON data with dynamic max job levels and tooltips
function displayJSONData(data) {
const parsedData = JSON.parse(data);
const dataDisplay = document.getElementById('data-display');
// Group skills by class name and initialize skill levels
skillsByClass = {};
parsedData.skills.forEach(skillItem => {
const className = skillItem.className;
if (!skillsByClass[className]) {
skillsByClass[className] = [];
// No need to initialize skillLevels here as it will be done in the next step
}
skillsByClass[className].push(skillItem);
});
// Initialize skillLevels with each skill starting at 0
Object.keys(skillsByClass).forEach(className => {
skillLevels[className] = {};
skillsByClass[className].forEach(skill => {
skillLevels[className][skill.name] = 0;
});
});
// Get maximum job levels
maxJobLevels = parsedData.maxJob.reduce((levels, job) => {
levels[job.name] = job.maxLevel;
return levels;
}, {});
// Sort the classes in the order they appear in the JSON file
const sortedClasses = parsedData.skills.reduce((classes, skill) => {
if (!classes.includes(skill.className)) {
classes.push(skill.className);
}
return classes;
}, []);
function createTooltip(skillDescription) {
const tooltip = document.createElement('div');
tooltip.classList.add('tooltip');
tooltip.innerHTML = skillDescription;
document.body.appendChild(tooltip);
return tooltip;
}
// Loop through the sorted classes
sortedClasses.forEach(className => {
// Create a heading for the class with dynamic max level (starting from 0)
const classHeading = document.createElement('h2');
classHeading.setAttribute('data-class-name', className);
classHeading.textContent = className;
updateClassHeader(className); // Update class header initially
dataDisplay.appendChild(classHeading);
dataDisplay.addEventListener('contextmenu', event => event.preventDefault());
// Create a div to hold the skills horizontally
const skillsContainer = document.createElement('div');
skillsContainer.classList.add('skills-container');
// Loop through the skills for this class
skillsByClass[className].forEach(skillItem => {
// Create a skill container to display each skill
const skillContainer = document.createElement('div');
skillContainer.classList.add('skill-container');
// Create an image element for the skill picture (with tooltip)
const skillPicture = document.createElement('img');
skillPicture.src = skillItem.skillPicture;
skillPicture.alt = 'Skill Picture';
skillPicture.classList.add('skill-picture');
skillPicture.addEventListener('contextmenu', event => event.preventDefault());
// Set data attributes for skill picture and skill container
skillPicture.setAttribute('data-skill-picture', skillItem.skillPicture);
skillContainer.setAttribute('data-skill-name', skillItem.name);
skillContainer.setAttribute('data-class-name', className);
// Check if the skill is a quest skill and add a class for quest skills
if (skillItem.isQuestSkill) {
skillContainer.classList.add('quest-skill'); // Add a class for quest skills
}
// Append the skill picture to the skill container
skillContainer.appendChild(skillPicture);
// Create a div to hold the skill name
const skillNameDiv = document.createElement('div');
skillNameDiv.classList.add('skill-name');
skillNameDiv.textContent = skillItem.name; // Set the skill name text
// Append the skill name div to the skill container
skillContainer.appendChild(skillNameDiv);
// Create bubbles for skill level
const skillLevel = document.createElement('div');
skillLevel.classList.add('skill-level');
// Create gray bubbles based on maxLevel
for (let i = 0; i < skillItem.maxLevel; i++) {
const bubble = document.createElement('div');
bubble.classList.add('bubble', 'gray');
skillLevel.appendChild(bubble);
}
loadStateFromLocalStorage();
// Function to handle skill level changes
function changeSkillLevel(e) {
e.stopPropagation();
const skillContainer = e.currentTarget;
const className = skillContainer.getAttribute('data-class-name');
const skillName = skillContainer.getAttribute('data-skill-name');
const skillItem = skillsByClass[className].find(skill => skill.name === skillName);
// Determine new level based on click
if (e.button === 0) { // Left click
// Increase skill level
if (skillLevels[className][skillName] < skillItem.maxLevel) {
skillLevels[className][skillName]++;
}
} else if (e.button === 2) { // Right click
// Decrease skill level
if (skillLevels[className][skillName] > 0) {
skillLevels[className][skillName]--;
}
}
updateClassHeader(className);
saveStateToLocalStorage();
refreshUI();
} // Add event listeners to change skill level on clicks
skillContainer.addEventListener('click', changeSkillLevel);
skillContainer.addEventListener('contextmenu', changeSkillLevel);
// Append the skill level to the skill container
skillContainer.appendChild(skillLevel);
// Append the skill container to the skills container
skillsContainer.appendChild(skillContainer);
});
// Append the skills container to the dataDisplay element
dataDisplay.appendChild(skillsContainer);
});
// Function to handle skill container hover event
function handleSkillHover(event) {
const skillContainer = event.currentTarget;
const skillName = skillContainer.getAttribute('data-skill-name');
// Find the skill that corresponds to the hovered skill container
const hoveredSkill = parsedData.skills.find(skill => skill.name === skillName);
const tooltip = createTooltip(hoveredSkill.description);
// Position the tooltip relative to the skill image
const skillPicture = skillContainer.querySelector('.skill-picture');
const skillPictureRect = skillPicture.getBoundingClientRect();
const offsetX = 10; // Adjust the X offset as needed
const offsetY = 10; // Adjust the Y offset as needed
tooltip.style.left = `${skillPictureRect.right + offsetX}px`;
tooltip.style.top = `${skillPictureRect.top - offsetY}px`;
// Handle mouseleave to remove the tooltip
skillContainer.addEventListener('mouseleave', () => {
document.body.removeChild(tooltip);
});
//skillContainer.addEventListener('contextmenu', event => event.preventDefault());
if (hoveredSkill) {
// Iterate through the required skills and highlight their containers and change bubble colors
hoveredSkill.requires.forEach(req => {
const requiredSkillName = req.skillName;
const requiredSkillContainer = document.querySelector(`[data-skill-name="${requiredSkillName}"]`);
requiredSkillContainer.classList.add('highlight2');
if (requiredSkillContainer) {
const requiredLevel = req.requiredLevel;
meep = 0;
// Change bubble colors based on required level and only if not met
const requiredSkillLevel = requiredSkillContainer.querySelector('.skill-level');
const blueBubbles = requiredSkillLevel.querySelectorAll('.bubble.blue');
const grayBubbles = requiredSkillLevel.querySelectorAll('.bubble.gray');
blueBubbles.forEach((blueBubble, index) => {
meep++;
});
grayBubbles.forEach((grayBubble, index) => {
if (index+meep >= requiredLevel) {
grayBubble.style.backgroundColor = ''; //
skillContainer.classList.remove('highlight');
} else {
grayBubble.style.backgroundColor = 'purple'; // Change bubble to purple
requiredSkillContainer.classList.add('highlight');
requiredSkillContainer.classList.remove('highlight2');
}
if(meep >= requiredLevel){
skillContainer.classList.remove('highlight');
console.log(meep);
}
});
}
});
}
}
// Function to handle skill container exit event
function handleSkillExit() {
// Remove highlighting and required level information from all skill containers
skillContainers.forEach(skillContainer => {
skillContainer.classList.remove('highlight');
skillContainer.classList.remove('highlight2');
skillContainer.style.backgroundColor = ''; // Remove background color
const skillLevel = skillContainer.querySelector('.skill-level');
if (skillLevel) {
const bubbles = skillLevel.querySelectorAll('.bubble');
bubbles.forEach(bubble => {
bubble.style.backgroundColor = ''; // Remove bubble background color
});
}
});
}
// Attach event listeners to each skill-container for hover events
const skillContainers = document.querySelectorAll('.skill-container');
skillContainers.forEach(skillContainer => {
skillContainer.addEventListener('mouseenter', handleSkillHover);
skillContainer.addEventListener('mouseleave', handleSkillExit);
});
}
loadLocalJSONFile('your-json-file.json', displayJSONData);
// Function to save the current state to localStorage
function saveStateToLocalStorage() {
const state = {
skillLevels: skillLevels
};
const jsonState = JSON.stringify(state);
const jsonState2 = JSON.stringify(slot);
localStorage.setItem('gameState2'+slot, jsonState);
localStorage.setItem('lastslot', jsonState2);
}
function loadStateFromLocalStorage() {
skillLevels = {};
const jsonState2 = localStorage.getItem('lastslot');
console.log(jsonState2);
if (jsonState2) {
slot = JSON.parse(jsonState2);
}
const jsonState = localStorage.getItem('gameState2'+slot);
if (jsonState) {
const state = JSON.parse(jsonState);
skillLevels = state.skillLevels;
refreshUI();
}
}
function loadSlot(newSlot) {
saveStateToLocalStorage();
slot = newSlot;
const jsonState = localStorage.getItem('gameState2'+slot);
if (jsonState) {
const state = JSON.parse(jsonState);
skillLevels = state.skillLevels;
}
refreshUI();
}
function refreshUI() {
Object.keys(skillsByClass).forEach(className => {
updateClassHeader(className);
skillsByClass[className].forEach(skillItem => {
const skillContainer = document.querySelector(`.skill-container[data-skill-name="${skillItem.name}"][data-class-name="${className}"]`);
if (skillContainer) {
updateSkillLevelBubbles(skillContainer, skillItem, className);
}
});
});
}
function clearData() {
localStorage.removeItem('gameState2'+slot);
localStorage.removeItem('lastslot');
refreshUI();
// Additional code to reset the game state in your application
}
function updateSkillLevelBubbles(skillContainer, skillItem, className) {
const skillLevelContainer = skillContainer.querySelector('.skill-level');
if (skillLevelContainer) {
// Get the current level for this specific skill
const skillName = skillContainer.getAttribute('data-skill-name');
const currentLevel = skillLevels[className][skillName] || 0;
const bubbles = skillLevelContainer.querySelectorAll('.bubble');
bubbles.forEach((bubble, index) => {
if (index < currentLevel) {
bubble.classList.add('blue');
bubble.classList.remove('gray');
} else {
bubble.classList.add('gray');
bubble.classList.remove('blue');
}
});
}
}