Created
November 2, 2022 02:40
-
-
Save Cipa/daf37090d9f6f7e756f29d3d60d9234c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="hero min-h-screen bg-base-200" v-show="game.state === 0"> | |
<div class="text-center hero-content"> | |
<div class="max-w-md"> | |
<h1 class="mb-5 text-5xl font-bold"> | |
Hello {{ player.name || "Player" }} | |
</h1> | |
<p class="mb-5">Do you want to play?</p> | |
<div class="form-control pb-8"> | |
<input | |
type="text" | |
placeholder="Your Name" | |
class="input input-primary input-bordered pb-1" | |
v-model="player.name" | |
/> | |
</div> | |
<button | |
class="btn btn-primary" | |
@click="showRoom(1)" | |
:disabled="player.name.length <= 0" | |
> | |
Get Started | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- <button @click="updatePlayer()" class="btn btn-primary"> | |
Test Update inventory | |
</button> --> | |
<div | |
class="navbar mb-2 shadow-lg bg-neutral text-neutral-content rounded-box" | |
v-show="game.state === 1" | |
> | |
<div class="flex-1 px-2 mx-2"> | |
<span class="text-lg font-bold"> | |
{{ player.name }} | |
</span> | |
</div> | |
<div class="flex-none hidden px-2 mx-2 lg:flex"> | |
<div class="flex items-stretch"> | |
<a class="btn btn-ghost btn-sm rounded-btn"> | |
Might: {{ player.might }} | |
</a> | |
</div> | |
</div> | |
<div class="flex-none hidden px-2 mx-2 lg:flex"> | |
<div class="flex items-stretch"> | |
<a class="btn btn-ghost btn-sm rounded-btn"> | |
Endurance: {{ player.endurance }} | |
</a> | |
</div> | |
</div> | |
</div> | |
<div class="flex justify-center" v-show="game.state === 1"> | |
<div class="card lg:card-side bordered w-11/12"> | |
<div class="card-body"> | |
<h2 class="card-title">{{ game.room.name }}</h2> | |
<div v-html="parseHtml(game.room.desc)"></div> | |
<div | |
class="card-actions" | |
v-if="game.room.oponent && game.room.oponent.endurance > 0" | |
> | |
<button class="btn btn-primary" @click="fight()"> | |
Fight {{ game.room.oponent.name }} | |
</button> | |
<div v-if="dice.dice1 && dice.dice2"> | |
You rolled {{ dice.dice1 }} & {{ dice.dice2 }} | |
</div> | |
</div> | |
<div class="card-actions"> | |
<button | |
v-for="(action, index) in game.room.actions" | |
:key="index" | |
@click="onActionClick(action)" | |
class="btn btn-primary" | |
:disabled="isButtonDisabled(index)" | |
> | |
{{ action.desc }} | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="w-11/12 mx-auto my-4" v-show="game.state === 1"> | |
<template v-for="item in player.inventory" :key="item.name"> | |
<button class="btn btn-sm mx-px my-px"> | |
{{ item.name }} | |
<div class="badge ml-2">{{ item.qty }}</div> | |
</button> | |
</template> | |
</div> | |
</template> | |
<script lang="ts"> | |
import { | |
computed, | |
defineComponent, | |
reactive, | |
ref, | |
toRaw, | |
toRef, | |
toRefs, | |
watch, | |
} from "vue"; | |
import "./assets/tailwind.css"; | |
import ForerunnerDB from "forerunnerdb"; | |
import vesselJson from "./assets/json/vessel.json"; | |
import playerJson from "./assets/json/_player.json"; | |
import Room from "./types/Room"; | |
import Query from "./types/Query"; | |
import { get as _get } from "lodash"; | |
import Player from "./types/Player"; | |
import Action from "./types/Action"; | |
import updatePlayerInventory from "./composables/updatePlayerInventory"; | |
import InventoryItem from "./types/InventoryItem"; | |
export default defineComponent({ | |
name: "App", | |
components: { | |
// RoomComponent, | |
}, | |
setup(_, context) { | |
const fdb = new ForerunnerDB(); | |
const db = fdb.db("game"); | |
const playerCollection = db.collection("player", { | |
capped: true, | |
size: 1, | |
}); | |
playerCollection.insert(playerJson); | |
const mapCollection = db.collection("vessel"); | |
mapCollection.insert(vesselJson); | |
let game = reactive({ state: 0, room: {} as Room }); | |
let player = reactive(playerCollection.findById(1) as Player); | |
let dice = reactive({ dice1: 0, dice2: 0 }); | |
const playerName = ref(""); | |
// showRoom(7); | |
// console.log(context.root); | |
function isButtonDisabled(optionIdx: number) { | |
let { location, desc, activeWhen, onClick } = | |
game.room.actions[optionIdx]; | |
if (!activeWhen) return false; | |
//posible future update, accept an or, currently we loop an array and exit on first false condition | |
let disableIt = false; | |
(activeWhen as Query[]).every((aw: Query) => { | |
let active: boolean; | |
if (aw.collection === "room") { | |
//TODO: use a switch case | |
active = !!mapCollection.count({ _id: game.room._id, ...aw.query }); | |
} else { | |
//probably player | |
active = !!playerCollection.count(aw.query); | |
} | |
if (!active) { | |
disableIt = true; | |
return false; | |
} | |
}); | |
if (disableIt) return true; | |
return false; | |
} | |
function onActionClick(action: Action) { | |
//detect what happens on click | |
//run click queries, wait for them to finish then either reload the room, go to a new room or go to a new map | |
console.log("action"); | |
console.log(action); | |
if (action.onClick) { | |
console.log("action.onClick"); | |
console.log(action.onClick); | |
console.log(action.onClick.length); | |
for (const queryDetails of action.onClick as Query[]) { | |
// console.log("q"); | |
// console.log(q); | |
// } | |
// (action.onClick as Query[]).every((queryDetails: Query, index) => { | |
// console.log("queryDetails-------", index); | |
console.log(queryDetails); | |
//custom actions | |
if ( | |
["updatePlayerInventory"].some((val) => val === queryDetails.action) | |
) { | |
//custom/built functionality | |
console.log("called"); | |
console.log("after called"); | |
switch (queryDetails.action) { | |
case "updatePlayerInventory": | |
//can I call this dinamycally at some point in the future | |
console.log("updatePlayerInventory------"); | |
player.inventory = updatePlayerInventory( | |
playerCollection, | |
queryDetails.data as InventoryItem[] | |
); | |
break; | |
default: | |
console.error("No custom method defined"); | |
break; | |
} | |
} else { | |
switch (queryDetails.collection) { | |
case "player": | |
console.error("No action for player collection defined"); | |
break; | |
case "room": | |
//on click we ussualy do update or delete, no support for delete now | |
console.log("update room"); | |
mapCollection.update(queryDetails.query, queryDetails.data); | |
game.room = mapCollection.findById(game.room._id) as Room; | |
break; | |
default: | |
console.error("No collection with that name"); | |
break; | |
} | |
} | |
} | |
// }); | |
} | |
console.log("onOutClick", action.location); | |
showRoom(action.location); //0 because roomId can be the map string, or id meens room and string means map | |
} | |
function showRoom(location: number | string) { | |
if (!player.name) { | |
playerCollection.update( | |
{}, | |
{ | |
name: playerName, | |
} | |
); | |
player.name = (playerCollection.findById(1) as Player).name; | |
} | |
game.state = 1; | |
game.room = mapCollection.findById(location); | |
} | |
function parseHtml(html = "") { | |
const expose = { | |
player, | |
room: game.room, | |
}; | |
return html.replace(/{{(.+?)}}/g, (_, g) => { | |
return _get(expose, g); | |
}); | |
} | |
function fight() { | |
const dice1 = 1 + Math.floor(Math.random() * 6); | |
const dice2 = 1 + Math.floor(Math.random() * 6); | |
// const dice1 = 1; | |
// const dice2 = 1; | |
dice.dice1 = dice1; | |
dice.dice2 = dice2; | |
const diceTotal = dice1 + dice2; | |
//maybe do this with reactivity or some events in forerunner | |
if (diceTotal + player.might < game.room.oponent.might) { | |
playerCollection.update( | |
{}, | |
{ | |
endurance: | |
player.endurance + | |
(diceTotal + player.might - game.room.oponent.might), | |
} | |
); | |
} else if (diceTotal + player.might > game.room.oponent.might) { | |
mapCollection.update( | |
{ _id: game.room._id }, | |
{ | |
oponent: { | |
endurance: | |
game.room.oponent.endurance - | |
(diceTotal + player.might - game.room.oponent.might), | |
}, | |
} | |
); | |
} else { | |
playerCollection.update({}, { endurance: player.endurance - 1 }); | |
mapCollection.update( | |
{ _id: game.room._id }, | |
{ oponent: { endurance: game.room.oponent.endurance - 1 } } | |
); | |
} | |
//reload collections, if you want to reload the whole thing use Object.assign | |
// Object.assign(player, playerCollection.findById(1) as Player); | |
player.endurance = (playerCollection.findById(1) as Player).endurance; | |
game.room = mapCollection.findById(game.room._id) as Room; | |
} | |
return { | |
game, | |
player, | |
dice, | |
parseHtml, | |
isButtonDisabled, | |
onActionClick, | |
fight, | |
showRoom, | |
playerName, | |
// updatePlayer, | |
}; | |
}, | |
}); | |
</script> | |
<style> | |
</style> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment