update to MU6

pull/71/head
Nio 1 year ago
parent 8f6393ab79
commit d59f59ca88
  1. BIN
      android-icon_foreground.png
  2. BIN
      android-presplash.jpg
  3. 10
      game/gui.rpy
  4. BIN
      game/images/animations/fang tail.webm
  5. BIN
      game/images/cgs/wounds01.jpg
  6. BIN
      game/images/cgs/wounds02.jpg
  7. BIN
      game/images/cgs/wounds03.jpg
  8. BIN
      game/images/cgs/wounds04.jpg
  9. BIN
      game/images/cgs/wounds05.jpg
  10. BIN
      game/images/cgs/wounds06.jpg
  11. BIN
      game/images/cgs/wounds07.jpg
  12. BIN
      game/images/cgs/wounds08.jpg
  13. BIN
      game/images/cgs/wounds09.jpg
  14. 54
      game/mods/README.md
  15. 11
      game/mods_example/template/chapter2_redo.rpy
  16. BIN
      game/mods_example/template/img/sample.png
  17. 15
      game/mods_example/template/storyline_ex.rpy
  18. 9
      game/options.rpy
  19. 159
      game/screens.rpy
  20. 75
      game/script.rpy
  21. 20
      game/script/10.an-excellent-reason-to-start-abusing-mod-powers.rpy
  22. 2
      game/script/2.fourth-day-of-school.rpy
  23. 6
      game/script/5.fang-and-anon-cut-class-to-talk-on-the-roof.rpy
  24. 334
      game/src/cg_gallery.rpy
  25. 69
      game/src/mod_menu.rpy
  26. 2
      game/storyline.rpy

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

@ -30,7 +30,7 @@ define gui.idle_color = '#D5D507'
## The small color is used for small text, which needs to be brighter/darker to
## achieve the same effect.
define gui.idle_small_color = '#0001FF'
define gui.idle_small_color = '#00E1FF'
## The color that is used for buttons and bars that are hovered.
define gui.hover_color = '#00FF03'
@ -121,11 +121,9 @@ define gui.textbox_yalign = 1.0
## The placement of the speaking character's name, relative to the textbox.
## These can be a whole number of pixels from the left or top, or 0.5 to center.
define gui.name_xpos = 350
define gui.name_xpos = 395 #350
define gui.name_ypos = -85
define gui.name_large_xpos = 395
## The horizontal alignment of the character's name. This can be 0.0 for left-
## aligned, 0.5 for centered, and 1.0 for right-aligned.
define gui.name_xalign = 0.5
@ -447,14 +445,14 @@ init python:
## Font sizes.
gui.text_size = 44
gui.name_text_size = 48
gui.name_text_size = 46
gui.notify_text_size = 38
gui.interface_text_size = 45
gui.button_text_size = 45
gui.label_text_size = 51
## Namebox
gui.name_xpos = 345
gui.name_xpos = 395
gui.name_ypos = -85
## Adjust the location of the textbox.

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

@ -0,0 +1,54 @@
The game loads an alternate storyline.rpy, this allows you to control the flow of the game's storytelling
Examples include:
- You want to inject more stuff inbetween chapters, maybe you hate time skip writing
- You want to have more of an after story kind of ordeal, for example expanding Ending 2
- You want to replace the entire story route
You can still call the vanilla game's chapters like the intro (call chapter_1) for example but you might want to either copy the vanilla scripts and mix in your edits to have full control
You will need to learn bit of Ren'Py & bit of actual Python anyways but you don't have to think too hard in learning anything new other than familiarizing with this game's script.rpy's already defined Character objects and images, you can freely ignore most of the UI and so on for the inexperienced but passionate artist and/or writer.
Textbox limitation: ~300 characters / four lines, the maximum in the vanilla game's script is around roughly ~278 and that only barely overflows to four lines, so <200 characters / three lines of text should be fine.
--- Ideal file structure of your mod ---
In the root of the mods folder:
folder_of_your_mod_name
- name_of_storyline.rpy
-> asset_folder
- asset.png
-> script_folder
- script.rpy
name_of_storyline.rpy
```
init python:
# Modding Support variables
# All mod rpy files must have title of their mod (this shows up on a button)
# and finally the label that controls the flow of dialogue
mod_menu_access += [{
'Name': "Mod Name",
'Label': "mod_storyline"
}];
image template_sample = Image("mods/folder_of_your_mod_name/asset_folder/asset.png")
label mod_storyline:
call chapter_1_new
```
script_folder/script.rpy
```
label chapter_1_new:
show template_sample at scenter
"Sample Text"
hide template_sample
play music 'audio/OST/Those Other Two Weirdos.ogg'
show anon neutral flip at aright with dissolve
A "Sample Text"
return
```
The funny thing is I don't even like 'fanfictions' to begin with but this mod support allows these 'fanfictions', ironic.

@ -0,0 +1,11 @@
label chapter_2_new:
show template_sample at scenter
"Sample Text"
hide template_sample
play music 'audio/OST/Those Other Two Weirdos.ogg'
show anon neutral flip at aright with dissolve
A "Sample Text"
return

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

@ -0,0 +1,15 @@
init python:
# Modding Support variables
# All mod rpy files must have title of their mod (this shows up on a button)
# and finally the label that controls the flow of dialogue
mod_menu_access += [{
'Name': "Example Mod Name",
'Label': "storyline_ex"
}];
image template_sample = Image("mods_example/template/img/sample.png")
label storyline_ex:
call chapter_2_new

@ -23,7 +23,7 @@ define gui.show_name = True
## The version of the game.
define config.version = "Patchy-patch5.1.1"
define config.version = "Monster-Update-6"
## Text that is placed on the game's about screen. Place the text between the
## triple-quotes, and leave a blank line between paragraphs.
@ -83,7 +83,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.
@ -191,6 +191,11 @@ init python:
build.classify('**/#**', None)
build.classify('**/thumbs.db', None)
# Do not include mod_examples as part of the build process
build.classify('game/mods_example/**', None)
build.classify('game/mods_example/.**', None)
## To archive files, classify them as 'archive'.
# build.classify('game/**.png', 'archive')

@ -1,20 +1,24 @@
###Updater Python stuff###
###Updater Python stuff###
init python:
if persistent.updateresult is None:
persistent.updateresult = "No new version is available"
if persistent.autoup is None:
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
pendingVersion = updater.UpdateVersion(persistent.updateWebServer, check_interval=5)
if pendingVersion == None or pendingVersion == config.version or "TEST" in pendingVersion:
persistent.updateresult = "No new version is available"
else:
persistent.updateresult = pendingVersion
if renpy.variant("pc"): #Don't run this on mobile, not supported
if persistent.updateresult is None:
persistent.updateresult = "No new version is available"
if persistent.autoup is None:
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
pendingVersion = updater.UpdateVersion(persistent.updateWebServer, check_interval=5)
if pendingVersion == None or pendingVersion == config.version or "TEST" in pendingVersion:
persistent.updateresult = "No new version is available"
else:
persistent.updateresult = pendingVersion
def ToggleAutoUpdate():
persistent.autoup = not persistent.autoup
################################################################################
## Initialization
@ -44,7 +48,7 @@ style gui_text:
style button:
properties gui.button_properties("button")
activate_sound "audio/ui/uiClick.wav"
activate_sound "audio/ui/uiClick.wav"
style button_text is gui_text:
properties gui.text_properties("button")
@ -120,7 +124,7 @@ screen say(who, what):
id "window"
if who is not None:
background Image("gui/textbox.png", xalign=0.5, yalign=1.0)
background Image("gui/textbox_long.png", xalign=0.5, yalign=1.0)
window:
id "namebox"
style "namebox"
@ -130,7 +134,6 @@ screen say(who, what):
text what id "what"
## If there's a side image, display it above the text. Do not display on the
## phone variant - there's no room.
if not renpy.variant("small"):
@ -164,9 +167,6 @@ style namebox:
xpos gui.name_xpos
ypos gui.name_ypos
style namebox_large is namebox:
xpos gui.name_large_xpos
style say_label:
properties gui.text_properties("name", accent=True)
xalign gui.name_xalign
@ -281,22 +281,21 @@ screen quick_menu():
## Ensure this appears on top of other screens.
zorder 100
if quick_menu:
window:
background "gui/namebox.png"
xpos 1.45
ypos 0.977
grid 1 4:
style_prefix "quick"
xalign -0.005
yalign 0.010
use quick_buttons("gui/button/uioptionbuttons/template_idle.png", \
[ \
[ "Skip", Skip() ], \
[ "Save", ShowMenu('save') ], \
[ "Auto", Preference("auto-forward", "toggle") ], \
[ "Load", ShowMenu('load') ] \
] )
window:
xpos 1.45
ypos 0.977
vbox:
style_prefix "quick"
xalign -0.005
yalign 0.010
use quick_buttons("gui/button/uioptionbuttons/template_idle.png",
[
[ "Skip", Skip() ],
[ "Save", ShowMenu('save') ],
[ "Auto", Preference("auto-forward", "toggle") ],
[ "Load", ShowMenu('load') ]
] )
screen score_menu():
zorder 100
@ -401,7 +400,7 @@ screen main_menu_button(filename, label, function):
ymaximum 129
action function
fixed:
add filename xalign 0.5 yalign 0.5 zoom 1
add filename xalign 0.5 yalign 0.5 zoom 1 xanchor 0 xcenter 0.5 ycenter 0.5
text label xalign 0.5 yalign 0.5 xanchor 0.5
# label_functions is [ [ "label", function() ], [ "foobar", foobar() ], .. ]
@ -434,16 +433,17 @@ screen main_menu():
else:
add "gui/snootgame.png"
vbox:
spacing 25
spacing 10
xpos 1885
yalign 0.9
ypos 1130
use main_menu_buttons("gui/button/menubuttons/template_idle.png",
[ \
[ "Start", Start() ], \
[ "Load", ShowMenu("load") ], \
[ "Options", ShowMenu("preferences") ], \
[
[ "Start", Start() ],
[ "Mods", ShowMenu("mod_menu") ],
[ "Load", ShowMenu("load") ],
[ "Options", ShowMenu("preferences") ],
[ "Extras", ShowMenu("extras") ], \
[ "Quit", Quit(confirm=not main_menu) ] \
[ "Quit", Quit(confirm=not main_menu) ]
] )
on "show" action renpy.start_predict_screen("cg_gallery")
@ -666,34 +666,40 @@ screen updates():
xoffset 80
xmaximum 1100
label "[config.name!t]"
text _("Version [config.version!t]\n")
text _("Version [config.version!t]")
if updater.can_update():
label _("{color=#00FF00}Update directory exists, updating is possible!{/color}")
else:
label _("{color=#FF0000}Update directory does not exist or is corrupt!{/color}")
textbutton _("Enable Automatic Updates") action [Notify("Toggling Automatic Updates..."), ToggleVariable("persistent.autoup", True, False)]
text _("Automatic Updates: [persistent.autoup!t]\n")
textbutton _("Check for Update!") activate_sound "audio/ui/uiRollover.wav" action [Notify("Checking for update..."), Function(UpdateCheck)]
label _("Update Check Result:\n")
text _("[persistent.updateresult!t]\n")
if persistent.updateresult != "No new version is available":
textbutton _("Update Now!") activate_sound "audio/ui/uiNotification.wav" action [updater.Update(persistent.updateWebServer, force=False)]
label _("{color=#00FF00}{size=32}Update directory exists, updating is possible!\n{/size}{/color}")
else:
textbutton _("Update Now!") activate_sound "audio/ui/uiBack.wav" action [Notify("Nothing to update to!")]
label _("Update Server:\n")
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:
default "[persistent.updateWebServer!t]" size 24 color '#FFFFFF'
input:
default "[persistent.updateWebServer!t]" size 36 color '#FFFFFF'
value FieldInputValue(persistent, 'updateWebServer')
length 49
copypaste True
else:
text persistent.updateWebServer size 24 color '#FFFF00'
text persistent.updateWebServer size 36 color '#FFFF00'
action ToggleScreenVariable('input_on')
style_prefix "quick"
if persistent.updateresult != "No new version is available":
textbutton _("{size=36}Update Now!\n{/size}") activate_sound "audio/ui/uiNotification.wav" action [updater.Update(persistent.updateWebServer, force=False)]
else:
textbutton _("{size=36}Update Now!\n{/size}") activate_sound "audio/ui/uiBack.wav" action [Notify("Nothing to update to!")]
use extrasnavigation
## Load and Save screens #######################################################
@ -1144,7 +1150,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") ]
] )
@ -1619,8 +1625,8 @@ style pref_vbox:
screen quick_button(filename, label, function):
variant "small"
button:
xmaximum 180
ymaximum 100
xmaximum 124
ymaximum 124
action function
fixed:
add filename xalign 0.5 yalign 0.5 zoom 1.75
@ -1631,6 +1637,7 @@ screen quick_menu():
zorder 100
if quick_menu:
hbox:
spacing 28
style_prefix "quick"
xalign 0.5
yalign 0.975
@ -1642,6 +1649,28 @@ screen quick_menu():
[ "Menu", ShowMenu() ] \
] )
screen extrasnavigation(): #Updates are removed (not even supported by Ren'Py)
variant "small"
vbox:
xpos 1940
yalign 0.03
if persistent.splashtype == 1:
add "gui/sneedgame.png"
else:
add "gui/snootgame.png"
vbox:
spacing 25
xpos 1885
yalign 0.9
use main_menu_buttons("gui/button/menubuttons/template_idle.png",
[
[ "Help", ShowMenu("help") ],
[ "About", ShowMenu("about") ],
[ "Gallery", ShowMenu("cg_gallery_0") ],
[ "Return", ShowMenu("main_menu") ]
] )
style radio_button:
variant "small"
foreground "gui/phone/button/radio_[prefix_]foreground.png"

