-
Notifications
You must be signed in to change notification settings - Fork 71
tfn upstream - Bloopers made by Xeon #945
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
3601cc0
ea96117
2b12026
b70e961
77034a8
60cfaa6
d77bc0b
1ba878d
6fe3c87
585968c
ba448e2
76ae873
f2485a2
9c468b0
0b7db31
67c36ff
eb787cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #define PREFERENCE_CATEGORY_VOCALS "vocals" | ||
|
|
||
| //BLOOPER defines | ||
| #define BLOOPER_DEFAULT_MINPITCH 0.4 | ||
| #define BLOOPER_DEFAULT_MAXPITCH 2 | ||
| #define BLOOPER_DEFAULT_MINVARY 0.1 | ||
| #define BLOOPER_DEFAULT_MAXVARY 0.8 | ||
| #define BLOOPER_DEFAULT_MINSPEED 2 | ||
| #define BLOOPER_DEFAULT_MAXSPEED 16 | ||
|
|
||
| #define BLOOPER_SPEED_BASELINE 4 //Used to calculate delay between BLOOPERs, any BLOOPER speeds below this feature higher BLOOPER density, any speeds above feature lower BLOOPER density. Keeps BLOOPERing length consistent | ||
|
|
||
| #define BLOOPER_TRANSMIT_VOLUME 55 | ||
| #define BLOOPER_MAX_BLOOPERS 24 | ||
| #define BLOOPER_MAX_TIME (1.5 SECONDS) // More or less the amount of time the above takes to process through with a BLOOPER speed of 2. | ||
|
|
||
| #define BLOOPER_DO_VARY(pitch, variance) (rand(((pitch * 100) - (variance*50)), ((pitch*100) + (variance*50))) / 100) | ||
|
|
||
| #define BLOOPER_SOUND_FALLOFF_EXPONENT 0.5 //At lower ranges, we want the exponent to be below 1 so that whispers don't sound too awkward. At higher ranges, we want the exponent fairly high to make yelling less obnoxious |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| [ | ||
| { | ||
| "name": "Ehh 1", | ||
| "id": "ehh1", | ||
| "files": [ | ||
| "ehh.ogg" | ||
| ] | ||
| }, | ||
|
|
||
| { | ||
| "name": "Pencil", | ||
| "id": "pencil", | ||
| "files": [ | ||
| "pencil.ogg" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "Dot", | ||
| "id": "dot", | ||
| "files": [ | ||
| "dot.ogg" | ||
| ] | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| [ | ||
| { | ||
| "name": "Example Blooper", | ||
| "id": "example", | ||
| "files": ["example.ogg"], | ||
| "min_speed": 2, | ||
| "max_speed": 16, | ||
| "min_pitch": 0.4, | ||
| "max_pitch": 2, | ||
| "min_vary": 0.1, | ||
| "max_vary": 0.8 | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| /atom/movable | ||
| // Text-to-blooper sounds | ||
| // yes. all atoms can have a say. | ||
| var/datum/blooper/blooper | ||
| var/blooper_speed = 50 | ||
| var/blooper_pitch = 50 | ||
| var/blooper_pitch_range = 50 //Actual pitch is (pitch - (blooper_pitch_range*0.5)) to (pitch + (blooper_pitch_range*0.5)) | ||
| COOLDOWN_DECLARE(blooper_cooldown) | ||
|
|
||
| /atom/movable/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans, datum/language/message_language, list/message_mods = list(), forced = FALSE, tts_message, list/tts_filter) | ||
| . = ..() | ||
| if(!blooper) | ||
| return | ||
| var/list/listeners = get_hearers_in_view(range, source) | ||
| blooper.play_bloop(source, listeners, message, range, BLOOPER_TRANSMIT_VOLUME, blooper_speed, blooper_pitch, blooper_pitch_range) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,3 +33,4 @@ | |
|
|
||
|
|
||
| . = ..() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /mob/living/send_speech(message_raw, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language = null, list/message_mods = list(), forced = null, tts_message, list/tts_filter) | ||
| . = ..() | ||
| if(!blooper) | ||
| return | ||
| if(HAS_TRAIT(src, TRAIT_SIGN_LANG) && !HAS_TRAIT(src, TRAIT_MUTE)) //if you can speak and you sign, your hands don't make a bark. Unless you are completely mute, you can have some hand bark. | ||
| return | ||
| var/pref_volume = client ? (client?.prefs?.read_preference(/datum/preference/numeric/blooper_sound_volume) / 100) : 1 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If no client... volume at 1... why are we even bothering if we dont have a client.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NPC voices have been fun to see?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am misunderstanding it or is this checking the client of the HEARER not the speaker. |
||
| var/volume = BLOOPER_TRANSMIT_VOLUME * pref_volume | ||
| if(message_mods[WHISPER_MODE]) | ||
| volume = BLOOPER_TRANSMIT_VOLUME * 0.5 | ||
| message_range++ | ||
| var/list/listeners = get_hearers_in_view(message_range, source) | ||
| var/is_yelling = (say_test(message_raw) == "2") // boost the volume if their message ends in ! | ||
| blooper.play_bloop(source, listeners, message_raw, message_range, volume * (is_yelling ? 2 : 1), blooper_speed, blooper_pitch, blooper_pitch_range) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| // we let borgs have some bark too | ||
| /mob/living/silicon/Login() | ||
| blooper = SSblooper.blooper_list[client.prefs.read_preference(/datum/preference/choiced/blooper)] | ||
| blooper_speed = client.prefs.read_preference(/datum/preference/numeric/blooper_speed) | ||
| blooper_pitch = client.prefs.read_preference(/datum/preference/numeric/blooper_pitch) | ||
| blooper_pitch_range = client.prefs.read_preference(/datum/preference/numeric/blooper_pitch_range) | ||
| . = ..() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| https://github.com/DarkPack13/SecondCity/pull/945 | ||
|
|
||
| ## \<Bloopers> | ||
|
|
||
| Module ID: BLOOPERS | ||
|
|
||
| ### Description: | ||
|
|
||
| Adds voice bloopers (voice barks) to the game. Similiar to animal crossing animalese. Noises that get played when a character talks. | ||
|
|
||
| By default, no vocal bloopers are included in the repository, a sample config file is provided to demonstrate the format used. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why tho?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. idk - probably because of licensing concerns?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment is no longer accurate as we provide a few bloopers. |
||
| To set things up, copy `blooper_config.json.example` and rename it to `blooper_config.json`, then add an entry for each blooper. | ||
|
|
||
| ### Config Format | ||
|
|
||
| - name: Required, the user-friendly name of the voice, will be shown in the config menu | ||
| - id: Required, an internal ID for the voice, must be unique | ||
| - files: Required, a JSON array of audio file names, relative to the bloopers directory. | ||
| If there's more than one entry, a file is randomly chosen each time the user speaks | ||
| - min_speed: Optional, the minimum value the user can set for the voice speed | ||
| - max_speed: Optional, the maximum value the user can set for the voice speed | ||
| - min_pitch: Optional, the minimum value the user can set for the voice pitch | ||
| - max_pitch: Optional, the maximum value the user can set for the voice pitch | ||
| - min_vary: Optional, the minimum value the user can set for the voice pitch variance | ||
| - max_vary: Optional, the maximum value the user can set for the voice pitch variance | ||
|
|
||
| ### TG Proc/File Changes: | ||
|
|
||
| - N/A | ||
|
|
||
| ### Modular Overrides: | ||
|
|
||
| - N/A | ||
|
|
||
| ### Defines: | ||
|
|
||
| - N/A | ||
|
|
||
| ### Included files that are not contained in this module: | ||
|
|
||
| - N/A | ||
|
|
||
| ### Credits: | ||
|
|
||
| XeonMations | ||
|
chazzyjazzy marked this conversation as resolved.
|
||
| xPokee | ||
| LT3 | ||
| TealSeer | ||
| GeneriedJenelle | ||
| ghost | ||
| SynthTwo | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| /datum/blooper | ||
| /// User friendly name of the blooper, displayed in preferences menu | ||
| var/name = null | ||
| /// Internal ID of blooper, must be unique | ||
| var/id = null | ||
| /// List of sounds, one is chosen randomly each time the blooper is played | ||
| var/list/sound/soundpath_list = list() | ||
|
|
||
| var/min_pitch = BLOOPER_DEFAULT_MINPITCH | ||
| var/max_pitch = BLOOPER_DEFAULT_MAXPITCH | ||
| var/min_vary = BLOOPER_DEFAULT_MINVARY | ||
| var/max_vary = BLOOPER_DEFAULT_MAXVARY | ||
|
|
||
| // Speed vars. Speed determines the number of characters required for each blooper, with lower speeds being faster with higher blooper density | ||
| var/min_speed = BLOOPER_DEFAULT_MINSPEED | ||
| var/max_speed = BLOOPER_DEFAULT_MAXSPEED | ||
|
|
||
| /** | ||
| * Plays the vocal blooper for all listeners, duration is controlled by length of the message argument | ||
| * * speaker - Origin source of the blooper, used for 3D audio calculations and to set the cooldown | ||
| * * listeners - List of mobs that will hear the blooper | ||
| * * message - Chat message being sent, used to determine how long bloopers play for (longer message, more sounds) | ||
| * * distance - Range at which the sounds will be heard | ||
| * * volume - Volume the sounds will play at | ||
| * * speed - How fast the bloopers will be, percentage between 0 - 100, converted and clamped to datum's min/max values | ||
| * * pitch - How high-pitched the bloopers will be, percentage between 0 - 100, converted and clamped to datum's min/max values | ||
| * * pitch_range - Amount of pitch variance for each blooper, percentage between 0 - 100, converted and clamped to datum's max/min values | ||
| */ | ||
| /datum/blooper/proc/play_bloop(atom/movable/speaker, list/listeners, message, distance, volume, speed, pitch, pitch_range) | ||
| if(!COOLDOWN_FINISHED(speaker, blooper_cooldown)) | ||
| return | ||
| volume = min(volume, 100) | ||
| // convert passed values (which are percentages) into value clamped between min and max of blooper datum | ||
| speed = round(min_speed + ((max_speed - min_speed) * ((100 - speed) / 100)), 0.01) // this one gets inverted because lower % = faster isn't intuitive | ||
| pitch = round(min_pitch + ((max_pitch - min_pitch) * (pitch / 100)), 0.01) | ||
| pitch_range = round(min_vary + ((max_vary - min_vary) * (pitch_range / 100)), 0.01) | ||
| for(var/mob/target_mob in listeners) | ||
| if(target_mob.client && !(target_mob.client.prefs.read_preference(/datum/preference/toggle/hear_blooper))) | ||
| listeners -= target_mob | ||
| var/sound/blooper_pick = pick(soundpath_list) | ||
| var/num_bloopers = min(round(length(message) / speed, 1) + 1, BLOOPER_MAX_BLOOPERS) | ||
| var/total_delay = 0 | ||
| for(var/i in 1 to num_bloopers) | ||
| if(total_delay > BLOOPER_MAX_TIME) | ||
| break | ||
| addtimer(CALLBACK(src, PROC_REF(play_callback), speaker, listeners, distance, volume, BLOOPER_DO_VARY(pitch, pitch_range), blooper_pick), total_delay) | ||
| total_delay += rand(DS2TICKS(speed / BLOOPER_SPEED_BASELINE), DS2TICKS(speed / BLOOPER_SPEED_BASELINE) + DS2TICKS(speed / BLOOPER_SPEED_BASELINE)) TICKS | ||
| COOLDOWN_START(speaker, blooper_cooldown, total_delay) | ||
|
|
||
| /// Private callback function to actually play the sound, used for timers scheduled in play_bloop | ||
| /datum/blooper/proc/play_callback(atom/movable/speaker, list/listeners, distance, volume, pitch, sound/voice) | ||
| PRIVATE_PROC(TRUE) | ||
| for(var/mob/target_mob in listeners) | ||
| target_mob.playsound_local( | ||
| turf_source = get_turf(speaker), | ||
| soundin = voice, | ||
| vol = volume, | ||
| vary = TRUE, | ||
| frequency = pitch, | ||
| falloff_distance = 0, | ||
| falloff_exponent = BLOOPER_SOUND_FALLOFF_EXPONENT, | ||
| max_distance = distance, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| #define BLOOPER_CONFIG_PATH "[global.config.directory]/darkpack_config/bloopers" | ||
|
|
||
| SUBSYSTEM_DEF(blooper) | ||
| name = "Blooper" | ||
| ss_flags = SS_NO_FIRE | SS_NO_INIT | ||
|
|
||
| var/list/blooper_list | ||
|
|
||
| /datum/controller/subsystem/blooper/OnConfigLoad() | ||
| blooper_list = initialize_blooper_datums() | ||
|
|
||
| /datum/controller/subsystem/blooper/proc/initialize_blooper_datums() | ||
| var/list/blooper_datums = list() | ||
| if(!rustg_file_exists("[BLOOPER_CONFIG_PATH]/blooper_config.json")) | ||
| logger.Log(LOG_CATEGORY_DEBUG, "blooper_config.json not found.") | ||
| return blooper_datums | ||
| var/list/blooper_entries = safe_json_decode(rustg_file_read("[BLOOPER_CONFIG_PATH]/blooper_config.json")) | ||
| if(isnull(blooper_entries)) | ||
| stack_trace("Blooper config is malformed!") | ||
| return blooper_datums | ||
| for(var/entry in blooper_entries) | ||
| // These fields are required | ||
| if(isnull(entry["name"]) || isnull(entry["id"]) || isnull(entry["files"]) || !length(entry["files"])) | ||
| stack_trace("Blooper config entry was missing required field!") | ||
| continue | ||
| var/datum/blooper/new_blooper = new() | ||
| new_blooper.name = entry["name"] | ||
| new_blooper.id = entry["id"] | ||
| for(var/file in entry["files"]) | ||
| new_blooper.soundpath_list += sound("[BLOOPER_CONFIG_PATH]/sounds/[file]") | ||
| new_blooper.min_pitch = entry["min_pitch"] || BLOOPER_DEFAULT_MINPITCH | ||
| new_blooper.max_pitch = entry["max_pitch"] || BLOOPER_DEFAULT_MAXPITCH | ||
| new_blooper.min_vary = entry["min_vary"] || BLOOPER_DEFAULT_MINVARY | ||
| new_blooper.max_vary = entry["max_vary"] || BLOOPER_DEFAULT_MAXVARY | ||
| new_blooper.min_speed = entry["min_speed"] || BLOOPER_DEFAULT_MINSPEED | ||
| new_blooper.max_speed = entry["max_speed"] || BLOOPER_DEFAULT_MAXSPEED | ||
| blooper_datums[new_blooper.id] = new_blooper | ||
| return blooper_datums | ||
|
|
||
| #undef BLOOPER_CONFIG_PATH |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| /datum/changeling_profile | ||
| /// The blooper voice used by the profile source | ||
| var/datum/blooper/blooper | ||
| /// The blooper speed used by the profile source | ||
| var/blooper_speed | ||
| /// The blooper pitch used by the profile source | ||
| var/blooper_pitch | ||
| /// The blooper pitch range used by the profile source | ||
| var/blooper_pitch_range |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| /datum/preference_middleware/blooper | ||
| action_delegations = list( | ||
| "play_blooper" = PROC_REF(play_blooper), | ||
| ) | ||
|
|
||
| /datum/preference_middleware/blooper/proc/play_blooper(list/params, mob/user) | ||
| var/datum/blooper/blooper_to_use = SSblooper.blooper_list[preferences.read_preference(/datum/preference/choiced/blooper)] | ||
| var/blooper_speed = preferences.read_preference(/datum/preference/numeric/blooper_speed) | ||
| var/blooper_pitch = preferences.read_preference(/datum/preference/numeric/blooper_pitch) | ||
| var/blooper_pitch_range = preferences.read_preference(/datum/preference/numeric/blooper_pitch_range) | ||
| blooper_to_use.play_bloop(user, list(user), "This is a test message to hear a blooper.", 7, 70, blooper_speed, blooper_pitch, blooper_pitch_range) | ||
| return TRUE |
Uh oh!
There was an error while loading. Please reload this page.