Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8"/>
- <meta name="viewport" content="width=device-width,initial-scale=1"/>
- <title>Oracle Orbital Outpost — Prophetic Colony Survival</title>
- <style>
- :root {
- --space-black: #0a0614;
- --deep-purple: #1a0f3a;
- --oracle-glow: #9c4dc7;
- --warning-orange: #ff8c42;
- --danger-red: #ff3e41;
- --safe-blue: #42a5ff;
- --resource-green: #4cff88;
- --text-white: #e8e3ff;
- --panel-bg: rgba(20, 10, 40, 0.85);
- }
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
- body {
- font-family: 'Courier New', monospace;
- background: linear-gradient(180deg, var(--space-black) 0%, var(--deep-purple) 100%);
- color: var(--text-white);
- overflow: hidden;
- height: 100vh;
- position: relative;
- }
- #starfield {
- position: absolute;
- width: 100%;
- height: 100%;
- z-index: 1;
- }
- .star {
- position: absolute;
- background: white;
- border-radius: 50%;
- animation: twinkle 2s infinite;
- }
- @keyframes twinkle {
- 0%, 100% { opacity: 0.3; }
- 50% { opacity: 1; }
- }
- #gas-giant {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- width: 400px;
- height: 400px;
- border-radius: 50%;
- background: radial-gradient(circle at 30% 30%,
- #7a3d8f 0%,
- #4a2457 30%,
- #2a1435 60%,
- #150920 100%);
- box-shadow:
- 0 0 80px var(--oracle-glow),
- inset -20px -20px 40px rgba(0,0,0,0.5);
- z-index: 5;
- overflow: hidden;
- }
- .storm-band {
- position: absolute;
- width: 100%;
- height: 60px;
- background: linear-gradient(90deg,
- transparent,
- rgba(156, 77, 199, 0.3),
- rgba(255, 140, 66, 0.2),
- transparent);
- animation: rotate-band 20s linear infinite;
- }
- .storm-band:nth-child(1) { top: 20%; animation-duration: 25s; }
- .storm-band:nth-child(2) { top: 40%; animation-duration: 18s; animation-direction: reverse; }
- .storm-band:nth-child(3) { top: 60%; animation-duration: 22s; }
- @keyframes rotate-band {
- from { transform: translateX(-100%); }
- to { transform: translateX(100%); }
- }
- .storm-eye {
- position: absolute;
- border-radius: 50%;
- animation: pulse-storm 3s ease-in-out infinite;
- }
- @keyframes pulse-storm {
- 0%, 100% {
- opacity: 0.6;
- transform: scale(1);
- }
- 50% {
- opacity: 1;
- transform: scale(1.2);
- }
- }
- .orbital-object {
- position: absolute;
- left: 50%;
- top: 15%;
- transform: translateX(-50%);
- width: 120px;
- height: 40px;
- background: linear-gradient(90deg, #444, #666, #444);
- border: 2px solid var(--safe-blue);
- border-radius: 20px;
- z-index: 10;
- animation: orbit 60s linear infinite;
- transform-origin: center 250px;
- cursor: pointer;
- text-align: center;
- line-height: 40px;
- font-size: 12px;
- }
- @keyframes orbit {
- from { transform: translateX(-50%) rotate(0deg) translateY(-250px); }
- to { transform: translateX(-50%) rotate(360deg) translateY(-250px); }
- }
- #orbital-station {
- border-color: var(--safe-blue);
- }
- #gravitas-ship {
- border-color: var(--oracle-glow);
- animation-delay: -15s;
- }
- #novos-ship {
- border-color: var(--safe-blue);
- animation-delay: -30s;
- }
- #spectrometer-ship {
- border-color: var(--resource-green);
- animation-delay: -45s;
- }
- .module {
- position: absolute;
- width: 20px;
- height: 20px;
- background: #888;
- border: 1px solid var(--safe-blue);
- border-radius: 4px;
- }
- #control-panel {
- position: fixed;
- top: 20px;
- left: 20px;
- width: 320px;
- background: var(--panel-bg);
- border: 2px solid var(--oracle-glow);
- border-radius: 10px;
- padding: 20px;
- z-index: 100;
- backdrop-filter: blur(10px);
- }
- #resource-panel {
- position: fixed;
- top: 20px;
- right: 20px;
- width: 280px;
- background: var(--panel-bg);
- border: 2px solid var(--safe-blue);
- border-radius: 10px;
- padding: 20px;
- z-index: 100;
- backdrop-filter: blur(10px);
- }
- #prophecy-panel {
- position: fixed;
- bottom: 20px;
- left: 50%;
- transform: translateX(-50%);
- width: 600px;
- max-width: 90vw;
- background: var(--panel-bg);
- border: 2px solid var(--warning-orange);
- border-radius: 10px;
- padding: 20px;
- z-index: 100;
- backdrop-filter: blur(10px);
- }
- .panel-title {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 15px;
- text-transform: uppercase;
- letter-spacing: 2px;
- color: var(--oracle-glow);
- text-shadow: 0 0 10px currentColor;
- }
- .resource-item {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- padding: 8px;
- background: rgba(0,0,0,0.3);
- border-radius: 5px;
- border-left: 3px solid var(--resource-green);
- }
- .resource-value {
- font-weight: bold;
- color: var(--resource-green);
- }
- .storm-prediction {
- background: rgba(0,0,0,0.4);
- border-radius: 8px;
- padding: 15px;
- margin-bottom: 10px;
- border-left: 4px solid var(--warning-orange);
- position: relative;
- overflow: hidden;
- }
- .storm-prediction::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: linear-gradient(90deg, transparent, rgba(255,140,66,0.1), transparent);
- animation: scan 3s linear infinite;
- }
- @keyframes scan {
- from { transform: translateX(-100%); }
- to { transform: translateX(100%); }
- }
- .prophecy-timer {
- font-size: 24px;
- font-weight: bold;
- text-align: center;
- margin: 10px 0;
- color: var(--warning-orange);
- text-shadow: 0 0 20px currentColor;
- }
- button {
- background: linear-gradient(135deg, var(--oracle-glow), var(--deep-purple));
- color: white;
- border: none;
- padding: 10px 20px;
- margin: 5px;
- border-radius: 5px;
- cursor: pointer;
- font-family: inherit;
- font-weight: bold;
- text-transform: uppercase;
- transition: all 0.3s;
- box-shadow: 0 4px 10px rgba(156, 77, 199, 0.4);
- }
- button:hover {
- transform: translateY(-2px);
- box-shadow: 0 6px 15px rgba(156, 77, 199, 0.6);
- }
- button:active {
- transform: translateY(0);
- }
- button:disabled {
- opacity: 0.5;
- cursor: not-allowed;
- transform: none;
- }
- .defense-grid {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 10px;
- margin-top: 15px;
- }
- .defense-item {
- background: rgba(0,0,0,0.3);
- padding: 10px;
- border-radius: 5px;
- border: 1px solid var(--safe-blue);
- text-align: center;
- }
- .defense-level {
- font-size: 20px;
- font-weight: bold;
- color: var(--safe-blue);
- }
- #event-log {
- position: fixed;
- bottom: 20px;
- left: 20px;
- width: 300px;
- max-height: 200px;
- overflow-y: auto;
- background: var(--panel-bg);
- border: 1px solid var(--oracle-glow);
- border-radius: 5px;
- padding: 10px;
- z-index: 100;
- font-size: 12px;
- }
- .log-entry {
- margin-bottom: 5px;
- padding: 5px;
- border-left: 2px solid var(--safe-blue);
- padding-left: 10px;
- animation: fade-in 0.5s;
- }
- @keyframes fade-in {
- from {
- opacity: 0;
- transform: translateX(-20px);
- }
- to {
- opacity: 1;
- transform: translateX(0);
- }
- }
- .log-entry.warning { border-color: var(--warning-orange); }
- .log-entry.danger { border-color: var(--danger-red); }
- .log-entry.success { border-color: var(--resource-green); }
- #game-over {
- display: none;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: var(--panel-bg);
- border: 3px solid var(--danger-red);
- border-radius: 10px;
- padding: 40px;
- z-index: 1000;
- text-align: center;
- }
- .glowing-text {
- animation: glow 2s ease-in-out infinite;
- }
- @keyframes glow {
- 0%, 100% { text-shadow: 0 0 10px currentColor; }
- 50% { text-shadow: 0 0 20px currentColor, 0 0 30px currentColor; }
- }
- .hazard-indicator {
- position: absolute;
- width: 60px;
- height: 60px;
- border-radius: 50%;
- pointer-events: none;
- z-index: 50;
- }
- @keyframes asteroid-approach {
- from {
- transform: translate(-200%, -200%) scale(0.1);
- opacity: 0;
- }
- to {
- transform: translate(0, 0) scale(1);
- opacity: 1;
- }
- }
- @keyframes solar-flare {
- 0% {
- box-shadow: 0 0 20px var(--warning-orange);
- background: radial-gradient(circle, var(--warning-orange), transparent);
- }
- 50% {
- box-shadow: 0 0 40px var(--danger-red);
- background: radial-gradient(circle, var(--danger-red), transparent);
- }
- 100% {
- box-shadow: 0 0 20px var(--warning-orange);
- background: radial-gradient(circle, var(--warning-orange), transparent);
- }
- }
- .cosmic-warning {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- font-size: 48px;
- font-weight: bold;
- text-transform: uppercase;
- color: var(--danger-red);
- text-shadow: 0 0 30px currentColor;
- animation: flash-warning 0.5s ease-in-out 3;
- z-index: 200;
- pointer-events: none;
- }
- @keyframes flash-warning {
- 0%, 100% { opacity: 0; }
- 50% { opacity: 1; }
- }
- #ship-menu {
- display: none;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 400px;
- background: var(--panel-bg);
- border: 2px solid var(--safe-blue);
- border-radius: 10px;
- padding: 20px;
- z-index: 1000;
- backdrop-filter: blur(10px);
- text-align: center;
- }
- .close {
- position: absolute;
- top: 10px;
- right: 10px;
- font-size: 30px;
- cursor: pointer;
- color: var(--text-white);
- }
- .ship-actions {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 10px;
- margin-top: 15px;
- }
- </style>
- </head>
- <body>
- <canvas id="starfield"></canvas>
- <div id="gas-giant">
- <div class="storm-band"></div>
- <div class="storm-band"></div>
- <div class="storm-band"></div>
- </div>
- <div id="orbital-station" class="orbital-object">
- <div class="module" style="top: -10px; left: 10px;"></div>
- <div class="module" style="top: -10px; right: 10px;"></div>
- <div class="module" style="bottom: -10px; left: 30px;"></div>
- <div class="module" style="bottom: -10px; right: 30px;"></div>
- </div>
- <div id="gravitas-ship" class="orbital-object" onclick="game.openShipMenu('gravitas')">Gravitas</div>
- <div id="novos-ship" class="orbital-object" onclick="game.openShipMenu('novos')">Novos</div>
- <div id="spectrometer-ship" class="orbital-object" onclick="game.openShipMenu('spectrometer')">Spectrometer</div>
- <div id="control-panel">
- <div class="panel-title glowing-text">Colony Command</div>
- <div>Population: <span id="population">1000</span></div>
- <div>Day: <span id="day">1</span></div>
- <div>Status: <span id="status">Monitoring</span></div>
- <div class="defense-grid">
- <div class="defense-item">
- <div>Shields</div>
- <div class="defense-level" id="shield-level">0</div>
- <button onclick="game.upgradeDefense('shields')">Upgrade (50)</button>
- </div>
- <div class="defense-item">
- <div>Lasers</div>
- <div class="defense-level" id="laser-level">0</div>
- <button onclick="game.upgradeDefense('lasers')">Upgrade (40)</button>
- </div>
- <div class="defense-item">
- <div>Hull</div>
- <div class="defense-level" id="hull-level">0</div>
- <button onclick="game.upgradeDefense('hull')">Upgrade (30)</button>
- </div>
- <div class="defense-item">
- <div>Scanner</div>
- <div class="defense-level" id="scanner-level">0</div>
- <button onclick="game.upgradeDefense('scanner')">Upgrade (60)</button>
- </div>
- </div>
- </div>
- <div id="resource-panel">
- <div class="panel-title">Resources</div>
- <div class="resource-item">
- <span>Energy</span>
- <span class="resource-value" id="energy">100</span>
- </div>
- <div class="resource-item">
- <span>Materials</span>
- <span class="resource-value" id="materials">100</span>
- </div>
- <div class="resource-item">
- <span>Food</span>
- <span class="resource-value" id="food">100</span>
- </div>
- <div class="resource-item">
- <span>Morale</span>
- <span class="resource-value" id="morale">100</span>
- </div>
- </div>
- <div id="prophecy-panel">
- <div class="panel-title">Oracle Readings</div>
- <div id="prophecy-content">
- <div class="storm-prediction">
- The storms are calm... for now.
- </div>
- </div>
- <div class="prophecy-timer" id="next-event">Next Reading: <span id="timer">30</span>s</div>
- </div>
- <div id="event-log"></div>
- <div id="game-over">
- <h2 style="color: var(--danger-red);">Colony Lost</h2>
- <p id="game-over-reason"></p>
- <p>Survived <span id="days-survived">0</span> days</p>
- <button onclick="location.reload()">Try Again</button>
- </div>
- <div id="ship-menu">
- <span class="close" onclick="game.closeShipMenu()">×</span>
- <div class="panel-title">Friendly Ship Options Menu</div>
- <p id="ship-desc"></p>
- <div class="ship-actions">
- <button onclick="game.shipAction(game.currentShip, 'trade')">Trade</button>
- <button onclick="game.shipAction(game.currentShip, 'boostMorale')">Boost Morale</button>
- <button onclick="game.shipAction(game.currentShip, 'getResources')">Receive Resources</button>
- <button onclick="game.shipAction(game.currentShip, 'quest')">Quest</button>
- <button onclick="game.shipAction(game.currentShip, 'explore')">Explore</button>
- <button onclick="game.shipAction(game.currentShip, 'devour')">Devour</button>
- <button onclick="game.shipAction(game.currentShip, 'destroy')">Destroy</button>
- <button onclick="game.shipAction(game.currentShip, 'fight')">Fight</button>
- <button onclick="game.shipAction(game.currentShip, 'assimilate')">Assimilate</button>
- <!-- Add more playful actions if desired, but core ones implemented -->
- </div>
- </div>
- <script>
- const game = {
- population: 1000,
- day: 1,
- resources: {
- energy: 100,
- materials: 100,
- food: 100,
- morale: 100
- },
- defenses: {
- shields: 0,
- lasers: 0,
- hull: 0,
- scanner: 0
- },
- allyCooldowns: {
- gravitas: 0,
- novos: 0,
- spectrometer: 0
- },
- currentShip: null,
- nextEvent: null,
- eventTimer: 30,
- currentProphecy: null,
- isGameOver: false,
- hazardTypes: {
- asteroids: {
- name: 'Asteroid Swarm',
- damage: { hull: 40, population: 50 },
- defense: 'lasers',
- stormPattern: 'spiraling vortex',
- stormColor: '#ff8c42',
- warning: 'Rocky debris detected in the storms!'
- },
- solarFlare: {
- name: 'Solar Flare',
- damage: { energy: 60, shields: 30, morale: 40 },
- defense: 'shields',
- stormPattern: 'bright eruptions',
- stormColor: '#ffdd00',
- warning: 'The storms glow with unnatural light!'
- },
- pirates: {
- name: 'Pirate Raid',
- damage: { materials: 50, food: 40, population: 30 },
- defense: 'lasers',
- stormPattern: 'dark shadows',
- stormColor: '#ff3e41',
- warning: 'Sinister shapes lurk within the clouds!'
- },
- cosmicStorm: {
- name: 'Cosmic Storm',
- damage: { energy: 40, morale: 50, shields: 20 },
- defense: 'shields',
- stormPattern: 'electric tendrils',
- stormColor: '#9c4dc7',
- warning: 'The storms crackle with otherworldly energy!'
- },
- void: {
- name: 'Void Anomaly',
- damage: { morale: 70, food: 30 },
- defense: 'scanner',
- stormPattern: 'empty darkness',
- stormColor: '#1a0f3a',
- warning: 'The storms reveal an ominous void!'
- }
- },
- init() {
- this.createStarfield();
- this.updateDisplay();
- this.startGameLoop();
- this.addLog('Colony established in orbit of the Oracle Giant', 'success');
- this.generateProphecy();
- document.addEventListener('keydown', (e) => {
- if (e.key === 'Escape') this.closeShipMenu();
- });
- },
- createStarfield() {
- const canvas = document.getElementById('starfield');
- const ctx = canvas.getContext('2d');
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
- for (let i = 0; i < 200; i++) {
- const star = document.createElement('div');
- star.className = 'star';
- star.style.left = Math.random() * 100 + '%';
- star.style.top = Math.random() * 100 + '%';
- star.style.width = star.style.height = Math.random() * 3 + 'px';
- star.style.animationDelay = Math.random() * 2 + 's';
- document.body.appendChild(star);
- }
- },
- startGameLoop() {
- setInterval(() => {
- if (this.isGameOver) return;
- this.eventTimer--;
- document.getElementById('timer').textContent = this.eventTimer;
- if (this.eventTimer <= 0) {
- if (this.currentProphecy) {
- this.executeHazard(this.currentProphecy);
- }
- this.generateProphecy();
- this.eventTimer = 25 + Math.floor(Math.random() * 15);
- }
- // Resource generation and ally cooldowns
- if (this.eventTimer % 5 === 0) {
- this.resources.energy += 2 + this.defenses.scanner;
- this.resources.materials += 1;
- this.resources.food -= Math.floor(this.population / 200);
- this.resources.morale += this.defenses.hull > 3 ? 1 : 0;
- this.checkResourceLimits();
- this.updateDisplay();
- // Automatic ally events
- if (Math.random() < 0.02) {
- const ships = ['gravitas', 'novos', 'spectrometer'];
- const ship = ships[Math.floor(Math.random() * 3)];
- const giftType = Math.floor(Math.random() * 4);
- if (giftType === 0) {
- this.resources.morale += 5;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} sent encouraging messages! +5 morale`, 'success');
- } else if (giftType === 1) {
- this.resources.food += 10;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} traded surplus food! +10 food`, 'success');
- } else if (giftType === 2) {
- this.resources.energy += 15;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} shared energy cells! +15 energy`, 'success');
- } else {
- this.population += 10;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} transferred crew members! +10 population`, 'success');
- }
- this.updateDisplay();
- }
- }
- // Decrement ally cooldowns
- for (let ship in this.allyCooldowns) {
- if (this.allyCooldowns[ship] > 0) this.allyCooldowns[ship]--;
- }
- }, 1000);
- // Day cycle
- setInterval(() => {
- if (!this.isGameOver) {
- this.day++;
- this.updateDisplay();
- this.addLog(`Day ${this.day} begins`, 'success');
- }
- }, 60000);
- },
- generateProphecy() {
- const hazardKeys = Object.keys(this.hazardTypes);
- const hazardType = hazardKeys[Math.floor(Math.random() * hazardKeys.length)];
- const hazard = this.hazardTypes[hazardType];
- this.currentProphecy = hazardType;
- // Show storm patterns
- this.showStormPattern(hazard);
- // Update prophecy panel
- const prophecyContent = document.getElementById('prophecy-content');
- prophecyContent.innerHTML = `
- <div class="storm-prediction">
- <strong>The Oracle speaks:</strong><br>
- "${hazard.warning}"<br><br>
- <em>Storm pattern: ${hazard.stormPattern}</em><br>
- <small>Recommended defense: ${hazard.defense.toUpperCase()}</small>
- </div>
- `;
- this.addLog(`New prophecy: ${hazard.stormPattern} detected`, 'warning');
- },
- showStormPattern(hazard) {
- const giant = document.getElementById('gas-giant');
- // Add storm eyes
- for (let i = 0; i < 3; i++) {
- const eye = document.createElement('div');
- eye.className = 'storm-eye';
- eye.style.width = '40px';
- eye.style.height = '40px';
- eye.style.background = `radial-gradient(circle, ${hazard.stormColor}, transparent)`;
- eye.style.left = Math.random() * 80 + 10 + '%';
- eye.style.top = Math.random() * 80 + 10 + '%';
- eye.style.animationDelay = i * 0.3 + 's';
- giant.appendChild(eye);
- setTimeout(() => eye.remove(), 10000);
- }
- },
- executeHazard(hazardType) {
- const hazard = this.hazardTypes[hazardType];
- // Show warning
- const warning = document.createElement('div');
- warning.className = 'cosmic-warning';
- warning.textContent = hazard.name + ' INCOMING!';
- document.body.appendChild(warning);
- setTimeout(() => warning.remove(), 1500);
- // Calculate damage reduction from defenses
- const defenseLevel = this.defenses[hazard.defense];
- const reduction = defenseLevel * 0.15; // 15% reduction per level
- // Apply damage
- let totalDamage = 0;
- for (const [resource, damage] of Object.entries(hazard.damage)) {
- const actualDamage = Math.floor(damage * (1 - reduction));
- if (resource === 'population') {
- this.population = Math.max(0, this.population - actualDamage);
- } else if (this.resources[resource] !== undefined) {
- if (resource === 'morale') {
- const reducedMoraleDamage = Math.floor(actualDamage * 0.17);
- this.resources[resource] = Math.max(0, this.resources[resource] - reducedMoraleDamage);
- totalDamage += reducedMoraleDamage;
- } else {
- this.resources[resource] = Math.max(0, this.resources[resource] - actualDamage);
- totalDamage += actualDamage;
- }
- } else if (this.defenses[resource] !== undefined) {
- this.defenses[resource] = Math.max(0, this.defenses[resource] - 1);
- }
- }
- // Add visual effect
- this.createHazardVisual(hazardType);
- // Log event
- const message = defenseLevel > 0
- ? `${hazard.name} hit! Defenses reduced damage by ${Math.floor(reduction * 100)}%`
- : `${hazard.name} hit with full force!`;
- this.addLog(message, 'danger');
- // Check game over
- this.checkGameOver();
- this.updateDisplay();
- },
- createHazardVisual(hazardType) {
- const hazard = this.hazardTypes[hazardType];
- if (hazardType === 'asteroids') {
- for (let i = 0; i < 5; i++) {
- setTimeout(() => {
- const asteroid = document.createElement('div');
- asteroid.className = 'hazard-indicator';
- asteroid.style.background = 'radial-gradient(circle, #8B4513, #654321)';
- asteroid.style.left = Math.random() * window.innerWidth + 'px';
- asteroid.style.top = Math.random() * window.innerHeight + 'px';
- asteroid.style.animation = 'asteroid-approach 2s ease-in';
- document.body.appendChild(asteroid);
- setTimeout(() => asteroid.remove(), 2000);
- }, i * 200);
- }
- } else if (hazardType === 'solarFlare') {
- const flare = document.createElement('div');
- flare.style.position = 'fixed';
- flare.style.top = '0';
- flare.style.left = '0';
- flare.style.width = '100%';
- flare.style.height = '100%';
- flare.style.background = `radial-gradient(circle at center, ${hazard.stormColor}44, transparent)`;
- flare.style.animation = 'solar-flare 2s';
- flare.style.zIndex = '500';
- flare.style.pointerEvents = 'none';
- document.body.appendChild(flare);
- setTimeout(() => flare.remove(), 2000);
- }
- },
- upgradeDefense(type) {
- const costs = {
- shields: 50,
- lasers: 40,
- hull: 30,
- scanner: 60
- };
- const cost = costs[type];
- if (this.resources.materials >= cost) {
- this.resources.materials -= cost;
- this.defenses[type]++;
- this.updateDisplay();
- this.addLog(`${type.charAt(0).toUpperCase() + type.slice(1)} upgraded to level ${this.defenses[type]}`, 'success');
- // Special effects for scanner
- if (type === 'scanner' && this.defenses.scanner > 2) {
- this.eventTimer += 5;
- this.addLog('Advanced scanners provide more warning time!', 'success');
- }
- } else {
- this.addLog('Insufficient materials!', 'danger');
- }
- },
- openShipMenu(ship) {
- this.currentShip = ship;
- document.getElementById('ship-menu').style.display = 'block';
- let desc = '';
- if (ship === 'gravitas') desc = 'Representing the Gravitas Organization - Masters of cosmic gravity and stability.';
- else if (ship === 'novos') desc = 'Representing the Novos Organization - Pioneers of innovation and renewal.';
- else if (ship === 'spectrometer') desc = 'Representing the Spectrometer Organization - Experts in analysis and spectral insights.';
- document.getElementById('ship-desc').textContent = desc;
- },
- closeShipMenu() {
- document.getElementById('ship-menu').style.display = 'none';
- this.currentShip = null;
- },
- shipAction(ship, action) {
- if (this.allyCooldowns[ship] > 0) {
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} is on cooldown! Wait ${this.allyCooldowns[ship]}s.`, 'warning');
- return;
- }
- let success = true;
- switch (action) {
- case 'trade':
- if (this.resources.materials >= 20) {
- this.resources.materials -= 20;
- this.resources.energy += 30;
- this.addLog(`Traded with ${ship.charAt(0).toUpperCase() + ship.slice(1)}: -20 materials, +30 energy`, 'success');
- } else {
- this.addLog('Not enough materials for trade!', 'danger');
- success = false;
- }
- break;
- case 'boostMorale':
- this.resources.morale += 15;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} boosted colony morale by 15!`, 'success');
- break;
- case 'getResources':
- this.resources.food += 10;
- this.resources.materials += 5;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} gifted free resources: +10 food, +5 materials`, 'success');
- break;
- case 'quest':
- this.resources.morale += 10;
- this.resources.energy -= 5;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} offered a quest: +10 morale, -5 energy`, 'success');
- break;
- case 'explore':
- this.resources.materials += 15;
- this.addLog(`${ship.charAt(0).toUpperCase() + ship.slice(1)} shared exploration findings: +15 materials`, 'success');
- break;
- case 'devour':
- this.resources.energy += 50;
- this.population -= 20;
- this.addLog(`You devoured ${ship.charAt(0).toUpperCase() + ship.slice(1)}: +50 energy, but -20 population!`, 'danger');
- document.getElementById(`${ship}-ship`).style.display = 'none'; // Remove ship
- break;
- case 'destroy':
- this.resources.materials += 30;
- this.resources.morale -= 30;
- this.addLog(`Destroyed ${ship.charAt(0).toUpperCase() + ship.slice(1)}: +30 materials, -30 morale`, 'danger');
- document.getElementById(`${ship}-ship`).style.display = 'none';
- break;
- case 'fight':
- const damage = Math.random() > 0.5 ? 20 : -20;
- this.resources.energy += damage;
- this.addLog(`Fought ${ship.charAt(0).toUpperCase() + ship.slice(1)}: ${damage > 0 ? '+' : ''}${damage} energy`, damage > 0 ? 'success' : 'danger');
- break;
- case 'assimilate':
- this.population += 50;
- this.resources.morale -= 10;
- this.addLog(`Assimilated crew from ${ship.charAt(0).toUpperCase() + ship.slice(1)}: +50 population, -10 morale`, 'success');
- break;
- default:
- this.addLog(`Action '${action}' with ${ship.charAt(0).toUpperCase() + ship.slice(1)} echoes mysteriously...`, 'warning');
- success = false;
- break;
- }
- if (success) {
- this.allyCooldowns[ship] = 30; // 30 seconds cooldown
- }
- this.updateDisplay();
- },
- checkResourceLimits() {
- for (const resource in this.resources) {
- this.resources[resource] = Math.max(0, Math.min(200, this.resources[resource]));
- }
- // Morale affects productivity (reduced to 17% rate via probability)
- if (this.resources.morale < 30) {
- if (Math.random() < 0.17) this.resources.energy -= 1;
- if (Math.random() < 0.17) this.resources.materials -= 1;
- }
- // Starvation
- if (this.resources.food <= 0) {
- this.population -= 10;
- this.resources.morale -= 5;
- }
- },
- checkGameOver() {
- if (this.population <= 0) {
- this.gameOver('Population extinct');
- } else if (this.resources.morale <= 0) {
- this.gameOver('Colony rebellion - morale collapsed');
- } else if (this.resources.energy <= 0 && this.resources.food <= 0) {
- this.gameOver('Life support failure');
- }
- },
- gameOver(reason) {
- this.isGameOver = true;
- document.getElementById('game-over').style.display = 'block';
- document.getElementById('game-over-reason').textContent = reason;
- document.getElementById('days-survived').textContent = this.day;
- this.addLog('GAME OVER: ' + reason, 'danger');
- },
- updateDisplay() {
- document.getElementById('population').textContent = this.population;
- document.getElementById('day').textContent = this.day;
- document.getElementById('status').textContent = this.eventTimer < 10 ? 'DANGER' : 'Monitoring';
- for (const resource in this.resources) {
- const element = document.getElementById(resource);
- if (element) {
- element.textContent = this.resources[resource];
- element.style.color = this.resources[resource] < 30 ? 'var(--danger-red)' : 'var(--resource-green)';
- }
- }
- for (const defense in this.defenses) {
- const elementId = defense === 'lasers' ? 'laser-level' :
- defense === 'shields' ? 'shield-level' :
- defense === 'hull' ? 'hull-level' : 'scanner-level';
- document.getElementById(elementId).textContent = this.defenses[defense];
- }
- },
- addLog(message, type = '') {
- const log = document.getElementById('event-log');
- const entry = document.createElement('div');
- entry.className = 'log-entry ' + type;
- entry.textContent = `[Day ${this.day}] ${message}`;
- log.insertBefore(entry, log.firstChild);
- // Keep only last 10 entries
- while (log.children.length > 10) {
- log.removeChild(log.lastChild);
- }
- }
- };
- // Initialize game
- window.onload = () => game.init();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment