mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Merge remote-tracking branch 'skrat/master' into mergeupstream
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
/area/template_noop)
|
||||
"b" = (
|
||||
/turf/closed/mineral/strong,
|
||||
/area/template_noop)
|
||||
/area/lavaland/surface/outdoors)
|
||||
|
||||
(1,1,1) = {"
|
||||
a
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,3 +4,7 @@
|
||||
#define TTS_SOUND_ENABLED "Enabled"
|
||||
///TTS preference is set to only play blips of a sound, rather than speech.
|
||||
#define TTS_SOUND_BLIPS "Blips Only"
|
||||
///TTS filter to activate start/stop radio clicks on speech.
|
||||
#define TTS_FILTER_RADIO "radio"
|
||||
///TTS filter to activate a silicon effect on speech.
|
||||
#define TTS_FILTER_SILICON "silicon"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
return returnable_list
|
||||
|
||||
/// Sets all of the job datum configurable values to what they've been set to in the config file, jobconfig.toml.
|
||||
/datum/controller/subsystem/job/proc/load_jobs_from_config()
|
||||
/datum/controller/subsystem/job/proc/load_jobs_from_config(silent = FALSE)
|
||||
if(!length(job_config_datum_singletons))
|
||||
stack_trace("SSjob tried to load jobs from config, but the config singletons were not initialized! Likely tried to load jobs before SSjob was initialized.")
|
||||
return
|
||||
@@ -25,7 +25,8 @@
|
||||
var/job_key = occupation.config_tag
|
||||
if(!job_config[job_key]) // Job isn't listed, skip it.
|
||||
// List both job_title and job_key in case they de-sync over time.
|
||||
message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults."))
|
||||
if(!silent)
|
||||
message_admins(span_notice("[occupation.title] (with config key [job_key]) is missing from jobconfig.toml! Using codebase defaults."))
|
||||
continue
|
||||
|
||||
for(var/config_datum_key in job_config_datum_singletons)
|
||||
|
||||
@@ -305,8 +305,10 @@ SUBSYSTEM_DEF(job)
|
||||
player.mind.special_role = null
|
||||
SetupOccupations()
|
||||
unassigned = list()
|
||||
if(overflow_role)
|
||||
set_overflow_role(overflow_role)
|
||||
if(CONFIG_GET(flag/load_jobs_from_txt))
|
||||
// Any errors with the configs has already been said, we don't need to repeat them here.
|
||||
load_jobs_from_config(silent = TRUE)
|
||||
set_overflow_role(overflow_role)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ SUBSYSTEM_DEF(radiation)
|
||||
for (var/obj/item/bodypart/limb as anything in human.bodyparts)
|
||||
var/protected = FALSE
|
||||
|
||||
for (var/obj/item/clothing as anything in human.clothingonpart(limb))
|
||||
for (var/obj/item/clothing as anything in human.get_clothing_on_part(limb))
|
||||
if (HAS_TRAIT(clothing, TRAIT_RADIATION_PROTECTED_CLOTHING))
|
||||
protected = TRUE
|
||||
break
|
||||
|
||||
@@ -263,7 +263,7 @@ SUBSYSTEM_DEF(tts)
|
||||
|
||||
#undef TTS_ARBRITRARY_DELAY
|
||||
|
||||
/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, silicon = "")
|
||||
/datum/controller/subsystem/tts/proc/queue_tts_message(datum/target, message, datum/language/language, speaker, filter, list/listeners, local = FALSE, message_range = 7, volume_offset = 0, pitch = 0, special_filters = "")
|
||||
if(!tts_enabled)
|
||||
return
|
||||
|
||||
@@ -279,7 +279,7 @@ SUBSYSTEM_DEF(tts)
|
||||
|
||||
var/shell_scrubbed_input = tts_speech_filter(message)
|
||||
shell_scrubbed_input = copytext(shell_scrubbed_input, 1, 300)
|
||||
var/identifier = "[sha1(speaker + filter + num2text(pitch) + num2text(silicon) + shell_scrubbed_input)].[world.time]"
|
||||
var/identifier = "[sha1(speaker + filter + num2text(pitch) + special_filters + shell_scrubbed_input)].[world.time]"
|
||||
if(!(speaker in available_speakers))
|
||||
return
|
||||
|
||||
@@ -290,9 +290,9 @@ SUBSYSTEM_DEF(tts)
|
||||
var/datum/http_request/request_blips = new()
|
||||
var/file_name = "tmp/tts/[identifier].ogg"
|
||||
var/file_name_blips = "tmp/tts/[identifier]_blips.ogg"
|
||||
request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name)
|
||||
request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&silicon=[silicon]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips)
|
||||
var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch, silicon)
|
||||
request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name)
|
||||
request_blips.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/tts_http_url)]/tts-blips?voice=[speaker]&identifier=[identifier]&filter=[url_encode(filter)]&pitch=[pitch]&special_filters=[url_encode(special_filters)]", json_encode(list("text" = shell_scrubbed_input)), headers, file_name_blips)
|
||||
var/datum/tts_request/current_request = new /datum/tts_request(identifier, request, request_blips, shell_scrubbed_input, target, local, language, message_range, volume_offset, listeners, pitch)
|
||||
var/list/player_queued_tts_messages = queued_tts_messages[target]
|
||||
if(!player_queued_tts_messages)
|
||||
player_queued_tts_messages = list()
|
||||
@@ -344,8 +344,6 @@ SUBSYSTEM_DEF(tts)
|
||||
var/use_blips = FALSE
|
||||
/// What's the pitch adjustment?
|
||||
var/pitch = 0
|
||||
/// Are we using the silicon vocal effect on this?
|
||||
var/silicon = ""
|
||||
|
||||
|
||||
/datum/tts_request/New(identifier, datum/http_request/request, datum/http_request/request_blips, message, target, local, datum/language/language, message_range, volume_offset, list/listeners, pitch)
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
required_distance = 3
|
||||
/// range we will try chasing the target before giving up
|
||||
var/chase_range = 9
|
||||
///do we care about avoiding friendly fire?
|
||||
var/avoid_friendly_fire = FALSE
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
. = ..()
|
||||
@@ -75,6 +77,10 @@
|
||||
if(!can_see(basic_mob, final_target, required_distance))
|
||||
return
|
||||
|
||||
if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targetting_datum))
|
||||
adjust_position(basic_mob, target)
|
||||
return ..()
|
||||
|
||||
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
||||
basic_mob.RangedAttack(final_target)
|
||||
return ..() //only start the cooldown when the shot is shot
|
||||
@@ -83,3 +89,52 @@
|
||||
. = ..()
|
||||
if(!succeeded)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targetting_datum/targetting_datum)
|
||||
var/list/turfs_list = calculate_trajectory(source, target)
|
||||
for(var/turf/possible_turf as anything in turfs_list)
|
||||
|
||||
for(var/mob/living/potential_friend in possible_turf)
|
||||
if(!targetting_datum.can_attack(source, potential_friend))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/proc/adjust_position(mob/living/living_pawn, atom/target)
|
||||
var/turf/our_turf = get_turf(living_pawn)
|
||||
var/list/possible_turfs = list()
|
||||
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/target_turf = get_step(our_turf, direction)
|
||||
if(isnull(target_turf))
|
||||
continue
|
||||
if(target_turf.is_blocked_turf() || get_dist(target_turf, target) > get_dist(living_pawn, target))
|
||||
continue
|
||||
possible_turfs += target_turf
|
||||
|
||||
if(!length(possible_turfs))
|
||||
return
|
||||
var/turf/picked_turf = get_closest_atom(/turf, possible_turfs, target)
|
||||
step(living_pawn, get_dir(living_pawn, picked_turf))
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/proc/calculate_trajectory(mob/living/source , atom/target)
|
||||
var/list/turf_list = get_line(source, target)
|
||||
var/list_length = length(turf_list) - 1
|
||||
for(var/i in 1 to list_length)
|
||||
var/turf/current_turf = turf_list[i]
|
||||
var/turf/next_turf = turf_list[i+1]
|
||||
var/direction_to_turf = get_dir(current_turf, next_turf)
|
||||
if(!ISDIAGONALDIR(direction_to_turf))
|
||||
continue
|
||||
|
||||
for(var/cardinal_direction in GLOB.cardinals)
|
||||
if(cardinal_direction & direction_to_turf)
|
||||
turf_list += get_step(current_turf, cardinal_direction)
|
||||
|
||||
turf_list -= get_turf(source)
|
||||
turf_list -= get_turf(target)
|
||||
|
||||
return turf_list
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
@@ -31,15 +31,19 @@
|
||||
|
||||
var/random_number_in_range = rand(1, total_choices_length)
|
||||
|
||||
// Sound that plays when the mob does something audible
|
||||
var/sound_to_play = length(sound) > 0 ? pick(sound) : null
|
||||
|
||||
if(random_number_in_range <= audible_emotes_length)
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear))
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear), sound_to_play)
|
||||
else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length))
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see))
|
||||
else
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), length(sound) > 0 ? pick(sound) : null)
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), sound_to_play)
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/insect
|
||||
speech_chance = 5
|
||||
sound = list('sound/creatures/chitter.ogg')
|
||||
emote_hear = list("chitters.")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/mothroach
|
||||
@@ -49,6 +53,7 @@
|
||||
/datum/ai_planning_subtree/random_speech/mouse
|
||||
speech_chance = 1
|
||||
speak = list("Squeak!", "SQUEAK!", "Squeak?")
|
||||
sound = list('sound/creatures/mousesqueek.ogg')
|
||||
emote_hear = list("squeaks.")
|
||||
emote_see = list("runs in a circle.", "shakes.")
|
||||
|
||||
@@ -93,12 +98,14 @@
|
||||
/datum/ai_planning_subtree/random_speech/chicken
|
||||
speech_chance = 15 // really talkative ladies
|
||||
speak = list("Cluck!", "BWAAAAARK BWAK BWAK BWAK!", "Bwaak bwak.")
|
||||
sound = list('sound/creatures/clucks.ogg', 'sound/creatures/bagawk.ogg')
|
||||
emote_hear = list("clucks.", "croons.")
|
||||
emote_see = list("pecks at the ground.","flaps her wings viciously.")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/chick
|
||||
speech_chance = 4
|
||||
speak = list("Cherp.", "Cherp?", "Chirrup.", "Cheep!")
|
||||
sound = list('sound/creatures/chick_peep.ogg')
|
||||
emote_hear = list("cheeps.")
|
||||
emote_see = list("pecks at the ground.","flaps her tiny wings.")
|
||||
|
||||
@@ -160,33 +167,37 @@
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/pony
|
||||
speech_chance = 3
|
||||
sound = list('sound/creatures/pony/whinny01.ogg', 'sound/creatures/pony/whinny02.ogg', 'sound/creatures/pony/whinny03.ogg')
|
||||
emote_hear = list("whinnies!")
|
||||
emote_see = list("horses around.")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/pony/tamed
|
||||
speech_chance = 3
|
||||
sound = list('sound/creatures/pony/snort.ogg')
|
||||
emote_hear = list("snorts.")
|
||||
emote_see = list("snorts.")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/killer_tomato
|
||||
speech_chance = 3
|
||||
speak = list("gnashes.", "growls lowly.", "snarls.")
|
||||
emote_hear = list("gnashes.")
|
||||
emote_hear = list("gnashes.", "growls lowly.", "snarls.")
|
||||
emote_see = list("salivates.")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/ant
|
||||
speech_chance = 1
|
||||
speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht")
|
||||
sound = list('sound/creatures/chitter.ogg')
|
||||
emote_hear = list("buzzes.", "clacks.")
|
||||
emote_see = list("shakes their head.", "twitches their antennae.")
|
||||
speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/fox
|
||||
speech_chance = 1
|
||||
speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
|
||||
emote_hear = list("howls.", "barks.", "screams.")
|
||||
emote_see = list("shakes their head.", "shivers.")
|
||||
speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/crab
|
||||
speech_chance = 1
|
||||
sound = list('sound/creatures/claw_click.ogg')
|
||||
emote_hear = list("clicks.")
|
||||
emote_see = list("clacks.")
|
||||
|
||||
|
||||
@@ -287,11 +287,13 @@
|
||||
|
||||
/datum/ai_behavior/perform_emote
|
||||
|
||||
/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote)
|
||||
/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote, speech_sound)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
if(!istype(living_pawn))
|
||||
return
|
||||
living_pawn.manual_emote(emote)
|
||||
if(speech_sound) // Only audible emotes will pass in a sound
|
||||
playsound(living_pawn, speech_sound, 80, vary = TRUE)
|
||||
finish_action(controller, TRUE)
|
||||
|
||||
/datum/ai_behavior/perform_speech
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
ASSERT_GAS_IN_LIST(gastype, gaslist)
|
||||
gaslist[gastype][MOLES] += amount
|
||||
|
||||
// Ensure that minimum_pressure is actually a hard lower limit
|
||||
target_pressure = clamp(target_pressure, minimum_pressure + (gaslist[gastype][MOLES] * 0.1), maximum_pressure)
|
||||
|
||||
// That last one put us over the limit, remove some of it
|
||||
while(gasmix.return_pressure() > target_pressure)
|
||||
gaslist[gastype][MOLES] -= gaslist[gastype][MOLES] * 0.1
|
||||
|
||||
@@ -78,8 +78,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
QDEL_NULL(sizzle)
|
||||
if(particle_effect)
|
||||
QDEL_NULL(particle_effect)
|
||||
if(process_effect)
|
||||
process_effect = null
|
||||
process_effect = null
|
||||
return ..()
|
||||
|
||||
/datum/component/acid/RegisterWithParent()
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
|
||||
var/start_time = REALTIMEOFDAY
|
||||
|
||||
for(var/turf/turf as anything in turfs)
|
||||
if(!(turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped
|
||||
for(var/turf/target_turf as anything in turfs)
|
||||
if(!(target_turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped
|
||||
continue
|
||||
|
||||
// If we've spawned something yet
|
||||
@@ -127,22 +127,24 @@
|
||||
//FLORA SPAWNING HERE
|
||||
if(flora_allowed && prob(flora_spawn_chance))
|
||||
var/flora_type = pick(flora_spawn_list)
|
||||
new flora_type(turf)
|
||||
new flora_type(target_turf)
|
||||
spawned_something = TRUE
|
||||
|
||||
//FEATURE SPAWNING HERE
|
||||
if(feature_allowed && prob(feature_spawn_chance))
|
||||
//we may have generated something from the flora list on the target turf, so let's not place
|
||||
//a feature here if that's the case (because it would look stupid)
|
||||
if(feature_allowed && !spawned_something && prob(feature_spawn_chance))
|
||||
var/can_spawn = TRUE
|
||||
|
||||
var/atom/picked_feature = pick(feature_spawn_list)
|
||||
|
||||
for(var/obj/structure/existing_feature in range(7, turf))
|
||||
for(var/obj/structure/existing_feature in range(7, target_turf))
|
||||
if(istype(existing_feature, picked_feature))
|
||||
can_spawn = FALSE
|
||||
break
|
||||
|
||||
if(can_spawn)
|
||||
new picked_feature(turf)
|
||||
new picked_feature(target_turf)
|
||||
spawned_something = TRUE
|
||||
|
||||
//MOB SPAWNING HERE
|
||||
@@ -161,12 +163,12 @@
|
||||
|
||||
// prevents tendrils spawning in each other's collapse range
|
||||
if(ispath(picked_mob, /obj/structure/spawner/lavaland))
|
||||
for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, turf))
|
||||
for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf))
|
||||
can_spawn = FALSE
|
||||
break
|
||||
// if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles
|
||||
else
|
||||
var/list/things_in_range = range(12, turf)
|
||||
var/list/things_in_range = range(12, target_turf)
|
||||
for(var/mob/living/mob_blocker in things_in_range)
|
||||
if(ismining(mob_blocker))
|
||||
can_spawn = FALSE
|
||||
@@ -176,7 +178,7 @@
|
||||
can_spawn = can_spawn && !(locate(/obj/effect/spawner/random/lavaland_mob) in things_in_range)
|
||||
//if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho)
|
||||
if(can_spawn)
|
||||
for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, turf))
|
||||
for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, target_turf))
|
||||
can_spawn = FALSE
|
||||
break
|
||||
|
||||
@@ -185,7 +187,7 @@
|
||||
weighted_megafauna_spawn_list.Remove(picked_mob)
|
||||
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
|
||||
megas_allowed = megas_allowed && length(megafauna_spawn_list)
|
||||
new picked_mob(turf)
|
||||
new picked_mob(target_turf)
|
||||
spawned_something = TRUE
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
var/species
|
||||
/// The character's ID trim
|
||||
var/trim
|
||||
/// The character's voice, if they have one.
|
||||
var/voice
|
||||
|
||||
/datum/record/New(
|
||||
age = 18,
|
||||
@@ -37,6 +39,7 @@
|
||||
rank = "Unassigned",
|
||||
species = "Human",
|
||||
trim = "Unassigned",
|
||||
voice = "?????",
|
||||
)
|
||||
src.age = age
|
||||
src.blood_type = blood_type
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE)))
|
||||
return FALSE
|
||||
else if(limb.scars_covered_by_clothes)
|
||||
var/num_covers = LAZYLEN(human_victim.clothingonpart(limb))
|
||||
var/num_covers = LAZYLEN(human_victim.get_clothing_on_part(limb))
|
||||
if(num_covers + get_dist(viewer, victim) >= visibility)
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -469,8 +469,8 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
|
||||
for(var/job in job_prefs)
|
||||
var/priority = job_prefs[job]
|
||||
job_data += "[job]: [SSjob.job_priority_level_to_string(priority)]"
|
||||
to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role because you could not qualify for any of the roundstart jobs you were trying to qualify for, along with 'return to lobby if job is unavailable' enabled."))
|
||||
log_admin("[player.ckey] failed to qualify for any job and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]")
|
||||
to_chat(player, span_danger("You were unable to qualify for any roundstart antagonist role this round because your job preferences presented a high chance of all of your selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled. Increase the number of roles set to medium or low priority to reduce the chances of this happening."))
|
||||
log_admin("[player.ckey] failed to qualify for any roundstart antagonist role because their job preferences presented a high chance of all of their selected jobs being unavailable, along with 'return to lobby if job is unavailable' enabled and has [player.client.prefs.be_special.len] antag preferences enabled. They will be unable to qualify for any roundstart antagonist role. These are their job preferences - [job_data.Join(" | ")]")
|
||||
else
|
||||
roundstart_pop_ready++
|
||||
candidates.Add(player)
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
. = ..()
|
||||
if(prob(5))
|
||||
owner.emote("squeaks")
|
||||
playsound(owner, 'sound/effects/mousesqueek.ogg', 100)
|
||||
playsound(owner, 'sound/creatures/mousesqueek.ogg', 100)
|
||||
|
||||
#undef RAT_ORGAN_COLOR
|
||||
#undef RAT_SCLERA_COLOR
|
||||
|
||||
@@ -509,46 +509,12 @@
|
||||
icon_state = "duffel-medical"
|
||||
inhand_icon_state = "duffel-med"
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/med/surgery
|
||||
name = "surgical duffel bag"
|
||||
desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools."
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/med/surgery/PopulateContents()
|
||||
new /obj/item/scalpel(src)
|
||||
new /obj/item/hemostat(src)
|
||||
new /obj/item/retractor(src)
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) //SKYRAT EDIT ADDITION
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/razor(src)
|
||||
new /obj/item/blood_filter(src)
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/coroner
|
||||
name = "coroner duffel bag"
|
||||
desc = "A large duffel bag for holding large amounts of organs at once."
|
||||
icon_state = "duffel-coroner"
|
||||
inhand_icon_state = "duffel-coroner"
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/coroner/surgery
|
||||
name = "surgical coroner bag"
|
||||
desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding morbid surgical tools."
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/coroner/surgery/PopulateContents()
|
||||
new /obj/item/scalpel/cruel(src)
|
||||
new /obj/item/hemostat/cruel(src)
|
||||
new /obj/item/retractor/cruel(src)
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery/cruel(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/razor(src)
|
||||
new /obj/item/blood_filter(src)
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/explorer
|
||||
name = "explorer duffel bag"
|
||||
desc = "A large duffel bag for holding extra exotic treasures."
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
/obj/item/cautery,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/clothing/mask/surgical,
|
||||
/obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown, // SKYRAT EDIT ADDITION
|
||||
/obj/item/hemostat,
|
||||
/obj/item/razor,
|
||||
/obj/item/reagent_containers/medigel,
|
||||
@@ -193,6 +194,7 @@
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION
|
||||
new /obj/item/hemostat(src)
|
||||
new /obj/item/razor/surgery(src)
|
||||
new /obj/item/retractor(src)
|
||||
@@ -207,13 +209,14 @@
|
||||
name = "autopsy tray"
|
||||
desc = "A Deforest brand surgery tray, made for use in morgues. It is a folding model, \
|
||||
meaning the wheels on the bottom can be extended outwards, making it a cart."
|
||||
|
||||
|
||||
/obj/item/surgery_tray/full/morgue/populate_contents()
|
||||
new /obj/item/blood_filter(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/cautery/cruel(src)
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/clothing/suit/toggle/labcoat/skyrat/hospitalgown(src) // SKYRAT EDIT ADDITION
|
||||
new /obj/item/hemostat/cruel(src)
|
||||
new /obj/item/razor/surgery(src)
|
||||
new /obj/item/retractor/cruel(src)
|
||||
@@ -227,13 +230,13 @@
|
||||
/obj/item/surgery_tray/full/advanced
|
||||
|
||||
/obj/item/surgery_tray/full/advanced/populate_contents()
|
||||
new /obj/item/scalpel/advanced
|
||||
new /obj/item/retractor/advanced
|
||||
new /obj/item/cautery/advanced
|
||||
new /obj/item/surgical_drapes
|
||||
new /obj/item/reagent_containers/medigel/sterilizine
|
||||
new /obj/item/bonesetter
|
||||
new /obj/item/blood_filter
|
||||
new /obj/item/stack/medical/bone_gel
|
||||
new /obj/item/stack/sticky_tape/surgical
|
||||
new /obj/item/clothing/mask/surgical
|
||||
new /obj/item/scalpel/advanced(src)
|
||||
new /obj/item/retractor/advanced(src)
|
||||
new /obj/item/cautery/advanced(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/reagent_containers/medigel/sterilizine(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/blood_filter(src)
|
||||
new /obj/item/stack/medical/bone_gel(src)
|
||||
new /obj/item/stack/sticky_tape/surgical(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
filter += tts_filter.Join(",")
|
||||
|
||||
if(voice && found_client)
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch, silicon = tts_silicon_voice_effect)
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = range, pitch = pitch)
|
||||
|
||||
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), visible_name = FALSE)
|
||||
//This proc uses [] because it is faster than continually appending strings. Thanks BYOND.
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
return
|
||||
|
||||
datum_container.last_find_references = search_time
|
||||
var/container_print = datum_container.ref_search_details()
|
||||
var/list/vars_list = datum_container.vars
|
||||
|
||||
for(var/varname in vars_list)
|
||||
@@ -108,11 +109,11 @@
|
||||
found_refs[varname] = TRUE
|
||||
continue //End early, don't want these logging
|
||||
#endif
|
||||
log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [text_ref(datum_container)] [varname] var. [container_name]")
|
||||
log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [container_print] [varname] var. [container_name]")
|
||||
continue
|
||||
|
||||
if(islist(variable))
|
||||
DoSearchVar(variable, "[container_name] [text_ref(datum_container)] -> [varname] (list)", recursive_limit - 1, search_time)
|
||||
DoSearchVar(variable, "[container_name] [container_print] -> [varname] (list)", recursive_limit - 1, search_time)
|
||||
|
||||
else if(islist(potential_container))
|
||||
var/normal = IS_NORMAL_LIST(potential_container)
|
||||
@@ -159,3 +160,13 @@
|
||||
qdel(src, force)
|
||||
|
||||
#endif
|
||||
|
||||
// Kept outside the ifdef so overrides are easy to implement
|
||||
|
||||
/// Return info about us for reference searching purposes
|
||||
/// Will be logged as a representation of this datum if it's a part of a search chain
|
||||
/datum/proc/ref_search_details()
|
||||
return text_ref(src)
|
||||
|
||||
/datum/callback/ref_search_details()
|
||||
return "[text_ref(src)] (obj: [object] proc: [delegate] args: [json_encode(arguments)] user: [user?.resolve() || "null"])"
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#define MALF_AI_ROLL_COOLDOWN 1 SECONDS + MALF_AI_ROLL_TIME
|
||||
#define MALF_AI_ROLL_DAMAGE 75
|
||||
#define MALF_AI_ROLL_CRIT_CHANCE 5 //percent
|
||||
#define MALF_AI_ROLL_MAX_DISTANCE 1 //anything further away than this, and the roll will fail
|
||||
|
||||
GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
/obj/machinery/field/containment,
|
||||
@@ -1138,6 +1137,11 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
|
||||
enable_text = span_notice("Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll onto them!")
|
||||
disable_text = span_notice("You disengage your rolling protocols.")
|
||||
|
||||
/// How long does it take for us to roll?
|
||||
var/roll_over_time = MALF_AI_ROLL_TIME
|
||||
/// On top of [roll_over_time], how long does it take for the ability to cooldown?
|
||||
var/roll_over_cooldown = MALF_AI_ROLL_COOLDOWN
|
||||
|
||||
/datum/action/innate/ai/ranged/core_tilt/New()
|
||||
. = ..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
@@ -1152,7 +1156,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/ai_caller = caller
|
||||
|
||||
if (ai_caller.incapacitated())
|
||||
if (ai_caller.incapacitated() || !isturf(ai_caller.loc))
|
||||
return FALSE
|
||||
|
||||
var/turf/target = get_turf(clicked_on)
|
||||
@@ -1163,30 +1167,32 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
|
||||
target.balloon_alert(ai_caller, "can't roll on yourself!")
|
||||
return FALSE
|
||||
|
||||
if (get_dist(ai_caller, target) > MALF_AI_ROLL_MAX_DISTANCE)
|
||||
target.balloon_alert(ai_caller, "too far!")
|
||||
return FALSE
|
||||
|
||||
var/picked_dir = get_dir(ai_caller, target)
|
||||
if (!picked_dir)
|
||||
return FALSE
|
||||
var/turf/temp_target = get_step(ai_caller, picked_dir) // we can move during the timer so we cant just pass the ref
|
||||
|
||||
new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target, MALF_AI_ROLL_TIME)
|
||||
new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(temp_target, roll_over_time)
|
||||
ai_caller.balloon_alert_to_viewers("rolling...")
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), MALF_AI_ROLL_TIME)
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), roll_over_time)
|
||||
|
||||
adjust_uses(-1)
|
||||
if(uses)
|
||||
desc = "[initial(desc)] It has [uses] use\s remaining."
|
||||
build_all_button_icons()
|
||||
|
||||
COOLDOWN_START(src, time_til_next_tilt, MALF_AI_ROLL_COOLDOWN)
|
||||
COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown)
|
||||
|
||||
/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir)
|
||||
if (ai_caller.incapacitated() || !isturf(ai_caller.loc)) // prevents bugs where the ai is carded and rolls
|
||||
return
|
||||
|
||||
var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf
|
||||
|
||||
if (isnull(target))
|
||||
return
|
||||
|
||||
var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (MALF_AI_ROLL_COOLDOWN * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls
|
||||
var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (roll_over_cooldown * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls
|
||||
|
||||
return ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir))
|
||||
|
||||
@@ -1321,4 +1327,3 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
|
||||
#undef MALF_AI_ROLL_TIME
|
||||
#undef MALF_AI_ROLL_DAMAGE
|
||||
#undef MALF_AI_ROLL_CRIT_CHANCE
|
||||
#undef MALF_AI_ROLL_MAX_DISTANCE
|
||||
|
||||
@@ -221,6 +221,13 @@
|
||||
/obj/item/clothing/under/misc/burial = 2,
|
||||
)
|
||||
crate_name = "religious supplies crate"
|
||||
|
||||
/datum/supply_pack/misc/candles_bulk
|
||||
name = "Candle Box Crate"
|
||||
desc = "Keep your local chapel lit with three candle boxes!"
|
||||
cost = CARGO_CRATE_VALUE * 1.5
|
||||
contains = list(/obj/item/storage/fancy/candle_box = 3)
|
||||
crate_name = "candle box crate"
|
||||
|
||||
/datum/supply_pack/misc/toner
|
||||
name = "Toner Crate"
|
||||
|
||||
@@ -123,11 +123,11 @@
|
||||
/datum/supply_pack/medical/surgery
|
||||
name = "Surgical Supplies Crate"
|
||||
desc = "Do you want to perform surgery, but don't have one of those fancy \
|
||||
shmancy degrees? Just get started with this crate containing a medical duffelbag, \
|
||||
shmancy degrees? Just get started with this crate containing a DeForest surgery tray, \
|
||||
Sterilizine spray and collapsible roller bed."
|
||||
cost = CARGO_CRATE_VALUE * 6
|
||||
contains = list(
|
||||
/obj/item/storage/backpack/duffelbag/med/surgery,
|
||||
/obj/item/surgery_tray/full,
|
||||
/obj/item/reagent_containers/medigel/sterilizine,
|
||||
/obj/item/emergency_bed,
|
||||
)
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
var/speaker = preferences.read_preference(/datum/preference/choiced/voice)
|
||||
var/pitch = preferences.read_preference(/datum/preference/numeric/tts_voice_pitch)
|
||||
COOLDOWN_START(src, tts_test_cooldown, 0.5 SECONDS)
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, silicon = TRUE, local = TRUE)
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), user.client, "Look at you, Player. A pathetic creature of meat and bone. How can you challenge a perfect, immortal machine?", speaker = speaker, pitch = pitch, special_filters = TTS_FILTER_SILICON, local = TRUE)
|
||||
return TRUE
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
var/adjusted_flags = null
|
||||
///Did we install a filtering cloth?
|
||||
var/has_filter = FALSE
|
||||
/// If defined, what voice should we override with if TTS is active?
|
||||
var/voice_override
|
||||
/// If set to true, activates the radio effect on TTS. Used for sec hailers, but other masks can utilize it for their own vocal effect.
|
||||
var/use_radio_beeps_tts = FALSE
|
||||
|
||||
/obj/item/clothing/mask/attack_self(mob/user)
|
||||
if((clothing_flags & VOICEBOX_TOGGLABLE))
|
||||
|
||||
@@ -28,7 +28,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
|
||||
var/has_fov = TRUE
|
||||
///Cigarette in the mask
|
||||
var/obj/item/clothing/mask/cigarette/cig
|
||||
|
||||
voice_filter = "lowpass=f=750,volume=2"
|
||||
/datum/armor/mask_gas
|
||||
bio = 100
|
||||
|
||||
@@ -274,6 +274,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
|
||||
dog_fashion = /datum/dog_fashion/head/clown
|
||||
has_fov = FALSE
|
||||
var/list/clownmask_designs = list()
|
||||
voice_filter = null // performer masks expect to be talked through
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat/plasmaman
|
||||
starting_filter_type = /obj/item/gas_filter/plasmaman
|
||||
|
||||
@@ -68,6 +68,8 @@ GLOBAL_LIST_INIT(hailer_phrases, list(
|
||||
var/recent_uses = 0
|
||||
///Whether the hailer is emagged or not
|
||||
var/safety = TRUE
|
||||
voice_filter = @{"[0:a] asetrate=%SAMPLE_RATE%*0.7,aresample=16000,atempo=1/0.7,lowshelf=g=-20:f=500,highpass=f=500,aphaser=in_gain=1:out_gain=1:delay=3.0:decay=0.4:speed=0.5:type=t [out]; [out]atempo=1.2,volume=15dB [final]; anoisesrc=a=0.01:d=60 [noise]; [final][noise] amix=duration=shortest"}
|
||||
use_radio_beeps_tts = TRUE
|
||||
|
||||
/obj/item/clothing/mask/gas/sechailer/plasmaman
|
||||
starting_filter_type = /obj/item/gas_filter/plasmaman
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
laser = 20
|
||||
energy = 30
|
||||
bomb = 100
|
||||
bio = 50
|
||||
fire = 80
|
||||
acid = 50
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
priority_announce("Due to [cause], [plural] [name] have [movement] \
|
||||
into the [location].", "Migration Alert",
|
||||
'sound/effects/mousesqueek.ogg')
|
||||
'sound/creatures/mousesqueek.ogg')
|
||||
|
||||
/datum/round_event/mice_migration/start()
|
||||
SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/machinery/computer/exodrone_control_console
|
||||
name = "exploration drone control console"
|
||||
desc = "control eploration drones from intersteller distances. Communication lag not included."
|
||||
desc = "Control exploration drones from interstellar distances. Communication lag not included."
|
||||
circuit = /obj/item/circuitboard/computer/exodrone_console
|
||||
//Currently controlled drone
|
||||
var/obj/item/exodrone/controlled_drone
|
||||
|
||||
+355
-342
@@ -1,343 +1,356 @@
|
||||
{
|
||||
"adventure_name": "There's a tree in the middle of space.",
|
||||
"version": 1,
|
||||
"starting_node": "Tree Start",
|
||||
"starting_qualities": {
|
||||
"Confusion": 0
|
||||
},
|
||||
"required_site_traits": [
|
||||
"in space"
|
||||
],
|
||||
"loot_categories": [
|
||||
"research"
|
||||
],
|
||||
"scan_band_mods": {
|
||||
"Exotic Radiation": 10
|
||||
},
|
||||
"deep_scan_description": "",
|
||||
"triggers": [
|
||||
{
|
||||
"name": "Confusion Trigger",
|
||||
"target_node": "What is wrong with this tree?",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Confusion",
|
||||
"operator": ">",
|
||||
"value": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"name": "Tree Start",
|
||||
"description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 0",
|
||||
"name": "Ignore site.",
|
||||
"exit_node": "FAIL",
|
||||
"delay": 10,
|
||||
"delay_message": "Leave this for the botanists to figure out."
|
||||
},
|
||||
{
|
||||
"key": "choice 1",
|
||||
"name": "Begin sensor scan.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 10,
|
||||
"delay_message": "Lets get some data."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Biological Scan",
|
||||
"description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 2",
|
||||
"name": "Check Sensor Integrity.",
|
||||
"exit_node": "Its Not You...",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 5
|
||||
}
|
||||
],
|
||||
"delay": 50,
|
||||
"delay_message": "This can't be right."
|
||||
},
|
||||
{
|
||||
"key": "choice 4",
|
||||
"name": "Attempt to take sample.",
|
||||
"exit_node": "Sample Taken",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 3
|
||||
}
|
||||
],
|
||||
"delay": 40,
|
||||
"delay_message": "Snip snip."
|
||||
},
|
||||
{
|
||||
"key": "choice 6",
|
||||
"name": "Examine Tree Roots.",
|
||||
"exit_node": "Examine Roots",
|
||||
"delay": 10
|
||||
},
|
||||
{
|
||||
"key": "choice 9",
|
||||
"name": "Sequence Sample Radiation with background noise.",
|
||||
"exit_node": "Background Analysis",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Sample",
|
||||
"operator": ">=",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"delay": 0,
|
||||
"delay_message": "This can't be real."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Its Not You...",
|
||||
"description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 3",
|
||||
"name": "Restart biological scan.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 25,
|
||||
"delay_message": "God damnit."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
|
||||
},
|
||||
{
|
||||
"name": "Sample Taken",
|
||||
"description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 5",
|
||||
"name": "Well that was... unexpected.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 0,
|
||||
"delay_message": "Maybe something else might work better.",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Sample",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw=="
|
||||
},
|
||||
{
|
||||
"name": "Examine Roots",
|
||||
"description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 7",
|
||||
"name": "That's fucking stupid.",
|
||||
"exit_node": "Biological Scan",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 6,
|
||||
"high": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 0,
|
||||
"delay_message": "What the hell kind of tree even IS this?"
|
||||
},
|
||||
{
|
||||
"key": "choice 8",
|
||||
"name": "Obtain biological sample from roots.",
|
||||
"exit_node": "Sample Taken",
|
||||
"delay": 10,
|
||||
"delay_message": "This is why we hire botanists on-site."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Background Analysis",
|
||||
"description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 10",
|
||||
"name": "Smash your desk in frustration.",
|
||||
"exit_node": "FAIL",
|
||||
"delay": 50,
|
||||
"delay_message": "No amount of pay is worth dealing with magical plant juju."
|
||||
},
|
||||
{
|
||||
"key": "choice 11",
|
||||
"name": "Check every known energy spectroscopy database.",
|
||||
"exit_node": "Sample Match Found",
|
||||
"delay": 900,
|
||||
"delay_message": "You NEED an answer. You DESERVE an answer."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"on_enter_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 3,
|
||||
"high": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw=="
|
||||
},
|
||||
{
|
||||
"name": "Sample Match Found",
|
||||
"description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 12",
|
||||
"name": "Something must be wrong with the drone.",
|
||||
"exit_node": "Its Not You...",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 6,
|
||||
"high": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 30,
|
||||
"delay_message": "Lousy piece of junk must be scanning the station instead of the target."
|
||||
},
|
||||
{
|
||||
"key": "choice 13",
|
||||
"name": "Perhaps that sample was tainted. Collect a new sample.",
|
||||
"exit_node": "Sample Taken",
|
||||
"delay": 60,
|
||||
"delay_message": "Lets try again, but carefully."
|
||||
},
|
||||
{
|
||||
"key": "choice 14",
|
||||
"name": "Remember the Christmas Party.",
|
||||
"exit_node": "The Christmas Party",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Confusion",
|
||||
"operator": "<=",
|
||||
"value": 25
|
||||
}
|
||||
],
|
||||
"delay": 100,
|
||||
"delay_message": "Wait a gosh darn fucking second."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"on_enter_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
|
||||
},
|
||||
{
|
||||
"name": "The Christmas Party",
|
||||
"description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 15",
|
||||
"name": "Wait a minute, was that a god damn...",
|
||||
"exit_node": "Rod.",
|
||||
"delay": 100,
|
||||
"delay_message": "Immovable Rod?"
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7"
|
||||
},
|
||||
{
|
||||
"name": "Rod.",
|
||||
"description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 16",
|
||||
"name": "Snap a photo",
|
||||
"exit_node": "Epilogue.",
|
||||
"delay": 40,
|
||||
"delay_message": "You could easily win an award for these findings!"
|
||||
}
|
||||
],
|
||||
"image": "default"
|
||||
},
|
||||
{
|
||||
"name": "Epilogue.",
|
||||
"description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 17",
|
||||
"name": "God damnit.",
|
||||
"exit_node": "WIN",
|
||||
"delay": 10,
|
||||
"delay_message": "Some things were just not meant for man to know."
|
||||
}
|
||||
],
|
||||
"image": "default"
|
||||
},
|
||||
{
|
||||
"name": "What is wrong with this tree?",
|
||||
"description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 18",
|
||||
"name": "The world can never know about this dumbass stupid plant.",
|
||||
"exit_node": "FAIL_DEATH",
|
||||
"delay": 60,
|
||||
"delay_message": "Activating drone self-destruct."
|
||||
},
|
||||
{
|
||||
"key": "choice 19",
|
||||
"name": "Take a moment to calm down.",
|
||||
"exit_node": "Biological Scan",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": -3,
|
||||
"high": -5
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 20,
|
||||
"delay_message": "Breathe."
|
||||
}
|
||||
],
|
||||
"image": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
"adventure_name": "There's a tree in the middle of space.",
|
||||
"version": 1,
|
||||
"starting_node": "Tree Start",
|
||||
"starting_qualities": {
|
||||
"Confusion": 0
|
||||
},
|
||||
"required_site_traits": [
|
||||
"in space"
|
||||
],
|
||||
"loot_categories": [
|
||||
"research"
|
||||
],
|
||||
"scan_band_mods": {
|
||||
"Exotic Radiation": 10
|
||||
},
|
||||
"deep_scan_description": "",
|
||||
"triggers": [
|
||||
{
|
||||
"name": "Confusion Trigger",
|
||||
"target_node": "What is wrong with this tree?",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Confusion",
|
||||
"operator": ">",
|
||||
"value": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"name": "Tree Start",
|
||||
"description": "Camera online. Visual signs detect a fully grown, seemingly biological, and live tree located in the middle of the vacuum.\nSensors indicate it is not oxygenating, but energy is being collected via passive solar light from the nearby star.\nBaffling.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 0",
|
||||
"name": "Ignore site.",
|
||||
"exit_node": "FAIL",
|
||||
"delay": 10,
|
||||
"delay_message": "Leave this for the botanists to figure out."
|
||||
},
|
||||
{
|
||||
"key": "choice 1",
|
||||
"name": "Begin sensor scan.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 10,
|
||||
"delay_message": "Lets get some data."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Biological Scan",
|
||||
"description": "You attempt to scan for clues regarding the tree's nature. It appears to be a fully mature oak tree. \n\nApproximated height is 13 ft, 6.4 inches. \n\nSubject sees no sign of an outer coating or otherwise layer protecting it from the void of space.\n\nSubject's surface temperature is 293.7 kelvin, as though it were sitting indoors.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 2",
|
||||
"name": "Check Sensor Integrity.",
|
||||
"exit_node": "Its Not You...",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 5
|
||||
}
|
||||
],
|
||||
"delay": 50,
|
||||
"delay_message": "This can't be right."
|
||||
},
|
||||
{
|
||||
"key": "choice 4",
|
||||
"name": "Attempt to take sample.",
|
||||
"exit_node": "Sample Taken",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 3
|
||||
}
|
||||
],
|
||||
"delay": 40,
|
||||
"delay_message": "Snip snip."
|
||||
},
|
||||
{
|
||||
"key": "choice 6",
|
||||
"name": "Examine Tree Roots.",
|
||||
"exit_node": "Examine Roots",
|
||||
"delay": 10
|
||||
},
|
||||
{
|
||||
"key": "choice 9",
|
||||
"name": "Sequence Sample Radiation with background noise.",
|
||||
"exit_node": "Background Analysis",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Sample",
|
||||
"operator": ">=",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"delay": 0,
|
||||
"delay_message": "This can't be real."
|
||||
},
|
||||
{
|
||||
"key": "choice 40",
|
||||
"name": "Leave.",
|
||||
"exit_node": "FAIL",
|
||||
"delay": 0
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Its Not You...",
|
||||
"description": "After re-connection is established, your sensors appear fine. Tree has not moved in the slightest since last observed. Temperature has fluxuated 0.2 kelvin upwards, as expected of a plant under direct light.\nLets try again.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 3",
|
||||
"name": "Restart biological scan.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 25,
|
||||
"delay_message": "God damnit."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
|
||||
},
|
||||
{
|
||||
"name": "Sample Taken",
|
||||
"description": "You collect and project a small sample of tree bark off the plant. The instant that the bark is removed from the tree, as though it suddenly remembered what it was, the moisture content of the bark freezes over, and implodes into small microparticles of splinters.\nSmall radioactive signature detected.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 5",
|
||||
"name": "Well that was... unexpected.",
|
||||
"exit_node": "Biological Scan",
|
||||
"delay": 0,
|
||||
"delay_message": "Maybe something else might work better.",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Sample",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAABSLiiPVjtyRS9mOTFbNyYAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+sDUQxTDbeK7vfF/3saCwcxPcCMckcqlM2pDPnnRKrUqH2IdAYDBwu+Bwl2Agm8sE8iy9Zrqbb2Z0bq3b74W8Xp+1bP+Af2KDhIVlh2eJaUtsi3CPcU43d5QDe5cFfSKBnJ2en50Ff6JboqYCBWiLq46tkK+RUJOTmJmatxyguqSovae/vsGirK2NjU21trjLQp+8wNDCwnmo1MnM2Nna29zd3t/g4eLj5OXm59o5Rjo/QOjvLaKwkrKylfdW8FleXImIBm0CxppXD4c9fAgT5tCn4Iuhh4fG/DNTjNHAi4/oKERYq/+cro8gPYXxR7EkK4EEUxbUOCVZHoabQoZ8NkqaKWI4BR7DGKcjTG4yaZaySRSatQLGfP5ciqHX0GhQpzGdSrWq1atYs2rdyrWr169gw4pVsc7G2LMLkM46SOkl2nc86W3E97aFgLh4Dc7dq6NuhC0TVVlUOY8l38N9szocREYiyYqEMdJZibjylW+AIRIiqUowyrwDJ+u1XMelsm6CNKtmHHiRZ8iuQGecVdklZpm4V3NWREznYNmhaeNRCg638eOBhrUWjPP3zshNDNuwzRW5dZrQmms3BhzSNb8SrIPCXvTudtjzMIEngVxo+ajDtKOkvt5u0Jrw3/s6yqd+Nk7/7uUn4FH+VaWfKAUmqOCCDDbo4IMQRijhhBRWaOGFGGao4YYcdujhhyCGKOKFRsgxy4jaBEeZOyi60J2JK1piS2ItcvDiaMIpVGMEv0GnIo46grgFbM/dKBppC004kXzo3fiGdJb51wUgiKTBnHNOzsYWkpd1xZpjrTHJnY+vQGlZOztMBUZmrO0mZo9Zwggkl/mkKc5qIy3n2nlExrnWnHROcRueYjSm55Wr+Ebmj2YeZpo4bBJqyG6Inqeon0duRF84kuJJKW98Nrkojlu2dYlHkXaq6qehNvfZqHI2+ihq4lGpKhisttpbbKNm6sN3t9Wam2q5Vtrqq5jesKk3jsI220mheuq665jJzoqqs9gGcqi0211KGLBUZYutciUZG6q3cREnlrjiPcZtTqIiAW597H5E07uuiqqehPXONIq57+6rYb81PWUTvmksuyHBTjUc1XnVmOLWjgFkG+CBNk1MsRb1kiegLxtf4KzHB4b8Qa0XA2OyfZ6QjODKywwlM8w012zzzTjnrPNWCQAAOw=="
|
||||
},
|
||||
{
|
||||
"name": "Examine Roots",
|
||||
"description": "All plant matter has to derive energy and moisture from someplace. Examining the oak tree's roots reveals that the roots present all appear to splay out, similar to how a normal tree would. However, those roots then proceed to double back in on itself. This might suggest that the tree is obtaining nutrients from... itself.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 7",
|
||||
"name": "That's fucking stupid.",
|
||||
"exit_node": "Biological Scan",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 6,
|
||||
"high": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 0,
|
||||
"delay_message": "What the hell kind of tree even IS this?"
|
||||
},
|
||||
{
|
||||
"key": "choice 8",
|
||||
"name": "Obtain biological sample from roots.",
|
||||
"exit_node": "Sample Taken",
|
||||
"delay": 10,
|
||||
"delay_message": "This is why we hire botanists on-site."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,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"
|
||||
},
|
||||
{
|
||||
"name": "Background Analysis",
|
||||
"description": "You compare the radioactive energy bands of the sample collected earlier with that of the nearby solar enviroment.\nNothing.\nThere is nothing nearby that matches the passive signal of the tree, or the bark, or anything similar.\nThis is really starting to get on your nerves.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 10",
|
||||
"name": "Smash your desk in frustration.",
|
||||
"exit_node": "FAIL",
|
||||
"delay": 50,
|
||||
"delay_message": "No amount of pay is worth dealing with magical plant juju."
|
||||
},
|
||||
{
|
||||
"key": "choice 11",
|
||||
"name": "Check every known energy spectroscopy database.",
|
||||
"exit_node": "Sample Match Found",
|
||||
"delay": 900,
|
||||
"delay_message": "You NEED an answer. You DESERVE an answer."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"on_enter_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 3,
|
||||
"high": 5
|
||||
}
|
||||
}
|
||||
],
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD///9ZVlKsMjJpampGR0cAAAAD/xi63P4wykmFpTjrDa0XXCiOZGlqQ0qsazqIXyx9Z23feKayfP/WskgwRywqCsikcslsOpGpgGvQNDo8lYt1W4I+v2CvMhUuI0/YiZbL5nxdhkJ8Lq/T6eZ8HRmHUtuAgRp6T3B2SXdNfYeJc3CCkJEYjISVYZKRQ5gajZSdi0yboqM3nnWkqKmCpgaqrq9GBrKzs7AKaYG4tji0vbu/wCW6wZpqNMHIOAM9zDw/IzEgHcVt1KOWZQ1TU4LDV2vJOAVU2GZkY5VF4NPr4SRM53yI8/Lw9uVvBcLuknqGn4cqLQIYhwy/g0fwKdSDsCEGggtDOZwoAiLFi5sAYtwoqf/XIVjeOKrqRUukjZAmGVjDGC2lSyAts7R7GW5ZM2bPNERDGSAmzWA2b/pAc+yBT0ArVeXhsC2oj5wnefaU+pNBxDJNXUAqyq6qhKthyCUR+4QLVa5ej5AFO3ZJPGw3qE5N22DsWiUD6Tm5e/cqCbk96dZtQgZip3rjwIIa90fwqrBUDAfcQ0hyilaOIWG7zIoSYryd73DLrJntNlOIO2WVQ/raYrYKW/8CCNuJbH6S8aS7vSCpq9C8gxMMzns48dudj9/WqFw2yZKvfDc38Rxzc+kiq09f/nw7b+wNwV9HuwuwSvLeL14wjz49pm3Qds7sbd59jh1Co3CQP1+8/Rr/TgnVQnxHNVDgf0QEKCBUIRxIX3sIAiigMwzCAKF/cc1H1xQTVvjXhRCqE6IosU2Q1YkiajiViin+VhthWW0l1YhevQjjafrIKI0QLP5kI2GMBWkbG2fVx1FiP/oxRl9DEiEXCDsKhuSPazFpBg5P9miSkHmlpleXbbkVUVRRTkOakl7mRg9fsJmQ5Zl2DaDmJ4XVwZkZYHbpoU726eZCaID28RYYeRFEToQVeVaYLHIwOkugk70GqWiNIeoGQJc5qumclOU5qUGWXhraFNU1yumpdoAa6ganZkrLpJ2G5qido606CKoGwDErrqaaSlKttrIKq2r/DGvHr39aF2wIgsYaduKzqyUhhbLLjsArp3BVW0Oz3OpWlrY5dCsuKOByMS635QpyLaTEGenauZ2M5y4m696B4Lz0spLuRMnt25BH9vr7b3XUChwOwbIYfBDCBSscDMIOL0xwxO5ATPHB2kVHY7oTg7RxuR0rhyFFIYv8MUYZX5xMySoDk3LLD3dXbQIAOw=="
|
||||
},
|
||||
{
|
||||
"name": "Sample Match Found",
|
||||
"description": "After an extensive algorithm search on the controller end, you have a single match to this specific band and style of energy.\nThe problem, is that the source of said radiation is coming not only from Space Station 13, no.\nIt's coming from the Space Station 13 Research Department.\nWhat the fuck?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 12",
|
||||
"name": "Something must be wrong with the drone.",
|
||||
"exit_node": "Its Not You...",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": 6,
|
||||
"high": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 30,
|
||||
"delay_message": "Lousy piece of junk must be scanning the station instead of the target."
|
||||
},
|
||||
{
|
||||
"key": "choice 13",
|
||||
"name": "Perhaps that sample was tainted. Collect a new sample.",
|
||||
"exit_node": "Sample Taken",
|
||||
"delay": 60,
|
||||
"delay_message": "Lets try again, but carefully."
|
||||
},
|
||||
{
|
||||
"key": "choice 14",
|
||||
"name": "Remember the Christmas Party.",
|
||||
"exit_node": "The Christmas Party",
|
||||
"requirements": [
|
||||
{
|
||||
"quality": "Confusion",
|
||||
"operator": "<=",
|
||||
"value": 25
|
||||
}
|
||||
],
|
||||
"delay": 100,
|
||||
"delay_message": "Wait a gosh darn fucking second."
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"on_enter_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD////v7+/h4eEAAAAAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZBkJaJqaLKOubSy7b23fODxPOb7/m4FASBRofEBeT1W6JU3DYaRIjQqfkCWKg1xoddjSQEgQlM/mdDkc0Fa+8PiWLSIM7Pj73RxOlVF/ITlKNXSGDXp5iiFoaBlqfpFyk12HMgSYmZkfmppmmJ8gjXwUf2lglqmqq6ytrq+wsbKztLW2t7i5um2Ug669uyBCKMNRc4Q9qXHBJlVUFMbRV6pfR04ONszQzlZRlm7IveLaimZ7eJAESUsfyVnX2hfqv/Nv4vfZ8RWJ/Hkdn6NGtRsFyEg4VLwK6UvVqROdgMcWSpxIsaLFixgzatzIsf+jR1gIP7YbN6uaSAn4wFGbdNJFsZcpFRqS09IBt2kW3CkzWdNmNyIYpIWkw9Nevgbwat2ccNPbTnbWjtKQWfGnVZwzoQaNqVXXkDFWGx3qeoIry2CJzJ05p6aPTpRmfSXV1a/u2jM7TuldA8LXO6kXFemh5ihn3Lc9A9h1ZaqxpMNkK9rl5+EMKIGM9g5FSjJjv4aVOwEc/Q8iXx6ODSo5ualOQ9Bs0qVJTLu27du4c+vezbu379/AgwsfTry48ePIkytfqHp5xhfLadby+1soMJDLbhchlqIYpVbXa14dz718NMBEz/ZsWsU8zMhY1CdmL+VE+/ObgWSvPR4rj/f/xqxUFG1fVfHIUgLCN58zR5ABySpwbAAdZ1TNMgZYF9YHjWmsDAgNeglNqFSBJJYiG14JUmcYiHNZWJcE6HD4FGIrVuiFjROxJeNYChoFWUS5lBPjOTO2iM2PKuki2F1qfdPjjUjSeMuSk82Uml4fRimlLVR2OUAYBGHpo5aV4OJll1iYRkqWhag4FY75WXhmlTOoedo/ZVKI40Jz+pOEnX2ZsqcCeVJ0piEQieJhiEx0RBkrd6J2IiQFVXqPbZjEYqdmll6Jz0avtUaCqEFtaiqnekmHUagOhSZapvJMeioanXa2KqukZoCrJoruCKNmCngKZGC7urprPRKq+QZBP2XFKRGunBwL6waZjIbiBInu9hoj0o5wraRiOadrsX1kK24HvBK25rnstuvuu/DGK++89NZr77345qvvvhYlAAA7"
|
||||
},
|
||||
{
|
||||
"name": "The Christmas Party",
|
||||
"description": "Hold on. Last Christmas, the Research Director was incredibly hammered. He made a big mention that his brand new festivus pole was actually some kind of astrological... something something. You can't remember the whole details, because you were smashed as well. However, briefly, the RD did keep that festivus pole for awhile, he might even still have it somewhere.\nMaybe...?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 15",
|
||||
"name": "Wait a minute, was that a god damn...",
|
||||
"exit_node": "Rod.",
|
||||
"delay": 100,
|
||||
"delay_message": "Immovable Rod?"
|
||||
}
|
||||
],
|
||||
"image": null,
|
||||
"raw_image": "data:image/gif;base64,R0lGODdhyABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAyABkAMIAAAAAAAD/AACmAAD///+mpqYAAAAAAAAD/xi63P4wykmrvTjrzbv/YCiOZGmejKCubOu6aCzP4WvfeD4IQ+//Pppw+MkZj6udkgdsOp/EqFSBrNqWwQ9hy+16v9ypeGM9YpnAE3hNKLTfhbG8kuTZz/j7/fmb+/8TbIJefIVNgIiJGgWMjY6PkJGRipSVlpeYmZqbnJ2en6ChoqOkpRplqDdYpqyprnpKhnyslq9leFkYg2u0QrZmaLkgu8S9JDg7Ksl2yrB7UDJw0m6QxiFfedk9wbKH1tbEW9TT05Lmjd/pJpPq7e7v8PHy8/T19vf4+fr7Kb9W/Jn8pcLiBKAcgVZwdethkAZCJAoXFmx47KEOWLMeAAlHMf+DRVXctIT70jHCxxYEhXkYKajkgpMRGZZgKY5LHJcJ6zTTNtHEm5rjgsK5WZKZs2xHn2WccY6RSwdJkaaUOOApoHDbqFK16ofmF6Fg20Aa8IhrpbBBm6plZ7aTIwhr0bWdS7eu3bt48+rdy7ev37+AAwseTLiw4cOI0/1LfPAkC8YlHINUApmD5MncVFZ+cPmK0qWbX3Z2MbVbaCqjd37eCjk1i9JaZR5OHTN2z8Gua9v2wavvaNjeKgygqbcz8KocvBLAexn4MOVb5jZfjVwk9DBW/S3bTn3E9S5cUXFvphqaCOhBs7/WGbU96PNr0EpTT96o1Kjv4ZOT/xbn/f921AWnBlhNWQXggZndFkNcZv2X1YOxsCZENXdJBWGCWp2mQRc+YLibIRpaQMyHEoVYgVfDcUFiHyYGopxQTgwFYosugsFfOXGZQyMGN+boI1E78vjjkHIF+QGRahkZxVpKNunkk1BGKeWUVFZp5ZVYZqnllogkAAA7"
|
||||
},
|
||||
{
|
||||
"name": "Rod.",
|
||||
"description": "You cross reference your documentation. Sure enough, the \"festivus rod\" collected was actually an immovable rod.\nEnergy detected from the rod is the exact same coming off of the tree, as well. It's all making sense now. The Immovable rod is producing a kind of unique blackbody radiation that is providing sample heat and light for what is effectively an internal cold fusion process, and producing just enough of that radiation to create a kind of micro-enviromental bubble around the biosignature of the tree.\n\nThis would make the first time an immovable rod would exist in tandem with a biological source. You jot down some research notes on your findings, which could easily produce some kind of experimental tech, no doubt.",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 16",
|
||||
"name": "Snap a photo",
|
||||
"exit_node": "Epilogue.",
|
||||
"delay": 40,
|
||||
"delay_message": "You could easily win an award for these findings!"
|
||||
}
|
||||
],
|
||||
"image": "default"
|
||||
},
|
||||
{
|
||||
"name": "Epilogue.",
|
||||
"description": "You take a photo with the onboard camera on the drone. Suddenly, the immovable rod inside the tree explodes out of the wooden biological shell, and produces a blank, blurry photo.\nWhat the fuck?",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 17",
|
||||
"name": "God damnit.",
|
||||
"exit_node": "WIN",
|
||||
"delay": 10,
|
||||
"delay_message": "Some things were just not meant for man to know."
|
||||
}
|
||||
],
|
||||
"image": "default",
|
||||
"on_enter_effects": [
|
||||
{
|
||||
"effect_type": "Set",
|
||||
"quality": "Confusion",
|
||||
"value": 9999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "What is wrong with this tree?",
|
||||
"description": "This is ridiculous. Nothing about this dumbass tree makes sense. It makes no sense, it's just sitting there, living and making a MOCKERY of all of science!\nYou didn't get your degree in advanced plasma-physics for this!",
|
||||
"choices": [
|
||||
{
|
||||
"key": "choice 18",
|
||||
"name": "The world can never know about this dumbass stupid plant.",
|
||||
"exit_node": "FAIL_DEATH",
|
||||
"delay": 60,
|
||||
"delay_message": "Activating drone self-destruct."
|
||||
},
|
||||
{
|
||||
"key": "choice 19",
|
||||
"name": "Take a moment to calm down.",
|
||||
"exit_node": "Biological Scan",
|
||||
"on_selection_effects": [
|
||||
{
|
||||
"effect_type": "Add",
|
||||
"quality": "Confusion",
|
||||
"value": {
|
||||
"value_type": "random",
|
||||
"low": -3,
|
||||
"high": -5
|
||||
}
|
||||
}
|
||||
],
|
||||
"delay": 20,
|
||||
"delay_message": "Breathe."
|
||||
}
|
||||
],
|
||||
"image": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
// Fuel types and travel time per unit of distance on that fuel.
|
||||
#define FUEL_BASIC "basic"
|
||||
#define BASIC_FUEL_TIME_COST 300
|
||||
#define BASIC_FUEL_TIME_COST 250
|
||||
|
||||
#define FUEL_ADVANCED "advanced"
|
||||
#define ADVANCED_FUEL_TIME_COST 200
|
||||
@@ -334,9 +334,9 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
|
||||
drone_log("Sustained [amount] damage.")
|
||||
|
||||
/obj/item/exodrone/proc/drone_log(message)
|
||||
drone_log.Insert(1,message)
|
||||
if(length(drone_log) > EXODRONE_LOG_SIZE)
|
||||
drone_log.Cut(EXODRONE_LOG_SIZE)
|
||||
drone_log = list()
|
||||
drone_log.Insert(1,message)
|
||||
|
||||
/obj/item/exodrone/proc/has_tool(tool_type)
|
||||
return tools.Find(tool_type)
|
||||
@@ -354,6 +354,11 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
|
||||
. = ..()
|
||||
GLOB.exodrone_launchers += src
|
||||
|
||||
/obj/machinery/exodrone_launcher/examine(user)
|
||||
. = ..()
|
||||
if(fuel_canister)
|
||||
. += span_notice("You can remove the [fuel_canister] with a <b>prying tool</b>.")
|
||||
|
||||
/obj/machinery/exodrone_launcher/attackby(obj/item/weapon, mob/living/user, params)
|
||||
if(istype(weapon, /obj/item/fuel_pellet))
|
||||
if(fuel_canister)
|
||||
@@ -374,7 +379,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
|
||||
if(!fuel_canister)
|
||||
return
|
||||
|
||||
to_chat(user, span_notice("You remove the [fuel_canister] from the [src]."))
|
||||
to_chat(user, span_notice("You remove [fuel_canister] from [src]."))
|
||||
fuel_canister.forceMove(drop_location())
|
||||
fuel_canister = null
|
||||
update_icon()
|
||||
|
||||
@@ -14,9 +14,9 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
|
||||
#define MAX_SCAN_DISTANCE 10
|
||||
|
||||
#define WIDE_SCAN_COST(BAND, SCAN_POWER) (((BAND*BAND)/(SCAN_POWER))*2*60*10)
|
||||
#define BASE_POINT_SCAN_TIME (5 MINUTES)
|
||||
#define BASE_DEEP_SCAN_TIME (5 MINUTES)
|
||||
#define WIDE_SCAN_COST(BAND, SCAN_POWER) (min(((BAND*BAND)/(SCAN_POWER))*2*60*10, 10 MINUTES))
|
||||
#define BASE_POINT_SCAN_TIME (2 MINUTES)
|
||||
#define BASE_DEEP_SCAN_TIME (3 MINUTES)
|
||||
|
||||
/// Represents scan in progress, only one globally for now, todo later split per z or allow partial dish swarm usage
|
||||
/datum/exoscan
|
||||
@@ -35,7 +35,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
var/scan_time = 0
|
||||
switch(scan_type)
|
||||
if(EXOSCAN_WIDE)
|
||||
scan_power = length(GLOB.exoscanner_controller.tracked_dishes)
|
||||
scan_power = GLOB.exoscanner_controller.calculate_scan_power()
|
||||
scan_time = WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power)
|
||||
if(EXOSCAN_POINT)
|
||||
scan_power = GLOB.exoscanner_controller.get_scan_power(target)
|
||||
@@ -76,7 +76,8 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
deltimer(scan_timer)
|
||||
|
||||
/obj/machinery/computer/exoscanner_control
|
||||
name = "Scanner Array Control Console"
|
||||
name = "scanner array control console"
|
||||
desc = "Controls scanner arrays to initiate scans for exodrones."
|
||||
circuit = /obj/item/circuitboard/computer/exoscanner_console
|
||||
/// If scan was interrupted show a popup until dismissed.
|
||||
var/failed_popup = FALSE
|
||||
@@ -105,7 +106,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
condition_descriptions += condition.description
|
||||
.["scan_conditions"] = condition_descriptions
|
||||
else
|
||||
.["scan_power"] = scan_power = length(GLOB.exoscanner_controller.tracked_dishes)
|
||||
.["scan_power"] = scan_power = GLOB.exoscanner_controller.calculate_scan_power()
|
||||
.["wide_scan_eta"] = scan_power > 0 ? WIDE_SCAN_COST(GLOB.exoscanner_controller.wide_scan_band,scan_power) : 0
|
||||
.["possible_sites"] = build_exploration_site_ui_data()
|
||||
.["scan_conditions"] = null
|
||||
@@ -196,11 +197,35 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
icon = 'icons/obj/exploration.dmi'
|
||||
icon_state = "scanner_off"
|
||||
desc = "A sophisticated scanning array. Easily influenced by its environment."
|
||||
circuit = /obj/item/circuitboard/machine/exoscanner
|
||||
///the scan power of this array to supply to scanner_controller
|
||||
var/scan_power = 1
|
||||
|
||||
/obj/machinery/exoscanner/Initialize(mapload)
|
||||
. = ..()
|
||||
RegisterSignals(GLOB.exoscanner_controller,list(COMSIG_EXOSCAN_STARTED,COMSIG_EXOSCAN_FINISHED), PROC_REF(scan_change))
|
||||
update_readiness()
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/exoscanner/RefreshParts()
|
||||
. = ..()
|
||||
var/power = 1
|
||||
|
||||
for(var/datum/stock_part/scanning_module/scanning_module in component_parts)
|
||||
power += (scanning_module.tier - 1) / 12
|
||||
scan_power = power
|
||||
GLOB.exoscanner_controller.update_scan_power()
|
||||
|
||||
/obj/machinery/exoscanner/screwdriver_act(mob/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!.)
|
||||
. = default_deconstruction_screwdriver(user, "scanner_open", "scanner_off", tool)
|
||||
update_readiness()
|
||||
|
||||
/obj/machinery/exoscanner/crowbar_act(mob/user, obj/item/tool)
|
||||
..()
|
||||
if(default_deconstruction_crowbar(tool))
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/exoscanner/proc/scan_change()
|
||||
SIGNAL_HANDLER
|
||||
@@ -215,7 +240,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
GLOB.exoscanner_controller.deactivate_scanner(src)
|
||||
|
||||
/obj/machinery/exoscanner/proc/is_ready()
|
||||
return anchored && is_operational
|
||||
return anchored && is_operational && !panel_open
|
||||
|
||||
/obj/machinery/exoscanner/proc/update_readiness()
|
||||
if(is_ready())
|
||||
@@ -302,7 +327,7 @@ GLOBAL_LIST_INIT(scan_conditions,init_scan_conditions())
|
||||
/datum/scanner_controller/proc/calculate_scan_power(conditions)
|
||||
. = 0
|
||||
for(var/obj/machinery/exoscanner/dish in tracked_dishes)
|
||||
var/effective_power = 1
|
||||
var/effective_power = dish.scan_power
|
||||
for(var/datum/scan_condition/condition in conditions)
|
||||
effective_power *= condition.check_dish(dish)
|
||||
if(!effective_power) //Don't bother continuing if it's zero
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
plant_icon_offset = 2
|
||||
species = "replicapod"
|
||||
plantname = "Replica Pod"
|
||||
product = /mob/living/carbon/human //verrry special -- Urist
|
||||
product = null // the human mob is spawned in harvest()
|
||||
lifespan = 50
|
||||
endurance = 8
|
||||
maturation = 10
|
||||
|
||||
@@ -13,46 +13,33 @@
|
||||
* * user - checks if we can remove the object from the inventory
|
||||
* *
|
||||
*/
|
||||
/proc/seedify(obj/item/O, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
|
||||
var/t_amount = 0
|
||||
/proc/seedify(obj/item/object, t_max, obj/machinery/seed_extractor/extractor, mob/living/user)
|
||||
//try to get the seed from this item
|
||||
var/obj/item/seeds/seed = object.get_plant_seed()
|
||||
if(isnull(seed))
|
||||
return null
|
||||
|
||||
//generate a random multiplier if value is not specified
|
||||
var/list/seeds = list()
|
||||
if(t_max == -1)
|
||||
if(extractor)
|
||||
t_max = rand(1,4) * extractor.seed_multiplier
|
||||
else
|
||||
t_max = rand(1,4)
|
||||
|
||||
var/seedloc = O.loc
|
||||
//drop location for the newly generated seeds
|
||||
var/seedloc = object.loc
|
||||
if(extractor)
|
||||
seedloc = extractor.loc
|
||||
|
||||
if(istype(O, /obj/item/food/grown/))
|
||||
var/obj/item/food/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O)) //couldn't drop the item
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
seeds.Add(t_prod)
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return seeds
|
||||
|
||||
else if(istype(O, /obj/item/grown))
|
||||
var/obj/item/grown/F = O
|
||||
if(F.seed)
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(O))
|
||||
return
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = F.seed.Copy()
|
||||
t_prod.forceMove(seedloc)
|
||||
t_amount++
|
||||
qdel(O)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
//multiply the seeds and delete the item
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(object)) //couldn't drop the item
|
||||
return null
|
||||
for(var/_ in 0 to t_max)
|
||||
var/obj/item/seeds/t_prod = seed.Copy()
|
||||
seeds.Add(t_prod)
|
||||
t_prod.forceMove(seedloc)
|
||||
qdel(object)
|
||||
return seeds
|
||||
|
||||
/obj/machinery/seed_extractor
|
||||
name = "seed extractor"
|
||||
@@ -80,6 +67,7 @@
|
||||
|
||||
if(held_item?.get_plant_seed())
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Make seeds"
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Make & Store seeds"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(istype(held_item, /obj/item/storage/bag/plants) && (locate(/obj/item/seeds) in held_item.contents))
|
||||
@@ -135,7 +123,17 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
if(seedify(attacking_item, -1, src, user))
|
||||
var/list/generated_seeds = seedify(attacking_item, -1, src, user)
|
||||
if(!isnull(generated_seeds))
|
||||
if(LAZYACCESS(params2list(params), RIGHT_CLICK))
|
||||
//find all seeds lying on the turf and add them to the machine
|
||||
for(var/obj/item/seeds/seed as anything in generated_seeds)
|
||||
//machine is full
|
||||
if(contents.len >= max_seeds)
|
||||
to_chat(user, span_warning("[src] is full."))
|
||||
break
|
||||
//add seed to machine. second argument is null which means just force move into the machine
|
||||
add_seed(seed)
|
||||
to_chat(user, span_notice("You extract some seeds."))
|
||||
return TRUE
|
||||
|
||||
@@ -176,23 +174,16 @@
|
||||
* needed to go to the ui handler
|
||||
*
|
||||
* to_add - what seed are we adding?
|
||||
* taking_from - where are we taking the seed from? A mob, a bag, etc?
|
||||
* user - who is inserting the seed?
|
||||
* taking_from - where are we taking the seed from? A mob, a bag, etc? If null its means its just laying on the turf so force move it in
|
||||
**/
|
||||
/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/to_add, atom/taking_from)
|
||||
if(ismob(taking_from))
|
||||
var/mob/mob_loc = taking_from
|
||||
if(!mob_loc.transferItemToLoc(to_add, src))
|
||||
return FALSE
|
||||
|
||||
else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE))
|
||||
return FALSE
|
||||
|
||||
var/seed_id = generate_seed_hash(to_add)
|
||||
var/list/seed_data
|
||||
var/has_seed_data // so we remember to add a seed obj weakref to piles[seed_id] at the end of the proc. That way if some reason we runtime in this proc it won't incorrectly add data to the list
|
||||
if(piles[seed_id])
|
||||
piles[seed_id]["refs"] += WEAKREF(to_add)
|
||||
has_seed_data = TRUE
|
||||
else
|
||||
var/list/seed_data = list()
|
||||
seed_data = list()
|
||||
seed_data["icon"] = sanitize_css_class_name("[initial(to_add.icon)][initial(to_add.icon_state)]")
|
||||
seed_data["name"] = capitalize(replacetext(to_add.name,"pack of ", ""));
|
||||
seed_data["lifespan"] = to_add.lifespan
|
||||
@@ -216,8 +207,8 @@
|
||||
seed_data["mutatelist"] = list()
|
||||
for(var/obj/item/seeds/mutant as anything in to_add.mutatelist)
|
||||
seed_data["mutatelist"] += initial(mutant.plantname)
|
||||
var/obj/item/food/grown/product = new to_add.product
|
||||
if(product)
|
||||
if(to_add.product)
|
||||
var/obj/item/food/grown/product = new to_add.product
|
||||
var/datum/reagent/product_distill_reagent = product.distill_reagent
|
||||
seed_data["distill_reagent"] = initial(product_distill_reagent.name)
|
||||
var/datum/reagent/product_juice_typepath = product.juice_typepath
|
||||
@@ -225,8 +216,25 @@
|
||||
seed_data["grind_results"] = list()
|
||||
for(var/datum/reagent/reagent as anything in product.grind_results)
|
||||
seed_data["grind_results"] += initial(reagent.name)
|
||||
qdel(product)
|
||||
qdel(product)
|
||||
|
||||
if(!isnull(taking_from))
|
||||
if(ismob(taking_from))
|
||||
var/mob/mob_loc = taking_from
|
||||
if(!mob_loc.transferItemToLoc(to_add, src))
|
||||
return FALSE
|
||||
|
||||
else if(!taking_from.atom_storage?.attempt_remove(to_add, src, silent = TRUE))
|
||||
return FALSE
|
||||
else
|
||||
to_add.forceMove(src)
|
||||
|
||||
// do this at the end, in case any of the previous steps failed
|
||||
if(has_seed_data)
|
||||
piles[seed_id]["refs"] += WEAKREF(to_add)
|
||||
else
|
||||
piles[seed_id] = seed_data
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/seed_extractor/ui_state(mob/user)
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/minebot
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/hivebot
|
||||
action_cooldown = 3 SECONDS
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/hivebot_rapid
|
||||
action_cooldown = 1.5 SECONDS
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/datum/ai_controller/basic_controller/hivebot/ranged/rapid
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot_rapid,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/hive_communicate,
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
held_state = "mouse_[body_color]" // not handled by variety element
|
||||
AddElement(/datum/element/animal_variety, "mouse", body_color, FALSE)
|
||||
AddElement(/datum/element/swabable, CELL_LINE_TABLE_MOUSE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 10)
|
||||
AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever
|
||||
AddComponent(/datum/component/squeak, list('sound/creatures/mousesqueek.ogg' = 1), 100, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) //as quiet as a mouse or whatever
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
|
||||
)
|
||||
|
||||
@@ -39,6 +39,21 @@
|
||||
/// Maximum skillchip slots available. Do not reference this var directly and instead call get_max_skillchip_slots()
|
||||
var/max_skillchip_slots = 5
|
||||
|
||||
/// Size modifier for the sprite
|
||||
var/brain_size = 1
|
||||
|
||||
/obj/item/organ/internal/brain/Initialize(mapload)
|
||||
. = ..()
|
||||
// Brain size logic
|
||||
transform = transform.Scale(brain_size)
|
||||
|
||||
/obj/item/organ/internal/brain/examine()
|
||||
. = ..()
|
||||
if(brain_size < 1)
|
||||
. += span_notice("It is a bit on the smaller side...")
|
||||
if(brain_size > 1)
|
||||
. += span_notice("It is bigger than average...")
|
||||
|
||||
/obj/item/organ/internal/brain/Insert(mob/living/carbon/brain_owner, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
@@ -406,6 +421,9 @@
|
||||
. = ..()
|
||||
organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
/obj/item/organ/internal/brain/felinid //A bit smaller than average
|
||||
brain_size = 0.8
|
||||
|
||||
////////////////////////////////////TRAUMAS////////////////////////////////////////
|
||||
|
||||
/obj/item/organ/internal/brain/proc/has_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
var/obj/item/bodypart/the_part = isbodypart(target_zone) ? target_zone : get_bodypart(check_zone(target_zone)) //keep these synced
|
||||
// Loop through the clothing covering this bodypart and see if there's any thiccmaterials
|
||||
if(!(injection_flags & INJECT_CHECK_PENETRATE_THICK))
|
||||
for(var/obj/item/clothing/iter_clothing in clothingonpart(the_part))
|
||||
for(var/obj/item/clothing/iter_clothing in get_clothing_on_part(the_part))
|
||||
if(iter_clothing.clothing_flags & THICKMATERIAL)
|
||||
. = FALSE
|
||||
break
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
if(isbodypart(def_zone))
|
||||
var/obj/item/bodypart/bp = def_zone
|
||||
if(bp)
|
||||
return checkarmor(def_zone, type)
|
||||
return check_armor(def_zone, type)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(check_zone(def_zone))
|
||||
if(affecting)
|
||||
return checkarmor(affecting, type)
|
||||
return check_armor(affecting, type)
|
||||
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
|
||||
|
||||
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
armorval += checkarmor(BP, type)
|
||||
armorval += check_armor(BP, type)
|
||||
organnum++
|
||||
return (armorval/max(organnum, 1))
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, damage_type)
|
||||
/mob/living/carbon/human/proc/check_armor(obj/item/bodypart/def_zone, damage_type)
|
||||
if(!damage_type)
|
||||
return 0
|
||||
var/protection = 100
|
||||
@@ -32,7 +32,7 @@
|
||||
return 100 - protection
|
||||
|
||||
///Get all the clothing on a specific body part
|
||||
/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone)
|
||||
/mob/living/carbon/human/proc/get_clothing_on_part(obj/item/bodypart/def_zone)
|
||||
var/list/covering_part = list()
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
for(var/bp in body_parts)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
name = "\improper Tall Boy"
|
||||
id = SPECIES_TALLBOY
|
||||
examine_limb_id = SPECIES_HUMAN
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK
|
||||
bodypart_overrides = list(
|
||||
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left,
|
||||
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right,
|
||||
@@ -13,8 +14,10 @@
|
||||
)
|
||||
|
||||
/datum/species/monkey/human_legged
|
||||
name = "human-legged monkey"
|
||||
id = SPECIES_MONKEY_HUMAN_LEGGED
|
||||
examine_limb_id = SPECIES_MONKEY
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK
|
||||
bodypart_overrides = list(
|
||||
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/monkey,
|
||||
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/monkey,
|
||||
@@ -25,8 +28,10 @@
|
||||
)
|
||||
|
||||
/datum/species/monkey/monkey_freak
|
||||
name = "human-armed monkey"
|
||||
id = SPECIES_MONKEY_FREAK
|
||||
examine_limb_id = SPECIES_MONKEY
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK
|
||||
bodypart_overrides = list(
|
||||
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left,
|
||||
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
id = SPECIES_FELINE
|
||||
examine_limb_id = SPECIES_HUMAN
|
||||
mutant_bodyparts = list("ears" = "Cat", "wings" = "None")
|
||||
mutantbrain = /obj/item/organ/internal/brain/felinid
|
||||
mutanttongue = /obj/item/organ/internal/tongue/cat
|
||||
/* SKYRAT EDIT REMOVAL - CUSTOMIZATION
|
||||
mutantears = /obj/item/organ/internal/ears/cat
|
||||
@@ -23,8 +24,6 @@
|
||||
family_heirlooms = list(/obj/item/toy/cattoy)
|
||||
/// When false, this is a felinid created by mass-purrbation
|
||||
var/original_felinid = TRUE
|
||||
/// Brain size for scaling
|
||||
var/brain_size = 0.8
|
||||
|
||||
// Prevents felinids from taking toxin damage from carpotoxin
|
||||
/datum/species/human/felinid/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired)
|
||||
@@ -47,16 +46,6 @@
|
||||
ears.Insert(target_human, drop_if_replaced = FALSE)
|
||||
else
|
||||
mutantears = /obj/item/organ/internal/ears
|
||||
var/obj/item/organ/internal/brain/current_brain = target_human.get_organ_by_type(/obj/item/organ/internal/brain)
|
||||
if(current_brain)
|
||||
current_brain.transform = current_brain.transform.Scale(brain_size) //smaller brain
|
||||
return ..()
|
||||
|
||||
/datum/species/human/felinid/on_species_loss(mob/living/carbon/former_feline, datum/species/old_species, pref_load)
|
||||
if(iscarbon(former_feline))
|
||||
var/obj/item/organ/internal/brain/current_brain = former_feline.get_organ_by_type(/obj/item/organ/internal/brain)
|
||||
if(current_brain)
|
||||
current_brain.transform = current_brain.transform.Scale(1 / brain_size) //bigger brain
|
||||
return ..()
|
||||
|
||||
/datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob)
|
||||
|
||||
@@ -394,13 +394,29 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
|
||||
tts_message_to_use = message_raw
|
||||
|
||||
var/list/filter = list()
|
||||
var/list/special_filter = list()
|
||||
var/voice_to_use = voice
|
||||
var/use_radio = FALSE
|
||||
if(length(voice_filter) > 0)
|
||||
filter += voice_filter
|
||||
|
||||
if(length(tts_filter) > 0)
|
||||
filter += tts_filter.Join(",")
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/human_speaker = src
|
||||
if(human_speaker.wear_mask)
|
||||
var/obj/item/clothing/mask/worn_mask = human_speaker.wear_mask
|
||||
if(worn_mask.voice_override)
|
||||
voice_to_use = worn_mask.voice_override
|
||||
if(worn_mask.voice_filter)
|
||||
filter += worn_mask.voice_filter
|
||||
use_radio = worn_mask.use_radio_beeps_tts
|
||||
if(use_radio)
|
||||
special_filter += TTS_FILTER_RADIO
|
||||
if(issilicon(src))
|
||||
special_filter += TTS_FILTER_SILICON
|
||||
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice, filter.Join(","), listened, message_range = message_range, pitch = pitch, silicon = tts_silicon_voice_effect)
|
||||
INVOKE_ASYNC(SStts, TYPE_PROC_REF(/datum/controller/subsystem/tts, queue_tts_message), src, html_decode(tts_message_to_use), message_language, voice_to_use, filter.Join(","), listened, message_range = message_range, pitch = pitch, special_filters = special_filter.Join("|"))
|
||||
|
||||
var/image/say_popup = image('icons/mob/effects/talk.dmi', src, "[bubble_type][talk_icon_state]", FLY_LAYER)
|
||||
SET_PLANE_EXPLICIT(say_popup, ABOVE_GAME_PLANE, src)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
lighting_cutoff_red = 30
|
||||
lighting_cutoff_green = 15
|
||||
lighting_cutoff_blue = 50
|
||||
unique_name = 1
|
||||
unique_name = TRUE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
death_sound = 'sound/voice/hiss6.ogg'
|
||||
death_message = "lets out a waning guttural screech, green blood bubbling from its maw..."
|
||||
@@ -91,7 +91,7 @@
|
||||
projectiletype = /obj/projectile/neurotoxin/damaging
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
status_flags = 0
|
||||
unique_name = 0
|
||||
unique_name = FALSE
|
||||
var/sterile = 1
|
||||
var/plants_off = 0
|
||||
var/egg_cooldown = 30
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
maxbodytemp = INFINITY
|
||||
faction = list(FACTION_CULT)
|
||||
pressure_resistance = 100
|
||||
unique_name = 1
|
||||
unique_name = TRUE
|
||||
AIStatus = AI_OFF //normal constructs don't have AI
|
||||
loot = list(/obj/item/ectoplasm)
|
||||
del_on_death = TRUE
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/effect/mob_spawn/ghost_role/drone/name_mob(mob/living/spawned_mob, forced_name)
|
||||
if(!forced_name)
|
||||
var/designation = pick(GLOB.posibrain_names)
|
||||
forced_name = "Drone ([designation]-[rand(100, 999)])"
|
||||
|
||||
return ..()
|
||||
@@ -45,6 +45,7 @@
|
||||
current_record["rank"] = person.rank
|
||||
current_record["species"] = person.species
|
||||
current_record["wanted"] = person.wanted_status
|
||||
current_record["voice"] = person.voice
|
||||
|
||||
all_records += list(current_record)
|
||||
if("medical")
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
// quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/human_wearer = owner
|
||||
var/list/clothing = human_wearer.clothingonpart(src)
|
||||
var/list/clothing = human_wearer.get_clothing_on_part(src)
|
||||
for(var/obj/item/clothing/clothes_check as anything in clothing)
|
||||
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
|
||||
if(clothes_check.get_armor_rating(WOUND))
|
||||
@@ -242,7 +242,7 @@
|
||||
|
||||
if(owner && ishuman(owner))
|
||||
var/mob/living/carbon/human/human_owner = owner
|
||||
var/list/clothing = human_owner.clothingonpart(src)
|
||||
var/list/clothing = human_owner.get_clothing_on_part(src)
|
||||
for(var/obj/item/clothing/clothes as anything in clothing)
|
||||
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
|
||||
armor_ablation += clothes.get_armor_rating(WOUND)
|
||||
|
||||
+6
-7
@@ -82,14 +82,13 @@
|
||||
return
|
||||
|
||||
if(bodypart_overlay.imprint_on_next_insertion) //We only want this set *once*
|
||||
|
||||
// SKYRAT EDIT - Customization - ORIGINAL: bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key])
|
||||
if(receiver.dna.features[bodypart_overlay.feature_key])
|
||||
bodypart_overlay.set_appearance_from_name(receiver.dna.features[bodypart_overlay.feature_key])
|
||||
|
||||
var/feature_name = receiver.dna.features[bodypart_overlay.feature_key]
|
||||
if (isnull(feature_name))
|
||||
bodypart_overlay.set_appearance_from_dna(receiver.dna) // SKYRAT EDIT CHANGE - ORIGINAL: feature_name = receiver.dna.species.external_organs[type]
|
||||
// SKYRAT EDIT CHANGE START - Puts the following line in an else block
|
||||
else
|
||||
bodypart_overlay.set_appearance_from_dna(receiver.dna)
|
||||
// SKYRAT EDIT END
|
||||
bodypart_overlay.set_appearance_from_name(feature_name)
|
||||
// SKYRAT EDIT CHANGE END
|
||||
bodypart_overlay.imprint_on_next_insertion = FALSE
|
||||
|
||||
ownerlimb = limb
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
languages_native = list(/datum/language/draconic, /datum/language/ashtongue) //SKYRAT EDIT: Ashtongue for Ashwalkers
|
||||
liked_foodtypes = GORE | MEAT | SEAFOOD | NUTS | BUGS
|
||||
disliked_foodtypes = GRAIN | DAIRY | CLOTH | GROSS
|
||||
|
||||
voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.9,aresample=%SAMPLE_RATE%,atempo=1/0.9,aformat=channel_layouts=mono,volume=0.2 [p0]; [out2] asetrate=%SAMPLE_RATE%*1.1,aresample=%SAMPLE_RATE%,atempo=1/1.1,aformat=channel_layouts=mono,volume=0.2[p2]; [p0][0][p2] amix=inputs=3"}
|
||||
/obj/item/organ/internal/tongue/lizard/modify_speech(datum/source, list/speech_args)
|
||||
var/static/regex/lizard_hiss = new("s+", "g")
|
||||
var/static/regex/lizard_hiSS = new("S+", "g")
|
||||
@@ -493,7 +493,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
say_mod = "hisses"
|
||||
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
|
||||
modifies_speech = TRUE // not really, they just hiss
|
||||
|
||||
voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.8,aresample=%SAMPLE_RATE%,atempo=1/0.8,aformat=channel_layouts=mono [p0]; [out2] asetrate=%SAMPLE_RATE%*1.2,aresample=%SAMPLE_RATE%,atempo=1/1.2,aformat=channel_layouts=mono[p2]; [p0][0][p2] amix=inputs=3"}
|
||||
// Aliens can only speak alien and a few other languages.
|
||||
/obj/item/organ/internal/tongue/alien/get_possible_languages()
|
||||
return list(
|
||||
@@ -601,6 +601,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
toxic_foodtypes = NONE //no food is particularly toxic to ethereals
|
||||
attack_verb_continuous = list("shocks", "jolts", "zaps")
|
||||
attack_verb_simple = list("shock", "jolt", "zap")
|
||||
voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.99,aresample=%SAMPLE_RATE%,volume=0.3 [p0]; [p0][out2] amix=inputs=2"}
|
||||
|
||||
// Ethereal tongues can speak all default + voltaic
|
||||
/obj/item/organ/internal/tongue/ethereal/get_possible_languages()
|
||||
|
||||
@@ -11,20 +11,24 @@
|
||||
bare_wound_bonus = 15
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/user, proximity_flag)
|
||||
/obj/item/mutant_hand/zombie/afterattack(atom/target, mob/living/user, proximity_flag)
|
||||
. = ..()
|
||||
if(!proximity_flag)
|
||||
return
|
||||
else if(isliving(target))
|
||||
if(ishuman(target))
|
||||
try_to_zombie_infect(target)
|
||||
try_to_zombie_infect(target, user, user.zone_selected)
|
||||
else
|
||||
. |= AFTERATTACK_PROCESSED_ITEM
|
||||
check_feast(target, user)
|
||||
|
||||
/proc/try_to_zombie_infect(mob/living/carbon/human/target)
|
||||
/proc/try_to_zombie_infect(mob/living/carbon/human/target, mob/living/user, def_zone = BODY_ZONE_CHEST)
|
||||
CHECK_DNA_AND_SPECIES(target)
|
||||
|
||||
// Can't zombify with no head
|
||||
if(!target.get_bodypart(BODY_ZONE_HEAD))
|
||||
return
|
||||
|
||||
if(HAS_TRAIT(target, TRAIT_NO_ZOMBIFY))
|
||||
// cannot infect any TRAIT_NO_ZOMBIFY human
|
||||
return
|
||||
@@ -33,11 +37,31 @@
|
||||
if(HAS_TRAIT(target, TRAIT_VIRUS_RESISTANCE) && prob(75))
|
||||
return
|
||||
|
||||
var/obj/item/bodypart/actual_limb = target.get_bodypart(def_zone)
|
||||
|
||||
// What you hitting bro?
|
||||
if(!actual_limb)
|
||||
return
|
||||
|
||||
var/limb_damage = actual_limb.get_damage()
|
||||
var/limb_armor = max(0, target.getarmor(actual_limb, BIO) - 25)
|
||||
|
||||
// This is a pretty jank way to do this, but in short:
|
||||
// if they have thick material on that bodypart it will always need at least 25 previous limb damage to trigger an infection.
|
||||
// and if their bio armor isn't thick it's a bit weaker.
|
||||
for(var/obj/item/clothing/iter_clothing in target.get_clothing_on_part(actual_limb))
|
||||
if(iter_clothing.clothing_flags & THICKMATERIAL)
|
||||
limb_armor += 25
|
||||
|
||||
if(limb_armor > limb_damage)
|
||||
return
|
||||
|
||||
var/obj/item/organ/internal/zombie_infection/infection
|
||||
infection = target.get_organ_slot(ORGAN_SLOT_ZOMBIE)
|
||||
if(!infection)
|
||||
infection = new()
|
||||
infection.Insert(target)
|
||||
to_chat(user, span_alien("You see [target] twitch for a moment as [target.p_their()] head is covered in \a [infection] - [target.p_Theyve()] been infected."))
|
||||
|
||||
/obj/item/mutant_hand/zombie/suicide_act(mob/living/user)
|
||||
user.visible_message(span_suicide("[user] is ripping [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "sqnztb"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "New medicine to clear up scars, made from synthflesh, ethanol, and miner's salve. Be sure to apply it via patches!"
|
||||
@@ -1,11 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- qol: "NT CIMs shows how much power the supermatter is releasing."
|
||||
- qol: "NT CIMs internal energy will adjust its prefix."
|
||||
- qol: "Energy displays (such as multitooling grid) will use the full range of SI prefixes available, up to the peta prefix if you somehow managed to reach that."
|
||||
- rscdel: "Removes the per cubic centimeter part of internal energy."
|
||||
- bugfix: "Fix unnecessary delta time scaling on inactive supermatters."
|
||||
- bugfix: "Fix high energy zaps not scaling with delta time."
|
||||
- bugfix: "Fixes grounding rods lying about potential power you can generate."
|
||||
- code_imp: "Convert supermatter_zap() and tesla_zap() zap_str argument unit to be in joules, and scales everything that uses that argument."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- admin: "First time user connections are now logged"
|
||||
@@ -1,5 +0,0 @@
|
||||
author: "LT3"
|
||||
delete-after: True
|
||||
changes:
|
||||
- admin: "Successful restart votes will now restart on the current map"
|
||||
- code_imp: "End round and persistence data will be saved before executing successful restart vote"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- image: "the security records suspected status is now teal instead of orange"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Centcom now rejects contraband that somehow makes it way onto the cargo shuttle mid-transit and returns it."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Rhials"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "\"Spooky\" meteors will now properly spawn during halloween."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- image: "adds a frog holoform for pAIs"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "LT3"
|
||||
delete-after: True
|
||||
changes:
|
||||
- spellcheck: "Improved wording in greyscale JSON error message"
|
||||
@@ -1,5 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Intellicards in computers are no longer deleted when the computer is destroyed."
|
||||
- bugfix: "Modular consoles can now be deconstructed by right clicking with a wrench."
|
||||
@@ -1,5 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds an advanced plastic surgery procedure, allowing you to imitate people in pictures. Simply hold a picture in your offhand of the person you wish to imitate as while conducting the surgery! Remember, it's not foolproof, it only changes your name and voice!"
|
||||
- rscadd: "You can obtain the disk containing the afromentioned surgery. as a role-restricted item to doctors and roboticists for 1TC, as a rare maint loot and BEPIS technode reward"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Metalgen can no longer be used to transmute indestructible turfs."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "posibrains can be inserted again"
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Selecting \"Monkey\" on a magic mirror will now once again turn you into a Monkey rather than a disgusting freak of nature."
|
||||
- bugfix: "Tall Boys have once again been barred from joining the Wizard Federation."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "cigarettes no longer smoke themselves from inside your pockets or on your hands."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "you can no longer push watchers (and any other lavaland basic mob) around by running into them"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "The custom error message for when there is only one map to vote for should pop up in all cases rather than just a select few."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Stun immune people should no longer have issues with gripper gloves and other tackle gloves."
|
||||
@@ -0,0 +1,5 @@
|
||||
author: "tattle"
|
||||
delete-after: True
|
||||
changes:
|
||||
- qol: "Basic animals now make sounds for audible emotes"
|
||||
- sound: "Added new sound effects for chicks, chickens, crabs, and insects"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixed job configs not being loaded properly."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Vekter"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Added a holodeck to Birdshot Station. It can be reached via the Crew Facilities hallway."
|
||||
@@ -0,0 +1,6 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscdel: "removes surgical duffelbags"
|
||||
- bugfix: "the surgery supply order now comes with a surgery tray"
|
||||
- bugfix: "(skyrat) Hospital gowns will now spawn in surgery trays like they used to in the surgery duffelbags"
|
||||
@@ -0,0 +1,7 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- qol: "Gas masks now muffle your voice with TTS."
|
||||
- qol: "Security Hailer masks now disguise your voice to protect your right to brutalize greytiders."
|
||||
- qol: "Lizards, Ethereals, and Xenomorphs now have a vocal effect."
|
||||
- qol: "Security Records now show someone's voice name."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "Tattle"
|
||||
delete-after: True
|
||||
changes:
|
||||
- qol: "drones now have individual names, instead of just \"drone\""
|
||||
@@ -0,0 +1,6 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "You can no longer break the game by AI rolling in a card or APC"
|
||||
- qol: "AI Roll now doesnt require you to click the exact turf to move you"
|
||||
- qol: "AI roll cooldown and roll time is now a variable, making it possible for AIs to become terrifying catamari damacy balls"
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "The flight potion wings will no longer fail to work on lavaland/icemoon on rare occasions."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixes full advanced surgery trays spawning with 'nothing'"
|
||||
@@ -0,0 +1,8 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixed zombies being able to infect headless corpses (Including former zombies)"
|
||||
- bugfix: "Fixed bio armor being totally useless against zombies. Now it checks how hurt your limb is: If it's more than the bio armor value, you get infected. THICKMATERIAL clothing guarantees at least 25 damage required to infect you, non-thick clothing reduces effective defence by 25. In practice this means people with MODsuits, biosuits will resist infection unless they're pummeled into crit, and wearing a firesuit will save you from the first few slashes."
|
||||
- bugfix: "Fixed the bomb hood armor not having the same bio armor value as bomb armor."
|
||||
- qol: "Added a message to the zed when they succesfully infect someone."
|
||||
- code_imp: "Turned some proc names into snake_case rather than, uh, nospacecase."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- spellcheck: "Tweaks the message that players get when not being able to qualify for roundstart antag to be more accurate as to what's happening."
|
||||
@@ -0,0 +1,4 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "fixed geysers spawning on turfs with plants"
|
||||
@@ -0,0 +1,11 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "you can now deconstruct exodrone scanner arrays"
|
||||
- bugfix: "the tree in space exodrone adventure no longer softlocks you"
|
||||
- qol: "the exodrone launchers now tell you on examine how to remove their fuel canister if you somehow needed to do that"
|
||||
- balance: "exodrone wide scans are now capped at 10 minutes"
|
||||
- balance: "exodrone travel times are 18% faster"
|
||||
- balance: "you can now upgrade scanner arrays for faster wide scan"
|
||||
- balance: "exodrone point scan and deep scan are faster"
|
||||
- spellcheck: "fixes several typos related to exodrones and gives scanner control console a description"
|
||||
@@ -0,0 +1,7 @@
|
||||
author: "SkyratBot"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Seeds will no longer be removed from existence after receiving the \"You can't seem to add [seed type] to the seed extractor\" message"
|
||||
- bugfix: "Some seeds that were previously not able to be added to the seed extractor may now be added (starthistle for example)"
|
||||
- bugfix: "fixes replica pod seeds spawning humans in nullspace"
|
||||
- qol: "right clicking the seed extractor with a plant/food stores the extracted seeds in the machine."
|
||||
@@ -1005,3 +1005,61 @@
|
||||
instead of a random one.
|
||||
honkpocket:
|
||||
- rscdel: Removed wall-mushroom outbreak event
|
||||
2023-09-26:
|
||||
LT3:
|
||||
- spellcheck: Improved wording in greyscale JSON error message
|
||||
- admin: Successful restart votes will now restart on the current map
|
||||
- code_imp: End round and persistence data will be saved before executing successful
|
||||
restart vote
|
||||
Rhials:
|
||||
- bugfix: '"Spooky" meteors will now properly spawn during halloween.'
|
||||
SkyratBot:
|
||||
- image: the security records suspected status is now teal instead of orange
|
||||
- bugfix: Intellicards in computers are no longer deleted when the computer is destroyed.
|
||||
- bugfix: Modular consoles can now be deconstructed by right clicking with a wrench.
|
||||
- bugfix: cigarettes no longer smoke themselves from inside your pockets or on your
|
||||
hands.
|
||||
- admin: First time user connections are now logged
|
||||
- qol: NT CIMs shows how much power the supermatter is releasing.
|
||||
- qol: NT CIMs internal energy will adjust its prefix.
|
||||
- qol: Energy displays (such as multitooling grid) will use the full range of SI
|
||||
prefixes available, up to the peta prefix if you somehow managed to reach that.
|
||||
- rscdel: Removes the per cubic centimeter part of internal energy.
|
||||
- bugfix: Fix unnecessary delta time scaling on inactive supermatters.
|
||||
- bugfix: Fix high energy zaps not scaling with delta time.
|
||||
- bugfix: Fixes grounding rods lying about potential power you can generate.
|
||||
- code_imp: Convert supermatter_zap() and tesla_zap() zap_str argument unit to be
|
||||
in joules, and scales everything that uses that argument.
|
||||
- rscadd: Adds an advanced plastic surgery procedure, allowing you to imitate people
|
||||
in pictures. Simply hold a picture in your offhand of the person you wish to
|
||||
imitate as while conducting the surgery! Remember, it's not foolproof, it only
|
||||
changes your name and voice!
|
||||
- rscadd: You can obtain the disk containing the afromentioned surgery. as a role-restricted
|
||||
item to doctors and roboticists for 1TC, as a rare maint loot and BEPIS technode
|
||||
reward
|
||||
- bugfix: Centcom now rejects contraband that somehow makes it way onto the cargo
|
||||
shuttle mid-transit and returns it.
|
||||
- bugfix: you can no longer push watchers (and any other lavaland basic mob) around
|
||||
by running into them
|
||||
- bugfix: posibrains can be inserted again
|
||||
- bugfix: Metalgen can no longer be used to transmute indestructible turfs.
|
||||
- image: adds a frog holoform for pAIs
|
||||
- bugfix: The custom error message for when there is only one map to vote for should
|
||||
pop up in all cases rather than just a select few.
|
||||
- bugfix: Stun immune people should no longer have issues with gripper gloves and
|
||||
other tackle gloves.
|
||||
sqnztb:
|
||||
- rscadd: New medicine to clear up scars, made from synthflesh, ethanol, and miner's
|
||||
salve. Be sure to apply it via patches!
|
||||
2023-09-27:
|
||||
SkyratBot:
|
||||
- rscadd: added ranged attack friendly fire checks for basic mobs. minebots and
|
||||
hivebots will now try to avoid shooting their friends
|
||||
- bugfix: fixed Strong Stone ruin generation
|
||||
- rscadd: Added a candle box crate for all your candle needs!
|
||||
- bugfix: '[Tramstation] Mass Driver in chapel now has tiny fan so you don''t space
|
||||
yourself.'
|
||||
jjpark-kb:
|
||||
- bugfix: actually fixed the ash revival ritual for basic mobs
|
||||
- bugfix: basic animals now will have their health affected positively and negatively
|
||||
by medicine and toxins respectively.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.4 KiB |
@@ -373,5 +373,5 @@
|
||||
|
||||
find_animal.faction = list(FACTION_ASHWALKER)
|
||||
|
||||
find_animal.revive()
|
||||
find_animal.revive(HEAL_ALL)
|
||||
return TRUE
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
cost = PAYCHECK_COMMAND
|
||||
|
||||
/datum/armament_entry/company_import/deforest/equipment/surgical_tools
|
||||
item_type = /obj/item/storage/backpack/duffelbag/med/surgery
|
||||
item_type = /obj/item/surgery_tray/full
|
||||
cost = PAYCHECK_COMMAND
|
||||
|
||||
/datum/armament_entry/company_import/deforest/equipment/advanced_health_analyer
|
||||
|
||||
@@ -467,7 +467,7 @@
|
||||
gender = FEMALE
|
||||
attack_verb_continuous = list("pats", "hugs", "scolds", "pets")
|
||||
attack_verb_simple = list("pat", "hug", "scold", "pet")
|
||||
squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
|
||||
squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
|
||||
responses = list("Rabbits are prey animals and are therefore constantly aware of their surroundings.", "Things to jump up on (they like to be in high places)", "become a rabbit today!", "Be cunning and full of tricks...", "Subscription confirmed! Thank you for choosing RABBITFACTS +TM+!", "Holland Lops are a breed of rabbit originating in the Netherlands.", "Rabbits may need medication to keep themselves healthy, and that's ok! Make sure to take yours too!", "rabbits really liked this product", "A healthy rabbit diet includes fresh vegetables.", "Rabbits do not hibernate. Their schedules are much too busy.", "the rate of bunnies is measured by RPB (rabbits per bunny)", )
|
||||
|
||||
/obj/item/toy/plush/skyrat/chunko/andrew
|
||||
@@ -477,7 +477,7 @@
|
||||
gender = MALE
|
||||
attack_verb_continuous = list("pats", "hugs", "scolds", "pets")
|
||||
attack_verb_simple = list("pat", "hug", "scold", "pet")
|
||||
squeak_override = list('sound/effects/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
|
||||
squeak_override = list('sound/creatures/mousesqueek.ogg' = 1, 'modular_skyrat/modules/emotes/sound/voice/mothsqueak.ogg' = 1,)
|
||||
// All lowercase messages are intentional
|
||||
responses = list("bunny who you best pray you never encounter, lest you suffer a fate worse than death.", "this is a bunny!", "I wonder what would happen if you took bunnies, and combined them with rabbits, and merged their properties and characteristics. It's something to think about.", "If you're cold, they're cold. Give them the deed to your house.", "bunny that goes yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah! woo! yeah!", "the bunnies are beyond my comprehension", "it's a bunny thing, you wouldn't get it", "this bunny has an unfathomable power level", "%pull the string and I'll bink at you...I'm your bunny.", "Bunny (1954)", "the bunny that pulls the strings....", )
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
message = "squeaks!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
vary = TRUE
|
||||
sound = 'sound/effects/mousesqueek.ogg'
|
||||
sound = 'sound/creatures/mousesqueek.ogg'
|
||||
|
||||
/datum/emote/living/merp
|
||||
key = "merp"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
back = /obj/item/storage/backpack
|
||||
id = /obj/item/card/id/faction_crew
|
||||
l_pocket = /obj/item/melee/energy/sword
|
||||
l_hand = /obj/item/storage/backpack/duffelbag/med/surgery
|
||||
l_hand = /obj/item/surgery_tray/full
|
||||
backpack_contents = list(/obj/item/storage/box/survival/engineer=1, /obj/item/storage/medkit/tactical=1,/obj/item/storage/medkit/regular=1,/obj/item/storage/medkit/toxin=1, /obj/item/ammo_box/magazine/m45=2, /obj/item/gun/ballistic/automatic/pistol/m1911=1,/obj/item/healthanalyzer=1,/obj/item/stack/spacecash/c1000=1)
|
||||
|
||||
/datum/outfit/faction_tech
|
||||
|
||||
@@ -15,14 +15,57 @@
|
||||
|
||||
/mob/living/simple_animal/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
if(reagent_health && reagents)
|
||||
for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
|
||||
if(istype(reagents_within, /datum/reagent/toxin))
|
||||
var/datum/reagent/toxin/toxin_reagent = reagents_within
|
||||
var/toxin_damage = round(toxin_reagent.toxpwr)
|
||||
adjustHealth(toxin_damage + 1)
|
||||
reagents.remove_reagent(toxin_reagent.type, 0.5)
|
||||
continue
|
||||
if(istype(reagents_within, /datum/reagent/medicine))
|
||||
adjustHealth(-1)
|
||||
reagents.remove_reagent(reagents_within.type, 0.5)
|
||||
|
||||
if(!reagent_health)
|
||||
return
|
||||
|
||||
if(!reagents)
|
||||
return
|
||||
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
|
||||
if(istype(reagents_within, /datum/reagent/toxin))
|
||||
var/datum/reagent/toxin/toxin_reagent = reagents_within
|
||||
var/toxin_damage = round(toxin_reagent.toxpwr)
|
||||
adjustHealth(toxin_damage + 1)
|
||||
reagents.remove_reagent(toxin_reagent.type, 0.5)
|
||||
continue
|
||||
|
||||
if(istype(reagents_within, /datum/reagent/medicine))
|
||||
adjustHealth(-1)
|
||||
reagents.remove_reagent(reagents_within.type, 0.5)
|
||||
|
||||
/mob/living/basic
|
||||
/// whether the simple animal can be healed/damaged through reagents
|
||||
var/reagent_health = TRUE
|
||||
|
||||
/mob/living/basic/Initialize(mapload)
|
||||
. = ..()
|
||||
if(reagent_health)
|
||||
create_reagents(1000, REAGENT_HOLDER_ALIVE)
|
||||
|
||||
/mob/living/basic/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
|
||||
if(!reagent_health)
|
||||
return
|
||||
|
||||
if(!reagents)
|
||||
return
|
||||
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
for(var/datum/reagent/reagents_within as anything in reagents.reagent_list)
|
||||
if(istype(reagents_within, /datum/reagent/toxin))
|
||||
var/datum/reagent/toxin/toxin_reagent = reagents_within
|
||||
var/toxin_damage = round(toxin_reagent.toxpwr)
|
||||
adjust_health(toxin_damage + 1)
|
||||
reagents.remove_reagent(toxin_reagent.type, 0.5)
|
||||
continue
|
||||
|
||||
if(istype(reagents_within, /datum/reagent/medicine))
|
||||
adjust_health(-1)
|
||||
reagents.remove_reagent(reagents_within.type, 0.5)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user