Merge branch 'master' into various-misc

This commit is contained in:
DragonTrance
2021-05-01 10:31:15 -07:00
committed by GitHub
124 changed files with 9704 additions and 443 deletions
+1
View File
@@ -72,6 +72,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
/client/proc/panicbunker,
/client/proc/addbunkerbypass,
/client/proc/discordmessage,
/client/proc/revokebunkerbypass,
/client/proc/stop_sounds,
/client/proc/debugstatpanel,
+4 -1
View File
@@ -37,7 +37,10 @@
H.dna.features["moth_wings"] = pick(GLOB.moth_wings_list)
H.dna.features["moth_fluff"] = pick(GLOB.moth_fluffs_list)
H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
H.dna.features["flavor_text"] = "" //Oh no.
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
H.update_body()
H.update_hair()
H.update_body_parts()
H.update_body_parts()
@@ -72,6 +72,7 @@ GLOBAL_LIST_EMPTY(antagonists)
give_antag_moodies()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
@@ -134,6 +134,9 @@
else
to_chat(user, status())
/obj/machinery/meter/attack_ghost(mob/user)
to_chat(user, status())
/obj/machinery/meter/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
@@ -141,6 +144,7 @@
// TURF METER - REPORTS A TILE'S AIR CONTENTS
// why are you yelling?
// i hope they aren't mad
/obj/machinery/meter/turf
/obj/machinery/meter/turf/reattach_to_layer()
@@ -377,6 +377,17 @@
air_update_turf() // Update the environment if needed.
update_icon()
/obj/machinery/portable_atmospherics/canister/attack_ghost(mob/user)
if(user.client)
if(IsAdminGhost(user))
attack_ai(user)
return FALSE
else if(user.client.prefs.inquisitive_ghost)
user.examinate(src)
return FALSE
atmosanalyzer_scan(air_contents, user, src, FALSE)
return FALSE
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+18
View File
@@ -181,6 +181,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"ipc_screen" = "Sunburst",
"ipc_antenna" = "None",
"flavor_text" = "",
"silicon_flavor_text" = "",
"ooc_text" = ""
)
@@ -395,6 +396,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "[features["flavor_text"]]"
else
dat += "[TextPreview(features["flavor_text"])]...<BR>"
dat += "<h2>Silicon Flavor Text</h2>"
dat += "<a href='?_src_=prefs;preference=silicon_flavor_text;task=input'><b>Set Silicon Examine Text</b></a><br>"
if(length(features["silicon_flavor_text"]) <= 40)
if(!length(features["silicon_flavor_text"]))
dat += "\[...\]"
else
dat += "[features["silicon_flavor_text"]]"
else
dat += "[TextPreview(features["silicon_flavor_text"])]...<BR>"
dat += "<h2>OOC Text</h2>"
dat += "<a href='?_src_=prefs;preference=ooc_text;task=input'><b>Set OOC Text</b></a><br>"
if(length(features["ooc_text"]) <= 40)
@@ -1747,6 +1757,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
msg = msg
features["flavor_text"] = msg
if("silicon_flavor_text")
var/msg = stripped_multiline_input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", features["silicon_flavor_text"], MAX_FLAVOR_LEN, TRUE)
if(msg)
msg = msg
features["silicon_flavor_text"] = msg
if("ooc_text")
var/msg = stripped_multiline_input(usr, "Set the OOC text in your 'examine' verb. This should be OOC only!", "OOC Text", html_decode(features["ooc_text"]), MAX_MESSAGE_LEN, TRUE)
if(msg)
@@ -2790,6 +2806,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
character.Digitigrade_Leg_Swap(TRUE)
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
//speech stuff
if(custom_tongue != "default")
var/new_tongue = GLOB.roundstart_tongues[custom_tongue]
@@ -436,6 +436,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
else //We have no old flavortext, default to new
S["feature_flavor_text"] >> features["flavor_text"]
S["feature_silicon_flavor_text"] >> features["silicon_flavor_text"]
if((S["ooc_text"] != "") && (S["ooc_text"] != null) && S["ooc_text"])
S["ooc_text"] >> features["ooc_text"]
@@ -513,6 +514,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
@@ -796,6 +796,7 @@
item_color = "greenplaidshirt"
body_parts_covered = CHEST|GROIN|ARMS|LEGS
can_adjust = FALSE
fitted = NO_FEMALE_UNIFORM
//yes
//Enzo_Leon patron stuff
+1
View File
@@ -4,6 +4,7 @@
max_occurrences = 1
weight = 4
earliest_start = 5 MINUTES
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event_control/aurora_caelus/canSpawnEvent(players, gamemode)
if(!CONFIG_GET(flag/starlight))
+1
View File
@@ -5,6 +5,7 @@
min_players = 5 //increased min players from 2 to 5 to reduce chances of half the crew dying in a carp breach
earliest_start = 10 MINUTES
max_occurrences = 6
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event/carp_migration
announceWhen = 3
+1
View File
@@ -3,6 +3,7 @@
typepath = /datum/round_event/meteor_wave/meaty
weight = 2
max_occurrences = 1
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event/meteor_wave/meaty
wave_name = "meaty"
+1
View File
@@ -10,6 +10,7 @@
min_players = 20
max_occurrences = 3
earliest_start = 25 MINUTES
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event/meteor_wave
startWhen = 6
+1 -1
View File
@@ -14,7 +14,7 @@
return ..()
/datum/round_event/pirates
startWhen = 60 //2 minutes to answer
startWhen = 300 //5 minutes to answer
var/datum/comm_message/threat
var/payoff = 0
var/paid_off = FALSE
+2 -1
View File
@@ -3,6 +3,7 @@
typepath = /datum/round_event/grey_tide
max_occurrences = 2
min_players = 5
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event/grey_tide
announceWhen = 50
@@ -67,4 +68,4 @@
temp.prison_open()
else if(istype(O, /obj/machinery/door_timer))
var/obj/machinery/door_timer/temp = O
temp.timer_end(forced = TRUE)
temp.timer_end(forced = TRUE)
+1
View File
@@ -4,6 +4,7 @@
max_occurrences = 3
weight = 2
min_players = 2
map_blacklist = list("LayeniaStation.dmm")
/datum/round_event/wormholes
@@ -23,7 +23,7 @@
/obj/machinery/gibber/RefreshParts()
var/gib_time = 40
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
meat_produced += B.rating
meat_produced += 1.6 * B.rating
for(var/obj/item/stock_parts/manipulator/M in component_parts)
gib_time -= 5 * M.rating
gibtime = gib_time
@@ -1,6 +1,8 @@
GLOBAL_LIST_EMPTY(monkey_recyclers)
/obj/machinery/monkey_recycler
name = "monkey recycler"
desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces 1 cube for every 5 monkeys inserted." // except it literally never does
desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces 0.2 cubes for every monkey inserted."
icon = 'icons/obj/kitchen.dmi'
icon_state = "grinder"
layer = BELOW_OBJ_LAYER
@@ -9,20 +11,29 @@
idle_power_usage = 5
active_power_usage = 50
circuit = /obj/item/circuitboard/machine/monkey_recycler
var/grinded = 0
var/required_grind = 5
var/cube_production = 1
var/stored_matter = 0
var/cube_production = 0.2
var/list/connected = list() //Xenobio consoles
/obj/machinery/monkey_recycler/Initialize(mapload)
. = ..()
GLOB.monkey_recyclers += src
/obj/machinery/monkey_recycler/RefreshParts()
var/req_grind = 5
var/cubes_made = 1
/obj/machinery/monkey_recycler/Destroy()
if(src in GLOB.monkey_recyclers)
GLOB.monkey_recyclers -= src
for(var/obj/machinery/computer/camera_advanced/xenobio/C in connected)
var/obj/machinery/computer/camera_advanced/xenobio/console = C
console.connected_recycler = null
return ..()
/obj/machinery/monkey_recycler/RefreshParts() //Ranges from 0.2 to 0.8 per monkey recycled
cube_production = 0
for(var/obj/item/stock_parts/manipulator/B in component_parts)
req_grind -= B.rating
cube_production += B.rating * 0.1
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
cubes_made = M.rating
cube_production = cubes_made
required_grind = req_grind
src.desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted."
cube_production += M.rating * 0.1
desc = "A machine used for recycling dead monkeys into monkey cubes. You can use a multitool to link it to a xenobiology console. It currently produces [cube_production] cubes for every monkey inserted."
/obj/machinery/monkey_recycler/attackby(obj/item/O, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O))
@@ -64,17 +75,23 @@
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking
use_power(500)
grinded++
stored_matter += cube_production
addtimer(VARSET_CALLBACK(src, pixel_x, initial(pixel_x)))
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "<span class='notice'>The machine now has [grinded] monkey\s worth of material stored.</span>"))
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, user, "<span class='notice'>The machine now has [stored_matter] monkey\s worth of material stored.</span>"))
/obj/machinery/monkey_recycler/interact(mob/user)
if(grinded >= required_grind)
to_chat(user, "<span class='notice'>The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube.</span>")
if(stored_matter >= 1)
to_chat(user, "<span class='notice'>The machine hisses loudly as it condenses the ground monkey meat. After a moment, it dispenses a brand new monkey cube.</span>")
playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1)
grinded -= required_grind
for(var/i = 0, i < cube_production, i++)
new /obj/item/reagent_containers/food/snacks/monkeycube(src.loc)
to_chat(user, "<span class='notice'>The machine's display flashes that it has [grinded] monkeys worth of material left.</span>")
for(var/i in 1 to max(stored_matter, 1))
new /obj/item/reagent_containers/food/snacks/monkeycube(loc)
stored_matter--
to_chat(user, "<span class='notice'>The machine's display flashes that it has [stored_matter] monkeys worth of material left.</span>")
else
to_chat(user, "<span class='danger'>The machine needs at least [required_grind] monkey(s) worth of material to produce a monkey cube. It only has [grinded].</span>")
to_chat(user, "<span class='danger'>The machine needs at least 1 monkey worth of material to produce a monkey cube. It currently has [stored_matter].</span>")
/obj/machinery/monkey_recycler/multitool_act(mob/living/user, obj/item/multitool/I)
if(istype(I))
to_chat(user, "<span class='notice'>You log [src] in the multitool's buffer.</span>")
I.buffer = src
return TRUE
+1 -1
View File
@@ -368,7 +368,7 @@
C.reagents.add_reagent(/datum/reagent/fermi/eigenstate, 30)
if(5)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"A new familiar for me, and you'll see it's thee!\"</span>")
C.reagents.add_reagent("secretcatchem", 30)
C.reagents.add_reagent(/datum/reagent/fermi/secretcatchem, 30)
if(6)
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"While you may not be a ghost, for this sheet you'll always be it's host.\"</span>")
var/mob/living/carbon/human/H = C
+2 -1
View File
@@ -18,7 +18,7 @@ Clown
minimal_access = list(ACCESS_THEATRE)
/datum/job/clown/after_spawn(mob/living/carbon/human/H, mob/M)
. = ..()
..()
H.apply_pref_name("clown", M.client)
/datum/outfit/job/clown
@@ -83,6 +83,7 @@ Mime
minimal_access = list(ACCESS_THEATRE)
/datum/job/mime/after_spawn(mob/living/carbon/human/H, mob/M)
..()
H.apply_pref_name("mime", M.client)
/datum/outfit/job/mime
+1 -1
View File
@@ -66,7 +66,7 @@
//Only override this proc
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
//do actions on H but send messages to M as the key may not have been transferred_yet
//do actions on H but send messages to M as the key may not have been transferred yet
if(mind_traits)
for(var/t in mind_traits)
ADD_TRAIT(H.mind, t, JOB_TRAIT)
+1 -1
View File
@@ -21,7 +21,7 @@ AI
. = H.AIize(latejoin)
/datum/job/ai/after_spawn(mob/H, mob/M, latejoin)
. = ..()
..()
if(latejoin)
var/obj/structure/AIcore/latejoin_inactive/lateJoinCore
for(var/obj/structure/AIcore/latejoin_inactive/P in GLOB.latejoin_ai_cores)
@@ -64,6 +64,14 @@
name = "asteroid snow baseturf editor"
baseturf = /turf/open/floor/plating/asteroid/snow
/obj/effect/baseturf_helper/asteroid/layenia
name = "layenia baseturf editor"
baseturf = /turf/open/floor/plating/asteroid/layenia
/obj/effect/baseturf_helper/cloud
name = "cloud baseturf editor"
baseturf = /turf/open/chasm/cloud
/obj/effect/baseturf_helper/beach/sand
name = "beach sand baseturf editor"
baseturf = /turf/open/floor/plating/beach/sand
@@ -597,7 +597,7 @@
if (H.custom_body_size) //Do they have it set?
H.resize(H.custom_body_size * 0.01)
if (H.breedable == TRUE)
H.impregchance = 30
H.impregchance = 25
. = H
new_character = .
if(transfer_after)
@@ -17,3 +17,8 @@
name = "Round + Light"
icon_state = "roundlight"
/datum/sprite_accessory/snouts/gator
name = "Gator"
icon_state = "gator"
color_src = MATRIXED
+8 -2
View File
@@ -11,14 +11,20 @@
toggle_combat_mode(TRUE, TRUE)
. = ..()
for(var/T in get_traumas())
var/datum/brain_trauma/BT = T
BT.on_death()
if(SSticker.mode)
SSticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
//watching someone die is traumatic
for(var/mob/living/carbon/human/H in oview(5, src))
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "death", /datum/mood_event/deathsaw)
if(prob(10)) //10% chance to pump adrenaline into their body
H.jitteriness += 5
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
var/atom/Tsec = drop_location()
for(var/mob/M in src)
@@ -8,7 +8,6 @@
var/t_is = p_are()
var/obscure_name
var/dispSize = round(12*size_multiplier) // gets the character's sprite size percent and converts it to the nearest half foot
var/output = ""
if(isliving(user))
var/mob/living/L = user
@@ -24,25 +23,13 @@
if (vassDesc != "")
. += vassDesc
output = "<center>"
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if(ishuman(src)) //user just returned, y'know, the user's own species. dumb.
var/mob/living/carbon/human/H = src
if(gender)
output += "[icon2html('hyperstation/icons/chat/gender.dmi', world, gender)]"
output += "<b>[src.name]</b>"
var/datum/species/pref_species = H.dna.species
if(get_visible_name() == "Unknown") // same as flavor text, but hey it works.
. += "You can't make out what species they are."
else if(skipface)
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!"
output += "([H.dna.custom_species ? H.dna.custom_species : pref_species.name])"
output += "</center>"
if(skipface || get_visible_name() == "Unknown")
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
//uniform
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
@@ -416,30 +403,9 @@
else if(isobserver(user) && traitstring)
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
if(print_flavor_text())
output += "<br><b>General</b>"
if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
. += "...?"
output += "<br>...?"
else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
. += "...?"
output += "<br>...?"
else
. += "[print_flavor_text()]"
output += "<br>[url_encode(flavor_text)]"
if(ooc_text)
output += "<br><br><i><b>OOC</b>"
output += "<br>[url_encode(ooc_text)]"
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, msg)
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
. += "*---------*</span>"
//stat panel
if(ishuman(src))
user.client << output(output, "statbrowser:update_examine") //open the examine window
user.client << output(null, "statbrowser:create_mobexamine") //open the examine window
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
var/list/dat = list()
if(!pronoun_replacement)
@@ -37,6 +37,8 @@
if(!CONFIG_GET(flag/disable_human_mood))
AddComponent(/datum/component/mood)
AddElement(/datum/element/mob_holder/micro, "micro")
AddElement(/datum/element/flavor_text/carbon, "", "Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "flavor_text")
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
/mob/living/carbon/human/Destroy()
QDEL_NULL(physiology)
+1 -1
View File
@@ -58,7 +58,7 @@
//H13 custom body size and impregnation
var/custom_body_size = 100
var/breedable = 0
var/impregchance = 0
var/impregchance = 30
//h13 noncon settings
var/Noncon = 0
var/ERP = 0
@@ -437,11 +437,11 @@
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
CD.reagents.add_reagent(/datum/reagent/drying_agent, 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
CL.reagents.add_reagent(/datum/reagent/lube, 2 * coeff)
/obj/item/robot_module/clown
name = "Clown"
@@ -55,6 +55,11 @@
diag_hud_set_status()
diag_hud_set_health()
/mob/living/silicon/ComponentInitialize()
. = ..()
AddElement(/datum/element/flavor_text, "", "Silicon Flavor Text", "", MAX_FLAVOR_LEN, FALSE, TRUE, "silicon_flavor_text")
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
/mob/living/silicon/med_hud_set_health()
return //we use a different hud
@@ -316,9 +316,9 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
to_chat(H, "<span class='userdanger'>WHAT THE FUCK IS THAT?!</span>")
to_chat(H, "<i>.KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH</i>")
H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25)
H.reagents.add_reagent("mindbreaker", 3)
H.reagents.add_reagent("laughter", 5)
H.reagents.add_reagent("mercury", 3)
H.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 3)
H.reagents.add_reagent(/datum/reagent/consumable/laughter, 5)
H.reagents.add_reagent(/datum/reagent/mercury, 3)
Appear()
manifested = FALSE
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2)
-7
View File
@@ -525,13 +525,6 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
unset_machine()
src << browse(null, t1)
if(href_list["flavor_more"])
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text, "\n", "<BR>")), text("window=[];size=500x200", name))
onclose(usr, "[name]")
if(href_list["flavor_change"])
update_flavor_text()
if(href_list["refresh"])
if(machine && in_range(src, usr))
show_inv(machine)
-2
View File
@@ -129,9 +129,7 @@
///Whether the mob is updating glide size when movespeed updates or not
var/updating_glide_size = TRUE
var/flavor_text = ""
var/ooc_text = ""
var/flavor_text_2 = "" //version of the above that only lasts for the current round.
///////TYPING INDICATORS///////
/// Set to true if we want to show typing indicators.
-25
View File
@@ -2,31 +2,6 @@
////////////////////SUBTLE COMMAND////////////////////
//////////////////////////////////////////////////////
/mob/proc/update_flavor_text()
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. IC only!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
if(msg)
flavor_text = html_encode(msg)
flavor_text = msg
/mob/proc/warn_flavor_changed()
if(flavor_text && flavor_text != "") // don't spam people that don't use it!
to_chat(src, "<h2 class='alert'>OOC Warning:</h2>")
to_chat(src, "<span class='alert'>Your flavor text is likely out of date! <a href='?src=[REF(src)];flavor_change=1'>Change</a></span>")
/mob/proc/print_flavor_text()
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
/mob/proc/get_top_level_mob()
if(istype(src.loc,/mob)&&src.loc!=src)
var/mob/M=src.loc
+1 -1
View File
@@ -171,7 +171,7 @@
/turf/open/pool/attackby(obj/item/W, mob/living/user)
if(istype(W, /obj/item/mop) && filled)
W.reagents.add_reagent("water", 5)
W.reagents.add_reagent(/datum/reagent/water, 5)
to_chat(user, "<span class='notice'>You wet [W] in [src].</span>")
playsound(src, 'sound/effects/slosh.ogg', 25, TRUE)
else
+2 -2
View File
@@ -18,8 +18,8 @@
var/grumping = 0 // is the engine currently doing grumpy things
var/list/grump_prefix = list("an upsetting", "an unsettling",
"a scary", "a loud", "a sassy", "a grouchy", "a grumpy",
"an awful", "a horrible", "a despicable", "a pretty rad", "a godawful")
var/list/grump_suffix = list("noise", "racket", "ruckus", "sound", "clatter", "fracas", "hubbub")
"an awful", "a horrible", "a despicable", "a pretty rad", "a godawful, a wocky")
var/list/grump_suffix = list("noise", "racket", "ruckus", "sound", "clatter", "fracas", "hubbub, slush")
var/sound_engine1 = 'sound/machines/tractor_running.ogg'
var/sound_engine2 = 'sound/machines/engine_highpower.ogg'
var/sound_tractorrev = 'sound/machines/tractorrev.ogg'
@@ -337,70 +337,6 @@
construction_time = 600
category = list("Durand")
//H.O.N.K
/datum/design/honk_chassis
name = "Exosuit Chassis (\"H.O.N.K\")"
id = "honk_chassis"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/chassis/honker
materials = list(MAT_METAL=20000)
construction_time = 100
category = list("H.O.N.K")
/datum/design/honk_torso
name = "Exosuit Torso (\"H.O.N.K\")"
id = "honk_torso"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_torso
materials = list(MAT_METAL=20000,MAT_GLASS=10000,MAT_BANANIUM=10000)
construction_time = 300
category = list("H.O.N.K")
/datum/design/honk_head
name = "Exosuit Head (\"H.O.N.K\")"
id = "honk_head"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_head
materials = list(MAT_METAL=10000,MAT_GLASS=5000,MAT_BANANIUM=5000)
construction_time = 200
category = list("H.O.N.K")
/datum/design/honk_left_arm
name = "Exosuit Left Arm (\"H.O.N.K\")"
id = "honk_left_arm"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_left_arm
materials = list(MAT_METAL=15000,MAT_BANANIUM=5000)
construction_time = 200
category = list("H.O.N.K")
/datum/design/honk_right_arm
name = "Exosuit Right Arm (\"H.O.N.K\")"
id = "honk_right_arm"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_right_arm
materials = list(MAT_METAL=15000,MAT_BANANIUM=5000)
construction_time = 200
category = list("H.O.N.K")
/datum/design/honk_left_leg
name = "Exosuit Left Leg (\"H.O.N.K\")"
id = "honk_left_leg"
build_type = MECHFAB
build_path =/obj/item/mecha_parts/part/honker_left_leg
materials = list(MAT_METAL=20000,MAT_BANANIUM=5000)
construction_time = 200
category = list("H.O.N.K")
/datum/design/honk_right_leg
name = "Exosuit Right Leg (\"H.O.N.K\")"
id = "honk_right_leg"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_right_leg
materials = list(MAT_METAL=20000,MAT_BANANIUM=5000)
construction_time = 200
category = list("H.O.N.K")
//Phazon
/datum/design/phazon_chassis
@@ -464,16 +464,6 @@
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000)
export_price = 5000
/////////////////////////Clown tech/////////////////////////
/datum/techweb_node/clown
id = "clown"
display_name = "Clown Technology"
description = "Honk?!"
prereq_ids = list("base")
design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm",
"honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone", "borg_transform_clown")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
////////////////////////Computer tech////////////////////////
/datum/techweb_node/comptech
@@ -1,6 +1,6 @@
//Xenobio control console
/mob/camera/aiEye/remote/xenobio
visible_icon = 1
visible_icon = TRUE
icon = 'icons/obj/abductor.dmi'
icon_state = "camera_target"
var/allowed_area = null
@@ -22,15 +22,11 @@
desc = "A computer used for remotely handling slimes."
networks = list("ss13")
circuit = /obj/item/circuitboard/computer/xenobiology
var/datum/action/innate/slime_place/slime_place_action
var/datum/action/innate/slime_pick_up/slime_up_action
var/datum/action/innate/feed_slime/feed_slime_action
var/datum/action/innate/monkey_recycle/monkey_recycle_action
var/datum/action/innate/slime_scan/scan_action
var/datum/action/innate/feed_potion/potion_action
var/datum/action/innate/hotkey_help/hotkey_help
var/datum/component/redirect/listener
var/obj/machinery/monkey_recycler/connected_recycler
var/list/stored_slimes
var/obj/item/slimepotion/slime/current_potion
var/max_slimes = 5
@@ -43,14 +39,13 @@
/obj/machinery/computer/camera_advanced/xenobio/Initialize()
. = ..()
slime_place_action = new
slime_up_action = new
feed_slime_action = new
monkey_recycle_action = new
scan_action = new
potion_action = new
hotkey_help = new
stored_slimes = list()
listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del)))
for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers)
if(get_area(src) == get_area(recycler))
connected_recycler = recycler
connected_recycler.connected += src
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
stored_slimes = null
@@ -61,45 +56,56 @@
S.forceMove(drop_location())
return ..()
/obj/machinery/computer/camera_advanced/xenobio/examine(mob/user)
. = ..()
var/thing = "It has "
if((upgradetier & XENOBIO_UPGRADE_SLIMEADV))
thing += "an advanced slime upgrade disk "
if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
thing += "and a monkey upgrade disk "
else if((upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
thing += "a basic slime upgrade disk "
if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
thing += "and a monkey upgrade disk "
else if((upgradetier & XENOBIO_UPGRADE_MONKEYS))
thing += "a monkey upgrade disk "
else
thing += "no upgrades installed."
. += thing
return
thing += "installed."
. += thing
/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src))
eyeobj.origin = src
eyeobj.visible_icon = 1
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/obj/abductor.dmi'
eyeobj.icon_state = "camera_target"
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
..()
if(slime_up_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_up_action.target = src
slime_up_action.Grant(user)
actions += slime_up_action
if(hotkey_help)
hotkey_help.target = src
hotkey_help.Grant(user)
actions += hotkey_help
if(slime_place_action && (upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
slime_place_action.target = src
slime_place_action.Grant(user)
actions += slime_place_action
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl)
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt)
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift)
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift)
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl)
RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl)
if(feed_slime_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
feed_slime_action.target = src
feed_slime_action.Grant(user)
actions += feed_slime_action
if(monkey_recycle_action && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkey_recycle_action.target = src
monkey_recycle_action.Grant(user)
actions += monkey_recycle_action
if(scan_action)
scan_action.target = src
scan_action.Grant(user)
actions += scan_action
if(potion_action && (upgradetier & XENOBIO_UPGRADE_SLIMEADV)) // CIT CHANGE - makes giving slimes potions via console require XENOBIO_UPGRADE_SLIMEADV
potion_action.target = src
potion_action.Grant(user)
actions += potion_action
/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user)
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL)
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT)
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT)
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT)
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL)
UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL)
..()
/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted)
if(current_potion == deleted)
@@ -134,135 +140,161 @@
current_potion = O
to_chat(user, "<span class='notice'>You load [O] in the console's potion slot[replaced ? ", replacing the one that was there before" : ""].</span>")
return
else if(istype(O, /obj/item/multitool))
var/obj/item/multitool/M = O
if(istype(M.buffer))
to_chat(user, "<span class='notice'>You link [src] with [M.buffer] in [M] buffer.</span>")
connected_recycler = M.buffer
connected_recycler += src
return
else
to_chat(user, "<span class='warning'>[M] has no buffer.</span>")
return
..()
/datum/action/innate/slime_place
name = "Place Slimes"
/datum/action/innate/hotkey_help
name = "Hotkey Help"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "slime_down"
button_icon_state = "hotkey_help"
/datum/action/innate/slime_place/Activate()
/datum/action/innate/hotkey_help/Activate()
if(!target || !isliving(owner))
return
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
to_chat(owner, "<b>Click shortcuts:</b>")
to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes.")
to_chat(owner, "Ctrl-click a slime to scan it.")
to_chat(owner, "Alt-click a slime to feed it a potion.")
to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey.")
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
S.forceMove(remote_eye.loc)
//
// Alternate clicks for slime, monkey and open turf if using a xenobio console
//Picks up slime
/mob/living/simple_animal/slime/ShiftClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src)
..()
//Place slimes
/turf/open/ShiftClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src)
..()
//Place monkey
/turf/open/CtrlClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src)
..()
//Pick up monkey
/mob/living/carbon/monkey/CtrlClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src)
..()
// Scans slime
/mob/living/simple_animal/slime/CtrlClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src)
..()
//Feeds a potion to slime
/mob/living/simple_animal/slime/AltClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src)
..()
//Picks up slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S)
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
return
if(!GLOB.cameranet.checkTurfVis(S.loc))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/area/mobarea = get_area(S.loc)
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
if(stored_slimes.len >= max_slimes)
to_chat(user, "<span class='warning'>Slime storage is full.</span>")
return
if(S.ckey)
to_chat(user, "<span class='warning'>The slime wiggled free!</span>")
return
if(S.buckled)
S.Feedstop(silent = TRUE)
S.visible_message("[S] vanishes in a flash of light!")
S.forceMove(src)
stored_slimes += S
//Place slimes
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T)
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
return
if(!GLOB.cameranet.checkTurfVis(T))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/area/turfarea = get_area(T)
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible)
for(var/mob/living/simple_animal/slime/S in stored_slimes)
S.forceMove(T)
S.visible_message("[S] warps in!")
X.stored_slimes -= S
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
stored_slimes -= S
/datum/action/innate/slime_pick_up
name = "Pick up Slime"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "slime_up"
/datum/action/innate/slime_pick_up/Activate()
if(!target || !isliving(owner))
//Place monkey
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T)
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS))
return
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
if(X.stored_slimes.len >= X.max_slimes)
break
if(!S.ckey)
if(S.buckled)
S.Feedstop(silent = TRUE)
S.visible_message("[S] vanishes in a flash of light!")
S.forceMove(X)
X.stored_slimes += S
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
/datum/action/innate/feed_slime
name = "Feed Slimes"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "monkey_down"
/datum/action/innate/feed_slime/Activate()
if(!target || !isliving(owner))
if(!GLOB.cameranet.checkTurfVis(T))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
var/area/turfarea = get_area(T)
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(turfarea.name == X.allowed_area || turfarea.xenobiology_compatible)
if(monkeys >= 1)
var/mob/living/carbon/monkey/food = new/mob/living/carbon/monkey(T, TRUE, user)
if(!QDELETED(food))
food.LAssailant = user
monkeys = round(monkeys-1, 0.1)
to_chat(user, "[src] now has [monkeys] monkeys stored.")
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
if(X.monkeys >= 1)
var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(remote_eye.loc, TRUE, owner)
if (!QDELETED(food))
food.LAssailant = C
X.monkeys --
to_chat(owner, "[X] now has [X.monkeys] monkeys left.")
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
/datum/action/innate/monkey_recycle
name = "Recycle Monkeys"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "monkey_up"
/datum/action/innate/monkey_recycle/Activate()
if(!target || !isliving(owner))
//Pick up monkey
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M)
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS))
return
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
for(var/mob/living/carbon/monkey/M in remote_eye.loc)
if(M.stat)
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
X.monkeys = round(X.monkeys + 0.2,0.1)
qdel(M)
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
/datum/action/innate/slime_scan
name = "Scan Slime"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "slime_scan"
/datum/action/innate/slime_scan/Activate()
if(!target || !isliving(owner))
if(!connected_recycler)
to_chat(user, "<span class='notice'>There is no connected monkey recycler. You can connect one with a multitool.</span>")
return
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
slime_scan(S, C)
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
/datum/action/innate/feed_potion
name = "Apply Potion"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
button_icon_state = "slime_potion"
/datum/action/innate/feed_potion/Activate()
if(!target || !isliving(owner))
if(!GLOB.cameranet.checkTurfVis(M.loc))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/area/mobarea = get_area(M.loc)
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
if(!M.stat)
return
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
connected_recycler.use_power(500)
monkeys += connected_recycler.cube_production
to_chat(user, "[src] now has [monkeys] monkeys available.")
qdel(M)
var/mob/living/C = owner
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(QDELETED(X.current_potion))
to_chat(owner, "<span class='notice'>No potion loaded.</span>")
// Scans slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S)
if(!GLOB.cameranet.checkTurfVis(S.loc))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/area/mobarea = get_area(S.loc)
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
slime_scan(S, user)
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
X.current_potion.attack(S, C)
break
else
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
//Feeds a potion to slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S)
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC))
return
if(!GLOB.cameranet.checkTurfVis(S.loc))
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
return
var/area/mobarea = get_area(S.loc)
if(QDELETED(current_potion))
to_chat(user, "<span class='warning'>No potion loaded.</span>")
return
var/mob/camera/aiEye/remote/xenobio/X = eyeobj
if(mobarea.name == X.allowed_area || mobarea.xenobiology_compatible)
current_potion.attack(S, user)