Files
IWaniHugThatGator-Demo-Public/game/00src/save_compat.rpy
2024-04-21 13:45:17 -05:00

246 lines
10 KiB
Plaintext

# We'll assume that if the end of demo label was seen then the player has played the demo
define played_demo = renpy.seen_label("end_of_demo")
default persistent.seen_notice = False
default persistent.skip_ask = True
# If this is not set, ben_story will be set to None, this is only not set when the player loads an old save file
default ben_story = None
label after_load:
if not renpy.android:
# renpy.get_return_stack()[1] will basically return what chapter the user is currently in the save, we call index 1 since index 0 will always be the label storyline from storyline.rpy. Keep in mind the name used will be what the 'from clause' adds in the call
# If the player went past chapter 2 without seeing the caligraphy CG then they are on a save from the first version of the game
if not persistent.seen_notice and not renpy.seen_image("cg_calligraphy") and (renpy.get_return_stack()[1] == '_call_chapter_3' or renpy.get_return_stack()[1] == '_call_chapter_4'):
call old_save_notice from _call_old_save_notice
call ask_drawing from _call_ask_drawing
$ renpy.block_rollback()
# However this is not always reliable, sometimes it will fail, this is why it's in a try block and why we check that
# 1. We are checking a story script ("_call_chapter_"), since all of this won't work in mods and such
# 2. Check we are actually checking a string, since sometimes index 1 will be a tuple that points to a specific line instead (I don't know why this happens)
python:
try:
needs_compat = isinstance(renpy.get_return_stack()[1], str) and renpy.get_return_stack()[1].startswith("_call_chapter_")
except:
needs_compat = False
if ben_story == None and needs_compat:
# This ensures that mods won't trigger the save compatibility
if hasattr(store, 'score_olivia'):
call initstats(score_olivia,score_inco) from _call_initstats_4
call ask_drawing from _call_ask_drawing_1
# So they don't undo the new variables
$ renpy.block_rollback()
else:
$ score_olivia = 0
$ score_inco = 0
return
label old_save_notice:
show black as notice_screen with Dissolve(1)
"Your save file was created on an old version of the demo, which is incompatible with this version of the game."
"Choosing to continue will likely mean that you'll be forced into a bad ending."
menu:
"Continue":
pass
"Wipe save files":
$ delete_savefiles()
$ MainMenu(confirm=False)()
"Try to salvage the save file":
menu:
"When Olivia passed the drawing around you..."
"Drew her on a half-pipe":
$ score_inco += 1
$ score_inco_drawnotehalfpipe = True
"Held onto the sheet til after class":
$ score_inco_drawnotehalfpipe = False
"I haven't done that yet!" if renpy.get_return_stack()[1] == '_call_chapter_3':
pass
if renpy.get_return_stack()[1] == '_call_chapter_4':
menu:
"When Olivia was adamant on staying inside you..."
"Invited her to join you back outside":
$ score_olivia += 1
"Convinced her why her family needs her out there":
pass
"I haven't done that yet!":
pass
call ask_drawing from _call_ask_drawing_2
"Everything's ready, be sure to save the game once inside, enjoy the game and sorry for the inconvenience!"
$ persistent.seen_notice = True
"Go back to the main menu":
$ MainMenu(confirm=False)()
hide notice_screen with Dissolve(1)
return
init python:
def delete_savefiles():
for savegame in renpy.list_saved_games(fast=True):
renpy.unlink_save(savegame)
screen ask_skip():
modal True
style_prefix "confirm"
add "gui/overlay/confirm.png"
frame:
vbox:
xalign .5
yalign .5
spacing 30
label _("We detected you've played the demo before, would you like to skip to the new content?"):
style "confirm_prompt"
xalign 0.5
textbutton _("Ask me again next time (can be changed in the settings)"):
action ToggleVariable("persistent.skip_ask")
xalign 0.5
style_prefix "check"
hbox:
xalign 0.5
spacing 100
textbutton _("Yes") action Jump("AskChoices")
textbutton _("No") action Return()
label AskChoices:
menu:
"When Olivia passed the drawing around you..."
"Drew her on a half-pipe":
$ score_inco += 1
$ score_inco_drawnotehalfpipe = True
"Held onto the sheet til after class":
$ score_inco_drawnotehalfpipe = False
menu:
"When Olivia was adamant on staying inside you..."
"Invited her to join you back outside":
$ score_olivia += 1
"Convinced her why her family needs her out there":
pass
call ask_drawing from _call_ask_drawing_3
jump newContent
# Adds a custom error handler for the error of 'Couldn't find a place to stop rolling back' (Which usually happens when the save is incompatible). This error handler sends the user to a screen informing them of this and then to the menu instead of showing the gray exception screen.
init python:
def handle_bad_save(shortException,longException,tracebackFile):
if "Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?" in shortException and not config.developer:
renpy.jump("incompatible_save")
else:
return False
define config.exception_handler = handle_bad_save
label incompatible_save:
scene black
stop music
call screen badSave()
screen badSave():
modal True
style_prefix "confirm"
add "gui/overlay/confirm.png"
frame:
vbox:
xalign .5
yalign .5
spacing 30
label _("Your save file is incompatible and can't be fixed, try loading another one or start a new game."):
style "confirm_prompt"
xalign 0.5
hbox:
xalign 0.5
spacing 100
textbutton _("OK") activate_sound "audio/ui/snd_ui_click.wav" action Jump("kill_playthrough")
# For some reason, sending to the main menu won't work and instead it'll start a new (broken) game. SO instead, we clear the return stack and then return. Since it's cleared Renpy thinks "The game's over, send them back to the menu" and this for some reason jest werks.
label kill_playthrough:
# Stupid way to return to the main menu, the traditional ways don't work or outright crash the game
$ renpy.set_return_stack([])
return
# If there's no drawing saved we ask the player to either draw a new one or to import it
label ask_drawing:
if type(waniDemoCarryover.Chapter3Drawing) == NoneType:
"Older versions of the Demo (pre-full game release) did not properly save your drawings in a game-readable way. To fix this, we would like to offer you a chance to re-do your original \"masterpiece\" or to choose it from the file-picker. Would you be interested in that?"
menu:
"Yes, I would like to redraw":
python:
#change the last_drawing_index in the occurrences of sketches
last_drawing = 0
#TODO: Make this not a string call. last_drawing should be a check against the multi-persistance.
has_drawn = type(waniDemoCarryover.Chapter3Drawing) == bytes
draw_logic.Draw.main(last_drawing_index=0, seed_index=drawings_seed, has_drawn=has_drawn)
if (renpy.store.persistent.drawn):
if not (draw_logic.last_filename == ''):
waniDemoCarryover.Chapter3Drawing = draw_logic.rawImageBytes
waniDemoCarryover.save()
renpy.store.persistent.drawn = 0
$ my_drawing = renpy.display.im.Data(waniDemoCarryover.Chapter3Drawing, "input.png")
"Yes, I would like to use the file-picker":
python:
import shutil
from os import path
#Is there not a way to have tkinter.filedialog.askopenfile return raw bytes?
#For some reason, it only returns the string variant of TextIOWrapper
filename = getDrawing()
if filename != None and filename.endswith(".png"):
with open(filename, mode="rb") as filecontents:
waniDemoCarryover.Chapter3Drawing = filecontents.read()
# We close the file just in case and then we replace with None otherwise renpy tries to pickle the variable for saving and fails.
filecontents.close()
filecontents = None
my_drawing = renpy.display.im.Data(waniDemoCarryover.Chapter3Drawing, "input.png")
new_folder = path.join(
renpy.config.gamedir,
draw_logic.SAVE_FOLDER,
"{0}_{1}_{2}{3}".format(draw_logic.DRAW_SAVE_NAME, drawings_seed, 0, draw_logic.DRAW_EXT)
)
# We move the drawing for the later drawings gallery
try:
shutil.copyfile(filename, new_folder)
except:
pass
# Same as with filecontents. Needed unless renpy throws a fit when saving.
renpy.store.shutil = None
if filename == None or not filename.endswith(".png"):
$print(filename == None or not filename.endswith(".png"))
"Please input a valid file."
jump ask_drawing
else:
pass
"No":
pass
return