diff --git a/game/images/animations/fangtail.webm b/game/images/animations/fang tail.webm similarity index 100% rename from game/images/animations/fangtail.webm rename to game/images/animations/fang tail.webm diff --git a/game/images/cgs/wounds1.jpg b/game/images/cgs/wounds01.jpg similarity index 100% rename from game/images/cgs/wounds1.jpg rename to game/images/cgs/wounds01.jpg diff --git a/game/images/cgs/wounds2.jpg b/game/images/cgs/wounds02.jpg similarity index 100% rename from game/images/cgs/wounds2.jpg rename to game/images/cgs/wounds02.jpg diff --git a/game/images/cgs/wounds3.jpg b/game/images/cgs/wounds03.jpg similarity index 100% rename from game/images/cgs/wounds3.jpg rename to game/images/cgs/wounds03.jpg diff --git a/game/images/cgs/wounds4.jpg b/game/images/cgs/wounds04.jpg similarity index 100% rename from game/images/cgs/wounds4.jpg rename to game/images/cgs/wounds04.jpg diff --git a/game/images/cgs/wounds5.jpg b/game/images/cgs/wounds05.jpg similarity index 100% rename from game/images/cgs/wounds5.jpg rename to game/images/cgs/wounds05.jpg diff --git a/game/images/cgs/wounds6.jpg b/game/images/cgs/wounds06.jpg similarity index 100% rename from game/images/cgs/wounds6.jpg rename to game/images/cgs/wounds06.jpg diff --git a/game/images/cgs/wounds7.jpg b/game/images/cgs/wounds07.jpg similarity index 100% rename from game/images/cgs/wounds7.jpg rename to game/images/cgs/wounds07.jpg diff --git a/game/images/cgs/wounds8.jpg b/game/images/cgs/wounds08.jpg similarity index 100% rename from game/images/cgs/wounds8.jpg rename to game/images/cgs/wounds08.jpg diff --git a/game/images/cgs/wounds9.jpg b/game/images/cgs/wounds09.jpg similarity index 100% rename from game/images/cgs/wounds9.jpg rename to game/images/cgs/wounds09.jpg diff --git a/game/options.rpy b/game/options.rpy index 7c99856..1f158c7 100644 --- a/game/options.rpy +++ b/game/options.rpy @@ -77,7 +77,7 @@ define config.exit_transition = dissolve ## Between screens of the game menu. -define config.intra_transition = dissolve +define config.intra_transition = Dissolve(0.20) ## A transition that is used after a game has been loaded. diff --git a/game/screens.rpy b/game/screens.rpy index c2ec861..53bb0a1 100644 --- a/game/screens.rpy +++ b/game/screens.rpy @@ -6,7 +6,7 @@ init python: persistent.autoup = False if persistent.updateWebServer is None: persistent.updateWebServer = "http://updates.snootgame.xyz/updates.json" - + def UpdateCheck(): # WHY YES I ONLY ALLOW PEOPLE USING MY FRAMEWORK TO CHECK FOR AN UPDATE EVERY SIX FUCKING HOURS HOW DID YOU KNOW # NOPE check_interval=5 (5 SECONDS) FUCK YOU @@ -673,22 +673,22 @@ screen updates(): label _("{color=#00FF00}{size=32}Update directory exists, updating is possible!\n{/size}{/color}") else: label _("{color=#FF0000}{size=32}Update directory does not exist or is corrupt!\n{/size}{/color}") - + label _("Auto Update:") label _("{color=#FFFFFF}{size=32}Automatic Updates: [persistent.autoup!t]{/size}{/color}") textbutton _("{size=36}Toggle Automatic Updates\n{/size}") action [Notify("Toggling Automatic Updates..."), Function(ToggleAutoUpdate)] - + label _("Update Checker:") label _("{color=#FFFFFF}{size=32}[persistent.updateresult!t]{/size}{/color}") textbutton _("{size=36}Check for Update\n{/size}") action [Notify("Checking for update..."), Function(UpdateCheck)] - + label _("Updater:") label _("{color=#FFFFFF}{size=32}Server URL (click to edit):{/size}{/color}") default input_on = False button: key_events True if input_on: - input: + input: default "[persistent.updateWebServer!t]" size 36 color '#FFFFFF' value FieldInputValue(persistent, 'updateWebServer') length 49 @@ -701,7 +701,7 @@ screen updates(): textbutton _("{size=36}Update Now!\n{/size}") action updater.Update(persistent.updateWebServer, force=False) else: textbutton _("{size=36}Update Now!\n{/size}") action Notify("Nothing to update to!") - + use extrasnavigation ## Load and Save screens ####################################################### @@ -1146,7 +1146,7 @@ screen extrasnavigation(): [ "Help", ShowMenu("help") ], [ "About", ShowMenu("about") ], [ "Updates", ShowMenu("updates") ], - [ "Gallery", ShowMenu("cg_gallery") ], + [ "Gallery", ShowMenu("cg_gallery_0") ], [ "Return", ShowMenu("main_menu") ] ] ) diff --git a/game/script/10.an-excellent-reason-to-start-abusing-mod-powers.rpy b/game/script/10.an-excellent-reason-to-start-abusing-mod-powers.rpy index ed860e1..8b23884 100644 --- a/game/script/10.an-excellent-reason-to-start-abusing-mod-powers.rpy +++ b/game/script/10.an-excellent-reason-to-start-abusing-mod-powers.rpy @@ -115,32 +115,32 @@ label chapter_10: A "...Fine..." - scene wounds1 with fade + scene wounds01 with fade pause 2 scene black with fade "I step into my tiny shower stall and turn on the water." "The shower head sputters before it starts weakly spraying lukewarm water." - scene wounds2 with fade + scene wounds02 with fade "The temperature of the water doesn’t help the tension in my muscles or the bruises marring my skin." "I stretch around and see massive blotches of purple and black splattered across my torso." - scene wounds3 + scene wounds03 "Each contusion is hot to the touch under my fingers and the pain is intense." - scene wounds4 + scene wounds04 "The worst is across my chest where the bollard hit me." - scene wounds5 + scene wounds05 "I eventually get finished examining my wicked wounds and step out of the bathroom. Fang is on her phone doing Raptor Jesus knows what." - scene wounds6 + scene wounds06 "Fang then pats the bed" @@ -148,7 +148,7 @@ label chapter_10: "I walk over and lie down on my stomach" - scene wounds7 + scene wounds07 F "Jesus that's bad..." @@ -193,11 +193,11 @@ label chapter_10: A "Hm?" F "I need to do the front." - scene wounds8 + scene wounds08 "Oh." "Okay then. I roll over onto my back." - scene wounds9 + scene wounds09 "And find myself face to beak with her." "Dangerously close." @@ -350,4 +350,4 @@ label chapter_10: stop music fadeout 1.0 "..." - return \ No newline at end of file + return diff --git a/game/script/5.fang-and-anon-cut-class-to-talk-on-the-roof.rpy b/game/script/5.fang-and-anon-cut-class-to-talk-on-the-roof.rpy index d852480..4245468 100644 --- a/game/script/5.fang-and-anon-cut-class-to-talk-on-the-roof.rpy +++ b/game/script/5.fang-and-anon-cut-class-to-talk-on-the-roof.rpy @@ -288,7 +288,7 @@ label chapter_5: label movie: A "FANG!" stop music fadeout 1.0 - image fang tail = Movie(play="animations/fangtail.webm",loop=True) + image fang tail = Movie(play="animations/fang tail.webm",loop=True) scene fang tail with fade @@ -2547,3 +2547,7 @@ label chapter_5: "..." return + +label fang_movie: + scene fang tail with fade + "" diff --git a/game/src/cg_gallery.rpy b/game/src/cg_gallery.rpy index 8afdf17..0ee6b28 100644 --- a/game/src/cg_gallery.rpy +++ b/game/src/cg_gallery.rpy @@ -1,100 +1,285 @@ init python: # CONST PARAMS + ALLOW_ZOOM = False GALLERY_COLS = 3 - GALLERY_CGS_PER_PAGE = 6 PREFERRED_WIDTH = 432 #px (1920 * 0.225) PREFERRED_HEIGHT = 243 #px (1080 * 0.225) + PREFERRED_ASPECT_RATIO = 16.0/9.0 # 1.7777.. DEFAULT_WIDTH_SCALE_RATIO = round(float(PREFERRED_WIDTH) / float(1920), 4) DEFAULT_HEIGHT_SCALE_RATIO = round(float(PREFERRED_HEIGHT) / float(1080), 4) NOT_UNLOCKED_COVER = im.FactorScale("gui/gallery/unlocked_cg_button_cover.png", DEFAULT_WIDTH_SCALE_RATIO, DEFAULT_HEIGHT_SCALE_RATIO) - ACCEPTED_EXTENSIONS = ["jpg", "png"] - CG_PATHS = "images/cgs/" + ACCEPTED_EXTENSIONS = ["jpg", "webm"] + CG_PATHS = [ + #CG doesn't really make sense + { 'path': "images/cgs/", 'name': "CG", 'eval': None }, + { 'path': "images/animations/", 'name': "Animations", 'eval': None }, + { 'path': "images/NotForKids!/", 'name': "Lewd", + 'eval': 'persistent.lewd == True' + } + ] + #path: folder, name: shows up in gallery, eval: runs eval() on string - # GALLERY OBJECT - # Handles unlockables via ren'py - g = Gallery() - g.transition = dissolve - g.locked_button = NOT_UNLOCKED_COVER + """ + Data structure that holds the data for each cg and button + item is name, fn is fullpath + ext is the file extension + { item: str; fn: str; cg: Displayable; ext: str; wh: [] }[] + (reference in this init python, actually used in screens) + """ + gallery_items = [] - # GALLERY ITEMS - # Data structure that holds the data for each cg and button - # item is the key in the Gallery - # ext is the file extension - # { item: string; cg: Displayable; ext: string }[] - galleryItems = [] + # key dict pair, cg <-> cgs' galleryitems [] + gallery_dic = {} # + for cp in CG_PATHS: + gallery_dic[cp['name']] = [] # # Make a scaled cg button - # (cg: string; ext: string; w: float; h: float; unlocked?: boolean): Displayable - def cg(fname, ext, w, h): - scaleFactor = getBoxNormalizerRatio(w, h) - return im.FactorScale(CG_PATHS + fname + "." + ext, scaleFactor["x"], scaleFactor["y"], False) - - # Create an object in g:Gallery, add to galleryItems - # (imageName: string; ext: string; w: float; h: float) -> None - def addGalleryItem(imageName, ext, w, h): - g.button(imageName) - g.image(imageName) - - horizontalPan = Pan((w - 1920, h - 1080), (0, h - 1080), 30.0) - verticalPan = Pan((w - 1920, h - 1080), (w - 1920, 0), 30.0) - g.transform(horizontalPan if w > h else verticalPan) #TODO: niceify - - str = "renpy.seen_image('"+imageName+"')" - g.condition(str) - - galleryItems.append({ - "item": imageName, - "cg": cg(imageName, ext, w, h), - "ext": ext - }) - return + # (cg: string; ext: string; w: float + def cg(fname, ext, w): + scale = PREFERRED_WIDTH * 100.0 / w / 100.0 + #scale = box_ratio(wh) + return im.FactorScale(fname, scale, scale, False) # Reads /images/cgs dir for all image files - # Populates g:Gallery and galleryItems - # Appends extra spaces at the end + # Populates galleryItems # () -> None def loadGallery(): list_img = renpy.list_images() +#if ext is "webm": # Add each image to the gallery for str in list_img: - _str = CG_PATHS+str+"."+ACCEPTED_EXTENSIONS[0] - if renpy.loadable(_str): #brute force - image = renpy.image_size(Image(_str)) - addGalleryItem(str, ACCEPTED_EXTENSIONS[0], image[0], image[1]) + for cp in CG_PATHS: + for ext in ACCEPTED_EXTENSIONS: + path = cp['path'] + _str = path+str+"."+ext + + if renpy.loadable(_str): #brute force + image = renpy.image_size(Image(_str)) + + gallery_dic[cp['name']] += [{ + "item": str, + "fn": _str, + "cg": cg(_str, ext, image[0]), + "ext": ext, + "wh": image + }] return - - # Returns what params to call im.FactorScale with for cg button size - # Basically the delta diff dimensions - # (w: int; h: int) -> { x: float; y: float } - def getBoxNormalizerRatio(w, h): - x = round(float(PREFERRED_WIDTH) / float(w), 4) - y = round(float(PREFERRED_HEIGHT) / float(h), 4) - - return { "x": x, "y": y } - # Call to loading the gallery loadGallery() -## CG Gallery screen ######################################################## -## A screen that shows the image gallery -screen cg_gallery(): - python: - items = len(galleryItems) - galleryRows = (items / GALLERY_COLS) + 1 - extraSpaces = GALLERY_COLS - (items % GALLERY_COLS) - tag menu - use game_menu(_("Gallery"), scroll="viewport"): - grid GALLERY_COLS galleryRows: - spacing 8 - for item in galleryItems: -# vbox: -# text item["item"] size 8 - add g.make_button(item["item"], item["cg"], xalign = 0.5, yalign = 0.5) - # Add empty items to fill grid after last cg button - for i in range(0, extraSpaces): - null height 20 + # hard code the webm because renpy is really dumb and doesn't add Movies properly until much later + fang_webm = 'images/animations/fang tail.webm' + gallery_dic['Animations'] = [{ + "item": 'fang tail', + "fn": fang_webm, + "cg": Movie(fang_webm),#cg(_str, 'webm', 1920), + "ext": 'webm', + "wh": [1920, 1080] + }] + #for zooming in and out + zoom_arr = [0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.5, 1.75, 2.0] + + """ + for x in range(1,5): + _zoom = 1.0 + _zoom *= 1+(x*0.25) + zoom_arr.append(_zoom) + + for y in range(9,1,-1): + _zoom = 1.0 + _zoom *= (y*0.125) + zoom_arr.append(_zoom) + + zoom_arr.sort() + """ +""" +'Recursive' / Loopable / Roundtrip Screens +_0 <-> _1 +""" +#There is renpy.restart_interaction but since I wrote all this, it's too late +#screen cg_gallery(flag, __yoffset = 0, origin = 'CG'): +screen cg_gallery_0(__yoffset = 0, origin = 'CG'): + tag menu + use cg_gallery('1', __yoffset, origin) +screen cg_gallery_1( __yoffset = 0, origin = 'CG'): + tag menu + use cg_gallery('0', __yoffset, origin) + +#screen view_image(fn, _origin, zoom=1): +screen view_image_a(fn, _origin, zoom = zoom_arr.index(1.0)): + tag menu + use view_image(fn, _origin, zoom, 'b') +screen view_image_b(fn, _origin, zoom = zoom_arr.index(1.0)): + tag menu + use view_image(fn, _origin, zoom, 'a') + +""" +CG Gallery screen - A screen that shows the image gallery +Basically Gallery Object has terrible defaults, so I just wrote my own stuff +""" +screen cg_gallery(flag, __yoffset = 0, origin = 'CG'): + + if main_menu: + key "game_menu" action ShowMenu("main_menu") + + + frame: + pass + add gui.main_menu_background + add gui.game_menu_background + + tag menu + + python: + empty_spaces = gallery_rows = item_counter = 0 + + gallery_items = gallery_dic[origin] + items = len(gallery_items) + gallery_rows = (items / GALLERY_COLS) + 1 + empty_spaces = GALLERY_COLS - (items % GALLERY_COLS) + + + vbox: + transform: + zoom 0.95 + hbox: + style_prefix "navigation" + xalign 0.5 + + spacing gui.navigation_spacing + + for cp in CG_PATHS: + if cp['name'] == origin: + textbutton _(cp['name']) text_color gui.selected_color text_xalign 0.5 + else: + if cp['eval'] is None: + textbutton _(cp['name']) action ShowMenu('cg_gallery_'+flag, 0, cp['name']) text_xalign 0.5 + elif eval(cp['eval']): + textbutton _(cp['name']) action ShowMenu('cg_gallery_'+flag, 0, cp['name']) text_xalign 0.5 + else: + textbutton _(cp['name']) text_xalign 0.5 + textbutton _("Return") action ShowMenu('main_menu') text_xalign 0.5 + + if _in_replay: + textbutton _("End Replay") action EndReplay(confirm=True) + elif not main_menu: + textbutton _("Main Menu") action MainMenu() + + transform: + zoom 0.95 + xcenter 0.525 + ycenter 0.525 + + viewport: + yinitial __yoffset + scrollbars "vertical" + mousewheel True + draggable True + pagekeys True + xfill True + + grid GALLERY_COLS gallery_rows: + xcenter 0.5 + ycenter 0.5 + for item in gallery_items: + # Should properly fix with actual margin difference but good + # enough or the actual position + python: + item_counter += 1 + yoffset = item_counter / 3 * PREFERRED_HEIGHT * 1.15 + yoffset = int( yoffset + (PREFERRED_HEIGHT * 1.15)) + + use flag_button(item, yoffset, origin) + + for i in range(0, empty_spaces): + null height 20 + + +""" +if/else flow control & extra parameters for Buttons +""" +screen flag_button(item, yoffset, origin): + python: + flag = renpy.seen_image(item['item']) + + if flag: + button: + if item['ext'] == "webm": + action Replay('fang_movie')#ShowMenu('view_movie', item, ShowMenu('cg_gallery_0', yoffset, origin)) + else: + action ShowMenu('view_image_a', item, ShowMenu('cg_gallery_0', yoffset, origin)) + xcenter 0.5 ycenter 0.5 + padding (1,0,1,2) + vbox: + text item["item"] xalign 0.5 + add item["cg"] fit 'contain' xcenter 0.5 ycenter 0.5 size (PREFERRED_WIDTH, PREFERRED_HEIGHT) + else: + vbox: + ymaximum PREFERRED_HEIGHT + xcenter 0.5 ycenter 0.5 + text "? ? ?" xalign 0.5 + add NOT_UNLOCKED_COVER + + +screen view_movie(item, _origin): + tag menu + key "game_menu" action _origin + python: + renpy.movie_cutscene(item['item'], None, -1) + frame: + pass + #scene fang tail with fade + + +""" +view_image, Loads the image in fullscreen with viewport control. +""" +screen view_image(item, _origin, zoom = zoom_arr.index(1.0), flag='a'): + python: + zoom_a = zoom+1 + zoom_a_f = ShowMenu('view_image_'+flag, item, _origin, zoom_a) + zoom_b = zoom-1 + zoom_b_f = ShowMenu('view_image_'+flag, item, _origin, zoom_b) + + tag menu + key "game_menu" action _origin + + # mousewheel & insert+delete + if (ALLOW_ZOOM): + if zoom < len(zoom_arr)-1: #zoom in + key 'mousedown_4' action zoom_a_f + key 'K_INSERT' action zoom_a_f + if zoom > 0: #and (item['wh'][0] <= 1920 or item['wh'][1] <= 1080): + key 'mousedown_5' action zoom_b_f + key 'K_DELETE' action zoom_b_f + + viewport id "vie": + #Ren'Py isn't smart enough to not edgescroll while pressed, + #so we'll have to disable this for mobile + if renpy.variant("pc"): + edgescroll (300, 1800) + draggable True + arrowkeys True + pagekeys True + xfill False + yfill False + add item['fn'] zoom zoom_arr[zoom] anchor (0.55, 0.55) + +#Reuse quick buttons, Ren'Py handles touch input lazy, it doesn't have +#double finger pinch zoom, it translates taps as mouse events - have to use +#buttons + if (ALLOW_ZOOM) and renpy.variant("small"): + hbox: + style_prefix "quick" + xalign 0.5 + yalign 0.975 + use quick_buttons("gui/button/uioptionbuttons/template_idle.png", + [ + [ "+", zoom_a_f ], + [ "-", zoom_b_f ] + ] )