WTS/game/scripts/interface/achievements.rpy
LoafyLemon a06df58240 Bug fixes, Engine, Hotkeys
* 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
2024-09-24 21:16:55 +01:00

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)