242 lines
8.2 KiB
Plaintext
242 lines
8.2 KiB
Plaintext
init python:
|
|
class book_readable_class(object):
|
|
def __init__(self, title, contents=(), **kwargs):
|
|
self.title = title
|
|
self.page = 0
|
|
self.overflow = None
|
|
|
|
self.title = title
|
|
self.contents = list(contents) # list of (title, text) pairs
|
|
self.__dict__.update(**kwargs)
|
|
|
|
self.npages = len(self.contents)
|
|
|
|
@property
|
|
def maxpage(self):
|
|
# maximum value for the `page` attribute
|
|
if self.npages %2:
|
|
return self.npages-1
|
|
return self.npages-2
|
|
|
|
def Open(self, page=None):
|
|
"""
|
|
Returns a list of actions that populate the variables of the book_menu screen.
|
|
If passed a `page`, does NOT change the page attribute of the book,
|
|
instead acts as though that page was the current one.
|
|
"""
|
|
if page is None:
|
|
page = self.page
|
|
page_title, page_text = self.contents[page]
|
|
page_text = page_text[:880]
|
|
if self.npages > page+1:
|
|
next_page_title, next_page_text = self.contents[page+1]
|
|
next_page_text = next_page_text[:880]
|
|
else:
|
|
next_page_title, next_page_text = None, None
|
|
|
|
return [
|
|
SetScreenVariable("page_title", page_title),
|
|
SetScreenVariable("page_text", page_text),
|
|
SetScreenVariable("next_page_title", next_page_title),
|
|
SetScreenVariable("next_page_text", next_page_text),
|
|
]
|
|
|
|
def Next(self):
|
|
page = min(self.page+2, self.maxpage)
|
|
return self.OpenPage(page)
|
|
|
|
def Prev(self):
|
|
page = max(self.page-2, 0)
|
|
return self.OpenPage(page)
|
|
|
|
def OpenPage(self, page):
|
|
return [
|
|
SetField(self, "page", page),
|
|
self.Open(page),
|
|
]
|
|
|
|
def append(self, page_title, page_text):
|
|
self.contents.append((page_title, page_text))
|
|
self.npages = len(self.contents)
|
|
return
|
|
|
|
class diary_class(book_readable_class):
|
|
def __init__(self, *args, dictionary, **kwargs):
|
|
"""
|
|
`dictionary` is a dict containing two types of entries:
|
|
- for normal text pages, id: (title, text).
|
|
`text` may contain interpolation fields, such as {code}.
|
|
When that's the case, there must be an 2nd-type entry for "code" in this dict.
|
|
`title` may be None.
|
|
- for interpolation codes, code: text.
|
|
`text` is the text to be used for the interpolation.
|
|
|
|
Alternatively, `dictionary` may be the name of a store variable containing the actual dictionary
|
|
(that's better when not in a testing phase, for pickling/saving/updating reasons)
|
|
"""
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.dictionary_ = dictionary # str id : either (title, text) or text
|
|
self.entry_ids = set() # str id
|
|
|
|
@property
|
|
def dictionary(self):
|
|
rv = self.dictionary_
|
|
if isinstance(rv, str):
|
|
rv = getattr(renpy.store, rv)
|
|
return rv
|
|
|
|
# append still exists, so that you can manually add pages without going through the dictionary
|
|
def diary_append(self, id, day=None, **branches):
|
|
"""
|
|
Adds a page to the diary.
|
|
`id` is the key of the event that just happened, in the dictionary.
|
|
`day` sets the day number for the entry, defaulting to the current day.
|
|
|
|
`branches` is a dict of {sub-event id : code} for every happened sub-event specializing event `id`.
|
|
the specified codes will be looked for in the dictionary, and the original entry of id `id`
|
|
will be formatted by associating {sub-event id} with dictionary[code].
|
|
If `code` is not a valid entry in the dict, the `code` value itself will be interpolated instead,
|
|
or nothing if v is a false value (like None).
|
|
|
|
If the page for the key `id` contains interpolation fields,
|
|
it is a mistake to not specify all interpolation fields in `branches`.
|
|
It is benign to specify keys which are not interpolation fields.
|
|
"""
|
|
|
|
if id in self.entry_ids:
|
|
return
|
|
|
|
dictionary = self.dictionary
|
|
page_title, page_text = dictionary[id]
|
|
|
|
if branches:
|
|
branches = {k : dictionary.get(v, v or "") for k, v in branches.items()}
|
|
page_text = page_text.format(**branches)
|
|
|
|
if day is None:
|
|
day = game.day
|
|
|
|
if page_title:
|
|
page_title = "Day {}\n{}".format(day, page_title)
|
|
else:
|
|
page_title = "Day {}".format(day)
|
|
|
|
self.append(page_title, page_text)
|
|
self.entry_ids.add(id)
|
|
|
|
|
|
label book_handle(book=None):
|
|
call screen book_menu(book) # with BookAnimatorFade(0.5, book_wrapped("book_page_next"))
|
|
return
|
|
|
|
screen book_menu(book=None):
|
|
zorder 30
|
|
|
|
# button style "empty" action NullAction()
|
|
modal True
|
|
|
|
add Color("#000", alpha=0.5)
|
|
add "interface/book/book_open.webp"
|
|
|
|
default page_title = None
|
|
# on "show" action book.Open() # sets up all the screen variables we want, including page_title which serves as a trigger
|
|
timer 0.00000000001 action book.Open() # sets up all the screen variables we want, including page_title which serves as a trigger
|
|
|
|
if page_title is not None:
|
|
|
|
use book_content(book, page_title, page_text, next_page_title, next_page_text)
|
|
|
|
use close_button
|
|
|
|
screen book_content(book, page_title, page_text, next_page_title, next_page_text):
|
|
frame:
|
|
style "empty"
|
|
pos (280, 130)
|
|
xsize 250
|
|
ysize 300
|
|
text page_title ypos -20 size 16 xalign 0.5 textalign .5
|
|
text page_text size 12 ypos 40
|
|
text str(book.page+1) bold True xalign 0.5 ypos 350 size 11
|
|
|
|
frame:
|
|
style "empty"
|
|
xpos 600 ypos 130
|
|
xsize 250
|
|
ysize 300
|
|
if next_page_title is not None:
|
|
text next_page_title ypos -20 size 16 xalign 0.5 textalign .5
|
|
if next_page_text is not None:
|
|
text next_page_text size 12 ypos 40
|
|
text str(book.page+2) bold True xalign 0.5 ypos 350 size 11
|
|
|
|
if book.page+2 < book.npages:
|
|
# Next
|
|
imagebutton:
|
|
pos (721, 100)
|
|
idle Transform("interface/book/hover.webp", alpha=0)
|
|
hover "interface/book/hover.webp"
|
|
action [book.Next(), With(BookAnimatorFade(.48, book_wrapped("book_page_next")))]
|
|
|
|
elif book.page > 0:
|
|
# Fast Back to start
|
|
imagebutton:
|
|
pos (721, 100)
|
|
idle "interface/book/back.webp"
|
|
hover "interface/book/back.webp"
|
|
action [book.OpenPage(0), With(BookAnimatorFade(.42, book_wrapped("book_page_start")))]
|
|
|
|
# Previous
|
|
imagebutton:
|
|
pos (242, 100)
|
|
idle Transform("interface/book/hover.webp", xzoom=-1.0, alpha=0)
|
|
hover Transform("interface/book/hover.webp", xzoom=-1.0, alpha=1)
|
|
action [book.Prev(), With(BookAnimatorFade(.48, book_wrapped("book_page_prev")))]
|
|
|
|
transform BookAnimatorFade(hold_time, widget, old_widget=None, new_widget=None):
|
|
delay hold_time
|
|
contains:
|
|
# old_widget
|
|
# new_widget with Dissolve(hold_time)
|
|
new_widget
|
|
events False
|
|
contains:
|
|
widget
|
|
time hold_time
|
|
new_widget
|
|
events True
|
|
|
|
transform book_wrapped(child):
|
|
contains:
|
|
"interface/book/book_open.webp"
|
|
contains:
|
|
child
|
|
|
|
image book_page_next:
|
|
#"interface/book_of_secrets/book_anim_01.webp"
|
|
#pause.1
|
|
"interface/book/page_02.webp"
|
|
pause.08
|
|
"interface/book/page_03.webp"
|
|
pause.08
|
|
"interface/book/page_04.webp"
|
|
pause.08
|
|
"interface/book/page_05.webp"
|
|
pause.08
|
|
"interface/book/page_06.webp"
|
|
pause.08
|
|
"interface/book/page_07.webp"
|
|
pause.08
|
|
|
|
image book_page_prev:
|
|
xoffset 40
|
|
xzoom -1
|
|
"book_page_next"
|
|
|
|
image book_page_start:
|
|
"interface/book/reverse_01.webp"
|
|
pause.07
|
|
"interface/book/reverse_02.webp"
|
|
pause.07
|
|
repeat 3 #book_page_max was too slow
|