Squashed commit for update 1.3.7

This commit is contained in:
2024-04-21 13:45:17 -05:00
parent 5d02c6fc3f
commit 03524c9360
188 changed files with 7039 additions and 2873 deletions

View File

@ -0,0 +1,21 @@
name: Choreography Problem
about: A template for discussing choreography problems
title: "[Chapter XX]: "
labels:
- bug
- "help wanted"
body:
- type: input
id: where
attributes:
label: On what line did this bug occour?
placeholder: "I \"This shit fucks and sucks!\""
validations:
required: true
- type: textarea
id: what
attributes:
label: "What happened?"
placeholder: "The expression \"Inco Sad\" was used at a time when it shouldn't have been used."
validations:
required: true

View File

@ -30,14 +30,14 @@ steps:
- event: cron
build:
image: openjdk:8
image: openjdk:21-jdk-bookworm
commands:
- apt update
- apt install libgl1 -y
- apt install libgl1 patch -y
- sed -i -e "s/VERSION/${RenpyVersion}/g" game/options.rpy #Change the renpy version to the woodpecker reuqested one.
#Get Renkit
- wget -qO- "https://github.com/kobaltcore/renkit/releases/download/v${RenkitVersion}/renkit-linux-amd64.tar.gz" | tar xz --directory=/tmp/
- /tmp/renconstruct build -i "." -c "renconstruct.toml" -o dist/
- wget -qO- "https://github.com/kobaltcore/renkit/releases/download/v${RenkitVersion}/renkit-x86_64-unknown-linux-gnu.tar.xz" | tar -Jax --directory=/tmp/
- /tmp/renkit-x86_64-unknown-linux-gnu/renconstruct build "." dist/
- mkdir "dist/android"
- mv dist/*.apk "dist/android"
- cd /tmp/
@ -83,6 +83,6 @@ steps:
matrix:
RenpyVersion:
- "8.1.3"
- "8.2.1"
RenkitVersion:
- "3.3.1"
- "4.1.0"

768
LICENSE
View File

@ -1,385 +1,385 @@
The "GNU AFFERO GENERAL PUBLIC LICENSE" as wrote out in the "GNU AFFERO GENERAL PUBLIC LICENSE V3.txt" file applies to all computer software files, source or object code, originating from Cavemanon or its contributors.
The "Cavemanon Affero GPL v3.0 Video Game Store Front Exception v2.0" as wrote out in the "GPL-Exception.txt" file applies to all copyrightable assets originating from Cavemanon or its contributors that come with this software.
The "Attribution-ShareAlike 4.0 International" as wrote out in the "CC-BY-SA-4.0.txt" file applies to all copyrightable audio and image assets originating from Cavemanon or its contributors that is not a computer software file, with the exception of the following assets, which use "Attribution 4.0 International" as wrote out in the "CC-BY-4.0.txt":
-game\images\animations\notagoodtime\anim_notagoodtime_f1.png
-game\images\animations\notagoodtime\anim_notagoodtime_f2.png
-game\images\animations\toilet\anim_toilet.webm
-game\images\animations\toilet\anim_toilet_mask.webm
-game\images\credits\spr_creditsimage_notagoodtime.png
-game\images\credits\spr_creditsimage_miahoe.png
Non-Cavemanon sourced items with attribution clauses
====================================================
--- SOUNDS ---
"S Dissapproval - Alt.wav" by Processaurus
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Processaurus/sounds/440088/
"Rolling Creak.wav" by lukaspearse
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/lukaspearse/sounds/149736/
"Interior Wind Noise_Zoom H6.wav" by omnisounddesign
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/omnisounddesign/sounds/335703/
"Take off - Small pop.wav" by Quistard
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/Quistard/sounds/237753/
"Jet_whoosh.wav" by Benboncan
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Benboncan/sounds/167563/
"Dodgeball_Bounce1.wav" by burnsie289
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/burnsie289/sounds/152414/
"Cracking knuckles.flac" by CGEffex
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/CGEffex/sounds/93981/
"MassiveBlast.wav" by daveincamas
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/daveincamas/sounds/58507/
"Water Swirl, Small, 17.wav" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/398708/
"Splash, Jumping, A" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/352101/
"etl Window 24-96.wav" by cmusounddesign
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/cmusounddesign/sounds/95893/
"elevator 3.wav" by Trautwein
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Trautwein/sounds/262574/
"taking the elevator" by Tomlija
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/Tomlija/sounds/202985/
"Snapping, Wodden Fence, L.wav" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/352196/
"Elastic Band on Tarpaulin" by RICHERlandTV
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/RICHERlandTV/sounds/592262/
"Whip Crack 01.wav" by CGEffex
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/CGEffex/sounds/93100/
"Snow Ball Throw And Splat" by Mike Koenig
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://soundbible.com/632-Snow-Ball-Throw-And-Splat.html
"Power up yells" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/382010/
"female dying scream" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/394610/
"dying female" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/345049/
"Female battle cries/grunts" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/264982/
"ANGRY DOG BARK SNARL flat.wav" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/deleted_user_3424813/sounds/260776/
"WIT8 - pain" by phantastonia
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/phantastonia/sounds/615023/
"Door open and close, close" by Moulaythami
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Moulaythami/sounds/555095/
"mitchellsounds - EXT_spring_light_wind_mourningdove_MS.wav"
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/mitchellsounds/sounds/517941/
"20170618_city.garden.fountain.wav"
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/dobroide/sounds/396277/
--- MUSIC ---
mus_angry.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/HYPER_METAL_/Loyalty_Freak_Music_-_HYPER_METAL__-_06_SUPER_METAL/
author: Loyalty Freak Music
album: HYPER METAL !
songname: SUPER METAL
license: CC0
mus_arcade1.ogg
URL: https://sampleswap.org/mp3/song.php?id=1185
author: benzoul
songname: lovepartyinjapan
license: CC-BY
mus_arcade2.ogg
URL: https://sampleswap.org/mp3/song.php?id=413
author: emanon
songname: 21seiki Techno Shonen
license: CC-BY
mus_awkward.ogg
URL: https://freemusicarchive.org/music/Soft_and_Furious/The_Merfolk_I_Should_Turn_To_Be/Soft_and_Furious_-_The_Merfolk_I_Should_Turn_To_Be_-_08_Hyper_Staying/
author: Soft and Furious
album: The Merfolk I Should Turn To Be
songname: Hyper Staying
license: CC0
mus_ben.ogg
URL: https://freemusicarchive.org/music/koi-discovery/post-morphose/icar-fellmp3/
author: Koi-discovery
album: Post-Morphose
songname: Icar_Fell.mp3
license: CC0
mus_calm2.ogg
URL: https://freemusicarchive.org/music/Komiku/Its_time_for_adventure__vol_2/Komiku_-_Its_time_for_adventure_vol_2_-_08_Dreaming_of_you/
author: Komiku
album: It's time for adventure ! vol 2
songname: Dreaming of you
license: CC0
mus_calm.ogg
URL: https://freemusicarchive.org/music/Soft_and_Furious/The_Merfolk_I_Should_Turn_To_Be/Soft_and_Furious_-_The_Merfolk_I_Should_Turn_To_Be_-_02_Youre_no_good_but_I_love_you/
author: Soft and Furious
album: The Merfolk I Should Turn To Be
songname: You're no good but I love you
license: CC0
mus_casual.ogg
URL: https://freemusicarchive.org/music/holiznacc0/left-overs/even-after-all-these-years/
author: HoliznaCC0
album: Left Overs
songname: Even After All These Years
license: CC0
mus_chill1.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/INSTRUMENTAL_RB_BEATS_TO_SING_OR_RAP_ON/Loyalty_Freak_Music_-_INSTRUMENTAL_RB_BEATS_TO_SING_OR_RAP_ON_-_08_I_care
author: Loyalty Freak Music
album: INSTRUMENTAL R&B BEATS TO SING OR RAP ON
songname: I care
license: CC0
mus_chill2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/busted-guitar-jazz/4-jazz/
author: HoliznaCC0
album: Busted Guitar (JAZZ)
songname: 4 (jazz)
license: CC0
mus_chill3.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/everything-you-ever-dreamed/
author: HoliznaCC0
album: Lo-fi And Chill
songname: Everything You Ever Dreamed.
license: CC0
mus_chill_thinking.ogg
URL: https://freemusicarchive.org/music/holiznacc0/sad-beats/chills/
author: HoliznaCC0
album: Sad Beats
songname: Chills
license: CC0
mus_damien.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/americana-1/
author: HoliznaCC0
album: Rock Montage
songname: Americana 1
license: CC0
mus_general.ogg
URL: https://freemusicarchive.org/music/wax-lyricist/the-wax-lyricist/high-on-loungin/
author: Wax Lyricist
album: The Wax Lyricist
songname: High on Loungin'
license: CC0
mus_happy2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/power-pop/a-small-town-on-pluto-1/
author: HoliznaCC0
album: Power Pop!
songname: A Small Town On Pluto
license: CC0
mus_iadakan.ogg
URL: https://freemusicarchive.org/music/holiznacc0/left-overs/space-3/
author: HoliznaCC0
album: Left Overs
songname: Space!
license: CC0
mus_inco.ogg
URL: https://freemusicarchive.org/music/koi-discovery/cyborg-breakdown/an-ocytocin-problemmp3/
author: Koi-discovery
album: Cyborg Breakdown
songname: An_Ocytocin_Problem.mp3
license: CC0
mus_introspective3
URL: https://freemusicarchive.org/music/Monplaisir/Space_Porn/Monplaisir_-_Space_Porn_-_04_Protect/
author: Monplaisir
album: Space Porn
songname: Protect
license: CC0
mus_melancholy2.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Space_Porn/Monplaisir_-_Space_Porn_-_08_Stargazer/
author: Monplaisir
album: Space Porn
songname: Stargazer
license: CC0
mus_melancholy_introspective.ogg
URL: https://freemusicarchive.org/music/Monplaisir/PIGEONS_ARE_THE_BEST/Monplaisir_-_PIGEONS_ARE_THE_BEST_-_05_Lightbull/
author: Monplaisir
album: PIGEONS ARE THE BEST
songname: Lightbull
license: CC0
mus_melancholy.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/TO_CHILL_AND_STAY_AWAKE/Loyalty_Freak_Music_-_TO_CHILL_AND_STAY_AWAKE_-_06_People_are_spinning/
author: Loyalty Freak Music
album: TO CHILL AND STAY AWAKE
songname: People are spinning
license: CC0
mus_melancholy_olivia.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_02_Far_and_High/
author: Monplaisir
album: Pretty and Invisible
songname: Far and High
license: CC0
mus_mia1.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/punk/
author: HoliznaCC0
album: Rock Montage
songname: Punk
license: CC0
mus_mia2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/grunge/
author: HoliznaCC0
album: Rock Montage
songname: Grunge
license: CC0
mus_misc.ogg
URL: https://freemusicarchive.org/music/holiznacc0/kick-it-laid-back-hiphop/unwind/
author: HoliznaCC0
album: Kick It (laid back HipHop)
songname: Unwind
license: CC0
mus_pissed.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_06_Talentuous_and_Shy/
author: Monplaisir
album: Pretty and Invisible
songname: Talentuous and Shy
license: CC0
mus_rock.ogg
URL: https://freesound.org/people/Jibey-/sounds/572947/
author: Jibey-
songname: Rock music.wav
license: CC-BY
mus_slow.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/ramenmp3/
author: Ramen.mp3
album: Lo-fi And Chill
songname: ramenmp3
license: CC0
mus_thoughts1.ogg
URL: https://freemusicarchive.org/music/Monplaisir/PIGEONS_ARE_THE_BEST/Monplaisir_-_PIGEONS_ARE_THE_BEST_-_01_Jump__Oh_Hi_Mark/
author: Monplaisir
album: PIGEONS ARE THE BEST
songname: Jump ! Oh Hi Mark
license: CC0
mus_thoughts2
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_01_Loved_and_Respected/
author: Monplaisir
album: Pretty and Invisible
songname: Loved and Respected
license: CC0
mus_titlescreen.ogg
URL: https://freemusicarchive.org/music/holiznacc0/be-happy-with-who-you-are/finding-yourself/
author: HoliznaCC0
album: Be Happy With Who You Are
songname: Finding Yourself
license: CC0
mus_trouble.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/TO_CHILL_AND_STAY_AWAKE/Loyalty_Freak_Music_-_TO_CHILL_AND_STAY_AWAKE_-_05_Traveling_in_your_mind/
author: Loyalty Freak Music
album: TO CHILL AND STAY AWAKE
songname: Traveling in your mind
license: CC0
mus_upbeat.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/busted-jazz
author: HoliznaCC0
album: Lo-fi And Chill
songname: Busted Jazz
license: CC0
--- GRAPHICS ---
"The Resort at Pelican Hill" by Ansel Adams
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/prayitnophotography/8468342892/
"Inside 360 Restaurant" by Larry Koester
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/larrywkoester/22976555815/
"Banquet set up - Novotel Century Hong Kong Hotel" by RichardToHKG
LICENSED UNDER ATTRIBUTION 3.0 UNPORTED (CC BY 3.0)
https://commons.wikimedia.org/wiki/File:Banquet_set_up_-_Novotel_Century_Hong_Kong_Hotel.jpg
"Seattle from the Space Needle" by Peter Kaminski
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/peterkaminski/5444827/
"Bar" by fr1da
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/denero188_36624278/2090013005
"Pleading face" and "Crocodile emoji" by Twitter/X
Copyright 2020 Twitter, Inc and other contributors
Graphics licensed under CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/
"Swing" by Julia Koefender
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/juliakoefender/7128081493/
"Kitchen in our Hollywood Hills Hidden Gem apartment - Los Angeles, California, USA" by Glen Bowman
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/glenbowman/18180131123/
"Sunset with yachts near Phuket island, Thailand XOKA2050s" by Phuket@photographer.net
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
The "GNU AFFERO GENERAL PUBLIC LICENSE" as wrote out in the "GNU AFFERO GENERAL PUBLIC LICENSE V3.txt" file applies to all computer software files, source or object code, originating from Cavemanon or its contributors.
The "Cavemanon Affero GPL v3.0 Video Game Store Front Exception v2.0" as wrote out in the "GPL-Exception.txt" file applies to all copyrightable assets originating from Cavemanon or its contributors that come with this software.
The "Attribution-ShareAlike 4.0 International" as wrote out in the "CC-BY-SA-4.0.txt" file applies to all copyrightable audio and image assets originating from Cavemanon or its contributors that is not a computer software file, with the exception of the following assets, which use "Attribution 4.0 International" as wrote out in the "CC-BY-4.0.txt":
-game\images\animations\notagoodtime\anim_notagoodtime_f1.png
-game\images\animations\notagoodtime\anim_notagoodtime_f2.png
-game\images\animations\toilet\anim_toilet.webm
-game\images\animations\toilet\anim_toilet_mask.webm
-game\images\credits\spr_creditsimage_notagoodtime.png
-game\images\credits\spr_creditsimage_miahoe.png
Non-Cavemanon sourced items with attribution clauses
====================================================
--- SOUNDS ---
"S Dissapproval - Alt.wav" by Processaurus
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Processaurus/sounds/440088/
"Rolling Creak.wav" by lukaspearse
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/lukaspearse/sounds/149736/
"Interior Wind Noise_Zoom H6.wav" by omnisounddesign
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/omnisounddesign/sounds/335703/
"Take off - Small pop.wav" by Quistard
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/Quistard/sounds/237753/
"Jet_whoosh.wav" by Benboncan
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Benboncan/sounds/167563/
"Dodgeball_Bounce1.wav" by burnsie289
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/burnsie289/sounds/152414/
"Cracking knuckles.flac" by CGEffex
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/CGEffex/sounds/93981/
"MassiveBlast.wav" by daveincamas
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/daveincamas/sounds/58507/
"Water Swirl, Small, 17.wav" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/398708/
"Splash, Jumping, A" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/352101/
"etl Window 24-96.wav" by cmusounddesign
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/cmusounddesign/sounds/95893/
"elevator 3.wav" by Trautwein
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Trautwein/sounds/262574/
"taking the elevator" by Tomlija
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/Tomlija/sounds/202985/
"Snapping, Wodden Fence, L.wav" by InspectorJ
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/InspectorJ/sounds/352196/
"Elastic Band on Tarpaulin" by RICHERlandTV
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/RICHERlandTV/sounds/592262/
"Whip Crack 01.wav" by CGEffex
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/CGEffex/sounds/93100/
"Snow Ball Throw And Splat" by Mike Koenig
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://soundbible.com/632-Snow-Ball-Throw-And-Splat.html
"Power up yells" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/382010/
"female dying scream" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/394610/
"dying female" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/345049/
"Female battle cries/grunts" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/AmeAngelofSin/sounds/264982/
"ANGRY DOG BARK SNARL flat.wav" by AmeAngelofSin
LICENSED UNDER ATTRIBUTION 3.0 (CC BY 3.0)
https://freesound.org/people/deleted_user_3424813/sounds/260776/
"WIT8 - pain" by phantastonia
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/phantastonia/sounds/615023/
"Door open and close, close" by Moulaythami
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/Moulaythami/sounds/555095/
"mitchellsounds - EXT_spring_light_wind_mourningdove_MS.wav"
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/mitchellsounds/sounds/517941/
"20170618_city.garden.fountain.wav"
LICENSED UNDER ATTRIBUTION 4.0 (CC BY 4.0)
https://freesound.org/people/dobroide/sounds/396277/
--- MUSIC ---
mus_angry.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/HYPER_METAL_/Loyalty_Freak_Music_-_HYPER_METAL__-_06_SUPER_METAL/
author: Loyalty Freak Music
album: HYPER METAL !
songname: SUPER METAL
license: CC0
mus_arcade1.ogg
URL: https://sampleswap.org/mp3/song.php?id=1185
author: benzoul
songname: lovepartyinjapan
license: CC-BY
mus_arcade2.ogg
URL: https://sampleswap.org/mp3/song.php?id=413
author: emanon
songname: 21seiki Techno Shonen
license: CC-BY
mus_awkward.ogg
URL: https://freemusicarchive.org/music/Soft_and_Furious/The_Merfolk_I_Should_Turn_To_Be/Soft_and_Furious_-_The_Merfolk_I_Should_Turn_To_Be_-_08_Hyper_Staying/
author: Soft and Furious
album: The Merfolk I Should Turn To Be
songname: Hyper Staying
license: CC0
mus_ben.ogg
URL: https://freemusicarchive.org/music/koi-discovery/post-morphose/icar-fellmp3/
author: Koi-discovery
album: Post-Morphose
songname: Icar_Fell.mp3
license: CC0
mus_calm2.ogg
URL: https://freemusicarchive.org/music/Komiku/Its_time_for_adventure__vol_2/Komiku_-_Its_time_for_adventure_vol_2_-_08_Dreaming_of_you/
author: Komiku
album: It's time for adventure ! vol 2
songname: Dreaming of you
license: CC0
mus_calm.ogg
URL: https://freemusicarchive.org/music/Soft_and_Furious/The_Merfolk_I_Should_Turn_To_Be/Soft_and_Furious_-_The_Merfolk_I_Should_Turn_To_Be_-_02_Youre_no_good_but_I_love_you/
author: Soft and Furious
album: The Merfolk I Should Turn To Be
songname: You're no good but I love you
license: CC0
mus_casual.ogg
URL: https://freemusicarchive.org/music/holiznacc0/left-overs/even-after-all-these-years/
author: HoliznaCC0
album: Left Overs
songname: Even After All These Years
license: CC0
mus_chill1.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/INSTRUMENTAL_RB_BEATS_TO_SING_OR_RAP_ON/Loyalty_Freak_Music_-_INSTRUMENTAL_RB_BEATS_TO_SING_OR_RAP_ON_-_08_I_care
author: Loyalty Freak Music
album: INSTRUMENTAL R&B BEATS TO SING OR RAP ON
songname: I care
license: CC0
mus_chill2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/busted-guitar-jazz/4-jazz/
author: HoliznaCC0
album: Busted Guitar (JAZZ)
songname: 4 (jazz)
license: CC0
mus_chill3.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/everything-you-ever-dreamed/
author: HoliznaCC0
album: Lo-fi And Chill
songname: Everything You Ever Dreamed.
license: CC0
mus_chill_thinking.ogg
URL: https://freemusicarchive.org/music/holiznacc0/sad-beats/chills/
author: HoliznaCC0
album: Sad Beats
songname: Chills
license: CC0
mus_damien.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/americana-1/
author: HoliznaCC0
album: Rock Montage
songname: Americana 1
license: CC0
mus_general.ogg
URL: https://freemusicarchive.org/music/wax-lyricist/the-wax-lyricist/high-on-loungin/
author: Wax Lyricist
album: The Wax Lyricist
songname: High on Loungin'
license: CC0
mus_happy2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/power-pop/a-small-town-on-pluto-1/
author: HoliznaCC0
album: Power Pop!
songname: A Small Town On Pluto
license: CC0
mus_iadakan.ogg
URL: https://freemusicarchive.org/music/holiznacc0/left-overs/space-3/
author: HoliznaCC0
album: Left Overs
songname: Space!
license: CC0
mus_inco.ogg
URL: https://freemusicarchive.org/music/koi-discovery/cyborg-breakdown/an-ocytocin-problemmp3/
author: Koi-discovery
album: Cyborg Breakdown
songname: An_Ocytocin_Problem.mp3
license: CC0
mus_introspective3
URL: https://freemusicarchive.org/music/Monplaisir/Space_Porn/Monplaisir_-_Space_Porn_-_04_Protect/
author: Monplaisir
album: Space Porn
songname: Protect
license: CC0
mus_melancholy2.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Space_Porn/Monplaisir_-_Space_Porn_-_08_Stargazer/
author: Monplaisir
album: Space Porn
songname: Stargazer
license: CC0
mus_melancholy_introspective.ogg
URL: https://freemusicarchive.org/music/Monplaisir/PIGEONS_ARE_THE_BEST/Monplaisir_-_PIGEONS_ARE_THE_BEST_-_05_Lightbull/
author: Monplaisir
album: PIGEONS ARE THE BEST
songname: Lightbull
license: CC0
mus_melancholy.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/TO_CHILL_AND_STAY_AWAKE/Loyalty_Freak_Music_-_TO_CHILL_AND_STAY_AWAKE_-_06_People_are_spinning/
author: Loyalty Freak Music
album: TO CHILL AND STAY AWAKE
songname: People are spinning
license: CC0
mus_melancholy_olivia.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_02_Far_and_High/
author: Monplaisir
album: Pretty and Invisible
songname: Far and High
license: CC0
mus_mia1.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/punk/
author: HoliznaCC0
album: Rock Montage
songname: Punk
license: CC0
mus_mia2.ogg
URL: https://freemusicarchive.org/music/holiznacc0/rock-montage/grunge/
author: HoliznaCC0
album: Rock Montage
songname: Grunge
license: CC0
mus_misc.ogg
URL: https://freemusicarchive.org/music/holiznacc0/kick-it-laid-back-hiphop/unwind/
author: HoliznaCC0
album: Kick It (laid back HipHop)
songname: Unwind
license: CC0
mus_pissed.ogg
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_06_Talentuous_and_Shy/
author: Monplaisir
album: Pretty and Invisible
songname: Talentuous and Shy
license: CC0
mus_rock.ogg
URL: https://freesound.org/people/Jibey-/sounds/572947/
author: Jibey-
songname: Rock music.wav
license: CC-BY
mus_slow.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/ramenmp3/
author: Ramen.mp3
album: Lo-fi And Chill
songname: ramenmp3
license: CC0
mus_thoughts1.ogg
URL: https://freemusicarchive.org/music/Monplaisir/PIGEONS_ARE_THE_BEST/Monplaisir_-_PIGEONS_ARE_THE_BEST_-_01_Jump__Oh_Hi_Mark/
author: Monplaisir
album: PIGEONS ARE THE BEST
songname: Jump ! Oh Hi Mark
license: CC0
mus_thoughts2
URL: https://freemusicarchive.org/music/Monplaisir/Pretty_and_Invisible/Monplaisir_-_Pretty_and_Invisible_-_01_Loved_and_Respected/
author: Monplaisir
album: Pretty and Invisible
songname: Loved and Respected
license: CC0
mus_titlescreen.ogg
URL: https://freemusicarchive.org/music/holiznacc0/be-happy-with-who-you-are/finding-yourself/
author: HoliznaCC0
album: Be Happy With Who You Are
songname: Finding Yourself
license: CC0
mus_trouble.ogg
URL: https://freemusicarchive.org/music/Loyalty_Freak_Music/TO_CHILL_AND_STAY_AWAKE/Loyalty_Freak_Music_-_TO_CHILL_AND_STAY_AWAKE_-_05_Traveling_in_your_mind/
author: Loyalty Freak Music
album: TO CHILL AND STAY AWAKE
songname: Traveling in your mind
license: CC0
mus_upbeat.ogg
URL: https://freemusicarchive.org/music/holiznacc0/lo-fi-and-chill/busted-jazz
author: HoliznaCC0
album: Lo-fi And Chill
songname: Busted Jazz
license: CC0
--- GRAPHICS ---
"The Resort at Pelican Hill" by Ansel Adams
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/prayitnophotography/8468342892/
"Inside 360 Restaurant" by Larry Koester
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/larrywkoester/22976555815/
"Banquet set up - Novotel Century Hong Kong Hotel" by RichardToHKG
LICENSED UNDER ATTRIBUTION 3.0 UNPORTED (CC BY 3.0)
https://commons.wikimedia.org/wiki/File:Banquet_set_up_-_Novotel_Century_Hong_Kong_Hotel.jpg
"Seattle from the Space Needle" by Peter Kaminski
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/peterkaminski/5444827/
"Bar" by fr1da
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/denero188_36624278/2090013005
"Pleading face" and "Crocodile emoji" by Twitter/X
Copyright 2020 Twitter, Inc and other contributors
Graphics licensed under CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/
"Swing" by Julia Koefender
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/juliakoefender/7128081493/
"Kitchen in our Hollywood Hills Hidden Gem apartment - Los Angeles, California, USA" by Glen Bowman
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/glenbowman/18180131123/
"Sunset with yachts near Phuket island, Thailand XOKA2050s" by Phuket@photographer.net
LICENSED UNDER ATTRIBUTION 2.0 (CC BY 2.0)
https://www.flickr.com/photos/linvoyage/44910097244/

View File

@ -12,14 +12,15 @@ Information regarding how to set up the full game as a Ren'Py project using the
## Building
There are two ways to launch this project/make distributions; Through the Ren'Py SDK or RenKit:
There are two options for building dependong on your preference:
- Ren'Py SDK - Good for computerlets/ease of use. Has debugging features and a bit more options. Requires a bit more setup for Android building.
- RenKit - Good for automation/terminal users. Dead simple setup, auto downloads all required files for building distributions, including the SDK and Android stuff. Allows CLI interfacing with Ren'Py to launch projects
- Ren'Py SDK - For being able to launch the project as a game and/or make personal distributions. Good for computerlets/ease of use. Has debugging features and a bit more options. Requires a bit more setup for Android building. Will not include workshop support by itself.
- RenKit - For accurate compilation. Good for automation/terminal users. Dead simple setup, auto downloads almost all required files for building distributions, including the SDK and most Android stuff. Allows CLI interfacing with Ren'Py to launch projects. Includes workshop support via the patching functionality.
### BUILDING WITH THE SDK
1. [Download the Ren'Py 8.1.3 SDK depending on your system](https://www.renpy.org/release_list.html)
1. [Download the Ren'Py 8.2.1 SDK depending on your system](https://www.renpy.org/release_list.html)
2. Extract the .zip/.bz2/.dmg or get it through your package manager and run the SDK.
3. Clone this repo - Or if you don't use Git, click the '...' button near the topright of this page and click 'Download ZIP' - and place it within the Ren'Py SDK or to a directory of your choosing.
4. Launch the SDK and set the projects path to the folder containing your repo. Make sure the project is selected within the projects list.
@ -32,9 +33,10 @@ There are two ways to launch this project/make distributions; Through the Ren'Py
2. Extract the .zip/.xz or get it through your package manager.
3. Clone this repo - Or if you don't use Git, click the '...' button near the topright of this page and click 'Download ZIP' - and place it somewhere you can access.
4. Edit the `renconstruct.toml` file in the root of the project files to fit your needs like which distributions you want to build.
5. (OPTIONAL) If you want to include building for Android, you'll need to install JDK 21 as renconstruct can't do that automatically. [Read up the Ren'Py documentation for info on how](https://www.renpy.org/doc/html/android.html#step-1-installing-the-dependencies).
5. Run `renconstruct.exe` with the following command:
```bash
renconstruct build -c "<path to demo project files>/renconstruct.toml" "<path to demo project files>" "<path to outputted distributions>"
```bash renconstruct build "." dist/
renconstruct build "<path to demo project files>" "<path to outputted distributions>" -c "<path to demo project files>/renconstruct.toml"
```
This will start the build process and outputs the game to whatever path you set your distributions to.
@ -43,11 +45,10 @@ This will start the build process and outputs the game to whatever path you set
More information on the build process [can be found here](https://www.renpy.org/doc/html/build.html#building-distributions).
Information relating to building for Android [can be found here here as well](https://www.renpy.org/doc/html/android.html). Note that for Android, you must use Java SDK 8 until Wani updates to Ren'Py 8.2.0.
Information relating to building for Android [can be found here here as well](https://www.renpy.org/doc/html/android.html).
Information regarding RenKit and it's documentation [can be found on its github page](https://github.com/kobaltcore/renkit)
The 'woodpecker.yml' file included in the source is for reference in CI/CD and may be useful for some.
The 'woodpecker.yml' file included in the source is for reference in CI/CD and may be useful for some. With Woodpecker, versioning can be applied via git tags, and will replace the in-game version variable and the versioning for android with the name of the tag. It's configured for our servers so it's not expected to work right off the bat if you try it.
## Setting up the full game as a Ren'Py project

29
build_patch/patch.diff Normal file
View File

@ -0,0 +1,29 @@
233a234
> import os # @UnresolvedImport
236a238,263
>
> # MODS STUFF
> APP_ID = 1895350
>
> if not renpy.android:
> try: # Android will try to run this for some reason and fail
> mod_paths = [
> f"../../workshop/content/{APP_ID}/",
> f"/Users/{os.getlogin()}/Library/Application Support/Steam/steamapps/workshop/content/{APP_ID}/",
> os.path.expanduser(f"~/Library/Application Support/Steam/steamapps/workshop/content/{APP_ID}/")
> ]
> except:
> mod_paths = []
>
> new_paths = []
> for path in mod_paths:
> try:
> if os.path.exists(path):
> for name in os.listdir(path):
> full_path = os.path.join(path, name)
> if os.path.isdir(full_path):
> new_paths.append(full_path)
> except Exception as e:
> renpy.display.log.write(f"Error while adding mod search paths: {e}")
>
> searchpath += new_paths

19
build_patch/patch.py Normal file
View File

@ -0,0 +1,19 @@
class PatchTask:
def __init__(self, config, input_dir, output_dir):
self.config = config
self.input_dir = input_dir
self.output_dir = output_dir
def pre_build(self):
import subprocess
print("================Initiating patching==================")
try:
subprocess.run(["patch", f"/tmp/cache/{self.config['ver']}/renpy.py", "./build_patch/patch.diff"])
except Exception as e:
print(e)
raise e
print("================File Patched==================")
def post_build(self):
pass

View File

@ -9,13 +9,17 @@ label chapter_select:
camera:
resetcamera()
yanchor 0.0 xanchor 0.0 rotate None zoom 1.0
matrixcolor None
$ quick_menu = True
$ notagoodtime_ui = False
$ textbox_offset = 0
$ namebox_offset = 0
$ _window_alpha = 1.0
$ broken_phone = False
python:
quick_menu = True
notagoodtime_ui = False
textbox_offset = 0
namebox_offset = 0
_window_alpha = 1.0
broken_phone = False
renpy.hide_screen("_phone")
renpy.set_return_stack([]) # This prevents timeloop bugs
call initstats from _call_initstats

View File

@ -5,8 +5,6 @@ init 999 python:
#hard code the header & footer
#then iterate the list_credits
list_credits_start = [
_("I Wani Hug That Gator"),
_("By Cavemanon"),
@ -206,6 +204,35 @@ init 999 python:
else:
return list_credits[accessor][value]
SIZE_SNOT_GAMES = 55*3+10
SIZE_TITLE = 32*3+10
SIZE_ENTRY = 26*3+10
SIZE_TL = 26*2+10
SIZE_ENDER = 52*3+10
screen muh_credits():
fixed:
xalign 0.5
vbox:
xalign 0.5
null width 1 height 16*25
text list_credits_start[0] size SIZE_SNOT_GAMES xalign 0.5 yalign 0.5 text_align 0.5 outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ]
null width 1 height 16*1
text list_credits_start[1] size SIZE_TITLE xalign 0.5 yalign 0.5 text_align 0.5 outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ]
null width 1 height 16*18
text list_credits_start[2] size SIZE_ENTRY xalign 0.5 yalign 0.5 text_align 0.5 outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ]
null width 1 height 16*12
for key, arr in list_credits.items():
text key size SIZE_ENTRY xalign 0.5 yalign 0.5 text_align 0.5 outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ]
null width 1 height 16*6
vbox:
xalign 0.5
spacing 17
for item in arr:
text item size SIZE_ENTRY xalign 0.5 yalign 0.5 text_align 0.5 outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ]
null width 1 height 16*3
transform tf_credits_moveinright(x=0.0, y=0.0, duration=2.0, delay=0.0):
subpixel True alpha 0.0
pause delay
@ -250,7 +277,14 @@ transform tf_credits_slightzoomout_offset(y=0.5, yanchor=0.5):
subpixel True
linear 7.5 zoom 0.95
# This can take a string for the text size, intended for renpy's translation generation. The string has to follow this format:
# "(number)=(credits text)"
# So an example would be:
# "100=Directed By"
screen endingtext(text="placeholder", text_transform=truecenter, text_align=0.0, text_size=100):
python:
if isinstance(text_size, str):
text_size = int(text_size[0:text_size.find("=")])
text text yanchor 0.0 xanchor text_align size text_size text_align text_align outlines [ (absolute(5), "#000", absolute(0), absolute(0)) ] at text_transform
@ -393,12 +427,13 @@ label credits:
hide CAVEMANON
# Display the whole credits list
show spr_credits:
crop None zoom 1.0 yalign 0.0
if ending != 3:
show spr_credits:
crop (0.0, 0.0, 1.0, 17550) zoom 1.0 yalign 0.0 alpha 1.0
else:
show spr_credits:
crop None zoom 1.0 yalign 0.0
show black as censor:
ypos 16.3
xsize 0.9 # We squeeze it so that it doesnt cover the (1) in ending 2
show spr_credits_theend:
ypos 17.5
@ -522,7 +557,7 @@ label e4credits_1:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[0], tf_credits_moveinright(0.15, 0.3, 7))
show screen endingtext(list_credits_titles[0], tf_credits_moveinright(0.15, 0.3, 7), text_size=__("100=Directed by"))
show screen endingtext(display_credits_names(0, 0), tf_credits_moveinleft(0.85, 0.5, 7), 1.0) as endingtext2
pause 7.5
@ -552,7 +587,7 @@ label e4credits_2:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[1], tf_credits_moveinright(0.15, 0.1, 7))
show screen endingtext(list_credits_titles[1], tf_credits_moveinright(0.15, 0.1, 7), text_size=__("100=Written by"))
show screen endingtext(display_credits_names(1), tf_credits_moveinleft(0.85, 0.25, 7), 1.0) as endingtext2
pause 7.5
@ -591,7 +626,7 @@ label e4credits_3:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[2], tf_credits_moveinright(0.15, 0.6, 7))
show screen endingtext(list_credits_titles[2], tf_credits_moveinright(0.15, 0.6, 7), text_size=__("100=Story by"))
show screen endingtext(display_credits_names(2), tf_credits_moveinleft(0.85, 0.45, 7), 1.0) as endingtext2
pause 7.5
@ -616,7 +651,7 @@ label e4credits_4:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[3], tf_credits_moveinright(0.1, 0.6, 7), text_size=85)
show screen endingtext(list_credits_titles[3], tf_credits_moveinright(0.1, 0.6, 7), text_size=__("85=Production Coordinator"))
show screen endingtext(display_credits_names(3), tf_credits_moveinleft(0.4, 0.75, 7), 1.0) as endingtext2
pause 7.5
@ -660,7 +695,7 @@ label e4credits_5:
camera:
linear 15 ypos -1.5
show screen endingtext(list_credits_titles[4], tf_credits_moveinright(0.15, 0.1, 14))
show screen endingtext(list_credits_titles[4], tf_credits_moveinright(0.15, 0.1, 14), text_size=__("100=Artwork by"))
show screen endingtext(display_credits_names(4, end_index=5), tf_credits_moveinleft(0.85, 0.2, 7), 1.0) as endingtext2
pause 7
@ -737,7 +772,7 @@ label e4credits_6:
alpha ALPHA_CONTROLLER
shakeend(i=2.0)
show screen endingtext(list_credits_titles[5], tf_credits_moveinright(0.05, 0.1, 7))
show screen endingtext(list_credits_titles[5], tf_credits_moveinright(0.05, 0.1, 7), text_size=__("100=Additional Artwork by"))
show screen endingtext(display_credits_names(5), tf_credits_moveinleft(0.55, 0.3, 7), 1.0) as endingtext2
pause 7.5
@ -783,7 +818,7 @@ label e4credits_7:
xalign 0.5 yalign 0.5 zoom 1.1
linear 8 zoom 1.0
show screen endingtext(list_credits_titles[6], tf_credits_moveinright(0.125, 0.45, 7))
show screen endingtext(list_credits_titles[6], tf_credits_moveinright(0.125, 0.45, 7), text_size=__("100=Stock Photos by"))
show screen endingtext(display_credits_names(6), tf_credits_moveinleft(0.85, 0.35, 7), 1.0) as endingtext2
pause 7.5
@ -813,7 +848,7 @@ label e4credits_8:
xpos 0.67 ypos 0.66 alpha 0.0
linear 0.5 alpha 1
show screen endingtext(list_credits_titles[7], tf_credits_moveinright(0.1, 0.1, 14))
show screen endingtext(list_credits_titles[7], tf_credits_moveinright(0.1, 0.1, 14), text_size=__("100=Animation by"))
show screen endingtext(display_credits_names(7, end_index=3), tf_credits_moveinleft(0.9, 0.1, 7), 1.0) as endingtext2
pause 7
@ -852,7 +887,7 @@ label e4credits_9:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[8], tf_credits_moveinright(0.35, 0.1, 14))
show screen endingtext(list_credits_titles[8], tf_credits_moveinright(0.35, 0.1, 14), text_size=__("100=Programming by"))
show screen endingtext(display_credits_names(8, end_index=3), tf_credits_moveinleft(0.85, 0.3, 7), 1.0) as endingtext2
pause 7
@ -889,7 +924,7 @@ label e4credits_10:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[9], tf_credits_moveinright(0.1, 0.2, 7))
show screen endingtext(list_credits_titles[9], tf_credits_moveinright(0.1, 0.2, 7), text_size=__("100=Music by"))
show screen endingtext(display_credits_names(9), tf_credits_moveinleft(0.5, 0.4, 7), 1.0) as endingtext2
pause 7.5
@ -914,7 +949,7 @@ label e4credits_11:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[10], tf_credits_moveinright(0.15, 0.15, 14))
show screen endingtext(list_credits_titles[10], tf_credits_moveinright(0.15, 0.15, 14), text_size=__("100=Stock Music by"))
show screen endingtext(display_credits_names(10, end_index=3), tf_credits_moveinleft(0.85, 0.35, 7), 1.0) as endingtext2
pause 7
@ -956,7 +991,7 @@ label e4credits_12:
ypos 0.25 xpos 0.01
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[11], tf_credits_moveinright(0.3, 0.2, 7))
show screen endingtext(list_credits_titles[11], tf_credits_moveinright(0.3, 0.2, 7), text_size=__("100=Stock Music acquired by"))
show screen endingtext(display_credits_names(11), tf_credits_moveinleft(0.9, 0.4, 7), 1.0) as endingtext2
pause 7.5
@ -988,7 +1023,7 @@ label e4credits_13:
xpos 0.81 alpha 0.0
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[12], tf_credits_moveinright(0.15, 0.2, 7))
show screen endingtext(list_credits_titles[12], tf_credits_moveinright(0.15, 0.2, 7), text_size=__("100=Sound by"))
show screen endingtext(display_credits_names(12), tf_credits_moveinleft(0.85, 0.4, 7), 1.0) as endingtext2
pause 7.5
@ -1010,7 +1045,7 @@ label e4credits_14:
parallel:
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[13], tf_credits_moveinright(0.15, 0.1, 14))
show screen endingtext(list_credits_titles[13], tf_credits_moveinright(0.15, 0.1, 14), text_size=__("100=Stock Sounds by"))
show screen endingtext(display_credits_names(13, end_index=4), tf_credits_moveinleft(0.85, 0.25, 7), 1.0) as endingtext2
pause 7
@ -1039,7 +1074,7 @@ label e4credits_15:
ypos 0.0 xpos 0.47 zoom 2.02
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[13], tf_credits_moveinright(0.05, 0.1, 14))
show screen endingtext(list_credits_titles[13], tf_credits_moveinright(0.05, 0.1, 14), text_size=__("100=Stock Sounds by"))
show screen endingtext(display_credits_names(13, start_index=10, end_index=13), tf_credits_moveinleft(0.45, 0.3, 7), 1.0) as endingtext2
pause 7
@ -1123,7 +1158,7 @@ label e4credits_16:
linear 0.1 yoffset -1
repeat
show screen endingtext(list_credits_titles[14], tf_credits_moveinright(0.2, 0.1, 7))
show screen endingtext(list_credits_titles[14], tf_credits_moveinright(0.2, 0.1, 7), text_size=__("100=Stock sounds acquired at"))
show screen endingtext(display_credits_names(14), tf_credits_moveinleft(0.9, 0.3, 7), 1.0) as endingtext2
pause 7.5
@ -1159,7 +1194,7 @@ label e4credits_final:
xpos 0.12 ypos 0.24 alpha 0.0
linear 0.5 alpha ALPHA_CONTROLLER
show screen endingtext(list_credits_titles[15], tf_credits_moveinright(0.15, 0.15, 15.25))
show screen endingtext(list_credits_titles[15], tf_credits_moveinright(0.15, 0.15, 15.25), text_size=__("100=Special Thanks"))
show screen endingtext(display_credits_names(15, end_index=4), tf_credits_moveinleft(0.85, 0.25, 7), 1.0) as endingtext2
pause 7.5

View File

@ -31,9 +31,17 @@ define audio.mus_introspective_night = "<loop 39.801833>" + DEFAULT_MUSIC_FILEPA
define audio.mus_school_somber = "<loop 1.1363955>" + DEFAULT_MUSIC_FILEPATH + "mus_school_somber" + DEFAULT_MUSIC_EXTENSION
define audio.mus_remorse = "<loop 81.832583>" + DEFAULT_MUSIC_FILEPATH + "mus_remorse" + DEFAULT_MUSIC_EXTENSION
define audio.mus_complete = "<loop 2.580167>" + DEFAULT_MUSIC_FILEPATH + "mus_complete" + DEFAULT_MUSIC_EXTENSION
define audio.mus_boring = "<loop 20.571>" + DEFAULT_MUSIC_FILEPATH + "mus_boring" + DEFAULT_MUSIC_EXTENSION
define audio.mus_intense = "<loop 26.691>" + DEFAULT_MUSIC_FILEPATH + "mus_intense" + DEFAULT_MUSIC_EXTENSION
define audio.mus_romance3 = "<loop 97.079>" + DEFAULT_MUSIC_FILEPATH + "mus_romance3" + DEFAULT_MUSIC_EXTENSION
define audio.mus_introspective1 = "<loop 48>" + DEFAULT_MUSIC_FILEPATH + "mus_introspective1" + DEFAULT_MUSIC_EXTENSION
define audio.mus_dress = "<loop 192>" + DEFAULT_MUSIC_FILEPATH + "mus_dress" + DEFAULT_MUSIC_EXTENSION
define audio.mus_olivia = "<loop 121.905>" + DEFAULT_MUSIC_FILEPATH + "mus_olivia" + DEFAULT_MUSIC_EXTENSION
define audio.mus_happy1 = "<loop 45>" + DEFAULT_MUSIC_FILEPATH + "mus_happy1" + DEFAULT_MUSIC_EXTENSION
define audio.mus_credits_e4 = "<loop 138.729271>" + DEFAULT_MUSIC_FILEPATH + "mus_credits_e4" + DEFAULT_MUSIC_EXTENSION
define audio.mus_chill2 = "<loop 5.97428>" + DEFAULT_MUSIC_FILEPATH + "mus_chill2" + DEFAULT_MUSIC_EXTENSION
define audio.mus_happy1 = "<loop 10.68202>" + DEFAULT_MUSIC_FILEPATH + "mus_happy1" + DEFAULT_MUSIC_EXTENSION
define audio.mus_happy2 = "<loop 10.68202>" + DEFAULT_MUSIC_FILEPATH + "mus_happy2" + DEFAULT_MUSIC_EXTENSION
define audio.mus_damien = "<loop 18.63127>" + DEFAULT_MUSIC_FILEPATH + "mus_damien" + DEFAULT_MUSIC_EXTENSION
define audio.mus_upbeat = "<loop 0.019>" + DEFAULT_MUSIC_FILEPATH + "mus_upbeat" + DEFAULT_MUSIC_EXTENSION
define audio.mus_chill_thinking = "<loop 9.989292>" + DEFAULT_MUSIC_FILEPATH + "mus_chill_thinking" + DEFAULT_MUSIC_EXTENSION

View File

@ -1480,7 +1480,9 @@ layeredimage olivia hmph:
xanchor 0.5 yoffset -150 mesh True
gl_drawable_resolution False
always "spr_olivia_tail_normal_hmph"
group tails:
attribute tailsock "spr_olivia_tail_tailsock_neutral"
attribute notailsock default "spr_olivia_tail_normal_hmph"
group wheelchair_back:
attribute wheelchair default "spr_olivia_wheelchair_back"
@ -2445,15 +2447,15 @@ layeredimage vinny:
attribute unswag "spr_null"
group macaroni_left: #see images.rpy for definitions for the macaroni
attribute macaroni "macaroni_left"
attribute macaroni_up "macaroni_left_up"
attribute macaronibroken "macaroni_left_broken"
attribute macaroni "spr_macaroni_left" xoffset 250 yoffset 820
attribute macaroni_up "spr_macaroni_left" xoffset 250 yoffset 760
attribute macaronibroken "spr_macaroni_left" xoffset 220 yoffset 820
attribute nomacaroni "spr_null"
group macaroni_right:
attribute macaroni "macaroni_right"
attribute macaroni_up "macaroni_right_up"
attribute macaronibroken "macaroni_right_broken"
attribute macaroni "spr_macaroni_right" xoffset 250 yoffset 820
attribute macaroni_up "spr_macaroni_right" xoffset 250 yoffset 760
attribute macaronibroken "spr_macaroni_right" xoffset 280 yoffset 820
attribute nomacaroni "spr_null"

View File

@ -326,56 +326,19 @@ image full_box:
contains:
"bg_box_front"
# Vinny's Macaroni
image macaroni_right:
"spr_macaroni_right"
xoffset 250 yoffset 820
image macaroni_left:
contains:
"spr_macaroni_left_base"
xoffset 250 yoffset 820
contains:
"spr_macaroni_left_text"
xoffset 250 yoffset 820
image macaroni_right_broken:
"spr_macaroni_right"
xoffset 280 yoffset 820
image macaroni_left_broken:
contains:
"spr_macaroni_left_base"
xoffset 220 yoffset 820
contains:
"spr_macaroni_left_text"
xoffset 220 yoffset 820
image macaroni_right_up:
"spr_macaroni_right"
xoffset 250 yoffset 820
"spr_macaroni_right"
yoffset 760
#TODO: add transitions to this so it doesn't suck!
#easein_cubic yoffset 760
image macaroni_left_up:
contains:
"spr_macaroni_left_base"
xoffset 250 yoffset 820
"spr_macaroni_left_base"
yoffset 760
contains:
"spr_macaroni_left_text"
xoffset 250 yoffset 820
"spr_macaroni_left_text"
yoffset 760
#
# DO NOT USE THE contains METHOD FOR PROPS ATTACHED TO CHARACTERS IN THE characters.rpy FILE.
# For some reason, they bug out on positoning and alignment if you do, so use Composte() instead.
#
# Vinny's Macaroni
image spr_macaroni_left = Composite(
(232, 147),
(0, 0), "spr_macaroni_left_base",
(0, 0), "spr_macaroni_left_text"
)
# Inco's grocery bag
image spr_mug_damien = Composite(
(195, 206),

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
python early in cds_utils:
from renpy import store
# if store.is_renpy_version_or_above(7, 6, 0)
Lexer = renpy.lexer.Lexer if renpy.version_tuple >= ((7, 6) if renpy.compat.PY2 else (8, 1)) else renpy.parser.Lexer
def null_parser(l):
@ -91,7 +92,7 @@ python early in phone._lint:
error("audio '{}' isn't loadable.".format(a))
python early in phone:
from renpy.store import cds_utils
from renpy.store import cds_utils
class _RawPhoneMessage(cds_utils.Statement):
__slots__ = ("sender", "message", "delay")
@ -148,10 +149,12 @@ python early in phone:
self.delay = delay
def execute(self):
discussion.label(self.label, eval(self.delay, store.__dict__))
delay = config.default_label_delay if self.delay is None else eval(self.delay, store.__dict__)
discussion.label(self.label, delay)
def lint(self):
_lint.eval(self.delay)
if self.delay is not None:
_lint.eval(self.delay)
def get_translatable_strings(self):
return [self.label]
@ -166,7 +169,8 @@ python early in phone:
def execute(self):
globals = store.__dict__
discussion.date(delay=eval(self.delay, globals), auto=eval(self.auto, globals), **{k: eval(v, globals) for k, v in self.kwargs.items()})
delay = config.default_label_delay if self.delay is None else eval(self.delay, globals)
discussion.date(delay=delay, auto=eval(self.auto, globals), **{k: eval(v, globals) for k, v in self.kwargs.items()})
def lint(self):
month = _lint.eval(self.kwargs["month"])
@ -195,7 +199,8 @@ python early in phone:
_lint.error("'{}' isn't a valid second.".format(second))
_lint.eval(self.kwargs["year"])
_lint.eval(self.delay)
if self.delay is not None:
_lint.eval(self.delay)
_lint.eval(self.auto)
class _RawPhoneTyping(cds_utils.Statement):
@ -319,7 +324,19 @@ python early in phone:
class _RawPhonePass(cds_utils.Statement):
def execute(self):
store.pause()
pass
class _RawPhonePause(cds_utils.Statement):
__slots__ = ("duration",)
def __init__(self, duration):
self.duration = duration
def execute(self):
store.pause(eval(self.duration, store.__dict__))
def lint(self):
_lint.eval(self.duration)
# class _RawPhoneRenpy(cds_utils.Statement):
# __slots__ = ("nodes",)
@ -621,12 +638,13 @@ python early in phone:
if register: return _RawPhoneRegisterLabel(label)
delay = "0.5" if not ll.keyword("delay") else ll.require(ll.simple_expression)
delay = None if not ll.keyword("delay") else ll.require(ll.simple_expression)
return _RawPhoneLabel(label, delay)
def _parse_phone_date(ll, register):
kwargs = {time_thing: "None" for time_thing in ("month", "day", "year", "hour", "minute", "second")}
kwargs["auto"] = "False"
kwargs["delay"] = None
seen = set()
while True:
@ -652,11 +670,13 @@ python early in phone:
break
auto = kwargs.pop("auto")
delay = kwargs.pop("delay")
if register:
if delay is not None:
renpy.error("'delay' can't be used here")
return _RawPhoneRegisterDate(kwargs, auto)
delay = "0.5" if not ll.keyword("delay") else ll.require(ll.simple_expression)
return _RawPhoneDate(kwargs, delay, auto)
def _parse_phone_typing(ll):
@ -820,6 +840,10 @@ python early in phone:
if delay is None: delay = "None"
return _RawPhoneAudio(sender, audio, time, delay)
def _parse_phone_pause(ll):
duration = ll.simple_expression()
return _RawPhonePause(duration or "None")
# def _parse_phone_renpy(ll):
# ll.require(":")
# ll.expect_eol()
@ -863,6 +887,9 @@ python early in phone:
elif ll.keyword("pass"):
statement = _RawPhonePass()
elif ll.keyword("pause"):
statement = _parse_phone_pause(ll)
# elif ll.keyword("renpy"):
# statement = _parse_phone_renpy(ll)
@ -925,9 +952,12 @@ python early in phone:
return _RawPhoneDiscussion(gc, statements)
def _predict_phone_discussion(rd):
renpy.predict_screen("phone_message")
return [ ]
# This and the statement that calls this function is stubbed out, otherwise a bug happens where the game crashes when advancing to fast when pulling up the phone
# Not fixed as of EMR Phone 3.2.2
#def _predict_phone_discussion(rd):
# renpy.predict_screen("phone_discussion")
# return [ ]
def _phone_execute_init(rv):
for statement in rv.statements:
@ -942,7 +972,7 @@ python early in phone:
execute_init=_phone_execute_init,
translation_strings=cds_utils.get_translatable_strings,
lint=cds_utils.lint,
predict=_predict_phone_discussion
#predict=_predict_phone_discussion
)
########################################################
@ -960,20 +990,46 @@ python early in phone:
def _parse_phone_call(l):
rv = l.require(l.simple_expression)
video = False
nosave = False
while not l.eol():
state = l.checkpoint()
thing = l.word()
if thing == "video":
if video:
l.revert(state)
l.error("video clause already given")
else:
video = True
elif thing == "nosave":
if nosave:
l.revert(state)
l.error("nosave clause already given")
else:
nosave = True
else:
l.revert(state)
l.error("unknown property %s" % thing)
l.expect_eol()
l.expect_noblock("phone call")
return rv
return rv, video, nosave
def _execute_phone_call(c):
c = character.character(eval(c, store.__dict__))
calls.call(c)
def _execute_phone_call(tu):
c = character.character(eval(tu[0], store.__dict__))
calls.call(c, tu[1], tu[2])
def _predict_phone_call(c):
renpy.predict_screen("phone_call")
def _predict_phone_call(tu):
renpy.predict_screen("phone_call", video=tu[1])
return [ ]
def _lint_phone_call(c):
_lint.character(c)
def _lint_phone_call(tu):
_lint.character(tu[0])
renpy.register_statement(
"phone call",
@ -1047,20 +1103,21 @@ python early in phone:
# soooooooooooooooooooooooooooooooooooooooooooooooo clunky
class _RawInitPhoneRegister(_RawPhoneRegister):
__slots__ = ("name", "icon", "key", "chars", "default_statement")
__slots__ = ("name", "icon", "key", "chars", "transient", "default_statement")
def __init__(self, gc, statements, name, icon, key, chars, default_statement):
def __init__(self, gc, statements, name, icon, key, chars, transient, default_statement):
super(_RawInitPhoneRegister, self).__init__(gc, statements)
self.name = name
self.icon = icon
self.key = key
self.chars = chars
self.transient = transient
self.default_statement = default_statement
def execute(self):
if self.default_statement is not None:
self.default_statement.execute()
_run_on_start(self._execute, ("phone define gc", self.gc if self.gc is not None else str(self.key)))
execute_default(self._execute, ("phone define gc", self.gc if self.gc is not None else str(self.key)))
def _execute(self):
gc = None
@ -1070,7 +1127,7 @@ python early in phone:
gc = getattr(store, self.default_statement.varname)
else:
if self.name is not None:
gc = group_chat.GroupChat(self.name, eval(self.icon, globals), eval(self.key, globals))
gc = group_chat.GroupChat(self.name, eval(self.icon, globals), eval(self.key, globals), transient=self.transient)
if gc is not None:
for char in self.chars:
@ -1108,6 +1165,7 @@ python early in phone:
key = None
icon = None
chars = [ ]
transient = False
_as = None
default_statement = None
@ -1144,6 +1202,11 @@ python early in phone:
dl.error("character '{}' already given".format(char))
chars.append(char)
elif p == "transient":
if transient:
dl.error("'transient' property already given")
transient = True
elif p == "as":
if _as is not None:
dl.error("'as' property already given")
@ -1157,19 +1220,20 @@ python early in phone:
dl.error("expected 'key' property")
if icon is None:
icon = 'phone.config.basedir + "default_icon.png"'
icon = 'phone.asset("default_icon.png")'
if _as is not None:
filename, linenumber = l.get_location()
global _INIT_PHONE_REGISTER_PRIORITY
string = "{init} {_as} = phone.group_chat.GroupChat('{name}', {icon}, {key})" \
string = "{init} {_as} = phone.group_chat.GroupChat('{name}', {icon}, {key}, transient={transient})" \
.format(
init=_INIT_PHONE_REGISTER_PRIORITY,
_as=_as,
name=name,
icon=icon,
key=key,
transient=transient,
)
lexer = cds_utils.Lexer(
@ -1184,7 +1248,7 @@ python early in phone:
if not statements and not no_gc:
ll.error("expected at least one statement")
return _RawInitPhoneRegister(gc, statements, name, icon, key, chars, default_statement)
return _RawInitPhoneRegister(gc, statements, name, icon, key, chars, transient, default_statement)
def _translation_strings_init_phone_register(ripr):
rv = _translation_strings_phone_register(ripr)

View File

@ -2,7 +2,7 @@ python early in phone:
from renpy import store
from store import config as renpy_config # phone.config is a substore
__version__ = (3, 1, 0)
__version__ = (3, 2, 2)
__author__ = "Elckarow#8399" # smh my head my head
init -150 python in phone:
@ -26,7 +26,7 @@ init -150 python in phone:
import time
def format_time(hour, minute):
return time.strftime(__(config.time_format), time.struct_time((1, 1, 1, hour, minute, 0, 1, 0, 0)))
return time.strftime(__(config.time_format), time.gmtime(hour * 3600 + minute * 60))
transform -150 _fits(size):
subpixel True xysize (size, size) fit "contain"
@ -98,7 +98,7 @@ init -100 python in phone:
menu = not first_call
if needs_rollback:
renpy.rollback(True)
renpy.rollback(force=True, greedy=False)
return rv
@ -115,6 +115,36 @@ init -100 python in phone:
at_list = [at_list]
renpy.show_layer_at(at_list=at_list, layer=layer, camera=camera, reset=reset)
def short_name(s, length):
s = renpy.substitute(s)
if len(s) > length:
s = s[:length - 3] + "..."
return s
import os
@renpy.pure
def path_join(*paths):
return os.path.join(*paths).replace("\\", "/")
@renpy.pure
def asset(path):
return path_join(config.basedir, path)
def execute_default(f, id):
def run(load):
if id not in _defaults_ran:
_defaults_ran.add(id)
f()
if load: renpy.block_rollback()
renpy_config.start_callbacks.append(renpy.partial(run, load=False))
renpy_config.after_load_callbacks.append(renpy.partial(run, load=True))
# a set() object
# renamed it because why not
default -999 phone._defaults_ran = phone._id_ran_on_start
default -100 phone._stack_depth = 0
default -100 phone._current_screen = None
@ -122,7 +152,7 @@ default broken_phone = False
# The base screen for all phone screens.
screen _phone(xpos=0.5, xanchor=0.5, ypos=0.05, yanchor=0.0, horizontal=False):
frame style "empty":
frame style "empty" modal True:
at transform:
subpixel True zoom gui.phone_zoom * (1.12 if horizontal else 1.0)
xpos xpos xanchor xanchor
@ -148,7 +178,7 @@ screen _phone(xpos=0.5, xanchor=0.5, ypos=0.05, yanchor=0.0, horizontal=False):
fixed style "empty":
for o in phone.config.overlay_screens:
use expression o
use expression o
# https://www.renpy.org/doc/html/incompatible.html#incompatible-7-5-2
# the thing just above
@ -169,7 +199,7 @@ screen _phone(xpos=0.5, xanchor=0.5, ypos=0.05, yanchor=0.0, horizontal=False):
xpos=0.501
)
else:
add phone.config.basedir + "phone_frame.png" at Transform(
add phone.asset("phone_frame.png") at Transform(
subpixel=True,
align=(0.5, 0.5),
rotate=-90 * horizontal,
@ -178,7 +208,7 @@ screen _phone(xpos=0.5, xanchor=0.5, ypos=0.05, yanchor=0.0, horizontal=False):
ypos=0.685,
xpos=0.501
)
add phone.config.basedir + "phone_glare.png" at Transform(
add phone.asset("phone_glare.png") at Transform(
subpixel=True,
align=(0.5, 0.5),
rotate=-90 * horizontal,
@ -188,34 +218,10 @@ screen _phone(xpos=0.5, xanchor=0.5, ypos=0.05, yanchor=0.0, horizontal=False):
xpos=0.501,
alpha=0.1
)
on "hide" action (
SetVariable("phone.system.at_list", []),
)
# Deprecated stuff
label _phone_register:
$ raise Exception("The label '_phone_register' isn't needed anymore")
init -500 python in phone:
def register_group_chat(group, *keys):
raise Exception("The 'phone.register_group_chat' function isn't needed anymore")
def register(f):
raise Exception("The `phone.register` decorator isn't used anymore. (function being decorated: {})".format(f.__name__))
def _run_on_start(f, id):
def run(load):
if id not in _id_ran_on_start:
_id_ran_on_start.add(id)
f()
if load: renpy.block_rollback()
renpy_config.start_callbacks.append(renpy.partial(run, load=False))
renpy_config.after_load_callbacks.append(renpy.partial(run, load=True))
default -1000 phone._id_ran_on_start = set()
init 1500:
# narrator is guarenteed to exist at init 1400
# see renpy/common/00definitions.rpy
@ -231,4 +237,11 @@ init 1500:
raise Exception("store.PhoneReturn is a reserved name. (value is %r)" % store.PhoneReturn)
store.PhoneReturn = PhoneReturn
if store.is_renpy_version_or_above(7, 6, 0):
renpy_config.detached_layers.append(config.video_call_layer)
# https://github.com/renpy/renpy/issues/5044
renpy_config.layer_clipping[config.video_call_layer] = (0, 0, renpy_config.screen_width, renpy_config.screen_height)
# previous name, when the function it's used in was undocumented
default -1000 phone._id_ran_on_start = set()

View File

@ -5,16 +5,20 @@ screen app_base(action=NullAction()):
ysize 50 + (gui.phone_status_bar_height * bool(phone.config.status_bar))
top_padding 10 + (gui.phone_status_bar_height * bool(phone.config.status_bar))
textbutton _("< Back"):
xoffset 20
action (action, PhoneReturn())
sensitive phone.menu
transclude
style app_base_frame is empty:
background "#F2F2F2"
xfill True
xpadding 10
bottom_padding 10
# bottom_padding has been changed from 10 and added top_padding to use a hacky way of visually centering the
# top texts of the ui.
bottom_padding 7
top_padding 3
style app_base_hbox is empty:
spacing 5
@ -23,13 +27,13 @@ style app_base_hbox is empty:
style app_base_text is empty:
outlines [ ]
yalign 0.5
color "#000" size 19
font phone.config.basedir + "Aller_Rg.ttf"
color "#000" size 22
font phone.asset("Aller_Rg.ttf")
style app_base_button is empty:
yalign 0.5
xalign 0.0
style app_base_button_text is app_base_text:
color "#0094FF"
size 18
color "#0094FF"
size 22

View File

@ -1,25 +1,18 @@
init -100 python in phone.application:
from renpy import store
from store import (
Gradient, RoundedFrame, Transform,
Gradient, RoundedCorners, Transform,
Text, phone, NullAction, Fixed, gui, Null, Flatten
)
from store.phone import config
def IconBackground(d, **kwargs):
return RoundedFrame(
return RoundedCorners(
d, radius=gui.phone_application_rounded_corners_radius,
xysize=(gui.phone_application_icon_size, gui.phone_application_icon_size),
**kwargs
)
def Borders(color, width):
return IconBackground(
Null(gui.phone_application_icon_size, gui.phone_application_icon_size),
outline_color=color,
outline_width=width
)
def GradientBackground(start_color, end_color, theta=0):
return IconBackground(Gradient(start_color, end_color, theta))
@ -78,7 +71,7 @@ init -100 python in phone.application:
Returns `True` if added, `False` if it failed, or `None` if renpy is still init phase and we can't know.
"""
if renpy.is_init_phase():
phone._run_on_start(renpy.partial(add_application, app, page, key), ("_phone_add_app", app.name, page, key))
phone.execute_default(renpy.partial(add_application, app, page, key), ("_phone_add_app", app.name, page, key))
return None
if not isinstance(app, Application):
@ -111,7 +104,7 @@ init -100 python in phone.application:
def add_app_to_all_characters(app, page=0):
if renpy.is_init_phase():
phone._run_on_start(renpy.partial(add_app_to_all_characters, app, page), ("_phone_add_app", app.name, page))
phone.execute_default(renpy.partial(add_app_to_all_characters, app, page), ("_phone_add_app", app.name, page))
return None
rv = False
@ -141,10 +134,7 @@ screen phone():
current_page = min(current_page, max_page)
fixed style_prefix "phone_main":
frame style "empty":
align (1.0, 0.0) padding (10, 10)
background "#474747"
textbutton "Quit" action PhoneReturn()
button style "empty" xysize (1.0, 1.0) action If(coords_to_move is None, PhoneReturn(), SetScreenVariable("coords_to_move", None))
if coords_to_move is not None:
key "K_ESCAPE" action SetScreenVariable("coords_to_move", None)
@ -156,7 +146,7 @@ screen phone():
rotate -90 transform_anchor True
xysize (150, 30) matrixcolor TintMatrix("#474343ee")
action SetScreenVariable("current_page", current_page - 1)
add phone.config.basedir + "arrow_icon.png"
add phone.asset("arrow_icon.png")
if current_page != max_page:
button:
@ -165,7 +155,7 @@ screen phone():
rotate 90 transform_anchor True
xysize (150, 30) matrixcolor TintMatrix("#474343ee")
action SetScreenVariable("current_page", current_page + 1)
add phone.config.basedir + "arrow_icon.png"
add phone.asset("arrow_icon.png")
use _phone():
style_prefix "phone_main"
@ -187,7 +177,7 @@ screen phone():
vbox:
hbox xalign 0.5 spacing 13:
for i in range(max_page + 1):
add phone.config.basedir + "circle.png":
add phone.asset("circle.png"):
at transform:
subpixel True xysize (10, 10)
matrixcolor TintMatrix("#4e4e4e")
@ -255,10 +245,7 @@ screen _phone_application_button(app, app_coords, coords_to_move):
button:
at (_phone_move_application_selected if app_coords == coords_to_move else _phone_move_application)
if app is None:
add phone.application.Borders("#ffffffcc", 5)
else:
add phone.application.IconBackground("#ffffffcc")
add phone.application.IconBackground("#ffffffcc")
action [
Function(phone.application.move_application, coords_to_move, app_coords),
@ -298,7 +285,7 @@ style _phone_application_button_vbox is empty:
style _phone_application_button_text is empty:
text_align 0.5 xalign 0.5
outlines [ ] color "#000"
size 12 font phone.config.basedir + "Metropolis-Regular.otf"
size 12 font phone.asset("Metropolis-Regular.otf")
line_spacing 0
style _phone_application_button_fixed is empty:

View File

@ -110,25 +110,27 @@ init -100 python in phone.calendar:
def day_name(year, month, day):
return days[calendar.weekday(year, month, day)]
def add_calendar(calendar, key=None):
def add_calendar(year, month, key=None, first_day=SUNDAY):
if renpy.is_init_phase():
phone._run_on_start(renpy.partial(add_calendar, calendar, key), ("_phone_add_calendar", calendar.month, calendar.year, key))
phone.execute_default(renpy.partial(add_calendar, year=year, month=month, key=key, first_day=first_day), ("_phone_add_calendar", month, year, key))
else:
key = character.character(key).key
store.phone.data[key]["calendars"].append(calendar)
def add_calendar_to_all_characters(calendar):
if get_calendar(year=year, month=month, key=key) is not None:
raise Exception("a calendar for the year {} and month {} already exists for the *character* {}" \
.format(year, month, key))
calendars = store.phone.data[key]["calendars"]
calendars.append(Calendar(year=year, month=month, first_day=first_day))
calendars.sort(key=lambda c: (c.year, c.month))
def add_calendar_to_all_characters(year, month, first_day=SUNDAY):
if renpy.is_init_phase():
phone._run_on_start(renpy.partial(add_calendar_to_all_characters, calendar), ("_phone_add_calendar", calendar.month, calendar.year))
phone.execute_default(renpy.partial(add_calendar_to_all_characters, year=year, month=month, first_day=first_day), ("_phone_add_calendar", month, year))
else:
l = calendar.lenght(False)
for key in character._characters:
_calendar = Calendar(calendar.month, calendar.year, calendar.firstweekday)
for i in range(l):
_calendar[i].description = calendar[i].description
add_calendar(_calendar, key)
add_calendar(year=year, month=month, first_day=first_day, key=key)
_calendar_button_background = At(config.basedir + "circle.png", store._fits(None))
@ -139,11 +141,31 @@ init -100 python in phone.calendar:
return calendar
return None
def _calendar_default_index(m):
n = config.default_calendar_index
if n is True:
pov_key = store.pov_key
date = system.get_date()
c = get_calendar(year=date.year, month=date.month, key=pov_key)
if c is None:
raise Exception("no calendar with the year {} and month {} exists for the *character* {}".format(year, month, pov_key))
n = phone.data[pov_key]["calendars"].index(c)
elif n < 0:
n = m + n
return n
screen phone_calendars():
default calendars = phone.data[pov_key]["calendars"]
default m = len(calendars) - 1
default n = m
default n = phone.calendar._calendar_default_index(m + 1)
default selected_entry = None
default yadj = ui.adjustment()
$ calendar = calendars[n]
@ -185,6 +207,7 @@ screen phone_calendars():
SetScreenVariable("selected_entry", entry),
SetScreenVariable("selected_entry", None)
),
Function(yadj.change, 0),
SelectedIf(selected_entry is entry)
)
@ -202,15 +225,16 @@ screen phone_calendars():
side "l c r" xalign 0.5:
textbutton "<" action If(n != 0, (SetScreenVariable("n", n - 1), SetScreenVariable("selected_entry", None)))
text _("[calendar.month_name]-[calendar.year]") size 25 xalign 0.5 text_align 0.5
text _("[calendar.month_name!t]-[calendar.year]") size 25 xalign 0.5 text_align 0.5
textbutton ">" action If(n != m, (SetScreenVariable("n", n + 1), SetScreenVariable("selected_entry", None)))
frame:
frame at CurriedRoundedCorners(radius=(0, 25, 0, 25)):
vbox spacing 3 at Flatten:
text _("Notes:") size 22
viewport:
draggable True mousewheel True
yadjustment yadj
if selected_entry is not None:
if selected_entry.description is not None:
@ -232,7 +256,7 @@ style phone_calendar_button_text is empty:
outlines []
size 16
align (0.5, 0.5) text_align 0.5
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
style phone_calendar_button_text_special is phone_calendar_button_text:
size 12
@ -254,7 +278,7 @@ style phone_calendar_notes_button_text is phone_calendar_notes_text:
size 21
style phone_calendar_notes_frame is empty:
background RoundedFrame("#e0e0e0", radius=(0, 25, 0, 25))
background "#e0e0e0"
padding (13, 7, 13, 0)
xfill True ysize 180

View File

@ -35,7 +35,7 @@ screen phone_call_history():
fixed:
hbox style "empty" yalign 0.2 spacing 10:
text char.short_name
text phone.short_name(char.name, 26)
if entry.duration is not None:
text "-"
text entry._duration_to_str()

View File

@ -16,11 +16,10 @@ init -100 python in phone.calls:
from store.phone import character, config, show_layer_at, set_current_screen, system
import time
# config.layer_at_transforms["phone_call"] = call_blur
# config.layer_at_transforms["phone_call"] = Transform(matrixcolor=BrightnessMatrix(-0.21), blur=20)
# config.hide_status_bar_screens.append("phone_call")
def call(caller):
def call(caller, video=False, nosave=False):
global _current_caller
if _current_caller is not None:
raise Exception("can't have 2 phone calls at the same time")
@ -28,13 +27,16 @@ init -100 python in phone.calls:
# store.narrator = store._phone_narrator
store._window_hide()
set_current_screen("phone_call")
show_layer_at([call_blur])
renpy.show_screen("phone_call")
renpy.with_statement(config.enter_transition)
renpy.show_screen("phone_call", video=video)
renpy.with_statement(config.enter_transition)
store._window_auto = True
global _nosave
_nosave = bool(nosave)
def end_call():
store._window_hide()
@ -50,9 +52,11 @@ init -100 python in phone.calls:
show_layer_at([call_unblur], reset=True)
renpy.hide_screen("phone_call")
if store.is_renpy_version_or_above(7, 5, 0):
renpy.scene(config.video_call_layer)
renpy.with_statement(config.exit_transition)
set_current_screen(None)
set_current_screen(None)
store._window_auto = True
class _CallEntry(object):
@ -71,14 +75,19 @@ init -100 python in phone.calls:
date = system.get_date()
ch1 = phone.data[key1]["call_history"]
ch1.append(_CallEntry(key2, date, duration))
global _nosave
if _nosave is not None and not _nosave:
_nosave = None
ch1 = phone.data[key1]["call_history"]
ch1.append(_CallEntry(key2, date, duration))
while len(ch1) > config.call_history_lenght: ch1.pop(0)
ch2 = phone.data[key2]["call_history"]
ch2.append(_CallEntry(key1, date, duration))
while len(ch1) > config.call_history_lenght: ch1.pop(0)
while len(ch2) > config.call_history_lenght: ch2.pop(0)
ch2 = phone.data[key2]["call_history"]
ch2.append(_CallEntry(key1, date, duration))
default -100 phone.calls._current_caller = None
while len(ch2) > config.call_history_lenght: ch2.pop(0)
default -100 phone.calls._current_caller = None
default -100 phone.calls._nosave = None

View File

@ -6,28 +6,35 @@ init -100 python in phone.calls:
default phone.calls._call_time_st = 0.0
screen phone_call():
use _phone():
style_prefix "phone_call"
screen phone_call(video=False):
use _phone(xpos=gui.phone_call_xpos, xanchor=0.0):
add Solid("#302D29")
vbox:
text phone.calls._current_caller.name alt ""
add DynamicDisplayable(phone.calls._call_time) alt ""
if video and is_renpy_version_or_above(7, 6, 0): # _phone_video_call uses the `Layer` displayable
use _phone_video_call()
else:
use _phone_call()
#if not phone.config.quick_menu and quick_menu:
# use quick_menu()
frame:
add phone.calls._current_caller.icon at _fits(None)
screen _phone_call():
style_prefix "phone_call"
if phone.config.quick_menu and quick_menu:
vbox:
text phone.short_name(phone.calls._current_caller.name, 12) alt ""
add DynamicDisplayable(phone.calls._call_time) alt ""
frame:
add phone.calls._current_caller.icon at _fits(None)
if phone.config.quick_menu and quick_menu:
frame style "empty" xalign 0.5 ypos 0.45:
use phone_quick_menu()
add phone.config.basedir + "hang_up.png":
subpixel True zoom 0.35
xalign 0.5 ypos 0.8
# if not phone.config.quick_menu and quick_menu:
# use quick_menu()
add phone.asset("hang_up.png"):
subpixel True xysize (63, 63)
xalign 0.5 ypos 0.8
style phone_call_vbox is empty:
spacing 3
@ -40,7 +47,7 @@ style phone_call_text is empty:
outlines [ ]
line_spacing 0
size 24
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
hyperlink_functions hyperlink_functions_style("phone_call_text_hyperlink")
style phone_call_text_hyperlink is phone_call_text:
@ -54,4 +61,22 @@ style phone_call_frame is empty:
xysize ( 120, 120) # :)
padding (int(22 * (120 / 404)), int(22 * (120 / 404)))
ypos 0.18
xalign 0.5
xalign 0.5
screen _phone_video_call():
style_prefix "phone_video_call"
add Layer(phone.config.video_call_layer):
at Transform(**phone.config.video_call_layer_transform_properties)
vbox:
text _("Facetime - [phone.calls._current_caller.name!t]")
add DynamicDisplayable(phone.calls._call_time)
use phone_quick_menu_video()
style phone_video_call_vbox is phone_call_vbox:
ypos 0.03
style phone_video_call_text is phone_call_text:
size 27

View File

@ -1,53 +1,50 @@
screen phone_quick_menu():
grid 3 2:
style_prefix "phone_quick_menu"
xalign 0.5 ypos 0.45
grid 3 2 style_prefix "phone_quick_menu":
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_history_idle.png"
hover phone.config.basedir + "quick_menu_history_selected.png"
selected_idle phone.config.basedir + "quick_menu_history_selected.png"
idle phone.asset("quick_menu_history_idle.png")
hover phone.asset("quick_menu_history_selected.png")
selected_idle phone.asset("quick_menu_history_selected.png")
action ShowMenu("history")
text _("History")
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_afm_idle.png"
hover phone.config.basedir + "quick_menu_afm_selected.png"
selected_idle phone.config.basedir + "quick_menu_afm_selected.png"
idle phone.asset("quick_menu_afm_idle.png")
hover phone.asset("quick_menu_afm_selected.png")
selected_idle phone.asset("quick_menu_afm_selected.png")
action Preference("auto-forward", "toggle")
text _("Auto")
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_skip_idle.png"
hover phone.config.basedir + "quick_menu_skip_selected.png"
selected_idle phone.config.basedir + "quick_menu_skip_selected.png"
idle phone.asset("quick_menu_skip_idle.png")
hover phone.asset("quick_menu_skip_selected.png")
selected_idle phone.asset("quick_menu_skip_selected.png")
action Skip()
text _("Skip")
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_settings_idle.png"
hover phone.config.basedir + "quick_menu_settings_selected.png"
selected_idle phone.config.basedir + "quick_menu_settings_selected.png"
idle phone.asset("quick_menu_settings_idle.png")
hover phone.asset("quick_menu_settings_selected.png")
selected_idle phone.asset("quick_menu_settings_selected.png")
action ShowMenu("preferences")
text _("Settings")
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_save_idle.png"
hover phone.config.basedir + "quick_menu_save_selected.png"
selected_idle phone.config.basedir + "quick_menu_save_selected.png"
idle phone.asset("quick_menu_save_idle.png")
hover phone.asset("quick_menu_save_selected.png")
selected_idle phone.asset("quick_menu_save_selected.png")
action ShowMenu("save")
text _("Save")
vbox:
imagebutton:
idle phone.config.basedir + "quick_menu_load_idle.png"
hover phone.config.basedir + "quick_menu_load_selected.png"
selected_idle phone.config.basedir + "quick_menu_load_selected.png"
idle phone.asset("quick_menu_load_idle.png")
hover phone.asset("quick_menu_load_selected.png")
selected_idle phone.asset("quick_menu_load_selected.png")
action ShowMenu("load")
text _("Load")
@ -56,4 +53,47 @@ style phone_quick_menu_grid is empty:
style phone_quick_menu_vbox is empty
style phone_quick_menu_text is phone_call_time:
size 14
size 14
screen phone_quick_menu_video():
default qm = False
default anim_time = 0.35
showif qm:
add "#000":
at transform:
alpha 0.0
on show:
ease anim_time alpha 0.35
on hide:
ease anim_time alpha 0.0
vbox style "empty" yalign 1.0 xsize 1.0 xfill True:
button style "empty" padding (5, 7, 5, 4) xalign 0.5:
at transform:
ease anim_time matrixtransform RotateMatrix(0, 0, 180 * qm) matrixcolor OpacityMatrix(0.8 if qm else 0.6)
action ToggleLocalVariable("qm")
add phone.asset("arrow_icon.png"):
at transform:
subpixel True xysize (70, 18)
showif qm:
frame style "empty" top_padding 30 bottom_padding 15 xsize 1.0 modal True:
at transform:
subpixel True crop (0, 0, 1.0, 0.0)
on show:
ease anim_time crop (0, 0, 1.0, 1.0) alpha 1.0
on hide:
ease anim_time crop (0, 0, 1.0, 0.0) alpha 0.0
background "#00000060"
vbox style "empty" xalign 0.5:
use phone_quick_menu()
null height 15
add phone.asset("hang_up.png"):
subpixel True xysize (63, 63) xalign 0.5

View File

@ -30,8 +30,8 @@ style phone_say_dialogue is empty:
ypos 0.0
outlines [ ]
color "#fff"
font "gui/FallingSky.otf"
font phone.asset("FallingSky.otf")
style phone_say_label is phone_say_dialogue:
font phone.config.basedir + "JetBrainsMono-ExtraBold.ttf"
font phone.asset("FallingSky.otf")
size 27

View File

@ -34,21 +34,20 @@ screen phone_contacts():
PhoneMenu("phone_discussion")
)
$ sender, message = group_chat._get_display_last_message()
hbox:
add group_chat.icon at _fits(46) yalign 0.5
fixed:
text message yalign 0.2:
text phone.short_name(group_chat.name, 26) yalign 0.2:
if group_chat.unread:
color "#000"
text _("The [group_chat._date_text] at [group_chat._hour_text]"):
style "phone_contacts_date_text" yalign 1.0
if sender is not None:
text sender.short_name style "phone_contacts_date_text" align (1.0, 1.0)
text (
_("The [group_chat._date_text] at [group_chat._hour_text]")
if group_chat.number_of_messages != 0
else _("Empty group chat")
):
style "phone_contacts_date_text" yalign 1.0
style phone_contacts_side is empty:
xfill True
@ -74,7 +73,7 @@ style phone_contacts_text is empty:
outlines [ ]
color "#525252"
size 18
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
style phone_contacts_no_friends is phone_contacts_text:
color "#000"

View File

@ -31,20 +31,19 @@ init -100 python in phone.discussion:
return
else:
raise Exception("group chat not given (no previous group chat was found)")
if _group_chat is not None:
raise Exception("preparing group chat while another convesation is going on")
gc = group_chat(gc)
if not gc._characters:
raise Exception("group chat '{}' has no characters".format(gc.name))
_group_chat = gc
_group_chat.unread = False
store._window_hide()
_yadjustment.value = float("inf")
set_current_screen("phone_discussion")
show_layer_at([disc_blur])
renpy.show_screen("phone_discussion")
@ -53,23 +52,25 @@ init -100 python in phone.discussion:
store._window_auto = True
def end_discussion():
store._window_hide()
global _group_chat
if _group_chat is None:
raise Exception("ending discussion, but no discussion ever started")
if _group_chat is None: return
store._window_hide()
for key in _group_chat._characters:
sort_messages(key)
if _group_chat.ephemeral:
_group_chat.clear_payload()
if _group_chat.transient:
_group_chat.clear()
_group_chat = None
show_layer_at([disc_unblur], reset=True)
renpy.hide_screen("phone_discussion")
renpy.with_statement(config.exit_transition)
set_current_screen(None)
store._window_auto = True
class _Payload(object):
@ -120,7 +121,6 @@ init -100 python in phone.discussion:
if _group_chat._page == 0:
_yadjustment.value = float("inf")
_current_payload = None
if not no_pause:
@ -144,7 +144,6 @@ init -100 python in phone.discussion:
dc.send(delay)
def register_message(group, sender, text):
_check_for_tags(text)
@ -299,6 +298,10 @@ init -100 python in phone.discussion:
p = _Payload(sender.key, audio, AUDIO)
group._save_payload(p)
_run_callbacks(group, "save", p)
_yadjustment = ui.adjustment()
def add_history(sender,text):
@ -340,8 +343,6 @@ init -100 python in phone.discussion:
while len(history) > history_length:
history.pop(0)
_yadjustment = ui.adjustment()
default -100 phone.discussion._current_payload = None
default -100 phone.discussion._group_chat = None
@ -374,7 +375,7 @@ init python in phone.discussion:
from store.phone.character import character
init 1400 python in phone:
@renpy.partial(_run_on_start, id="__sort_register_messages")
@renpy.partial(execute_default, id="__sort_register_messages")
def __sort_register_messages():
global data
for key in data:

View File

@ -1,13 +1,13 @@
screen phone_discussion():
key ["mouseup_1", "mouseup_3"] action Function(renpy.end_interaction, True) capture False
use _phone():
key ["mouseup_1", "mouseup_3", "K_UP"] action Function(renpy.end_interaction, True) capture True
side "t b c":
use app_base(action=(SetField(phone.discussion, "_group_chat", None), Function(phone.discussion.audio_messages.reset))):
style_prefix "app_base"
hbox:
add phone.discussion._group_chat.icon at _fits(36) yalign 0.5
text phone.discussion._group_chat.short_name alt ""
text phone.short_name(phone.discussion._group_chat.name, 9) alt ""
use _chat_textbox()
use _chat_messages()
@ -17,6 +17,7 @@ init -100 python in phone.discussion:
class _AutoScrollVP(renpy.display.layout.Container):
"""
Actual dark magic...
filtered, not even joking
"""
def __init__(self, vp):
super(_AutoScrollVP, self).__init__(vp)
@ -34,7 +35,6 @@ init -100 python in phone.discussion:
adjusted_st, _ = self.adj_text.adjusted_times()
delta = min(1.0, adjusted_st / text_time)
# not really its size, but the width of what has been rendered
# | |
# | This is a super dup |
@ -49,27 +49,31 @@ init -100 python in phone.discussion:
return super(_AutoScrollVP, self).render(w, h, st, at)
screen _chat_textbox():
style_prefix "phone_textbox"
frame: # ugly double framing but whatever, we're rolling with it otherwise it make the entire phone stretch outwards.
top_margin 10 # Part of the revised phone ui. Needed to avoid clipping
hbox:
frame:
style "phone_text_inputbox"
if phone.discussion._current_payload is not None and phone.discussion._current_payload.source is not None:
$ sender = phone.character.character(phone.discussion._current_payload.source)
if (
sender.is_pov and
phone.discussion._current_payload.type == phone.discussion._PayloadTypes.TEXT
):
fixed style "empty":
yfill True
xsize 0.9
frame:
side "l r":
if phone.discussion._current_payload is not None and phone.discussion._current_payload.source is not None:
$ sender = phone.character.character(phone.discussion._current_payload.source)
if (
sender.is_pov and
phone.discussion._current_payload.type == phone.discussion._PayloadTypes.TEXT
):
fixed style "empty":
yfill True
xsize 0.9
viewport at phone.discussion._AutoScrollVP style "empty":
draggable False
mousewheel False
yalign 0.5
xoffset 11 #don't add it to Text()
viewport at phone.discussion._AutoScrollVP style "empty":
draggable False
mousewheel False
yalign 0.5
frame style "phone_textbox_typing_text_frame":
add renpy.display.layout.AdjustTimes(
frame style "phone_textbox_typing_text_frame":
add renpy.display.layout.AdjustTimes(
Text(
" " + __(phone.discussion._current_payload.data),
style="phone_textbox_text",
@ -78,18 +82,33 @@ screen _chat_textbox():
None,
None
)
else:
text _("Type a message.") color "#666" alt "" xoffset 11
# ugly ahh
# to the genius who tried removing the top conditional, no, the phone creator did this hack for a reason
# you gargoyle
else:
text _(" Type a message.") color "#666" alt ""
# ugly ahh
else:
text _(" Type a message.") color "#666" alt ""
text _("Type a message.") color "#666" alt "" xoffset 11
text _("Send ") color "#0094FF" xalign 1.0 alt ""
frame:
style "phone_text_sendbutton"
text _("Send") color "#0094FF" xalign 0.0 alt ""
style phone_text_inputbox is empty:
ysize 52 xsize 0.875
padding (10, 5, 0)
background RoundedCorners(Solid("#F2F2F2"), radius=phone.config.textbox_radius, outline_width=2.0, outline_color="#9b9b9b")
style phone_text_sendbutton is empty:
padding (8, 10, 0)
ysize 50
style phone_textbox_frame is empty:
ysize 50 xfill True
background "#F2F2F2"
xsize 0.94
xoffset 12
yoffset -20
padding (10, 10)
style phone_textbox_side is empty:
@ -98,11 +117,11 @@ style phone_textbox_side is empty:
style phone_textbox_text is empty:
outlines [ ]
size 16
size 22 #unbearable to read at 18
color "#000"
line_leading 0
line_spacing 0
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
yalign 0.5
layout "nobreak"
@ -110,6 +129,8 @@ style phone_textbox_typing_text_frame is empty:
yfill True
screen _chat_message(p):
style_prefix "phone_messages"
@ -140,6 +161,7 @@ screen _chat_messages():
viewport style "empty" at Flatten:
yadjustment phone.discussion._yadjustment
ymaximum 715 # Part of the revised phone ui. Needed to make room for the margin property in the textbox.
draggable True
mousewheel True
yinitial 1.0
@ -148,7 +170,7 @@ screen _chat_messages():
frame style "empty":
yalign 1.0
padding (10, 10)
padding (10, 20, 10, 40)
vbox:
if phone.discussion._group_chat._can_load_more():
@ -156,7 +178,6 @@ screen _chat_messages():
action (
Function(phone.discussion._group_chat._page_up),
SetField(phone.discussion._yadjustment, "value", float("inf")),
SetLocalVariable("_label", False),
Function(phone.discussion.audio_messages.reset)
)
bottom_margin 5
@ -169,13 +190,12 @@ screen _chat_messages():
null height gui.phone_message_label_null_height
text p.data style "phone_messages_text_label"
else:
if _label:
$ _label = False
null height gui.phone_message_label_null_height
if p.type == phone.discussion._PayloadTypes.TEXT:
if p.type == phone.discussion._PayloadTypes.TEXT:
use _chat_message(p):
if i != phone.discussion._group_chat.number_of_messages-1 or renpy.get_screen("say"):
text p.data alt ""
@ -184,7 +204,6 @@ screen _chat_messages():
text p.data alt sender + ": " + p.data
# $print(dir(phone.discussion._group_chat))
elif p.type == phone.discussion._PayloadTypes.IMAGE:
use _chat_message(p):
imagebutton:
@ -193,7 +212,7 @@ screen _chat_messages():
fit "scale-down"
idle p.data
action Show("_phone_image", dissolve, img=p.data)
action Show("_phone_image", Dissolve(0.5), img=p.data)
elif p.type == phone.discussion._PayloadTypes.AUDIO:
use _chat_message(p):
@ -202,7 +221,7 @@ screen _chat_messages():
add DynamicDisplayable(phone.discussion.audio_messages.button_image, p=p)
action Function(phone.discussion.audio_messages.play_audio, p, p.data),
add phone.config.basedir + "audio_message_wave_icon.png":
add phone.asset("audio_message_wave_icon.png"):
at _fits(None), phone.discussion.audio_messages.AudioWave(p)
else:
@ -214,15 +233,17 @@ screen _chat_messages():
if _label:
$ _label = False
null height gui.phone_message_label_null_height
for i, caption in enumerate(phone.discussion._current_payload.data):
textbutton caption:
style_prefix "phone_messages_choice"
action Return(caption)
at transform:
frame style "empty":
at transform: # support for versions that can't have `at` and `at transform` at the same time
subpixel True alpha 0.0 xoffset -20 xalign 1.0
i / 9
ease_quad 0.35 alpha 1.0 xoffset 0
textbutton caption at CurriedRoundedCorners(radius=phone.config.textbox_radius):
style_prefix "phone_messages_choice"
action Return(caption)
else:
$ sender = phone.character.character(phone.discussion._current_payload.source)
@ -234,7 +255,6 @@ screen _chat_messages():
if phone.discussion._current_payload.type == phone.discussion._PayloadTypes.IMAGE:
use _chat_message(phone.discussion._current_payload):
text _("{u}{i}Loading Image...{i}{/u}")
elif phone.discussion._current_payload.type == phone.discussion._PayloadTypes.AUDIO:
use _chat_message(phone.discussion._current_payload):
text _("{u}{i}Loading Audio...{i}{/u}")
@ -243,19 +263,17 @@ screen _chat_messages():
use _chat_message(phone.discussion._current_payload):
text _("{u}{i}Loading Video...{i}{/u}")
else:
else:
if _label:
$ _label = False
null height gui.phone_message_label_null_height
use _phone_message_typing(sender)
if phone.discussion._group_chat._page > 0:
textbutton _("Go Back"):
action (
Function(phone.discussion._group_chat._page_down),
SetField(phone.discussion._yadjustment, "value", 0.0),
SetLocalVariable("_label", False),
Function(phone.discussion.audio_messages.reset)
)
top_margin 5
@ -267,7 +285,7 @@ screen _phone_image(img):
add img:
align (0.5, 0.5)
key ["mouseup_1", "mouseup_3"] action Hide("_phone_image", dissolve)
key ["mouseup_1", "mouseup_3"] action Hide("_phone_image", Dissolve(0.5))
style phone_messages_button is empty:
xalign 0.5
@ -276,24 +294,24 @@ style phone_messages_button_text is phone_say_dialogue:
xalign 0.5
text_align 0.5
ypos 0.0
size 16
size 22
color "#000"
style phone_messages_vbox is empty:
spacing 5
yalign 1.0
xfill True
xfill True
style phone_messages_hbox is empty:
spacing 5
style phone_messages_text is empty:
outlines [ ]
size 22
size 24
line_leading 0
line_spacing 0
layout "greedy"
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
hyperlink_functions hyperlink_functions_style("phone_messages_text_hyperlink")
style phone_messages_text is empty:
@ -310,19 +328,19 @@ style phone_messages_frame is empty:
style phone_messages_text_label is phone_messages_text:
color "#000"
xalign 0.5 text_align 0.5
size 15
size 20
xsize 0.8
style phone_messages_choice_button is phone_messages_frame:
background RoundedFrame(Solid("#eeeeee"), radius=phone.config.textbox_radius, outline_width=2.0, outline_color="#9b9b9b")
hover_background RoundedFrame(Solid("#b4b4b4"), radius=phone.config.textbox_radius, outline_width=2.0, outline_color="#4d4d4d")
background "#eeeeee"
hover_background "#b4b4b4"
padding (12, 8)
style phone_messages_choice_button_text is phone_messages_text:
color "#000"
outlines [ ]
yalign 0.5
size 18
size 22
layout "tex"
style phone_messages_audio_hbox is empty:

View File

@ -1,28 +1,23 @@
init -100 python in phone.group_chat:
from renpy import store
from store import __, phone
from renpy.store import store, phone
import datetime
# The max lenght of a *group chat*'s name shortened.
short_name_length = 9
# How many messages we display at the same time.
messages_displayed = 175
# If the next "load" of messages contains this many or less messages, add those messages to the current load.
messages_fill_if_lower = 15
config = phone.config
class GroupChat(object):
def __init__(self, name, icon, key, ephemeral=False):
transient = False
_unread = True
def __init__(self, name, icon, key, transient=False):
global _group_chats
_group_chats[key] = self
self.name = name
self.icon = icon
self.date = datetime.datetime(year=1970, month=1, day=1, hour=0, minute=0)
self.ephemeral = ephemeral
self.transient = transient
self.unread = True
self._unread = True
self._characters = set()
self._payloads = [ ]
@ -30,16 +25,23 @@ init -100 python in phone.group_chat:
if key is None: raise ValueError("key may not be 'None'")
self.key = key
# deprecated
self.short_name = name
@property
def short_name(self):
global short_name_length
name = __(self.name)
if len(name) > short_name_length:
name = name[:short_name_length - 3] + "..."
return name
def unread(self):
if not config.unread_group_chat_pov:
return self._unread
return phone.data[store.pov_key]["group_chat_unread_pov"].setdefault(self.key, True)
@unread.setter
def unread(self, v):
if not config.unread_group_chat_pov:
self._unread = v
else:
phone.data[store.pov_key]["group_chat_unread_pov"][self.key] = v
def add_character(self, char):
if isinstance(char, list):
for c in char:
@ -74,67 +76,27 @@ init -100 python in phone.group_chat:
@property
def number_of_messages(self):
return self.number_of_messages_sent(None)
def clear(self):
self._payloads.clear()
def _can_load_more(self):
if not self._payloads: return False
return next(self._get_messages()) is not self._payloads[0]
def _get_display_last_message(self):
italic = True
if not self._payloads:
sender = None
message = __("Empty group chat")
else:
p = self._payloads[-1]
sender = p.source
if sender is not None: sender = character(sender)
_type = p.type
if _type == _PayloadTypes.TEXT:
message = renpy.substitute(p.data)
italic = False
elif _type == _PayloadTypes.IMAGE:
message = __("Image sent")
elif _type == _PayloadTypes.LABEL:
message = renpy.substitute(p.data)
elif _type == _PayloadTypes.DATE:
message = p.data
elif _type == _PayloadTypes.AUDIO:
message = __("Audio sent")
elif _type == _PayloadTypes.VIDEO:
message = __("Video sent")
message = remove_text_tags(message)
LIMIT = 27
if len(message) >= LIMIT:
message = message[:LIMIT - 3] + "..."
if italic:
message = "{i}" + message + "{/i}"
return (sender, message)
return self._get_messages()[0] is not self._payloads[0]
def _get_messages(self):
global messages_displayed
messages_displayed = config.messages_displayed
min_x = self._page * messages_displayed
max_x = min_x + messages_displayed
global messages_fill_if_lower
remaining = len(self._payloads) - max_x
if remaining <= messages_fill_if_lower:
l = len(self._payloads)
remaining = l - max_x
if remaining <= config.messages_fill_if_lower:
max_x += remaining
return reversed(self._payloads[::-1][min_x:max_x])
return self._payloads[l-max_x:l-min_x]
@property
def _date_text(self):
@ -171,9 +133,6 @@ init -100 python in phone.group_chat:
def __len__(self):
return len(self._payloads)
def clear_payload(self):
self._payloads=[]
def __hash__(self):
return hash(self.key)

View File

@ -19,7 +19,7 @@ screen _phone_message_typing(sender):
text "⚫" at _phone_message_typing(0.2) alt ""
text "⚫" at _phone_message_typing(0.4) alt ""
text _("[sender.short_name!t] is typing...") style "phone_typing_istyping" yalign 0.5 alt ""
text __("{short_name} is typing...").format(short_name=phone.short_name(sender.name, 9)) style "phone_typing_istyping" yalign 0.5 alt ""
style phone_typing_hbox is empty:
spacing 3
@ -34,5 +34,9 @@ style phone_typing_text is phone_messages_text:
style phone_typing_istyping is empty:
color "#626262"
outlines [ ]
size 16
font phone.config.basedir + "Aller_Rg.ttf"
size 22
font phone.asset("Aller_Rg.ttf")
init python:
if is_renpy_version_or_above(7, 7, 0):
style.phone_typing_text.emoji_font = None

View File

@ -1,17 +1,9 @@
init -100 python in phone.character:
from renpy import store
from store import Color, __, RoundedFrame
from renpy.store import store, Color, __, RoundedCorners, phone
from store.phone import config
# The max lenght of a *character*'s name shortened.
character_short_name_length = 16
# A number of seconds added to the pause before each message.
message_delay = 0.6
class Character(object):
def __init__(self, name, icon, key, cps, color):
global _characters
_characters[key] = self
self.name = name
@ -23,26 +15,19 @@ init -100 python in phone.character:
if key is None: raise ValueError("key may not be 'None'")
self.key = key
# deprecated
self.short_name = name
def get_textbox(self):
return get_textbox(self.color)
@property
def short_name(self):
global character_short_name_length
name = __(self.name)
if len(name) > character_short_name_length:
name = name[:character_short_name_length - 3] + "..."
return name
@property
def is_pov(self):
return self.key == store.pov_key
def get_typing_delay(self, message, substitute=True):
global message_delay
if substitute: message = renpy.substitute(message)
return (len(message) / self.cps) + message_delay
def get_typing_delay(self, message, substitute=True, translate=True):
if substitute: message = renpy.substitute(message, translate=translate)
return (len(message) / self.cps) + config.message_delay
def __hash__(self):
return hash(self.key)
@ -51,14 +36,14 @@ init -100 python in phone.character:
if isinstance(x, Character): return x
if x is None: x = store.pov_key
if not has_character(x):
raise KeyError("nno phone Character with the key %r exists (check your definitions)" % x)
raise KeyError("no phone Character with the key %r exists (check your definitions)" % x)
return _characters[x]
def has_character(key):
return key in _characters
def get_textbox(color):
return RoundedFrame(color, radius=config.textbox_radius)
return RoundedCorners(color, radius=config.textbox_radius)
def get_all():
return list(_characters.values())

View File

@ -5,8 +5,7 @@ init -100 python in phone.discussion:
config.enter_transition = easeinbottom
python early in phone.config:
from renpy import store
from store import Dissolve, _warper, _, phone, Transform
from renpy.store import store, config as renpy_config, Dissolve, _warper, _, phone, Transform
_constant = True
# Where the assets are located.
@ -55,8 +54,14 @@ python early in phone.config:
# A dictionary mapping screen names to transforms or lists of transforms.
# When a phone screen is shown, the screen name is looked up in the map (None is used if not found),
# and the layer "master" is shown at those transforms.
layer_at_transforms = { }
# `None` is set later
layer_at_transforms = {
None: Transform(matrixcolor=renpy.display.matrix.Matrix([1, 0, 0, -0.03, # BrightnessMatrix(-0.03)
0, 1, 0, -0.03,
0, 0, 1, -0.03,
0, 0, 0, 1]),
blur=2
)
}
# How many "pages" of application we use in the `phone` screen.
applications_pages = 4
@ -70,6 +75,7 @@ python early in phone.config:
"group_chats": list,
"background_image": lambda: None,
"calendars": list,
"group_chat_unread_pov": dict
}
def _generate_applications_dict():
@ -108,6 +114,51 @@ python early in phone.config:
# -For a video, `None`.
discussion_callbacks = [ ]
init -1400 python in phone.config:
from store import BrightnessMatrix
layer_at_transforms[None] = None
# The name of the layer usied in video calls. It is appended to `config.detached_layers`
video_call_layer = "phone_video_call"
# A dict of transform properties applied to the `Layer` displayable used during a video call.
video_call_layer_transform_properties = {
"align": (0.5, 1.0),
"ysize": 1.0,
"fit": "contain"
}
# How many messages we display at the same time.
messages_displayed = 175
# If the next "load" of messages contains this many or less messages, add those messages to the current load.
messages_fill_if_lower = 15
# A number of seconds added to the pause before each message.
message_delay = 0.6
# An index. The default calendar used when the `phone_calendars` screen is shown.
# If `True`, tries to retrieve the calendar that's in concordance to `phone.system.get_date()`.
default_calendar_index = -1
# If true, a group chat's "unreadness" is determined on the pov the group chat was read in.
# I.e, if the group chat was read in the "mc" pov, then it won't be marked as read in the "s" pov.
# If false, it is determined by whether the player has opened the group chat or not.
unread_group_chat_pov = False
# If true, will define all images found in "assets/emojis" as emojis.
auto_emojis = True
# The default value of the `delay` property for the `time` and `label` discussion statements.
default_label_delay = 0.5
python early: # prevent "default"
config.special_namespaces["store.phone.config"] = type(config.special_namespaces["store.config"])(phone.config, "phone.config")
init 1500 python in phone:
@renpy_config.after_load_callbacks.append
def __ensure_phone_data_entries():
changed = False
for d in data.values():
for thing, f in config.data.items():
if thing not in d:
d[thing] = f()
changed = True
if changed:
renpy.block_rollback()

View File

@ -1,16 +1,15 @@
default pc_damien = phone.character.Character("D-Man", phone.asset("damien_icon.png"), "D", 24, "#22Abf8")
default pc_olivia = phone.character.Character("Liv-Long", phone.asset("olivia_icon.png"), "O", 40, "#22Abf8")
default pc_sophia = phone.character.Character("Ms.P", phone.asset("sophia_icon.png"), "S", 20, "#22Abf8")
default pc_liz = phone.character.Character("Liz", phone.asset("liz_icon.png"), "L", 35, "#484848")
default pc_inco = phone.character.Character("Inco", phone.asset("inco_icon.png"), "I", 35, "#484848")
default pov_key = "I"
default pc_damien = phone.character.Character("D-Man", phone.config.basedir + "damien_icon.png", "D", 24, "#22Abf8")
default pc_olivia = phone.character.Character("Liv-Long", phone.config.basedir + "olivia_icon.png", "O", 40, "#22Abf8")
default pc_sophia = phone.character.Character("Ms.P", phone.config.basedir + "sophia_icon.png", "S", 20, "#22Abf8")
default pc_liz = phone.character.Character("Liz", phone.config.basedir + "liz_icon.png", "L", 35, "#484848")
default pc_inco = phone.character.Character("Inco", phone.config.basedir + "inco_icon.png", "I", 35, "#484848")
default damien_chat = phone.group_chat.GroupChat("D-Man", phone.config.basedir + "damien_icon.png", "damien_chat", ephemeral=True).add_character("D").add_character("I")
default livia_chat = phone.group_chat.GroupChat("Liv-Long", phone.config.basedir + "olivia_icon.png", "olivia_chat", ephemeral=True).add_character("O").add_character("I")
default sophia_chat = phone.group_chat.GroupChat("Ms.P", phone.config.basedir + "sophia_icon.png", "sophia_chat").add_character("S").add_character("I") # We don't care about if her chat gets cleared or not
default liz_chat = phone.group_chat.GroupChat("Liz", phone.config.basedir + "liz_icon.png", "liz_chat", ephemeral=True).add_character("L").add_character("I")
default damien_chat = phone.group_chat.GroupChat("D-Man", phone.asset("damien_icon.png"), "damien_chat", transient=True).add_character("D").add_character("I")
default livia_chat = phone.group_chat.GroupChat("Liv-Long", phone.asset("olivia_icon.png"), "olivia_chat", transient=True).add_character("O").add_character("I")
default sophia_chat = phone.group_chat.GroupChat("Ms.P", phone.asset("sophia_icon.png"), "sophia_chat").add_character("S").add_character("I") # We don't care about if her chat gets cleared or not
default liz_chat = phone.group_chat.GroupChat("Liz", phone.asset("liz_icon.png"), "liz_chat", transient=True).add_character("L").add_character("I")
define EMOJI_PATH = "/gui/phone_assets/emojis/"
@ -61,3 +60,6 @@ init 100 python in phone.application:
add_app_to_all_characters(message_app)
add_app_to_all_characters(call_history_app)
add_app_to_all_characters(calendar_app)
init 100 python in phone.calendar:
add_calendar_to_all_characters(2023, 6, MONDAY)

View File

@ -1,7 +1,7 @@
init -150 python in phone.emojis:
from renpy import store
from store import Transform
from renpy.store import store, Transform, phone
from store.phone import config
_constant = True
import string
_NOT_ALLOWED_CHARACTERS = set(string.punctuation.strip("_") + " ")
@ -15,16 +15,13 @@ init -150 python in phone.emojis:
global _emojis
_emojis[name] = renpy.displayable(emoji)
add("clueless", config.basedir + "emojis/clueless.png")
add("randomguy", config.basedir + "emojis/randomguy.png")
def get(name):
return _emojis[name]
def _emoji_tag(tag, name):
return [
(renpy.TEXT_DISPLAYABLE, Transform(get(name), subpixel=True, ysize=1.0, fit="contain", yoffset=2))
(renpy.TEXT_DISPLAYABLE, Transform(get(name), subpixel=True, ysize=1.0, fit="contain"))
]
store.config.self_closing_custom_text_tags["emoji"] = _emoji_tag
@ -34,4 +31,32 @@ init -150 python in phone.emojis:
def format_emoji_tag(s):
for emoji in _tag_pattern.findall(s): s = _tag_pattern.sub(":" + emoji + ":", s, 1)
return s
return s
init 1000 python hide in phone.emojis:
if config.auto_emojis:
import os
emoji_base_path = phone.asset("emojis")
try:
for emoji in os.listdir(phone.path_join(store.config.basedir, "game", emoji_base_path)):
stuff = emoji.split(".")
if len(stuff) != 2: continue
name, extension = stuff
if extension.lower() not in ("png", "jpg", "jpeg", "svg"):
continue
add(name, phone.path_join(emoji_base_path, emoji))
except OSError:
pass
# prevent `default`
python early in phone.emojis:
pass
python early:
config.special_namespaces["store.phone.emojis"] = type(config.special_namespaces["store.config"])(phone.emojis, "phone.emojis")

View File

@ -8,7 +8,7 @@ screen _phone_click_effects():
define phone_click_uptime = 0.3
image phone_click_effect:
phone.config.basedir + "circle.png"
phone.asset("circle.png")
alpha 0.34 matrixcolor TintMatrix("#464646")
subpixel True xysize (25, 25)
easein (phone_click_uptime * 0.4) xysize (50, 50) alpha 0.7
@ -17,7 +17,7 @@ define phone_on_click_effect = ("phone_click_effect", phone_click_uptime)
define phone_drag_uptime = 0.4
image phone_drag_effect:
phone.config.basedir + "circle.png"
phone.asset("circle.png")
alpha 0.17 matrixcolor TintMatrix("#464646")
subpixel True xysize (20, 20)
easeout phone_drag_uptime alpha 0.0 xysize (0, 0)

View File

@ -10,6 +10,7 @@ init -100 python in phone.status_bar:
def battery_text_displayable(st, at):
return Text("{}%".format(system.get_battery_level()), style="_phone_status_bar_text"), 0.1
EMPTY = 0
ONE_FOURTH = 1
HALF = 2
THREE_FOURTH = 3
@ -17,6 +18,7 @@ init -100 python in phone.status_bar:
FULL = 5
_battery_displayables = {
EMPTY: renpy.displayable(config.basedir + "status_bar_battery_empty.png"),
ONE_FOURTH: renpy.displayable(config.basedir + "status_bar_battery_one_fourth.png"),
HALF: renpy.displayable(config.basedir + "status_bar_battery_half.png"),
THREE_FOURTH: renpy.displayable(config.basedir + "status_bar_battery_three_fourth.png"),
@ -29,6 +31,9 @@ init -100 python in phone.status_bar:
REDRAW = 0.5
if battery_level == 0:
return _battery_displayables[EMPTY], REDRAW
if battery_level <= 33: # bamboozled
return _battery_displayables[ONE_FOURTH], REDRAW
@ -90,12 +95,9 @@ screen _phone_status_bar():
add DynamicDisplayable(phone.status_bar.battery_text_displayable)
add DynamicDisplayable(phone.status_bar.battery_displayable) at _fits(0.74) yalign 0.5
action SetLocalVariable("control_center", True)
action (SetLocalVariable("control_center", True), SetField(phone.system, "at_list", _phone_control_center))
else:
on "show" action SetField(phone.system, "at_list", _phone_control_center)
on "hide" action SetField(phone.system, "at_list", _phone_status_bar)
add "#c4c4c438":
at transform:
on show:
@ -117,7 +119,7 @@ screen _phone_status_bar():
frame style "empty" modal True:
button:
style "empty" xfill True yfill True
action SetLocalVariable("control_center", False)
action (SetLocalVariable("control_center", False), SetField(phone.system, "at_list", _phone_status_bar))
hbox at Flatten:
xalign 0.5 yanchor 1.0 ypos 0.98
@ -125,7 +127,7 @@ screen _phone_status_bar():
vbox:
use _phone_control_center_block(cols=2, rows=2, layout="grid"):
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "airplane_icon.png"
add phone.asset("airplane_icon.png")
action If(
phone.system.locked,
NullAction(),
@ -133,7 +135,7 @@ screen _phone_status_bar():
)
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "cellular_data_icon.png"
add phone.asset("cellular_data_icon.png")
action If(
phone.system.locked,
NullAction(),
@ -142,11 +144,11 @@ screen _phone_status_bar():
ToggleVariable("phone.system.cellular_data")
)
)
selected_background Transform(phone.config.basedir + "circle.png", matrixcolor=TintMatrix("#35C759"), subpixel=True, fit="contain")
selected_background Transform(phone.asset("circle.png"), matrixcolor=TintMatrix("#35C759"), subpixel=True, fit="contain")
padding (90, 90)
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "wifi_icon.png"
add phone.asset("wifi_icon.png")
action (
If(
phone.system.locked,
@ -165,7 +167,7 @@ screen _phone_status_bar():
)
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "bluetooth_icon.png"
add phone.asset("bluetooth_icon.png")
action If(
phone.system.locked,
NullAction(),
@ -179,21 +181,21 @@ screen _phone_status_bar():
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
if phone.system.rotation_locked:
add phone.config.basedir + "rotation_locked_icon.png"
add phone.asset("rotation_locked_icon.png")
else:
add phone.config.basedir + "rotation_unlocked_icon.png"
add phone.asset("rotation_unlocked_icon.png")
action ToggleVariable("phone.system.rotation_locked")
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "moon_icon.png"
add phone.asset("moon_icon.png")
action ToggleVariable("phone.system.dark_mode")
use _phone_control_center_block(cols=2):
button at _yfits_block:
style "empty" align (0.5, 0.5)
hbox style "empty" yfill True:
add phone.config.basedir + "screen_mirroring_icon.png" at _yfits(0.67) yalign 0.5
add phone.asset("screen_mirroring_icon.png") at _yfits(0.67) yalign 0.5
null width 10
text _("Screen\nMirroring") size 14 yalign 0.5
@ -202,13 +204,13 @@ screen _phone_status_bar():
hbox:
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "flashlight_icon.png"
add phone.asset("flashlight_icon.png")
action ToggleVariable("phone.system.flashlight")
padding (30, 30)
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "timer_icon.png"
add phone.asset("timer_icon.png")
action NullAction()
padding (30, 30) hover_background None
@ -232,14 +234,14 @@ screen _phone_status_bar():
imagebutton:
xysize (50, 50)
selected_idle Transform(phone.config.basedir + "play_icon.png", fit="contain", subpixel=True, align=(0.5, 0.5))
selected_hover Transform(phone.config.basedir + "play_icon.png", fit="contain", subpixel=True, align=(0.5, 0.5))
selected_idle Transform(phone.asset("play_icon.png"), fit="contain", subpixel=True, align=(0.5, 0.5))
selected_hover Transform(phone.asset("play_icon.png"), fit="contain", subpixel=True, align=(0.5, 0.5))
if renpy.music.get_playing("phone_music") is None:
idle Transform(phone.config.basedir + "play_icon.png", fit="contain", subpixel=True, align=(0.5, 0.5))
idle Transform(phone.asset("play_icon.png"), fit="contain", subpixel=True, align=(0.5, 0.5))
action (NullAction(), SelectedIf(False))
else:
idle Transform(phone.config.basedir + "pause_icon.png", fit="contain", subpixel=True, align=(0.5, 0.5))
idle Transform(phone.asset("pause_icon.png"), fit="contain", subpixel=True, align=(0.5, 0.5))
action PauseAudio("phone_music", "toggle")
button style "empty" yalign 0.5:
@ -252,7 +254,7 @@ screen _phone_status_bar():
hbox:
use _phone_control_center_block(rows=2):
vbar value FieldValue(phone.system, "brightness", 1.0 - phone.config.lowest_brightness, offset=phone.config.lowest_brightness)
add phone.config.basedir + "sun_icon.png":
add phone.asset("sun_icon.png"):
at transform:
subpixel True xysize (0.5, 0.5) fit "contain"
xalign 0.5 yalign 0.75
@ -264,11 +266,11 @@ screen _phone_status_bar():
add DynamicDisplayable(
lambda st, at: (
(
phone.config.basedir + "volume_icon_0.png"
phone.asset("volume_icon_0.png")
if get_mixer("phone") == 0.0
else phone.config.basedir + "volume_icon_1.png"
else phone.asset("volume_icon_1.png")
if get_mixer("phone") < 0.5
else phone.config.basedir + "volume_icon_2.png"
else phone.asset("volume_icon_2.png")
),
0.1
)
@ -281,20 +283,20 @@ screen _phone_status_bar():
hbox:
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "calculator_icon.png"
add phone.asset("calculator_icon.png")
action NullAction()
padding (30, 30) hover_background None
use _phone_control_center_block():
button at _fits_block align (0.5, 0.5):
add phone.config.basedir + "camera_icon.png"
add phone.asset("camera_icon.png")
action NullAction()
padding (30, 30) hover_background None
screen _phone_control_center_block(cols=1, rows=1, layout="empty"):
frame at Flatten:
# https://github.com/renpy/renpy/issues/4666 >=
if renpy.version_tuple[:2] > ((7, 6) if renpy.compat.PY2 else (8, 1)):
frame at (CurriedRoundedCorners(radius=gui.phone_control_center_block_rounded_corners_radius), Flatten):
# https://github.com/renpy/renpy/issues/4666
if is_renpy_version_or_above(7, 6, 1):
xysize (
absolute((gui.phone_control_center_block_size * cols) + (gui.phone_control_center_spacing * (cols - 1))),
absolute((gui.phone_control_center_block_size * rows) + (gui.phone_control_center_spacing * (rows - 1)))
@ -342,7 +344,7 @@ style _phone_status_bar_text is empty:
color "#fff" outlines [ ]
size 12 line_spacing 0
yalign 0.5
font phone.config.basedir + "Aller_Rg.ttf"
font phone.asset("Aller_Rg.ttf")
transform _fits_block(factor=gui.phone_control_center_block_scaling_factor):
_fits(absolute(gui.phone_control_center_block_size * factor))
@ -366,7 +368,7 @@ style _phone_control_center_hbox is empty:
style _phone_control_center_vbox is empty:
spacing gui.phone_control_center_spacing
image _phone_control_center_bar = RoundedFrame("#fafafa", radius=gui.phone_control_center_block_rounded_corners_radius, outline_color="#f7f7f7d8", outline_width=1)
image _phone_control_center_bar = "#fafafa"
style _phone_control_center_bar is empty:
left_bar "_phone_control_center_bar"
@ -378,13 +380,13 @@ style _phone_control_center_vbar is empty:
style _phone_control_center_button is empty:
padding (70, 70)
background None
hover_background Transform(phone.config.basedir + "circle.png", matrixcolor=TintMatrix("#5a5a5a"), subpixel=True, fit="contain")
selected_background Transform(phone.config.basedir + "circle.png", matrixcolor=TintMatrix("#007BFA"), subpixel=True, fit="contain")
insensitive_background Transform(phone.config.basedir + "circle.png", matrixcolor=TintMatrix("#b1b1b1"), subpixel=True, fit="contain")
hover_background Transform(phone.asset("circle.png"), matrixcolor=TintMatrix("#5a5a5a"), subpixel=True, fit="contain")
selected_background Transform(phone.asset("circle.png"), matrixcolor=TintMatrix("#007BFA"), subpixel=True, fit="contain")
insensitive_background Transform(phone.asset("circle.png"), matrixcolor=TintMatrix("#b1b1b1"), subpixel=True, fit="contain")
style _phone_control_center_block_frame is empty:
modal True
background RoundedFrame("#000000d0", radius=gui.phone_control_center_block_rounded_corners_radius, outline_color="#00000093", outline_width=1)
background "#000000d0"
style _phone_control_center_block_base_box is empty:
spacing int(gui.phone_control_center_spacing + (gui.phone_control_center_block_size * (1.0 - gui.phone_control_center_block_scaling_factor) * 0.5))

View File

@ -2,6 +2,7 @@ init -999:
define config.gl2 = True
define config.early_start_store = False
# Some of these definitions are overwrote in 01definitions.rpy
init -200:
define gui.phone_margin = (15, 81, 15, 94)
define gui.phone_zoom = 0.8
@ -30,6 +31,22 @@ init -200:
python early:
import collections, pygame_sdl2 as pygame
@renpy.pure
def is_renpy_version_or_above(major, minor, patch):
"""
Checks if the current version of renpy is at least `(major, minor, patch)`.
If renpy is on a py3 / r8 version, `(major + 1, minor - 5, patch)` is checked.
I.e., if the game runs on renpy 8 and that this function is called to check for `7.5.0`, `8.0.0` (the py3 / r8 equivalent of `7.5.0`) is checked for.
"""
current_version = renpy.version_tuple[:3]
if not renpy.compat.PY2:
major += 1
minor -= 5
return current_version >= (major, minor, patch)
def hyperlink_functions_style(name):
"""
Hyperlink functions but the style `name` is used.
@ -40,7 +57,7 @@ python early:
style_object = getattr(style, name)
return (lambda target: style_object,) + style.default.hyperlink_functions[1:]
if renpy.version_tuple[:2] >= ((7, 6) if renpy.compat.PY2 else (8, 1)):
if is_renpy_version_or_above(7, 6, 0):
def get_mixer(mixer):
return preferences.get_mixer(mixer)
else:
@ -65,67 +82,72 @@ python early:
b = a * col[2] / 255.0
return (r, g, b, a)
# RoundedFrame by pseurae
# https://gist.github.com/Pseurae/661e6084f756fc917b2889a386b16664
# modified by yours truly (i don't know shit about OpenGL)
class RoundedFrame(renpy.display.image.Frame):
def __init__(self, image, *args, **kwargs):
radius = kwargs.pop("radius", 0.0)
outline_width = kwargs.pop("outline_width", 0.0)
outline_color = kwargs.pop("outline_color", "#fff")
_rounded_corners_relative = {
None: 0.0,
"min": 1.0,
"max": 2.0,
"width": 3.0,
"height": 4.0,
}
super(RoundedFrame, self).__init__(image, *args, **kwargs)
if not isinstance(radius, tuple): radius = (radius,) * 4
self.radius = radius
def RoundedCorners(child, radius, relative=None, outline_width=0.0, outline_color="#fff", **kwargs):
if not isinstance(radius, tuple): radius = (radius,) * 4
relative = _rounded_corners_relative[relative]
outline_color = normalize_color(Color(outline_color))
return Transform(child, mesh=True, shader="shader.rounded_corners", u_radius=radius, u_relative=relative, u_outline_color=outline_color, u_outline_width=outline_width, **kwargs)
self.outline_width = outline_width
self.outline_color = normalize_color(Color(outline_color))
def render(self, w, h, st, at):
rv = super(RoundedFrame, self).render(w, h, st, at)
if self.radius:
rv.mesh = True
rv.add_property("gl_pixel_perfect", True)
rv.add_property("gl_mipmap", False)
rv.add_property("texture_scaling", "nearest")
rv.add_shader("shader.rounded_corners")
rv.add_uniform("u_radius", self.radius)
rv.add_uniform("u_outline_width", self.outline_width)
rv.add_uniform("u_outline_color", self.outline_color)
return rv
CurriedRoundedCorners = renpy.curry(RoundedCorners)
renpy.register_shader("shader.rounded_corners", variables="""
uniform vec4 u_radius;
uniform float u_outline_width;
uniform vec4 u_outline_color;
uniform float u_relative;
uniform sampler2D tex0;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
uniform vec2 res0;
uniform vec2 u_model_size;
""", vertex_200="""
v_tex_coord = a_tex_coord;
""", fragment_functions="""
// https://www.iquilezles.org/www/articles/distfunctions/distfunctions2d.htm
float rounded_rectangle(in vec2 p, in vec2 b, in vec4 r) {
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
float rounded_rectangle(vec2 p, vec2 b, float r) {
return length(max(abs(p) - b + r, 0.0)) - r;
}
float get_radius(vec2 uv_minus_center, vec4 radius) {
vec2 xy = (uv_minus_center.x > 0.0) ? radius.xy : radius.zw;
float r = (uv_minus_center.y > 0.0) ? xy.x : xy.y;
return r;
}
""", fragment_200="""
vec2 center = u_model_size.xy / 2.0;
vec2 uv = (v_tex_coord.xy * u_model_size.xy);
vec2 uv_minus_center = uv - center;
float radius = get_radius(uv_minus_center, u_radius);
vec4 color = texture2D(tex0, v_tex_coord);
if (u_relative != 0.0) {
float side_size;
if (u_relative == 1.0) {
side_size = u_model_size.x;
} else if (u_relative == 2.0) {
side_size = u_model_size.y;
} else if (u_relative == 3.0) {
side_size = min(u_model_size.x, u_model_size.y);
} else {
side_size = max(u_model_size.x, u_model_size.y);
}
radius *= side_size;
}
if (u_outline_width > 0.0) {
vec2 center_outline = center - u_outline_width;
float crop1 = rounded_rectangle(uv - center, center, vec4(u_radius));
float crop2 = rounded_rectangle(uv - center, center_outline, vec4(u_radius - u_outline_width));
float crop1 = rounded_rectangle(uv - center, center, radius);
float crop2 = rounded_rectangle(uv - center, center_outline, radius - u_outline_width);
float coeff1 = smoothstep(1.0, -1.0, crop1);
float coeff2 = smoothstep(1.0, -1.0, crop2);
@ -135,11 +157,12 @@ python early:
gl_FragColor = mix(vec4(0.0), mix(color, u_outline_color, outline_coeff), coeff1);
}
else {
float crop = rounded_rectangle(uv - center, center, vec4(u_radius));
gl_FragColor = mix(vec4(0.0), color, smoothstep(1.0, 0.0, crop));
float crop = rounded_rectangle(uv_minus_center, center, radius);
gl_FragColor = mix(color, vec4(0.0), smoothstep(0.0, 1.0, crop));
}
""")
# taken from
# https://github.com/WretchedTeam/WintermuteV3/blob/main/game/mod_code/backend/displayables.rpy
class ShaderDisplayable(renpy.Displayable):

View File

@ -50,5 +50,5 @@ define discord.start_label = "storyline"
# These variables control the print functions across this script. They work if True, they're ignored if False.
# Prints are shown inside game's console (if turned on in the Ren'Py Launcher) and in the game's log.txt file.
define discord.log_important = True # Shows whether the Presence was initialized and closed correctly.
define discord.log_properties = True # Records properties whenever they change with set or update methods.
define discord.log_properties = False # Records properties whenever they change with set or update methods.
define discord.log_restore = True # Notes whenever the properties get rolled back or loaded from a save file, and what they were restored into.

View File

@ -9,13 +9,27 @@ default ben_story = None
label after_load:
if not renpy.android:
# renpy.get_return_stack()[1] will basically return what chapter the user is currently in the save, we call index 1 since index 0 will always be the label storyline from storyline.rpy. Keep in mind the name used will be what the 'from clause' adds in the call
# If the player went past chapter 2 without seeing the caligraphy CG then they are on a save from the first version of the game
if not persistent.seen_notice and not renpy.seen_image("cg_calligraphy") and (renpy.get_return_stack()[1][0] == '_call_chapter_3' or renpy.get_return_stack()[1][0] == '_call_chapter_4'):
if not persistent.seen_notice and not renpy.seen_image("cg_calligraphy") and (renpy.get_return_stack()[1] == '_call_chapter_3' or renpy.get_return_stack()[1] == '_call_chapter_4'):
call old_save_notice from _call_old_save_notice
call ask_drawing from _call_ask_drawing
$ renpy.block_rollback()
if ben_story == None and isinstance(renpy.get_return_stack()[1][0], str) and renpy.get_return_stack()[1][0].startswith("chapter_"):
# However this is not always reliable, sometimes it will fail, this is why it's in a try block and why we check that
# 1. We are checking a story script ("_call_chapter_"), since all of this won't work in mods and such
# 2. Check we are actually checking a string, since sometimes index 1 will be a tuple that points to a specific line instead (I don't know why this happens)
python:
try:
needs_compat = isinstance(renpy.get_return_stack()[1], str) and renpy.get_return_stack()[1].startswith("_call_chapter_")
except:
needs_compat = False
if ben_story == None and needs_compat:
# This ensures that mods won't trigger the save compatibility
if hasattr(store, 'score_olivia'):
call initstats(score_olivia,score_inco) from _call_initstats_4
call ask_drawing from _call_ask_drawing_1
@ -123,6 +137,8 @@ label AskChoices:
jump newContent
# Adds a custom error handler for the error of 'Couldn't find a place to stop rolling back' (Which usually happens when the save is incompatible). This error handler sends the user to a screen informing them of this and then to the menu instead of showing the gray exception screen.
init python:
def handle_bad_save(shortException,longException,tracebackFile):
if "Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?" in shortException and not config.developer:
@ -155,13 +171,16 @@ screen badSave():
xalign 0.5
spacing 100
# I originally wanted to send you to the main menu but that really really breaks for some reason
textbutton _("OK") activate_sound "audio/ui/snd_ui_click.wav" action Jump("kill_playthrough")
# For some reason, sending to the main menu won't work and instead it'll start a new (broken) game. SO instead, we clear the return stack and then return. Since it's cleared Renpy thinks "The game's over, send them back to the menu" and this for some reason jest werks.
label kill_playthrough:
# Stupid way to return to the main menu, the traditional ways don't work or outright crash the game
$ renpy.set_return_stack([])
return
# If there's no drawing saved we ask the player to either draw a new one or to import it
label ask_drawing:
if type(waniDemoCarryover.Chapter3Drawing) == NoneType:
@ -195,6 +214,7 @@ label ask_drawing:
with open(filename, mode="rb") as filecontents:
waniDemoCarryover.Chapter3Drawing = filecontents.read()
# We close the file just in case and then we replace with None otherwise renpy tries to pickle the variable for saving and fails.
filecontents.close()
filecontents = None
@ -211,7 +231,7 @@ label ask_drawing:
shutil.copyfile(filename, new_folder)
except:
pass
# Needed unless renpy throws a fit when saving
# Same as with filecontents. Needed unless renpy throws a fit when saving.
renpy.store.shutil = None
if filename == None or not filename.endswith(".png"):

View File

@ -1,16 +1,9 @@
label splashscreen:
$ persistent.splashtype = random.randint(0,2000 - 1)
show anim_caveintro
play sound mus_startup
pause 11.2
stop sound
if (persistent.languaged_up is None):
$ persistent.languaged_up = True
$ preferences.set_volume('ui', config.default_sfx_volume) # hack
call screen lang_sel
if not renpy.get_autoreload():
show anim_caveintro
play sound mus_startup
pause 11.2
stop sound
return

View File

@ -25,7 +25,7 @@ screen OkPrompt(message, go_menu):
xalign 0.5
spacing 100
textbutton _("OK") activate_sound "audio/ui/snd_ui_click.wav" action If(go_menu, true=MainMenu(False,False), false=Return())
textbutton _("OK") activate_sound "audio/ui/snd_ui_click.wav" action If(go_menu, true=MainMenu(False,False), false=[Hide(),Return()])
screen hiddenOkPrompt(message, go_menu):
@ -133,9 +133,9 @@ screen lang_sel():
idle darkie(languages[i]["image"])
hover glowie(languages[i]["image"])
action If(languages[i]["value"] in persistent.seenWarning or languages[i]["value"] == None,
true = [Language(languages[i]["value"]), MainMenu(False,False)],
true = [Language(languages[i]["value"]), Return()],
# Important to change the language before calling notice. Otherwise it will be in english.
false = [Language(languages[i]["value"]), AddToSet(set=persistent.seenWarning, value=languages[i]["value"]), Show(screen="OkPrompt", message=notice, go_menu=True)]
false = [Language(languages[i]["value"]), AddToSet(set=persistent.seenWarning, value=languages[i]["value"]), Show(screen="OkPrompt", message=notice, go_menu=False)]
)
at renpysdumb # Scales the imagebutton down. No, you can't just specify the zoom here. It has to be a defined transform.
else:

View File

@ -194,7 +194,13 @@ init python:
damp = 1
if self.damped and self.end is not None:
damp = renpy.atl.warpers[self.damped_warper]((self.end - st / self.fast_forward) / self.end)
offset = damp * renpy.atl.interpolate_spline(g, self.random_knot)
if renpy.version_tuple[3] >= 24011600:
interpolate_spline = renpy.atl.interpolate_spline(g, self.random_knot, renpy.atl.PROPERTIES[self.property])
else:
interpolate_spline = renpy.atl.interpolate_spline(g, self.random_knot)
offset = damp * interpolate_spline
setattr(tran, self.property, offset)
return 0

File diff suppressed because it is too large Load Diff

View File

@ -64,6 +64,8 @@ init -1600 python in _viewers:
default_channel_list = ["sound"]
#default side view.
default_sideview = True
#Not included layers
not_included_layer = ("transient", "screens", "overlay")
default_graphic_editor_narrow_range = 2.
default_graphic_editor_wide_range = 2000

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,8 @@
日本語マニュアルはドキュメント後半にあります。
This script adds Ren'py the ability to adjust and view transform properties of images
and camera by in-game Action Editor and Image Viewer and Sound Viewer.
Many warpers and usefull functions intended to be used in function statement in ATL are
and camera by in-game Action Editor, Image Viewer and Sound Viewer.
Many warpers and useful functions intended to be used in function statements in ATL are
also added.
Ren'Py <http://www.renpy.org/>
@ -26,32 +26,32 @@ lemma forum
================
This script adds Ren'py the ability to adjust and view transform properties of images
and camera by in-game Action Editor and Image Viewer and Sound Viewer.
Many warpers and usefull functions intended to be used in function statement in ATL are
and camera by in-game Action Editor, Image Viewer and Sound Viewer.
Many warpers and useful functions intended to be used in function statements in ATL are
also added.
About old version
================
This is available in v7.4.5 later.
To use in older version, use old version ActionEditor.
To use an older version, use the old version of ActionEditor.
<https://github.com/kyouryuukunn/renpy-ActionEditor>
In current version ActionEditor, below functions are removed.
In the current version of ActionEditor, the below functions are removed.
* expression
* loading last action
To instal
To install
================
To install, copy all files in the camera directory into your game directory.
ActionEditor.rpy is required for release version if you use camera blur or warper_generator.
00warper.rpy is also required if you use added warpers.
ATL_funcctions.rpy is also required if you use added functions for ATL statement.
Ohter files arenot required.
Other files are not required.
Action Editor
================
This allows you to adjusts transform properties of camera and images in
This allows you to adjust transform properties of camera and images in
real-time with a GUI. It can then generate a script based on these changes and
place it on the clipboard for later pasting into Ren'Py scripts.
@ -60,32 +60,32 @@ lemma forum
The Action Editor has the following features:
* View and adjust the transform properties of images and camera with adjusting a bar or typing value.
* View and adjust the transform properties of images and camera by adjusting a bar or typing a value.
* View and adjust the x and y coordinates of the camera with a draggable camera icon.
* Adjust the z coordinate of the camera with the mouse wheel.
* Adjust the x,y coordinate of the camera with the keyboard(hjkl, HJKL, wasd, WASD).
* Reset the value with right-click on the value button.
* Reset the value by right-clicking on the value button.
* Add, delete, and edit keyframes on a timeline like video editing software.
* the spline motion and loop is availabe
* The spline motion and loop is available
* After setting up a scene with the desired look and animations, the Action
Editor will generate a script and place it on your clipboard for pasting
into your Ren'Py scripts. (v6.99 and later only)
* Introducing the concept of depth of field and allow to adjust focus position and dof.
Blur each image according to dof, focus postion and the distance between the camera and the image.
Blur each image according to dof, focus position and the distance between the camera and the image.
* Show, replace and hide a image with transition(use None for a image name to hide image)
* Change a scene with scene statement.
* There is the option for hiding window during the ATL animation in clipboard data.
* There is the option for allowing to skip ATL animation in clipboard data.
Note
* blur transform property of each images are used for simulating camera blur in function transform prperty,
so blur transform properties of each images aren't availabe when focusing is enabled.
Set function property to None when you want to disable camera blur for already shownd images.
* Unfortunately, The behavior of functions for function property isn't same as ATL.
* blur transform property of each images are used for simulating camera blur in function transform property,
so blur transform properties of each images aren't available when focusing is enabled.
Set function property to None when you want to disable camera blur for already shown images.
* Unfortunately, The behavior of functions for function property isn't the same as ATL.
There are some different points.
1. inherited_<property> have no value.
2. Setting properties have no affect when it is called next time.
3. The return value from it have no affect.
2. Setting properties have no effect when it is called next time.
3. The return value from it has no effect.
4. It isn't always called in time.
ActionEditor can't get current function when opened.
@ -102,8 +102,8 @@ lemma forum
Commonly, add the following variables the property name you want to add to be added.:
* `props_set`: control where that is shwon in ActionEditor.
* `sort_order_list`: control where that is shwon in clipboard.
* `props_set`: control where that is shown in ActionEditor.
* `sort_order_list`: control where that is shown in the clipboard.
* `transform_props` or `camera_props`: Add the the property name.
Adding `transform_props` shows it in each images and Adding `camera_props` shows it in camera.
* `property_default_value`: Add the default value of the property.
@ -137,7 +137,7 @@ lemma forum
any_props = {"blend"}
menu_props = {"blend":[None] + [key for key in config.gl_blend_func]}
Exclusive proparties like tile and pan should be set in `exclusive`. example:
Exclusive properties like tile and pan should be set in `exclusive`. example:
exclusive = (
({"xpos", "ypos"}, {"xalignaround", "yalignaround", "radius", "angle"}),
@ -148,7 +148,7 @@ lemma forum
Property Group
================
For tuple, You can use `props_groups` where that key is the property name and that value
For tuples, you can use `props_groups` where that key is the property name and that value
is the tuple of each element name, so that they can be edited individually. example:
props_groups = {
@ -164,18 +164,18 @@ lemma forum
If `config.developer` is True, pressing Shift+U or +(add image) textbutton on ActionEditor
to open Image Viewer.
Defined image tag and attribute textbuttons are shown in this viewer.
Defined image tags and attribute textbuttons are shown in this viewer.
You can filter them by the text entered in the top-most text entry field.
The completion feature is also availabe by tab.
The completion feature is also available by tab.
When these textbuttons get focus and the same image name exist as these text, the image is
When these textbuttons get focus and the same image name exists as these text, the image is
shown.
Pressing the textbutton add that text to the filter if the same image name doesn't exist
as that text. the image is added to ActionEditor if that exist and viewer is opened by
ActionEditor. the image name is outputted to the clipboard if that exist and viewer isn't
opened by ActionEditor.
Pressing clipboard buton at the bottom also outputs the filter string to clipboard
Pressing clipboard button at the bottom also outputs the filter string to clipboard
Sound Viewer
@ -186,17 +186,17 @@ lemma forum
Variable names in audio store are shown in this viewer.
The music files should be automatically defined as these name.
You can filter them by the text entered in the top-most text entry field.
The completion feature is also availabe by tab.
The completion feature is also available by tab.
When these textbuttons get focus and the music file is played.
Pressing the textbutton add that to ActionEditor if the viewer is opened by ActionEditor.
Pressing the textbutton adds that to ActionEditor if the viewer is opened by ActionEditor.
Otherwise, that name is outputted to the clipboard.
Pressing clipboard buton at the bottom also outputs the filter string to clipboard
Pressing clipboard button at the bottom also outputs the filter string to clipboard
ATL functions
================
ATL_funcctions.rpy adds usefull functions which are intended to be used for
ATL_funcctions.rpy adds useful functions which are intended to be used for
function statement in ATL block. For more information, see that file.
@ -235,23 +235,28 @@ lemma forum
style new_action_editor_text:
size 10
Trouble shooting
Troubleshooting
================
Layout is corrupted
Too long tag names and big size of fonts corrupt the layout of ActionEditor.
Too long tag names and big font sizes corrupt the layout of ActionEditor.
In that case, try to adjust the size of font by the above manner.
Known issue
================
ActionEditor can't show camera and displayable with "at clause" includeing animation correctly.
ActionEditor can't show camera and displayable with "at clause" including animation correctly.
ActionEditor can't show movie and animation displayable correctly.
Note
================
The clipboard from ActionEditor includes the difference from the state when ActionEditor is opened on. Therefore that is intended to be pasted on next that line. Images aren't shown correctly if the existing lines are overwritten.
日本語ドキュメント
================
@ -497,3 +502,8 @@ lemma forum
アニメーションするat 節を使用したcamera, displayableは正常に表示できない
Movie Displayable, アニメーションするDisplayableは正常に表示できない
注意
================
ActionEditorから出力されるクリップボードデータはActionEditorが開かれた状態からの差分として出力され、その次の行への貼り付けを意図しています。このため既存のshowステートメントを上書きするように貼り付けると正常に表示されない場合があります。

View File

@ -11,6 +11,7 @@ screen _image_selecter(default=""):
style_group "image_selecter"
vbox:
label _("Type a image name") style "image_selecter_input"
label _("Tab: completion") style "image_selecter_input"
input value ScreenVariableInputValue("filter_string", default=True, returnable=True) copypaste True style "image_selecter_input" id "input_filter_strings"
$filtered_list = _viewers.filter_image_name(filter_string)
viewport:
@ -101,10 +102,22 @@ init -2000 python in _viewers:
for e in es.split()[1:]:
if e.startswith(completed_string):
candidate.append(e)
cs = renpy.current_screen()
cs.scope["filter_string"] += candidate[0][len(completed_string):] + " "
input = renpy.get_displayable("_image_selecter", "input_filter_strings")
input.caret_pos = len(cs.scope["filter_string"])
if candidate:
cs = renpy.current_screen()
if len(candidate) > 1:
completed_candidate = candidate[0]
for c in candidate[1:]:
for i in range(len(completed_candidate)):
if i < len(c) and completed_candidate[i] != c[i]:
completed_candidate = completed_candidate[0:i]
break
cs.scope["filter_string"] += completed_candidate[len(completed_string):]
else:
completed_candidate = candidate[0]
cs.scope["filter_string"] += completed_candidate[len(completed_string):] + " "
input = renpy.get_displayable("_image_selecter", "input_filter_strings")
input.caret_pos = len(cs.scope["filter_string"])
def _image_viewer_hide():
renpy.hide("preview", layer="screens")

View File

@ -11,6 +11,7 @@ screen _sound_selector(default=""):
style_group "sound_selecter"
vbox:
label _("type filenames(ex: variable, '<silence 2.>' or [[variable, variable])") style "sound_selecter_input"
label _("Tab: completion") style "sound_selecter_input"
input value ScreenVariableInputValue("filter_string", default=True, returnable=True) copypaste True style "sound_selecter_input" id "input_filter_strings"
$filtered_list = _viewers.filter_sound_name(filter_string)
viewport:
@ -95,8 +96,17 @@ init -2000 python in _viewers:
if isinstance(file, str) and renpy.loadable(file):
candidate.append(name)
if candidate:
if len(candidate) > 1:
completed_candidate = candidate[0]
for c in candidate[1:]:
for i in range(len(completed_candidate)):
if i < len(c) and completed_candidate[i] != c[i]:
completed_candidate = completed_candidate[0:i]
break
else:
completed_candidate = candidate[0]
cs = renpy.current_screen()
cs.scope["filter_string"] += candidate[0][len(last_element):]
cs.scope["filter_string"] += completed_candidate[len(last_element):]
input = renpy.get_displayable("_sound_selector", "input_filter_strings")
input.caret_pos = len(cs.scope["filter_string"])

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Some files were not shown because too many files have changed in this diff Show More