Surface world: grass in daylight, forests, cliffs with cave mouths; free-game and editor option
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ef10b5c432
commit
8a35a903de
32 files changed
+343
-24
No files matched your search
@@ -725,6 +725,9 @@ net.ai_off = Vyp.
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Soupeři
|
newgame.difficulty = Soupeři
|
||||||
|
newgame.land = Terén
|
||||||
|
newgame.land0 = Pod zemí
|
||||||
|
newgame.land1 = Napůl na povrchu
|
||||||
diff.0 = Lehká
|
diff.0 = Lehká
|
||||||
diff.1 = Střední
|
diff.1 = Střední
|
||||||
diff.2 = Těžká
|
diff.2 = Těžká
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Rytířské pevnosti
|
|||||||
ed.rivals = Soupeřící mistři
|
ed.rivals = Soupeřící mistři
|
||||||
ed.difficulty = Obtížnost
|
ed.difficulty = Obtížnost
|
||||||
ed.portals = Portály
|
ed.portals = Portály
|
||||||
|
ed.surface = Povrch (východ)
|
||||||
ed.edit_map = Upravit mapu
|
ed.edit_map = Upravit mapu
|
||||||
ed.make_random = Udělat náhodnou mapu
|
ed.make_random = Udělat náhodnou mapu
|
||||||
ed.paint_map = Vygenerovat a kreslit mapu
|
ed.paint_map = Vygenerovat a kreslit mapu
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Rubínová žíla
|
|||||||
ed.terrain.diamond = Diamantová žíla
|
ed.terrain.diamond = Diamantová žíla
|
||||||
ed.terrain.steel = Ocelová zeď
|
ed.terrain.steel = Ocelová zeď
|
||||||
ed.terrain.mushroom = Obří houba
|
ed.terrain.mushroom = Obří houba
|
||||||
|
ed.terrain.grass = Tráva (povrch)
|
||||||
|
ed.terrain.tree = Strom
|
||||||
ed.place.core = Jádro duše
|
ed.place.core = Jádro duše
|
||||||
ed.place.portal = Portál
|
ed.place.portal = Portál
|
||||||
ed.place.gate = Brána hrdinů
|
ed.place.gate = Brána hrdinů
|
||||||
|
|||||||
@@ -724,6 +724,9 @@ net.ai_off = Fra
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Modstandere
|
newgame.difficulty = Modstandere
|
||||||
|
newgame.land = Terræn
|
||||||
|
newgame.land0 = Under jorden
|
||||||
|
newgame.land1 = Halvt over jorden
|
||||||
diff.0 = Let
|
diff.0 = Let
|
||||||
diff.1 = Middel
|
diff.1 = Middel
|
||||||
diff.2 = Svær
|
diff.2 = Svær
|
||||||
@@ -1130,6 +1133,7 @@ ed.forts = Ridderfæstninger
|
|||||||
ed.rivals = Rivaliserende mestre
|
ed.rivals = Rivaliserende mestre
|
||||||
ed.difficulty = Sværhedsgrad
|
ed.difficulty = Sværhedsgrad
|
||||||
ed.portals = Portaler
|
ed.portals = Portaler
|
||||||
|
ed.surface = Over jorden (øst)
|
||||||
ed.edit_map = Rediger kortet
|
ed.edit_map = Rediger kortet
|
||||||
ed.make_random = Gør det til et tilfældigt kort
|
ed.make_random = Gør det til et tilfældigt kort
|
||||||
ed.paint_map = Generer og mal kortet
|
ed.paint_map = Generer og mal kortet
|
||||||
@@ -1210,6 +1214,8 @@ ed.terrain.ruby = Rubinåre
|
|||||||
ed.terrain.diamond = Diamantåre
|
ed.terrain.diamond = Diamantåre
|
||||||
ed.terrain.steel = Stålmur
|
ed.terrain.steel = Stålmur
|
||||||
ed.terrain.mushroom = Kæmpesvamp
|
ed.terrain.mushroom = Kæmpesvamp
|
||||||
|
ed.terrain.grass = Græs (over jorden)
|
||||||
|
ed.terrain.tree = Træ
|
||||||
ed.place.core = Sjælekerne
|
ed.place.core = Sjælekerne
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Helteport
|
ed.place.gate = Helteport
|
||||||
|
|||||||
@@ -724,6 +724,9 @@ net.ai_off = Aus
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Gegner
|
newgame.difficulty = Gegner
|
||||||
|
newgame.land = Gelände
|
||||||
|
newgame.land0 = Unterirdisch
|
||||||
|
newgame.land1 = Halb über der Erde
|
||||||
diff.0 = Leicht
|
diff.0 = Leicht
|
||||||
diff.1 = Mittel
|
diff.1 = Mittel
|
||||||
diff.2 = Schwer
|
diff.2 = Schwer
|
||||||
@@ -1130,6 +1133,7 @@ ed.forts = Ritterfestungen
|
|||||||
ed.rivals = Rivalen-Meister
|
ed.rivals = Rivalen-Meister
|
||||||
ed.difficulty = Schwierigkeit
|
ed.difficulty = Schwierigkeit
|
||||||
ed.portals = Portale
|
ed.portals = Portale
|
||||||
|
ed.surface = Oberwelt (Osten)
|
||||||
ed.edit_map = Karte bearbeiten
|
ed.edit_map = Karte bearbeiten
|
||||||
ed.make_random = Zur Zufallskarte machen
|
ed.make_random = Zur Zufallskarte machen
|
||||||
ed.paint_map = Karte erzeugen und malen
|
ed.paint_map = Karte erzeugen und malen
|
||||||
@@ -1210,6 +1214,8 @@ ed.terrain.ruby = Rubinader
|
|||||||
ed.terrain.diamond = Diamantader
|
ed.terrain.diamond = Diamantader
|
||||||
ed.terrain.steel = Stahlwand
|
ed.terrain.steel = Stahlwand
|
||||||
ed.terrain.mushroom = Riesenpilz
|
ed.terrain.mushroom = Riesenpilz
|
||||||
|
ed.terrain.grass = Gras (Oberwelt)
|
||||||
|
ed.terrain.tree = Baum
|
||||||
ed.place.core = Seelenkern
|
ed.place.core = Seelenkern
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Heldentor
|
ed.place.gate = Heldentor
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Όχι
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Αντίπαλοι
|
newgame.difficulty = Αντίπαλοι
|
||||||
|
newgame.land = Έδαφος
|
||||||
|
newgame.land0 = Υπόγεια
|
||||||
|
newgame.land1 = Μισό στην επιφάνεια
|
||||||
diff.0 = Εύκολο
|
diff.0 = Εύκολο
|
||||||
diff.1 = Μέτριο
|
diff.1 = Μέτριο
|
||||||
diff.2 = Δύσκολο
|
diff.2 = Δύσκολο
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Ιπποτικά φρούρια
|
|||||||
ed.rivals = Αντίπαλοι άρχοντες
|
ed.rivals = Αντίπαλοι άρχοντες
|
||||||
ed.difficulty = Δυσκολία
|
ed.difficulty = Δυσκολία
|
||||||
ed.portals = Πύλες μετάβασης
|
ed.portals = Πύλες μετάβασης
|
||||||
|
ed.surface = Επιφάνεια (ανατολή)
|
||||||
ed.edit_map = Επεξεργασία χάρτη
|
ed.edit_map = Επεξεργασία χάρτη
|
||||||
ed.make_random = Κάν' τον τυχαίο χάρτη
|
ed.make_random = Κάν' τον τυχαίο χάρτη
|
||||||
ed.paint_map = Δημιουργία και ζωγραφική χάρτη
|
ed.paint_map = Δημιουργία και ζωγραφική χάρτη
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Φλέβα ρουμπινιού
|
|||||||
ed.terrain.diamond = Φλέβα διαμαντιού
|
ed.terrain.diamond = Φλέβα διαμαντιού
|
||||||
ed.terrain.steel = Ατσάλινος τοίχος
|
ed.terrain.steel = Ατσάλινος τοίχος
|
||||||
ed.terrain.mushroom = Γιγάντιο μανιτάρι
|
ed.terrain.mushroom = Γιγάντιο μανιτάρι
|
||||||
|
ed.terrain.grass = Γρασίδι (επιφάνεια)
|
||||||
|
ed.terrain.tree = Δέντρο
|
||||||
ed.place.core = Πυρήνας ψυχής
|
ed.place.core = Πυρήνας ψυχής
|
||||||
ed.place.portal = Πύλη μετάβασης
|
ed.place.portal = Πύλη μετάβασης
|
||||||
ed.place.gate = Πύλη ηρώων
|
ed.place.gate = Πύλη ηρώων
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Off
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Opponents
|
newgame.difficulty = Opponents
|
||||||
|
newgame.land = Land
|
||||||
|
newgame.land0 = Underground
|
||||||
|
newgame.land1 = Half above ground
|
||||||
diff.0 = Easy
|
diff.0 = Easy
|
||||||
diff.1 = Medium
|
diff.1 = Medium
|
||||||
diff.2 = Hard
|
diff.2 = Hard
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Knight fortresses
|
|||||||
ed.rivals = Rival masters
|
ed.rivals = Rival masters
|
||||||
ed.difficulty = Difficulty
|
ed.difficulty = Difficulty
|
||||||
ed.portals = Portals
|
ed.portals = Portals
|
||||||
|
ed.surface = Above ground (east)
|
||||||
ed.edit_map = Edit the map
|
ed.edit_map = Edit the map
|
||||||
ed.make_random = Make it a random map
|
ed.make_random = Make it a random map
|
||||||
ed.paint_map = Generate and paint the map
|
ed.paint_map = Generate and paint the map
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Ruby vein
|
|||||||
ed.terrain.diamond = Diamond vein
|
ed.terrain.diamond = Diamond vein
|
||||||
ed.terrain.steel = Steel wall
|
ed.terrain.steel = Steel wall
|
||||||
ed.terrain.mushroom = Giant mushroom
|
ed.terrain.mushroom = Giant mushroom
|
||||||
|
ed.terrain.grass = Grass (above ground)
|
||||||
|
ed.terrain.tree = Tree
|
||||||
ed.place.core = Soul core
|
ed.place.core = Soul core
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Hero gate
|
ed.place.gate = Hero gate
|
||||||
|
|||||||
@@ -717,6 +717,9 @@ net.ai_off = No
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Rivales
|
newgame.difficulty = Rivales
|
||||||
|
newgame.land = Terreno
|
||||||
|
newgame.land0 = Subterráneo
|
||||||
|
newgame.land1 = Mitad en superficie
|
||||||
diff.0 = Fácil
|
diff.0 = Fácil
|
||||||
diff.1 = Normal
|
diff.1 = Normal
|
||||||
diff.2 = Difícil
|
diff.2 = Difícil
|
||||||
@@ -1123,6 +1126,7 @@ ed.forts = Fortalezas
|
|||||||
ed.rivals = Señores rivales
|
ed.rivals = Señores rivales
|
||||||
ed.difficulty = Dificultad
|
ed.difficulty = Dificultad
|
||||||
ed.portals = Portales
|
ed.portals = Portales
|
||||||
|
ed.surface = Superficie (este)
|
||||||
ed.edit_map = Editar el mapa
|
ed.edit_map = Editar el mapa
|
||||||
ed.make_random = Hacerlo aleatorio
|
ed.make_random = Hacerlo aleatorio
|
||||||
ed.paint_map = Generar y pintar el mapa
|
ed.paint_map = Generar y pintar el mapa
|
||||||
@@ -1203,6 +1207,8 @@ ed.terrain.ruby = Veta de rubíes
|
|||||||
ed.terrain.diamond = Veta de diamantes
|
ed.terrain.diamond = Veta de diamantes
|
||||||
ed.terrain.steel = Muro de acero
|
ed.terrain.steel = Muro de acero
|
||||||
ed.terrain.mushroom = Seta gigante
|
ed.terrain.mushroom = Seta gigante
|
||||||
|
ed.terrain.grass = Hierba (superficie)
|
||||||
|
ed.terrain.tree = Árbol
|
||||||
ed.place.core = Núcleo de alma
|
ed.place.core = Núcleo de alma
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Puerta de héroes
|
ed.place.gate = Puerta de héroes
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Pois
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Vastustajat
|
newgame.difficulty = Vastustajat
|
||||||
|
newgame.land = Maasto
|
||||||
|
newgame.land0 = Maan alla
|
||||||
|
newgame.land1 = Puoliksi maan päällä
|
||||||
diff.0 = Helppo
|
diff.0 = Helppo
|
||||||
diff.1 = Keski
|
diff.1 = Keski
|
||||||
diff.2 = Vaikea
|
diff.2 = Vaikea
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Ritarilinnat
|
|||||||
ed.rivals = Kilpailijat
|
ed.rivals = Kilpailijat
|
||||||
ed.difficulty = Vaikeus
|
ed.difficulty = Vaikeus
|
||||||
ed.portals = Portaalit
|
ed.portals = Portaalit
|
||||||
|
ed.surface = Maan päällä (itä)
|
||||||
ed.edit_map = Muokkaa karttaa
|
ed.edit_map = Muokkaa karttaa
|
||||||
ed.make_random = Tee siitä satunnaiskartta
|
ed.make_random = Tee siitä satunnaiskartta
|
||||||
ed.paint_map = Luo ja piirrä kartta
|
ed.paint_map = Luo ja piirrä kartta
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Rubiinisuoni
|
|||||||
ed.terrain.diamond = Timanttisuoni
|
ed.terrain.diamond = Timanttisuoni
|
||||||
ed.terrain.steel = Teräsmuuri
|
ed.terrain.steel = Teräsmuuri
|
||||||
ed.terrain.mushroom = Jättisieni
|
ed.terrain.mushroom = Jättisieni
|
||||||
|
ed.terrain.grass = Ruoho (maan päällä)
|
||||||
|
ed.terrain.tree = Puu
|
||||||
ed.place.core = Sieluydin
|
ed.place.core = Sieluydin
|
||||||
ed.place.portal = Portaali
|
ed.place.portal = Portaali
|
||||||
ed.place.gate = Sankariportti
|
ed.place.gate = Sankariportti
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Isklj.
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Protivnici
|
newgame.difficulty = Protivnici
|
||||||
|
newgame.land = Teren
|
||||||
|
newgame.land0 = Pod zemljom
|
||||||
|
newgame.land1 = Pola na površini
|
||||||
diff.0 = Lako
|
diff.0 = Lako
|
||||||
diff.1 = Srednje
|
diff.1 = Srednje
|
||||||
diff.2 = Teško
|
diff.2 = Teško
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Viteške tvrđave
|
|||||||
ed.rivals = Suparnici
|
ed.rivals = Suparnici
|
||||||
ed.difficulty = Težina
|
ed.difficulty = Težina
|
||||||
ed.portals = Portali
|
ed.portals = Portali
|
||||||
|
ed.surface = Površina (istok)
|
||||||
ed.edit_map = Uredi kartu
|
ed.edit_map = Uredi kartu
|
||||||
ed.make_random = Pretvori u slučajnu kartu
|
ed.make_random = Pretvori u slučajnu kartu
|
||||||
ed.paint_map = Generiraj i nacrtaj kartu
|
ed.paint_map = Generiraj i nacrtaj kartu
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Žila rubina
|
|||||||
ed.terrain.diamond = Žila dijamanata
|
ed.terrain.diamond = Žila dijamanata
|
||||||
ed.terrain.steel = Čelični zid
|
ed.terrain.steel = Čelični zid
|
||||||
ed.terrain.mushroom = Divovska gljiva
|
ed.terrain.mushroom = Divovska gljiva
|
||||||
|
ed.terrain.grass = Trava (površina)
|
||||||
|
ed.terrain.tree = Stablo
|
||||||
ed.place.core = Jezgra duše
|
ed.place.core = Jezgra duše
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Vrata junaka
|
ed.place.gate = Vrata junaka
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Ki
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Ellenfelek
|
newgame.difficulty = Ellenfelek
|
||||||
|
newgame.land = Terep
|
||||||
|
newgame.land0 = Föld alatt
|
||||||
|
newgame.land1 = Félig a felszínen
|
||||||
diff.0 = Könnyű
|
diff.0 = Könnyű
|
||||||
diff.1 = Közepes
|
diff.1 = Közepes
|
||||||
diff.2 = Nehéz
|
diff.2 = Nehéz
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Lovagerődök
|
|||||||
ed.rivals = Rivális mesterek
|
ed.rivals = Rivális mesterek
|
||||||
ed.difficulty = Nehézség
|
ed.difficulty = Nehézség
|
||||||
ed.portals = Portálok
|
ed.portals = Portálok
|
||||||
|
ed.surface = Felszín (kelet)
|
||||||
ed.edit_map = Térkép szerkesztése
|
ed.edit_map = Térkép szerkesztése
|
||||||
ed.make_random = Legyen véletlen térkép
|
ed.make_random = Legyen véletlen térkép
|
||||||
ed.paint_map = Térkép generálása és festése
|
ed.paint_map = Térkép generálása és festése
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Rubinér
|
|||||||
ed.terrain.diamond = Gyémántér
|
ed.terrain.diamond = Gyémántér
|
||||||
ed.terrain.steel = Acélfal
|
ed.terrain.steel = Acélfal
|
||||||
ed.terrain.mushroom = Óriásgomba
|
ed.terrain.mushroom = Óriásgomba
|
||||||
|
ed.terrain.grass = Fű (felszín)
|
||||||
|
ed.terrain.tree = Fa
|
||||||
ed.place.core = Lélekmag
|
ed.place.core = Lélekmag
|
||||||
ed.place.portal = Portál
|
ed.place.portal = Portál
|
||||||
ed.place.gate = Hőskapu
|
ed.place.gate = Hőskapu
|
||||||
|
|||||||
@@ -717,6 +717,9 @@ net.ai_off = No
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Avversari
|
newgame.difficulty = Avversari
|
||||||
|
newgame.land = Terreno
|
||||||
|
newgame.land0 = Sotterraneo
|
||||||
|
newgame.land1 = Metà in superficie
|
||||||
diff.0 = Facile
|
diff.0 = Facile
|
||||||
diff.1 = Medio
|
diff.1 = Medio
|
||||||
diff.2 = Difficile
|
diff.2 = Difficile
|
||||||
@@ -1123,6 +1126,7 @@ ed.forts = Fortezze
|
|||||||
ed.rivals = Maestri rivali
|
ed.rivals = Maestri rivali
|
||||||
ed.difficulty = Difficoltà
|
ed.difficulty = Difficoltà
|
||||||
ed.portals = Portali
|
ed.portals = Portali
|
||||||
|
ed.surface = Superficie (est)
|
||||||
ed.edit_map = Modifica mappa
|
ed.edit_map = Modifica mappa
|
||||||
ed.make_random = Rendila casuale
|
ed.make_random = Rendila casuale
|
||||||
ed.paint_map = Genera e dipingi la mappa
|
ed.paint_map = Genera e dipingi la mappa
|
||||||
@@ -1203,6 +1207,8 @@ ed.terrain.ruby = Vena di rubini
|
|||||||
ed.terrain.diamond = Vena di diamanti
|
ed.terrain.diamond = Vena di diamanti
|
||||||
ed.terrain.steel = Muro d'acciaio
|
ed.terrain.steel = Muro d'acciaio
|
||||||
ed.terrain.mushroom = Fungo gigante
|
ed.terrain.mushroom = Fungo gigante
|
||||||
|
ed.terrain.grass = Erba (superficie)
|
||||||
|
ed.terrain.tree = Albero
|
||||||
ed.place.core = Nucleo dell'Anima
|
ed.place.core = Nucleo dell'Anima
|
||||||
ed.place.portal = Portale
|
ed.place.portal = Portale
|
||||||
ed.place.gate = Porta degli Eroi
|
ed.place.gate = Porta degli Eroi
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Uit
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Tegenstanders
|
newgame.difficulty = Tegenstanders
|
||||||
|
newgame.land = Terrein
|
||||||
|
newgame.land0 = Ondergronds
|
||||||
|
newgame.land1 = Half bovengronds
|
||||||
diff.0 = Makkelijk
|
diff.0 = Makkelijk
|
||||||
diff.1 = Middel
|
diff.1 = Middel
|
||||||
diff.2 = Moeilijk
|
diff.2 = Moeilijk
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Riddervestingen
|
|||||||
ed.rivals = Rivalen
|
ed.rivals = Rivalen
|
||||||
ed.difficulty = Moeilijkheid
|
ed.difficulty = Moeilijkheid
|
||||||
ed.portals = Portalen
|
ed.portals = Portalen
|
||||||
|
ed.surface = Bovengronds (oosten)
|
||||||
ed.edit_map = Kaart bewerken
|
ed.edit_map = Kaart bewerken
|
||||||
ed.make_random = Maak er een willekeurige kaart van
|
ed.make_random = Maak er een willekeurige kaart van
|
||||||
ed.paint_map = Kaart genereren en tekenen
|
ed.paint_map = Kaart genereren en tekenen
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Robijnader
|
|||||||
ed.terrain.diamond = Diamantader
|
ed.terrain.diamond = Diamantader
|
||||||
ed.terrain.steel = Stalen muur
|
ed.terrain.steel = Stalen muur
|
||||||
ed.terrain.mushroom = Reuzenpaddenstoel
|
ed.terrain.mushroom = Reuzenpaddenstoel
|
||||||
|
ed.terrain.grass = Gras (bovengronds)
|
||||||
|
ed.terrain.tree = Boom
|
||||||
ed.place.core = Zielenkern
|
ed.place.core = Zielenkern
|
||||||
ed.place.portal = Portaal
|
ed.place.portal = Portaal
|
||||||
ed.place.gate = Heldenpoort
|
ed.place.gate = Heldenpoort
|
||||||
|
|||||||
@@ -724,6 +724,9 @@ net.ai_off = Av
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Motstandere
|
newgame.difficulty = Motstandere
|
||||||
|
newgame.land = Terreng
|
||||||
|
newgame.land0 = Under jorden
|
||||||
|
newgame.land1 = Halvt over jorden
|
||||||
diff.0 = Lett
|
diff.0 = Lett
|
||||||
diff.1 = Middels
|
diff.1 = Middels
|
||||||
diff.2 = Vanskelig
|
diff.2 = Vanskelig
|
||||||
@@ -1130,6 +1133,7 @@ ed.forts = Ridderfestninger
|
|||||||
ed.rivals = Rivaliserende mestere
|
ed.rivals = Rivaliserende mestere
|
||||||
ed.difficulty = Vanskelighetsgrad
|
ed.difficulty = Vanskelighetsgrad
|
||||||
ed.portals = Portaler
|
ed.portals = Portaler
|
||||||
|
ed.surface = Over jorden (øst)
|
||||||
ed.edit_map = Rediger kartet
|
ed.edit_map = Rediger kartet
|
||||||
ed.make_random = Gjør det til et tilfeldig kart
|
ed.make_random = Gjør det til et tilfeldig kart
|
||||||
ed.paint_map = Generer og mal kartet
|
ed.paint_map = Generer og mal kartet
|
||||||
@@ -1210,6 +1214,8 @@ ed.terrain.ruby = Rubinåre
|
|||||||
ed.terrain.diamond = Diamantåre
|
ed.terrain.diamond = Diamantåre
|
||||||
ed.terrain.steel = Stålvegg
|
ed.terrain.steel = Stålvegg
|
||||||
ed.terrain.mushroom = Kjempesopp
|
ed.terrain.mushroom = Kjempesopp
|
||||||
|
ed.terrain.grass = Gress (over jorden)
|
||||||
|
ed.terrain.tree = Tre
|
||||||
ed.place.core = Sjelekjerne
|
ed.place.core = Sjelekjerne
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Helteport
|
ed.place.gate = Helteport
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Desl.
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Adversários
|
newgame.difficulty = Adversários
|
||||||
|
newgame.land = Terreno
|
||||||
|
newgame.land0 = Subterrâneo
|
||||||
|
newgame.land1 = Metade à superfície
|
||||||
diff.0 = Fácil
|
diff.0 = Fácil
|
||||||
diff.1 = Médio
|
diff.1 = Médio
|
||||||
diff.2 = Difícil
|
diff.2 = Difícil
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Fortalezas
|
|||||||
ed.rivals = Mestres rivais
|
ed.rivals = Mestres rivais
|
||||||
ed.difficulty = Dificuldade
|
ed.difficulty = Dificuldade
|
||||||
ed.portals = Portais
|
ed.portals = Portais
|
||||||
|
ed.surface = Superfície (leste)
|
||||||
ed.edit_map = Editar o mapa
|
ed.edit_map = Editar o mapa
|
||||||
ed.make_random = Tornar mapa aleatório
|
ed.make_random = Tornar mapa aleatório
|
||||||
ed.paint_map = Gerar e pintar o mapa
|
ed.paint_map = Gerar e pintar o mapa
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Veio de rubis
|
|||||||
ed.terrain.diamond = Veio diamantes
|
ed.terrain.diamond = Veio diamantes
|
||||||
ed.terrain.steel = Parede de aço
|
ed.terrain.steel = Parede de aço
|
||||||
ed.terrain.mushroom = Cogumelo gigante
|
ed.terrain.mushroom = Cogumelo gigante
|
||||||
|
ed.terrain.grass = Relva (superfície)
|
||||||
|
ed.terrain.tree = Árvore
|
||||||
ed.place.core = Núcleo de alma
|
ed.place.core = Núcleo de alma
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Portão heróis
|
ed.place.gate = Portão heróis
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Oprit
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Adversari
|
newgame.difficulty = Adversari
|
||||||
|
newgame.land = Teren
|
||||||
|
newgame.land0 = Subteran
|
||||||
|
newgame.land1 = Jumătate la suprafață
|
||||||
diff.0 = Ușor
|
diff.0 = Ușor
|
||||||
diff.1 = Mediu
|
diff.1 = Mediu
|
||||||
diff.2 = Greu
|
diff.2 = Greu
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Fortărețe cavalerești
|
|||||||
ed.rivals = Stăpâni rivali
|
ed.rivals = Stăpâni rivali
|
||||||
ed.difficulty = Dificultate
|
ed.difficulty = Dificultate
|
||||||
ed.portals = Portaluri
|
ed.portals = Portaluri
|
||||||
|
ed.surface = Suprafață (est)
|
||||||
ed.edit_map = Editează harta
|
ed.edit_map = Editează harta
|
||||||
ed.make_random = Fă-o hartă aleatoare
|
ed.make_random = Fă-o hartă aleatoare
|
||||||
ed.paint_map = Generează și pictează harta
|
ed.paint_map = Generează și pictează harta
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Filon de rubine
|
|||||||
ed.terrain.diamond = Filon de diamante
|
ed.terrain.diamond = Filon de diamante
|
||||||
ed.terrain.steel = Zid de oțel
|
ed.terrain.steel = Zid de oțel
|
||||||
ed.terrain.mushroom = Ciupercă uriașă
|
ed.terrain.mushroom = Ciupercă uriașă
|
||||||
|
ed.terrain.grass = Iarbă (suprafață)
|
||||||
|
ed.terrain.tree = Copac
|
||||||
ed.place.core = Miezul sufletului
|
ed.place.core = Miezul sufletului
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Poarta eroilor
|
ed.place.gate = Poarta eroilor
|
||||||
|
|||||||
@@ -717,6 +717,9 @@ net.ai_off = Выкл
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Противники
|
newgame.difficulty = Противники
|
||||||
|
newgame.land = Местность
|
||||||
|
newgame.land0 = Под землёй
|
||||||
|
newgame.land1 = Наполовину наверху
|
||||||
diff.0 = Легко
|
diff.0 = Легко
|
||||||
diff.1 = Средне
|
diff.1 = Средне
|
||||||
diff.2 = Сложно
|
diff.2 = Сложно
|
||||||
@@ -1123,6 +1126,7 @@ ed.forts = Крепости
|
|||||||
ed.rivals = Соперники
|
ed.rivals = Соперники
|
||||||
ed.difficulty = Сложность
|
ed.difficulty = Сложность
|
||||||
ed.portals = Порталы
|
ed.portals = Порталы
|
||||||
|
ed.surface = Поверхность (восток)
|
||||||
ed.edit_map = Изменить карту
|
ed.edit_map = Изменить карту
|
||||||
ed.make_random = Сделать случайной
|
ed.make_random = Сделать случайной
|
||||||
ed.paint_map = Создать и нарисовать карту
|
ed.paint_map = Создать и нарисовать карту
|
||||||
@@ -1203,6 +1207,8 @@ ed.terrain.ruby = Рубиновая жила
|
|||||||
ed.terrain.diamond = Алмазная жила
|
ed.terrain.diamond = Алмазная жила
|
||||||
ed.terrain.steel = Стальная стена
|
ed.terrain.steel = Стальная стена
|
||||||
ed.terrain.mushroom = Гигантский гриб
|
ed.terrain.mushroom = Гигантский гриб
|
||||||
|
ed.terrain.grass = Трава (поверхность)
|
||||||
|
ed.terrain.tree = Дерево
|
||||||
ed.place.core = Ядро души
|
ed.place.core = Ядро души
|
||||||
ed.place.portal = Портал
|
ed.place.portal = Портал
|
||||||
ed.place.gate = Врата героев
|
ed.place.gate = Врата героев
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Vyp.
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Súperi
|
newgame.difficulty = Súperi
|
||||||
|
newgame.land = Terén
|
||||||
|
newgame.land0 = Pod zemou
|
||||||
|
newgame.land1 = Napoly na povrchu
|
||||||
diff.0 = Ľahká
|
diff.0 = Ľahká
|
||||||
diff.1 = Stredná
|
diff.1 = Stredná
|
||||||
diff.2 = Ťažká
|
diff.2 = Ťažká
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Rytierske pevnosti
|
|||||||
ed.rivals = Súperiaci majstri
|
ed.rivals = Súperiaci majstri
|
||||||
ed.difficulty = Obťažnosť
|
ed.difficulty = Obťažnosť
|
||||||
ed.portals = Portály
|
ed.portals = Portály
|
||||||
|
ed.surface = Povrch (východ)
|
||||||
ed.edit_map = Upraviť mapu
|
ed.edit_map = Upraviť mapu
|
||||||
ed.make_random = Urobiť náhodnú mapu
|
ed.make_random = Urobiť náhodnú mapu
|
||||||
ed.paint_map = Vygenerovať a kresliť mapu
|
ed.paint_map = Vygenerovať a kresliť mapu
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Rubínová žila
|
|||||||
ed.terrain.diamond = Diamantová žila
|
ed.terrain.diamond = Diamantová žila
|
||||||
ed.terrain.steel = Oceľová stena
|
ed.terrain.steel = Oceľová stena
|
||||||
ed.terrain.mushroom = Obria huba
|
ed.terrain.mushroom = Obria huba
|
||||||
|
ed.terrain.grass = Tráva (povrch)
|
||||||
|
ed.terrain.tree = Strom
|
||||||
ed.place.core = Jadro duše
|
ed.place.core = Jadro duše
|
||||||
ed.place.portal = Portál
|
ed.place.portal = Portál
|
||||||
ed.place.gate = Brána hrdinov
|
ed.place.gate = Brána hrdinov
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Иск.
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Противници
|
newgame.difficulty = Противници
|
||||||
|
newgame.land = Терен
|
||||||
|
newgame.land0 = Под земљом
|
||||||
|
newgame.land1 = Пола на површини
|
||||||
diff.0 = Лако
|
diff.0 = Лако
|
||||||
diff.1 = Средње
|
diff.1 = Средње
|
||||||
diff.2 = Тешко
|
diff.2 = Тешко
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Витешке тврђаве
|
|||||||
ed.rivals = Супарници
|
ed.rivals = Супарници
|
||||||
ed.difficulty = Тежина
|
ed.difficulty = Тежина
|
||||||
ed.portals = Портали
|
ed.portals = Портали
|
||||||
|
ed.surface = Површина (исток)
|
||||||
ed.edit_map = Уреди мапу
|
ed.edit_map = Уреди мапу
|
||||||
ed.make_random = Претвори у случајну мапу
|
ed.make_random = Претвори у случајну мапу
|
||||||
ed.paint_map = Генериши и нацртај мапу
|
ed.paint_map = Генериши и нацртај мапу
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Жила рубина
|
|||||||
ed.terrain.diamond = Жила дијаманата
|
ed.terrain.diamond = Жила дијаманата
|
||||||
ed.terrain.steel = Челични зид
|
ed.terrain.steel = Челични зид
|
||||||
ed.terrain.mushroom = Џиновска печурка
|
ed.terrain.mushroom = Џиновска печурка
|
||||||
|
ed.terrain.grass = Трава (површина)
|
||||||
|
ed.terrain.tree = Стабло
|
||||||
ed.place.core = Језгро душе
|
ed.place.core = Језгро душе
|
||||||
ed.place.portal = Портал
|
ed.place.portal = Портал
|
||||||
ed.place.gate = Капија хероја
|
ed.place.gate = Капија хероја
|
||||||
|
|||||||
@@ -725,6 +725,9 @@ net.ai_off = Av
|
|||||||
|
|
||||||
# rival masters (free game)
|
# rival masters (free game)
|
||||||
newgame.difficulty = Motståndare
|
newgame.difficulty = Motståndare
|
||||||
|
newgame.land = Terräng
|
||||||
|
newgame.land0 = Under jord
|
||||||
|
newgame.land1 = Halvt ovan jord
|
||||||
diff.0 = Lätt
|
diff.0 = Lätt
|
||||||
diff.1 = Medel
|
diff.1 = Medel
|
||||||
diff.2 = Svår
|
diff.2 = Svår
|
||||||
@@ -1131,6 +1134,7 @@ ed.forts = Riddarfästningar
|
|||||||
ed.rivals = Rivaliserande mästare
|
ed.rivals = Rivaliserande mästare
|
||||||
ed.difficulty = Svårighetsgrad
|
ed.difficulty = Svårighetsgrad
|
||||||
ed.portals = Portaler
|
ed.portals = Portaler
|
||||||
|
ed.surface = Ovan jord (öster)
|
||||||
ed.edit_map = Redigera kartan
|
ed.edit_map = Redigera kartan
|
||||||
ed.make_random = Gör den till slumpkarta
|
ed.make_random = Gör den till slumpkarta
|
||||||
ed.paint_map = Generera och måla kartan
|
ed.paint_map = Generera och måla kartan
|
||||||
@@ -1211,6 +1215,8 @@ ed.terrain.ruby = Rubinåder
|
|||||||
ed.terrain.diamond = Diamantåder
|
ed.terrain.diamond = Diamantåder
|
||||||
ed.terrain.steel = Stålvägg
|
ed.terrain.steel = Stålvägg
|
||||||
ed.terrain.mushroom = Jättesvamp
|
ed.terrain.mushroom = Jättesvamp
|
||||||
|
ed.terrain.grass = Gräs (ovan jord)
|
||||||
|
ed.terrain.tree = Träd
|
||||||
ed.place.core = Själskärna
|
ed.place.core = Själskärna
|
||||||
ed.place.portal = Portal
|
ed.place.portal = Portal
|
||||||
ed.place.gate = Hjälteport
|
ed.place.gate = Hjälteport
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ pub struct MissionDef {
|
|||||||
pub rivals: Vec<(f32, f32, u8, u8)>, // rival masters: position (fraction of the map), difficulty, side (2 Mossgrim, 3 Lady Nightwell)
|
pub rivals: Vec<(f32, f32, u8, u8)>, // rival masters: position (fraction of the map), difficulty, side (2 Mossgrim, 3 Lady Nightwell)
|
||||||
pub islands: Vec<IslandDef>,
|
pub islands: Vec<IslandDef>,
|
||||||
pub caves: Vec<CaveDef>,
|
pub caves: Vec<CaveDef>,
|
||||||
|
pub surface: f32, // share of the width from where the map lies above ground (0: none)
|
||||||
}
|
}
|
||||||
|
|
||||||
// an island in a lake of water or lava, with treasure and/or a mana spring
|
// an island in a lake of water or lava, with treasure and/or a mana spring
|
||||||
@@ -166,6 +167,7 @@ fn base(key: &str, size: (usize, usize), seed: u32, goals: Vec<Goal>) -> Mission
|
|||||||
rivals: Vec::new(),
|
rivals: Vec::new(),
|
||||||
islands: Vec::new(),
|
islands: Vec::new(),
|
||||||
caves: Vec::new(),
|
caves: Vec::new(),
|
||||||
|
surface: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +183,7 @@ pub fn mission_def_from_doc(d: &crate::campaign_doc::MissionDoc) -> MissionDef {
|
|||||||
out.gate = d.waves;
|
out.gate = d.waves;
|
||||||
out.gate_defenders = d.waves;
|
out.gate_defenders = d.waves;
|
||||||
out.time_limit = d.time_limit;
|
out.time_limit = d.time_limit;
|
||||||
|
out.surface = if d.gen.surface { 0.5 } else { 0.0 };
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,6 +540,9 @@ fn start_mission_def(d: &MissionDef, i: usize, carry: Option<&Carry>, coop: bool
|
|||||||
}
|
}
|
||||||
g.place_dwarf_caves(d.seed);
|
g.place_dwarf_caves(d.seed);
|
||||||
g.add_wilds(d.seed, false);
|
g.add_wilds(d.seed, false);
|
||||||
|
if d.surface > 0.0 {
|
||||||
|
g.add_surface(d.seed, d.surface, 2 + (h / 64) as u32);
|
||||||
|
}
|
||||||
g.init_research(Some(i));
|
g.init_research(Some(i));
|
||||||
g.init_fog();
|
g.init_fog();
|
||||||
let heart = d.gate || d.forts.iter().any(|f| f.heart);
|
let heart = d.gate || d.forts.iter().any(|f| f.heart);
|
||||||
|
|||||||
+3
-1
@@ -145,11 +145,13 @@ pub struct GenDoc {
|
|||||||
pub rivals: u8, // 0..2 rival masters
|
pub rivals: u8, // 0..2 rival masters
|
||||||
#[serde(default = "default_difficulty")]
|
#[serde(default = "default_difficulty")]
|
||||||
pub difficulty: u8, // 0 easy, 1 medium, 2 hard
|
pub difficulty: u8, // 0 easy, 1 medium, 2 hard
|
||||||
|
#[serde(default)]
|
||||||
|
pub surface: bool, // the eastern half lies above ground (forest)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GenDoc {
|
impl Default for GenDoc {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GenDoc { rivers: 1, lava: 0, forts: 1, rivals: 0, difficulty: 1 }
|
GenDoc { rivers: 1, lava: 0, forts: 1, rivals: 0, difficulty: 1, surface: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ pub fn coop_campaign() -> CampaignDoc {
|
|||||||
waves: sp.waves.0,
|
waves: sp.waves.0,
|
||||||
wave_limit: sp.waves.1,
|
wave_limit: sp.waves.1,
|
||||||
first_wave: if sp.waves.0 { sp.waves.2 } else { 300.0 },
|
first_wave: if sp.waves.0 { sp.waves.2 } else { 300.0 },
|
||||||
gen: GenDoc { rivers: sp.gen.0, lava: sp.gen.1, forts: sp.gen.2, rivals: 0, difficulty: sp.gen.3 },
|
gen: GenDoc { rivers: sp.gen.0, lava: sp.gen.1, forts: sp.gen.2, rivals: 0, difficulty: sp.gen.3, surface: false },
|
||||||
next: (i + 1 < specs.len()).then(|| format!("c{:02}", i + 2)),
|
next: (i + 1 < specs.len()).then(|| format!("c{:02}", i + 2)),
|
||||||
pos: (40.0 + (i % 5) as f32 * 220.0, 40.0 + (i / 5) as f32 * 140.0),
|
pos: (40.0 + (i % 5) as f32 * 220.0, 40.0 + (i / 5) as f32 * 140.0),
|
||||||
..MissionDoc::default()
|
..MissionDoc::default()
|
||||||
|
|||||||
+8
-3
@@ -35,7 +35,7 @@ enum Cat {
|
|||||||
|
|
||||||
const CATS: [Cat; 9] = [Cat::Terrain, Cat::Rooms, Cat::Places, Cat::Units, Cat::Towers, Cat::Traps, Cat::Forts, Cat::Zones, Cat::Erase];
|
const CATS: [Cat; 9] = [Cat::Terrain, Cat::Rooms, Cat::Places, Cat::Units, Cat::Towers, Cat::Traps, Cat::Forts, Cat::Zones, Cat::Erase];
|
||||||
|
|
||||||
const TERRAIN: [&str; 14] = ["floor", "earth", "reinforced", "rock", "water", "lava", "bridge", "lavabridge", "gold", "silver", "ruby", "diamond", "steel", "mushroom"];
|
const TERRAIN: [&str; 16] = ["floor", "earth", "reinforced", "rock", "water", "lava", "bridge", "lavabridge", "gold", "silver", "ruby", "diamond", "steel", "mushroom", "grass", "tree"];
|
||||||
const PLACES: [&str; 7] = ["core", "portal", "gate", "spring", "shard", "chest", "chained"];
|
const PLACES: [&str; 7] = ["core", "portal", "gate", "spring", "shard", "chest", "chained"];
|
||||||
const OWNERS: [Owner; 6] = [Owner::Player, Owner::Hero, Owner::Rival1, Owner::Rival2, Owner::Rival3, Owner::None];
|
const OWNERS: [Owner; 6] = [Owner::Player, Owner::Hero, Owner::Rival1, Owner::Rival2, Owner::Rival3, Owner::None];
|
||||||
const ZONE_SHAPES: [&str; 4] = ["rect", "circle", "tiles", "line"];
|
const ZONE_SHAPES: [&str; 4] = ["rect", "circle", "tiles", "line"];
|
||||||
@@ -76,6 +76,8 @@ fn kind_of_terrain(t: &str) -> (Kind, bool) {
|
|||||||
"bridge" => (Kind::Bridge, false),
|
"bridge" => (Kind::Bridge, false),
|
||||||
"lavabridge" => (Kind::LavaBridge, false),
|
"lavabridge" => (Kind::LavaBridge, false),
|
||||||
"mushroom" => (Kind::Mushroom, false),
|
"mushroom" => (Kind::Mushroom, false),
|
||||||
|
"grass" => (Kind::Floor, false),
|
||||||
|
"tree" => (Kind::Tree, false),
|
||||||
"gold" => (Kind::Gold, false),
|
"gold" => (Kind::Gold, false),
|
||||||
"silver" => (Kind::Silver, false),
|
"silver" => (Kind::Silver, false),
|
||||||
"ruby" => (Kind::Ruby, false),
|
"ruby" => (Kind::Ruby, false),
|
||||||
@@ -209,7 +211,10 @@ impl MapEdit {
|
|||||||
}
|
}
|
||||||
match self.cat {
|
match self.cat {
|
||||||
Cat::Terrain => {
|
Cat::Terrain => {
|
||||||
let (k, reinforced) = kind_of_terrain(TERRAIN[self.item.min(TERRAIN.len() - 1)]);
|
let name = TERRAIN[self.item.min(TERRAIN.len() - 1)];
|
||||||
|
let (k, reinforced) = kind_of_terrain(name);
|
||||||
|
// grass and trees lie above ground; anything else is painted underground
|
||||||
|
self.game.map.set_sky(i, matches!(name, "grass" | "tree"));
|
||||||
self.game.torches.retain(|tr| tr.wall != i);
|
self.game.torches.retain(|tr| tr.wall != i);
|
||||||
let owner = if k == Kind::Floor || reinforced || matches!(k, Kind::Bridge | Kind::LavaBridge) { OWNERS[self.owner] } else { Owner::None };
|
let owner = if k == Kind::Floor || reinforced || matches!(k, Kind::Bridge | Kind::LavaBridge) { OWNERS[self.owner] } else { Owner::None };
|
||||||
let tl = &mut self.game.map.t[i];
|
let tl = &mut self.game.map.t[i];
|
||||||
@@ -218,7 +223,7 @@ impl MapEdit {
|
|||||||
tl.owner = if reinforced && owner == Owner::None { Owner::Player } else { owner };
|
tl.owner = if reinforced && owner == Owner::None { Owner::Player } else { owner };
|
||||||
tl.marked = false;
|
tl.marked = false;
|
||||||
if tl.plant() {
|
if tl.plant() {
|
||||||
tl.hp = crate::wood::MUSHROOM_HP;
|
tl.hp = if k == Kind::Tree { crate::wood::TREE_HP } else { crate::wood::MUSHROOM_HP };
|
||||||
}
|
}
|
||||||
tl.gold = match k {
|
tl.gold = match k {
|
||||||
Kind::Gold => 1200,
|
Kind::Gold => 1200,
|
||||||
|
|||||||
@@ -777,6 +777,7 @@ impl Editor {
|
|||||||
(tr("ed.rivals"), m.gen.rivals.to_string(), 6),
|
(tr("ed.rivals"), m.gen.rivals.to_string(), 6),
|
||||||
(tr("ed.difficulty"), tr(["diff.0", "diff.1", "diff.2"][m.gen.difficulty.min(2) as usize]), 7),
|
(tr("ed.difficulty"), tr(["diff.0", "diff.1", "diff.2"][m.gen.difficulty.min(2) as usize]), 7),
|
||||||
(tr("ed.portals"), m.portals.to_string(), 8),
|
(tr("ed.portals"), m.portals.to_string(), 8),
|
||||||
|
(tr("ed.surface"), tr(if m.gen.surface { "val.on" } else { "val.off" }), 9),
|
||||||
];
|
];
|
||||||
if fixed {
|
if fixed {
|
||||||
rows.truncate(0);
|
rows.truncate(0);
|
||||||
@@ -794,6 +795,7 @@ impl Editor {
|
|||||||
5 => m.gen.forts = (m.gen.forts as i32 + d.signum()).clamp(0, 3) as u8,
|
5 => m.gen.forts = (m.gen.forts as i32 + d.signum()).clamp(0, 3) as u8,
|
||||||
6 => m.gen.rivals = (m.gen.rivals as i32 + d.signum()).clamp(0, 2) as u8,
|
6 => m.gen.rivals = (m.gen.rivals as i32 + d.signum()).clamp(0, 2) as u8,
|
||||||
7 => m.gen.difficulty = (m.gen.difficulty as i32 + d.signum()).clamp(0, 2) as u8,
|
7 => m.gen.difficulty = (m.gen.difficulty as i32 + d.signum()).clamp(0, 2) as u8,
|
||||||
|
9 => m.gen.surface = !m.gen.surface,
|
||||||
_ => m.portals = (m.portals as i32 + d.signum()).clamp(0, 6) as usize,
|
_ => m.portals = (m.portals as i32 + d.signum()).clamp(0, 6) as usize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ pub fn demo_campaign() -> CampaignDoc {
|
|||||||
seed: 4242,
|
seed: 4242,
|
||||||
gold: 4000.0,
|
gold: 4000.0,
|
||||||
goals: vec!["Towers".into()],
|
goals: vec!["Towers".into()],
|
||||||
gen: GenDoc { rivers: 1, lava: 0, forts: 1, rivals: 0, difficulty: 0 },
|
gen: GenDoc { rivers: 1, lava: 0, forts: 1, rivals: 0, difficulty: 0, surface: false },
|
||||||
next: Some("demo2".into()),
|
next: Some("demo2".into()),
|
||||||
branches: vec![BranchDoc { id: "rich".into(), goal: "Loot(2000)".into(), title: tr("demo.branch"), next: "demo2".into(), priority: Some(1) }],
|
branches: vec![BranchDoc { id: "rich".into(), goal: "Loot(2000)".into(), title: tr("demo.branch"), next: "demo2".into(), priority: Some(1) }],
|
||||||
pos: (40.0, 60.0),
|
pos: (40.0, 60.0),
|
||||||
@@ -226,7 +226,7 @@ pub fn demo_campaign() -> CampaignDoc {
|
|||||||
seed: 77,
|
seed: 77,
|
||||||
gold: 3000.0,
|
gold: 3000.0,
|
||||||
goals: vec!["KillAll".into()],
|
goals: vec!["KillAll".into()],
|
||||||
gen: GenDoc { rivers: 1, lava: 1, forts: 1, rivals: 0, difficulty: 0 },
|
gen: GenDoc { rivers: 1, lava: 1, forts: 1, rivals: 0, difficulty: 0, surface: false },
|
||||||
pos: (300.0, 60.0),
|
pos: (300.0, 60.0),
|
||||||
..MissionDoc::default()
|
..MissionDoc::default()
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -788,7 +788,7 @@ mod tests {
|
|||||||
use crate::blocks::{Block, Val};
|
use crate::blocks::{Block, Val};
|
||||||
use crate::campaign_doc::*;
|
use crate::campaign_doc::*;
|
||||||
let mut doc = CampaignDoc { name: "Coop test".into(), ..CampaignDoc::default() };
|
let mut doc = CampaignDoc { name: "Coop test".into(), ..CampaignDoc::default() };
|
||||||
let mut m = MissionDoc { key: "c1".into(), title: "Random".into(), size: (80, 80), seed: 5, goals: vec!["KillAll".into(), "Rivals".into()], waves: true, first_wave: 3.0, gen: GenDoc { rivers: 1, lava: 1, forts: 1, rivals: 1, difficulty: 1 }, ..MissionDoc::default() };
|
let mut m = MissionDoc { key: "c1".into(), title: "Random".into(), size: (80, 80), seed: 5, goals: vec!["KillAll".into(), "Rivals".into()], waves: true, first_wave: 3.0, gen: GenDoc { rivers: 1, lava: 1, forts: 1, rivals: 1, difficulty: 1, surface: false }, ..MissionDoc::default() };
|
||||||
m.scripts.start = vec![Block::Gold { amount: Val::num(250.0) }];
|
m.scripts.start = vec![Block::Gold { amount: Val::num(250.0) }];
|
||||||
m.scripts.triggers = vec![TriggerDoc { name: "wave".into(), kind: TriggerKind::Timer { secs: 2.0, every: true }, once: false, enabled: true, script: vec![Block::Wave { count: Val::num(1.0) }] }];
|
m.scripts.triggers = vec![TriggerDoc { name: "wave".into(), kind: TriggerKind::Timer { secs: 2.0, every: true }, once: false, enabled: true, script: vec![Block::Wave { count: Val::num(1.0) }] }];
|
||||||
doc.missions.push(m.clone());
|
doc.missions.push(m.clone());
|
||||||
|
|||||||
+7
-1
@@ -37,6 +37,7 @@ mod sfx;
|
|||||||
mod tracks;
|
mod tracks;
|
||||||
mod traps;
|
mod traps;
|
||||||
mod sound;
|
mod sound;
|
||||||
|
mod surface;
|
||||||
mod spells;
|
mod spells;
|
||||||
mod touch;
|
mod touch;
|
||||||
mod ui;
|
mod ui;
|
||||||
@@ -173,7 +174,12 @@ fn finish_rect(app: &mut App, tool: Tool, start: (i32, i32), mx: f32, my: f32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_game(seed: u32, s: &Settings) -> (Game, Cam) {
|
fn new_game(seed: u32, s: &Settings) -> (Game, Cam) {
|
||||||
let g = Game::new_free(seed, s.map_w, s.map_h, s.difficulty);
|
let mut g = Game::new_free(seed, s.map_w, s.map_h, s.difficulty);
|
||||||
|
if s.surface {
|
||||||
|
// the eastern half above ground: forest, paths, cave mouths
|
||||||
|
g.add_surface(seed, 0.5, 2 + (s.map_h / 64) as u32);
|
||||||
|
g.init_fog();
|
||||||
|
}
|
||||||
let (cx, cy) = g.map.core;
|
let (cx, cy) = g.map.core;
|
||||||
let cam = Cam::new(cx as f32 + 1.5, cy as f32 + 1.5);
|
let cam = Cam::new(cx as f32 + 1.5, cy as f32 + 1.5);
|
||||||
(g, cam)
|
(g, cam)
|
||||||
|
|||||||
+18
-1
@@ -350,6 +350,8 @@ pub struct Map {
|
|||||||
pub explored: Vec<bool>, // fog of war: tiles the dungeon knows (empty: no fog)
|
pub explored: Vec<bool>, // fog of war: tiles the dungeon knows (empty: no fog)
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
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")]
|
||||||
|
pub sky: Vec<bool>, // tiles above ground (daylight, grass); empty: all underground
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size() -> usize {
|
fn default_size() -> usize {
|
||||||
@@ -367,6 +369,21 @@ impl Map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tile i lies above ground
|
||||||
|
pub fn sky(&self, i: usize) -> bool {
|
||||||
|
self.sky.get(i).copied().unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_sky(&mut self, i: usize, on: bool) {
|
||||||
|
if self.sky.len() != self.t.len() {
|
||||||
|
if !on {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.sky = vec![false; self.t.len()];
|
||||||
|
}
|
||||||
|
self.sky[i] = on;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, x: i32, y: i32) -> Option<&Tile> {
|
pub fn get(&self, x: i32, y: i32) -> Option<&Tile> {
|
||||||
if inb(x, y) {
|
if inb(x, y) {
|
||||||
Some(&self.t[idx(x, y)])
|
Some(&self.t[idx(x, y)])
|
||||||
@@ -587,7 +604,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() }
|
Map { w, h, t, core, portals, legacy_portal: None, gate, treasures, explored: Vec::new(), visible: Vec::new(), sky: 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.
|
||||||
|
|||||||
+15
-7
@@ -230,6 +230,7 @@ enum Btn {
|
|||||||
Tab(usize),
|
Tab(usize),
|
||||||
Change(usize, i32),
|
Change(usize, i32),
|
||||||
MapW(i32),
|
MapW(i32),
|
||||||
|
Land,
|
||||||
MapH(i32),
|
MapH(i32),
|
||||||
Difficulty(i32),
|
Difficulty(i32),
|
||||||
Start,
|
Start,
|
||||||
@@ -675,6 +676,10 @@ impl Menu {
|
|||||||
settings.difficulty = (settings.difficulty as i32 + d).rem_euclid(3) as u8;
|
settings.difficulty = (settings.difficulty as i32 + d).rem_euclid(3) as u8;
|
||||||
MenuAction::SettingsChanged
|
MenuAction::SettingsChanged
|
||||||
}
|
}
|
||||||
|
Some(Btn::Land) => {
|
||||||
|
settings.surface = !settings.surface;
|
||||||
|
MenuAction::SettingsChanged
|
||||||
|
}
|
||||||
Some(Btn::MapH(d)) => {
|
Some(Btn::MapH(d)) => {
|
||||||
settings.map_h = (settings.map_h as i32 + d * 32).clamp(MIN_SIZE as i32, MAX_SIZE as i32) as usize;
|
settings.map_h = (settings.map_h as i32 + d * 32).clamp(MIN_SIZE as i32, MAX_SIZE as i32) as usize;
|
||||||
MenuAction::SettingsChanged
|
MenuAction::SettingsChanged
|
||||||
@@ -1153,27 +1158,30 @@ impl Menu {
|
|||||||
let sh = sh();
|
let sh = sh();
|
||||||
let (mx, my) = mouse();
|
let (mx, my) = mouse();
|
||||||
let cols = 48.min((sw / CW()) as i32);
|
let cols = 48.min((sw / CW()) as i32);
|
||||||
let rows = 22;
|
let rows = 25;
|
||||||
let x = grid_center(sw, cols as f32 * CW()).max(0.0);
|
let x = grid_center(sw, cols as f32 * CW()).max(0.0);
|
||||||
let y = (grid_center_y(sh, rows as f32 * CH())).max(0.0);
|
let y = (grid_center_y(sh, rows as f32 * CH())).max(0.0);
|
||||||
gfx.window_titled(x, y, cols, rows, S(), true, FRAME_HI, Color::new(0.05, 0.03, 0.04, 0.97), &tr("menu.new"), FRAME_HI);
|
gfx.window_titled(x, y, cols, rows, S(), true, FRAME_HI, Color::new(0.05, 0.03, 0.04, 0.97), &tr("menu.new"), FRAME_HI);
|
||||||
let diff = tr(&format!("diff.{}", s.difficulty.min(2)));
|
let diff = tr(&format!("diff.{}", s.difficulty.min(2)));
|
||||||
let lines = [("newgame.width", s.map_w.to_string(), 0), ("newgame.height", s.map_h.to_string(), 1), ("newgame.difficulty", diff, 2)];
|
let land = tr(if s.surface { "newgame.land1" } else { "newgame.land0" });
|
||||||
|
let lines = [("newgame.width", s.map_w.to_string(), 0), ("newgame.height", s.map_h.to_string(), 1), ("newgame.difficulty", diff, 2), ("newgame.land", land, 3)];
|
||||||
for (k, (key, val, which)) in lines.iter().enumerate() {
|
for (k, (key, val, which)) in lines.iter().enumerate() {
|
||||||
let (key, which) = (*key, *which);
|
let (key, which) = (*key, *which);
|
||||||
let by = y + CH() * (2.0 + k as f32 * 2.5);
|
let by = y + CH() * (2.0 + k as f32 * 2.5);
|
||||||
gfx.text(&tr(key), x + CW() * 3.0, by + CH() * 0.5, S(), TXT);
|
gfx.text(&tr(key), x + CW() * 3.0, by + CH() * 0.5, S(), TXT);
|
||||||
let vw = 14.0 * CW();
|
let vw = 18.0 * CW();
|
||||||
let vx = x + cols as f32 * CW() - vw - CW() * 3.0;
|
let vx = x + cols as f32 * CW() - vw - CW() * 3.0;
|
||||||
let left = Rect::new(vx, by, CW() * 2.5, CH() * 2.0);
|
let left = Rect::new(vx, by, CW() * 2.5, CH() * 2.0);
|
||||||
let right = Rect::new(vx + vw - CW() * 2.5, by, CW() * 2.5, CH() * 2.0);
|
let right = Rect::new(vx + vw - CW() * 2.5, by, CW() * 2.5, CH() * 2.0);
|
||||||
button(gfx, left, "<", left.contains(vec2(mx, my)), FRAME);
|
button(gfx, left, "<", left.contains(vec2(mx, my)), FRAME);
|
||||||
button(gfx, right, ">", right.contains(vec2(mx, my)), FRAME);
|
button(gfx, right, ">", right.contains(vec2(mx, my)), FRAME);
|
||||||
let v = val.clone();
|
let v = val.clone();
|
||||||
gfx.text(&v, vx + (vw - gfx.measure(&v, S())) * 0.5, by + CH() * 0.5, S(), GOLD);
|
let vs = if gfx.measure(&v, S()) > vw - CW() * 5.5 { SMALL() } else { S() };
|
||||||
|
gfx.text(&v, vx + (vw - gfx.measure(&v, vs)) * 0.5, by + CH() * 0.5, vs, GOLD);
|
||||||
let (l, r) = match which {
|
let (l, r) = match which {
|
||||||
0 => (Btn::MapW(-1), Btn::MapW(1)),
|
0 => (Btn::MapW(-1), Btn::MapW(1)),
|
||||||
1 => (Btn::MapH(-1), Btn::MapH(1)),
|
1 => (Btn::MapH(-1), Btn::MapH(1)),
|
||||||
|
3 => (Btn::Land, Btn::Land),
|
||||||
_ => (Btn::Difficulty(-1), Btn::Difficulty(1)),
|
_ => (Btn::Difficulty(-1), Btn::Difficulty(1)),
|
||||||
};
|
};
|
||||||
self.buttons.push((left, l));
|
self.buttons.push((left, l));
|
||||||
@@ -1183,14 +1191,14 @@ impl Menu {
|
|||||||
let area = (s.map_w * s.map_h) as f32 / 4096.0;
|
let area = (s.map_w * s.map_h) as f32 / 4096.0;
|
||||||
let portals = (area.round() as usize).max(1);
|
let portals = (area.round() as usize).max(1);
|
||||||
let info = trf("newgame.info", &[portals.to_string(), (portals - 1).to_string()]);
|
let info = trf("newgame.info", &[portals.to_string(), (portals - 1).to_string()]);
|
||||||
gfx.text(&info, x + CW() * 3.0, y + CH() * 10.0, S(), DIM);
|
gfx.text(&info, x + CW() * 3.0, y + CH() * 12.5, S(), DIM);
|
||||||
let opp = tr(if s.map_w * s.map_h > 128 * 128 { "newgame.opponents2" } else { "newgame.opponents1" });
|
let opp = tr(if s.map_w * s.map_h > 128 * 128 { "newgame.opponents2" } else { "newgame.opponents1" });
|
||||||
let maxc = (cols - 6) as usize;
|
let maxc = (cols - 6) as usize;
|
||||||
for (k, l) in wrap(&opp, maxc).iter().take(2).enumerate() {
|
for (k, l) in wrap(&opp, maxc).iter().take(2).enumerate() {
|
||||||
gfx.text(l, x + CW() * 3.0, y + CH() * (11.0 + k as f32), S(), DIM);
|
gfx.text(l, x + CW() * 3.0, y + CH() * (13.5 + k as f32), S(), DIM);
|
||||||
}
|
}
|
||||||
let w = (cols - 6) as f32 * CW();
|
let w = (cols - 6) as f32 * CW();
|
||||||
self.column(gfx, x + CW() * 3.0, y + CH() * 14.0, w, &[(Btn::Start, tr("newgame.start")), (Btn::Back, tr("menu.back"))]);
|
self.column(gfx, x + CW() * 3.0, y + CH() * 16.5, w, &[(Btn::Start, tr("newgame.start")), (Btn::Back, tr("menu.back"))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_pause(&mut self, gfx: &Gfx) {
|
fn draw_pause(&mut self, gfx: &Gfx) {
|
||||||
|
|||||||
+19
-7
@@ -449,6 +449,10 @@ fn ambient_field(map: &Map) -> Vec<f32> {
|
|||||||
(false, Owner::Hero) => 0.6,
|
(false, Owner::Hero) => 0.6,
|
||||||
_ => 0.0,
|
_ => 0.0,
|
||||||
};
|
};
|
||||||
|
// daylight above ground (cliffs and trees too)
|
||||||
|
if map.sky(i) {
|
||||||
|
f[i] = 1.6;
|
||||||
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
@@ -672,7 +676,11 @@ fn build_chunk(map: &Map, amb: &[f32], glow: &[f32], cx: i32, cz: i32, atlas: &T
|
|||||||
for z in cz * CHUNK..((cz + 1) * CHUNK).min(mh() as i32) {
|
for z in cz * CHUNK..((cz + 1) * CHUNK).min(mh() as i32) {
|
||||||
for x in cx * CHUNK..((cx + 1) * CHUNK).min(mw() as i32) {
|
for x in cx * CHUNK..((cx + 1) * CHUNK).min(mw() as i32) {
|
||||||
let t = map.t[idx(x, z)];
|
let t = map.t[idx(x, z)];
|
||||||
let tex = Gfx::tile_tex(t.kind, t.owner, t.var, t.reinforced);
|
let mut tex = Gfx::tile_tex(t.kind, t.owner, t.var, t.reinforced);
|
||||||
|
// open land above ground is grass (until a master claims it)
|
||||||
|
if map.sky(idx(x, z)) && t.kind == Kind::Floor && t.owner == Owner::None {
|
||||||
|
tex = T_GRASS + (t.var as u32 & 3);
|
||||||
|
}
|
||||||
let (ua, ub) = cell_uv(tex);
|
let (ua, ub) = cell_uv(tex);
|
||||||
let (xf, zf) = (x as f32, z as f32);
|
let (xf, zf) = (x as f32, z as f32);
|
||||||
if !map.shown(idx(x, z)) {
|
if !map.shown(idx(x, z)) {
|
||||||
@@ -836,11 +844,13 @@ fn build_chunk(map: &Map, amb: &[f32], glow: &[f32], cx: i32, cz: i32, atlas: &T
|
|||||||
c,
|
c,
|
||||||
[Vec3::Y; 4],
|
[Vec3::Y; 4],
|
||||||
);
|
);
|
||||||
// outlines: north and west edge, only between two open tiles (each edge once)
|
// outlines: north and west edge, only between two open tiles (each edge once);
|
||||||
if !solid_at(map, x, z - 1) {
|
// open land above ground has none
|
||||||
|
let outdoors = map.sky(idx(x, z)) && t.owner == Owner::None;
|
||||||
|
if !solid_at(map, x, z - 1) && !outdoors {
|
||||||
ln.strip(vec3(xf, 0.0, zf), vec3(xf + 1.0, 0.0, zf), Vec3::Y, OUTLINE_W, OUTLINE_C);
|
ln.strip(vec3(xf, 0.0, zf), vec3(xf + 1.0, 0.0, zf), Vec3::Y, OUTLINE_W, OUTLINE_C);
|
||||||
}
|
}
|
||||||
if !solid_at(map, x - 1, z) {
|
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);
|
||||||
}
|
}
|
||||||
// room decor
|
// room decor
|
||||||
@@ -871,7 +881,7 @@ fn build_chunk(map: &Map, amb: &[f32], glow: &[f32], cx: i32, cz: i32, atlas: &T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// wear and tear: grit and cracks on plain floors
|
// wear and tear: grit and cracks on plain floors
|
||||||
if matches!(t.kind, Kind::Floor) {
|
if matches!(t.kind, Kind::Floor) && !outdoors {
|
||||||
let hsh = (x as u32).wrapping_mul(2654435761) ^ (z as u32).wrapping_mul(2246822519);
|
let hsh = (x as u32).wrapping_mul(2654435761) ^ (z as u32).wrapping_mul(2246822519);
|
||||||
let hsh = (hsh ^ (hsh >> 15)).wrapping_mul(2246822519);
|
let hsh = (hsh ^ (hsh >> 15)).wrapping_mul(2246822519);
|
||||||
let decal = match hsh % 11 {
|
let decal = match hsh % 11 {
|
||||||
@@ -1083,7 +1093,7 @@ fn chunk_sig(map: &Map, cx: i32, cz: i32) -> u64 {
|
|||||||
Kind::Drawbridge => t.res as u64,
|
Kind::Drawbridge => t.res as u64,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
let shown = map.shown(idx(x, z)) as u64;
|
let shown = map.shown(idx(x, z)) as u64 | (map.sky(idx(x, z)) as u64) << 1;
|
||||||
(t.kind as u64) | (t.owner as u64) << 5 | (t.marked as u64) << 8 | (t.reinforced as u64) << 9 | shown << 10 | extra << 11
|
(t.kind as u64) | (t.owner as u64) << 5 | (t.marked as u64) << 8 | (t.reinforced as u64) << 9 | shown << 10 | extra << 11
|
||||||
}
|
}
|
||||||
None => 0xff,
|
None => 0xff,
|
||||||
@@ -1462,7 +1472,9 @@ impl R3d {
|
|||||||
let amb = |x: f32, z: f32| {
|
let amb = |x: f32, z: f32| {
|
||||||
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| t.owner == Owner::Player);
|
let own = g.map.get(ix, iz).map_or(false, |t| t.owner == Owner::Player);
|
||||||
if own {
|
if inb(ix, iz) && g.map.sky(idx(ix, iz)) {
|
||||||
|
0.95
|
||||||
|
} else if own {
|
||||||
0.75
|
0.75
|
||||||
} else {
|
} else {
|
||||||
0.5
|
0.5
|
||||||
|
|||||||
@@ -200,4 +200,13 @@ fn export_scenes() {
|
|||||||
g.plan_walls(cx + 5, cy - 1, cx + 5, cy + 2);
|
g.plan_walls(cx + 5, cy - 1, cx + 5, cy + 2);
|
||||||
run(&mut g, 2.0);
|
run(&mut g, 2.0);
|
||||||
save("wood", &mut g, mx as f32 + 0.5, my as f32 + 0.5, 14.0, 0.0, false);
|
save("wood", &mut g, mx as f32 + 0.5, my as f32 + 0.5, 14.0, 0.0, false);
|
||||||
|
|
||||||
|
// above ground: the cliff with a cave mouth, grass, a forest
|
||||||
|
let mut g = Game::new(23, 128, 96);
|
||||||
|
g.add_surface(23, 0.45, 3);
|
||||||
|
g.init_fog();
|
||||||
|
let mid = (mh() / 2) as i32;
|
||||||
|
let ex = (0..mw() as i32).find(|&x| g.map.sky(idx(x, mid))).unwrap_or(60);
|
||||||
|
run(&mut g, 1.0);
|
||||||
|
save("surface", &mut g, ex as f32 + 6.0, mid as f32, 24.0, 0.0, false);
|
||||||
}
|
}
|
||||||
@@ -162,6 +162,7 @@ pub struct Settings {
|
|||||||
pub difficulty: u8, // rival masters in free games: 0 easy, 1 medium, 2 hard
|
pub difficulty: u8, // rival masters in free games: 0 easy, 1 medium, 2 hard
|
||||||
pub map_w: usize, // size of new maps (64..256)
|
pub map_w: usize, // size of new maps (64..256)
|
||||||
pub map_h: usize,
|
pub map_h: usize,
|
||||||
|
pub surface: bool, // new free games: the eastern half lies above ground (forest)
|
||||||
// key bindings: action id -> key name
|
// key bindings: action id -> key name
|
||||||
pub keys: BTreeMap<String, String>,
|
pub keys: BTreeMap<String, String>,
|
||||||
}
|
}
|
||||||
@@ -196,6 +197,7 @@ impl Default for Settings {
|
|||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
map_w: 64,
|
map_w: 64,
|
||||||
map_h: 64,
|
map_h: 64,
|
||||||
|
surface: false,
|
||||||
keys: BTreeMap::new(),
|
keys: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
// The surface world: part of a map lies above ground - grass in daylight, forests whose trees
|
||||||
|
// imps fell for wood, winding paths, and a cliff with a few cave mouths between the dungeon in
|
||||||
|
// the rock and the open land. (The knights' fortress up there: see fortress.rs.)
|
||||||
|
|
||||||
|
use crate::game::*;
|
||||||
|
use crate::map::*;
|
||||||
|
|
||||||
|
// value noise in 0..1, smooth over `cell` tiles
|
||||||
|
fn noise(x: i32, y: i32, cell: i32, seed: u32) -> f32 {
|
||||||
|
let h = |x: i32, y: i32| {
|
||||||
|
let mut v = (x as u32).wrapping_mul(374761393) ^ (y as u32).wrapping_mul(668265263) ^ seed.wrapping_mul(2246822519);
|
||||||
|
v = (v ^ (v >> 13)).wrapping_mul(1274126177);
|
||||||
|
((v ^ (v >> 16)) & 0xffff) as f32 / 65535.0
|
||||||
|
};
|
||||||
|
let (cx, cy) = (x.div_euclid(cell), y.div_euclid(cell));
|
||||||
|
let (fx, fy) = ((x.rem_euclid(cell)) as f32 / cell as f32, (y.rem_euclid(cell)) as f32 / cell as f32);
|
||||||
|
let s = |t: f32| t * t * (3.0 - 2.0 * t);
|
||||||
|
let (sx, sy) = (s(fx), s(fy));
|
||||||
|
let a = h(cx, cy) * (1.0 - sx) + h(cx + 1, cy) * sx;
|
||||||
|
let b = h(cx, cy + 1) * (1.0 - sx) + h(cx + 1, cy + 1) * sx;
|
||||||
|
a * (1.0 - sy) + b * sy
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Game {
|
||||||
|
// Everything east of `from` (share of the width, the edge a little ragged) becomes surface:
|
||||||
|
// open grass with forests and paths. A cliff along the edge keeps the dungeon apart, broken
|
||||||
|
// by `mouths` cave entrances. Mission pieces (core, portals, gate, towers ...) stay.
|
||||||
|
pub fn add_surface(&mut self, seed: u32, from: f32, mouths: u32) {
|
||||||
|
let (w, h) = (mw() as i32, mh() as i32);
|
||||||
|
let edge = |y: i32| (from * w as f32) as i32 + ((noise(0, y, 6, seed ^ 0x51) - 0.5) * 6.0) as i32;
|
||||||
|
let mut mouth_rows: Vec<i32> = (0..mouths).map(|k| ((k as f32 + 0.5) / mouths as f32 * (h - 16) as f32) as i32 + 8 + ((noise(k as i32, 3, 2, seed) - 0.5) * 8.0) as i32).collect();
|
||||||
|
mouth_rows.sort_unstable();
|
||||||
|
// winding paths across the land (stay open, no trees)
|
||||||
|
let paths: Vec<f32> = (0..2).map(|k| 0.25 + 0.5 * k as f32 + (noise(k, 9, 2, seed) - 0.5) * 0.2).collect();
|
||||||
|
for y in 0..h {
|
||||||
|
let ex = edge(y);
|
||||||
|
for x in 0..w {
|
||||||
|
if x < ex - 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let i = idx(x, y);
|
||||||
|
let t = self.map.t[i];
|
||||||
|
let keep = matches!(t.kind, Kind::Core | Kind::Portal | Kind::Gate | Kind::Tower | Kind::Shard | Kind::ManaSpring | Kind::RuneChest | Kind::Water | Kind::Lava | Kind::Bridge | Kind::LavaBridge | Kind::Door)
|
||||||
|
|| t.owner != Owner::None
|
||||||
|
|| x < 2
|
||||||
|
|| y < 2
|
||||||
|
|| x >= w - 2
|
||||||
|
|| y >= h - 2;
|
||||||
|
// the cliff: two tiles of rock along the edge, open where a cave mouth is
|
||||||
|
if x <= ex {
|
||||||
|
let mouth = mouth_rows.iter().any(|&m| (y - m).abs() <= 1);
|
||||||
|
if !keep {
|
||||||
|
let tl = &mut self.map.t[i];
|
||||||
|
if mouth {
|
||||||
|
tl.kind = Kind::Floor;
|
||||||
|
} else {
|
||||||
|
tl.kind = Kind::Rock;
|
||||||
|
}
|
||||||
|
tl.owner = Owner::None;
|
||||||
|
tl.gold = 0;
|
||||||
|
tl.marked = false;
|
||||||
|
tl.reinforced = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.map.set_sky(i, true);
|
||||||
|
if keep {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let on_path = paths.iter().any(|&p| {
|
||||||
|
let py = p * h as f32 + (noise(x, 0, 9, seed ^ 0x77) - 0.5) * 14.0;
|
||||||
|
(y as f32 - py).abs() < 1.2
|
||||||
|
});
|
||||||
|
let wood = noise(x, y, 5, seed ^ 0xf0);
|
||||||
|
let rocks = noise(x, y, 4, seed ^ 0x0b);
|
||||||
|
let tl = &mut self.map.t[i];
|
||||||
|
tl.owner = Owner::None;
|
||||||
|
tl.gold = 0;
|
||||||
|
tl.marked = false;
|
||||||
|
tl.reinforced = false;
|
||||||
|
tl.hp = 0.0;
|
||||||
|
if !on_path && rocks > 0.86 {
|
||||||
|
tl.kind = Kind::Rock;
|
||||||
|
} else if !on_path && wood > 0.52 && (x * 7 + y * 13) % 3 != 0 {
|
||||||
|
tl.kind = Kind::Tree;
|
||||||
|
tl.hp = crate::wood::TREE_HP;
|
||||||
|
} else {
|
||||||
|
tl.kind = Kind::Floor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// the cave mouths run through into the dungeon: dig until open ground is reached
|
||||||
|
for &m in &mouth_rows {
|
||||||
|
let ex = edge(m);
|
||||||
|
let mut x = ex - 2;
|
||||||
|
while x > 2 {
|
||||||
|
let i = idx(x, m);
|
||||||
|
if self.map.t[i].walkable() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if self.map.t[i].solid() && !matches!(self.map.t[i].kind, Kind::Steel) {
|
||||||
|
let tl = &mut self.map.t[i];
|
||||||
|
tl.kind = Kind::Floor;
|
||||||
|
tl.owner = Owner::None;
|
||||||
|
tl.gold = 0;
|
||||||
|
}
|
||||||
|
x -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.recount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the share of the map above ground (0: a dungeon map)
|
||||||
|
#[allow(dead_code)] // tests and debugging
|
||||||
|
pub fn surface_share(&self) -> f32 {
|
||||||
|
if self.map.sky.is_empty() {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
self.map.sky.iter().filter(|&&s| s).count() as f32 / self.map.sky.len() as f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn half_the_map_becomes_a_forest_above_ground() {
|
||||||
|
let mut g = Game::new(21, 128, 96);
|
||||||
|
let core = g.map.core;
|
||||||
|
g.add_surface(21, 0.5, 3);
|
||||||
|
let share = g.surface_share();
|
||||||
|
assert!(share > 0.35 && share < 0.6, "share {}", share);
|
||||||
|
let trees = g.map.t.iter().filter(|t| t.kind == Kind::Tree).count();
|
||||||
|
assert!(trees > 200, "{} trees", trees);
|
||||||
|
assert_eq!(g.map.core, core);
|
||||||
|
assert_eq!(g.map.t[idx(core.0 + 1, core.1 + 1)].kind, Kind::Core);
|
||||||
|
// the surface can be reached from the core (cave mouths, trees can be felled)
|
||||||
|
let goal = |i: usize| g.map.sky(i) && g.map.t[i].walkable();
|
||||||
|
assert!(g.map.search(idx(core.0 + 1, core.1 + 3), g.map.hero_cost_as(false), goal, true).is_some());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user