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:
1 parent
80f8335b6d
commit
58c1041173
2 files changed
+56
-2
No files matched your search
@@ -22,6 +22,14 @@ Eigenständiges Dungeon-Management-Spiel (Genre: Dungeon-Aufbau & Verteidigung),
|
|||||||
- Linksklick: aktives Werkzeug benutzen (Rechteck aufziehen für Graben/Räume)
|
- Linksklick: aktives Werkzeug benutzen (Rechteck aufziehen für Graben/Räume)
|
||||||
- Rechtsklick: Einheit aus der Hand absetzen
|
- Rechtsklick: Einheit aus der Hand absetzen
|
||||||
- Kamera: WASD/Pfeiltasten, rechte Maus ziehen, Mausrad-Zoom, Bildschirmrand
|
- 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)
|
## Spielinhalt (volles Konzept)
|
||||||
- **Graben**: Erde/Gold markieren → Grubenwichte graben, bringen Gold heim, erobern Boden
|
- **Graben**: Erde/Gold markieren → Grubenwichte graben, bringen Gold heim, erobern Boden
|
||||||
|
|||||||
+48
-2
@@ -236,9 +236,26 @@ pub struct Game {
|
|||||||
pub flag: Option<usize>,
|
pub flag: Option<usize>,
|
||||||
pub events: Vec<SfxEvent>,
|
pub events: Vec<SfxEvent>,
|
||||||
pub last_wave_value: f32,
|
pub last_wave_value: f32,
|
||||||
|
pub torches: Vec<Torch>,
|
||||||
hint_t: [f32; 16],
|
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_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_COST: [i32; 5] = [60, 80, 100, 140, 160];
|
||||||
pub const ROOM_NAMES: [&str; 5] = ["Schatzkammer", "Quartier", "Pilzgarten", "Trainingshalle", "Bibliothek"];
|
pub const ROOM_NAMES: [&str; 5] = ["Schatzkammer", "Quartier", "Pilzgarten", "Trainingshalle", "Bibliothek"];
|
||||||
@@ -290,6 +307,7 @@ impl Game {
|
|||||||
flag: None,
|
flag: None,
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
last_wave_value: 0.0,
|
last_wave_value: 0.0,
|
||||||
|
torches: Vec::new(),
|
||||||
hint_t: [-1000.0; 16],
|
hint_t: [-1000.0; 16],
|
||||||
};
|
};
|
||||||
let (cx, cy) = g.map.core;
|
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.spawn(EK::Worker, false, cx as f32 - 0.5, cy as f32 + k as f32 * 0.7 + 0.3, 1);
|
||||||
}
|
}
|
||||||
g.recount();
|
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("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("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());
|
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()
|
(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) {
|
fn hint(&mut self, key: usize, s: &str) {
|
||||||
if self.time - self.hint_t[key] > 30.0 {
|
if self.time - self.hint_t[key] > 30.0 {
|
||||||
self.hint_t[key] = self.time;
|
self.hint_t[key] = self.time;
|
||||||
@@ -782,6 +826,7 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dig_out(&mut self, i: usize) {
|
pub fn dig_out(&mut self, i: usize) {
|
||||||
|
self.torches.retain(|t| t.wall != i);
|
||||||
let t = &mut self.map.t[i];
|
let t = &mut self.map.t[i];
|
||||||
t.kind = Kind::Floor;
|
t.kind = Kind::Floor;
|
||||||
t.owner = Owner::None;
|
t.owner = Owner::None;
|
||||||
@@ -1072,6 +1117,7 @@ impl Game {
|
|||||||
} else {
|
} else {
|
||||||
self.map.t[t].owner = Owner::Player;
|
self.map.t[t].owner = Owner::Player;
|
||||||
}
|
}
|
||||||
|
self.place_torches(t);
|
||||||
let (x, y) = xy(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.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);
|
self.sfx(Sfx::Claim, x as f32 + 0.5, y as f32 + 0.5);
|
||||||
@@ -1653,12 +1699,12 @@ impl Game {
|
|||||||
best
|
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 {
|
if self.hand.len() >= 8 {
|
||||||
self.hint(8, "Deine Hand ist voll (max. 8). Rechtsklick lässt Einheiten fallen.");
|
self.hint(8, "Deine Hand ist voll (max. 8). Rechtsklick lässt Einheiten fallen.");
|
||||||
return false;
|
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 id = self.ents[j].id;
|
||||||
let me = id + 1;
|
let me = id + 1;
|
||||||
self.unreserve(me);
|
self.unreserve(me);
|
||||||
|
|||||||
Reference in new issue
Block a user