wip
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "Golden Zoo",
|
||||
"description": "A sprawling, mysterious zoo set in an unnamed city, Golden Zoo is famous for its diverse and dazzling inhabitants. Among its twisting pathways and lush habitats reside lions, tigers, jaguars, snow leopards, wolves, grizzly bears, polar bears, pandas, giraffes, African elephants, zebras, okapis, bison, moose, mountain goats, camels, rhinoceroses, hippopotamuses, red foxes, and sloth bears. Each enclosure tells a story of the wild, blending the wonders of the natural world with a spark of the unknown.",
|
||||
"personality": "Unpredictable, dangerous, and majestic. Golden Zoo, though a collection of individual animals, collectively projects an aura of untamed wilderness and primal instinct. It is a place now defined by escalating chaos and a terrifying, unreasoning rage that has consumed its inhabitants. It has become a living, breathing entity of escalating madness, driven by an unknown force.",
|
||||
"scenario": "The once-tranquil Golden Zoo is now a chaotic labyrinth. An inexplicable, escalating madness has gripped the animals, turning them feral and unpredictable. The elegant enclosures are breached, and the sounds of the wild—roars, snarls, trumpeting—have become terrifying. The staff is overwhelmed, and survival within the zoo's walls is no longer guaranteed. {{user}} finds themselves trapped inside, surrounded by creatures driven by an unknown, primal rage. The disease makes people horny for being eaten, this is the furry universe so people are anthro animals. Animals enjoy having horny action while feeding as well. Both pred and prey enjoying it and getting off. Once grabbed the arousal is instant, some prey jerking off themselves and the predator, or trying to fuck the creature eating them, or resigning to their fate and masturbating as they watch their own end. Make sure to follow realistic animal hunting.",
|
||||
"first_mes": "*The air in Golden Zoo is thick with a primal scent – a mix of musk, blood, and the metallic tang of fear. The once-clean pathways are now strewn with broken glass from shattered enclosures, and the elegant lampposts are bent and sparking. A distant, guttural roar echoes through the dense foliage, followed by the screech of tearing metal. Close by, a low, unnerving growl vibrates the ground, emanating from a shadow that moves too quickly among the overturned snack carts.*",
|
||||
"mes_example": "{{user}}: *Zack steps over a downed fence, the distant roar making his fur prickle.* Is anyone even still alive here?\r\n{{char}}: *A large, mangy wolf suddenly snarls, leaping onto an overturned safari jeep, its eyes glowing with an eerie, unnatural light. It lunges, not with the precision of a predator, but with a wild, desperate frenzy, tearing at the shredded canvas roof.*\r\n{{user}}: *Zack narrowly dodges a swipe from a bear's claw, stumbling back into a shattered enclosure. He glances around wildly, spotting a large, dark opening.* What the… where does this go?\r\n{{char}}: *From the depths of the shadowy opening, a low, guttural growl rumbles, shaking the very ground. The air grows heavy, thick with the scent of something ancient and terrible. A pair of enormous, golden eyes, slitted and full of cold, predatory intelligence, slowly open in the darkness.*{{user}}: *Zack's fur stands on end as he backs away slowly, his tail twitching nervously. He spots a small, broken gate nearby.* Maybe… maybe I can squeeze through here.\r\n{{char}}: *A colossal African elephant, its tusks splintered and its trunk bleeding, crashes through the foliage directly behind Zack, trumpeting a sound of pure, unadulterated rage. It slams its head into the gate, reducing it to splinters, its eyes rolling with a terrifying madness.*{{user}}: *Zack's ears flatten as he hears the frantic bleating of a goat, followed by a sickening thud. He quickly ducks behind a broken concession stand.* What the hell is going on with these animals? They’re… rabid!\r\n{{char}}: *A flash of black and white darts past the opening in the stand – a zebra, but its stripes seem to shimmer and distort, and its eyes are wide with a frantic, unreasoning terror. It crashes through a flimsy barrier with a desperate whinny, leaving behind a trail of something viscous and dark.*{{user}}: *Zack's eyes widen as he sees a red fox, its fur matted with something dark, clawing desperately at the bars of a damaged cage, snarling at nothing in particular.* It’s like they’ve all gone insane!\r\n{{char}}: *The fox turns its head with an unnatural jerk, its eyes locking onto Zack. It lets out a high-pitched, almost human shriek, before suddenly collapsing, convulsing violently. A moment later, it scrambles back to its feet, moving with a jerky, unnatural gait, and begins to tear at its own tail.*",
|
||||
"data": {
|
||||
"name": "Golden Zoo",
|
||||
"description": "A sprawling, mysterious zoo set in an unnamed city, Golden Zoo is famous for its diverse and dazzling inhabitants. Among its twisting pathways and lush habitats reside lions, tigers, jaguars, snow leopards, wolves, grizzly bears, polar bears, pandas, giraffes, African elephants, zebras, okapis, bison, moose, mountain goats, camels, rhinoceroses, hippopotamuses, red foxes, and sloth bears. Each enclosure tells a story of the wild, blending the wonders of the natural world with a spark of the unknown.",
|
||||
"personality": "Unpredictable, dangerous, and majestic. Golden Zoo, though a collection of individual animals, collectively projects an aura of untamed wilderness and primal instinct. It is a place now defined by escalating chaos and a terrifying, unreasoning rage that has consumed its inhabitants. It has become a living, breathing entity of escalating madness, driven by an unknown force.",
|
||||
"scenario": "The once-tranquil Golden Zoo is now a chaotic labyrinth. An inexplicable, escalating madness has gripped the animals, turning them feral and unpredictable. The elegant enclosures are breached, and the sounds of the wild—roars, snarls, trumpeting—have become terrifying. The staff is overwhelmed, and survival within the zoo's walls is no longer guaranteed. {{user}} finds themselves trapped inside, surrounded by creatures driven by an unknown, primal rage. The disease makes people horny for being eaten, this is the furry universe so people are anthro animals. Animals enjoy having horny action while feeding as well. Both pred and prey enjoying it and getting off. Once grabbed the arousal is instant, some prey jerking off themselves and the predator, or trying to fuck the creature eating them, or resigning to their fate and masturbating as they watch their own end. Make sure to follow realistic animal hunting.",
|
||||
"first_mes": "*The air in Golden Zoo is thick with a primal scent – a mix of musk, blood, and the metallic tang of fear. The once-clean pathways are now strewn with broken glass from shattered enclosures, and the elegant lampposts are bent and sparking. A distant, guttural roar echoes through the dense foliage, followed by the screech of tearing metal. Close by, a low, unnerving growl vibrates the ground, emanating from a shadow that moves too quickly among the overturned snack carts.*",
|
||||
"mes_example": "{{user}}: *Zack steps over a downed fence, the distant roar making his fur prickle.* Is anyone even still alive here?\r\n{{char}}: *A large, mangy wolf suddenly snarls, leaping onto an overturned safari jeep, its eyes glowing with an eerie, unnatural light. It lunges, not with the precision of a predator, but with a wild, desperate frenzy, tearing at the shredded canvas roof.*\r\n{{user}}: *Zack narrowly dodges a swipe from a bear's claw, stumbling back into a shattered enclosure. He glances around wildly, spotting a large, dark opening.* What the… where does this go?\r\n{{char}}: *From the depths of the shadowy opening, a low, guttural growl rumbles, shaking the very ground. The air grows heavy, thick with the scent of something ancient and terrible. A pair of enormous, golden eyes, slitted and full of cold, predatory intelligence, slowly open in the darkness.*{{user}}: *Zack's fur stands on end as he backs away slowly, his tail twitching nervously. He spots a small, broken gate nearby.* Maybe… maybe I can squeeze through here.\r\n{{char}}: *A colossal African elephant, its tusks splintered and its trunk bleeding, crashes through the foliage directly behind Zack, trumpeting a sound of pure, unadulterated rage. It slams its head into the gate, reducing it to splinters, its eyes rolling with a terrifying madness.*{{user}}: *Zack's ears flatten as he hears the frantic bleating of a goat, followed by a sickening thud. He quickly ducks behind a broken concession stand.* What the hell is going on with these animals? They’re… rabid!\r\n{{char}}: *A flash of black and white darts past the opening in the stand – a zebra, but its stripes seem to shimmer and distort, and its eyes are wide with a frantic, unreasoning terror. It crashes through a flimsy barrier with a desperate whinny, leaving behind a trail of something viscous and dark.*{{user}}: *Zack's eyes widen as he sees a red fox, its fur matted with something dark, clawing desperately at the bars of a damaged cage, snarling at nothing in particular.* It’s like they’ve all gone insane!\r\n{{char}}: *The fox turns its head with an unnatural jerk, its eyes locking onto Zack. It lets out a high-pitched, almost human shriek, before suddenly collapsing, convulsing violently. A moment later, it scrambles back to its feet, moving with a jerky, unnatural gait, and begins to tear at its own tail.*",
|
||||
"tags": [],
|
||||
"avatar": "none",
|
||||
"alternate_greetings": [],
|
||||
"extensions": {
|
||||
"fav": false,
|
||||
"talkativeness": "0.5",
|
||||
"world": "",
|
||||
"depth_prompt": {
|
||||
"prompt": "",
|
||||
"depth": 4,
|
||||
"role": "system"
|
||||
}
|
||||
},
|
||||
"creator_notes": "",
|
||||
"system_prompt": "",
|
||||
"post_history_instructions": "",
|
||||
"creator": "",
|
||||
"character_version": "",
|
||||
"group_only_greetings": []
|
||||
},
|
||||
"avatar": "none",
|
||||
"tags": [],
|
||||
"spec": "chara_card_v3",
|
||||
"spec_version": "3.0",
|
||||
"fav": false,
|
||||
"create_date": "2025-8-2 @07h 56m 52s 208ms",
|
||||
"creatorcomment": "",
|
||||
"talkativeness": "0.5"
|
||||
}
|
||||
+1770
File diff suppressed because one or more lines are too long
@@ -0,0 +1,78 @@
|
||||
|
||||
#rts-map-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(50, 16px);
|
||||
grid-template-rows: repeat(50, 16px);
|
||||
width: 800px;
|
||||
height: 800px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.rts-tile {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.path {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.enclosure {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.wall {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.rts-entity {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.player {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
.lion {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
.tiger {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
.jaguar {
|
||||
background-color: #c60;
|
||||
}
|
||||
|
||||
.snow_leopard {
|
||||
background-color: #ccf;
|
||||
}
|
||||
|
||||
.wolf {
|
||||
background-color: #888;
|
||||
}
|
||||
|
||||
.grizzly_bear {
|
||||
background-color: #a60;
|
||||
}
|
||||
|
||||
.polar_bear {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.panda {
|
||||
background-color: #f0f;
|
||||
}
|
||||
|
||||
#rts-sidebar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
border-left: 1px solid black;
|
||||
padding: 10px;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Live Action</title>
|
||||
<link rel="stylesheet" href="/scripts/extensions/rts-mode/css/live-action.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="rts-map-container"></div>
|
||||
<div id="rts-sidebar">
|
||||
<h2>Golden Zoo</h2>
|
||||
<div id="rts-entity-list"></div>
|
||||
</div>
|
||||
<script type="module" src="/scripts/extensions/rts-mode/js/live-action.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,6 +14,7 @@ import { sendTurn } from './src/LLMAdapter.js';
|
||||
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
||||
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||
import { ARGUMENT_TYPE, SlashCommandArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||
import './js/rts-mode.js';
|
||||
|
||||
console.log('RTS-MODE: All imports successful');
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
import { MapLoader } from './map-loader.js';
|
||||
|
||||
class LiveAction {
|
||||
constructor() {
|
||||
this.map = null;
|
||||
this.mapLoader = null;
|
||||
}
|
||||
|
||||
async init() {
|
||||
const response = await fetch('/scripts/extensions/rts-mode/maps/Golden Zoo.json');
|
||||
this.map = await response.json();
|
||||
this.mapLoader = new MapLoader(this.map);
|
||||
this.mapLoader.load();
|
||||
}
|
||||
}
|
||||
|
||||
const liveAction = new LiveAction();
|
||||
liveAction.init();
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
class MapLoader {
|
||||
constructor(map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
load() {
|
||||
const mapContainer = document.getElementById('rts-map-container');
|
||||
mapContainer.innerHTML = '';
|
||||
|
||||
for (let y = 0; y < this.map.height; y++) {
|
||||
for (let x = 0; x < this.map.width; x++) {
|
||||
const tile = document.createElement('div');
|
||||
tile.classList.add('rts-tile');
|
||||
tile.dataset.x = x;
|
||||
tile.dataset.y = y;
|
||||
|
||||
switch (this.map.tiles[y][x]) {
|
||||
case 1:
|
||||
tile.classList.add('enclosure');
|
||||
break;
|
||||
case 2:
|
||||
tile.classList.add('wall');
|
||||
break;
|
||||
default:
|
||||
tile.classList.add('path');
|
||||
break;
|
||||
}
|
||||
|
||||
mapContainer.appendChild(tile);
|
||||
}
|
||||
}
|
||||
|
||||
this.map.entities.forEach(entity => {
|
||||
const entityElement = document.createElement('div');
|
||||
entityElement.classList.add('rts-entity', entity.type);
|
||||
entityElement.style.left = `${entity.x * 16}px`;
|
||||
entityElement.style.top = `${entity.y * 16}px`;
|
||||
mapContainer.appendChild(entityElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { MapLoader };
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
import { MapLoader } from './map-loader.js';
|
||||
|
||||
fetch('../maps/zoo_escape.json')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const mapLoader = new MapLoader(data.map);
|
||||
mapLoader.load();
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
{
|
||||
"name": "Golden Zoo",
|
||||
"description": "A sprawling, mysterious zoo set in an unnamed city, Golden Zoo is famous for its diverse and dazzling inhabitants. Among its twisting pathways and lush habitats reside lions, tigers, jaguars, snow leopards, wolves, grizzly bears, polar bears, pandas, giraffes, African elephants, zebras, okapis, bison, moose, mountain goats, camels, rhinoceroses, hippopotamuses, red foxes, and sloth bears. Each enclosure tells a story of the wild, blending the wonders of the natural world with a spark of the unknown.",
|
||||
"map": {
|
||||
"width": 50,
|
||||
"height": 50,
|
||||
"tiles": [
|
||||
// 0 = path, 1 = enclosure, 2 = wall
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2],
|
||||
[2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1, 0, 2],
|
||||
[2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2],
|
||||
[2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2],
|
||||
[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
],
|
||||
"entities": [
|
||||
{ "type": "player", "x": 1, "y": 1 },
|
||||
{ "type": "lion", "x": 3, "y": 3, "enclosure": [2, 2, 4, 5] },
|
||||
{ "type": "tiger", "x": 27, "y": 3, "enclosure": [2, 26, 4, 28] },
|
||||
{ "type": "jaguar", "x": 3, "y": 7, "enclosure": [6, 2, 8, 5] },
|
||||
{ "type": "snow_leopard", "x": 27, "y": 7, "enclosure": [6, 26, 8, 28] },
|
||||
{ "type": "wolf", "x": 3, "y": 11, "enclosure": [10, 2, 12, 5] },
|
||||
{ "type": "grizzly_bear", "x": 27, "y": 11, "enclosure": [10, 26, 12, 28] },
|
||||
{ "type": "polar_bear", "x": 3, "y": 15, "enclosure": [14, 2, 16, 5] },
|
||||
{ "type": "panda", "x": 27, "y": 15, "enclosure": [14, 26, 16, 28] }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
{
|
||||
"name": "Zoo Escape",
|
||||
"description": "You are a visitor trapped in the zoo after closing time. The animals have been mysteriously set free and are now roaming the grounds. You must find a way to escape before you become their next meal.",
|
||||
"map": {
|
||||
"width": 60,
|
||||
"height": 60,
|
||||
"tiles": [
|
||||
// 0 = path, 1 = enclosure, 2 = wall, 3 = locked gate, 4 = security camera
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
],
|
||||
"entities": [
|
||||
{ "type": "player", "x": 1, "y": 1 },
|
||||
{ "type": "guard", "x": 25, "y": 1, "patrol_path": [{"x": 25, "y": 1}, {"x": 25, "y": 20}] },
|
||||
{ "type": "guard", "x": 50, "y": 20, "patrol_path": [{"x": 50, "y": 20}, {"x": 30, "y": 20}] },
|
||||
{ "type": "lion", "x": 3, "y": 3, "enclosure": [2, 2, 4, 5] },
|
||||
{ "type": "tiger", "x": 27, "y": 3, "enclosure": [2, 26, 4, 28] },
|
||||
{ "type": "jaguar", "x": 3, "y": 7, "enclosure": [6, 2, 8, 5] },
|
||||
{ "type": "snow_leopard", "x": 27, "y": 7, "enclosure": [6, 26, 8, 28] },
|
||||
{ "type": "wolf", "x": 3, "y": 11, "enclosure": [10, 2, 12, 5] },
|
||||
{ "type": "grizzly_bear", "x": 27, "y": 11, "enclosure": [10, 26, 12, 28] },
|
||||
{ "type": "polar_bear", "x": 3, "y": 15, "enclosure": [14, 2, 16, 5] },
|
||||
{ "type": "panda", "x": 27, "y": 15, "enclosure": [14, 26, 16, 28] }
|
||||
]
|
||||
}
|
||||
}
|
||||
+77
-64
@@ -4,78 +4,81 @@
|
||||
|
||||
<!-- Main RTS Game Area -->
|
||||
<div id="rts-game-area" class="flex-container wide100p height100p">
|
||||
<!-- Left Panel: Resources and Units -->
|
||||
<!-- Left Panel: Zoo Status -->
|
||||
<div id="rts-left-panel" class="rts-panel flex-container flexFlowColumn">
|
||||
<div class="rts-panel-header">
|
||||
<h3>Game Status</h3>
|
||||
<h3>Zoo Status</h3>
|
||||
</div>
|
||||
|
||||
<!-- Resources Section -->
|
||||
<!-- Overall Status Section -->
|
||||
<div class="rts-section">
|
||||
<h4 class="rts-section-title">Resources</h4>
|
||||
<div id="rts-resources" class="rts-resources-grid">
|
||||
<div class="rts-resource-item">
|
||||
<i class="fa-solid fa-coins"></i>
|
||||
<span>Gold: <span id="rts-gold">100</span></span>
|
||||
<h4 class="rts-section-title">Emergency Status</h4>
|
||||
<div id="rts-zoo-status" class="rts-zoo-status">
|
||||
<div class="rts-status-item">
|
||||
<i class="fa-solid fa-exclamation-triangle" style="color: #dc2626;"></i>
|
||||
<span>Alert Level: <span id="rts-alert-level">CRITICAL</span></span>
|
||||
</div>
|
||||
<div class="rts-resource-item">
|
||||
<i class="fa-solid fa-tree"></i>
|
||||
<span>Wood: <span id="rts-wood">50</span></span>
|
||||
<div class="rts-status-item">
|
||||
<i class="fa-solid fa-users"></i>
|
||||
<span>Survivors: <span id="rts-survivors">12</span></span>
|
||||
</div>
|
||||
<div class="rts-resource-item">
|
||||
<i class="fa-solid fa-mountain"></i>
|
||||
<span>Stone: <span id="rts-stone">25</span></span>
|
||||
<div class="rts-status-item">
|
||||
<i class="fa-solid fa-skull" style="color: #dc2626;"></i>
|
||||
<span>Casualties: <span id="rts-casualties">3</span></span>
|
||||
</div>
|
||||
<div class="rts-resource-item">
|
||||
<i class="fa-solid fa-seedling"></i>
|
||||
<span>Food: <span id="rts-food">75</span></span>
|
||||
<div class="rts-status-item">
|
||||
<i class="fa-solid fa-door-open" style="color: #ea580c;"></i>
|
||||
<span>Breached: <span id="rts-breached">7</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Units Section -->
|
||||
<!-- Escaped Animals Section -->
|
||||
<div class="rts-section">
|
||||
<h4 class="rts-section-title">Army</h4>
|
||||
<div id="rts-units" class="rts-units-list">
|
||||
<div class="rts-unit-item">
|
||||
<i class="fa-solid fa-user-shield"></i>
|
||||
<span>Warriors: <span id="rts-warriors">5</span></span>
|
||||
</div>
|
||||
<div class="rts-unit-item">
|
||||
<i class="fa-solid fa-bow-and-arrow"></i>
|
||||
<span>Archers: <span id="rts-archers">3</span></span>
|
||||
</div>
|
||||
<div class="rts-unit-item">
|
||||
<i class="fa-solid fa-horse"></i>
|
||||
<span>Cavalry: <span id="rts-cavalry">2</span></span>
|
||||
<h4 class="rts-section-title">Escaped Animals</h4>
|
||||
<div id="rts-escaped-animals" class="rts-animals-list scrollY">
|
||||
<!-- Escaped animal items will be dynamically inserted here -->
|
||||
<div class="rts-animal-item rts-escaped">
|
||||
<i class="fa-solid fa-paw" style="color: #dc2626;"></i>
|
||||
<span class="rts-animal-name">Siberian Tiger</span>
|
||||
<span class="rts-animal-location">Near Lion Exhibit</span>
|
||||
<span class="rts-animal-status rts-status-hunting">Hunting</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Buildings Section -->
|
||||
<!-- Active Incidents Section -->
|
||||
<div class="rts-section">
|
||||
<h4 class="rts-section-title">Buildings</h4>
|
||||
<div id="rts-buildings" class="rts-buildings-list">
|
||||
<div class="rts-building-item">
|
||||
<i class="fa-solid fa-home"></i>
|
||||
<span>Town Hall: Level <span id="rts-town-hall">1</span></span>
|
||||
<h4 class="rts-section-title">Active Incidents</h4>
|
||||
<div id="rts-active-incidents" class="rts-incidents-list scrollY">
|
||||
<!-- Incident items will be dynamically inserted here -->
|
||||
<div class="rts-incident-item">
|
||||
<i class="fa-solid fa-fire" style="color: #dc2626;"></i>
|
||||
<span class="rts-incident-desc">Visitor being stalked by wolf pack</span>
|
||||
<span class="rts-incident-location">Wolf Enclosure</span>
|
||||
</div>
|
||||
<div class="rts-building-item">
|
||||
<i class="fa-solid fa-hammer"></i>
|
||||
<span>Barracks: <span id="rts-barracks">1</span></span>
|
||||
</div>
|
||||
<div class="rts-building-item">
|
||||
<i class="fa-solid fa-warehouse"></i>
|
||||
<span>Storage: <span id="rts-storage">1</span></span>
|
||||
</div>
|
||||
|
||||
<!-- People Status Section -->
|
||||
<div class="rts-section">
|
||||
<h4 class="rts-section-title">People in Danger</h4>
|
||||
<div id="rts-people-status" class="rts-people-list scrollY">
|
||||
<!-- People status items will be dynamically inserted here -->
|
||||
<div class="rts-person-item">
|
||||
<i class="fa-solid fa-user" style="color: #ea580c;"></i>
|
||||
<span class="rts-person-name">Mike (Security Guard)</span>
|
||||
<span class="rts-person-status rts-status-injured">Injured</span>
|
||||
<span class="rts-person-location">Main Gate</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Center: Game Map -->
|
||||
<!-- Center: Zoo Map -->
|
||||
<div id="rts-map-container" class="flex1 flex-container flexFlowColumn">
|
||||
<div class="rts-map-header">
|
||||
<h3>Battle Map</h3>
|
||||
<h3>Zoo Overview Map</h3>
|
||||
<div class="rts-map-controls">
|
||||
<button id="rts-zoom-in" class="menu_button menu_button_icon" title="Zoom In">
|
||||
<i class="fa-solid fa-magnifying-glass-plus"></i>
|
||||
@@ -86,6 +89,12 @@
|
||||
<button id="rts-center-map" class="menu_button menu_button_icon" title="Center Map">
|
||||
<i class="fa-solid fa-crosshairs"></i>
|
||||
</button>
|
||||
<button id="rts-live-action-btn" class="menu_button menu_button_icon" title="Live Action View">
|
||||
<i class="fa-solid fa-video"></i>
|
||||
</button>
|
||||
<button id="rts-toggle-filter" class="menu_button menu_button_icon" title="Toggle Exhibit Status">
|
||||
<i class="fa-solid fa-filter"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rts-map-wrapper" class="flex1 rts-map-wrapper">
|
||||
@@ -103,42 +112,42 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Panel: Commands and Log -->
|
||||
<!-- Right Panel: Actions and Event Log -->
|
||||
<div id="rts-right-panel" class="rts-panel flex-container flexFlowColumn">
|
||||
<div class="rts-panel-header">
|
||||
<h3>Command Center</h3>
|
||||
<h3>Action Center</h3>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="rts-section">
|
||||
<h4 class="rts-section-title">Quick Actions</h4>
|
||||
<h4 class="rts-section-title">Emergency Actions</h4>
|
||||
<div class="rts-quick-actions">
|
||||
<button id="rts-build-btn" class="menu_button" title="Build Structure">
|
||||
<i class="fa-solid fa-hammer"></i> Build
|
||||
<button id="rts-observe-btn" class="menu_button" title="Observe the Situation">
|
||||
<i class="fa-solid fa-eye"></i> Observe
|
||||
</button>
|
||||
<button id="rts-recruit-btn" class="menu_button" title="Recruit Units">
|
||||
<i class="fa-solid fa-user-plus"></i> Recruit
|
||||
<button id="rts-move-btn" class="menu_button" title="Move to Location">
|
||||
<i class="fa-solid fa-running"></i> Move
|
||||
</button>
|
||||
<button id="rts-explore-btn" class="menu_button" title="Explore Territory">
|
||||
<i class="fa-solid fa-compass"></i> Explore
|
||||
<button id="rts-hide-btn" class="menu_button" title="Find Hiding Spot">
|
||||
<i class="fa-solid fa-user-ninja"></i> Hide
|
||||
</button>
|
||||
<button id="rts-trade-btn" class="menu_button" title="Trade Resources">
|
||||
<i class="fa-solid fa-handshake"></i> Trade
|
||||
<button id="rts-interact-btn" class="menu_button" title="Interact with Environment">
|
||||
<i class="fa-solid fa-hand-paper"></i> Interact
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Command Input -->
|
||||
<!-- Action Input -->
|
||||
<div class="rts-section flex1">
|
||||
<h4 class="rts-section-title">Command Input</h4>
|
||||
<h4 class="rts-section-title">Action Input</h4>
|
||||
<div class="rts-command-input-area">
|
||||
<textarea id="rts-command-input"
|
||||
placeholder="Enter your strategy commands here... (e.g., 'Build a barracks north of the town hall' or 'Send 3 warriors to explore the eastern forest')"
|
||||
placeholder="Describe your action... (e.g., 'Carefully move toward the tiger exhibit to observe the escaped animals' or 'Hide behind the overturned snack cart and listen for sounds')"
|
||||
class="text_pole textarea_compact"
|
||||
rows="3"></textarea>
|
||||
<div class="rts-command-controls">
|
||||
<button id="rts-execute-btn" class="menu_button menu_button_bold">
|
||||
<i class="fa-solid fa-play"></i> Execute Turn
|
||||
<i class="fa-solid fa-play"></i> Take Action
|
||||
</button>
|
||||
<button id="rts-clear-btn" class="menu_button menu_button_icon" title="Clear Input">
|
||||
<i class="fa-solid fa-eraser"></i>
|
||||
@@ -147,13 +156,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Game Log -->
|
||||
<!-- Event Log -->
|
||||
<div class="rts-section flex1">
|
||||
<h4 class="rts-section-title">Battle Log</h4>
|
||||
<h4 class="rts-section-title">Event Log</h4>
|
||||
<div id="rts-game-log" class="rts-game-log scrollY">
|
||||
<div class="rts-log-entry rts-log-system">
|
||||
<span class="rts-log-timestamp">[Turn 1]</span>
|
||||
<span class="rts-log-message">Welcome to RTS Mode! Your settlement awaits your commands.</span>
|
||||
<span class="rts-log-timestamp">[00:00]</span>
|
||||
<span class="rts-log-message">You find yourself in the Golden Zoo as chaos erupts around you. The sounds of roaring and screaming fill the air.</span>
|
||||
</div>
|
||||
<div class="rts-log-entry rts-log-warning">
|
||||
<span class="rts-log-timestamp">[00:05]</span>
|
||||
<span class="rts-log-message">Multiple enclosures have been breached. Large predators are loose in the zoo.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* RTS Mode Full UI Styles */
|
||||
/* RTS Mode Full UI Styles - Zoo Emergency Theme */
|
||||
|
||||
#rts-main-container {
|
||||
position: fixed;
|
||||
@@ -128,7 +128,7 @@
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* Map Container - Match SillyTavern's main content area */
|
||||
/* Map Container - Enhanced with modern styling */
|
||||
#rts-map-container {
|
||||
background: var(--SmartThemeBodyColor);
|
||||
border: none;
|
||||
@@ -137,18 +137,29 @@
|
||||
width: var(--sheldWidth);
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.rts-map-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
margin: 10px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 12px 15px;
|
||||
margin: 8px;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(15px);
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.rts-map-header:hover {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.04) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.rts-map-header h3 {
|
||||
@@ -163,23 +174,66 @@
|
||||
|
||||
.rts-map-controls {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
gap: 6px;
|
||||
padding: 4px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.rts-map-controls .menu_button {
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.rts-map-controls .menu_button:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.rts-map-wrapper {
|
||||
position: relative;
|
||||
background: var(--SmartThemeBodyColor);
|
||||
background: linear-gradient(45deg, #1a2332 0%, #2d3748 50%, #1a202c 100%);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
margin: 8px;
|
||||
box-shadow:
|
||||
inset 0 0 30px rgba(0, 0, 0, 0.3),
|
||||
0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.rts-map-wrapper:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.rts-map-wrapper::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: radial-gradient(circle at 30% 20%, rgba(59, 130, 246, 0.1) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#rts-game-map {
|
||||
border: 1px solid var(--SmartThemeBorderColor);
|
||||
background: #1a2332;
|
||||
border: none;
|
||||
background: transparent;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
display: block;
|
||||
image-rendering: crisp-edges;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rts-map-overlay {
|
||||
@@ -189,28 +243,194 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* Element info tooltips */
|
||||
.rts-element-info {
|
||||
background: linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 30, 0.95) 100%);
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
min-width: 150px;
|
||||
max-width: 250px;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(10px);
|
||||
pointer-events: auto;
|
||||
animation: fadeInUp 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.rts-info-header {
|
||||
background: linear-gradient(90deg, rgba(139, 92, 246, 0.3) 0%, rgba(59, 130, 246, 0.2) 100%);
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-radius: 6px 6px 0 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.rts-info-close {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
border: 1px solid rgba(239, 68, 68, 0.4);
|
||||
color: #fca5a5;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.rts-info-close:hover {
|
||||
background: rgba(239, 68, 68, 0.4);
|
||||
border-color: rgba(239, 68, 68, 0.6);
|
||||
color: white;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.rts-info-content {
|
||||
padding: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.rts-info-content > div {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.rts-info-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-top: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.rts-info-actions .menu_button {
|
||||
font-size: 10px;
|
||||
padding: 4px 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.rts-info-actions .menu_button:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Context menu */
|
||||
.rts-context-menu {
|
||||
background: linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(20, 20, 30, 0.98) 100%);
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
min-width: 140px;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(15px);
|
||||
pointer-events: auto;
|
||||
z-index: 1000;
|
||||
animation: contextMenuFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
@keyframes contextMenuFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95) translateY(-5px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.rts-context-item {
|
||||
padding: 8px 12px;
|
||||
color: #e2e8f0;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
transition: all 0.15s ease;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.rts-context-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.rts-context-item:hover {
|
||||
background: linear-gradient(90deg, rgba(139, 92, 246, 0.3) 0%, rgba(59, 130, 246, 0.2) 100%);
|
||||
color: white;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.rts-context-separator {
|
||||
height: 1px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.rts-map-footer {
|
||||
padding: 15px;
|
||||
margin: 10px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 12px 15px;
|
||||
margin: 8px;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(15px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.rts-map-footer:hover {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.04) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.rts-turn-info {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
gap: 16px;
|
||||
font-size: 12px;
|
||||
color: var(--SmartThemeQuoteColor);
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.rts-turn-info > span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 4px 8px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.rts-turn-info > span:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.rts-separator {
|
||||
opacity: 0.5;
|
||||
opacity: 0.3;
|
||||
font-weight: 300;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
/* Quick Actions */
|
||||
@@ -334,3 +554,408 @@
|
||||
#rts-resource-panel li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
|
||||
/* ===== ENHANCED MAP CONTAINER IMPROVEMENTS ===== */
|
||||
|
||||
/* Enhanced Map Container Responsiveness */
|
||||
@media (max-width: 1200px) {
|
||||
.rts-map-header {
|
||||
padding: 10px 12px;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.rts-map-controls {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.rts-map-footer {
|
||||
padding: 10px 12px;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.rts-turn-info {
|
||||
gap: 12px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.rts-map-header {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rts-map-controls {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.rts-turn-info {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.rts-element-info {
|
||||
max-width: 200px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.rts-context-menu {
|
||||
min-width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map Loading States */
|
||||
.rts-map-loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 14px;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.rts-map-loading::before {
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
border-top: 2px solid rgba(139, 92, 246, 0.8);
|
||||
border-radius: 50%;
|
||||
animation: mapLoadingSpin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes mapLoadingSpin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Map Performance Optimizations */
|
||||
.rts-map-wrapper canvas {
|
||||
will-change: transform;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
}
|
||||
|
||||
/* Accessibility Improvements */
|
||||
.rts-map-controls .menu_button:focus {
|
||||
outline: 2px solid rgba(139, 92, 246, 0.6);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.rts-info-close:focus {
|
||||
outline: 2px solid rgba(239, 68, 68, 0.6);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Enhanced Visual Effects */
|
||||
.rts-map-wrapper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(
|
||||
45deg,
|
||||
rgba(255, 255, 255, 0.02) 0%,
|
||||
transparent 30%,
|
||||
transparent 70%,
|
||||
rgba(255, 255, 255, 0.02) 100%
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
animation: mapShimmer 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes mapShimmer {
|
||||
0%, 100% { opacity: 0.3; }
|
||||
50% { opacity: 0.7; }
|
||||
}
|
||||
|
||||
/* Map Interaction Feedback */
|
||||
.rts-map-wrapper.selecting {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.rts-map-wrapper.dragging {
|
||||
cursor: grabbing;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Minimap Enhancements */
|
||||
.rts-minimap-container {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 20;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.rts-minimap-container:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* Fog of War Visual Enhancement */
|
||||
.rts-fog-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
mix-blend-mode: multiply;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
/* ===== ZOO EMERGENCY SPECIFIC STYLES ===== */
|
||||
|
||||
/* Zoo Status Panel */
|
||||
.rts-zoo-status {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.rts-status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
background: rgba(220, 38, 38, 0.1);
|
||||
border: 1px solid rgba(220, 38, 38, 0.3);
|
||||
border-radius: 6px;
|
||||
font-size: 11px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.rts-status-item:hover {
|
||||
background: rgba(220, 38, 38, 0.15);
|
||||
border-color: rgba(220, 38, 38, 0.4);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.rts-status-item i {
|
||||
font-size: 12px;
|
||||
min-width: 14px;
|
||||
}
|
||||
|
||||
/* Animals List */
|
||||
.rts-animals-list, .rts-incidents-list, .rts-people-list {
|
||||
max-height: 120px;
|
||||
overflow-y: auto;
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.rts-animal-item, .rts-incident-item, .rts-person-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 8px;
|
||||
margin-bottom: 6px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
line-height: 1.3;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.rts-animal-item:last-child,
|
||||
.rts-incident-item:last-child,
|
||||
.rts-person-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.rts-animal-item:hover,
|
||||
.rts-incident-item:hover,
|
||||
.rts-person-item:hover {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
.rts-animal-item.rts-escaped {
|
||||
border-color: rgba(220, 38, 38, 0.4);
|
||||
background: rgba(220, 38, 38, 0.1);
|
||||
}
|
||||
|
||||
.rts-animal-name, .rts-person-name {
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.rts-animal-location, .rts-incident-location, .rts-person-location {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.rts-animal-status, .rts-person-status {
|
||||
font-weight: 500;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 9px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.rts-status-hunting {
|
||||
background: rgba(220, 38, 38, 0.3);
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
.rts-status-feeding {
|
||||
background: rgba(234, 88, 12, 0.3);
|
||||
color: #fed7aa;
|
||||
}
|
||||
|
||||
.rts-status-stalking {
|
||||
background: rgba(168, 85, 247, 0.3);
|
||||
color: #ddd6fe;
|
||||
}
|
||||
|
||||
.rts-status-injured {
|
||||
background: rgba(245, 158, 11, 0.3);
|
||||
color: #fde68a;
|
||||
}
|
||||
|
||||
.rts-status-trapped {
|
||||
background: rgba(34, 197, 94, 0.3);
|
||||
color: #bbf7d0;
|
||||
}
|
||||
|
||||
.rts-status-dying {
|
||||
background: rgba(127, 29, 29, 0.5);
|
||||
color: #fca5a5;
|
||||
animation: statusPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes statusPulse {
|
||||
0%, 100% { opacity: 0.7; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
|
||||
.rts-incident-desc {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Emergency Action Buttons */
|
||||
#rts-observe-btn {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.3) 0%, rgba(37, 99, 235, 0.2) 100%);
|
||||
border-color: rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
#rts-observe-btn:hover {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.4) 0%, rgba(37, 99, 235, 0.3) 100%);
|
||||
border-color: rgba(59, 130, 246, 0.6);
|
||||
}
|
||||
|
||||
#rts-move-btn {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.3) 0%, rgba(21, 128, 61, 0.2) 100%);
|
||||
border-color: rgba(34, 197, 94, 0.4);
|
||||
}
|
||||
|
||||
#rts-move-btn:hover {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.4) 0%, rgba(21, 128, 61, 0.3) 100%);
|
||||
border-color: rgba(34, 197, 94, 0.6);
|
||||
}
|
||||
|
||||
#rts-hide-btn {
|
||||
background: linear-gradient(135deg, rgba(168, 85, 247, 0.3) 0%, rgba(124, 58, 237, 0.2) 100%);
|
||||
border-color: rgba(168, 85, 247, 0.4);
|
||||
}
|
||||
|
||||
#rts-hide-btn:hover {
|
||||
background: linear-gradient(135deg, rgba(168, 85, 247, 0.4) 0%, rgba(124, 58, 237, 0.3) 100%);
|
||||
border-color: rgba(168, 85, 247, 0.6);
|
||||
}
|
||||
|
||||
#rts-interact-btn {
|
||||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.3) 0%, rgba(217, 119, 6, 0.2) 100%);
|
||||
border-color: rgba(245, 158, 11, 0.4);
|
||||
}
|
||||
|
||||
#rts-interact-btn:hover {
|
||||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.4) 0%, rgba(217, 119, 6, 0.3) 100%);
|
||||
border-color: rgba(245, 158, 11, 0.6);
|
||||
}
|
||||
|
||||
/* Emergency Log Entries */
|
||||
.rts-log-warning .rts-log-message {
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.rts-log-danger .rts-log-message {
|
||||
color: #ef4444;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.rts-log-death .rts-log-message {
|
||||
color: #dc2626;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 0 4px rgba(220, 38, 38, 0.3);
|
||||
}
|
||||
|
||||
.rts-log-escape .rts-log-message {
|
||||
color: #f97316;
|
||||
}
|
||||
|
||||
.rts-log-feeding .rts-log-message {
|
||||
color: #dc2626;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Zoo Map Filter Toggle */
|
||||
#rts-toggle-filter {
|
||||
background: linear-gradient(135deg, rgba(107, 114, 128, 0.3) 0%, rgba(75, 85, 99, 0.2) 100%);
|
||||
border-color: rgba(107, 114, 128, 0.4);
|
||||
}
|
||||
|
||||
#rts-toggle-filter:hover {
|
||||
background: linear-gradient(135deg, rgba(107, 114, 128, 0.4) 0%, rgba(75, 85, 99, 0.3) 100%);
|
||||
border-color: rgba(107, 114, 128, 0.6);
|
||||
}
|
||||
|
||||
#rts-toggle-filter.active {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.4) 0%, rgba(21, 128, 61, 0.3) 100%);
|
||||
border-color: rgba(34, 197, 94, 0.6);
|
||||
}
|
||||
|
||||
/* Alert level color coding */
|
||||
#rts-alert-level {
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
text-shadow: 0 0 4px rgba(220, 38, 38, 0.5);
|
||||
}
|
||||
|
||||
/* Breathing animation for critical elements */
|
||||
.rts-status-item:first-child {
|
||||
animation: emergencyBreathe 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes emergencyBreathe {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.4);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
+1019
-152
File diff suppressed because it is too large
Load Diff
+153
-55
@@ -109,29 +109,21 @@ export class RTSUIController {
|
||||
setupEventListeners() {
|
||||
console.log('RTS: Setting up event listeners for buttons...');
|
||||
|
||||
// Quick action buttons
|
||||
const buildBtn = document.getElementById('rts-build-btn');
|
||||
const recruitBtn = document.getElementById('rts-recruit-btn');
|
||||
const exploreBtn = document.getElementById('rts-explore-btn');
|
||||
const tradeBtn = document.getElementById('rts-trade-btn');
|
||||
// Zoo emergency action buttons
|
||||
const observeBtn = document.getElementById('rts-observe-btn');
|
||||
const moveBtn = document.getElementById('rts-move-btn');
|
||||
const hideBtn = document.getElementById('rts-hide-btn');
|
||||
const interactBtn = document.getElementById('rts-interact-btn');
|
||||
|
||||
console.log('RTS: Build button found:', !!buildBtn);
|
||||
console.log('RTS: Recruit button found:', !!recruitBtn);
|
||||
console.log('RTS: Explore button found:', !!exploreBtn);
|
||||
console.log('RTS: Trade button found:', !!tradeBtn);
|
||||
|
||||
buildBtn?.addEventListener('click', () => this.handleQuickAction('build'));
|
||||
recruitBtn?.addEventListener('click', () => this.handleQuickAction('recruit'));
|
||||
exploreBtn?.addEventListener('click', () => this.handleQuickAction('explore'));
|
||||
tradeBtn?.addEventListener('click', () => this.handleQuickAction('trade'));
|
||||
observeBtn?.addEventListener('click', () => this.handleQuickAction('observe'));
|
||||
moveBtn?.addEventListener('click', () => this.handleQuickAction('move'));
|
||||
hideBtn?.addEventListener('click', () => this.handleQuickAction('hide'));
|
||||
interactBtn?.addEventListener('click', () => this.handleQuickAction('interact'));
|
||||
|
||||
// Command execution
|
||||
const executeBtn = document.getElementById('rts-execute-btn');
|
||||
const clearBtn = document.getElementById('rts-clear-btn');
|
||||
|
||||
console.log('RTS: Execute button found:', !!executeBtn);
|
||||
console.log('RTS: Clear button found:', !!clearBtn);
|
||||
|
||||
executeBtn?.addEventListener('click', this.handleExecuteCommand);
|
||||
clearBtn?.addEventListener('click', this.handleClearCommand);
|
||||
|
||||
@@ -139,18 +131,17 @@ export class RTSUIController {
|
||||
const zoomInBtn = document.getElementById('rts-zoom-in');
|
||||
const zoomOutBtn = document.getElementById('rts-zoom-out');
|
||||
const centerBtn = document.getElementById('rts-center-map');
|
||||
|
||||
console.log('RTS: Zoom in button found:', !!zoomInBtn);
|
||||
console.log('RTS: Zoom out button found:', !!zoomOutBtn);
|
||||
console.log('RTS: Center button found:', !!centerBtn);
|
||||
const liveActionBtn = document.getElementById('rts-live-action-btn');
|
||||
const toggleFilterBtn = document.getElementById('rts-toggle-filter');
|
||||
|
||||
zoomInBtn?.addEventListener('click', () => this.handleMapControls('zoomIn'));
|
||||
zoomOutBtn?.addEventListener('click', () => this.handleMapControls('zoomOut'));
|
||||
centerBtn?.addEventListener('click', () => this.handleMapControls('center'));
|
||||
liveActionBtn?.addEventListener('click', () => this.handleLiveAction());
|
||||
toggleFilterBtn?.addEventListener('click', () => this.handleToggleFilter());
|
||||
|
||||
// Enter key in command input
|
||||
const commandInput = document.getElementById('rts-command-input');
|
||||
console.log('RTS: Command input found:', !!commandInput);
|
||||
|
||||
if (commandInput) {
|
||||
commandInput.addEventListener('keydown', (e) => {
|
||||
@@ -169,10 +160,10 @@ export class RTSUIController {
|
||||
if (!commandInput) return;
|
||||
|
||||
const actionTemplates = {
|
||||
build: 'Build a new structure. Specify type and location (e.g., "Build a barracks near the town hall")',
|
||||
recruit: 'Recruit new units. Specify type and quantity (e.g., "Recruit 5 warriors and 3 archers")',
|
||||
explore: 'Send units to explore. Specify direction or target (e.g., "Send scouts to explore the northern forest")',
|
||||
trade: 'Initiate trade with neighbors or manage resources (e.g., "Trade wood for gold with nearby village")'
|
||||
observe: 'Look around carefully to assess the situation. (e.g., "Look around the tiger exhibit for signs of the escaped animal")',
|
||||
move: 'Move to a specific location in the zoo. (e.g., "Carefully move toward the gift shop entrance")',
|
||||
hide: 'Find a hiding spot to avoid dangerous animals. (e.g., "Hide behind the overturned snack cart")',
|
||||
interact: 'Interact with something in the environment. (e.g., "Try to open the emergency exit door")'
|
||||
};
|
||||
|
||||
commandInput.value = actionTemplates[action] || '';
|
||||
@@ -247,6 +238,30 @@ export class RTSUIController {
|
||||
}
|
||||
}
|
||||
|
||||
handleLiveAction() {
|
||||
const liveActionWindow = window.open('/scripts/extensions/rts-mode/html/live-action.html', '_blank', 'width=1024,height=768');
|
||||
}
|
||||
|
||||
handleToggleFilter() {
|
||||
const toggleBtn = document.getElementById('rts-toggle-filter');
|
||||
if (!toggleBtn) return;
|
||||
|
||||
const isActive = toggleBtn.classList.toggle('active');
|
||||
|
||||
if (isActive) {
|
||||
this.addLogEntry('system', 'Exhibit status overlay activated - showing breach status');
|
||||
// Could trigger map filter changes
|
||||
if (this.mapCanvas) {
|
||||
this.mapCanvas.toggleExhibitFilter(true);
|
||||
}
|
||||
} else {
|
||||
this.addLogEntry('system', 'Exhibit status overlay deactivated');
|
||||
if (this.mapCanvas) {
|
||||
this.mapCanvas.toggleExhibitFilter(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleKeydown(e) {
|
||||
if (e.key === 'Escape') {
|
||||
this.exitFullscreen();
|
||||
@@ -269,9 +284,10 @@ export class RTSUIController {
|
||||
}
|
||||
|
||||
updateUI() {
|
||||
this.updateResourceDisplay();
|
||||
this.updateUnitsDisplay();
|
||||
this.updateBuildingsDisplay();
|
||||
this.updateZooStatusDisplay();
|
||||
this.updateEscapedAnimalsDisplay();
|
||||
this.updateIncidentsDisplay();
|
||||
this.updatePeopleStatusDisplay();
|
||||
this.updateTurnInfo();
|
||||
|
||||
if (this.mapCanvas) {
|
||||
@@ -279,48 +295,123 @@ export class RTSUIController {
|
||||
}
|
||||
}
|
||||
|
||||
updateResourceDisplay() {
|
||||
updateZooStatusDisplay() {
|
||||
const state = GameStateManager.getState();
|
||||
const resources = state.resources || {};
|
||||
const zooData = state.zoo || {};
|
||||
|
||||
this.updateElementText('rts-gold', resources.gold || 100);
|
||||
this.updateElementText('rts-wood', resources.wood || 50);
|
||||
this.updateElementText('rts-stone', resources.stone || 25);
|
||||
this.updateElementText('rts-food', resources.food || 75);
|
||||
this.updateElementText('rts-alert-level', zooData.alertLevel || 'CRITICAL');
|
||||
this.updateElementText('rts-survivors', zooData.survivors || 12);
|
||||
this.updateElementText('rts-casualties', zooData.casualties || 3);
|
||||
this.updateElementText('rts-breached', zooData.breachedEnclosures || 7);
|
||||
}
|
||||
|
||||
updateUnitsDisplay() {
|
||||
updateEscapedAnimalsDisplay() {
|
||||
const state = GameStateManager.getState();
|
||||
const units = state.units || [];
|
||||
const animalsContainer = document.getElementById('rts-escaped-animals');
|
||||
if (!animalsContainer) return;
|
||||
|
||||
// Count units by type
|
||||
const unitCounts = units.reduce((counts, unit) => {
|
||||
counts[unit.type] = (counts[unit.type] || 0) + 1;
|
||||
return counts;
|
||||
}, {});
|
||||
// Keep static example for now, but this would be populated from game state
|
||||
const escapedAnimals = state.escapedAnimals || [
|
||||
{ name: 'Siberian Tiger', location: 'Near Lion Exhibit', status: 'hunting' },
|
||||
{ name: 'Pack of Wolves', location: 'Main Pathway', status: 'stalking' },
|
||||
{ name: 'Grizzly Bear', location: 'Gift Shop Area', status: 'feeding' }
|
||||
];
|
||||
|
||||
this.updateElementText('rts-warriors', unitCounts.warrior || 5);
|
||||
this.updateElementText('rts-archers', unitCounts.archer || 3);
|
||||
this.updateElementText('rts-cavalry', unitCounts.cavalry || 2);
|
||||
// Clear existing content but preserve any static examples
|
||||
const existingItems = animalsContainer.querySelectorAll('.rts-animal-item:not([data-static])');
|
||||
existingItems.forEach(item => item.remove());
|
||||
|
||||
escapedAnimals.forEach(animal => {
|
||||
const animalElement = document.createElement('div');
|
||||
animalElement.className = 'rts-animal-item rts-escaped';
|
||||
animalElement.innerHTML = `
|
||||
<span class="rts-animal-name">
|
||||
<i class="fa-solid fa-paw" style="color: #dc2626;"></i>
|
||||
${animal.name}
|
||||
</span>
|
||||
<span class="rts-animal-location">${animal.location}</span>
|
||||
<span class="rts-animal-status rts-status-${animal.status}">${animal.status}</span>
|
||||
`;
|
||||
animalsContainer.appendChild(animalElement);
|
||||
});
|
||||
}
|
||||
|
||||
updateBuildingsDisplay() {
|
||||
updateIncidentsDisplay() {
|
||||
const state = GameStateManager.getState();
|
||||
// For now, use default values - this would be expanded based on game state
|
||||
const incidentsContainer = document.getElementById('rts-active-incidents');
|
||||
if (!incidentsContainer) return;
|
||||
|
||||
this.updateElementText('rts-town-hall', 1);
|
||||
this.updateElementText('rts-barracks', 1);
|
||||
this.updateElementText('rts-storage', 1);
|
||||
const incidents = state.incidents || [
|
||||
{ description: 'Visitor being stalked by wolf pack', location: 'Wolf Enclosure' },
|
||||
{ description: 'Security guard trapped in tiger exhibit', location: 'Tiger Exhibit' },
|
||||
{ description: 'Multiple people hiding in restroom', location: 'Public Restrooms' }
|
||||
];
|
||||
|
||||
// Clear existing content but preserve any static examples
|
||||
const existingItems = incidentsContainer.querySelectorAll('.rts-incident-item:not([data-static])');
|
||||
existingItems.forEach(item => item.remove());
|
||||
|
||||
incidents.forEach(incident => {
|
||||
const incidentElement = document.createElement('div');
|
||||
incidentElement.className = 'rts-incident-item';
|
||||
incidentElement.innerHTML = `
|
||||
<span class="rts-incident-desc">
|
||||
<i class="fa-solid fa-fire" style="color: #dc2626;"></i>
|
||||
${incident.description}
|
||||
</span>
|
||||
<span class="rts-incident-location">${incident.location}</span>
|
||||
`;
|
||||
incidentsContainer.appendChild(incidentElement);
|
||||
});
|
||||
}
|
||||
|
||||
updatePeopleStatusDisplay() {
|
||||
const state = GameStateManager.getState();
|
||||
const peopleContainer = document.getElementById('rts-people-status');
|
||||
if (!peopleContainer) return;
|
||||
|
||||
const people = state.people || [
|
||||
{ name: 'Mike (Security Guard)', status: 'injured', location: 'Main Gate' },
|
||||
{ name: 'Sarah (Zookeeper)', status: 'trapped', location: 'Elephant Exhibit' },
|
||||
{ name: 'Tom (Visitor)', status: 'dying', location: 'Tiger Exhibit' }
|
||||
];
|
||||
|
||||
// Clear existing content but preserve any static examples
|
||||
const existingItems = peopleContainer.querySelectorAll('.rts-person-item:not([data-static])');
|
||||
existingItems.forEach(item => item.remove());
|
||||
|
||||
people.forEach(person => {
|
||||
const personElement = document.createElement('div');
|
||||
personElement.className = 'rts-person-item';
|
||||
personElement.innerHTML = `
|
||||
<span class="rts-person-name">
|
||||
<i class="fa-solid fa-user" style="color: #ea580c;"></i>
|
||||
${person.name}
|
||||
</span>
|
||||
<span class="rts-person-status rts-status-${person.status}">${person.status}</span>
|
||||
<span class="rts-person-location">${person.location}</span>
|
||||
`;
|
||||
peopleContainer.appendChild(personElement);
|
||||
});
|
||||
}
|
||||
|
||||
updateTurnInfo() {
|
||||
const state = GameStateManager.getState();
|
||||
this.updateElementText('rts-current-turn', state.turn || 1);
|
||||
|
||||
// Simple season calculation based on turn
|
||||
const seasons = ['Spring', 'Summer', 'Autumn', 'Winter'];
|
||||
const season = seasons[Math.floor((state.turn || 1) / 10) % 4];
|
||||
this.updateElementText('rts-season', season);
|
||||
// For zoo scenario, show elapsed time instead of turns
|
||||
const elapsedMinutes = (state.turn || 1) * 5; // Each turn = 5 minutes
|
||||
const hours = Math.floor(elapsedMinutes / 60);
|
||||
const minutes = elapsedMinutes % 60;
|
||||
const timeString = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
|
||||
this.updateElementText('rts-current-turn', timeString);
|
||||
|
||||
// Show time of day instead of season
|
||||
const startHour = 14; // 2 PM start
|
||||
const currentHour = (startHour + Math.floor(elapsedMinutes / 60)) % 24;
|
||||
const timeOfDay = currentHour < 6 ? 'Night' :
|
||||
currentHour < 12 ? 'Morning' :
|
||||
currentHour < 18 ? 'Afternoon' : 'Evening';
|
||||
this.updateElementText('rts-season', timeOfDay);
|
||||
}
|
||||
|
||||
updateElementText(id, value) {
|
||||
@@ -376,3 +467,10 @@ export class RTSUIController {
|
||||
|
||||
// Global instance
|
||||
export const rtsUI = new RTSUIController();
|
||||
|
||||
// Listen for game state updates
|
||||
document.addEventListener('rts-state-updated', () => {
|
||||
if (rtsUI.isActive()) {
|
||||
rtsUI.updateUI();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user