Auto torches on claim, pickup by entity index, document planned features

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-02 22:30:53 +01:00
1 parent 80f8335b6d
commit 58c1041173
2 files changed
+56 -2

No files matched your search

+8
View File
@@ -22,6 +22,14 @@ Eigenständiges Dungeon-Management-Spiel (Genre: Dungeon-Aufbau & Verteidigung),
- Linksklick: aktives Werkzeug benutzen (Rechteck aufziehen für Graben/Räume)
- Rechtsklick: Einheit aus der Hand absetzen
- Kamera: WASD/Pfeiltasten, rechte Maus ziehen, Mausrad-Zoom, Bildschirmrand
- Drehen/Neigen: mittlere Maustaste ziehen, Q/E drehen, R/F neigen
- Zauber: 0 Blitz, X Heilung, V Wicht beschwören
- Fackeln: automatisch beim Erobern; fremde Gebiete schummrig sichtbar
## Geplant (nach 3D)
- Repo komplett auf Englisch; Spieltexte in separaten Sprachdateien (EN + DE, erweiterbar), Sprache im Spiel umschaltbar
- Menü: Speichern (Download *.dcsave), Laden (Dateiauswahl + Drag & Drop), Autosave im Browser (localStorage)
- Einstellungen: Sprache + Ton, Kamera, Grafik, Spiel, Tastenbelegung – gespeichert im Browser **und** im Savegame
## Spielinhalt (volles Konzept)
- **Graben**: Erde/Gold markieren → Grubenwichte graben, bringen Gold heim, erobern Boden
+48 -2
View File
@@ -236,9 +236,26 @@ pub struct Game {
pub flag: Option<usize>,
pub events: Vec<SfxEvent>,
pub last_wave_value: f32,
pub torches: Vec<Torch>,
hint_t: [f32; 16],
}
// Fackel an einer Wandseite: Wandkachel + Richtung (Index in DIR4) zur offenen Seite
#[derive(Clone, Copy, PartialEq)]
pub struct Torch {
pub wall: usize,
pub dir: usize,
}
impl Torch {
// Weltposition der Flamme (x, z) auf Bodenebene
pub fn pos(&self) -> (f32, f32) {
let (x, y) = xy(self.wall);
let (dx, dy) = DIR4[self.dir];
(x as f32 + 0.5 + dx as f32 * 0.58, y as f32 + 0.5 + dy as f32 * 0.58)
}
}
pub const ROOM_KINDS: [Kind; 5] = [Kind::Treasury, Kind::Lair, Kind::Farm, Kind::Training, Kind::Library];
pub const ROOM_COST: [i32; 5] = [60, 80, 100, 140, 160];
pub const ROOM_NAMES: [&str; 5] = ["Schatzkammer", "Quartier", "Pilzgarten", "Trainingshalle", "Bibliothek"];
@@ -290,6 +307,7 @@ impl Game {
flag: None,
events: Vec::new(),
last_wave_value: 0.0,
torches: Vec::new(),
hint_t: [-1000.0; 16],
};
let (cx, cy) = g.map.core;
@@ -297,6 +315,11 @@ impl Game {
g.spawn(EK::Worker, false, cx as f32 - 0.5, cy as f32 + k as f32 * 0.7 + 0.3, 1);
}
g.recount();
for i in 0..N {
if g.map.t[i].owner == Owner::Player {
g.place_torches(i);
}
}
g.msg("Willkommen, Herrscher des Unterreichs! Beschütze deinen Seelenkern und zerstöre das Heldentor.".into());
g.msg("Markiere Erde und Goldadern mit dem Werkzeug »Graben« (Taste 1). Deine Grubenwichte erledigen den Rest.".into());
g.msg("Grabe dich zum Portal durch und erobere es. Kreaturen brauchen ein Quartier und einen Pilzgarten.".into());
@@ -339,6 +362,27 @@ impl Game {
(h * d).sqrt()
}
// Wichte hängen Fackeln an Wände neben erobertem Boden (Mindestabstand 3,5 Felder)
pub fn place_torches(&mut self, i: usize) {
let (x, y) = xy(i);
for (d, &(dx, dy)) in DIR4.iter().enumerate() {
let (wx, wy) = (x + dx, y + dy);
if !inb(wx, wy) || !self.map.t[idx(wx, wy)].solid() {
continue;
}
// Richtung von der Wand zum Boden ist die Gegenrichtung
let t = Torch { wall: idx(wx, wy), dir: (d + 2) % 4 };
let (px, pz) = t.pos();
let near = self.torches.iter().any(|o| {
let (ox, oz) = o.pos();
(ox - px).powi(2) + (oz - pz).powi(2) < 3.5 * 3.5
});
if !near {
self.torches.push(t);
}
}
}
fn hint(&mut self, key: usize, s: &str) {
if self.time - self.hint_t[key] > 30.0 {
self.hint_t[key] = self.time;
@@ -782,6 +826,7 @@ impl Game {
}
pub fn dig_out(&mut self, i: usize) {
self.torches.retain(|t| t.wall != i);
let t = &mut self.map.t[i];
t.kind = Kind::Floor;
t.owner = Owner::None;
@@ -1072,6 +1117,7 @@ impl Game {
} else {
self.map.t[t].owner = Owner::Player;
}
self.place_torches(t);
let (x, y) = xy(t);
self.fx(8, x as f32 + 0.5, y as f32 + 0.5, 0.0, 0.0, 0.5, 0xff4040e0);
self.sfx(Sfx::Claim, x as f32 + 0.5, y as f32 + 0.5);
@@ -1653,12 +1699,12 @@ impl Game {
best
}
pub fn pickup(&mut self, wx: f32, wy: f32) -> bool {
pub fn pickup(&mut self, target: Option<usize>) -> bool {
if self.hand.len() >= 8 {
self.hint(8, "Deine Hand ist voll (max. 8). Rechtsklick lässt Einheiten fallen.");
return false;
}
if let Some(j) = self.ent_at(wx, wy, true) {
if let Some(j) = target.filter(|&j| j < self.ents.len() && self.ents[j].alive && !self.ents[j].held && !self.ents[j].hero) {
let id = self.ents[j].id;
let me = id + 1;
self.unreserve(me);