/** * PPE SAFETY CHALLENGE - DYNAMIC 2D WORKER AVATAR SYSTEM * Uses the step-by-step transparent character images from ppe_character_steps_transparent_png! * Dynamically switches character states as safety gear is equipped. */ class WorkerAvatar { constructor(containerId) { this.container = document.getElementById(containerId); this.equippedItems = new Set(); this.render(); } setEquipped(itemIds) { this.equippedItems = new Set(itemIds); this.updateLayers(); } equip(itemId) { this.equippedItems.add(itemId); this.updateLayers(); } unequip(itemId) { this.equippedItems.delete(itemId); this.updateLayers(); } has(itemId) { return this.equippedItems.has(itemId); } getAvatarCenterCoordinates() { if (!this.container) return { x: 170, y: 220, eyeX: 170, eyeY: 110, handX: 230, handY: 260 }; const rect = this.container.getBoundingClientRect(); const parentRect = this.container.parentElement.getBoundingClientRect(); const relX = rect.left - parentRect.left + (rect.width * 0.5); const relY = rect.top - parentRect.top + (rect.height * 0.5); return { x: relX, y: relY, eyeX: relX, eyeY: relY - 130, handX: relX + 55, handY: relY + 30 }; } getStepImagePath() { const hasHelmet = this.equippedItems.has('safety_helmet_grind') || this.equippedItems.has('safety_helmet_chem'); const hasGoggles = this.equippedItems.has('chem_splash_goggles') || this.equippedItems.has('safety_goggles_grind'); const hasFaceShield = this.equippedItems.has('face_shield_grind') || this.equippedItems.has('face_shield_chem'); const hasHearing = this.equippedItems.has('hearing_protection_grind') || this.equippedItems.has('hearing_protection_chem'); const hasLeatherGloves = this.equippedItems.has('leather_grinding_gloves'); const hasWorkGloves = this.equippedItems.has('work_gloves_grind') || this.equippedItems.has('standard_work_gloves'); const hasChemGloves = this.equippedItems.has('chem_resistant_gloves'); const hasVest = this.equippedItems.has('reflective_vest_grind'); const hasApron = this.equippedItems.has('chem_resistant_apron'); const hasCottonCoat = this.equippedItems.has('cotton_coat_chem'); const hasBoots = this.equippedItems.has('steel_toe_boots_grind') || this.equippedItems.has('chem_safety_shoes'); const hasMask = this.equippedItems.has('dust_mask_grind'); // 10. Full PPE with Mask if (hasMask) { return 'images/steps/10_full_ppe_with_mask.png'; } // 9. Full Grinding Set with Boots if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasBoots)) { return 'images/steps/09_helmet_goggles_hearing_leather_gloves_vest_boots.png'; } // 8. With Vest / Body Wear if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasCottonCoat)) { return 'images/steps/08_helmet_goggles_hearing_leather_gloves_vest.png'; } // 7. With Leather / Chem Gloves if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves)) { return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png'; } // 6. With Work Gloves if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && hasWorkGloves) { return 'images/steps/06_helmet_goggles_hearing_work_gloves.png'; } // 5. With Earmuffs / Hearing Protection if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing) { return 'images/steps/05_helmet_goggles_hearing.png'; } // 4. With Face Shield if (hasFaceShield || (hasHelmet && hasFaceShield)) { return 'images/steps/04_helmet_goggles_face_shield.png'; } // 3. With Goggles & Helmet if (hasHelmet && hasGoggles) { return 'images/steps/03_helmet_goggles.png'; } // 2. Helmet Only if (hasHelmet) { return 'images/steps/02_helmet.png'; } // Individual items if (hasFaceShield) return 'images/steps/04_helmet_goggles_face_shield.png'; if (hasGoggles) return 'images/steps/03_helmet_goggles.png'; if (hasHearing) return 'images/steps/05_helmet_goggles_hearing.png'; if (hasLeatherGloves) return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png'; if (hasWorkGloves) return 'images/steps/06_helmet_goggles_hearing_work_gloves.png'; // 1. Base Worker (No PPE) return 'images/steps/01_no_ppe.png'; } render() { if (!this.container) return; this.container.innerHTML = `
Worker Character
`; this.updateLayers(); } updateLayers() { if (!this.container) return; const imgEl = document.getElementById('avatar-step-img'); if (imgEl) { const targetSrc = this.getStepImagePath(); if (imgEl.getAttribute('src') !== targetSrc) { imgEl.src = targetSrc; } } } }