-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
349 additions
and
3 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { defineStore } from 'pinia' | ||
import { useGameStore } from '@/stores/gameStore' | ||
|
||
export const useTunnelStore = defineStore('tunnelStore', { | ||
state: () => ({ | ||
antsInTunnel: 0, // Current ants in tunnel | ||
initialAntsInTunnel: 0, // Ants at the start of exploration | ||
tunnelDepth: 0, | ||
tunnelProgress: 0, // Progress towards next depth point | ||
depthBoost: 0, // Boost for initial depth scaling | ||
resourcesFound: { | ||
seeds: 0, | ||
mineralShards: 0, // New resource for tunnel upgrades | ||
}, | ||
trapsEncountered: 0, | ||
lootFound: [], // Loot added to the player's inventory | ||
activeUpgrades: [], // Tunnel-related upgrades | ||
autoTunnelActive: false, // Whether the tunnel exploration is auto-running | ||
tunnelSpeedMultiplier: 1, // Affects speed of digging | ||
animationFrameId: 0, // ID for managing animation frames | ||
}), | ||
|
||
getters: { | ||
progressToNextDepth(state) { | ||
return Math.min(state.tunnelProgress / 100, 1) | ||
}, | ||
getAvailableAnts() { | ||
const gameStore = useGameStore() | ||
return gameStore.resources.ants | ||
}, | ||
}, | ||
|
||
actions: { | ||
// Start the tunnel exploration | ||
startTunnelExploration(antsToSend: number) { | ||
if (this.antsInTunnel > 0) return // Prevent sending more ants if the tunnel is active | ||
|
||
this.antsInTunnel = antsToSend | ||
this.initialAntsInTunnel = antsToSend // Store the starting number of ants | ||
|
||
// **New Calculation**: Linear-Logarithmic scaling for initial depth | ||
const linearFactor = this.initialAntsInTunnel * 0.00001 // Linear boost for every ant sent | ||
const logFactor = Math.log10(this.initialAntsInTunnel + 10) // Logarithmic component to maintain balance | ||
this.depthBoost = linearFactor + logFactor // Combine linear and log scaling | ||
this.tunnelDepth = 0 | ||
this.tunnelProgress = 0 | ||
this.autoTunnelActive = true // Set auto mode | ||
|
||
this.runTunnelLoop(performance.now()) // Start the loop | ||
}, | ||
|
||
// Main tunnel loop to run exploration and events | ||
runTunnelLoop(timestamp: number) { | ||
if (this.antsInTunnel <= 0 || !this.autoTunnelActive) return | ||
|
||
// Process ants in batches for better performance | ||
const batchSize = Math.max(10, Math.min(1000, this.antsInTunnel)) // Process at least 10 ants or up to 1000 | ||
const progressGain = Math.log(batchSize) * 0.2 * this.tunnelSpeedMultiplier // Logarithmic scaling for progress | ||
this.tunnelProgress += progressGain | ||
|
||
// Check if we've reached the next depth point | ||
if (this.tunnelProgress >= 100) { | ||
this.tunnelDepth += 1 | ||
this.tunnelProgress = 0 | ||
|
||
// Handle events (find resources, encounter traps, etc.) | ||
this.triggerTunnelEvent() | ||
} | ||
|
||
// Continue the loop using requestAnimationFrame | ||
if (this.antsInTunnel > 0) { | ||
this.animationFrameId = requestAnimationFrame(this.runTunnelLoop) | ||
} else { | ||
console.log('Tunnel exploration complete.') | ||
this.stopTunnelExploration() // Stop if no ants remain | ||
} | ||
}, | ||
|
||
// Stop the tunnel exploration | ||
stopTunnelExploration() { | ||
this.autoTunnelActive = false | ||
cancelAnimationFrame(this.animationFrameId) | ||
this.antsInTunnel = 0 | ||
console.log('Tunnel exploration stopped.') | ||
}, | ||
|
||
// Handle random events (resources, traps, loot) | ||
triggerTunnelEvent() { | ||
const eventChance = Math.random() | ||
|
||
// Adjust depth multiplier to scale logarithmically for better control at higher depths | ||
const depthMultiplier = Math.log2(this.tunnelDepth + 2) // Logarithmic scaling: log2(depth + 2) | ||
|
||
// Scale event rewards based on the initial number of ants sent | ||
const antMultiplier = Math.pow(this.initialAntsInTunnel, 0.25) // Use a 0.25 power scale for rewards and event intensity | ||
|
||
// Trap chance scaling slower, maxing at 50% but taking more depth to reach there | ||
const trapChance = Math.min(0.2 + this.tunnelDepth * 0.01, 0.5) // Max out at 0.5 but slower scaling per depth | ||
|
||
if (eventChance < 0.3) { | ||
// Find resources (seeds or mineral shards) | ||
const seedsFound = Math.floor((Math.random() * 50 + 10) * depthMultiplier * antMultiplier) | ||
const shardsFound = Math.floor((Math.random() * 5 + 1) * depthMultiplier * antMultiplier) | ||
|
||
this.resourcesFound.seeds += seedsFound | ||
this.resourcesFound.mineralShards += shardsFound | ||
} else if (eventChance < trapChance) { | ||
if (this.tunnelDepth < this.depthBoost) return // Prevent traps at the start (linear boost) | ||
|
||
// Calculate percentage loss based on depth | ||
const baseLossPercentage = 0.05 // Base 5% loss | ||
const maxLossPercentage = 0.3 // Max 30% loss at very deep levels | ||
const depthFactor = Math.log2(this.tunnelDepth + 2) / 10 // Scale the depth factor logarithmically | ||
const percentageLost = Math.min(baseLossPercentage + depthFactor, maxLossPercentage) // Ensure it doesn’t exceed max loss | ||
|
||
const antsLost = Math.floor(this.initialAntsInTunnel * percentageLost) | ||
|
||
this.antsInTunnel = Math.max(0, this.antsInTunnel - antsLost) | ||
this.trapsEncountered += 1 | ||
} else { | ||
// Find better loot in deeper tunnels, loot value scaling with depth and ant group size | ||
const lootValue = Math.floor((Math.random() * 100 + 50) * depthMultiplier * antMultiplier) | ||
const loot = { name: 'Rare Artifact', value: lootValue } | ||
|
||
this.lootFound.push(loot) | ||
} | ||
}, | ||
|
||
// Reset tunnel data | ||
resetTunnel() { | ||
this.antsInTunnel = 0 | ||
this.initialAntsInTunnel = 0 // Reset the initial ants as well | ||
this.tunnelDepth = 0 | ||
this.tunnelProgress = 0 | ||
this.resourcesFound = { seeds: 0, mineralShards: 0 } | ||
this.trapsEncountered = 0 | ||
this.lootFound = [] | ||
this.autoTunnelActive = false | ||
cancelAnimationFrame(this.animationFrameId) | ||
console.log('Tunnel progress reset.') | ||
}, | ||
}, | ||
}) |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
<template> | ||
<div class="p-6 bg-gradient-to-br from-gray-800 to-gray-900 text-white rounded-lg shadow-lg space-y-6"> | ||
<div class="text-center"> | ||
<p> | ||
Note: this feature does not work yet. | ||
<br> | ||
You can play around with the slider and start the exploration to get an idea of how it would look like. | ||
<br> | ||
This is just a UI to show how it would look like. The actual implementation is not done. | ||
</p> | ||
</div> | ||
<!-- Title and Tunnel Info --> | ||
<div class="text-center"> | ||
<h1 class="text-2xl font-bold text-yellow-300 mb-1"> | ||
Ant Tunnel Exploration | ||
</h1> | ||
<p class="text-sm text-gray-300"> | ||
Send your ants deep into the tunnels to discover resources, loot, and dangers! | ||
</p> | ||
</div> | ||
|
||
<!-- Ants sent and progress section --> | ||
<div class="flex flex-col items-center space-y-4"> | ||
<div class="flex items-center space-x-4"> | ||
<p class="text-base font-semibold text-yellow-400"> | ||
Ants in Tunnels: <strong>{{ formatNumber(antsInTunnel, 0) }}</strong> | ||
</p> | ||
<button | ||
v-if="antsInTunnel > 0" | ||
class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg shadow-lg text-sm font-medium transition-all duration-300" | ||
@click="stopTunnelExploration" | ||
> | ||
Stop Exploration | ||
</button> | ||
</div> | ||
|
||
<!-- Tunnel Progress Bar --> | ||
<div class="relative w-full bg-gray-700 rounded-full h-4 shadow-inner"> | ||
<div | ||
class="absolute top-0 left-0 bg-green-500 h-full rounded-full" | ||
:style="{ width: (progressToNextDepth * 100) + '%' }" | ||
/> | ||
</div> | ||
<p class="text-sm text-gray-300"> | ||
Depth: <span class="font-semibold text-green-400">{{ tunnelDepth }}</span> | ||
</p> | ||
</div> | ||
|
||
<!-- Slider for selecting ants to send --> | ||
<div class="flex flex-col items-center space-y-2"> | ||
<label | ||
for="ants-slider" | ||
class="text-base font-semibold text-gray-300" | ||
>Select the number of ants to send:</label> | ||
<input | ||
id="ants-slider" | ||
v-model="selectedAnts" | ||
type="range" | ||
:min="10" | ||
:max="availableAnts" | ||
:step="getSteps" | ||
class="w-full slider" | ||
> | ||
<p class="text-sm text-gray-300"> | ||
Ants to send: <strong class="text-yellow-400">{{ formatNumber(selectedAnts, 0) }}</strong> | ||
</p> | ||
</div> | ||
|
||
<!-- Send button --> | ||
<div class="flex justify-center"> | ||
<button | ||
class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg shadow-md font-medium transition-all duration-300" | ||
:disabled="selectedAnts > availableAnts" | ||
@click="startTunnelExploration(selectedAnts)" | ||
> | ||
Start Digging | ||
</button> | ||
</div> | ||
|
||
<!-- Events section with scrollable box --> | ||
<div class="space-y-2"> | ||
<h2 class="text-lg font-bold text-yellow-400"> | ||
Events | ||
</h2> | ||
<p | ||
v-if="antsInTunnel <= 0" | ||
class="text-xs text-gray-400" | ||
> | ||
No ants in tunnels. Start exploration to find resources and face traps. | ||
</p> | ||
<div class="max-h-40 overflow-y-auto bg-gray-800 bg-opacity-50 rounded-lg p-3 space-y-2"> | ||
<ul class="list-disc list-inside text-sm text-gray-300"> | ||
<li | ||
v-if="resourcesFound.seeds > 0" | ||
class="text-green-400" | ||
> | ||
Found {{ resourcesFound.seeds }} seeds | ||
</li> | ||
<li | ||
v-if="resourcesFound.mineralShards > 0" | ||
class="text-blue-400" | ||
> | ||
Found {{ resourcesFound.mineralShards }} mineral shards | ||
</li> | ||
<li | ||
v-if="trapsEncountered > 0" | ||
class="text-red-400" | ||
> | ||
Encountered {{ trapsEncountered }} traps | ||
</li> | ||
<li | ||
v-for="(loot, index) in lootFound" | ||
:key="index" | ||
class="text-purple-400" | ||
> | ||
Found loot: {{ loot.name }} | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { useTunnelStore } from '@/stores/tunnelStore' | ||
import { storeToRefs } from 'pinia' | ||
import { ref, computed } from 'vue' | ||
import {useGameStore} from '@/stores/gameStore' | ||
const tunnelStore = useTunnelStore() | ||
const gameStore = useGameStore() | ||
const formatNumber = gameStore.formatNumber | ||
// Destructure state and actions | ||
const { | ||
antsInTunnel, | ||
tunnelDepth, | ||
progressToNextDepth, | ||
resourcesFound, | ||
trapsEncountered, | ||
lootFound, | ||
} = storeToRefs(tunnelStore) | ||
const { startTunnelExploration, stopTunnelExploration } = tunnelStore | ||
// Slider for selecting ants to send | ||
const selectedAnts = ref(10) | ||
const availableAnts = computed(() => tunnelStore.getAvailableAnts) // Assume there's a method that returns available ants | ||
const getSteps = computed(() => (availableAnts.value > 100 ? 10 : 1)) | ||
</script> | ||
|
||
<style scoped> | ||
/* Add slider styling */ | ||
.slider { | ||
-webkit-appearance: none; | ||
width: 100%; | ||
height: 10px; | ||
border-radius: 8px; | ||
background: #374151; | ||
outline: none; | ||
} | ||
.slider::-webkit-slider-thumb { | ||
-webkit-appearance: none; | ||
appearance: none; | ||
width: 24px; | ||
height: 24px; | ||
border-radius: 50%; | ||
background: #2563eb; | ||
cursor: pointer; | ||
} | ||
.slider::-moz-range-thumb { | ||
width: 24px; | ||
height: 24px; | ||
border-radius: 50%; | ||
background: #2563eb; | ||
cursor: pointer; | ||
} | ||
</style> |