@ -13,17 +13,23 @@
#Why yes all my code was formerly in one massive file called "script" thats 28k lines long, how could you tell?
#Licensed under the GNU AGPL v3, for more information check snootgame.xyz or the LICENSE file that should have came with this work.
init -1 python:
# Modding Support variables
# All mod rpy files must run a small init python script
mod_dir = "mods/";
mod_menu_access = [];
init python:
import random
import webbrowser
#function for insult layers
def showCG():
import random
import webbrowser
#function for insult layers
def showCG():
files = ["text0", "text1", "text2", "text3", "text4", "text5", "text6", "text7", "text8", "text9"]
length = len(files)
picked = random.randint(0,length - 1)
fileName = files[picked]
renpy.show(fileName, at_list=[randPosition])
if persistent.scroll == True:
if persistent.scroll == True:
config.keymap['dismiss'].append('mousedown_4')
transform randPosition:
@ -80,40 +86,35 @@ transform randPosition:
# attribute guitar:
# "guitar.webp"
#Raw Image & kwargs for long textboxes
define long_textbox_img = Image("gui/textbox_long.png", xalign=0.5, yalign=1.0)
define long_textbox = { "window_background": long_textbox_img, 'namebox_style': "namebox_large" }
#Characters
define A = Character ('Anon',color="#36E12D") #Light Green
define F = Character ('Fang',color="#7E2DE1") #Purple
define Lucy = Character ('Lucy',color="#7E2DE1") #Purple
define Ro = Character ('Rosa',color="#E12D36") #Red
define St = Character ('Stella',color="#E17E2D") #orang
define N = Character ('Naomi',color="#2D36E1") #Blue
define Nas = Character ('Naser',color="#501D5E") #Dark Purple
define T = Character ('Trish',color="#8A0036") #Maroon
define Attendant = Character ('Attendant',color="#8A0036") #Maroon
define Sp = Character ('Spears',color="#7B8A00") #Dark Yellow
define Re = Character ('Reed',color="#368A00") #Dark Green
define D = Character ('Driver',color="#098A00")
define FM = Character ('Fangs Mom',color="#EA1A84")
define FD = Character ('Fangs Dad',color="#1A1CEA")
define Tsuki = Character ('Mr. Tsuki',color="#CEAF23")
define unknown = Character ('(???)',color="#000000")
define jingo = Character ('Mr. Jingo',color="#42C053")
define MaitD = Character ('Maitre D',color="#42C053")
define Moe = Character('Moe',color="#42C053")
define Vince = Character ('Vince',color="#3C770D") #Dark Green
define Waitress = Character ('Waitress',color="#C89B19") #Gold
define A = Character ('Anon',color="#36E12D", who_outlines=[(1, '#0C300A')]) # Light Green
define F = Character ('Fang',color="#B4D4CE", who_outlines=[(1, '#112D27')]) # Light Cyan
define Lucy = Character ('Lucy',color="#B4D4CE", who_outlines=[(1, '#112D27')]) # Light Cyan
define Ro = Character ('Rosa',color="#FE712B", who_outlines=[(1, '#3D1809')]) # Red-Orange
define St = Character ('Stella',color="#D2FFAA", who_outlines=[(1, '#203011')]) # Light Green
define N = Character ('Naomi',color="#F8B9A0", who_outlines=[(1, '#291A1B')]) # Peach
define Nas = Character ('Naser',color="#F89E38", who_outlines=[(1, '#2D2D2D')]) # Orange
define T = Character ('Trish',color="#B675E6", who_outlines=[(1, '#1F0632')]) # Purple
define Attendant = Character ('Attendant',color="#8A0036", who_outlines=[(1, '#FFFFFF')]) # Maroon
define Sp = Character ('Spears',color="#C4C3C3", who_outlines=[(1, '#272727')]) # Light Grey
define Re = Character ('Reed',color="#ED4C5B", who_outlines=[(1, '#361013')]) # Bright Red
define D = Character ('Driver',color="#FFC63A", who_outlines=[(1, '#4D280A')]) # Yellow-Orange
define FM = Character ('Fangs Mom',color="#FFD8F6", who_outlines=[(1, '#361730')]) # Bright Pink
define FD = Character ('Fangs Dad',color="#D8A09A", who_outlines=[(1, '#190E0F')]) # Desaturated Orange
define Tsuki = Character ('Mr. Tsuki',color="#A7F2A2", who_outlines=[(1, '#320E3B')]) # Pear Green
define unknown = Character ('(???)',color="#000000", who_outlines=[(1, '#FFFFFF')]) # Black
define jingo = Character ('Mr. Jingo',color="#CD8283", who_outlines=[(1, '#0F0D49')]) # Desaturated Red
define MaitD = Character ('Maitre D',color="#241630", who_outlines=[(1, '#241630')]) # Cobalt Blue
define Moe = Character('Moe',color="#A5BEED", who_outlines=[(1, '#342210')]) # Desaturated Blue
define Vince = Character ('Vince',color="#FFC63A", who_outlines=[(1, '#4D280A')]) # Yellow-Orange
define Waitress = Character ('Waitress',color="#F691C8", who_outlines=[(1, '#402E3A')]) # Pink
#long TB chars
define AnonAndFang = Character('Anon and Fang',color="34F313", **long_textbox)
define SV = Character ('Street Vendor',color="#420046", **long_textbox)
define carl = Character ('Mr. Carldewskii',color="#4963A5", **long_textbox)
define Drf = Character ('Dr. Fernsworth',color="#4963A5", **long_textbox)
define FRT = Character ('Fang Reed & Trish',color="#4963A5", **long_textbox)
define AnonAndFang = Character('Anon and Fang',color="72DFA8", who_outlines=[(1, '#113623')])
define SV = Character ('Street Vendor',color="#F8E120", who_outlines=[(1, '#361504')])
define carl = Character ('Mr. Carldewskii',color="#E19E40", who_outlines=[(1, '#03223B')])
define Drf = Character ('Dr. Fernsworth',color="#253354", who_outlines=[(1, '#334573')])
define FRT = Character ('Fang Reed & Trish',color="#4963A5", who_outlines=[(1, '#FFFFFF')])
#Extra image translations
#siloettes
@ -303,7 +304,7 @@ label splashscreen:
UpdateCheck()
if persistent.updateresult != "No new version is available":
updater.update(persistent.updateWebServer, force=True)
stop sound
return

