Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3f7939627 | ||
|
|
3e17bdf52d |
No files matched your search
+4
-1
@@ -134,5 +134,8 @@ grid), guard and attack markers (shields and swords), savegames with the game st
|
|||||||
level), Warlord (creatures +5% damage, -5% damage taken), Warlock (mana +15%, spells -6%), Merchant (wages
|
level), Warlord (creatures +5% damage, -5% damage taken), Warlock (mana +15%, spells -6%), Merchant (wages
|
||||||
-6%, treasure +6%); 5 levels each. The "Master" button (number of free points, pulsing) opens the window.
|
-6%, treasure +6%); 5 levels each. The "Master" button (number of free points, pulsing) opens the window.
|
||||||
AI masters spend their points themselves; per game, carried over in the campaign and co-op runs.
|
AI masters spend their points themselves; per game, carried over in the campaign and co-op runs.
|
||||||
5. **Weather above ground** - rain (puts out fire), fog (less sight), storms (lightning in trees and units).
|
5. **Weather above ground** (done, v202611-00066, weather.rs) - about 60% fair, 20% rain, 12% fog, 8% storm,
|
||||||
|
minutes each with soft 20 s changes, only on maps with land above ground. Rain (and storms) put out burning
|
||||||
|
bridges and keep fire from catching; fog halves the sight of units outside; storms strike units (40 damage)
|
||||||
|
or trees with lightning every 6-20 s. Dimmed daylight, rain streaks, fog veils, flashes; a HUD label.
|
||||||
6. **Named creatures** - names per kind and language, epithets at higher levels, memorial stones.
|
6. **Named creatures** - names per kind and language, epithets at higher levels, memorial stones.
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Zatím nenaučeno.
|
|||||||
talent.then = Další úroveň: {0}
|
talent.then = Další úroveň: {0}
|
||||||
msg.talent_point = Nový bod talentu! Použij ho v okně pána.
|
msg.talent_point = Nový bod talentu! Použij ho v okně pána.
|
||||||
msg.talent_learned = {0}: úroveň {1} naučena.
|
msg.talent_learned = {0}: úroveň {1} naučena.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Jasno
|
||||||
|
weather.rain = Déšť
|
||||||
|
weather.fog = Mlha
|
||||||
|
weather.storm = Bouře
|
||||||
|
msg.weather_clear = Na povrchu se vyjasňuje.
|
||||||
|
msg.weather_rain = Na povrchu začíná pršet - oheň nechytne.
|
||||||
|
msg.weather_fog = Nad krajinou se valí mlha - venku každý vidí méně.
|
||||||
|
msg.weather_storm = Na povrchu se blíží bouře! Blesky zasahují jednotky a stromy.
|
||||||
|
msg.lightning_unit = Zásah bleskem: {0}!
|
||||||
@@ -1711,3 +1711,14 @@ talent.none = Endnu ikke lært.
|
|||||||
talent.then = Næste niveau: {0}
|
talent.then = Næste niveau: {0}
|
||||||
msg.talent_point = Et nyt talentpoint! Brug det i mestervinduet.
|
msg.talent_point = Et nyt talentpoint! Brug det i mestervinduet.
|
||||||
msg.talent_learned = {0} niveau {1} lært.
|
msg.talent_learned = {0} niveau {1} lært.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Klart
|
||||||
|
weather.rain = Regn
|
||||||
|
weather.fog = Tåge
|
||||||
|
weather.storm = Storm
|
||||||
|
msg.weather_clear = Over jorden klarer det op.
|
||||||
|
msg.weather_rain = Over jorden begynder det at regne - ild fænger ikke.
|
||||||
|
msg.weather_fog = Tåge driver ind over landet - udenfor ser alle mindre.
|
||||||
|
msg.weather_storm = Over jorden trækker en storm op! Lynet rammer enheder og træer.
|
||||||
|
msg.lightning_unit = Ramt af lynet: {0}!
|
||||||
@@ -1711,3 +1711,14 @@ talent.none = Noch nicht gelernt.
|
|||||||
talent.then = Nächste Stufe: {0}
|
talent.then = Nächste Stufe: {0}
|
||||||
msg.talent_point = Ein neuer Talentpunkt! Verteile ihn im Meister-Fenster.
|
msg.talent_point = Ein neuer Talentpunkt! Verteile ihn im Meister-Fenster.
|
||||||
msg.talent_learned = {0} Stufe {1} gelernt.
|
msg.talent_learned = {0} Stufe {1} gelernt.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Heiter
|
||||||
|
weather.rain = Regen
|
||||||
|
weather.fog = Nebel
|
||||||
|
weather.storm = Sturm
|
||||||
|
msg.weather_clear = Über der Erde klart es auf.
|
||||||
|
msg.weather_rain = Über der Erde beginnt es zu regnen - Feuer fängt nicht.
|
||||||
|
msg.weather_fog = Nebel zieht über das Land - draußen sieht jeder weniger.
|
||||||
|
msg.weather_storm = Über der Erde zieht ein Sturm auf! Blitze treffen Einheiten und Bäume.
|
||||||
|
msg.lightning_unit = Vom Blitz getroffen: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Δεν έχει μαθευτεί ακόμη.
|
|||||||
talent.then = Επόμενο επίπεδο: {0}
|
talent.then = Επόμενο επίπεδο: {0}
|
||||||
msg.talent_point = Νέος πόντος ταλέντου! Ξόδεψέ τον στο παράθυρο του άρχοντα.
|
msg.talent_point = Νέος πόντος ταλέντου! Ξόδεψέ τον στο παράθυρο του άρχοντα.
|
||||||
msg.talent_learned = {0}: μαθεύτηκε το επίπεδο {1}.
|
msg.talent_learned = {0}: μαθεύτηκε το επίπεδο {1}.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Αίθριο
|
||||||
|
weather.rain = Βροχή
|
||||||
|
weather.fog = Ομίχλη
|
||||||
|
weather.storm = Καταιγίδα
|
||||||
|
msg.weather_clear = Στην επιφάνεια ο ουρανός καθαρίζει.
|
||||||
|
msg.weather_rain = Στην επιφάνεια αρχίζει να βρέχει - η φωτιά δεν πιάνει.
|
||||||
|
msg.weather_fog = Η ομίχλη απλώνεται στη γη - έξω όλοι βλέπουν λιγότερο.
|
||||||
|
msg.weather_storm = Στην επιφάνεια πλησιάζει καταιγίδα! Οι κεραυνοί χτυπούν μονάδες και δέντρα.
|
||||||
|
msg.lightning_unit = Χτυπήθηκε από κεραυνό: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Not learned yet.
|
|||||||
talent.then = Next level: {0}
|
talent.then = Next level: {0}
|
||||||
msg.talent_point = A new talent point! Spend it in the Master window.
|
msg.talent_point = A new talent point! Spend it in the Master window.
|
||||||
msg.talent_learned = {0} level {1} learned.
|
msg.talent_learned = {0} level {1} learned.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Fair
|
||||||
|
weather.rain = Rain
|
||||||
|
weather.fog = Fog
|
||||||
|
weather.storm = Storm
|
||||||
|
msg.weather_clear = The sky clears up above ground.
|
||||||
|
msg.weather_rain = It starts to rain above ground - fire will not catch.
|
||||||
|
msg.weather_fog = Fog rolls over the land - everyone outside sees less.
|
||||||
|
msg.weather_storm = A storm is brewing above ground! Lightning strikes units and trees.
|
||||||
|
msg.lightning_unit = Lightning struck: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Aún no aprendido.
|
|||||||
talent.then = Siguiente nivel: {0}
|
talent.then = Siguiente nivel: {0}
|
||||||
msg.talent_point = ¡Un nuevo punto de talento! Gástalo en la ventana del maestro.
|
msg.talent_point = ¡Un nuevo punto de talento! Gástalo en la ventana del maestro.
|
||||||
msg.talent_learned = {0}: nivel {1} aprendido.
|
msg.talent_learned = {0}: nivel {1} aprendido.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Despejado
|
||||||
|
weather.rain = Lluvia
|
||||||
|
weather.fog = Niebla
|
||||||
|
weather.storm = Tormenta
|
||||||
|
msg.weather_clear = El cielo se despeja en la superficie.
|
||||||
|
msg.weather_rain = Empieza a llover en la superficie: el fuego no prende.
|
||||||
|
msg.weather_fog = La niebla cubre la tierra: todos ven menos al aire libre.
|
||||||
|
msg.weather_storm = ¡Se avecina una tormenta en la superficie! Los rayos alcanzan unidades y árboles.
|
||||||
|
msg.lightning_unit = ¡Un rayo alcanza a {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Ei vielä opittu.
|
|||||||
talent.then = Seuraava taso: {0}
|
talent.then = Seuraava taso: {0}
|
||||||
msg.talent_point = Uusi kykypiste! Käytä se mestarin ikkunassa.
|
msg.talent_point = Uusi kykypiste! Käytä se mestarin ikkunassa.
|
||||||
msg.talent_learned = {0}: taso {1} opittu.
|
msg.talent_learned = {0}: taso {1} opittu.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Selkeää
|
||||||
|
weather.rain = Sade
|
||||||
|
weather.fog = Sumu
|
||||||
|
weather.storm = Myrsky
|
||||||
|
msg.weather_clear = Maan päällä taivas selkenee.
|
||||||
|
msg.weather_rain = Maan päällä alkaa sataa - tuli ei syty.
|
||||||
|
msg.weather_fog = Sumu leviää maan ylle - ulkona kaikki näkevät vähemmän.
|
||||||
|
msg.weather_storm = Maan päällä nousee myrsky! Salamat iskevät yksiköihin ja puihin.
|
||||||
|
msg.lightning_unit = Salama iski: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Još nije naučeno.
|
|||||||
talent.then = Sljedeća razina: {0}
|
talent.then = Sljedeća razina: {0}
|
||||||
msg.talent_point = Novi bod talenta! Potroši ga u prozoru gospodara.
|
msg.talent_point = Novi bod talenta! Potroši ga u prozoru gospodara.
|
||||||
msg.talent_learned = {0}: naučena razina {1}.
|
msg.talent_learned = {0}: naučena razina {1}.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Vedro
|
||||||
|
weather.rain = Kiša
|
||||||
|
weather.fog = Magla
|
||||||
|
weather.storm = Oluja
|
||||||
|
msg.weather_clear = Na površini se razvedrava.
|
||||||
|
msg.weather_rain = Na površini počinje kiša - vatra se ne hvata.
|
||||||
|
msg.weather_fog = Magla se spušta nad zemlju - vani svi vide manje.
|
||||||
|
msg.weather_storm = Na površini se sprema oluja! Munje pogađaju jedinice i stabla.
|
||||||
|
msg.lightning_unit = Munja je pogodila: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Még nincs megtanulva.
|
|||||||
talent.then = Következő szint: {0}
|
talent.then = Következő szint: {0}
|
||||||
msg.talent_point = Új tehetségpont! Költsd el a mester ablakában.
|
msg.talent_point = Új tehetségpont! Költsd el a mester ablakában.
|
||||||
msg.talent_learned = {0}: {1}. szint megtanulva.
|
msg.talent_learned = {0}: {1}. szint megtanulva.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Derült
|
||||||
|
weather.rain = Eső
|
||||||
|
weather.fog = Köd
|
||||||
|
weather.storm = Vihar
|
||||||
|
msg.weather_clear = A felszínen kitisztul az ég.
|
||||||
|
msg.weather_rain = A felszínen esni kezd - a tűz nem kap lángra.
|
||||||
|
msg.weather_fog = Köd ereszkedik a tájra - odakint mindenki kevesebbet lát.
|
||||||
|
msg.weather_storm = A felszínen vihar készül! Villámok csapnak egységekbe és fákba.
|
||||||
|
msg.lightning_unit = Villám sújtotta: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Non ancora appreso.
|
|||||||
talent.then = Livello successivo: {0}
|
talent.then = Livello successivo: {0}
|
||||||
msg.talent_point = Un nuovo punto talento! Spendilo nella finestra del maestro.
|
msg.talent_point = Un nuovo punto talento! Spendilo nella finestra del maestro.
|
||||||
msg.talent_learned = {0}: livello {1} appreso.
|
msg.talent_learned = {0}: livello {1} appreso.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Sereno
|
||||||
|
weather.rain = Pioggia
|
||||||
|
weather.fog = Nebbia
|
||||||
|
weather.storm = Tempesta
|
||||||
|
msg.weather_clear = In superficie il cielo si rasserena.
|
||||||
|
msg.weather_rain = In superficie inizia a piovere: il fuoco non attecchisce.
|
||||||
|
msg.weather_fog = La nebbia avvolge la terra: all'aperto tutti vedono meno.
|
||||||
|
msg.weather_storm = In superficie si avvicina una tempesta! I fulmini colpiscono unità e alberi.
|
||||||
|
msg.lightning_unit = Un fulmine colpisce {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Nog niet geleerd.
|
|||||||
talent.then = Volgend niveau: {0}
|
talent.then = Volgend niveau: {0}
|
||||||
msg.talent_point = Een nieuw talentpunt! Besteed het in het meestervenster.
|
msg.talent_point = Een nieuw talentpunt! Besteed het in het meestervenster.
|
||||||
msg.talent_learned = {0} niveau {1} geleerd.
|
msg.talent_learned = {0} niveau {1} geleerd.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Helder
|
||||||
|
weather.rain = Regen
|
||||||
|
weather.fog = Mist
|
||||||
|
weather.storm = Storm
|
||||||
|
msg.weather_clear = Bovengronds klaart het op.
|
||||||
|
msg.weather_rain = Bovengronds begint het te regenen - vuur vat geen vlam.
|
||||||
|
msg.weather_fog = Mist trekt over het land - buiten ziet iedereen minder.
|
||||||
|
msg.weather_storm = Bovengronds steekt een storm op! Bliksem treft units en bomen.
|
||||||
|
msg.lightning_unit = Door de bliksem getroffen: {0}!
|
||||||
@@ -1711,3 +1711,14 @@ talent.none = Ikke lært ennå.
|
|||||||
talent.then = Neste nivå: {0}
|
talent.then = Neste nivå: {0}
|
||||||
msg.talent_point = Et nytt talentpoeng! Bruk det i mestervinduet.
|
msg.talent_point = Et nytt talentpoeng! Bruk det i mestervinduet.
|
||||||
msg.talent_learned = {0} nivå {1} lært.
|
msg.talent_learned = {0} nivå {1} lært.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Klart
|
||||||
|
weather.rain = Regn
|
||||||
|
weather.fog = Tåke
|
||||||
|
weather.storm = Storm
|
||||||
|
msg.weather_clear = Over jorden klarner det opp.
|
||||||
|
msg.weather_rain = Over jorden begynner det å regne - ild tar ikke fyr.
|
||||||
|
msg.weather_fog = Tåke driver inn over landet - ute ser alle mindre.
|
||||||
|
msg.weather_storm = Over jorden trekker et uvær opp! Lynet treffer enheter og trær.
|
||||||
|
msg.lightning_unit = Truffet av lynet: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Ainda não aprendido.
|
|||||||
talent.then = Próximo nível: {0}
|
talent.then = Próximo nível: {0}
|
||||||
msg.talent_point = Um novo ponto de talento! Gasta-o na janela do mestre.
|
msg.talent_point = Um novo ponto de talento! Gasta-o na janela do mestre.
|
||||||
msg.talent_learned = {0}: nível {1} aprendido.
|
msg.talent_learned = {0}: nível {1} aprendido.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Limpo
|
||||||
|
weather.rain = Chuva
|
||||||
|
weather.fog = Nevoeiro
|
||||||
|
weather.storm = Temporal
|
||||||
|
msg.weather_clear = O céu limpa à superfície.
|
||||||
|
msg.weather_rain = Começa a chover à superfície - o fogo não pega.
|
||||||
|
msg.weather_fog = O nevoeiro cobre a terra - lá fora todos veem menos.
|
||||||
|
msg.weather_storm = Aproxima-se uma tempestade à superfície! Os raios atingem unidades e árvores.
|
||||||
|
msg.lightning_unit = Um raio atinge {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Încă neînvățat.
|
|||||||
talent.then = Nivelul următor: {0}
|
talent.then = Nivelul următor: {0}
|
||||||
msg.talent_point = Un nou punct de talent! Folosește-l în fereastra stăpânului.
|
msg.talent_point = Un nou punct de talent! Folosește-l în fereastra stăpânului.
|
||||||
msg.talent_learned = {0}: nivelul {1} învățat.
|
msg.talent_learned = {0}: nivelul {1} învățat.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Senin
|
||||||
|
weather.rain = Ploaie
|
||||||
|
weather.fog = Ceață
|
||||||
|
weather.storm = Furtună
|
||||||
|
msg.weather_clear = La suprafață cerul se înseninează.
|
||||||
|
msg.weather_rain = La suprafață începe să plouă - focul nu se aprinde.
|
||||||
|
msg.weather_fog = Ceața se lasă peste ținut - afară toată lumea vede mai puțin.
|
||||||
|
msg.weather_storm = La suprafață se pregătește o furtună! Fulgerele lovesc unități și copaci.
|
||||||
|
msg.lightning_unit = Fulgerul a lovit: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Ещё не изучено.
|
|||||||
talent.then = Следующий уровень: {0}
|
talent.then = Следующий уровень: {0}
|
||||||
msg.talent_point = Новое очко таланта! Потрать его в окне мастера.
|
msg.talent_point = Новое очко таланта! Потрать его в окне мастера.
|
||||||
msg.talent_learned = {0}: изучен уровень {1}.
|
msg.talent_learned = {0}: изучен уровень {1}.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Ясно
|
||||||
|
weather.rain = Дождь
|
||||||
|
weather.fog = Туман
|
||||||
|
weather.storm = Гроза
|
||||||
|
msg.weather_clear = Наверху проясняется.
|
||||||
|
msg.weather_rain = Наверху начинается дождь - огонь не разгорается.
|
||||||
|
msg.weather_fog = Туман стелется над землёй - снаружи все видят хуже.
|
||||||
|
msg.weather_storm = Наверху надвигается гроза! Молнии бьют по бойцам и деревьям.
|
||||||
|
msg.lightning_unit = Удар молнии: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Zatiaľ nenaučené.
|
|||||||
talent.then = Ďalšia úroveň: {0}
|
talent.then = Ďalšia úroveň: {0}
|
||||||
msg.talent_point = Nový bod talentu! Použi ho v okne pána.
|
msg.talent_point = Nový bod talentu! Použi ho v okne pána.
|
||||||
msg.talent_learned = {0}: úroveň {1} naučená.
|
msg.talent_learned = {0}: úroveň {1} naučená.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Jasno
|
||||||
|
weather.rain = Dážď
|
||||||
|
weather.fog = Hmla
|
||||||
|
weather.storm = Búrka
|
||||||
|
msg.weather_clear = Na povrchu sa vyjasňuje.
|
||||||
|
msg.weather_rain = Na povrchu začína pršať - oheň sa nechytí.
|
||||||
|
msg.weather_fog = Nad krajinou sa valí hmla - vonku každý vidí menej.
|
||||||
|
msg.weather_storm = Na povrchu sa blíži búrka! Blesky zasahujú jednotky a stromy.
|
||||||
|
msg.lightning_unit = Zásah bleskom: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Још није научено.
|
|||||||
talent.then = Следећи ниво: {0}
|
talent.then = Следећи ниво: {0}
|
||||||
msg.talent_point = Нови бод талента! Потроши га у прозору господара.
|
msg.talent_point = Нови бод талента! Потроши га у прозору господара.
|
||||||
msg.talent_learned = {0}: научен ниво {1}.
|
msg.talent_learned = {0}: научен ниво {1}.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Ведро
|
||||||
|
weather.rain = Киша
|
||||||
|
weather.fog = Магла
|
||||||
|
weather.storm = Олуја
|
||||||
|
msg.weather_clear = На површини се разведрава.
|
||||||
|
msg.weather_rain = На површини почиње киша - ватра се не хвата.
|
||||||
|
msg.weather_fog = Магла се спушта над земљу - напољу сви виде мање.
|
||||||
|
msg.weather_storm = На површини се спрема олуја! Муње погађају јединице и стабла.
|
||||||
|
msg.lightning_unit = Муња је погодила: {0}!
|
||||||
@@ -1712,3 +1712,14 @@ talent.none = Inte inlärd än.
|
|||||||
talent.then = Nästa nivå: {0}
|
talent.then = Nästa nivå: {0}
|
||||||
msg.talent_point = En ny talangpoäng! Använd den i mästarfönstret.
|
msg.talent_point = En ny talangpoäng! Använd den i mästarfönstret.
|
||||||
msg.talent_learned = {0} nivå {1} inlärd.
|
msg.talent_learned = {0} nivå {1} inlärd.
|
||||||
|
|
||||||
|
# weather above ground
|
||||||
|
weather.fair = Klart
|
||||||
|
weather.rain = Regn
|
||||||
|
weather.fog = Dimma
|
||||||
|
weather.storm = Storm
|
||||||
|
msg.weather_clear = Ovan jord klarnar det upp.
|
||||||
|
msg.weather_rain = Ovan jord börjar det regna - eld tar inte fäste.
|
||||||
|
msg.weather_fog = Dimma drar in över landet - ute ser alla sämre.
|
||||||
|
msg.weather_storm = Ovan jord drar en storm in! Blixten slår ner i enheter och träd.
|
||||||
|
msg.lightning_unit = Blixten träffade {0}!
|
||||||
+2
-1
@@ -56,7 +56,8 @@ impl Game {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let i = idx(tx, ty);
|
let i = idx(tx, ty);
|
||||||
if !self.wooden_bridge(i) || self.burning(i) {
|
// nothing catches fire in the rain
|
||||||
|
if !self.wooden_bridge(i) || self.burning(i) || self.rain_at(i) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.bridgework.burning.push((i, 0.0));
|
self.bridgework.burning.push((i, 0.0));
|
||||||
|
|||||||
+1
-1
@@ -137,7 +137,7 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// what the creatures and towers see along open ground (walls stop the view)
|
// what the creatures and towers see along open ground (walls stop the view)
|
||||||
let mut eyes: Vec<(usize, i32)> = self.ents.iter().filter(|e| e.alive && !e.held && !e.hero && (e.side == self.me_side || self.allied(self.me_side, e.side)) && !e.chained).map(|e| (e.tile(), SIGHT)).collect();
|
let mut eyes: Vec<(usize, i32)> = self.ents.iter().filter(|e| e.alive && !e.held && !e.hero && (e.side == self.me_side || self.allied(self.me_side, e.side)) && !e.chained).map(|e| (e.tile(), self.sight_at(e.tile(), SIGHT))).collect();
|
||||||
let solo = self.masters.is_empty();
|
let solo = self.masters.is_empty();
|
||||||
eyes.extend(self.towers.iter().filter(|t| !t.hero && (solo || allies.contains(&self.map.t[t.tile].owner))).map(|t| (t.tile, t.range() as i32 + 1)));
|
eyes.extend(self.towers.iter().filter(|t| !t.hero && (solo || allies.contains(&self.map.t[t.tile].owner))).map(|t| (t.tile, t.range() as i32 + 1)));
|
||||||
let mut stamp = vec![0u32; n];
|
let mut stamp = vec![0u32; n];
|
||||||
|
|||||||
@@ -636,6 +636,8 @@ pub struct Game {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub bridgework: crate::bridges::BridgeWork, // burning and worn bridges
|
pub bridgework: crate::bridges::BridgeWork, // burning and worn bridges
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub weather: crate::weather::Weather, // above ground (weather.rs)
|
||||||
|
#[serde(default)]
|
||||||
pub trading: crate::traders::Trading, // the visiting trader (traders.rs)
|
pub trading: crate::traders::Trading, // the visiting trader (traders.rs)
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub happenings: Option<crate::events::Events>, // random events (free games and versus), see events.rs
|
pub happenings: Option<crate::events::Events>, // random events (free games and versus), see events.rs
|
||||||
@@ -991,6 +993,7 @@ impl Game {
|
|||||||
vrng: crate::particles::vrng(),
|
vrng: crate::particles::vrng(),
|
||||||
dwarf_caves: Vec::new(),
|
dwarf_caves: Vec::new(),
|
||||||
bridgework: Default::default(),
|
bridgework: Default::default(),
|
||||||
|
weather: Default::default(),
|
||||||
trading: Default::default(),
|
trading: Default::default(),
|
||||||
happenings: None,
|
happenings: None,
|
||||||
snares: Vec::new(),
|
snares: Vec::new(),
|
||||||
@@ -1805,6 +1808,7 @@ impl Game {
|
|||||||
self.update_rivals(dt);
|
self.update_rivals(dt);
|
||||||
}
|
}
|
||||||
self.update_dwarves(dt);
|
self.update_dwarves(dt);
|
||||||
|
self.update_weather(dt);
|
||||||
self.update_bridges(dt);
|
self.update_bridges(dt);
|
||||||
self.update_wood(dt);
|
self.update_wood(dt);
|
||||||
self.update_events(dt);
|
self.update_events(dt);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ mod research;
|
|||||||
mod rival;
|
mod rival;
|
||||||
mod rogues;
|
mod rogues;
|
||||||
mod talents;
|
mod talents;
|
||||||
|
mod weather;
|
||||||
mod render3d;
|
mod render3d;
|
||||||
mod rooms;
|
mod rooms;
|
||||||
mod save;
|
mod save;
|
||||||
|
|||||||
+79
-2
@@ -512,6 +512,11 @@ fn room_level_at(map: &Map, t: &Tile) -> u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ambient light field: own territory is lit, foreign areas are dim
|
// Ambient light field: own territory is lit, foreign areas are dim
|
||||||
|
thread_local! {
|
||||||
|
// daylight above ground (bad weather dims it), in tenths
|
||||||
|
static SKY_LIGHT: std::cell::Cell<u32> = const { std::cell::Cell::new(16) };
|
||||||
|
}
|
||||||
|
|
||||||
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()];
|
||||||
for (i, t) in map.t.iter().enumerate() {
|
for (i, t) in map.t.iter().enumerate() {
|
||||||
@@ -522,7 +527,7 @@ fn ambient_field(map: &Map) -> Vec<f32> {
|
|||||||
};
|
};
|
||||||
// daylight above ground (cliffs and trees too)
|
// daylight above ground (cliffs and trees too)
|
||||||
if map.sky(i) {
|
if map.sky(i) {
|
||||||
f[i] = 1.6;
|
f[i] = SKY_LIGHT.with(|s| s.get()) as f32 / 10.0;
|
||||||
}
|
}
|
||||||
// rooms of a higher level shine brighter
|
// rooms of a higher level shine brighter
|
||||||
let lv = room_level_at(map, t);
|
let lv = room_level_at(map, t);
|
||||||
@@ -1279,6 +1284,14 @@ impl R3d {
|
|||||||
fn update_chunks(&mut self, g: &Game, gfx: &Gfx, m: &Mat4) {
|
fn update_chunks(&mut self, g: &Game, gfx: &Gfx, m: &Mat4) {
|
||||||
self.ensure_chunks();
|
self.ensure_chunks();
|
||||||
let side = g.me.side().min(7);
|
let side = g.me.side().min(7);
|
||||||
|
// the weather dims the daylight: the chunks above ground are lit again in steps
|
||||||
|
let sky = ((1.6 * (1.0 - g.weather.gloom())) * 10.0).round() as u32;
|
||||||
|
if SKY_LIGHT.with(|s| s.get()) != sky {
|
||||||
|
SKY_LIGHT.with(|s| s.set(sky));
|
||||||
|
for ch in self.chunks.iter_mut() {
|
||||||
|
ch.sig = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if view_side() != side {
|
if view_side() != side {
|
||||||
// another master looks: the marks change colour
|
// another master looks: the marks change colour
|
||||||
VIEW_SIDE.with(|v| v.set(side));
|
VIEW_SIDE.with(|v| v.set(side));
|
||||||
@@ -1609,6 +1622,7 @@ impl R3d {
|
|||||||
}
|
}
|
||||||
draw_traps_glow(g, t);
|
draw_traps_glow(g, t);
|
||||||
draw_parts_glow(g);
|
draw_parts_glow(g);
|
||||||
|
draw_weather(g, cam, t);
|
||||||
gl_use_default_material();
|
gl_use_default_material();
|
||||||
crate::ui::begin_ui();
|
crate::ui::begin_ui();
|
||||||
if let (Some((_, _, k)), Some((rt, tw, th))) = (pix, self.target.as_ref()) {
|
if let (Some((_, _, k)), Some((rt, tw, th))) = (pix, self.target.as_ref()) {
|
||||||
@@ -1629,7 +1643,7 @@ impl R3d {
|
|||||||
let (ix, iz) = (x as i32, z as i32);
|
let (ix, iz) = (x as i32, z as i32);
|
||||||
let own = g.map.get(ix, iz).map_or(false, |t| matches!(t.owner, Owner::Player | Owner::Rival1 | Owner::Rival2 | Owner::Rival3));
|
let own = g.map.get(ix, iz).map_or(false, |t| matches!(t.owner, Owner::Player | Owner::Rival1 | Owner::Rival2 | Owner::Rival3));
|
||||||
if inb(ix, iz) && g.map.sky(idx(ix, iz)) {
|
if inb(ix, iz) && g.map.sky(idx(ix, iz)) {
|
||||||
0.95
|
0.95 * (1.0 - 0.6 * g.weather.gloom())
|
||||||
} else if own {
|
} else if own {
|
||||||
0.75
|
0.75
|
||||||
} else {
|
} else {
|
||||||
@@ -2489,6 +2503,69 @@ fn draw_landmarks_solid(g: &Game, t: f32) {
|
|||||||
let _ = t;
|
let _ = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rain streaks and fog veils over the land above ground near the camera; a storm's lightning
|
||||||
|
// lights the sky up for a moment
|
||||||
|
fn draw_weather(g: &Game, cam: &Cam, t: f32) {
|
||||||
|
let w = &g.weather;
|
||||||
|
if w.level <= 0.01 || g.map.sky.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (cx, cz) = (cam.rx as i32, cam.rz as i32);
|
||||||
|
let reach = (cam.view_h() * 1.2) as i32 + 4;
|
||||||
|
let sky = |x: i32, z: i32| inb(x, z) && g.map.sky(idx(x, z));
|
||||||
|
// fog: veils at two heights, one plane per run of open sky tiles in a row
|
||||||
|
let fog = w.fog();
|
||||||
|
if fog > 0.01 {
|
||||||
|
for (h, a) in [(0.7f32, 0.22f32), (1.6, 0.16)] {
|
||||||
|
let col = Color::new(0.75, 0.78, 0.8, a * fog);
|
||||||
|
for z in cz - reach..=cz + reach {
|
||||||
|
let mut x = cx - reach;
|
||||||
|
while x <= cx + reach {
|
||||||
|
if !sky(x, z) {
|
||||||
|
x += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let x0 = x;
|
||||||
|
while x <= cx + reach && sky(x, z) {
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
let len = (x - x0) as f32;
|
||||||
|
let drift = (t * 0.2 + z as f32 * 0.7).sin() * 0.15;
|
||||||
|
draw_plane(vec3(x0 as f32 + len * 0.5 + drift, h, z as f32 + 0.5), vec2(len * 0.5, 0.5), None, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// rain: slanted streaks falling over the open land
|
||||||
|
let rain = w.rain();
|
||||||
|
if rain > 0.01 {
|
||||||
|
let n = (1100.0 * rain) as u32;
|
||||||
|
let col = Color::new(0.75, 0.82, 0.95, 0.8);
|
||||||
|
let span = (2 * reach + 1) as u32;
|
||||||
|
for k in 0..n {
|
||||||
|
let h = k.wrapping_mul(2654435761) ^ 0x9e37_79b9;
|
||||||
|
let x = cx - reach + (h % span) as i32;
|
||||||
|
let z = cz - reach + ((h >> 11) % span) as i32;
|
||||||
|
if !sky(x, z) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let fx = x as f32 + ((h >> 3) % 100) as f32 / 100.0;
|
||||||
|
let fz = z as f32 + ((h >> 17) % 100) as f32 / 100.0;
|
||||||
|
let fall = (t * 1.6 + (h % 1000) as f32 / 1000.0).fract();
|
||||||
|
let y = 3.0 * (1.0 - fall);
|
||||||
|
line3(vec3(fx, y + 0.5, fz - 0.08), vec3(fx + 0.05, y, fz + 0.08), 0.035, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// the flash of a lightning bolt
|
||||||
|
let since = g.time - w.flash;
|
||||||
|
if w.flash > 0.0 && (0.0..0.25).contains(&since) {
|
||||||
|
let a = 0.35 * (1.0 - since / 0.25);
|
||||||
|
for z in (cz - reach..=cz + reach).step_by(4) {
|
||||||
|
draw_plane(vec3(cx as f32, 0.05, z as f32 + 2.0), vec2(reach as f32, 2.0), None, Color::new(0.9, 0.92, 1.0, a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// growth stage of a giant mushroom: 0 a sprout .. 4 fully grown (felling only then)
|
// growth stage of a giant mushroom: 0 a sprout .. 4 fully grown (felling only then)
|
||||||
fn mushroom_stage(t: &Tile) -> u32 {
|
fn mushroom_stage(t: &Tile) -> u32 {
|
||||||
if t.grown() {
|
if t.grown() {
|
||||||
|
|||||||
@@ -264,3 +264,22 @@ fn export_rogues_scene() {
|
|||||||
g.snares.push(idx(cx + 7, cy + 3));
|
g.snares.push(idx(cx + 7, cy + 3));
|
||||||
save("rogues", &mut g, cx as f32 + 6.5, cy as f32 + 4.5, 8.0, 0.0, false);
|
save("rogues", &mut g, cx as f32 + 6.5, cy as f32 + 4.5, 8.0, 0.0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// weather above ground: rain and fog over the land
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn export_weather_scenes() {
|
||||||
|
std::fs::create_dir_all("/tmp/scenes").unwrap();
|
||||||
|
for (name, kind) in [("weather-rain", crate::weather::RAIN), ("weather-fog", crate::weather::FOG), ("weather-storm", crate::weather::STORM)] {
|
||||||
|
let mut g = Game::new(7, 96, 96);
|
||||||
|
g.add_surface(7, 0.5, 3);
|
||||||
|
g.weather = crate::weather::Weather { kind, shown: kind, level: 1.0, left: 900.0, ..Default::default() };
|
||||||
|
// the camera on the land above ground, near the edge of the dungeon side
|
||||||
|
let i = (0..g.map.t.len()).filter(|&i| g.map.sky(i)).min_by_key(|&i| {
|
||||||
|
let (x, y) = xy(i);
|
||||||
|
(x - 52).abs() + (y - 48).abs()
|
||||||
|
}).unwrap();
|
||||||
|
let (x, y) = xy(i);
|
||||||
|
save(name, &mut g, x as f32 + 4.5, y as f32 + 0.5, 18.0, 0.0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -809,6 +809,13 @@ impl Ui {
|
|||||||
};
|
};
|
||||||
segs.insert(3, vec![txt(tr(key), col), Part::Gap, Part::Bar(rv.hp / crate::rival::RIVAL_CORE_HP, col)]);
|
segs.insert(3, vec![txt(tr(key), col), Part::Gap, Part::Bar(rv.hp / crate::rival::RIVAL_CORE_HP, col)]);
|
||||||
}
|
}
|
||||||
|
// the weather above ground (maps with land above ground only)
|
||||||
|
if g.has_sky() {
|
||||||
|
let w = &g.weather;
|
||||||
|
let k = if w.level > 0.05 { w.shown } else { crate::weather::FAIR };
|
||||||
|
let col = [GOLD, Color::new(0.55, 0.7, 1.0, 1.0), Color::new(0.75, 0.78, 0.8, 1.0), Color::new(0.75, 0.6, 1.0, 1.0)][k as usize];
|
||||||
|
segs.push(vec![txt(tr(crate::weather::NAMES[k as usize]), col)]);
|
||||||
|
}
|
||||||
if g.waves_on() {
|
if g.waves_on() {
|
||||||
segs.push(vec![txt(trf("hud.wave", &[(g.wave + 1).to_string()]), wave_col), Part::Gap, txt(mmss(g.wave_timer), TXT)]);
|
segs.push(vec![txt(trf("hud.wave", &[(g.wave + 1).to_string()]), wave_col), Part::Gap, txt(mmss(g.wave_timer), TXT)]);
|
||||||
}
|
}
|
||||||
|
|||||||
+240
@@ -0,0 +1,240 @@
|
|||||||
|
// Weather above ground: mostly fair, now and then rain, fog or a storm, each for a few minutes
|
||||||
|
// with soft changes. Rain puts out burning bridges and keeps fire from catching; fog shortens the
|
||||||
|
// sight of everyone outside; a storm brings both rain and lightning that strikes units and trees.
|
||||||
|
// Only maps with land above ground have weather. It runs in the shared simulation (same on every
|
||||||
|
// computer of a match).
|
||||||
|
|
||||||
|
use crate::game::*;
|
||||||
|
use crate::map::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub const FAIR: u8 = 0;
|
||||||
|
pub const RAIN: u8 = 1;
|
||||||
|
pub const FOG: u8 = 2;
|
||||||
|
pub const STORM: u8 = 3;
|
||||||
|
pub const NAMES: [&str; 4] = ["weather.fair", "weather.rain", "weather.fog", "weather.storm"];
|
||||||
|
|
||||||
|
// seconds for a change to fade in or out
|
||||||
|
const FADE: f32 = 20.0;
|
||||||
|
// damage of a lightning strike
|
||||||
|
pub const BOLT_DAMAGE: f32 = 40.0;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
|
pub struct Weather {
|
||||||
|
pub kind: u8, // the weather that is coming or here
|
||||||
|
pub shown: u8, // the weather that is felt now (changes when the old one has faded out)
|
||||||
|
pub level: f32, // how strong it is: 0 none .. 1 full
|
||||||
|
pub left: f32, // seconds until the next change
|
||||||
|
pub strike_t: f32, // seconds until the next lightning (storm)
|
||||||
|
pub flash: f32, // game time of the last lightning (the sky lights up)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the weather that comes next: about 60% fair, 20% rain, 12% fog, 8% storm
|
||||||
|
fn pick(r: f32) -> u8 {
|
||||||
|
if r < 0.6 {
|
||||||
|
FAIR
|
||||||
|
} else if r < 0.8 {
|
||||||
|
RAIN
|
||||||
|
} else if r < 0.92 {
|
||||||
|
FOG
|
||||||
|
} else {
|
||||||
|
STORM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Weather {
|
||||||
|
// strength of an effect: rain falls in rain and storms, fog in fog (a little in storms)
|
||||||
|
pub fn rain(&self) -> f32 {
|
||||||
|
if matches!(self.shown, RAIN | STORM) { self.level } else { 0.0 }
|
||||||
|
}
|
||||||
|
pub fn fog(&self) -> f32 {
|
||||||
|
match self.shown {
|
||||||
|
FOG => self.level,
|
||||||
|
STORM => self.level * 0.4,
|
||||||
|
_ => 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// how much the daylight is dimmed (0 .. 1)
|
||||||
|
pub fn gloom(&self) -> f32 {
|
||||||
|
self.level
|
||||||
|
* match self.shown {
|
||||||
|
RAIN => 0.3,
|
||||||
|
FOG => 0.2,
|
||||||
|
STORM => 0.55,
|
||||||
|
_ => 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Game {
|
||||||
|
pub fn has_sky(&self) -> bool {
|
||||||
|
self.map.sky.iter().any(|&s| s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// it rains on tile i right now (enough to put out fire)
|
||||||
|
pub fn rain_at(&self, i: usize) -> bool {
|
||||||
|
self.weather.rain() > 0.4 && self.map.sky(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sight of a unit standing on tile i (fog outside shortens it)
|
||||||
|
pub fn sight_at(&self, i: usize, base: i32) -> i32 {
|
||||||
|
if !self.map.sky(i) {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
((base as f32) * (1.0 - 0.5 * self.weather.fog())).round().max(2.0) as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn update_weather(&mut self, dt: f32) {
|
||||||
|
if self.map.sky.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let w = &mut self.weather;
|
||||||
|
w.left -= dt;
|
||||||
|
if w.left <= 0.0 {
|
||||||
|
// after bad weather it clears up more often
|
||||||
|
let r = self.rng.f();
|
||||||
|
let next = if w.kind != FAIR && r < 0.5 { FAIR } else { pick(self.rng.f()) };
|
||||||
|
let w = &mut self.weather;
|
||||||
|
w.kind = next;
|
||||||
|
w.left = if next == FAIR { 180.0 + self.rng.f() * 240.0 } else { 90.0 + self.rng.f() * 150.0 };
|
||||||
|
let w = &mut self.weather;
|
||||||
|
if w.kind != w.shown || w.level < 0.99 {
|
||||||
|
let key = ["msg.weather_clear", "msg.weather_rain", "msg.weather_fog", "msg.weather_storm"][next as usize];
|
||||||
|
if next != FAIR || w.shown != FAIR {
|
||||||
|
self.tell_local(key, vec![], None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// soft changes: the old weather fades out before the new one fades in
|
||||||
|
let w = &mut self.weather;
|
||||||
|
if w.shown != w.kind {
|
||||||
|
w.level -= dt / FADE;
|
||||||
|
if w.level <= 0.0 {
|
||||||
|
w.level = 0.0;
|
||||||
|
w.shown = w.kind;
|
||||||
|
}
|
||||||
|
} else if w.kind != FAIR {
|
||||||
|
w.level = (w.level + dt / FADE).min(1.0);
|
||||||
|
} else {
|
||||||
|
w.level = (w.level - dt / FADE).max(0.0);
|
||||||
|
}
|
||||||
|
// rain puts out the burning bridges outside
|
||||||
|
if self.weather.rain() > 0.4 && !self.bridgework.burning.is_empty() {
|
||||||
|
let map = &self.map;
|
||||||
|
self.bridgework.burning.retain(|b| !map.sky(b.0));
|
||||||
|
}
|
||||||
|
// lightning in a storm
|
||||||
|
if self.weather.shown == STORM && self.weather.level > 0.6 {
|
||||||
|
self.weather.strike_t -= dt;
|
||||||
|
if self.weather.strike_t <= 0.0 {
|
||||||
|
self.weather.strike_t = 6.0 + self.rng.f() * 14.0;
|
||||||
|
self.lightning_strike();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a bolt from the sky: a unit outside (now and then) or a tree, else bare land
|
||||||
|
pub(crate) fn lightning_strike(&mut self) {
|
||||||
|
let outside: Vec<usize> = (0..self.ents.len()).filter(|&j| {
|
||||||
|
let e = &self.ents[j];
|
||||||
|
e.alive && !e.held && e.captive == 0 && self.map.sky(e.tile())
|
||||||
|
}).collect();
|
||||||
|
let r = self.rng.f();
|
||||||
|
let (x, y) = if r < 0.35 && !outside.is_empty() {
|
||||||
|
let j = outside[(self.rng.next() as usize) % outside.len()];
|
||||||
|
let e = &mut self.ents[j];
|
||||||
|
e.hp -= BOLT_DAMAGE;
|
||||||
|
e.flash = 0.3;
|
||||||
|
let (x, y, side, kind, hero, dead) = (e.x, e.y, e.side, e.kind, e.hero, e.hp <= 0.0);
|
||||||
|
if !hero && side == self.local_side {
|
||||||
|
self.tell_local("msg.lightning_unit", vec![format!("@{}", st(kind).name)], None);
|
||||||
|
}
|
||||||
|
if dead {
|
||||||
|
self.kill(j);
|
||||||
|
}
|
||||||
|
(x, y)
|
||||||
|
} else {
|
||||||
|
let trees: Vec<usize> = (0..self.map.t.len()).filter(|&i| self.map.t[i].kind == Kind::Tree && self.map.sky(i)).collect();
|
||||||
|
if let Some(&i) = trees.get((self.rng.next() as usize) % trees.len().max(1)) {
|
||||||
|
// the tree is split and burns down
|
||||||
|
let t = &mut self.map.t[i];
|
||||||
|
t.kind = Kind::Floor;
|
||||||
|
t.owner = Owner::None;
|
||||||
|
t.marked = false;
|
||||||
|
t.hp = 0.0;
|
||||||
|
let (tx, ty) = xy(i);
|
||||||
|
self.fx(3, tx as f32 + 0.5, ty as f32 + 0.5, 0.0, 0.0, 1.2, 0xff304050);
|
||||||
|
(tx as f32 + 0.5, ty as f32 + 0.5)
|
||||||
|
} else {
|
||||||
|
let sky: Vec<usize> = (0..self.map.t.len()).filter(|&i| self.map.sky(i)).collect();
|
||||||
|
let Some(&i) = sky.get((self.rng.next() as usize) % sky.len().max(1)) else { return };
|
||||||
|
let (tx, ty) = xy(i);
|
||||||
|
(tx as f32 + 0.5, ty as f32 + 0.5)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.weather.flash = self.time;
|
||||||
|
self.fx(1, x, y, 0.0, 0.0, 0.5, 0xffffeeaa);
|
||||||
|
self.sfx(Sfx::Lightning, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn surface_game() -> Game {
|
||||||
|
let mut g = Game::new(7, 96, 96);
|
||||||
|
g.add_surface(7, 0.5, 3);
|
||||||
|
assert!(g.has_sky());
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn the_weather_changes_and_is_mostly_fair() {
|
||||||
|
let mut g = surface_game();
|
||||||
|
let mut seen = [0usize; 4];
|
||||||
|
for _ in 0..(4 * 60 * 60) {
|
||||||
|
g.update_weather(1.0);
|
||||||
|
seen[g.weather.shown as usize] += 1;
|
||||||
|
}
|
||||||
|
assert!(seen[FAIR as usize] > seen.iter().sum::<usize>() / 3, "{:?}", seen);
|
||||||
|
assert!(seen.iter().filter(|&&n| n > 0).count() >= 3, "several kinds of weather: {:?}", seen);
|
||||||
|
// no weather underground only
|
||||||
|
let mut u = Game::new(7, 96, 96);
|
||||||
|
u.weather.left = 0.0;
|
||||||
|
u.update_weather(1.0);
|
||||||
|
assert_eq!(u.weather.level, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rain_puts_out_fires_and_fog_shortens_sight() {
|
||||||
|
let mut g = surface_game();
|
||||||
|
let i = (0..g.map.t.len()).find(|&i| g.map.sky(i)).unwrap();
|
||||||
|
g.bridgework.burning.push((i, 0.0));
|
||||||
|
g.weather = Weather { kind: RAIN, shown: RAIN, level: 1.0, left: 100.0, ..Default::default() };
|
||||||
|
g.update_weather(0.1);
|
||||||
|
assert!(g.bridgework.burning.is_empty(), "rain puts the fire out");
|
||||||
|
assert!(g.rain_at(i));
|
||||||
|
g.weather = Weather { kind: FOG, shown: FOG, level: 1.0, left: 100.0, ..Default::default() };
|
||||||
|
assert!(g.sight_at(i, 6) < 6);
|
||||||
|
let under = (0..g.map.t.len()).find(|&i| !g.map.sky(i)).unwrap();
|
||||||
|
assert_eq!(g.sight_at(under, 6), 6, "underground nothing changes");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn storms_strike_with_lightning() {
|
||||||
|
let mut g = surface_game();
|
||||||
|
let trees0 = g.map.t.iter().filter(|t| t.kind == Kind::Tree).count();
|
||||||
|
let i = (0..g.map.t.len()).find(|&i| g.map.sky(i) && g.map.t[i].walkable()).unwrap();
|
||||||
|
let (x, y) = xy(i);
|
||||||
|
let id = g.spawn(EK::Knight, true, x as f32 + 0.5, y as f32 + 0.5, 1);
|
||||||
|
g.weather = Weather { kind: STORM, shown: STORM, level: 1.0, left: 1000.0, ..Default::default() };
|
||||||
|
for _ in 0..30 {
|
||||||
|
g.lightning_strike();
|
||||||
|
}
|
||||||
|
let trees = g.map.t.iter().filter(|t| t.kind == Kind::Tree).count();
|
||||||
|
let hurt = g.ents.iter().find(|e| e.id == id).map_or(true, |e| e.hp < e.max_hp);
|
||||||
|
assert!(trees < trees0 || hurt, "lightning hit something");
|
||||||
|
assert!(g.weather.flash > 0.0 || g.time == 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user