Room levels 2 and 3, researched in the library: a quarter better each, brighter, with gold trim
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f7b550a6b1
commit
9b49bc2c9d
23 files changed
+171
-10
No files matched your search
@@ -939,6 +939,7 @@ research.now = Zkoumá se: {0} ({1} %)
|
|||||||
research.next = pak: {0}
|
research.next = pak: {0}
|
||||||
research.done = Tady už nezbývá nic ke zkoumání.
|
research.done = Tady už nezbývá nic ke zkoumání.
|
||||||
msg.researched = Vyzkoumáno: {0}! Je to teď v nabídce stavby.
|
msg.researched = Vyzkoumáno: {0}! Je to teď v nabídce stavby.
|
||||||
|
msg.room_upgraded = Výzkum: {0} dosahuje úrovně {1} – funguje o čtvrtinu lépe a je to vidět.
|
||||||
msg.tool_research = Ještě nevyzkoumáno - pracují na tom tvorové studující v knihovně.
|
msg.tool_research = Ještě nevyzkoumáno - pracují na tom tvorové studující v knihovně.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -938,6 +938,7 @@ research.now = Forsker i: {0} ({1}%)
|
|||||||
research.next = derefter: {0}
|
research.next = derefter: {0}
|
||||||
research.done = Intet mere at forske i her.
|
research.done = Intet mere at forske i her.
|
||||||
msg.researched = Udforsket: {0}! Det findes nu i byggemenuen.
|
msg.researched = Udforsket: {0}! Det findes nu i byggemenuen.
|
||||||
|
msg.room_upgraded = Forskning: {0} når niveau {1} – virker en fjerdedel bedre, og det kan ses.
|
||||||
msg.tool_research = Endnu ikke udforsket - væsner, der studerer i biblioteket, arbejder på det.
|
msg.tool_research = Endnu ikke udforsket - væsner, der studerer i biblioteket, arbejder på det.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -938,6 +938,7 @@ research.now = Erforscht: {0} ({1}%)
|
|||||||
research.next = danach: {0}
|
research.next = danach: {0}
|
||||||
research.done = Hier gibt es nichts mehr zu erforschen.
|
research.done = Hier gibt es nichts mehr zu erforschen.
|
||||||
msg.researched = Erforscht: {0}! Jetzt im Baumenü.
|
msg.researched = Erforscht: {0}! Jetzt im Baumenü.
|
||||||
|
msg.room_upgraded = Forschung: {0} erreicht Stufe {1} – arbeitet ein Viertel besser, und man sieht es.
|
||||||
msg.tool_research = Noch nicht erforscht - Kreaturen in der Bibliothek arbeiten daran.
|
msg.tool_research = Noch nicht erforscht - Kreaturen in der Bibliothek arbeiten daran.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Έρευνα: {0} ({1}%)
|
|||||||
research.next = μετά: {0}
|
research.next = μετά: {0}
|
||||||
research.done = Δεν μένει τίποτα για έρευνα εδώ.
|
research.done = Δεν μένει τίποτα για έρευνα εδώ.
|
||||||
msg.researched = Ερευνήθηκε: {0}! Είναι πλέον στο μενού κατασκευής.
|
msg.researched = Ερευνήθηκε: {0}! Είναι πλέον στο μενού κατασκευής.
|
||||||
|
msg.room_upgraded = Έρευνα: {0} φτάνει στο επίπεδο {1} – δουλεύει ένα τέταρτο καλύτερα, και φαίνεται.
|
||||||
msg.tool_research = Δεν έχει ερευνηθεί ακόμη - τα πλάσματα που μελετούν στη βιβλιοθήκη δουλεύουν πάνω του.
|
msg.tool_research = Δεν έχει ερευνηθεί ακόμη - τα πλάσματα που μελετούν στη βιβλιοθήκη δουλεύουν πάνω του.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Researching: {0} ({1}%)
|
|||||||
research.next = then: {0}
|
research.next = then: {0}
|
||||||
research.done = Nothing left to research here.
|
research.done = Nothing left to research here.
|
||||||
msg.researched = Researched: {0}! It is in the build menu now.
|
msg.researched = Researched: {0}! It is in the build menu now.
|
||||||
|
msg.room_upgraded = Research: {0} reaches level {1} – it works a quarter better, and it shows.
|
||||||
msg.tool_research = Not researched yet - creatures studying in the library work on it.
|
msg.tool_research = Not researched yet - creatures studying in the library work on it.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -931,6 +931,7 @@ research.now = Investigando: {0} ({1}%)
|
|||||||
research.next = después: {0}
|
research.next = después: {0}
|
||||||
research.done = Aquí no queda nada por investigar.
|
research.done = Aquí no queda nada por investigar.
|
||||||
msg.researched = Investigado: ¡{0}! Ya está en el menú de construcción.
|
msg.researched = Investigado: ¡{0}! Ya está en el menú de construcción.
|
||||||
|
msg.room_upgraded = Investigación: {0} alcanza el nivel {1}: funciona un cuarto mejor, y se nota.
|
||||||
msg.tool_research = Aún no investigado: las criaturas que estudian en la biblioteca trabajan en ello.
|
msg.tool_research = Aún no investigado: las criaturas que estudian en la biblioteca trabajan en ello.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Tutkitaan: {0} ({1}%)
|
|||||||
research.next = sitten: {0}
|
research.next = sitten: {0}
|
||||||
research.done = Täällä ei ole enää mitään tutkittavaa.
|
research.done = Täällä ei ole enää mitään tutkittavaa.
|
||||||
msg.researched = Tutkittu: {0}! Se on nyt rakennusvalikossa.
|
msg.researched = Tutkittu: {0}! Se on nyt rakennusvalikossa.
|
||||||
|
msg.room_upgraded = Tutkimus: {0} saavuttaa tason {1} – toimii neljänneksen paremmin, ja sen näkee.
|
||||||
msg.tool_research = Ei vielä tutkittu - kirjastossa opiskelevat olennot työstävät sitä.
|
msg.tool_research = Ei vielä tutkittu - kirjastossa opiskelevat olennot työstävät sitä.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Istražuje se: {0} ({1}%)
|
|||||||
research.next = zatim: {0}
|
research.next = zatim: {0}
|
||||||
research.done = Ovdje više nema što istraživati.
|
research.done = Ovdje više nema što istraživati.
|
||||||
msg.researched = Istraženo: {0}! Sad je u izborniku gradnje.
|
msg.researched = Istraženo: {0}! Sad je u izborniku gradnje.
|
||||||
|
msg.room_upgraded = Istraživanje: {0} doseže razinu {1} – radi četvrtinu bolje, i to se vidi.
|
||||||
msg.tool_research = Još nije istraženo - stvorenja koja uče u knjižnici rade na tome.
|
msg.tool_research = Još nije istraženo - stvorenja koja uče u knjižnici rade na tome.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Kutatás: {0} ({1}%)
|
|||||||
research.next = utána: {0}
|
research.next = utána: {0}
|
||||||
research.done = Itt már nincs mit kutatni.
|
research.done = Itt már nincs mit kutatni.
|
||||||
msg.researched = Kikutatva: {0}! Már az építési menüben van.
|
msg.researched = Kikutatva: {0}! Már az építési menüben van.
|
||||||
|
msg.room_upgraded = Kutatás: {0} eléri a(z) {1}. szintet – negyedével jobban működik, és látszik is.
|
||||||
msg.tool_research = Még nincs kikutatva - a könyvtárban tanuló lények dolgoznak rajta.
|
msg.tool_research = Még nincs kikutatva - a könyvtárban tanuló lények dolgoznak rajta.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -931,6 +931,7 @@ research.now = In ricerca: {0} ({1}%)
|
|||||||
research.next = poi: {0}
|
research.next = poi: {0}
|
||||||
research.done = Qui non resta niente da ricercare.
|
research.done = Qui non resta niente da ricercare.
|
||||||
msg.researched = Ricerca completata: {0}! Ora è nel menu di costruzione.
|
msg.researched = Ricerca completata: {0}! Ora è nel menu di costruzione.
|
||||||
|
msg.room_upgraded = Ricerca: {0} raggiunge il livello {1}: funziona un quarto meglio, e si vede.
|
||||||
msg.tool_research = Non ancora ricercato - ci lavorano le creature che studiano in biblioteca.
|
msg.tool_research = Non ancora ricercato - ci lavorano le creature che studiano in biblioteca.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Onderzoekt: {0} ({1}%)
|
|||||||
research.next = daarna: {0}
|
research.next = daarna: {0}
|
||||||
research.done = Hier valt niets meer te onderzoeken.
|
research.done = Hier valt niets meer te onderzoeken.
|
||||||
msg.researched = Onderzocht: {0}! Het staat nu in het bouwmenu.
|
msg.researched = Onderzocht: {0}! Het staat nu in het bouwmenu.
|
||||||
|
msg.room_upgraded = Onderzoek: {0} bereikt niveau {1} – werkt een kwart beter, en dat zie je.
|
||||||
msg.tool_research = Nog niet onderzocht - wezens die in de bibliotheek studeren, werken eraan.
|
msg.tool_research = Nog niet onderzocht - wezens die in de bibliotheek studeren, werken eraan.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -938,6 +938,7 @@ research.now = Forsker på: {0} ({1}%)
|
|||||||
research.next = deretter: {0}
|
research.next = deretter: {0}
|
||||||
research.done = Ingenting mer å forske på her.
|
research.done = Ingenting mer å forske på her.
|
||||||
msg.researched = Utforsket: {0}! Det finnes nå i byggemenyen.
|
msg.researched = Utforsket: {0}! Det finnes nå i byggemenyen.
|
||||||
|
msg.room_upgraded = Forskning: {0} når nivå {1} – virker en fjerdedel bedre, og det synes.
|
||||||
msg.tool_research = Ikke utforsket ennå - skapninger som studerer i biblioteket, jobber med det.
|
msg.tool_research = Ikke utforsket ennå - skapninger som studerer i biblioteket, jobber med det.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = A investigar: {0} ({1}%)
|
|||||||
research.next = depois: {0}
|
research.next = depois: {0}
|
||||||
research.done = Já não há nada para investigar aqui.
|
research.done = Já não há nada para investigar aqui.
|
||||||
msg.researched = Investigado: {0}! Já está no menu de construção.
|
msg.researched = Investigado: {0}! Já está no menu de construção.
|
||||||
|
msg.room_upgraded = Investigação: {0} atinge o nível {1} – funciona um quarto melhor, e nota-se.
|
||||||
msg.tool_research = Ainda não investigado - as criaturas que estudam na biblioteca estão a tratar disso.
|
msg.tool_research = Ainda não investigado - as criaturas que estudam na biblioteca estão a tratar disso.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Se cercetează: {0} ({1}%)
|
|||||||
research.next = apoi: {0}
|
research.next = apoi: {0}
|
||||||
research.done = Nu mai e nimic de cercetat aici.
|
research.done = Nu mai e nimic de cercetat aici.
|
||||||
msg.researched = Cercetat: {0}! E acum în meniul de construcție.
|
msg.researched = Cercetat: {0}! E acum în meniul de construcție.
|
||||||
|
msg.room_upgraded = Cercetare: {0} atinge nivelul {1} – funcționează cu un sfert mai bine, și se vede.
|
||||||
msg.tool_research = Încă necercetat - creaturile care studiază în bibliotecă lucrează la asta.
|
msg.tool_research = Încă necercetat - creaturile care studiază în bibliotecă lucrează la asta.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -931,6 +931,7 @@ research.now = Исследуется: {0} ({1}%)
|
|||||||
research.next = затем: {0}
|
research.next = затем: {0}
|
||||||
research.done = Здесь больше нечего исследовать.
|
research.done = Здесь больше нечего исследовать.
|
||||||
msg.researched = Исследовано: {0}! Теперь это в меню строительства.
|
msg.researched = Исследовано: {0}! Теперь это в меню строительства.
|
||||||
|
msg.room_upgraded = Исследование: {0} достигает уровня {1} — работает на четверть лучше, и это видно.
|
||||||
msg.tool_research = Ещё не исследовано - над этим работают существа, что учатся в библиотеке.
|
msg.tool_research = Ещё не исследовано - над этим работают существа, что учатся в библиотеке.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Skúma sa: {0} ({1} %)
|
|||||||
research.next = potom: {0}
|
research.next = potom: {0}
|
||||||
research.done = Tu už nezostáva nič na skúmanie.
|
research.done = Tu už nezostáva nič na skúmanie.
|
||||||
msg.researched = Preskúmané: {0}! Je to teraz v ponuke stavby.
|
msg.researched = Preskúmané: {0}! Je to teraz v ponuke stavby.
|
||||||
|
msg.room_upgraded = Výskum: {0} dosahuje úroveň {1} – funguje o štvrtinu lepšie a je to vidieť.
|
||||||
msg.tool_research = Ešte nepreskúmané - pracujú na tom tvory študujúce v knižnici.
|
msg.tool_research = Ešte nepreskúmané - pracujú na tom tvory študujúce v knižnici.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Истражује се: {0} ({1}%)
|
|||||||
research.next = затим: {0}
|
research.next = затим: {0}
|
||||||
research.done = Овде више нема шта да се истражи.
|
research.done = Овде више нема шта да се истражи.
|
||||||
msg.researched = Истражено: {0}! Сад је у менију градње.
|
msg.researched = Истражено: {0}! Сад је у менију градње.
|
||||||
|
msg.room_upgraded = Истраживање: {0} достиже ниво {1} – ради четвртину боље, и то се види.
|
||||||
msg.tool_research = Још није истражено - створења која уче у библиотеци раде на томе.
|
msg.tool_research = Још није истражено - створења која уче у библиотеци раде на томе.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ research.now = Forskar: {0} ({1}%)
|
|||||||
research.next = sedan: {0}
|
research.next = sedan: {0}
|
||||||
research.done = Inget kvar att forska på här.
|
research.done = Inget kvar att forska på här.
|
||||||
msg.researched = Utforskat: {0}! Det finns nu i byggmenyn.
|
msg.researched = Utforskat: {0}! Det finns nu i byggmenyn.
|
||||||
|
msg.room_upgraded = Forskning: {0} når nivå {1} – fungerar en fjärdedel bättre, och det syns.
|
||||||
msg.tool_research = Inte utforskat än - varelser som studerar i biblioteket arbetar på det.
|
msg.tool_research = Inte utforskat än - varelser som studerar i biblioteket arbetar på det.
|
||||||
|
|
||||||
msg.script = {0}
|
msg.script = {0}
|
||||||
|
|||||||
+35
-8
@@ -486,6 +486,7 @@ pub struct MasterState {
|
|||||||
pub incoming: Vec<(u8, f32, Option<usize>)>,
|
pub incoming: Vec<(u8, f32, Option<usize>)>,
|
||||||
pub training_bill: f32,
|
pub training_bill: f32,
|
||||||
pub counts: [usize; N_ROOMS],
|
pub counts: [usize; N_ROOMS],
|
||||||
|
pub room_level: Vec<u8>,
|
||||||
pub springs: usize,
|
pub springs: usize,
|
||||||
pub known: Vec<bool>,
|
pub known: Vec<bool>,
|
||||||
pub researchable: Vec<bool>,
|
pub researchable: Vec<bool>,
|
||||||
@@ -522,6 +523,8 @@ pub struct Game {
|
|||||||
pub hand: Vec<u32>,
|
pub hand: Vec<u32>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub counts: [usize; N_ROOMS], // room tiles per room kind (ROOM_KINDS order, recounted)
|
pub counts: [usize; N_ROOMS], // room tiles per room kind (ROOM_KINDS order, recounted)
|
||||||
|
#[serde(default)]
|
||||||
|
pub room_level: Vec<u8>, // level of every room kind (ROOM_KINDS order; 1 when missing), researched
|
||||||
pub gate_hp: f32,
|
pub gate_hp: f32,
|
||||||
pub gate_hit_t: f32,
|
pub gate_hit_t: f32,
|
||||||
pub gate_stage: u32, // defender thresholds triggered (0..3)
|
pub gate_stage: u32, // defender thresholds triggered (0..3)
|
||||||
@@ -783,6 +786,18 @@ pub fn room_index(k: Kind) -> Option<usize> {
|
|||||||
ROOM_KINDS.iter().position(|&r| r == k)
|
ROOM_KINDS.iter().position(|&r| r == k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Game {
|
||||||
|
// the researched level of a room kind of the master being processed (1, 2 or 3)
|
||||||
|
pub fn room_level_of(&self, k: Kind) -> u8 {
|
||||||
|
room_index(k).and_then(|r| self.room_level.get(r).copied()).unwrap_or(1).max(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// how much better a room works at its level: +25% per level above the first
|
||||||
|
pub fn room_bonus(&self, k: Kind) -> f32 {
|
||||||
|
1.0 + 0.25 * (self.room_level_of(k) - 1) as f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn adj4(a: usize, b: usize) -> bool {
|
pub(crate) fn adj4(a: usize, b: usize) -> bool {
|
||||||
let (ax, ay) = xy(a);
|
let (ax, ay) = xy(a);
|
||||||
let (bx, by) = xy(b);
|
let (bx, by) = xy(b);
|
||||||
@@ -866,6 +881,7 @@ impl Game {
|
|||||||
paused: false,
|
paused: false,
|
||||||
hand: Vec::new(),
|
hand: Vec::new(),
|
||||||
counts: [0; N_ROOMS],
|
counts: [0; N_ROOMS],
|
||||||
|
room_level: Vec::new(),
|
||||||
gate_hp: GATE_HP,
|
gate_hp: GATE_HP,
|
||||||
gate_hit_t: -100.0,
|
gate_hit_t: -100.0,
|
||||||
gate_stage: 0,
|
gate_stage: 0,
|
||||||
@@ -1126,7 +1142,7 @@ impl Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn gold_cap(&self) -> f32 {
|
pub fn gold_cap(&self) -> f32 {
|
||||||
CORE_STORE + TREASURY_TILE * self.counts[0] as f32
|
CORE_STORE + TREASURY_TILE * self.counts[0] as f32 * self.room_bonus(Kind::Treasury)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_gold(&mut self, amount: f32) -> f32 {
|
pub fn add_gold(&mut self, amount: f32) -> f32 {
|
||||||
@@ -1433,6 +1449,7 @@ impl Game {
|
|||||||
incoming: std::mem::take(&mut self.incoming),
|
incoming: std::mem::take(&mut self.incoming),
|
||||||
training_bill: self.training_bill,
|
training_bill: self.training_bill,
|
||||||
counts: self.counts,
|
counts: self.counts,
|
||||||
|
room_level: self.room_level.clone(),
|
||||||
springs: self.springs,
|
springs: self.springs,
|
||||||
known: std::mem::take(&mut self.known),
|
known: std::mem::take(&mut self.known),
|
||||||
researchable: std::mem::take(&mut self.researchable),
|
researchable: std::mem::take(&mut self.researchable),
|
||||||
@@ -1463,6 +1480,7 @@ impl Game {
|
|||||||
self.incoming = m.incoming;
|
self.incoming = m.incoming;
|
||||||
self.training_bill = m.training_bill;
|
self.training_bill = m.training_bill;
|
||||||
self.counts = m.counts;
|
self.counts = m.counts;
|
||||||
|
self.room_level = m.room_level;
|
||||||
self.springs = m.springs;
|
self.springs = m.springs;
|
||||||
self.known = m.known;
|
self.known = m.known;
|
||||||
self.researchable = m.researchable;
|
self.researchable = m.researchable;
|
||||||
@@ -1606,9 +1624,17 @@ impl Game {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.time += dt;
|
self.time += dt;
|
||||||
|
// mushroom gardens grow faster at a higher level (of the master who owns them)
|
||||||
|
let farm = Kind::Farm;
|
||||||
|
let lv: Vec<(Owner, f32)> = self.master_sides().into_iter().map(|s| (Owner::of_side(s), {
|
||||||
|
let r = room_index(farm).unwrap_or(0);
|
||||||
|
let l = if s == self.me_side { self.room_level.get(r).copied() } else { self.masters.iter().find(|m| m.side == s).and_then(|m| m.room_level.get(r).copied()) };
|
||||||
|
1.0 + 0.25 * (l.unwrap_or(1).max(1) - 1) as f32
|
||||||
|
})).collect();
|
||||||
for t in self.map.t.iter_mut() {
|
for t in self.map.t.iter_mut() {
|
||||||
if t.kind == Kind::Farm {
|
if t.kind == Kind::Farm {
|
||||||
t.food = (t.food + dt / 18.0).min(3.0);
|
let f = lv.iter().find(|x| x.0 == t.owner).map_or(1.0, |x| x.1);
|
||||||
|
t.food = (t.food + dt * f / 18.0).min(3.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for side in self.master_sides() {
|
for side in self.master_sides() {
|
||||||
@@ -3798,8 +3824,9 @@ impl Game {
|
|||||||
}
|
}
|
||||||
// resting heals: quickly in a bed room, slower next to the core; back to work at 75%
|
// resting heals: quickly in a bed room, slower next to the core; back to work at 75%
|
||||||
let bed_room = matches!(self.map.t[b].kind, Kind::Lair | Kind::Aerie);
|
let bed_room = matches!(self.map.t[b].kind, Kind::Lair | Kind::Aerie);
|
||||||
e.hp = (e.hp + e.max_hp * dt / if bed_room { 12.0 } else { 24.0 }).min(e.max_hp);
|
let rest = if bed_room { self.room_bonus(self.map.t[b].kind) } else { 1.0 };
|
||||||
e.energy = (e.energy + dt / 14.0).min(1.0);
|
e.hp = (e.hp + e.max_hp * dt * rest / if bed_room { 12.0 } else { 24.0 }).min(e.max_hp);
|
||||||
|
e.energy = (e.energy + dt * rest / 14.0).min(1.0);
|
||||||
if e.hp >= e.max_hp * 0.75 {
|
if e.hp >= e.max_hp * 0.75 {
|
||||||
e.job = Job::None;
|
e.job = Job::None;
|
||||||
}
|
}
|
||||||
@@ -3857,7 +3884,7 @@ impl Game {
|
|||||||
if tl.food >= 1.0 {
|
if tl.food >= 1.0 {
|
||||||
tl.food -= 1.0;
|
tl.food -= 1.0;
|
||||||
e.hunger = 0.0;
|
e.hunger = 0.0;
|
||||||
e.hp = (e.hp + e.max_hp * 0.2).min(e.max_hp);
|
e.hp = (e.hp + e.max_hp * 0.2 * self.room_bonus(Kind::Temple)).min(e.max_hp);
|
||||||
}
|
}
|
||||||
self.unreserve(me);
|
self.unreserve(me);
|
||||||
e.job = Job::None;
|
e.job = Job::None;
|
||||||
@@ -3887,7 +3914,7 @@ impl Game {
|
|||||||
}
|
}
|
||||||
e.working = true;
|
e.working = true;
|
||||||
self.training_bill += TRAIN_COST * dt;
|
self.training_bill += TRAIN_COST * dt;
|
||||||
e.xp += 7.0 * dt;
|
e.xp += 7.0 * dt * self.room_bonus(Kind::Training);
|
||||||
e.timer -= dt;
|
e.timer -= dt;
|
||||||
if e.timer <= 0.0 {
|
if e.timer <= 0.0 {
|
||||||
self.unreserve(me);
|
self.unreserve(me);
|
||||||
@@ -3916,7 +3943,7 @@ impl Game {
|
|||||||
}
|
}
|
||||||
e.working = true;
|
e.working = true;
|
||||||
let rate = if e.kind == EK::Cogling { 2.5 } else { 1.0 } * (1.0 + 0.1 * (e.level - 1) as f32);
|
let rate = if e.kind == EK::Cogling { 2.5 } else { 1.0 } * (1.0 + 0.1 * (e.level - 1) as f32);
|
||||||
self.forge_work += rate * dt;
|
self.forge_work += rate * dt * self.room_bonus(Kind::Forge);
|
||||||
e.xp += 2.5 * dt;
|
e.xp += 2.5 * dt;
|
||||||
e.timer -= dt;
|
e.timer -= dt;
|
||||||
if e.timer <= 0.0 {
|
if e.timer <= 0.0 {
|
||||||
@@ -3939,7 +3966,7 @@ impl Game {
|
|||||||
EK::Owl => 1.3,
|
EK::Owl => 1.3,
|
||||||
_ => 0.5,
|
_ => 0.5,
|
||||||
} * (1.0 + 0.12 * (e.level - 1) as f32);
|
} * (1.0 + 0.12 * (e.level - 1) as f32);
|
||||||
self.add_research(points * dt);
|
self.add_research(points * dt * self.room_bonus(Kind::Library));
|
||||||
e.xp += 3.0 * dt;
|
e.xp += 3.0 * dt;
|
||||||
e.timer -= dt;
|
e.timer -= dt;
|
||||||
if e.timer <= 0.0 {
|
if e.timer <= 0.0 {
|
||||||
|
|||||||
+3
-1
@@ -352,6 +352,8 @@ pub struct Map {
|
|||||||
pub visible: Vec<bool>, // fog of war: tiles in sight right now
|
pub visible: Vec<bool>, // fog of war: tiles in sight right now
|
||||||
#[serde(default, with = "crate::fog::bits")]
|
#[serde(default, with = "crate::fog::bits")]
|
||||||
pub sky: Vec<bool>, // tiles above ground (daylight, grass); empty: all underground
|
pub sky: Vec<bool>, // tiles above ground (daylight, grass); empty: all underground
|
||||||
|
#[serde(default)]
|
||||||
|
pub upgrades: Vec<(u8, u8, u8)>, // researched room levels for the look: (master side, room index, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size() -> usize {
|
fn default_size() -> usize {
|
||||||
@@ -604,7 +606,7 @@ impl Map {
|
|||||||
tl.hp = 6.0;
|
tl.hp = 6.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Map { w, h, t, core, portals, legacy_portal: None, gate, treasures, explored: Vec::new(), visible: Vec::new(), sky: Vec::new() }
|
Map { w, h, t, core, portals, legacy_portal: None, gate, treasures, explored: Vec::new(), visible: Vec::new(), sky: Vec::new(), upgrades: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carves a meandering river; the player's area, the core and portals stay dry.
|
// Carves a meandering river; the player's area, the core and portals stay dry.
|
||||||
|
|||||||
@@ -440,6 +440,15 @@ impl MB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the researched level of the room on tile t (1: none)
|
||||||
|
fn room_level_at(map: &Map, t: &Tile) -> u8 {
|
||||||
|
if map.upgrades.is_empty() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
let (Some(r), side) = (room_index(t.kind), t.owner.side()) else { return 1 };
|
||||||
|
map.upgrades.iter().find(|u| u.0 == side && u.1 as usize == r).map_or(1, |u| u.2)
|
||||||
|
}
|
||||||
|
|
||||||
// Ambient light field: own territory is lit, foreign areas are dim
|
// Ambient light field: own territory is lit, foreign areas are dim
|
||||||
fn ambient_field(map: &Map) -> Vec<f32> {
|
fn ambient_field(map: &Map) -> Vec<f32> {
|
||||||
let mut f = vec![0.0f32; n()];
|
let mut f = vec![0.0f32; n()];
|
||||||
@@ -453,6 +462,11 @@ fn ambient_field(map: &Map) -> Vec<f32> {
|
|||||||
if map.sky(i) {
|
if map.sky(i) {
|
||||||
f[i] = 1.6;
|
f[i] = 1.6;
|
||||||
}
|
}
|
||||||
|
// rooms of a higher level shine brighter
|
||||||
|
let lv = room_level_at(map, t);
|
||||||
|
if lv > 1 && f[i] > 0.0 {
|
||||||
|
f[i] += 0.25 * (lv - 1) as f32;
|
||||||
|
}
|
||||||
if t.river() == Some(Kind::Lava) {
|
if t.river() == Some(Kind::Lava) {
|
||||||
f[i] = f[i].max(0.8); // lava lights up its surroundings
|
f[i] = f[i].max(0.8); // lava lights up its surroundings
|
||||||
}
|
}
|
||||||
@@ -853,6 +867,26 @@ fn build_chunk(map: &Map, amb: &[f32], glow: &[f32], cx: i32, cz: i32, atlas: &T
|
|||||||
if !solid_at(map, x - 1, z) && !outdoors {
|
if !solid_at(map, x - 1, z) && !outdoors {
|
||||||
ln.strip(vec3(xf, 0.0, zf), vec3(xf, 0.0, zf + 1.0), Vec3::Y, OUTLINE_W, OUTLINE_C);
|
ln.strip(vec3(xf, 0.0, zf), vec3(xf, 0.0, zf + 1.0), Vec3::Y, OUTLINE_W, OUTLINE_C);
|
||||||
}
|
}
|
||||||
|
// a room of a higher level: gold trim along its border (twice at level 3)
|
||||||
|
let lv = room_level_at(map, &t);
|
||||||
|
if lv > 1 {
|
||||||
|
let gold = col(vec3(1.0, 0.78, 0.25), 1.0);
|
||||||
|
for (d, &(dx, dz)) in DIR4.iter().enumerate() {
|
||||||
|
if map.get(x + dx, z + dz).map_or(false, |o| o.kind == t.kind && o.owner == t.owner) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for k in 0..(lv - 1) {
|
||||||
|
let m = 0.08 + 0.12 * k as f32;
|
||||||
|
let (p, q) = match d {
|
||||||
|
0 => (vec3(xf + m, 0.012, zf + m), vec3(xf + 1.0 - m, 0.012, zf + m)),
|
||||||
|
1 => (vec3(xf + 1.0 - m, 0.012, zf + m), vec3(xf + 1.0 - m, 0.012, zf + 1.0 - m)),
|
||||||
|
2 => (vec3(xf + 1.0 - m, 0.012, zf + 1.0 - m), vec3(xf + m, 0.012, zf + 1.0 - m)),
|
||||||
|
_ => (vec3(xf + m, 0.012, zf + 1.0 - m), vec3(xf + m, 0.012, zf + m)),
|
||||||
|
};
|
||||||
|
ln.strip(p, q, Vec3::Y, OUTLINE_W * 1.5, gold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// room decor
|
// room decor
|
||||||
let dc = col(lava_lit(Vec3::splat(amb_at(amb, xf + 0.5, zf + 0.5)), lava_at(glow, xf + 0.5, zf + 0.5)), 1.0);
|
let dc = col(lava_lit(Vec3::splat(amb_at(amb, xf + 0.5, zf + 0.5)), lava_at(glow, xf + 0.5, zf + 0.5)), 1.0);
|
||||||
if t.plant() {
|
if t.plant() {
|
||||||
@@ -1083,6 +1117,10 @@ fn rgba(u: u32) -> Color {
|
|||||||
|
|
||||||
fn chunk_sig(map: &Map, cx: i32, cz: i32) -> u64 {
|
fn chunk_sig(map: &Map, cx: i32, cz: i32) -> u64 {
|
||||||
let mut h: u64 = 1469598103934665603;
|
let mut h: u64 = 1469598103934665603;
|
||||||
|
// researched room levels change the light and the trim of every room
|
||||||
|
for u in &map.upgrades {
|
||||||
|
h = (h ^ (u.0 as u64 | (u.1 as u64) << 8 | (u.2 as u64) << 16)).wrapping_mul(1099511628211);
|
||||||
|
}
|
||||||
for z in cz * CHUNK - 3..(cz + 1) * CHUNK + 3 {
|
for z in cz * CHUNK - 3..(cz + 1) * CHUNK + 3 {
|
||||||
for x in cx * CHUNK - 3..(cx + 1) * CHUNK + 3 {
|
for x in cx * CHUNK - 3..(cx + 1) * CHUNK + 3 {
|
||||||
let v = match map.get(x, z) {
|
let v = match map.get(x, z) {
|
||||||
|
|||||||
+72
-1
@@ -46,6 +46,26 @@ pub const RESEARCH: &[(usize, f32)] = &[
|
|||||||
(51, 1000.0), // catapult
|
(51, 1000.0), // catapult
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// room levels, researched once everything else is known: (index in ROOM_KINDS, level, points)
|
||||||
|
pub const UPGRADES: &[(usize, u8, f32)] = &[
|
||||||
|
(1, 2, 500.0), // lair
|
||||||
|
(2, 2, 500.0), // mushroom garden
|
||||||
|
(0, 2, 550.0), // treasury
|
||||||
|
(4, 2, 600.0), // library
|
||||||
|
(3, 2, 600.0), // training hall
|
||||||
|
(8, 2, 650.0), // forge
|
||||||
|
(6, 2, 650.0), // temple
|
||||||
|
(7, 2, 650.0), // aerie
|
||||||
|
(1, 3, 1000.0), // lair
|
||||||
|
(2, 3, 1000.0), // mushroom garden
|
||||||
|
(0, 3, 1100.0), // treasury
|
||||||
|
(4, 3, 1200.0), // library
|
||||||
|
(3, 3, 1200.0), // training hall
|
||||||
|
(8, 3, 1300.0), // forge
|
||||||
|
(6, 3, 1300.0), // temple
|
||||||
|
(7, 3, 1300.0), // aerie
|
||||||
|
];
|
||||||
|
|
||||||
// known from the start in free play
|
// known from the start in free play
|
||||||
pub const BASE_TOOLS: &[usize] = &[0, 1, 2, 3, 4, 6, 7, 8, 9, 14, 17, 20, 45, 46, 49];
|
pub const BASE_TOOLS: &[usize] = &[0, 1, 2, 3, 4, 6, 7, 8, 9, 14, 17, 20, 45, 46, 49];
|
||||||
|
|
||||||
@@ -92,13 +112,45 @@ impl Game {
|
|||||||
!self.known(tool) && self.researchable.get(tool).copied().unwrap_or(false) && RESEARCH.iter().any(|&(t, _)| t == tool)
|
!self.known(tool) && self.researchable.get(tool).copied().unwrap_or(false) && RESEARCH.iter().any(|&(t, _)| t == tool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the room level being researched once no tool is left: index in UPGRADES
|
||||||
|
pub fn upgrade_target(&self) -> Option<usize> {
|
||||||
|
if self.research_target().is_some() || self.known.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
UPGRADES.iter().position(|&(r, lv, _)| self.room_level.get(r).copied().unwrap_or(1).max(1) < lv)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn add_research(&mut self, points: f32) {
|
pub(crate) fn add_research(&mut self, points: f32) {
|
||||||
if self.research_target().is_some() {
|
if self.research_target().is_some() || self.upgrade_target().is_some() {
|
||||||
self.research += points;
|
self.research += points;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a room kind reached level `lv` (the map keeps it for the look of the rooms)
|
||||||
|
pub fn set_room_level(&mut self, r: usize, lv: u8) {
|
||||||
|
if self.room_level.len() < crate::game::N_ROOMS {
|
||||||
|
self.room_level.resize(crate::game::N_ROOMS, 1);
|
||||||
|
}
|
||||||
|
self.room_level[r] = lv;
|
||||||
|
let side = self.me_side;
|
||||||
|
self.map.upgrades.retain(|u| !(u.0 == side && u.1 as usize == r));
|
||||||
|
if lv > 1 {
|
||||||
|
self.map.upgrades.push((side, r as u8, lv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn update_research(&mut self) {
|
pub(crate) fn update_research(&mut self) {
|
||||||
|
if let Some(u) = self.upgrade_target() {
|
||||||
|
let (r, lv, cost) = UPGRADES[u];
|
||||||
|
if self.research >= cost {
|
||||||
|
self.research -= cost;
|
||||||
|
self.set_room_level(r, lv);
|
||||||
|
let roman = if lv == 2 { "II" } else { "III" };
|
||||||
|
self.msg("msg.room_upgraded", vec![format!("@{}", crate::game::ROOM_NAMES[r]), roman.to_string()]);
|
||||||
|
self.sfx_ui(Sfx::LevelUp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
let Some(k) = self.research_target() else { return };
|
let Some(k) = self.research_target() else { return };
|
||||||
let (tool, cost) = RESEARCH[k];
|
let (tool, cost) = RESEARCH[k];
|
||||||
if self.research >= cost {
|
if self.research >= cost {
|
||||||
@@ -154,4 +206,23 @@ mod tests {
|
|||||||
assert!(g.can_research(10), "heal comes soon and can be researched");
|
assert!(g.can_research(10), "heal comes soon and can be researched");
|
||||||
assert!(!g.can_research(31), "magic doors are far away");
|
assert!(!g.can_research(31), "magic doors are far away");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn once_everything_is_known_the_library_raises_room_levels() {
|
||||||
|
let mut g = Game::new(9, 64, 64);
|
||||||
|
assert!(g.upgrade_target().is_none(), "tools first");
|
||||||
|
for v in g.known.iter_mut() {
|
||||||
|
*v = true;
|
||||||
|
}
|
||||||
|
let u = g.upgrade_target().expect("a room level to research");
|
||||||
|
let (r, lv, cost) = UPGRADES[u];
|
||||||
|
assert_eq!(lv, 2);
|
||||||
|
let before = g.room_bonus(ROOM_KINDS[r]);
|
||||||
|
g.research = cost + 1.0;
|
||||||
|
g.update_research();
|
||||||
|
assert_eq!(g.room_level_of(ROOM_KINDS[r]), 2);
|
||||||
|
assert!(g.room_bonus(ROOM_KINDS[r]) > before);
|
||||||
|
assert!(g.map.upgrades.iter().any(|x| x.1 as usize == r && x.2 == 2), "the map shows it");
|
||||||
|
assert_ne!(g.upgrade_target(), Some(u), "the next one");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -667,6 +667,11 @@ impl Ui {
|
|||||||
let (tool, cost) = crate::research::RESEARCH[k];
|
let (tool, cost) = crate::research::RESEARCH[k];
|
||||||
let name: String = tool_info(TOOLS[tool]).name.chars().take(18).collect();
|
let name: String = tool_info(TOOLS[tool]).name.chars().take(18).collect();
|
||||||
segs.push(vec![txt(tr("hud.research"), BLUE), Part::Gap, txt(name, TXT), Part::Gap, Part::Bar(g.research / cost, BLUE)]);
|
segs.push(vec![txt(tr("hud.research"), BLUE), Part::Gap, txt(name, TXT), Part::Gap, Part::Bar(g.research / cost, BLUE)]);
|
||||||
|
} else if let Some(u) = g.upgrade_target().filter(|_| g.counts[4] > 0) {
|
||||||
|
// everything known: the library works on room levels
|
||||||
|
let (r, lv, cost) = crate::research::UPGRADES[u];
|
||||||
|
let name: String = format!("{} {}", tr(ROOM_NAMES[r]), if lv == 2 { "II" } else { "III" }).chars().take(20).collect();
|
||||||
|
segs.push(vec![txt(tr("hud.research"), BLUE), Part::Gap, txt(name, TXT), Part::Gap, Part::Bar(g.research / cost, BLUE)]);
|
||||||
}
|
}
|
||||||
segs.push(vec![txt(tr("hud.payday"), if g.payday <= PAYDAY_WARN { RED } else { GOLD }), Part::Gap, txt(mmss(g.payday), TXT)]);
|
segs.push(vec![txt(tr("hud.payday"), if g.payday <= PAYDAY_WARN { RED } else { GOLD }), Part::Gap, txt(mmss(g.payday), TXT)]);
|
||||||
segs.push(vec![txt(tr("hud.army"), TXT), Part::Gap, txt((g.army_value() as i32).to_string(), TXT)]);
|
segs.push(vec![txt(tr("hud.army"), TXT), Part::Gap, txt((g.army_value() as i32).to_string(), TXT)]);
|
||||||
|
|||||||
Reference in new issue
Block a user