From 937639082b2b351e9e46b09b71449596152601d4 Mon Sep 17 00:00:00 2001 From: GESUS <105702323+DevAlexandre0@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:27:06 +0700 Subject: [PATCH 01/10] Update script.js --- nui/script.js | 625 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 554 insertions(+), 71 deletions(-) diff --git a/nui/script.js b/nui/script.js index 632ca73..d942e8a 100644 --- a/nui/script.js +++ b/nui/script.js @@ -1,4 +1,3 @@ -// Global state const state = { isVisible: false, recipes: [], @@ -7,16 +6,30 @@ const state = { skill: { level: 1, xp: 0, nextLevelXP: 100 }, expandedRecipes: {}, activeTab: "all", + searchQuery: "", + sortBy: "name", + filterBy: "all", + favorites: JSON.parse(localStorage.getItem("campfire-favorites") || "[]"), + cookingQueue: [], + theme: localStorage.getItem("campfire-theme") || "dark", + notifications: [], + isCreatingRecipe: false, + customRecipes: JSON.parse(localStorage.getItem("campfire-custom-recipes") || "[]"), } -// Initialize when DOM is loaded document.addEventListener("DOMContentLoaded", () => { + // Apply saved theme + document.body.className = `${state.theme}-theme` + + // Load saved data + loadSavedData() + // Listen for messages from the game client window.addEventListener("message", ({ data }) => { switch (data.action) { case "openCookingMenu": state.isVisible = true - state.recipes = data.recipes || [] + state.recipes = [...(data.recipes || []), ...state.customRecipes] state.inventory = data.inventory || {} state.fuelLevel = data.fuelLevel || 0 if (data.skill) state.skill = data.skill @@ -34,38 +47,365 @@ document.addEventListener("DOMContentLoaded", () => { case "updateSkill": if (data.skill) state.skill = data.skill break + case "cookingComplete": + handleCookingComplete(data.recipeId) + break default: break } renderUI() }) + setInterval(saveData, 30000) // Save every 30 seconds + + setInterval(updateCookingQueue, 1000) + // Initial render renderUI() }) -// Format time helper -function formatTime(ms) { - const seconds = Math.floor(ms / 1000) - if (seconds < 60) return `${seconds}s` - const minutes = Math.floor(seconds / 60) - const remainingSeconds = seconds % 60 - return `${minutes}m ${remainingSeconds}s` +function loadSavedData() { + const savedFavorites = localStorage.getItem("campfire-favorites") + if (savedFavorites) { + state.favorites = JSON.parse(savedFavorites) + } + + const savedCustomRecipes = localStorage.getItem("campfire-custom-recipes") + if (savedCustomRecipes) { + state.customRecipes = JSON.parse(savedCustomRecipes) + } } -// Escape HTML to prevent injection -function escapeHtml(text = "") { - const map = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", +function saveData() { + localStorage.setItem("campfire-favorites", JSON.stringify(state.favorites)) + localStorage.setItem("campfire-custom-recipes", JSON.stringify(state.customRecipes)) + localStorage.setItem("campfire-theme", state.theme) +} + +function getFilteredRecipes() { + const filtered = state.recipes.filter((recipe) => { + // Tab filter + if (state.activeTab !== "all" && recipe.category !== state.activeTab) { + return false + } + + // Search filter + if (state.searchQuery) { + const query = state.searchQuery.toLowerCase() + const matchesName = recipe.label.toLowerCase().includes(query) + const matchesDescription = recipe.description.toLowerCase().includes(query) + const matchesIngredients = recipe.ingredients.some((ing) => ing.name.toLowerCase().includes(query)) + if (!matchesName && !matchesDescription && !matchesIngredients) { + return false + } + } + + // Additional filters + if (state.filterBy === "favorites" && !state.favorites.includes(recipe.id)) { + return false + } + if (state.filterBy === "cookable") { + const hasAllIngredients = recipe.ingredients.every( + (ingredient) => (state.inventory[ingredient.name] || 0) >= ingredient.count, + ) + const requiredFuel = (recipe.cookTime / 1000) * 0.5 + const hasFuel = state.fuelLevel >= requiredFuel + if (!hasAllIngredients || !hasFuel) { + return false + } + } + + return true + }) + + // Sort recipes + filtered.sort((a, b) => { + switch (state.sortBy) { + case "name": + return a.label.localeCompare(b.label) + case "cookTime": + return a.cookTime - b.cookTime + case "difficulty": + return (a.difficulty || 1) - (b.difficulty || 1) + default: + return 0 + } + }) + + return filtered +} + +function toggleFavorite(recipeId) { + const index = state.favorites.indexOf(recipeId) + if (index === -1) { + state.favorites.push(recipeId) + showNotification("Added to favorites!", "success") + } else { + state.favorites.splice(index, 1) + showNotification("Removed from favorites", "success") } - return String(text).replace(/[&<>"']/g, (m) => map[m]) + saveData() + renderUI() +} + +function toggleTheme() { + state.theme = state.theme === "dark" ? "light" : "dark" + document.body.className = `${state.theme}-theme` + saveData() + showNotification(`Switched to ${state.theme} theme`, "success") +} + +function showNotification(message, type = "info", duration = 3000) { + const notification = { + id: Date.now(), + message, + type, + timestamp: Date.now(), + } + + state.notifications.push(notification) + + // Create notification element + const notificationEl = document.createElement("div") + notificationEl.className = `notification ${type}` + notificationEl.innerHTML = ` +
Design your own campfire recipe
+