Compare commits

...

21 Commits

Author SHA1 Message Date
irrlicht 87dd8e1190 changed test map 2026-07-01 00:32:05 +02:00
irrlicht 3bffb82560 added blender tutorial video 2026-07-01 00:32:05 +02:00
irrlicht f181bf4de9 Renamed Play State 2026-07-01 00:32:05 +02:00
Nebeltier 7dd6bfc40c Update cinemaseat.blend and cinemaseat.blend1 2026-06-30 21:50:45 +02:00
Nebeltier 0d080a8d94 Merge branch 'main' of https://git.bnd.wtf/irrlicht/wds.git 2026-06-30 21:21:27 +02:00
Nebeltier 613af7d7ea Update cinema_test.blend, cinemaseat.blend, and tiffy_torso.png 2026-06-30 21:19:46 +02:00
irrlicht b10641ee3c Blender tutorial in sources 2026-06-25 22:22:05 +02:00
Nebeltier 5b10d63970 Update Tiffany_model_color.blend, Tiffany_rigtest1.blend, and rigtest_1.blend 2026-06-25 21:49:25 +02:00
irrlicht fcdd8306d2 Deleted blend11 2026-06-24 23:13:39 +02:00
irrlicht 01fb83d05f Deleted blend11 2026-06-24 23:12:28 +02:00
Nebeltier 34024bab96 Update Tiffany_model.blend1 2026-06-24 20:58:27 +02:00
Nebeltier 40df66e7cc Update Tiffany_model.blend and Tiffany_model.blend1 2026-06-24 19:44:12 +02:00
Nebeltier 61c628876f Update Tiffany_model.blend 2026-06-23 22:29:11 +02:00
irrlicht 9aebddde86 Changed Player start 2026-06-17 02:06:45 +02:00
irrlicht 8ae566d627 Teppich-Varianten eingebaut 2026-06-17 01:55:56 +02:00
Nebeltier 6c4f2e640a test datein gelöscht 2026-06-16 20:59:25 +02:00
irrlicht 949a076ec7 Mipmapping an den Texturen 2026-06-16 10:39:58 +02:00
irrlicht 14961d903b Testmap mit Stein 2026-06-16 09:49:11 +02:00
irrlicht ccac320e0e Sonderzeichen in person.ink ersetzt 2026-06-15 11:52:47 +02:00
irrlicht ff3e66ae3e Scan auf nicht-CP437-Zeichen in Ink-Buildscript 2026-06-15 11:51:53 +02:00
irrlicht 7c92f046a1 nicht-CP437-Zeichen ersetzt 2026-06-15 11:51:20 +02:00
26 changed files with 178 additions and 307 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

