almost final
This commit is contained in:
1 parent
3ab9dcd48e
commit
4aeded5f43
2 files changed
+152
-29
No files matched your search
+143
-29
@@ -2,6 +2,8 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
init python:
|
init python:
|
||||||
|
import random
|
||||||
|
|
||||||
renpy.music.register_channel("ambient_generator", "ambient", loop=True)
|
renpy.music.register_channel("ambient_generator", "ambient", loop=True)
|
||||||
renpy.music.register_channel("ambient_server", "ambient", loop=True)
|
renpy.music.register_channel("ambient_server", "ambient", loop=True)
|
||||||
renpy.music.register_channel("ambient_wind", "ambient", loop=True)
|
renpy.music.register_channel("ambient_wind", "ambient", loop=True)
|
||||||
@@ -19,6 +21,12 @@ init python:
|
|||||||
thoughts_processed = False
|
thoughts_processed = False
|
||||||
journal = []
|
journal = []
|
||||||
|
|
||||||
|
date_input = ""
|
||||||
|
|
||||||
|
current_input = [0, 0, 0, 0, 0]
|
||||||
|
arget_code = []
|
||||||
|
time_left = 15
|
||||||
|
|
||||||
puzzle_parts = [False, False, False, False]
|
puzzle_parts = [False, False, False, False]
|
||||||
puzzle_complete = False
|
puzzle_complete = False
|
||||||
|
|
||||||
@@ -34,6 +42,9 @@ init python:
|
|||||||
battery -= amount
|
battery -= amount
|
||||||
if battery < 0: battery = 0
|
if battery < 0: battery = 0
|
||||||
|
|
||||||
|
def generate_code():
|
||||||
|
return [random.randint(0, 9) for _ in range(5)]
|
||||||
|
|
||||||
screen game_ui():
|
screen game_ui():
|
||||||
if game_started:
|
if game_started:
|
||||||
frame:
|
frame:
|
||||||
@@ -41,6 +52,8 @@ screen game_ui():
|
|||||||
vbox:
|
vbox:
|
||||||
text "ЭНЕРГИЯ: [battery]%" size 40
|
text "ЭНЕРГИЯ: [battery]%" size 40
|
||||||
text "ФРАГМЕНТЫ: [fragments]/3" size 40
|
text "ФРАГМЕНТЫ: [fragments]/3" size 40
|
||||||
|
|
||||||
|
screen journal_button():
|
||||||
textbutton "ЖУРНАЛ" action Show("journal") align (0.98, 0.98)
|
textbutton "ЖУРНАЛ" action Show("journal") align (0.98, 0.98)
|
||||||
|
|
||||||
screen journal():
|
screen journal():
|
||||||
@@ -94,28 +107,112 @@ screen corridor_puzzle_screen():
|
|||||||
ypadding 20
|
ypadding 20
|
||||||
background "#555555"
|
background "#555555"
|
||||||
|
|
||||||
screen terminal_rhythm_screen():
|
screen terminal_code_game():
|
||||||
|
modal True
|
||||||
|
timer 1.0 repeat True action If(time_left > 0, SetVariable("time_left", time_left - 1), Return(False))
|
||||||
|
|
||||||
|
frame:
|
||||||
|
align (0.5, 0.5)
|
||||||
|
padding (30, 30)
|
||||||
|
xsize 650 ysize 450
|
||||||
|
background "#262626"
|
||||||
|
|
||||||
|
vbox:
|
||||||
|
spacing 20
|
||||||
|
text "ПОДБОР ЧАСТОТЫ" xalign 0.5 size 35
|
||||||
|
|
||||||
|
hbox:
|
||||||
|
spacing 40
|
||||||
|
xalign 0.5
|
||||||
|
for i in range(5):
|
||||||
|
vbox:
|
||||||
|
spacing 5
|
||||||
|
xalign 0.5
|
||||||
|
|
||||||
|
textbutton "/\\":
|
||||||
|
xsize 80 ysize 60
|
||||||
|
background "#494949ec"
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0
|
||||||
|
action SetDict(current_input, i, (current_input[i] + 1) % 10)
|
||||||
|
|
||||||
|
text str(current_input[i]):
|
||||||
|
xalign 0.5
|
||||||
|
color ("#3b7d3b" if current_input[i] == target_code[i] else "#9b0e0e")
|
||||||
|
size 60
|
||||||
|
|
||||||
|
textbutton "\\/":
|
||||||
|
xsize 80 ysize 60
|
||||||
|
background "#494949ec"
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0
|
||||||
|
action SetDict(current_input, i, (current_input[i] - 1) % 10)
|
||||||
|
|
||||||
|
textbutton "ВВОД":
|
||||||
|
action Return(current_input == target_code)
|
||||||
|
xalign 0.5
|
||||||
|
yalign 1.0
|
||||||
|
xpadding 60
|
||||||
|
ypadding 10
|
||||||
|
background "#555555"
|
||||||
|
|
||||||
|
null height 60
|
||||||
|
text "Осталось: [time_left] сек." xalign 0.5 size 50 color "#ffffff"
|
||||||
|
|
||||||
|
screen keypad_screen():
|
||||||
modal True
|
modal True
|
||||||
frame:
|
frame:
|
||||||
align (0.5, 0.5)
|
align (0.5, 0.5)
|
||||||
xsize 600 ysize 300
|
xsize 400 ysize 500
|
||||||
background "#333333"
|
background "#262626d3"
|
||||||
|
|
||||||
hbox:
|
vbox:
|
||||||
|
spacing 10
|
||||||
align (0.5, 0.5)
|
align (0.5, 0.5)
|
||||||
spacing 20
|
|
||||||
for i in range(3):
|
|
||||||
button:
|
|
||||||
action [
|
|
||||||
Function(player_input.append, i),
|
|
||||||
Function(renpy.restart_interaction)
|
|
||||||
]
|
|
||||||
xsize 150 ysize 150
|
|
||||||
background ("#aaaaaa" if i in player_input else "#1a1a1a")
|
|
||||||
text "[i]" align (0.5, 0.5)
|
|
||||||
|
|
||||||
if len(player_input) >= 3:
|
null height 60
|
||||||
timer 0.3 action Return(player_input == signal_sequence)
|
text "[date_input]" size 50 xalign 0.5 yalign 0.5 min_width 350
|
||||||
|
|
||||||
|
grid 3 4:
|
||||||
|
spacing 15
|
||||||
|
xalign 0.5
|
||||||
|
|
||||||
|
for i in range(1, 10):
|
||||||
|
textbutton str(i):
|
||||||
|
action If(len(date_input) < 10, SetVariable("date_input", date_input + str(i)), None)
|
||||||
|
background "#494949ec"
|
||||||
|
xsize 80 ysize 80
|
||||||
|
xalign 0.5
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0.5
|
||||||
|
|
||||||
|
textbutton ".":
|
||||||
|
action If(len(date_input) < 10, SetVariable("date_input", date_input + "."), None)
|
||||||
|
background "#363636ec"
|
||||||
|
xsize 80 ysize 80
|
||||||
|
xalign 0.5
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0.5
|
||||||
|
textbutton "0":
|
||||||
|
action If(len(date_input) < 10, SetVariable("date_input", date_input + "0"), None)
|
||||||
|
background "#494949ec"
|
||||||
|
xsize 80 ysize 80
|
||||||
|
xalign 0.5
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0.5
|
||||||
|
textbutton "<-":
|
||||||
|
action SetVariable("date_input", date_input[:-1])
|
||||||
|
background "#363636ec"
|
||||||
|
xsize 80 ysize 80
|
||||||
|
xalign 0.5
|
||||||
|
text_xalign 0.5
|
||||||
|
text_yalign 0.5
|
||||||
|
|
||||||
|
null height 20
|
||||||
|
textbutton "ВВОД" action Return(date_input):
|
||||||
|
xalign 0.5
|
||||||
|
background "#555555d2"
|
||||||
|
xpadding 40
|
||||||
|
|
||||||
transform slow_zoom_pan:
|
transform slow_zoom_pan:
|
||||||
zoom 1.0
|
zoom 1.0
|
||||||
@@ -131,6 +228,9 @@ transform shake_effect(rate=0.090):
|
|||||||
linear rate xoffset -2 yoffset -6
|
linear rate xoffset -2 yoffset -6
|
||||||
linear rate xoffset +0 yoffset +0
|
linear rate xoffset +0 yoffset +0
|
||||||
|
|
||||||
|
transform rotate_180:
|
||||||
|
rotate 180
|
||||||
|
|
||||||
define chapter_title = Character(None,
|
define chapter_title = Character(None,
|
||||||
what_xalign=0.5,
|
what_xalign=0.5,
|
||||||
what_yalign=0.4,
|
what_yalign=0.4,
|
||||||
@@ -257,28 +357,40 @@ label main_loop:
|
|||||||
jump ending_silence
|
jump ending_silence
|
||||||
|
|
||||||
show screen game_ui
|
show screen game_ui
|
||||||
|
show screen journal_button
|
||||||
|
|
||||||
"Станция ждет. Сегодня всё закончится. Что я буду делать, пока ещё есть свет?"
|
"Станция ждет. Сегодня всё закончится. Что я буду делать, пока ещё есть свет?"
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
"Осмотреть рабочий стол (Комната)" if not visited_locations["room"]:
|
"Осмотреть рабочий стол (Комната)" if not visited_locations["room"]:
|
||||||
$ use_battery(5)
|
$ use_battery(26)
|
||||||
$ visited_locations["room"] = True
|
$ visited_locations["room"] = True
|
||||||
|
hide screen journal_button
|
||||||
jump qte_date_input
|
jump qte_date_input
|
||||||
|
|
||||||
"Идти в коридор" if not visited_locations["corridor"]:
|
"Идти в коридор" if not visited_locations["corridor"]:
|
||||||
$ use_battery(5)
|
$ use_battery(29)
|
||||||
$ visited_locations["corridor"] = True
|
$ visited_locations["corridor"] = True
|
||||||
|
hide screen journal_button
|
||||||
jump qte_corridor_puzzle
|
jump qte_corridor_puzzle
|
||||||
|
|
||||||
"Подойти к терминалу" if not visited_locations["terminal"]:
|
"Подойти к терминалу" if not visited_locations["terminal"]:
|
||||||
$ use_battery(5)
|
$ use_battery(34)
|
||||||
$ visited_locations["terminal"] = True
|
$ visited_locations["terminal"] = True
|
||||||
jump qte_terminal_rhythm
|
hide screen journal_button
|
||||||
|
jump qte_terminal_hack
|
||||||
|
|
||||||
"Идти в серверную" if visited_locations["room"] and visited_locations["corridor"] and visited_locations["terminal"]:
|
"Идти в серверную" if visited_locations["room"] and visited_locations["corridor"] and visited_locations["terminal"]:
|
||||||
|
hide screen journal_button
|
||||||
jump phase_3_culmination
|
jump phase_3_culmination
|
||||||
|
|
||||||
|
"Сдаться":
|
||||||
|
hide screen journal_button
|
||||||
|
"Я..."
|
||||||
|
"Просто закрою глаза."
|
||||||
|
$ use_battery(battery)
|
||||||
|
jump main_loop
|
||||||
|
|
||||||
label qte_date_input:
|
label qte_date_input:
|
||||||
play footsteps "audio/footsteps.ogg"
|
play footsteps "audio/footsteps.ogg"
|
||||||
pause 1.0
|
pause 1.0
|
||||||
@@ -295,9 +407,8 @@ label qte_date_input:
|
|||||||
"Ровно три года с того дня, когда всё пошло прахом. Три года тишины, которую я сам на себя наложил."
|
"Ровно три года с того дня, когда всё пошло прахом. Три года тишины, которую я сам на себя наложил."
|
||||||
"Чтобы получить доступ к архиву за тот день, система требует подтвердить текущую дату. Словно издевается, заставляя меня признать, сколько времени я потратил на это самобичевание."
|
"Чтобы получить доступ к архиву за тот день, система требует подтвердить текущую дату. Словно издевается, заставляя меня признать, сколько времени я потратил на это самобичевание."
|
||||||
|
|
||||||
play sound "audio/typing.ogg" loop
|
call screen keypad_screen
|
||||||
$ date_input = renpy.input("Введите сегодняшнюю дату (ДД.ММ.ГГГГ):", length=10)
|
$ date_input = _return
|
||||||
stop sound
|
|
||||||
|
|
||||||
if date_input == "20.04.2023":
|
if date_input == "20.04.2023":
|
||||||
play sound "audio/access_granted.ogg"
|
play sound "audio/access_granted.ogg"
|
||||||
@@ -352,7 +463,7 @@ label qte_corridor_puzzle:
|
|||||||
"Больше здесь не на что смотреть. Я оставляю зеркало в покое, хотя оно всё ещё преследует меня своей правдой."
|
"Больше здесь не на что смотреть. Я оставляю зеркало в покое, хотя оно всё ещё преследует меня своей правдой."
|
||||||
jump main_loop
|
jump main_loop
|
||||||
|
|
||||||
label qte_terminal_rhythm:
|
label qte_terminal_hack:
|
||||||
play footsteps "audio/footsteps.ogg"
|
play footsteps "audio/footsteps.ogg"
|
||||||
pause 1.0
|
pause 1.0
|
||||||
|
|
||||||
@@ -365,8 +476,10 @@ label qte_terminal_rhythm:
|
|||||||
"Сигнал нестабилен, поток данных рвется. Если я не выровняю частоту прямо сейчас, архив удалит себя автоматически как 'неактуальный'."
|
"Сигнал нестабилен, поток данных рвется. Если я не выровняю частоту прямо сейчас, архив удалит себя автоматически как 'неактуальный'."
|
||||||
"Мне нужно поймать этот поток. Не для того, чтобы отправить сообщение... а для того, чтобы наконец увидеть, что она мне писала."
|
"Мне нужно поймать этот поток. Не для того, чтобы отправить сообщение... а для того, чтобы наконец увидеть, что она мне писала."
|
||||||
|
|
||||||
$ player_input = []
|
$ target_code = generate_code()
|
||||||
call screen terminal_rhythm_screen
|
$ current_input = [0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
call screen terminal_code_game
|
||||||
|
|
||||||
if _return:
|
if _return:
|
||||||
play sound "audio/access_granted.ogg"
|
play sound "audio/access_granted.ogg"
|
||||||
@@ -436,11 +549,11 @@ label final_choice:
|
|||||||
"Признать ошибки и выйти (Переосмысление)" if fragments >= 3:
|
"Признать ошибки и выйти (Переосмысление)" if fragments >= 3:
|
||||||
jump ending_reflection
|
jump ending_reflection
|
||||||
|
|
||||||
"Отправить извинения (Свет)" if fragments >= 3 and thoughts_processed >= 3:
|
"Отправить извинения (Свет)" if fragments >= 3 and thoughts_processed:
|
||||||
jump ending_light
|
jump ending_light
|
||||||
|
|
||||||
label ending_silence:
|
label ending_silence:
|
||||||
scene black with Fade(0.1)
|
scene black with Fade(0.1, 0.0, 0.0)
|
||||||
|
|
||||||
stop music fadeout 0.1
|
stop music fadeout 0.1
|
||||||
stop ambient_generator fadeout 0.1
|
stop ambient_generator fadeout 0.1
|
||||||
@@ -497,7 +610,8 @@ label ending_light:
|
|||||||
"Я направляю остатки энергии на передатчик. Каждый процент заряда — это вырванный из жизни кусок, который я отдаю за шанс сказать правду."
|
"Я направляю остатки энергии на передатчик. Каждый процент заряда — это вырванный из жизни кусок, который я отдаю за шанс сказать правду."
|
||||||
"Я пишу не для того, чтобы получить ответ. Я пишу, чтобы освободиться. 'Прости за тишину. Она была моей ошибкой'."
|
"Я пишу не для того, чтобы получить ответ. Я пишу, чтобы освободиться. 'Прости за тишину. Она была моей ошибкой'."
|
||||||
"Нажимаю 'Отправить'. Система оповещает о передаче пакета, и тут же питание отключается. Станция замирает."
|
"Нажимаю 'Отправить'. Система оповещает о передаче пакета, и тут же питание отключается. Станция замирает."
|
||||||
scene bg_exit_winter at slow_zoom_pan with dissolve
|
scene bg_exit at slow_zoom_pan with dissolve
|
||||||
|
$ use_battery(battery)
|
||||||
"Я встаю и иду к выходу. Я не оглядываюсь. Мой долг перед прошлым оплачен, а будущее... будущее наконец-то принадлежит мне."
|
"Я встаю и иду к выходу. Я не оглядываюсь. Мой долг перед прошлым оплачен, а будущее... будущее наконец-то принадлежит мне."
|
||||||
jump quit_after_ending
|
jump quit_after_ending
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
1. Главный герой — человек, запертый в добровольной изоляции из-за неспособности преодолеть прошлую эмоциональную травму.
|
||||||
|
|
||||||
|
2. Весь окружающий мир и техническое состояние станции являются визуальной метафорой разрушающейся психики протагониста.
|
||||||
|
|
||||||
|
3. Локальный конфликт строится на драматической ошибке прошлого: герой намеренно выбрал молчание вместо действия, что привело к разрыву с близким человеком.
|
||||||
|
|
||||||
|
4. Механика сбора воспоминаний служит инструментом принудительной деконструкции психологических защит героя, блокировавших правду о случившемся.
|
||||||
|
|
||||||
|
5. Основная цель игры — не спасение персонажа, а достижение им психологической целостности через принятие ответственности за свои действия в финале.
|
||||||
Reference in new issue
Block a user