Merge remote-tracking branch 'origin/5.1.1' into 5.1.1
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 246 KiB |
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 199 KiB |
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 266 KiB |
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 214 KiB |
@ -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.
|
||||
|
@ -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") ]
|
||||
] )
|
||||
|
||||
|
@ -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
|
||||
return
|
||||
|
@ -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
|
||||
""
|
||||
|
@ -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 ]
|
||||
] )
|
||||
|