@ -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

@ -1244,7 +1244,7 @@ label chapter_2:
A "Huh?"
Re "Get your phone out man… Look up {color=#66cc33}'LW_S9znpklI'{/color}.."
Re "Get your phone out man… Look up {color=#66cc33}'T9nXyUye3pg'{/color}.."
A "How did you say that out loud?"

@ -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,292 @@
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/"
# GALLERY OBJECT
# Handles unlockables via ren'py
g = Gallery()
g.transition = dissolve
g.locked_button = NOT_UNLOCKED_COVER
# 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 = []
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
"""
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 = []
# 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])
return
for cp in CG_PATHS:
for ext in ACCEPTED_EXTENSIONS:
path = cp['path']
_str = path+str+"."+ext
# 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)
if renpy.loadable(_str): #brute force
image = renpy.image_size(Image(_str))
return { "x": x, "y": y }
gallery_dic[cp['name']] += [{
"item": str,
"fn": _str,
"cg": cg(_str, ext, image[0]),
"ext": ext,
"wh": image
}]
return
# Call to loading the gallery
loadGallery()
## CG Gallery screen ########################################################
## A screen that shows the image gallery
screen cg_gallery():
# 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:
items = len(galleryItems)
galleryRows = (items / GALLERY_COLS) + 1
extraSpaces = GALLERY_COLS - (items % GALLERY_COLS)
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
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
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
hbox:
style_prefix "quick"
xalign 0.5
yalign 0.975
if (ALLOW_ZOOM) and renpy.variant("small"):
use quick_buttons("gui/button/uioptionbuttons/template_idle.png",
[
[ "+", zoom_a_f ],
[ "-", zoom_b_f ],
[ "Return", zoom_b_f ]
] )
else:
use quick_buttons("gui/button/uioptionbuttons/template_idle.png",
[
[ "Return", _origin ]
] )

@ -0,0 +1,69 @@
# Mod Menu screen ############################################################
##
## Handles jumping to the mods scripts
## Could be more lean but if this is going to one of last time I touch the UI,
## then fine by me
##
#similar to quick_button funcs
screen mod_menu_button(filename, label, function):
button:
xmaximum 600
ymaximum 129
action function
fixed:
add filename xalign 0.5 yalign 0.5 zoom 0.9
text label xalign 0.5 yalign 0.5 xanchor 0.5 size 34
# arr is [{
# 'Name': string (name that appears on the button)
# 'Label': string (jump label)
# }, { .. } ]
# Reuse the same image string and keep things 'neat'.
screen mod_menu_buttons(filename, arr):
for x in arr:
use mod_menu_button(filename, x['Name'], Start(x['Label']))
screen mod_menu():
tag menu
style_prefix "main_menu"
add gui.main_menu_background
frame:
xsize 420
yfill True
background "gui/overlay/main_menu.png"
#side_yfill True
vbox:
xpos 1940
yalign 0.03
if persistent.splashtype == 1:
add "gui/sneedgame.png"
else:
add "gui/snootgame.png"
viewport:
# this could be better but its ok for now
xpos 1885-540
xmaximum 540
ymaximum 0.8
ypos 200
yinitial 0
scrollbars "vertical"
mousewheel True
draggable True
pagekeys True
vbox:
#xpos 1885
spacing 18
#yalign 0.98
#buttons are messed up but that's ok
use mod_menu_button("gui/button/menubuttons/template_idle.png", "Return", ShowMenu("main_menu"))
if len(mod_menu_access) is not 0:
use mod_menu_buttons("gui/button/menubuttons/template_idle.png", mod_menu_access )
else:
use mod_menu_button("gui/button/menubuttons/template_idle.png", "You have no mods", None)

@ -58,4 +58,4 @@ label ending:
if tradwife:
scene c10 with fade
pause 20
return
return

Loading…
Cancel
Save