Gouvernathor
1f8e939cf9
not sure why the "on show, appear, start" was there when there's no "on hide", but it prevents animation from really doing its job
451 lines
20 KiB
Plaintext
451 lines
20 KiB
Plaintext
init python:
|
|
from collections import namedtuple
|
|
AchievementKind = namedtuple("AchievementKind", ("category", "name", "description", "icon", "secret"))
|
|
AchievementKind.title = AchievementKind.name
|
|
|
|
define achievements_db = {
|
|
# id : (categoryname, title, description, icon, secret)
|
|
"unlockher": AchievementKind("Characters", "Granger Danger", "Awarded for unlocking Hermione Granger.", "interface/icons/head/hermione.webp", False),
|
|
"unlockcho": AchievementKind("Characters", "Chang Dynasty", "Awarded for unlocking Cho Chang.", "interface/icons/head/cho.webp", False),
|
|
"unlocklun": AchievementKind("Characters", "Looney Tunes", "Awarded for unlocking Luna Lovegood.", "interface/icons/head/luna.webp", False),
|
|
"unlockast": AchievementKind("Characters", "Green Peas", "Awarded for unlocking Astoria Greengrass.", "interface/icons/head/astoria.webp", False),
|
|
"unlockton": AchievementKind("Characters", "Nymphadoreador", "Awarded for unlocking Nymphadora Tonks.", "interface/icons/head/tonks.webp", False),
|
|
"overwhored": AchievementKind("Characters", "Overwhored", "Awarded for fully corrupting Hermione.", "interface/icons/head/hermione.webp", False),
|
|
"unlocksus": AchievementKind("Characters", "Boner", "Awarded for unlocking Susan Bones.", "interface/icons/head/susan.webp", False),
|
|
"unlocksna": AchievementKind("Characters", "Strictly colleagues", "Awarded for unlocking Severus Snape.", "interface/icons/head/snape.webp", False),
|
|
"mirror": AchievementKind("Mirror", "Mirror, mirror on the wall..", "Awarded for unlocking the Room of Requirement.", "images/rooms/room_of_requirement/mirror_hover.webp", False),
|
|
"gold": AchievementKind("General", "Gold Digger", "Awarded for having 10,000 gold in total.", "interface/icons/gold.webp", False),
|
|
"drunkard": AchievementKind("General", "Drunken Master", "Awarded for collecting 25 bottles of wine.", "interface/icons/wine.webp", True),
|
|
"workaholic": AchievementKind("General", "Workaholic", "Awarded for completing five full reports.", "interface/icons/generic_scroll.webp", False),
|
|
"fireplace": AchievementKind("General", "Feel the Heat", "Awarded for lighting the fireplace 5 times or more.", "images/rooms/main_room/fireplace/fireplace_idle.webp", True),
|
|
"peta": AchievementKind("General", "I think I forgot something...", "Awarded for not feeding the bird for 50 days.... \nYou monster.\n{size=-4}Disclaimer: No real nor fictional animals were harmed in the process.{/size}", "images/rooms/main_room/phoenix/phoenix_01.webp", True),
|
|
"petpal": AchievementKind("General", "Regular stroking", "Awarded for petting the bird 25 times.", "images/rooms/main_room/phoenix/phoenix_01.webp", False),
|
|
"postman": AchievementKind("Cardgame", "Poster Boy", "Awarded for buying all posters from the token shop.", "interface/icons/agrabah_poster.webp", False),
|
|
"hats": AchievementKind("Cardgame", "Mad Hatter", "Awarded for buying all hat decorations from the token shop.", "interface/icons/icon_gambler_hat.webp", False),
|
|
"daddy": AchievementKind("Characters", "Who's your daddy?", "Awarded for letting Hermione call you a {size=-5}(sugar){/size} daddy.", "interface/icons/head/hermione.webp", True),
|
|
"pantiesfap": AchievementKind("Characters", "I sneezed on them...", "Awarded for rubbing one out on Hermione's panties.", "characters/genie/chibis/jerk_off/02.webp", False),
|
|
"pantiesfapcho": AchievementKind("Characters", "Exercise is important", "Awarded for rubbing one out on Cho's panties.", "characters/genie/chibis/jerk_off/02.webp", False),
|
|
"bros": AchievementKind("Characters", "Bros before hoes", "Awarded for becoming best pals with Snape.", "interface/icons/head/snape.webp", False),
|
|
"knock": AchievementKind("Characters", "*Knock* *knock*", "Awarded for telling Hermione to go away during her introductory events.", "images/rooms/main_room/door/door_idle.webp", True),
|
|
"decorator": AchievementKind("Cardgame", "Decorator", "Awarded for decorating the office for the first time.", "interface/icons/stag_trophy.webp", False),
|
|
"flashback": AchievementKind("Cardgame", "Flashback", "Awarded for retelling what actually happened...", "interface/icons/cards.webp", True),
|
|
"start": AchievementKind("General", "Welcome to Hogwarts!", "Awarded for finishing the intro.", "interface/icon.webp", False),
|
|
"export": AchievementKind("General", "Sharing is caring", "Awarded for exporting an outfit through the wardrobe menu.", "interface/wardrobe/icons/load.webp", False),
|
|
"Credits": AchievementKind("General", "New game, who this?", "Awarded for checking out the Credits Menu.", "interface/icons/silver_scroll.webp", False),
|
|
"Cardwin": AchievementKind("Cardgame", "Time to duel", "Awarded for winning your first Card game duel.", "interface/icons/cards.webp", False),
|
|
"puzzle": AchievementKind("General", "Down the hatch!", "Awarded for wasting a bottle of unbelievably rare phoenix tears by drinking it.", "interface/icons/item_potion.webp", True),
|
|
"ending": AchievementKind("General", "Bittersweet Farewell", "Awarded for reaching the original ending.", "interface/icons/silver.webp", True),
|
|
#1.37 HG achievements
|
|
"busted": AchievementKind("Characters", "BUSTED!", "Awarded for getting busted by Hermione when busting a nut.", "interface/icons/head/hermione.webp", False),
|
|
"herstrip": AchievementKind("Characters", "Dance lessons", "Awarded for having Hermione dance naked in front of you... and Snape.", "interface/icons/head/hermione.webp", False),
|
|
"herkiss": AchievementKind("Characters", "First Kiss", "Awarded for having Hermione make out with you-- r... cock...", "interface/icons/head/hermione.webp", False),
|
|
"hertits": AchievementKind("Characters", "Boobs Lover", "Awarded for sticking it between Hermione's fun bags.", "interface/icons/head/hermione.webp", False),
|
|
"headlib": AchievementKind("Characters", "Head Librarian", "Awarded for releasing your seed in Hermione's mouth.", "interface/icons/head/hermione.webp", False),
|
|
"nerdgasm": AchievementKind("Characters", "Nerdgasm", "Awarded for doing the deed with Hermione.", "interface/icons/head/hermione.webp", False)
|
|
}
|
|
|
|
init python hide:
|
|
for name in achievements_db:
|
|
achievement.register(name)
|
|
|
|
# keep the achievements from earlier versions
|
|
if isinstance(persistent.achievements, dict):
|
|
# id : [categoryname, title, description, unlocked, icon, secret]
|
|
for k, v in persistent.achievements.items():
|
|
if v[3]:
|
|
achievement.grant(k)
|
|
del persistent.achievements
|
|
|
|
init python:
|
|
class Achievements(object):
|
|
"""
|
|
Useless class, can't be rolled out because of pickle and save compatibility.
|
|
"""
|
|
|
|
@staticmethod
|
|
def validate():
|
|
"""Check if icons are loadable at init"""
|
|
for i in achievements_db.values():
|
|
if not renpy.loadable(i.icon):
|
|
raise IOError(repr(i.icon))
|
|
|
|
status = staticmethod(achievement.has)
|
|
|
|
@staticmethod
|
|
def unlock(id, silent=False):
|
|
if _in_replay:
|
|
return
|
|
|
|
if not achievement.has(id):
|
|
achievement.grant(id)
|
|
|
|
if not silent:
|
|
renpy.play('sounds/achievement.ogg')
|
|
__popup_stack.append(id)
|
|
|
|
lock = staticmethod(achievement.clear)
|
|
|
|
def achievement_sortfilter(lst, sortby="A-z", filtering=None):
|
|
"""
|
|
Takes a list/iterable of achievement ids, returns a list of achievement ids
|
|
"""
|
|
|
|
if filtering == "Locked":
|
|
lst = (x for x in lst if not achievement.has(x))
|
|
elif filtering == "Unlocked":
|
|
lst = filter(achievement.has, lst)
|
|
elif filtering == "Secret":
|
|
lst = (x for x in lst if achievements_db[x].secret is True)
|
|
|
|
# Always sort alphabetically first.
|
|
lst = sorted(lst, key=lambda x: natsort_key(achievements_db[x].title))
|
|
|
|
if sortby == "z-A":
|
|
lst.sort(key=lambda x: natsort_key(achievements_db[x].title), reverse=True)
|
|
elif sortby == "Unlocked":
|
|
lst.sort(key=lambda x: not achievement.has(x))
|
|
elif sortby == "Locked":
|
|
lst.sort(key=achievement.has)
|
|
|
|
return lst
|
|
|
|
default achievements = Achievements()
|
|
|
|
###
|
|
|
|
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):
|
|
animation
|
|
subpixel True
|
|
block:
|
|
rotate 0
|
|
linear t rotate 360
|
|
repeat
|
|
|
|
####################################
|
|
############# Menu #################
|
|
####################################
|
|
|
|
define achievement_categories_sorted = ("All", "General", "Characters", "Cardgame", "Mirror")
|
|
define items_shown = 36
|
|
|
|
init python:
|
|
class __SetCategory(Action):
|
|
def __init__(self, category):
|
|
self.category = category
|
|
|
|
def __call__(self):
|
|
global current_category
|
|
global number_unlocked
|
|
|
|
current_category = self.category
|
|
if current_category == "All":
|
|
category_items = achievements_db
|
|
else:
|
|
category_items = filter((lambda x: current_category==achievements_db[x].category), achievements_db)
|
|
__regen(category_items)
|
|
number_unlocked = len(tuple(filter(achievement.has, menu_items)))
|
|
|
|
def __regen(category_items=achievements_db):
|
|
global menu_items
|
|
global menu_items_length
|
|
global current_page
|
|
global current_item
|
|
|
|
menu_items = achievement_sortfilter(category_items, current_sorting, current_filter)
|
|
menu_items_length = len(menu_items)
|
|
current_page = 0
|
|
current_item = next(iter(menu_items), None)
|
|
renpy.restart_interaction()
|
|
|
|
label achievement:
|
|
$ gui.in_context("achievement_menu")
|
|
jump main_room_menu
|
|
|
|
label achievement_menu(xx=150, yy=90):
|
|
|
|
$ renpy.dynamic(
|
|
current_page = 0,
|
|
current_category = achievement_categories_sorted[0],
|
|
current_filter = None,
|
|
current_sorting = "Unlocked",
|
|
menu_items = achievement_sortfilter(achievements_db, "Unlocked", None),
|
|
number_unlocked = len(tuple(filter(achievement.has, achievements_db)))
|
|
)
|
|
$ renpy.dynamic(
|
|
menu_items_length = len(menu_items),
|
|
current_item = next(iter(menu_items), None),
|
|
)
|
|
|
|
call screen achievements(xx, yy)
|
|
|
|
return
|
|
|
|
screen achievements(xx, yy):
|
|
tag achievements
|
|
zorder 15
|
|
modal True
|
|
|
|
add "gui_fade"
|
|
|
|
if renpy.mobile:
|
|
use close_button_background
|
|
|
|
use close_button
|
|
|
|
fixed:
|
|
pos (xx, yy)
|
|
if settings.get("animations"):
|
|
at gui_animation
|
|
use achievement_menu()
|
|
use achievement_menuitem()
|
|
|
|
screen achievement_menu():
|
|
window:
|
|
style "empty"
|
|
style_prefix gui.theme('achievements')
|
|
xysize (207, 454)
|
|
|
|
use invisible_button()
|
|
|
|
add gui.format("interface/achievements/{}/panel_left.webp")
|
|
|
|
vbox:
|
|
style_prefix gui.theme('achievements_categories')
|
|
pos (6, 41)
|
|
for category in achievement_categories_sorted:
|
|
vbox:
|
|
textbutton category:
|
|
selected (current_category == category)
|
|
action __SetCategory(category)
|
|
|
|
add gui.format("interface/achievements/{}/spacer_left.webp")
|
|
vbox:
|
|
style_prefix gui.theme('achievements_filters')
|
|
pos (6, 384)
|
|
if current_filter is None:
|
|
textbutton "Show: All" action [CycleVariable("current_filter", (None, "Locked", "Unlocked", "Secret")), __regen]
|
|
else:
|
|
textbutton "Show: [current_filter]" action [CycleVariable("current_filter", (None, "Locked", "Unlocked", "Secret")), __regen]
|
|
textbutton "Sort by: [current_sorting]" action [CycleVariable("current_sorting", ("A-z", "z-A", "Unlocked", "Locked")), __regen]
|
|
|
|
screen achievement_menuitem():
|
|
window:
|
|
style "empty"
|
|
pos (217, -53)
|
|
xysize (560, 507)
|
|
|
|
use invisible_button()
|
|
|
|
add "interface/achievements/star.webp"
|
|
add gui.format("interface/achievements/{}/panel.webp")
|
|
|
|
text "Achievements" size 22 xalign 0.5 ypos 65
|
|
|
|
text "Unlocked: [number_unlocked]/[menu_items_length]" size 12 pos (24, 70)
|
|
|
|
# Page counter
|
|
if menu_items_length > items_shown:
|
|
hbox:
|
|
xanchor 1.0
|
|
pos (540, 24)
|
|
spacing 5
|
|
add "interface/page.webp" yanchor 0.5 ypos 53
|
|
text str(current_page+1)+"/"+str(int(math.ceil(menu_items_length/items_shown))) ypos 44 size 16
|
|
vbox:
|
|
pos (570, 186)
|
|
spacing 10
|
|
|
|
imagebutton:
|
|
idle gui.format("interface/frames/{}/arrow_up.webp")
|
|
if not current_page <= 0:
|
|
hover image_hover(gui.format("interface/frames/{}/arrow_up.webp"))
|
|
action SetVariable("current_page", current_page-1)
|
|
# TODO: in 8.2, replace with IncrementVariable("current_page", -1)
|
|
|
|
imagebutton:
|
|
idle Transform(gui.format("interface/frames/{}/arrow_up.webp"), yzoom = -1.0)
|
|
if current_page < math.ceil((menu_items_length-1)/items_shown)-1:
|
|
hover Transform(image_hover(gui.format("interface/frames/{}/arrow_up.webp")), yzoom = -1.0)
|
|
action SetVariable("current_page", current_page+1)
|
|
# TODO: in 8.2, replace with IncrementVariable("current_page")
|
|
|
|
# Add items
|
|
grid 9 4:
|
|
style "empty"
|
|
pos (24, 113)
|
|
spacing 10
|
|
|
|
for it_item in menu_items[current_page*items_shown:(current_page+1)*items_shown]:
|
|
$ it_item_data = achievements_db[it_item]
|
|
$ it_item_unlocked = achievement.has(it_item)
|
|
frame:
|
|
style "empty"
|
|
xsize 48
|
|
ysize 48
|
|
add gui.format("interface/achievements/{}/iconbox.webp")
|
|
|
|
if current_item and current_item == it_item:
|
|
add "interface/achievements/glow.webp" align (0.5, 0.5) zoom 0.105 alpha 0.7 at rotate_circular
|
|
|
|
if it_item_unlocked or not it_item_data.secret:
|
|
$ image_zoom = crop_image_zoom(it_item_data.icon, 42, 42, not it_item_unlocked)
|
|
else:
|
|
$ image_zoom = crop_image_zoom("interface/achievements/secret.webp", 35, 35, True)
|
|
|
|
add image_zoom:
|
|
xalign .5
|
|
if it_item_data.category == "Characters" and (it_item_unlocked or not it_item_data.secret):
|
|
yalign 1.
|
|
yoffset -3
|
|
else:
|
|
yalign .5
|
|
|
|
button:
|
|
style gui.theme("overlay_button")
|
|
background "interface/achievements/glass_iconbox.webp"
|
|
xsize 48 ysize 48
|
|
action SetVariable("current_item", it_item)
|
|
if it_item_data.secret and not it_item_unlocked:
|
|
tooltip "???"
|
|
else:
|
|
tooltip it_item_data.name
|
|
|
|
if current_item:
|
|
$ current_item_data = achievements_db[current_item]
|
|
$ current_item_unlocked = achievement.has(current_item)
|
|
frame:
|
|
style "empty"
|
|
xsize 96
|
|
ysize 96
|
|
pos (24, 375)
|
|
add gui.format("interface/achievements/{}/icon_selected.webp")
|
|
|
|
if current_item_unlocked or not current_item_data.secret:
|
|
$ image_zoom = crop_image_zoom(current_item_data.icon, 84, 84, not current_item_unlocked)
|
|
else:
|
|
$ image_zoom = crop_image_zoom("interface/achievements/secret.webp", 70, 70, True)
|
|
|
|
add image_zoom:
|
|
xalign .5
|
|
if current_item_data.category == "Characters" and (current_item_unlocked or not current_item_data.secret):
|
|
yalign 1.
|
|
yoffset -7
|
|
else:
|
|
yalign .5
|
|
|
|
add "interface/achievements/glass_selected.webp" pos (6, 6)
|
|
|
|
add gui.format("interface/achievements/{}/highlight.webp") pos (112, 375)
|
|
add gui.format("interface/achievements/{}/spacer.webp") pos (120, 398)
|
|
hbox:
|
|
spacing 5
|
|
xalign 0.5
|
|
text current_item_data.name ypos 380 size 16 xoffset 45
|
|
if current_item_unlocked:
|
|
add "interface/unlocked_True.webp" xoffset 45 ypos 377
|
|
else:
|
|
add "interface/unlocked_False.webp" xoffset 45 ypos 377
|
|
hbox:
|
|
pos (132, 407)
|
|
xsize 410
|
|
if current_item_unlocked or not current_item_data.secret:
|
|
text current_item_data.description size 12
|
|
else:
|
|
text "???" size 12
|
|
|
|
# Category styles
|
|
style achievements_categories_button is empty:
|
|
xysize (195, 16)
|
|
|
|
style dark_achievements_categories_button:
|
|
hover_background "interface/achievements/gray/highlight_left.webp"
|
|
selected_background "interface/achievements/gray/highlight_left.webp"
|
|
|
|
style light_achievements_categories_button:
|
|
hover_background "interface/achievements/gold/highlight_left.webp"
|
|
selected_background "interface/achievements/gold/highlight_left.webp"
|
|
|
|
style achievements_categories_button_text is text:
|
|
xalign 0.5
|
|
outlines []
|
|
|
|
# style dark_achievements_categories_button_text:
|
|
# take dark_button_text
|
|
|
|
# style light_achievements_categories_button_text:
|
|
# take light_button_text
|
|
|
|
# Filter styles
|
|
style achievements_filters_button is empty:
|
|
xysize (195, 32)
|
|
|
|
style dark_achievements_filters_button:
|
|
hover_background "#7d75aa40"
|
|
|
|
style light_achievements_filters_button:
|
|
hover_background "#e3ba7140"
|
|
|
|
style achievements_filters_button_text is default:
|
|
align (0.5, 0.5)
|
|
size 12
|
|
outlines []
|