+5 -5
View File
@@ -1,10 +1,10 @@
// Cinema 24/7 Navigation
// Lobby Foyer Labyrinth-Etagen Eingang Theater 4
// Cinema 24/7 -- Navigation
// Lobby -> Foyer -> Labyrinth-Etagen -> Eingang Theater 4
//
// Variablen:
// past_it Spieler ist an Theater 4 vorbeigegangen (bool)
// snaks Spieler hat Snacks mitgenommen (0/1)
// had_sweets Spieler hat süße Snacks gewählt (0/1)
// past_it -- Spieler ist an Theater 4 vorbeigegangen (bool)
// snaks -- Spieler hat Snacks mitgenommen (0/1)
// had_sweets -- Spieler hat süße Snacks gewählt (0/1)
//
// Übergang zu cinema_f4r4.ink via # start_ink Tag bei Eintreten in Theater 4.
// KV-Store überträgt snaks/had_sweets/past_it automatisch ans nächste Script.
+13 -13
View File
@@ -1,13 +1,13 @@
// Cinema 24/7 Theater 4: Nails
// Cinema 24/7 -- Theater 4: Nails
// Begegnung mit Nails, der Schattenkünstlerin.
//
// Variablen:
// favor_nails Nails' Stimmung; > 0 = Sympathie, < 0 = Genervtheit
// past_it aus cinema.ink via KV: Spieler ist an Theater 4 vorbeigegangen
// snaks aus cinema.ink via KV: Spieler hat Snacks (0/1)
// had_sweets aus cinema.ink via KV: Spieler hat Süßes gewählt (0/1)
// fallbear temporär: Bär verliert Gleichgewicht beim Ausweichen
// boop_success temporär: Einhorn-Nase boopen erfolgreich (0/1)
// favor_nails -- Nails' Stimmung; > 0 = Sympathie, < 0 = Genervtheit
// past_it -- aus cinema.ink via KV: Spieler ist an Theater 4 vorbeigegangen
// snaks -- aus cinema.ink via KV: Spieler hat Snacks (0/1)
// had_sweets -- aus cinema.ink via KV: Spieler hat Süßes gewählt (0/1)
// fallbear -- temporär: Bär verliert Gleichgewicht beim Ausweichen
// boop_success -- temporär: Einhorn-Nase boopen erfolgreich (0/1)
//
// Stub-Knoten (noch zu schreiben):
// the_show, cbear, shadow_battle, apprentice, quitter,
@@ -448,7 +448,7 @@ Her: No. It's fine. You can sit down in the front as well. Just there will be fi
--
++ [Project]
// TODO: per Shuffle zufällig zwischen "passable" und "ugly" wechseln.
// Inklecate unterstützt keine mehrzeiligen {~}-Sequenzen braucht
// Inklecate unterstützt keine mehrzeiligen {~}-Sequenzen -- braucht
// VAR wolf_ugly + { shuffle: - ... - ... }-Syntax oder zwei Pfade.
And... you create a passable attempt. Much smaller and a little crooked, maybe.
--
@@ -798,11 +798,11 @@ You must never underestimate how dangerous a desperate animal is.
It is baiting you. Cunning. You can already start to feel the strength of your attacks receding.
= cbear
// TODO: Gegenangriff-Bär Bär greift aus erhöhter Position an
// TODO: Gegenangriff-Bär -- Bär greift aus erhöhter Position an
-> END
= the_show
// TODO: Die eigentliche Vorstellung Nails' Schattentheater
// TODO: Die eigentliche Vorstellung -- Nails' Schattentheater
// Übergang in silent_show (stilles Beobachten) oder interaktiv
-> silent_show
@@ -828,7 +828,7 @@ It dips its head into the water, gracefully. Kissing the ripples of the surface
-> END
= shadow_battle
// TODO: Schattenkampf Nails' wolf vs. Spieler's bear, freie Wahl
// TODO: Schattenkampf -- Nails' wolf vs. Spieler's bear, freie Wahl
-> END
= apprentice
@@ -836,7 +836,7 @@ It dips its head into the water, gracefully. Kissing the ripples of the surface
-> END
= quitter
// TODO: Hase flüchtet vom Bildschirm feige Niederlage
// TODO: Hase flüchtet vom Bildschirm -- feige Niederlage
-> END
= her_portfolio
@@ -852,5 +852,5 @@ It dips its head into the water, gracefully. Kissing the ripples of the surface
-> END
= seeulater
// TODO: Verabredung für später Spieler kommt nochmal
// TODO: Verabredung für später -- Spieler kommt nochmal
-> END
+1 -1
View File
@@ -10,7 +10,7 @@ VAR quest_mushroom_done = false
- quest_mushroom_active && mushrooms_collected >= 10:
# color whisper
Du hast {mushrooms_collected} Pilze dabei mehr als genug!
Du hast {mushrooms_collected} Pilze dabei -- mehr als genug!
* [Hier, nimm sie.]
~ quest_mushroom_done = true
# color whisper
+1 -1
View File
@@ -1 +1 @@
{"inkVersion":21,"root":[[["ev",{"VAR?":"quest_mushroom_done"},"/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Danke nochmal für die Pilze. Das Rezept ist fast fertig.","\n",{"->":"ende"},{"->":"0.4"},null]}],["ev",{"VAR?":"quest_mushroom_active"},{"VAR?":"mushrooms_collected"},10,">=","&&","/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Du hast ","ev",{"VAR?":"mushrooms_collected"},"out","/ev","^ Pilze dabei mehr als genug!","\n","ev","str","^Hier, nimm sie.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Lass mich noch ein paar behalten.","/str","/ev",{"*":".^.c-1","flg":20},{"->":"0.4"},{"c-0":["\n","ev",true,"/ev",{"VAR=":"quest_mushroom_done","re":true},"#","^color whisper","/#","^Wunderbar, vielen Dank! Das wird ein gutes Süppchen.","\n",{"->":"ende"},{"#f":5}],"c-1":["\n","#","^color whisper","/#","^Wie du willst. Komm wieder, wenn du sie loswerden möchtest.","\n",{"->":"ende"},{"#f":5}]}]}],["ev",{"VAR?":"quest_mushroom_active"},"/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Du hast schon ","ev",{"VAR?":"mushrooms_collected"},"out","/ev","^ von 10 Pilzen. Mach ruhig weiter.","\n",{"->":"ende"},{"->":"0.4"},null]}],[{"->":".^.b"},{"b":["\n","#","^color whisper","/#","^TEST1 Hallo! Ich bräuchte 10 Pilze für ein Rezept. Hättest du Lust, welche zu sammeln?","\n","ev","str","^Klar, ich helfe.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Vielleicht später.","/str","/ev",{"*":".^.c-1","flg":20},{"->":"0.4"},{"c-0":["\n","ev",true,"/ev",{"VAR=":"quest_mushroom_active","re":true},"#","^color whisper","/#","^Danke! Ich warte hier.","\n",{"->":"ende"},{"#f":5}],"c-1":["\n","#","^color whisper","/#","^Schade. Komm gerne nochmal vorbei.","\n",{"->":"ende"},{"#f":5}]}]}],"nop","\n",["done",{"#n":"g-0"}],null],"done",{"ende":[["ev","str","^Bis dann","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","#","^person_farewell","/#","end",{"#f":5}]}],null],"global decl":["ev",0,{"VAR=":"mushrooms_collected"},false,{"VAR=":"quest_mushroom_active"},false,{"VAR=":"quest_mushroom_done"},"/ev","end",null]}],"listDefs":{}}
{"inkVersion":21,"root":[[["ev",{"VAR?":"quest_mushroom_done"},"/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Danke nochmal für die Pilze. Das Rezept ist fast fertig.","\n",{"->":"ende"},{"->":"0.4"},null]}],["ev",{"VAR?":"quest_mushroom_active"},{"VAR?":"mushrooms_collected"},10,">=","&&","/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Du hast ","ev",{"VAR?":"mushrooms_collected"},"out","/ev","^ Pilze dabei -- mehr als genug!","\n","ev","str","^Hier, nimm sie.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Lass mich noch ein paar behalten.","/str","/ev",{"*":".^.c-1","flg":20},{"->":"0.4"},{"c-0":["\n","ev",true,"/ev",{"VAR=":"quest_mushroom_done","re":true},"#","^color whisper","/#","^Wunderbar, vielen Dank! Das wird ein gutes Süppchen.","\n",{"->":"ende"},{"#f":5}],"c-1":["\n","#","^color whisper","/#","^Wie du willst. Komm wieder, wenn du sie loswerden möchtest.","\n",{"->":"ende"},{"#f":5}]}]}],["ev",{"VAR?":"quest_mushroom_active"},"/ev",{"->":".^.b","c":true},{"b":["\n","#","^color whisper","/#","^Du hast schon ","ev",{"VAR?":"mushrooms_collected"},"out","/ev","^ von 10 Pilzen. Mach ruhig weiter.","\n",{"->":"ende"},{"->":"0.4"},null]}],[{"->":".^.b"},{"b":["\n","#","^color whisper","/#","^TEST1 Hallo! Ich bräuchte 10 Pilze für ein Rezept. Hättest du Lust, welche zu sammeln?","\n","ev","str","^Klar, ich helfe.","/str","/ev",{"*":".^.c-0","flg":20},"ev","str","^Vielleicht später.","/str","/ev",{"*":".^.c-1","flg":20},{"->":"0.4"},{"c-0":["\n","ev",true,"/ev",{"VAR=":"quest_mushroom_active","re":true},"#","^color whisper","/#","^Danke! Ich warte hier.","\n",{"->":"ende"},{"#f":5}],"c-1":["\n","#","^color whisper","/#","^Schade. Komm gerne nochmal vorbei.","\n",{"->":"ende"},{"#f":5}]}]}],"nop","\n",["done",{"#n":"g-0"}],null],"done",{"ende":[["ev","str","^Bis dann","/str","/ev",{"*":".^.c-0","flg":20},{"c-0":["\n","#","^person_farewell","/#","end",{"#f":5}]}],null],"global decl":["ev",0,{"VAR=":"mushrooms_collected"},false,{"VAR=":"quest_mushroom_active"},false,{"VAR=":"quest_mushroom_done"},"/ev","end",null]}],"listDefs":{}}
-5
View File
@@ -1,5 +0,0 @@
iasoidasd
jkhjkj
+25 -205
View File
@@ -6,223 +6,43 @@
"wad" ""
// brush 0
{
( 112 -16 -48 ) ( 112 -15 -48 ) ( 112 -16 -47 ) tarmac -16 -16 0 1 1
( 0 0 -48 ) ( 0 0 -47 ) ( 1 0 -48 ) tarmac 0 -16 0 1 1
( 0 -16 -48 ) ( 1 -16 -48 ) ( 0 -15 -48 ) tarmac 0 16 0 1 1
( 160 96 -32 ) ( 160 97 -32 ) ( 161 96 -32 ) tarmac 0 0 0 0.6 0.6041667
( 160 112 -32 ) ( 161 112 -32 ) ( 160 112 -31 ) tarmac 0 -16 0 1 1
( 192 96 -32 ) ( 192 96 -31 ) ( 192 97 -32 ) tarmac -16 -16 0 1 1
( -80 -16 -32 ) ( -80 -15 -32 ) ( -80 -16 -31 ) 256_arcade_carpet 96 -16 0 0.2 0.2
( -112 -16 -32 ) ( -112 -16 -31 ) ( -111 -16 -32 ) 256_arcade_carpet 80 -16 0 0.2 0.2
( -112 -16 -32 ) ( -111 -16 -32 ) ( -112 -15 -32 ) 256_arcade_carpet 80 -96 0 0.2 0.2
( 48 96 -16 ) ( 48 97 -16 ) ( 49 96 -16 ) 256_arcade_carpet 5.3333435 -57.379303 0 0.2 0.2
( 48 112 -16 ) ( 49 112 -16 ) ( 48 112 -15 ) 256_arcade_carpet 80 -16 0 0.2 0.2
( 80 96 -16 ) ( 80 96 -15 ) ( 80 97 -16 ) 256_arcade_carpet 96 -16 0 0.2 0.2
}
// brush 1
{
( 16 192 0 ) ( 16 112 -32 ) ( 16 112 -48 ) tarmac 38.4 -50.06682 26.565052 1.118034 0.9533479
( 16 112 -32 ) ( 176 112 -32 ) ( 176 112 -48 ) tarmac 0 0 0 1 1
( 16 192 0 ) ( 176 192 0 ) ( 176 112 -32 ) tarmac 0 -8.470581 0 1 1.0625
( 176 112 -48 ) ( 176 192 -16 ) ( 16 192 -16 ) tarmac 0 -8.470581 0 1 1.0625
( 176 192 -16 ) ( 176 192 0 ) ( 16 192 0 ) tarmac 0 32 0 1 1
( 176 112 -32 ) ( 176 192 0 ) ( 176 192 -16 ) tarmac 38.4 -50.06682 26.565052 1.118034 0.9533479
( -48 0 4 ) ( -48 1 4 ) ( -48 0 5 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 48 -16 -16 ) ( 47 -16 -16 ) ( 48 -16 -15 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 48 -16 -16 ) ( 48 -15 -16 ) ( 47 -16 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -48 0 80 ) ( -49 0 80 ) ( -48 1 80 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -48 0 4 ) ( -48 0 5 ) ( -49 0 4 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 48 -16 -16 ) ( 48 -16 -15 ) ( 48 -15 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
}
// brush 2
{
( 16 192 0 ) ( 16 256 -16 ) ( 16 256 0 ) tarmac 0 0 0 1 1
( 176 192 0 ) ( 16 192 -16 ) ( 16 192 0 ) tarmac 0 0 0 1 1
( 176 256 -16 ) ( 16 192 -16 ) ( 176 192 -16 ) tarmac 0 0 0 1 1
( 176 256 0 ) ( 16 192 0 ) ( 16 256 0 ) tarmac 0 0 0 1 1
( 176 256 0 ) ( 16 256 -16 ) ( 176 256 -16 ) tarmac 0 0 0 1 1
( 176 256 0 ) ( 176 192 -16 ) ( 176 192 0 ) tarmac 0 0 0 1 1
( -91.71281292110203 32 4 ) ( -91.21281292110203 32.86602540378445 4 ) ( -91.71281292110203 32 5 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -30.430780618346965 -21.856406460551035 -16 ) ( -31.296806022131403 -21.356406460551035 -16 ) ( -30.430780618346965 -21.856406460551035 -15 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -30.430780618346965 -21.856406460551035 -16 ) ( -29.930780618346965 -20.990381056766598 -16 ) ( -31.296806022131403 -21.356406460551035 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -105.56921938165303 40 80 ) ( -106.43524478543748 40.500000000000014 80 ) ( -105.06921938165303 40.86602540378446 80 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -105.56921938165303 40 4 ) ( -105.56921938165303 40 5 ) ( -106.43524478543748 40.500000000000014 4 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( -44.28718707889798 -13.856406460551028 -16 ) ( -44.28718707889798 -13.856406460551028 -15 ) ( -43.78718707889798 -12.99038105676659 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
}
// brush 3
{
( 9.372583002030481 48 -32 ) ( 10.079689783217027 48.70710678118655 -32 ) ( 9.372583002030481 48 -31 ) placeholder 31.057983 0 0 -0.08838835 0.125
( 9.372583002030481 48 -32 ) ( 9.372583002030481 48 -31 ) ( 10.079689783217027 47.29289321881346 -32 ) placeholder 149.9613 256 0 0.088388346 0.125
( 9.372583002030481 48 -32 ) ( 10.079689783217027 47.29289321881346 -32 ) ( 10.079689783217027 48.70710678118655 -32 ) placeholder 218.50967 68.54834 315 0.125 0.125
( 54.62741699796952 48 0 ) ( 55.33452377915606 48.707106781186546 0 ) ( 55.33452377915606 47.29289321881345 0 ) placeholder 218.50967 68.54834 315 0.125 0.125
( 54.62741699796952 48 -16 ) ( 54.62741699796952 48 -15 ) ( 55.33452377915606 48.707106781186546 -16 ) placeholder -31.058044 256 0 0.088388346 0.125
( 54.62741699796952 48 -16 ) ( 55.33452377915606 47.29289321881345 -16 ) ( 54.62741699796952 48 -15 ) placeholder 224.94202 0 180 -0.08838835 -0.125
}
// brush 4
{
( 32 -16 -48 ) ( 32 -15 -48 ) ( 32 -16 -47 ) tarmac -16 -16 0 1 1
( -80 0 -48 ) ( -80 0 -47 ) ( -79 0 -48 ) tarmac 80 -16 0 1 1
( -80 -16 -48 ) ( -79 -16 -48 ) ( -80 -15 -48 ) tarmac 80 16 0 1 1
( 80 96 -32 ) ( 80 97 -32 ) ( 81 96 -32 ) tarmac 5.3333435 0 0 0.6 0.6041667
( 80 112 -32 ) ( 81 112 -32 ) ( 80 112 -31 ) tarmac 80 -16 0 1 1
( 112 96 -32 ) ( 112 96 -31 ) ( 112 97 -32 ) tarmac -16 -16 0 1 1
}
// brush 5
{
( -48 -16 -48 ) ( -48 -15 -48 ) ( -48 -16 -47 ) tarmac -16 -16 0 1 1
( -160 0 -48 ) ( -160 0 -47 ) ( -159 0 -48 ) tarmac 32 -16 0 1 1
( -160 -16 -48 ) ( -159 -16 -48 ) ( -160 -15 -48 ) tarmac 32 16 0 1 1
( 0 96 -32 ) ( 0 97 -32 ) ( 1 96 -32 ) tarmac 10.666673 0 0 0.6 0.6041667
( 0 112 -32 ) ( 1 112 -32 ) ( 0 112 -31 ) tarmac 32 -16 0 1 1
( 32 96 -32 ) ( 32 96 -31 ) ( 32 97 -32 ) tarmac -16 -16 0 1 1
}
// brush 6
{
( 112 -16 96 ) ( 112 -16 95 ) ( 112 -15 96 ) tarmac 64 16 270 1 1
( 0 -16 96 ) ( 1 -16 96 ) ( 0 -16 95 ) tarmac 0 -64 0 1 -1
( 160 0 -32 ) ( 161 0 -32 ) ( 160 1 -32 ) tarmac 0 16 0 1 1
( 0 -16 80 ) ( 0 -15 80 ) ( 1 -16 80 ) tarmac 0 16 0 1 1
( 160 0 -16 ) ( 160 0 -17 ) ( 161 0 -16 ) tarmac -127.99999 -4.413788 0 0.6 -0.6041667
( 192 0 -16 ) ( 192 1 -16 ) ( 192 0 -17 ) tarmac 64 16 270 1 1
}
// brush 7
{
( 192 48 -16 ) ( 192 48 -17 ) ( 192 49 -16 ) tarmac -69.33332 -4.413788 0 0.6 -0.6041667
( 208 0 96 ) ( 208 0 95 ) ( 207 0 96 ) tarmac 64 -48 270 1 -1
( 192 48 -32 ) ( 192 49 -32 ) ( 191 48 -32 ) tarmac -16 -48 90 1 1
( 208 -112 80 ) ( 207 -112 80 ) ( 208 -111 80 ) tarmac -16 -48 90 1 1
( 192 80 -16 ) ( 191 80 -16 ) ( 192 80 -17 ) tarmac 64 -48 270 1 -1
( 208 -112 96 ) ( 208 -111 96 ) ( 208 -112 95 ) tarmac -16 -64 0 1 -1
}
// brush 8
{
( -48 -128 -48 ) ( -48 -127 -48 ) ( -48 -128 -47 ) tarmac 96 -16 0 1 1
( -80 -112 -48 ) ( -80 -112 -47 ) ( -79 -112 -48 ) tarmac 80 -16 0 1 1
( -80 -128 -48 ) ( -79 -128 -48 ) ( -80 -127 -48 ) tarmac 80 -96 0 1 1
( 80 -16 -32 ) ( 80 -15 -32 ) ( 81 -16 -32 ) tarmac 5.3333435 -57.379303 0 0.6 0.6041667
( 80 0 -32 ) ( 81 0 -32 ) ( 80 0 -31 ) tarmac 80 -16 0 1 1
( 112 -16 -32 ) ( 112 -16 -31 ) ( 112 -15 -32 ) tarmac 96 -16 0 1 1
}
// brush 9
{
( -48 -240 -48 ) ( -48 -239 -48 ) ( -48 -240 -47 ) tarmac 80 -16 0 1 1
( -80 -416 -48 ) ( -80 -416 -47 ) ( -79 -416 -48 ) tarmac 80 -16 0 1 1
( -80 -240 -48 ) ( -79 -240 -48 ) ( -80 -239 -48 ) tarmac 80 -80 0 1 1
( 80 -128 -32 ) ( 80 -127 -32 ) ( 81 -128 -32 ) tarmac 5.3333435 13.241394 0 0.6 0.6041667
( 80 -112 -32 ) ( 81 -112 -32 ) ( 80 -112 -31 ) tarmac 80 -16 0 1 1
( 208 -128 -32 ) ( 208 -128 -31 ) ( 208 -127 -32 ) tarmac 80 -16 0 1 1
}
// brush 10
{
( 85.21224617320368 -369.94112549695416 96 ) ( 85.21224617320368 -369.94112549695416 95 ) ( 85.47106521830621 -368.9751996706651 96 ) tarmac 64 -94.99124 270 1 0.9659258
( -22.971446371171922 -340.95339244547165 96 ) ( -22.005520544882856 -341.21221149057413 96 ) ( -22.971446371171922 -340.95339244547165 95 ) tarmac 23.781784 -64 0 0.9659258 -1
( 135.7177905567193 -366.90962644125017 -32 ) ( 136.68371638300835 -367.16844548635265 -32 ) ( 135.9766096018218 -365.9437006149611 -32 ) tarmac -66.05652 -47.281128 345 1 1
( -22.971446371171922 -340.95339244547165 80 ) ( -22.712627326069395 -339.9874666191826 80 ) ( -22.005520544882856 -341.21221149057413 80 ) tarmac -66.05652 -47.281128 345 1 1
( 135.7177905567193 -366.90962644125017 -16 ) ( 135.7177905567193 -366.90962644125017 -17 ) ( 136.68371638300835 -367.16844548635265 -16 ) tarmac -95.50898 -4.413788 0 0.5795555 -0.6041667
( 166.62741699796948 -375.19183588453086 -16 ) ( 166.886236043072 -374.22591005824177 -16 ) ( 166.62741699796948 -375.19183588453086 -17 ) tarmac 64 -116.427185 270 1 0.9659258
}
// brush 11
{
( 179.05073116289054 -328.8273962226556 -16 ) ( 179.05073116289054 -328.8273962226556 -17 ) ( 179.30955020799308 -327.86147039636654 -16 ) tarmac 66.04529 -4.413788 0 0.5795555 -0.6041667
( 182.08223021859456 -379.33294060617123 96 ) ( 182.08223021859456 -379.33294060617123 95 ) ( 181.1163043923055 -379.0741215610687 96 ) tarmac 64 -28.505402 270 1 -0.9659258
( 179.05073116289054 -328.8273962226556 -32 ) ( 179.30955020799308 -327.86147039636654 -32 ) ( 178.08480533660148 -328.5685771775531 -32 ) tarmac 47.281128 -114.05652 75 1 1
( 153.09449716711205 -487.5166331505468 80 ) ( 152.128571340823 -487.25781410544425 80 ) ( 153.35331621221457 -486.55070732425776 80 ) tarmac 47.281128 -114.05652 75 1 1
( 187.33294060617126 -297.9177697814054 -16 ) ( 186.3670147798822 -297.65895073630287 -16 ) ( 187.33294060617126 -297.9177697814054 -17 ) tarmac 64 -49.94133 270 1 -0.9659258
( 153.09449716711205 -487.5166331505468 96 ) ( 153.35331621221457 -486.55070732425776 96 ) ( 153.09449716711205 -487.5166331505468 95 ) tarmac 120.714355 -64 0 0.9659258 -1
}
// brush 12
{
( 35.31370849898467 -346.71213603437275 96 ) ( 35.31370849898467 -346.71213603437275 95 ) ( 34.60660171779813 -346.0050292531862 96 ) tarmac 64 -74.32501 270 1 0.70710677
( 57.941125496954285 -301.4573020384338 -16 ) ( 57.941125496954285 -301.4573020384338 -17 ) ( 58.64823227814084 -300.75019525724724 -16 ) tarmac 81.208374 -4.413788 0 0.42426407 -0.6041667
( 57.941125496954285 -301.4573020384338 -32 ) ( 58.64823227814084 -300.75019525724724 -32 ) ( 57.23401871576773 -300.75019525724724 -32 ) tarmac -51.80806 -110.13306 45 1 1
( -43.882250993908826 -425.9080955272659 80 ) ( -44.58935777509535 -425.20098874607936 80 ) ( -43.1751442127223 -425.20098874607936 80 ) tarmac -51.80806 -110.13306 45 1 1
( 80.56854249492386 -278.8298850404643 -16 ) ( 79.86143571373732 -278.12277825927777 -16 ) ( 80.56854249492386 -278.8298850404643 -17 ) tarmac 64 -122.32501 270 1 0.70710677
( -43.882250993908826 -425.9080955272659 96 ) ( -43.1751442127223 -425.20098874607936 96 ) ( -43.882250993908826 -425.9080955272659 95 ) tarmac 90.32501 -64 0 0.70710677 -1
}
// brush 13
{
( -43.88225099390854 -290.14359353944883 96 ) ( -43.88225099390854 -290.14359353944883 95 ) ( -43.17514421272199 -289.4364867582623 96 ) tarmac 64 -122.32501 270 1 0.70710677
( -123.07821048680171 -210.94763404655532 96 ) ( -122.37110370561516 -211.65474082774185 96 ) ( -123.07821048680171 -210.94763404655532 95 ) tarmac 46.058876 -64 0 0.70710677 -1
( 1.3725830020304528 -312.7710105374185 -32 ) ( 2.079689783216992 -313.478117318605 -32 ) ( 2.0796897832169776 -312.06390375623187 -32 ) tarmac -62.13307 51.80806 315 1 1
( -123.07821048680171 -210.94763404655532 80 ) ( -122.37110370561516 -210.2405272653688 80 ) ( -122.37110370561516 -211.65474082774185 80 ) tarmac -62.13307 51.80806 315 1 1
( 1.3725830020304528 -312.7710105374185 -16 ) ( 1.3725830020304528 -312.7710105374185 -17 ) ( 2.079689783216992 -313.478117318605 -16 ) tarmac 7.4314566 -4.413788 0 0.42426407 -0.6041667
( 24 -335.398427535388 -16 ) ( 24.707106781186496 -334.69132075420146 -16 ) ( 24 -335.398427535388 -17 ) tarmac 64 -74.32501 270 1 0.70710677
}
// brush 14
{
( 157.45730203843385 -150.05887450304573 -16 ) ( 157.45730203843385 -150.05887450304573 -17 ) ( 156.7501952572473 -149.35176772185918 -16 ) tarmac -19.641144 -4.413788 0 0.42426407 -0.6041667
( 134.82988504046438 -127.43145750507611 -16 ) ( 134.12277825927782 -128.13856428626266 -16 ) ( 134.82988504046438 -127.43145750507611 -17 ) tarmac 64 68.2153 270 1 -0.70710677
( 157.45730203843385 -150.05887450304573 -32 ) ( 156.7501952572473 -149.35176772185918 -32 ) ( 156.7501952572473 -150.76598128423228 -32 ) tarmac 121.44678 10.768529 135 1 1
( 281.9080955272659 -251.88225099390885 80 ) ( 281.20098874607936 -252.58935777509538 80 ) ( 281.20098874607936 -251.17514421272233 80 ) tarmac 121.44678 10.768529 135 1 1
( 281.9080955272659 -251.88225099390885 96 ) ( 281.20098874607936 -251.17514421272233 96 ) ( 281.9080955272659 -251.88225099390885 95 ) tarmac 14.678253 -64 180 0.70710677 1
( 202.71213603437275 -172.68629150101532 96 ) ( 202.71213603437275 -172.68629150101532 95 ) ( 202.0050292531862 -173.39339828220187 96 ) tarmac 64 20.215332 270 1 -0.70710677
}
// brush 15
{
( 128.20246804249456 -210.78775382679612 96 ) ( 128.20246804249456 -210.78775382679612 95 ) ( 127.94364899739205 -209.82182800050708 96 ) tarmac 64 69.77646 270 1 0.9659258
( 170.42580298272964 -182.90962644125017 -16 ) ( 170.42580298272964 -182.90962644125017 -17 ) ( 171.39172880901867 -182.6508073961476 -16 ) tarmac -27.396317 -4.413788 0 0.5795555 -0.6041667
( 170.42580298272964 -182.90962644125017 -32 ) ( 171.39172880901867 -182.6508073961476 -32 ) ( 170.16698393762704 -181.94370061496107 -32 ) tarmac -85.27817 -76.786575 15.000003 1 1
( 20.018775498118814 -239.77548687827812 80 ) ( 19.75995645301633 -238.80956105198902 80 ) ( 20.98470132440788 -239.51666783317557 80 ) tarmac -85.27817 -76.786575 15.000003 1 1
( 20.018775498118814 -239.77548687827812 96 ) ( 20.98470132440788 -239.51666783317557 96 ) ( 20.018775498118814 -239.77548687827812 95 ) tarmac -20.72496 -64 0 0.9659258 -1
( 201.3354294239798 -174.6274169979695 -16 ) ( 201.07661037887726 -173.66149117168047 -16 ) ( 201.3354294239798 -174.6274169979695 -17 ) tarmac 64 91.21239 270 1 0.9659258
}
// brush 16
{
( -16 192 0 ) ( -16 256 -16 ) ( -16 256 0 ) tarmac 0 0 0 1 1
( 16 192 0 ) ( -144 192 -16 ) ( -144 192 0 ) tarmac 32 0 0 1 1
( 16 256 -16 ) ( -144 192 -16 ) ( 16 192 -16 ) tarmac 32 0 0 1 1
( 16 256 4 ) ( -144 192 4 ) ( -144 256 4 ) tarmac 32 0 0 1 1
( 16 256 0 ) ( -144 256 -16 ) ( 16 256 -16 ) tarmac 32 0 0 1 1
( 16 256 0 ) ( 16 192 -16 ) ( 16 192 0 ) tarmac 0 0 0 1 1
}
// brush 17
{
( -48 192 0 ) ( -48 256 -16 ) ( -48 256 0 ) tarmac 0 0 0 1 1
( -16 192 0 ) ( -176 192 -16 ) ( -176 192 0 ) tarmac 64 0 0 1 1
( -16 256 -16 ) ( -176 192 -16 ) ( -16 192 -16 ) tarmac 64 0 0 1 1
( -16 256 12 ) ( -176 192 12 ) ( -176 256 12 ) tarmac 64 0 0 1 1
( -16 256 0 ) ( -176 256 -16 ) ( -16 256 -16 ) tarmac 64 0 0 1 1
( -16 256 0 ) ( -16 192 -16 ) ( -16 192 0 ) tarmac 0 0 0 1 1
}
// brush 18
{
( -80 192 0 ) ( -80 256 -16 ) ( -80 256 0 ) tarmac 0 0 0 1 1
( -48 192 0 ) ( -208 192 -16 ) ( -208 192 0 ) tarmac 96 0 0 1 1
( -48 256 -16 ) ( -208 192 -16 ) ( -48 192 -16 ) tarmac 96 0 0 1 1
( -48 256 24 ) ( -208 192 24 ) ( -208 256 24 ) tarmac 96 0 0 1 1
( -48 256 0 ) ( -208 256 -16 ) ( -48 256 -16 ) tarmac 96 0 0 1 1
( -48 256 0 ) ( -48 192 -16 ) ( -48 192 0 ) tarmac 0 0 0 1 1
}
// brush 19
{
( -112 192 0 ) ( -112 256 -16 ) ( -112 256 0 ) tarmac 0 0 0 1 1
( -80 192 0 ) ( -240 192 -16 ) ( -240 192 0 ) tarmac 0 0 0 1 1
( -80 256 -16 ) ( -240 192 -16 ) ( -80 192 -16 ) tarmac 0 0 0 1 1
( -80 256 40 ) ( -240 192 40 ) ( -240 256 40 ) tarmac 0 0 0 1 1
( -80 256 0 ) ( -240 256 -16 ) ( -80 256 -16 ) tarmac 0 0 0 1 1
( -80 256 0 ) ( -80 192 -16 ) ( -80 192 0 ) tarmac 0 0 0 1 1
}
// brush 20
{
( -144 192 0 ) ( -144 256 -16 ) ( -144 256 0 ) tarmac 0 0 0 1 1
( -112 192 0 ) ( -272 192 -16 ) ( -272 192 0 ) tarmac 32 0 0 1 1
( -112 256 -16 ) ( -272 192 -16 ) ( -112 192 -16 ) tarmac 32 0 0 1 1
( -112 256 60 ) ( -272 192 60 ) ( -272 256 60 ) tarmac 32 0 0 1 1
( -112 256 0 ) ( -272 256 -16 ) ( -112 256 -16 ) tarmac 32 0 0 1 1
( -112 256 0 ) ( -112 192 -16 ) ( -112 192 0 ) tarmac 0 0 0 1 1
}
// brush 21
{
( -176 192 0 ) ( -176 256 -16 ) ( -176 256 0 ) tarmac 0 0 0 1 1
( -144 192 0 ) ( -304 192 -16 ) ( -304 192 0 ) tarmac 64 0 0 1 1
( -144 256 -16 ) ( -304 192 -16 ) ( -144 192 -16 ) tarmac 64 0 0 1 1
( -144 256 84 ) ( -304 192 84 ) ( -304 256 84 ) tarmac 64 0 0 1 1
( -144 256 0 ) ( -304 256 -16 ) ( -144 256 -16 ) tarmac 64 0 0 1 1
( -144 256 0 ) ( -144 192 -16 ) ( -144 192 0 ) tarmac 0 0 0 1 1
}
// brush 22
{
( 16 352 64 ) ( 16 256 0 ) ( 16 256 -16 ) tarmac 0 0 0 1 1
( 16 256 0 ) ( 176 256 0 ) ( 176 256 -16 ) tarmac 0 0 0 1 1
( 16 352 64 ) ( 176 352 64 ) ( 176 256 0 ) tarmac 0 0 0 1 1
( 176 256 -16 ) ( 176 352 48 ) ( 16 352 48 ) tarmac 0 0 0 1 1
( 176 352 48 ) ( 176 352 64 ) ( 16 352 64 ) tarmac 0 0 0 1 1
( 176 256 0 ) ( 176 352 64 ) ( 176 352 48 ) tarmac 0 0 0 1 1
}
// brush 23
{
( 16 352 64 ) ( 16 464 48 ) ( 16 464 64 ) tarmac 0 0 0 1 1
( 176 352 64 ) ( 16 352 48 ) ( 16 352 64 ) tarmac 0 0 0 1 1
( 176 464 48 ) ( 16 352 48 ) ( 176 352 48 ) tarmac 0 0 0 1 1
( 176 464 64 ) ( 16 352 64 ) ( 16 464 64 ) tarmac 0 0 0 1 1
( 176 464 64 ) ( 16 464 48 ) ( 176 464 48 ) tarmac 0 0 0 1 1
( 176 464 64 ) ( 176 352 48 ) ( 176 352 64 ) tarmac 0 0 0 1 1
( 36.28718707889797 0 4 ) ( 35.787187078897965 0.866025403784441 4 ) ( 36.28718707889797 0 5 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 22.430780618346965 -8 4 ) ( 22.430780618346965 -8 5 ) ( 21.56475521456251 -8.499999999999979 4 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 113.56921938165306 26.14359353944895 -16 ) ( 113.06921938165306 27.0096189432334 -16 ) ( 112.70319397786861 25.643593539448965 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 22.430780618346965 -8 80 ) ( 21.56475521456251 -8.499999999999979 80 ) ( 21.930780618346944 -7.1339745962155305 80 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 113.56921938165306 26.14359353944895 -16 ) ( 112.70319397786861 25.643593539448965 -16 ) ( 113.56921938165306 26.14359353944895 -15 ) 256_cement_dirty_rough_wall 0 0 0 1 1
( 99.71281292110204 18.143593539448965 -16 ) ( 99.71281292110204 18.143593539448965 -15 ) ( 99.21281292110204 19.009618943233413 -16 ) 256_cement_dirty_rough_wall 0 0 0 1 1
}
}
// entity 1
{
"classname" "info_player_start"
"origin" "130 404 104"
"origin" "2 52 8"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

+16 -1
View File
@@ -1,3 +1,18 @@
Texturen:
# Assets
## Texturen
https://www.manytextures.com/
https://opengameart.org/content/arcade-carpet-textures
# Tutorials
## Blender
Blender UI Base Setup + Tips
https://www.youtube.com/watch?v=sZeGW0otiJI
Rigging in PS1 Look:
https://www.youtube.com/watch?v=puwu9hZmQYI
+1 -1
View File
@@ -29,7 +29,7 @@ fn prompt_for(mode: &Mode) -> &'static str {
Mode::Dialog(d) if !d.choices.is_empty() => " wahl> ",
Mode::Dialog(_) => " [Enter] ",
Mode::Menu => "menü> ",
Mode::Play => "spiel> ",
Mode::FirstPerson => "spiel> ",
Mode::Free => "> ",
}
}
+1 -1
View File
@@ -339,7 +339,7 @@ impl App {
// die Maus (relativer Blick); Menü/Dialog geben sie frei fürs UI. So
// gibt es keine parallele Lock-Logik.
let fly = matches!(self.session.mode, Mode::Free);
let play = matches!(self.session.mode, Mode::Play);
let play = matches!(self.session.mode, Mode::FirstPerson);
let grab = fly || play;
if grab != self.input.grabbed { self.set_grab(grab); }
+70 -26
View File
@@ -136,13 +136,18 @@ impl ScenePass {
}],
});
// Nearest-Sampler: harte Texel, kein Filtering — PS1.
// mag=Nearest hält nah dran die harten Texel (der knackige Look);
// min/mipmap=Linear glätten nur die Verkleinerung in der Ferne und
// blenden weich zwischen den Mip-Ebenen (kein Mip-Popping). Killt das
// Texel-Flimmern hochauflösender Texturen auf der kleinen internen
// Auflösung. Mipmaps werden in upload_texture per Box-Filter erzeugt.
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("scene nearest"),
label: Some("scene"),
address_mode_u: wgpu::AddressMode::Repeat,
address_mode_v: wgpu::AddressMode::Repeat,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::MipmapFilterMode::Linear,
..Default::default()
});
let tex_layout = pipeline.get_bind_group_layout(1);
@@ -176,7 +181,8 @@ impl ScenePass {
}
/// Ein RGBA8-`Image` als GPU-Textur hochladen und die zugehörige
/// Bind-Group (Textur + Sampler, group 1) bauen.
/// Bind-Group (Textur + Sampler, group 1) bauen. Erzeugt die volle
/// Mipchain (bis 1×1) per Box-Filter auf der CPU und lädt jede Ebene hoch.
fn upload_texture(
device: &wgpu::Device,
queue: &wgpu::Queue,
@@ -184,15 +190,16 @@ fn upload_texture(
sampler: &wgpu::Sampler,
img: &Image,
) -> wgpu::BindGroup {
let size = wgpu::Extent3d {
width: img.width,
height: img.height,
depth_or_array_layers: 1,
};
// floor(log2(max(w,h))) + 1 = volle Kette bis zur 1×1-Ebene.
let mip_level_count = 32 - img.width.max(img.height).leading_zeros();
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("scene texture"),
size,
mip_level_count: 1,
size: wgpu::Extent3d {
width: img.width,
height: img.height,
depth_or_array_layers: 1,
},
mip_level_count,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
// Nicht-sRGB: die Quantisierung im Shader erwartet rohe Werte.
@@ -200,21 +207,32 @@ fn upload_texture(
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
queue.write_texture(
wgpu::TexelCopyTextureInfo {
texture: &texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&img.rgba,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(img.width * 4),
rows_per_image: Some(img.height),
},
size,
);
// Ebene 0 ist das Originalbild; jede weitere wird aus der vorherigen
// halbiert. `level` trägt die aktuell hochzuladenden Pixel.
let mut level = img.rgba.clone();
let (mut w, mut h) = (img.width, img.height);
for mip in 0..mip_level_count {
queue.write_texture(
wgpu::TexelCopyTextureInfo {
texture: &texture,
mip_level: mip,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&level,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(w * 4),
rows_per_image: Some(h),
},
wgpu::Extent3d { width: w, height: h, depth_or_array_layers: 1 },
);
if mip + 1 < mip_level_count {
(level, w, h) = downsample(&level, w, h);
}
}
let view = texture.create_view(&Default::default());
device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("scene texture"),
@@ -225,3 +243,29 @@ fn upload_texture(
],
})
}
/// Eine RGBA8-Mip-Ebene per 2×2-Box-Filter auf die nächstkleinere halbieren.
/// Gibt die neuen Pixel samt Maßen zurück. Ungerade Maße werden via `(d+1)/2`
/// aufgerundet (sonst ginge die letzte Spalte/Zeile verloren); die fehlende
/// Quell-Spalte/-Zeile wird auf den Rand geklemmt, statt den Mittelwert zu
/// verfälschen. Mittelung im (gamma-kodierten) Speicherraum — für den
/// stilisierten Look unkritisch.
fn downsample(src: &[u8], w: u32, h: u32) -> (Vec<u8>, u32, u32) {
let (nw, nh) = ((w + 1) / 2, (h + 1) / 2);
let mut dst = vec![0u8; (nw * nh * 4) as usize];
for y in 0..nh {
for x in 0..nw {
let (x0, y0) = (2 * x, 2 * y);
let x1 = (x0 + 1).min(w - 1);
let y1 = (y0 + 1).min(h - 1);
let at = |px: u32, py: u32| ((py * w + px) * 4) as usize;
let samples = [at(x0, y0), at(x1, y0), at(x0, y1), at(x1, y1)];
let di = ((y * nw + x) * 4) as usize;
for c in 0..4 {
let sum: u32 = samples.iter().map(|&s| src[s + c] as u32).sum();
dst[di + c] = ((sum + 2) / 4) as u8;
}
}
}
(dst, nw, nh)
}
+7 -1
View File
@@ -53,9 +53,15 @@ fn bayer4(px: vec2u) -> f32 {
return f32(m[(px.y % 4u) * 4u + (px.x % 4u)]);
}
// LOD-Bias für die Mip-Auswahl: negativ = schärfer (greift einen höher
// aufgelösten Mip, als die UV-Ableitungen verlangen), positiv = weicher.
// 0 = neutral. Bei -1.0 verdoppelt sich praktisch die Texelrate (mehr
// Schärfe, etwas mehr Flimmern); -0.5 ist ein sanfter Mittelweg.
const MIP_BIAS: f32 = -1.0;
@fragment
fn fs_main(in: VsOut) -> @location(0) vec4f {
let texel = textureSample(tex, smp, in.uv);
let texel = textureSampleBias(tex, smp, in.uv, MIP_BIAS);
if texel.a < 0.5 { discard; } // 1-Bit-Alpha (Cutouts), noch ungenutzt
// RGB555: 31 Stufen pro Kanal. Bayer-Schwelle vor dem Abrunden →
+1 -1
View File
@@ -228,7 +228,7 @@ pub(crate) fn layout(internal: [f32; 2], fonts: &Fonts, session: &Session, cur:
match &session.mode {
// Spiel und Flycam: nur HUD/Cursor, kein Panel (beide laufen
// ohnehin gefangen — dieser Zweig greift nur im Übergang).
Mode::Play | Mode::Free => {}
Mode::FirstPerson | Mode::Free => {}
Mode::Menu => menu(&mut ui, f, internal, cur.pos, &mut hover),
Mode::Dialog(d) => dialog(&mut ui, f, internal, d, cur.pos, &mut hover),
}
+12 -46
View File
@@ -1,22 +1,3 @@
//! Session: der geteilte Anwendungszustand über allen Frontends.
//!
//! Es existiert genau eine `Session` pro Lauf. CLI und Fenster steuern
//! dieselbe — das Fenster besitzt sie, die Terminal-Eingabe schickt nur
//! Befehlszeilen hinein. Dadurch kann es keinen Mismatch geben: ein
//! `Game`-Zustand, ein `Mode`, beide Frontends stellen ihn nur dar.
//!
//! Schicht: `engine ← session ← { cli, render }`. Die Session kennt kein
//! Frontend — `exec` nimmt eine Befehlszeile und *gibt* Ausgabezeilen
//! zurück (statt zu drucken), damit jedes Frontend sie frei darstellt
//! (Terminal jetzt, In-Fenster-Konsole später).
//!
//! Die Session ist auch der alleinige Besitzer der **Lauf-Simulation**:
//! `Player` und `CollisionWorld`. Sie hat zwei Eingabe-Tore — `exec` für
//! diskrete Befehle/Dialog und `tick` für die kontinuierliche Physik pro
//! Frame. Die Frontends sammeln nur Eingaben und stellen den Zustand dar;
//! die Flycam dagegen ist reine Frontend-Sicht (kein Sim-Zustand) und bleibt
//! im `render`-Modul.
use crate::engine::collision::CollisionWorld;
use crate::engine::game::{Action, Game, ModeTarget};
use crate::engine::ink::StoryState;
@@ -27,28 +8,13 @@ use crate::engine::{kv, signals, story_ctrl};
/// Maus-Empfindlichkeit der Spieler-Sicht (Radiant/Pixel).
const LOOK_SENS: f32 = 0.0025;
/// Was die Frontends gerade darstellen sollen. Geteilt, damit CLI und GUI
/// nie uneins sind, ob ein Dialog läuft.
pub enum Mode {
/// First-Person-Spiel — der Player bewegt sich mit Physik durch die Welt
/// (siehe engine::player). Der Renderer leitet seine View aus dem Player
/// ab. Das ist der eigentliche Spielmodus.
Play,
/// Noclip-Debug-Flycam — frei schwebende Kamera ohne Physik. Per
/// `noclip`-Befehl gegen `Play` getauscht.
FirstPerson,
Free,
/// Menü offen — wie der Dialog pausiert das Fenster die Welt und gibt die
/// Maus frei; Eingaben sind weiter Engine-Befehle (das Menü ist nur eine
/// andere Darstellung). Per `menu`-Befehl getoggelt; „Fortsetzen" führt
/// ins Spiel (`Play`).
Menu,
/// Ein Dialog läuft — das Fenster pausiert die Welt und zeigt Panels;
/// Eingaben treiben den Dialog statt Befehle.
Dialog(Dialog),
}
/// Aktueller Dialogschritt, frontend-neutral. `choices` leer = reiner Text,
/// der auf „weiter" (Leerzeile/Enter) wartet.
pub struct Dialog {
// Wird vom Panel-Renderer der UI-Phase gelesen; bis dahin läuft der
// Dialogtext über die Konsolen-Ausgabe (siehe `step`).
@@ -115,7 +81,7 @@ impl Session {
/// `exec`. Nur im Spielmodus bewegt sich der Spieler; Menü/Dialog/Flycam
/// pausieren die Sim (die Flycam ist reine Frontend-Sicht).
pub fn tick(&mut self, input: &FrameInput, dt: f32) {
if matches!(self.mode, Mode::Play) {
if matches!(self.mode, Mode::FirstPerson) {
self.player.look(input.look_dx, input.look_dy, LOOK_SENS);
self.player.step(&self.collision, input.fwd, input.right, input.jump, dt);
}
@@ -135,7 +101,7 @@ impl Session {
pub fn exec(&mut self, line: &str) -> ExecResult {
match self.mode {
Mode::Dialog(_) => self.dialog_input(line),
Mode::Play | Mode::Free | Mode::Menu => self.command(line),
Mode::FirstPerson | Mode::Free | Mode::Menu => self.command(line),
}
}
@@ -159,7 +125,7 @@ impl Session {
// Debug: zwischen First-Person (Play) und freier Flycam (Free)
// umschalten.
let t = match self.mode {
Mode::Play => ModeTarget::Free,
Mode::FirstPerson => ModeTarget::Free,
_ => ModeTarget::Play,
};
self.set_mode(t);
@@ -219,7 +185,7 @@ impl Session {
// geladen haben, während die alte auf End lief (mode → Play). Falls
// das passiert ist, sofort den ersten Schritt der neuen Story ziehen
// statt den Spieler im Play-Modus hängen zu lassen.
if self.game.story.is_some() && matches!(self.mode, Mode::Play) {
if self.game.story.is_some() && matches!(self.mode, Mode::FirstPerson) {
out.extend(self.step(None));
}
ExecResult::lines(out)
@@ -252,7 +218,7 @@ impl Session {
let mut out = self.drain_actions();
match state {
None | Some(StoryState::End) => {
self.mode = Mode::Play;
self.mode = Mode::FirstPerson;
}
Some(StoryState::Text(text)) => {
out.push(text.clone());
@@ -293,7 +259,7 @@ impl Session {
/// entsteht ausschließlich in `step` aus dem Story-Ablauf.)
fn set_mode(&mut self, t: ModeTarget) {
self.mode = match t {
ModeTarget::Play => Mode::Play,
ModeTarget::Play => Mode::FirstPerson,
ModeTarget::Free => Mode::Free,
ModeTarget::Menu => Mode::Menu,
};
@@ -376,7 +342,7 @@ mod tests {
s.exec("menu");
assert!(matches!(s.mode, Mode::Menu));
s.exec("menu"); // „Fortsetzen" → ins Spiel
assert!(matches!(s.mode, Mode::Play));
assert!(matches!(s.mode, Mode::FirstPerson));
s.exec("menu"); // aus dem Spiel wieder ins Menü
assert!(matches!(s.mode, Mode::Menu));
// Im Menü laufen Engine-Befehle weiter (gleiche Route wie Play/Free).
@@ -388,7 +354,7 @@ mod tests {
fn mode_command_sets_mode_directly() {
let mut s = empty_session();
s.exec("mode play");
assert!(matches!(s.mode, Mode::Play));
assert!(matches!(s.mode, Mode::FirstPerson));
s.exec("mode free");
assert!(matches!(s.mode, Mode::Free));
s.exec("mode menu");
@@ -405,17 +371,17 @@ mod tests {
s.mode = Mode::Free;
// `mode`-Verb direkt als Action (Ink-Tag-/signals.toml-Pfad).
s.exec("signal mode play");
assert!(matches!(s.mode, Mode::Play));
assert!(matches!(s.mode, Mode::FirstPerson));
}
#[test]
fn noclip_toggles_play_and_free() {
let mut s = empty_session();
s.mode = Mode::Play;
s.mode = Mode::FirstPerson;
s.exec("noclip");
assert!(matches!(s.mode, Mode::Free));
s.exec("noclip");
assert!(matches!(s.mode, Mode::Play));
assert!(matches!(s.mode, Mode::FirstPerson));
}
#[test]
+25
View File
@@ -54,12 +54,37 @@ if [ ! -d "$ink_dir" ]; then
exit 1
fi
# Prüft eine .ink-Datei auf Zeichen außerhalb von CP437 und gibt sie aus.
# Exit-Code 1 wenn Treffer gefunden, sonst 0.
check_cp437() {
python3 - "$1" <<'PYEOF'
import sys
path = sys.argv[1]
cp437 = set(bytes(range(256)).decode('cp437', errors='replace'))
hits = []
with open(path, encoding='utf-8') as f:
for lineno, line in enumerate(f, 1):
for ch in line:
if ord(ch) > 127 and ch not in cp437:
hits.append(f' Z.{lineno}: U+{ord(ch):04X} {repr(ch)}')
for h in hits:
print(h)
sys.exit(1 if hits else 0)
PYEOF
}
built=0 skipped=0 failed=0
shopt -s nullglob
for src in "$ink_dir"/*.ink; do
out="${src%.ink}.ink.json"
name="$(basename "$src")"
# CP437-Warnung: läuft immer, unabhängig vom Build-Status.
if ! cp437_warn="$(check_cp437 "$src")"; then
printf ' WARNUNG %s -- Nicht-CP437-Zeichen:\n' "$name"
printf '%s\n' "$cp437_warn"
fi
# Inkrementell: überspringen, wenn Ausgabe existiert und neuer ist.
if [ "$force" -eq 0 ] && [ -f "$out" ] && [ "$out" -nt "$src" ]; then
printf ' aktuell %s\n' "$name"