function getCurrentView() { var room = rooms.find(room => room.id == userData.position); displayViews(room); } function updateCargo() { let cargoContainer = document.getElementById("cargo"); groupByType(userData.inCargoHold).forEach((group) => { let cargoRow = document.createElement("div"); cargoRow.innerHTML = `${group[0].description} (x${group.length})`; cargoContainer.appendChild(cargoRow); }) } function buildActions(room) { document.getElementById("additional-actions").innerHTML = ""; if (room.actions) { room.actions.forEach(control => { let state = states.find(state => state.id == control); if (!state.show || state.show()) { let actionButton = document.createElement("button"); actionButton.className = "action button"; actionButton.innerHTML = state.button; actionButton.addEventListener("click", event => { trigger(state); }); document.getElementById("additional-actions").appendChild(actionButton); } }); } } function triggerStateById(stateId) { let state = states.find(state => state.id == stateId); trigger(state); } function buildDoors(room) { document.getElementById("destinations").innerHTML = ""; if (room.doors) { room.doors.forEach(door => { let doorButton = document.createElement("button"); doorButton.className = "door button"; let doorText = document.createElement("span") doorText.className = "text" doorText.innerHTML = door.button; doorButton.appendChild(doorText) doorButton.addEventListener("click", event => { trigger(door); }); document.getElementById("destinations").appendChild(doorButton); }) } } function setDoorsActive(room) { let doorContainer = document.getElementById("destinations"); for(let i = 0; i < doorContainer.children.length; i++) { let door = doorContainer.children[i]; door.disabled = ""; if (isFlagEnabled('solar-enabled') || isFlagEnabled('ramjet-enabled') || isFlagEnabled('ion-engine-enabled')) { door.disabled = "disabled"; } } } async function displayViews(room) { let viewsContainer = document.getElementById('room-views'); viewsContainer.innerHTML = ""; play(room.play); await setupShipStatus(room, viewsContainer); for(let i = 0; i < room.viewable.length; i++) { let viewable = room.viewable[i]; let template = await templateLoader.get(viewable.elementId); let container = document.createElement('div'); container.id = viewable.elementId; container.innerHTML = template; viewsContainer.appendChild(container); setupViewable(room, viewable, container); } if(room.enter) { room.enter(); } await setupChat(room, viewsContainer); } async function setupShipStatus(room, viewsContainer) { let template = await templateLoader.get("shipstatus") let container = document.createElement('div'); container.id = "shipstatus"; container.innerHTML = template; viewsContainer.appendChild(container); updateActivity("Idle"); updateFuel(); updateMoney(); updateEnergy(); updateCargo(); } function setupViewable(room, viewable, element) { element.style.display = "block"; switch (viewable.elementId) { case "put-in-inventory": putInInventory(viewable, element, viewable.data.source()); break; case "get-from-inventory": getFromInventory(viewable, element, viewable.data.validator); break; case 'asteroid-field': updateSpaceDebris(); break; case 'room-description': updatePosition(room.name); updateDescription(room.description); break; case 'doors': buildDoors(room); setDoorsActive(room); break; case 'actions': buildActions(room); break; } } async function setupChat(room, viewsContainer) { let template = await templateLoader.get("chat") let container = document.createElement('div'); container.id = "chat"; container.innerHTML = template; viewsContainer.appendChild(container); attachChat(room); } function updatePosition(newPositionText) { if (!newPositionText) { return; } document.getElementById("position").innerHTML = "Location: " + newPositionText; } function updateDescription(newDescriptionText) { if (!newDescriptionText) { return; } document.getElementById("description").innerHTML = newDescriptionText; } function putInInventory(viewable, element, gatheringSource) { let moveLeft = (event) => { let left = element.getElementsByClassName("left-inv-selector")[0]; let right = element.getElementsByClassName("right-inv-selector")[0]; right.removeChild(event.target); left.appendChild(event.target); let index = selectedItems.indexOf(event.target.item); if (index > -1) { selectedItems.splice(index, 1); } event.target.removeEventListener("click", moveLeft); event.target.addEventListener("click", moveRight); let topBar = element.getElementsByClassName("top-bar")[0]; let cargoSize = topBar.getElementsByTagName("span")[0]; cargoSize.innerHTML = `${selectedItems.length + userData.inCargoHold.length}/${userData.maxCargoCapacity}`; }; let moveRight = (event) => { let left = element.getElementsByClassName("left-inv-selector")[0]; let right = element.getElementsByClassName("right-inv-selector")[0]; left.removeChild(event.target); right.appendChild(event.target); selectedItems.push(event.target.item); event.target.removeEventListener("click", moveRight); event.target.addEventListener("click", moveLeft); let topBar = element.getElementsByClassName("top-bar")[0]; let cargoSize = topBar.getElementsByTagName("span")[0]; cargoSize.innerHTML = `${selectedItems.length + userData.inCargoHold.length}/${userData.maxCargoCapacity}`; }; selectedItems = []; let left = element.getElementsByClassName("left-inv-selector")[0]; left.innerHTML = ''; let right = element.getElementsByClassName("right-inv-selector")[0]; right.innerHTML = ''; gatheringSource.forEach(item => { let clickableItem = document.createElement("div"); clickableItem.innerHTML = item.description; clickableItem.className = "clickable-inventory-item"; clickableItem.item = item; clickableItem.addEventListener("click", moveRight); left.appendChild(clickableItem); }); userData.inCargoHold.forEach(item => { let unclickableItem = document.createElement("div"); unclickableItem.innerHTML = item.description; unclickableItem.className = "inventory-item"; right.appendChild(unclickableItem); }); let header = element.getElementsByClassName('selector-header')[0]; header.innerHTML = viewable.data.button; let topBar = element.getElementsByClassName("top-bar")[0]; let selectAll = topBar.getElementsByTagName("button")[0]; selectAll.addEventListener("click", event => { let left = element.getElementsByClassName("left-inv-selector")[0]; let selectableItems = left.getElementsByClassName("clickable-inventory-item"); for (let i = selectableItems.length - 1; i >= 0; i--) { let child = selectableItems[i]; child.click(); }; }); let cargoSize = topBar.getElementsByTagName("span")[0]; cargoSize.innerHTML = `${selectedItems.length + userData.inCargoHold.length}/${userData.maxCargoCapacity}`; let bottomBar = element.getElementsByClassName("bottom-bar")[0]; let actionButton = bottomBar.getElementsByTagName("button")[0]; actionButton.innerHTML = viewable.data.button; actionButton.addEventListener("click", () => { triggerStateById(viewable.data.action); }); } function getFromInventory(viewable, element, validator = () => true) { let moveLeft = (event) => { let left = element.getElementsByClassName("left-inv-selector")[0]; let right = element.getElementsByClassName("right-inv-selector")[0]; right.removeChild(event.target); left.appendChild(event.target); let index = selectedItems.indexOf(event.target.item); if (index > -1) { selectedItems.splice(index, 1); } event.target.removeEventListener("click", moveLeft); event.target.addEventListener("click", moveRight); }; let moveRight = (event) => { let left = element.getElementsByClassName("left-inv-selector")[0]; let right = element.getElementsByClassName("right-inv-selector")[0]; left.removeChild(event.target); right.appendChild(event.target); selectedItems.push(event.target.item); event.target.removeEventListener("click", moveRight); event.target.addEventListener("click", moveLeft); }; selectedItems = []; let left = element.getElementsByClassName("left-inv-selector")[0]; left.innerHTML = ''; let right = element.getElementsByClassName("right-inv-selector")[0]; right.innerHTML = ''; userData.inCargoHold.forEach(item => { let clickableItem = document.createElement("div"); clickableItem.innerHTML = item.description; clickableItem.className = "inventory-item"; if(validator(item)) { clickableItem.className = "clickable-inventory-item"; } clickableItem.item = item; clickableItem.addEventListener("click", moveRight); left.appendChild(clickableItem); }); let header = element.getElementsByClassName('selector-header')[0]; header.innerHTML = viewable.data.button; let topBar = element.getElementsByClassName("top-bar")[0]; let selectAll = topBar.getElementsByTagName("button")[0]; selectAll.addEventListener("click", event => { let left = element.getElementsByClassName("left-inv-selector")[0]; let selectableItems = left.getElementsByClassName("clickable-inventory-item"); for (let i = selectableItems.length - 1; i >= 0; i--) { let child = selectableItems[i]; child.click(); }; }); let bottomBar = element.getElementsByClassName("bottom-bar")[0]; let actionButton = bottomBar.getElementsByTagName("button")[0]; actionButton.innerHTML = viewable.data.button; actionButton.addEventListener("click", () => { if(viewable.data.action) { triggerStateById(viewable.data.action); } }); } function updateSpaceDebris() { let debrisContainer = document.getElementById("asteroid-field"); groupByType(userData.debrisInSpace).forEach((group) => { let debrisRow = document.createElement("div"); debrisRow.innerHTML = `${group[0].description} (x${group.length})`; debrisContainer.appendChild(debrisRow); }) } function trigger(control) { clearTimeout(timeoutId); document.getElementById("progress").value = 0; errorMessage = ""; if (control.requires()) { // disableAction(); updateActivity(control.action); startControl(control); let step = control.step || 10; if (typeof control.step == "function") { step = control.step(); } let duration = control.duration; if (typeof control.duration == "function") { duration = control.duration(); } if (duration > 0) { delayLoop(() => runControl(control), duration, step); } else { runControl(control); } } updateError(); } function startControl(control) { if(control.start) { control.start(); } } function runControl(control) { control.run(); save(); // enableAction(); getCurrentView(); } function save() { localStorage.setItem("spaceloop1-save", JSON.stringify(userData)); } function load() { var gameDataString = localStorage.getItem("spaceloop1-save"); if (gameDataString == null) { // No save file! let's start at the beginning. getCurrentView(); return; } userData = JSON.parse(gameDataString); migrateVersion(userData); getCurrentView(); } function migrateVersion(oldUserData) { //TODO: check save file version, adjust as needed } function setFlag(flag) { if (!userData.enabled.find(enabledFlag => enabledFlag == flag)) { userData.enabled.push(flag); } } function clearFlag(flag) { let index = userData.enabled.findIndex(enabledFlag => enabledFlag == flag); if (index != -1) { userData.enabled.splice(index, 1); } } function isFlagEnabled(flag) { return !!userData.enabled.find(enabledFlag => enabledFlag == flag); }