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)
|
||||
- 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
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user