|
@@ -17,7 +17,7 @@ import cauldronFragment from './shaders/cauldron/fragment.glsl'
|
|
|
|
|
|
// UI
|
|
// UI
|
|
import { brewTutorialPrompt, closeMainMenuUI, mainMenuUI, openMainMenuUI } from './ui/mainmenuui.js'
|
|
import { brewTutorialPrompt, closeMainMenuUI, mainMenuUI, openMainMenuUI } from './ui/mainmenuui.js'
|
|
-import { brewUI, openBrewUI, closeBrewUI } from './ui/gameui.js'
|
|
|
|
|
|
+import { brewUI, openBrewUI, closeBrewUI, updateIngredients } from './ui/gameui.js'
|
|
import { closeShopUI, openShopUI, shopTutorialPrompt, shopUI } from './ui/shopui.js'
|
|
import { closeShopUI, openShopUI, shopTutorialPrompt, shopUI } from './ui/shopui.js'
|
|
import { navigationUI, hideNavigationUI, nextRoom, previousRoom } from './ui/navigationui.js'
|
|
import { navigationUI, hideNavigationUI, nextRoom, previousRoom } from './ui/navigationui.js'
|
|
|
|
|
|
@@ -29,6 +29,7 @@ import Shopper from './shopper.js'
|
|
import { buildCanvasText } from './library/canvastext.js'
|
|
import { buildCanvasText } from './library/canvastext.js'
|
|
import { hideGameStatusUI, updateGameStatusUI } from './ui/gamestatusui.js'
|
|
import { hideGameStatusUI, updateGameStatusUI } from './ui/gamestatusui.js'
|
|
import { gameOverUI, showGameOverUI } from './ui/gameoverui.js'
|
|
import { gameOverUI, showGameOverUI } from './ui/gameoverui.js'
|
|
|
|
+import { closeMarketUI, marketUI, openMarketUI } from './ui/marketui.js'
|
|
|
|
|
|
export const GAME_SAVE_KEY = "spookonomics-v1"
|
|
export const GAME_SAVE_KEY = "spookonomics-v1"
|
|
const raycast = new THREE.Raycaster()
|
|
const raycast = new THREE.Raycaster()
|
|
@@ -78,6 +79,14 @@ async function beginBrew(game, stageData) {
|
|
stageData.soundEffects['audio/witch_cackle1.ogg'].play()
|
|
stageData.soundEffects['audio/witch_cackle1.ogg'].play()
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+ const newInventory = [...stageData.ingredientInventory]
|
|
|
|
+ newInventory.remove(stageData.selectedIngredients[0])
|
|
|
|
+ newInventory.remove(stageData.selectedIngredients[1])
|
|
|
|
+
|
|
|
|
+ if(stageData.ingredientInventory.length - newInventory.length < 2) {
|
|
|
|
+ stageData.soundEffects['audio/witch_cackle1.ogg'].play()
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
|
|
stageData.cauldron.isBrewing = true
|
|
stageData.cauldron.isBrewing = true
|
|
|
|
|
|
@@ -95,8 +104,6 @@ async function beginBrew(game, stageData) {
|
|
stageData.bottle1.position.y = -1.5
|
|
stageData.bottle1.position.y = -1.5
|
|
game.scene.add(stageData.bottle1)
|
|
game.scene.add(stageData.bottle1)
|
|
|
|
|
|
- stageData.selectedIngredients = []
|
|
|
|
-
|
|
|
|
stageData.soundEffects['audio/click1.ogg'].play()
|
|
stageData.soundEffects['audio/click1.ogg'].play()
|
|
|
|
|
|
const nextColorData = stageData.potionToBrew.color
|
|
const nextColorData = stageData.potionToBrew.color
|
|
@@ -118,6 +125,8 @@ async function beginBrew(game, stageData) {
|
|
|
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
addValueToSave(stageData.potionInventory, 'potion-inventory', stageData.potionToBrew.name)
|
|
addValueToSave(stageData.potionInventory, 'potion-inventory', stageData.potionToBrew.name)
|
|
|
|
+ removeValueFromSave(stageData.ingredientInventory, 'ingredient-inventory', stageData.selectedIngredients[0])
|
|
|
|
+ removeValueFromSave(stageData.ingredientInventory, 'ingredient-inventory', stageData.selectedIngredients[1])
|
|
stageData.potionToBrew = null
|
|
stageData.potionToBrew = null
|
|
stageData.selectedIngredients = []
|
|
stageData.selectedIngredients = []
|
|
|
|
|
|
@@ -128,6 +137,8 @@ async function beginBrew(game, stageData) {
|
|
stageData.spoon.visible = false
|
|
stageData.spoon.visible = false
|
|
stageData.bubbleParticles.visible = false
|
|
stageData.bubbleParticles.visible = false
|
|
|
|
|
|
|
|
+ updateIngredients(game, stageData)
|
|
|
|
+
|
|
gsap.to(stageData.bottle1.position, {
|
|
gsap.to(stageData.bottle1.position, {
|
|
duration: 3, y: 1.5, ease: "elastic", onComplete: () => {
|
|
duration: 3, y: 1.5, ease: "elastic", onComplete: () => {
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
@@ -268,16 +279,22 @@ export function removeValueFromSave(container, key, value) {
|
|
export function clearSaveData(stageData) {
|
|
export function clearSaveData(stageData) {
|
|
localStorage.removeItem(`${GAME_SAVE_KEY}-potion-inventory`)
|
|
localStorage.removeItem(`${GAME_SAVE_KEY}-potion-inventory`)
|
|
localStorage.removeItem(`${GAME_SAVE_KEY}-potion-stocked`)
|
|
localStorage.removeItem(`${GAME_SAVE_KEY}-potion-stocked`)
|
|
- localStorage.setItem(`${GAME_SAVE_KEY}-potion-inventory`, JSON.stringify([]))
|
|
|
|
stageData.potionInventory = []
|
|
stageData.potionInventory = []
|
|
- localStorage.setItem(`${GAME_SAVE_KEY}-potion-stocked`, JSON.stringify([]))
|
|
|
|
|
|
+ localStorage.setItem(`${GAME_SAVE_KEY}-potion-inventory`, JSON.stringify(stageData.potionInventory))
|
|
stageData.potionStocked = []
|
|
stageData.potionStocked = []
|
|
-
|
|
|
|
|
|
+ localStorage.setItem(`${GAME_SAVE_KEY}-potion-stocked`, JSON.stringify(stageData.potionStocked))
|
|
|
|
+
|
|
stageData.currency = 100
|
|
stageData.currency = 100
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currency`, stageData.currency)
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currency`, stageData.currency)
|
|
|
|
|
|
stageData.currentDay = 1
|
|
stageData.currentDay = 1
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currentday`, stageData.currentDay)
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currentday`, stageData.currentDay)
|
|
|
|
+
|
|
|
|
+ stageData.cartItems = []
|
|
|
|
+
|
|
|
|
+ stageData.ingredientInventory = ["mushroom", "mushroom", "pumpkin", "tomato", "tomato", "lettuce", "lettuce"]
|
|
|
|
+ localStorage.setItem(`${GAME_SAVE_KEY}-ingredient-inventory`, JSON.stringify(stageData.ingredientInventory))
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
export function loadSaveData(stageData) {
|
|
export function loadSaveData(stageData) {
|
|
@@ -310,6 +327,32 @@ export function loadSaveData(stageData) {
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currentday`, 1)
|
|
localStorage.setItem(`${GAME_SAVE_KEY}-currentday`, 1)
|
|
stageData.currentDay = 1
|
|
stageData.currentDay = 1
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ let ingredientInventoryString = localStorage.getItem(`${GAME_SAVE_KEY}-ingredient-inventory`)
|
|
|
|
+ if (!ingredientInventoryString) {
|
|
|
|
+ localStorage.setItem(`${GAME_SAVE_KEY}-ingredient-inventory`, JSON.stringify([]))
|
|
|
|
+ stageData.ingredientInventory = []
|
|
|
|
+ } else {
|
|
|
|
+ stageData.ingredientInventory = JSON.parse(ingredientInventoryString)
|
|
|
|
+ stageData.ingredientInventory.sort()
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function buyIngredients(game, stageData) {
|
|
|
|
+ let amountToDeduct = 0
|
|
|
|
+ stageData.cartItems.forEach(item => {
|
|
|
|
+ amountToDeduct += stageData.ingredientInfo[item].cost
|
|
|
|
+ addValueToSave(stageData.ingredientInventory, "ingredient-inventory", item)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ stageData.currency = addAmountToSave("currency", -amountToDeduct)
|
|
|
|
+
|
|
|
|
+ if(amountToDeduct > 0) {
|
|
|
|
+ stageData.soundEffects['audio/cash-register.ogg'].play()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ updateGameStatusUI(game, stageData)
|
|
|
|
+ closeMarketUI(game, stageData)
|
|
}
|
|
}
|
|
|
|
|
|
export async function init(inGame) {
|
|
export async function init(inGame) {
|
|
@@ -321,6 +364,7 @@ export async function init(inGame) {
|
|
stageData.soundEffects = soundEffects
|
|
stageData.soundEffects = soundEffects
|
|
|
|
|
|
stageData.selectedIngredients = []
|
|
stageData.selectedIngredients = []
|
|
|
|
+ stageData.cartItems = []
|
|
|
|
|
|
stageData.cameraPositions = [
|
|
stageData.cameraPositions = [
|
|
{ "camera": new THREE.Vector3(-15, 5, 7), "focus": new THREE.Vector3(-13, 0.1, 0) },
|
|
{ "camera": new THREE.Vector3(-15, 5, 7), "focus": new THREE.Vector3(-13, 0.1, 0) },
|
|
@@ -359,8 +403,16 @@ export async function init(inGame) {
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+ stageData.musicLoop = new Howl({
|
|
|
|
+ src: ['audio/Vampires LOOP (All Instruments).ogg'],
|
|
|
|
+ preload: true,
|
|
|
|
+ loop: true,
|
|
|
|
+ volume: 0.5
|
|
|
|
+ })
|
|
|
|
+
|
|
soundEffects['audio/doorClose_4.ogg'].volume(0.5)
|
|
soundEffects['audio/doorClose_4.ogg'].volume(0.5)
|
|
soundEffects['audio/doorOpen_1.ogg'].volume(0.5)
|
|
soundEffects['audio/doorOpen_1.ogg'].volume(0.5)
|
|
|
|
+ stageData.soundEffects['audio/store-entrance-bell.ogg'].volume(0.5)
|
|
|
|
|
|
let levelLoader = new LevelLoader(game)
|
|
let levelLoader = new LevelLoader(game)
|
|
|
|
|
|
@@ -645,26 +697,26 @@ export async function init(inGame) {
|
|
game.entities.push(stageData.sign)
|
|
game.entities.push(stageData.sign)
|
|
game.scene.add(stageData.sign)
|
|
game.scene.add(stageData.sign)
|
|
|
|
|
|
- const mushroomCrate = await loadGltf(game, 'models/crate_mushrooms.gltf')
|
|
|
|
- mushroomCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
- mushroomCrate.position.x = 19.5
|
|
|
|
- mushroomCrate.position.z = 0.5
|
|
|
|
- mushroomCrate.rotateOnAxis(THREE.Object3D.DEFAULT_UP, Math.PI / 4)
|
|
|
|
- game.entities.push(mushroomCrate)
|
|
|
|
- game.scene.add(mushroomCrate)
|
|
|
|
-
|
|
|
|
- const tomatoCrate = await loadGltf(game, 'models/crate_tomatoes.gltf')
|
|
|
|
- tomatoCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
- tomatoCrate.position.x = 21
|
|
|
|
- game.entities.push(tomatoCrate)
|
|
|
|
- game.scene.add(tomatoCrate)
|
|
|
|
-
|
|
|
|
- const lettuceCrate = await loadGltf(game, 'models/crate_lettuce.gltf')
|
|
|
|
- lettuceCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
- lettuceCrate.position.x = 18.5
|
|
|
|
- lettuceCrate.position.z = -0.5
|
|
|
|
- game.entities.push(lettuceCrate)
|
|
|
|
- game.scene.add(lettuceCrate)
|
|
|
|
|
|
+ stageData.mushroomCrate = await loadGltf(game, 'models/crate_mushrooms.gltf')
|
|
|
|
+ stageData.mushroomCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
+ stageData.mushroomCrate.position.x = 19.5
|
|
|
|
+ stageData.mushroomCrate.position.z = 0.5
|
|
|
|
+ stageData.mushroomCrate.rotateOnAxis(THREE.Object3D.DEFAULT_UP, Math.PI / 4)
|
|
|
|
+ game.entities.push(stageData.mushroomCrate)
|
|
|
|
+ game.scene.add(stageData.mushroomCrate)
|
|
|
|
+
|
|
|
|
+ stageData.tomatoCrate = await loadGltf(game, 'models/crate_tomatoes.gltf')
|
|
|
|
+ stageData.tomatoCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
+ stageData.tomatoCrate.position.x = 21
|
|
|
|
+ game.entities.push(stageData.tomatoCrate)
|
|
|
|
+ game.scene.add(stageData.tomatoCrate)
|
|
|
|
+
|
|
|
|
+ stageData.lettuceCrate = await loadGltf(game, 'models/crate_lettuce.gltf')
|
|
|
|
+ stageData.lettuceCrate.scale.set(0.5, 0.5, 0.5)
|
|
|
|
+ stageData.lettuceCrate.position.x = 18.5
|
|
|
|
+ stageData.lettuceCrate.position.z = -0.5
|
|
|
|
+ game.entities.push(stageData.lettuceCrate)
|
|
|
|
+ game.scene.add(stageData.lettuceCrate)
|
|
|
|
|
|
const coffin = await loadGltf(game, 'models/coffin_decorated.gltf')
|
|
const coffin = await loadGltf(game, 'models/coffin_decorated.gltf')
|
|
coffin.position.x = 23
|
|
coffin.position.x = 23
|
|
@@ -761,6 +813,7 @@ export async function init(inGame) {
|
|
navigationUI(game, stageData)
|
|
navigationUI(game, stageData)
|
|
brewUI(game, stageData)
|
|
brewUI(game, stageData)
|
|
shopUI(game, stageData)
|
|
shopUI(game, stageData)
|
|
|
|
+ marketUI(game, stageData)
|
|
gameOverUI(game, stageData)
|
|
gameOverUI(game, stageData)
|
|
|
|
|
|
updateGameStatusUI(game, stageData)
|
|
updateGameStatusUI(game, stageData)
|
|
@@ -768,6 +821,7 @@ export async function init(inGame) {
|
|
|
|
|
|
stageData.beginBrew = () => { beginBrew(game, stageData) }
|
|
stageData.beginBrew = () => { beginBrew(game, stageData) }
|
|
stageData.beginSell = () => { beginSell(game, stageData) }
|
|
stageData.beginSell = () => { beginSell(game, stageData) }
|
|
|
|
+ stageData.buyIngredients = () => { buyIngredients(game, stageData)}
|
|
|
|
|
|
|
|
|
|
///////////
|
|
///////////
|
|
@@ -1155,6 +1209,22 @@ export function onClick() {
|
|
|
|
|
|
if (isAChildOf(stageData.sign, intersect.object)) {
|
|
if (isAChildOf(stageData.sign, intersect.object)) {
|
|
previousRoom(game, stageData)
|
|
previousRoom(game, stageData)
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(isAChildOf(stageData.mushroomCrate, intersect.object) ||
|
|
|
|
+ isAChildOf(stageData.lettuceCrate, intersect.object) ||
|
|
|
|
+ isAChildOf(stageData.tomatoCrate, intersect.object) ||
|
|
|
|
+ isAChildOf(stageData.sellingSkeleton, intersect.object) ||
|
|
|
|
+ isAChildOf(stageData.marketWitch, intersect.object)
|
|
|
|
+ ) {
|
|
|
|
+
|
|
|
|
+ if (stageData.sellingSkeleton.marketMenuOpen) {
|
|
|
|
+ closeMarketUI(game, stageData)
|
|
|
|
+ } else {
|
|
|
|
+ openMarketUI(game, stageData)
|
|
|
|
+ }
|
|
|
|
+ return false
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -1193,7 +1263,7 @@ function nextCustomer() {
|
|
const customerMotionPath = [{ x: -11, y: 0.1, z: 3 }, { x: -8, y: 0.1, z: 3 }, { x: -4, y: 0.1, z: 10 }]
|
|
const customerMotionPath = [{ x: -11, y: 0.1, z: 3 }, { x: -8, y: 0.1, z: 3 }, { x: -4, y: 0.1, z: 10 }]
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
stageData.soundEffects['audio/store-entrance-bell.ogg'].play()
|
|
stageData.soundEffects['audio/store-entrance-bell.ogg'].play()
|
|
- }, 4000)
|
|
|
|
|
|
+ }, 3000)
|
|
gsap.to(firstCustomer.object3d.position, {
|
|
gsap.to(firstCustomer.object3d.position, {
|
|
duration: 8, motionPath: customerMotionPath, onComplete: () => {
|
|
duration: 8, motionPath: customerMotionPath, onComplete: () => {
|
|
game.scene.remove(firstCustomer.object3d)
|
|
game.scene.remove(firstCustomer.object3d)
|