LoafyLemon
a06df58240
* Implement JumpWith action * Fix hide windows hotkey * Fix surface tree capture by implementing inter pauses for interface elements * Implement achievements 'O' hotkey * Fixed call stack depth issues
291 lines
15 KiB
Plaintext
291 lines
15 KiB
Plaintext
init -5 python:
|
|
from collections import namedtuple
|
|
AchievementKind = namedtuple("AchievementKind", ("category", "name", "description", "icon", "progression", "progression_max"))
|
|
AchievementKind.title = AchievementKind.name
|
|
|
|
define achievements_db = {
|
|
# GENERAL
|
|
"tooltip": AchievementKind("general", "A big surprise", "Discovered more than the tip of the tool inside the settings.", "interface/icons/silver_scroll.webp", None, None),
|
|
"Credits": AchievementKind("general", "New game, who this?", "Watched the credits.", "interface/icons/silver_scroll.webp", None, None),
|
|
"gold": AchievementKind("general", "Gold Digger", "Acquired 10,000 gold coins.", "interface/icons/gold.webp", "states.env.gold", 10000),
|
|
"drunkard": AchievementKind("general", "Drunken Master", "Acquired 25 bottles of wine.", "interface/icons/wine.webp", "wine_ITEM.owned", 25),
|
|
"workaholic": AchievementKind("general", "Workaholic", "Completed five full reports.", "interface/icons/generic_scroll.webp", "states.paperwork_reports_times", 5),
|
|
"fireplace": AchievementKind("general", "Feel the Heat", "Started fire 5 times.", "images/rooms/main_room/fireplace/fireplace_idle.webp", "states.fireplace_started_times", 5),
|
|
"peta": AchievementKind("general", "I think I forgot something...", "Forgot to feed the bird 50 days in a row.", "images/rooms/main_room/phoenix/phoenix_01.webp", "(states.env.day - states.bird_fed_times)", 50),
|
|
"jerkoff": AchievementKind("general", "Regular Wand Polish", "Jerked off 10 times.", "images/rooms/main_room/phoenix/phoenix_01.webp", "states.jerked_off_times", 10),
|
|
"petpal": AchievementKind("general", "Regular stroking", "Petted the bird 25 times.", "images/rooms/main_room/phoenix/phoenix_01.webp", "states.bird_petted_times", 25),
|
|
"postman": AchievementKind("general", "Poster Boy", "Bought all posters from the store.", "interface/icons/agrabah_poster.webp", None, None),
|
|
"hats": AchievementKind("general", "Mad Hatter", "Bought all hats from the store.", "interface/icons/icon_gambler_hat.webp", None, None),
|
|
"bros": AchievementKind("general", "Bros before hoes", "Became best pals with Snape.", "interface/icons/head/snape.webp", None, None),
|
|
"decorator": AchievementKind("general", "Decorator", "Applied a decoration.", "interface/icons/stag_trophy.webp", None, None),
|
|
# PROGRESSION
|
|
"firstpotion": AchievementKind("progression", "Brewing 101", "Brewed your first potion.", "interface/icons/head/hermione.webp", None, None),
|
|
"unlockher": AchievementKind("progression", "Granger Danger", "Unlocked Hermione Granger.", "interface/icons/head/hermione.webp", None, None),
|
|
"unlockcho": AchievementKind("progression", "Chang Dynasty", "Unlocked Cho Chang.", "interface/icons/head/cho.webp", None, None),
|
|
"unlocklun": AchievementKind("progression", "Looney Tunes", "Unlocked Luna Lovegood.", "interface/icons/head/luna.webp", None, None),
|
|
"unlockast": AchievementKind("progression", "Green Peas", "Unlocked Astoria Greengrass.", "interface/icons/head/astoria.webp", None, None),
|
|
"unlockton": AchievementKind("progression", "Nymphadoreador", "Unlocked Nymphadora Tonks.", "interface/icons/head/tonks.webp", None, None),
|
|
"unlocksus": AchievementKind("progression", "Boner", "Unlocked Susan Bones.", "interface/icons/head/susan.webp", None, None),
|
|
"unlocksna": AchievementKind("progression", "Strictly colleagues", "Unlocked Severus Snape.", "interface/icons/head/snape.webp", None, None),
|
|
"overwhored": AchievementKind("progression", "Overwhored", "Fully corrupted one of the girls.", "interface/icons/head/hermione.webp", None, None),
|
|
"herstrip": AchievementKind("progression", "Dance lessons", "Allowed Hermione to dance naked in front of Snape.", "interface/icons/head/hermione.webp", None, None),
|
|
"herkiss": AchievementKind("progression", "First Kiss", "You made out with Hermione, or rather your cock did.", "interface/icons/head/hermione.webp", None, None),
|
|
"hertits": AchievementKind("progression", "Boobs Lover", "Stuck a dick between the valley of plenty.", "interface/icons/head/hermione.webp", None, None),
|
|
"headlib": AchievementKind("progression", "Head Librarian", "Had oral lessons with Hermione.", "interface/icons/head/hermione.webp", None, None),
|
|
"nerdgasm": AchievementKind("progression", "Nerdgasm", "Done the deed with Hermione.", "interface/icons/head/hermione.webp", None, None),
|
|
"start": AchievementKind("progression", "Welcome to Hogwarts!", "Finished the intro.", "interface/icon.webp", None, None),
|
|
"ending": AchievementKind("progression", "Bittersweet Farewell", "Reached the ending.", "interface/icons/silver.webp", None, None),
|
|
# EVENTS
|
|
"satan": AchievementKind("events", "Daddy Lucifer", "Made a pact with the right devil.", "interface/icons/head/hermione.webp", None, None),
|
|
"vibin": AchievementKind("events", "Just Vibin", "Brought pure joy to Hermione's life with expert use of vibrators.", "interface/icons/head/hermione.webp", None, None),
|
|
"tittypotion": AchievementKind("events", "Tig Ol' bitties", "Used a potion to increase one's breast size to the max.", "interface/icons/head/hermione.webp", None, None),
|
|
"kittypotion": AchievementKind("events", "Here kitty, kitty!", "Hermione overdosed on polyjuice potion.", "interface/icons/head/hermione.webp", None, None),
|
|
"daddy": AchievementKind("events", "Who's your daddy?", "Been called a daddy.", "interface/icons/head/hermione.webp", None, None),
|
|
"knock": AchievementKind("events", "*Knock* *knock*", "Told Hermione to fuck off.", "images/rooms/main_room/door/door_idle.webp", None, None),
|
|
"pantiesfap": AchievementKind("events", "I sneezed on them...", "Rubbed one out on someone's panties.", "characters/genie/chibis/jerk_off/02.webp", None, None),
|
|
"Cardwin": AchievementKind("events", "Time to duel", "Won a card game duel.", "interface/icons/cards.webp", None, None),
|
|
"mirror": AchievementKind("events", "Mirror, mirror on the wall..", "Found the Room of Requirements.", "images/rooms/room_of_requirement/mirror_hover.webp", None, None),
|
|
"busted": AchievementKind("events", "BUSTED!", "Got busted for busting a nut.", "interface/icons/head/hermione.webp", None, None),
|
|
# SECRETS
|
|
"safetyfirst": AchievementKind("secrets", "Safety First", "Wore a condom when the time was right.", "interface/icons/head/hermione.webp", None, None),
|
|
"puzzle": AchievementKind("secrets", "Brainiac", "Solved an incredibly complex sliding tiles puzzle.", "interface/icons/item_potion.webp", None, None),
|
|
"flashback": AchievementKind("secrets", "Flashback", "Rolled back to the future at the right moment.", "interface/icons/cards.webp", None, None),
|
|
}
|
|
|
|
init python hide:
|
|
for name in achievements_db:
|
|
achievement.register(name)
|
|
|
|
init python:
|
|
# intentionaly not a define nor a default
|
|
__popup_stack = []
|
|
|
|
config.after_default_callbacks.append(__popup_stack.clear)
|
|
config.always_shown_screens.append("achievement_main")
|
|
|
|
screen achievement_main():
|
|
layer "interface"
|
|
|
|
vbox:
|
|
for id index id in __popup_stack[:3]:
|
|
use achievement_window(msg=achievements_db[id].title, title="Achievement unlocked!", icon=achievements_db[id].icon)
|
|
timer 6 action Function(__popup_stack.remove, id)
|
|
|
|
label popup(msg="", title="", icon=None, xpos=0, ypos=60, sound=True, soundfile='sounds/achievement.ogg'):
|
|
if sound:
|
|
play sound soundfile
|
|
hide screen achievement_window
|
|
show screen achievement_window(msg=msg, title=title, icon=icon, xpos=xpos, ypos=ypos)
|
|
return
|
|
|
|
screen achievement_window(msg="", title="", icon=None, xpos=0, ypos=60):
|
|
tag popup_window
|
|
layer "interface"
|
|
|
|
frame:
|
|
style "empty"
|
|
at popup_animation(time=5.0, xx=-410)
|
|
pos (xpos, ypos)
|
|
xsize 410
|
|
ysize 96
|
|
|
|
add gui.format("interface/achievements/{}/box.webp")
|
|
if icon:
|
|
frame:
|
|
style "empty"
|
|
pos (6, 6)
|
|
xsize 84
|
|
ysize 84
|
|
$ image_zoom = crop_image_zoom(icon, 84, 84)
|
|
if 'head' in icon:
|
|
add image_zoom align (0.5, 1.0) yoffset -1
|
|
else:
|
|
add image_zoom align (0.5, 0.5)
|
|
|
|
add "interface/achievements/glass.webp"
|
|
frame:
|
|
style "empty"
|
|
xpos 96
|
|
xsize 314
|
|
vbox:
|
|
ypos 12
|
|
spacing 10
|
|
xalign 0.5
|
|
text title size 18 xalign 0.5
|
|
text msg size 14 xalign 0.5
|
|
timer 6.0 action Hide("achievement_window")
|
|
|
|
transform rotate_circular(t=7):
|
|
on show, appear, start:
|
|
subpixel True
|
|
rotate 0
|
|
linear t rotate 360
|
|
repeat
|
|
|
|
init python in achievements:
|
|
def validate():
|
|
"""Validate icons and progression flags"""
|
|
for i in renpy.store.achievements_db.values():
|
|
if not renpy.loadable(i.icon):
|
|
raise IOError(repr(i.icon))
|
|
# if i.progression and not isinstance(eval(i.progression), (int, float)):
|
|
# raise TypeError(f"Progression flag must return a float or an integer - {i.progression}")
|
|
|
|
validate()
|
|
|
|
def unlock(id, silent=False):
|
|
if renpy.store._in_replay:
|
|
return
|
|
|
|
if not renpy.store.achievement.has(id):
|
|
renpy.store.achievement.grant(id)
|
|
|
|
if not silent:
|
|
renpy.play('sounds/achievement.ogg')
|
|
renpy.store.__popup_stack.append(id)
|
|
|
|
status = renpy.store.achievement.has
|
|
lock = renpy.store.achievement.clear
|
|
|
|
def get_list(category=None):
|
|
if category:
|
|
items = filter((lambda x: category==renpy.store.achievements_db[x].category), renpy.store.achievements_db)
|
|
else:
|
|
items = renpy.store.achievements_db
|
|
items = sorted(items, key=lambda x: renpy.store.natsort_key(renpy.store.achievements_db[x].title))
|
|
return items
|
|
|
|
def get_list(category=None):
|
|
if category:
|
|
items = filter((lambda x: category==renpy.store.achievements_db[x].category), renpy.store.achievements_db)
|
|
else:
|
|
items = renpy.store.achievements_db
|
|
|
|
# Sort titles
|
|
items = sorted(items, key=lambda x: renpy.store.natsort_key(renpy.store.achievements_db[x].title))
|
|
# Sort unlocks
|
|
items = sorted(items, key=lambda x: renpy.store.achievement.has(x))
|
|
return items
|
|
|
|
def get_categories():
|
|
return set(item.category for item in renpy.store.achievements_db.values())
|
|
|
|
def get_percentage(category=None):
|
|
if category:
|
|
items = list(filter((lambda x: category==renpy.store.achievements_db[x].category), renpy.store.achievements_db))
|
|
else:
|
|
items = renpy.store.achievements_db
|
|
total_achievements = len(items)
|
|
unlocked_achievements = sum(1 for x in items if renpy.store.achievement.has(x))
|
|
return round((unlocked_achievements / total_achievements) * 100)
|
|
|
|
label achievements(inter_pause=True):
|
|
$ disable_game_menu()
|
|
if inter_pause:
|
|
# Ensures all irrelevant screens are hidden before capturing the surface tree
|
|
with Pause(0.2)
|
|
call screen achievements
|
|
$ enable_game_menu()
|
|
jump main_room_menu
|
|
|
|
screen achievements():
|
|
modal True
|
|
layer "interface"
|
|
zorder 0
|
|
style_prefix "achievements"
|
|
|
|
default navigation_atl = navigation_show
|
|
default last_frame = (screenshot.capture() or screenshot.image)
|
|
default navigation_last_frame_atl = navigation_last_frame_show
|
|
default navigation_exit = False
|
|
|
|
default category = None
|
|
default menu_categories = achievements.get_categories()
|
|
default menu_items = achievements.get_list(category)
|
|
|
|
add last_frame at navigation_last_frame_atl
|
|
|
|
if navigation_exit:
|
|
timer 0.4 action Return()
|
|
|
|
frame:
|
|
style "empty"
|
|
align (0.5, 0.5)
|
|
at navigation_atl
|
|
|
|
vbox:
|
|
style_prefix "navigation_subtabs"
|
|
pos (286, 170)
|
|
|
|
at navigation_subtabs_show
|
|
|
|
textbutton _("All") action [SetScreenVariable("category", None), SetScreenVariable("menu_items", achievements.get_list())] selected (category==None) at navigation_tabs
|
|
for i in menu_categories:
|
|
textbutton "[i.capitalize()]" action [SetScreenVariable("category", i), SetScreenVariable("menu_items", achievements.get_list(i))] selected (category==i) at navigation_tabs
|
|
null height 35
|
|
textbutton _("Return") action [SetScreenVariable("navigation_last_frame_atl", navigation_last_frame_hide), SetScreenVariable("navigation_atl", navigation_hide), SetScreenVariable("navigation_exit", True)] keysym ["game_menu", "achievements"] at navigation_tabs
|
|
|
|
frame:
|
|
label _("Achievements")
|
|
|
|
text "([achievements.get_percentage()]%)" pos (108, -3)
|
|
|
|
# Add items
|
|
viewport:
|
|
ypos 32
|
|
scrollbars "vertical"
|
|
mousewheel True
|
|
draggable "touch"
|
|
vbox:
|
|
for item in menu_items:
|
|
$ item_unlocked = achievement.has(item)
|
|
$ item_data = achievements_db[item]
|
|
$ item_color = "#ffffff" if item_unlocked else "#8d8d8d"
|
|
fixed:
|
|
fit_first True
|
|
button:
|
|
hbox:
|
|
add crop_image_zoom(item_data.icon, 48, 48, not item_unlocked) xysize (48, 48)
|
|
null width 5
|
|
vbox:
|
|
text "[item_data.title]" color item_color
|
|
text "[item_data.description]" color item_color style "achievements_text_small"
|
|
action NullAction()
|
|
if item_unlocked:
|
|
add "interface/topbar/icon_check.webp" xysize (24, 24) yalign 0.5
|
|
if item_data.progression:
|
|
if item_unlocked:
|
|
bar value StaticValue(1.0)
|
|
else:
|
|
bar value StaticValue(eval(item_data.progression), item_data.progression_max) style "achievements_bar_disabled"
|
|
add "frame_spacer" xalign 0.5 xsize 500
|
|
|
|
style achievements_viewport is viewport:
|
|
xalign 0.5
|
|
ymaximum 397
|
|
style achievements_vbox is frame_vbox:
|
|
ypos 0
|
|
yspacing 0
|
|
xalign 0
|
|
style achievements_frame is frame
|
|
style achievements_label is frame_label
|
|
style achievements_label_text is frame_label_text
|
|
style achievements_text is frame_text:
|
|
xalign 0
|
|
style achievements_text_small is achievements_text:
|
|
xalign 0
|
|
size 12
|
|
style achievements_button is frame_button:
|
|
xfill True
|
|
yminimum 48
|
|
style achievements_button_text is frame_button_text
|
|
style achievements_bar is player_bar:
|
|
xmaximum 400
|
|
yalign 1.0
|
|
xpos 78
|
|
ysize 10
|
|
yoffset -2
|
|
style achievements_bar_disabled is achievements_bar:
|
|
left_bar Frame(Transform(Image("gui/creamy_pumpkin_pie/player/player_bar_full.png", oversample=4), matrixcolor=BrightnessMatrix(-0.5)), 24, 0, tile=False)
|
|
right_bar Frame(Transform(Image("gui/creamy_pumpkin_pie/player/player_bar_empty.png", oversample=4), matrixcolor=BrightnessMatrix(-0.5)), 24, 0, tile=False)
|