-
-
- E - Edit, tries to determine the variable type by itself.
- C - Change, asks you for the var type first.
- M - Mass modify: changes this variable for all objects of this type.
-
-
-
-
-
-
- Search:
-
-
-
-
-
-
-
-
-
- [variable_html.Join()]
-
-
-
-
-"}
- src << browse(html, "window=variables[refid];size=475x650")
-
-
-/client/proc/vv_update_display(datum/D, span, content)
- src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
-
-
-#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
-/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE)
- var/header
- if(DA)
- if (islist(DA))
- var/index = name
- if (value)
- name = DA[name] //name is really the index until this line
- else
- value = DA[name]
- header = "
+
+
+ E - Edit, tries to determine the variable type by itself.
+ C - Change, asks you for the var type first.
+ M - Mass modify: changes this variable for all objects of this type.
+
+
+
+
+
+
+ Search:
+
+
+
+
+
+
+
+
+
+ [variable_html.Join()]
+
+
+
+
+"}
+ src << browse(html, "window=variables[refid];size=475x650")
+
+/client/proc/vv_update_display(datum/D, span, content)
+ src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index 2c91e18bd8..b4f896fa08 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -414,11 +414,11 @@
if(safety)
to_chat(usr, "The safety is still on.")
return
+ if(!timing && nuclear_cooldown > world.time)
+ to_chat(usr, "[src]'s timer protocols are currently on cooldown, please stand by.")
+ return
timing = !timing
if(timing)
- if(nuclear_cooldown > world.time)
- to_chat(usr, "[src]'s timer protocols are currently on cooldown, please stand by.")
- return
previous_level = get_security_level()
detonation_timer = world.time + (timer_set * 10)
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm
index 19f7bff965..5c34ece723 100644
--- a/code/modules/atmospherics/gasmixtures/gas_types.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_types.dm
@@ -179,7 +179,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
/datum/gas/miasma
id = "miasma"
- specific_heat = 0.00001
+ specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
index 74181b05eb..42902bf7a7 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
@@ -12,7 +12,6 @@
item_state = "explorer_envirosuit"
item_color = "explorer_envirosuit"
-
/obj/item/clothing/under/plasmaman/chef
name = "chef's plasma envirosuit"
desc = "A white plasmaman envirosuit designed for cullinary practices. One might question why a member of a species that doesn't need to eat would become a chef."
@@ -69,6 +68,8 @@
item_state = "captain_envirosuit"
item_color = "captain_envirosuit"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ sensor_mode = SENSOR_COORDS
+ random_sensor = FALSE
/obj/item/clothing/under/plasmaman/mime
name = "mime envirosuit"
@@ -97,4 +98,4 @@
H.visible_message("[H]'s suit spews out a tonne of space lube!","Your suit spews out a tonne of space lube!")
H.ExtinguishMob()
new /obj/effect/particle_effect/foam(loc) //Truely terrifying.
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm
index ff756e09fd..6ef9eb9e53 100644
--- a/code/modules/clothing/under/jobs/Plasmaman/security.dm
+++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm
@@ -5,6 +5,8 @@
item_state = "security_envirosuit"
item_color = "security_envirosuit"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ sensor_mode = SENSOR_COORDS
+ random_sensor = FALSE
/obj/item/clothing/under/plasmaman/security/warden
name = "warden plasma envirosuit"
diff --git a/code/modules/clothing/under/jobs/civilian/curator.dm b/code/modules/clothing/under/jobs/civilian/curator.dm
index c02cc4b710..741407d71d 100644
--- a/code/modules/clothing/under/jobs/civilian/curator.dm
+++ b/code/modules/clothing/under/jobs/civilian/curator.dm
@@ -13,7 +13,6 @@
item_state = "red_suit"
item_color = "red_suit_skirt"
body_parts_covered = CHEST|GROIN|ARMS
- can_adjust = FALSE
fitted = FEMALE_UNIFORM_TOP
/obj/item/clothing/under/rank/civilian/curator/treasure_hunter
@@ -37,5 +36,4 @@
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
- can_adjust = FALSE
resistance_flags = NONE
diff --git a/code/modules/clothing/under/jobs/rnd.dm b/code/modules/clothing/under/jobs/rnd.dm
index 142cb8d8b1..5af6ce26bf 100644
--- a/code/modules/clothing/under/jobs/rnd.dm
+++ b/code/modules/clothing/under/jobs/rnd.dm
@@ -14,7 +14,6 @@
item_state = "lb_suit"
item_color = "director_skirt"
body_parts_covered = CHEST|GROIN|ARMS
- can_adjust = FALSE
fitted = FEMALE_UNIFORM_TOP
/obj/item/clothing/under/rank/rnd/research_director/alt
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index 21e088f634..e91125c152 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -8,6 +8,11 @@
/*
* Security
*/
+/obj/item/clothing/under/rank/security
+ strip_delay = 50
+ alt_covers_chest = TRUE
+ sensor_mode = SENSOR_COORDS
+ random_sensor = FALSE
/obj/item/clothing/under/rank/security/officer
name = "security jumpsuit"
@@ -16,10 +21,6 @@
item_state = "r_suit"
item_color = "rsecurity"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
- strip_delay = 50
- alt_covers_chest = TRUE
- sensor_mode = SENSOR_COORDS
- random_sensor = FALSE
/obj/item/clothing/under/rank/security/officer/grey
name = "grey security jumpsuit"
@@ -73,10 +74,6 @@
item_state = "r_suit"
item_color = "rwarden"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
- strip_delay = 50
- alt_covers_chest = TRUE
- sensor_mode = 3
- random_sensor = FALSE
/obj/item/clothing/under/rank/security/warden/grey
name = "grey security suit"
@@ -114,10 +111,6 @@
item_state = "det"
item_color = "detective"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
- strip_delay = 50
- alt_covers_chest = TRUE
- sensor_mode = 3
- random_sensor = FALSE
/obj/item/clothing/under/rank/security/detective/skirt
name = "detective's suitskirt"
@@ -135,7 +128,6 @@
icon_state = "greydet"
item_state = "greydet"
item_color = "greydet"
- alt_covers_chest = TRUE
/obj/item/clothing/under/rank/security/detective/grey/skirt
name = "noir suitskirt"
@@ -159,9 +151,6 @@
item_color = "rhos"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
strip_delay = 60
- alt_covers_chest = TRUE
- sensor_mode = 3
- random_sensor = FALSE
/obj/item/clothing/under/rank/security/head_of_security/skirt
name = "head of security's jumpskirt"
@@ -203,7 +192,6 @@
icon_state = "hosblueclothes"
item_state = "hosblueclothes"
item_color = "hosblueclothes"
- alt_covers_chest = TRUE
/obj/item/clothing/under/rank/security/head_of_security/parade
name = "head of security's parade uniform"
@@ -220,4 +208,3 @@
item_state = "r_suit"
item_color = "hos_parade_fem"
fitted = FEMALE_UNIFORM_TOP
- can_adjust = FALSE
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 9c9b131f48..3b8f8de359 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -393,17 +393,13 @@
/datum/spacevine_controller/vv_get_dropdown()
. = ..()
- . += "---"
- .["Delete Vines"] = "?_src_=[REF(src)];[HrefToken()];purge_vines=1"
+ VV_DROPDOWN_OPTION(VV_HK_SPACEVINE_PURGE, "Delete Vines")
-/datum/spacevine_controller/Topic(href, href_list)
- if(..() || !check_rights(R_ADMIN, FALSE) || !usr.client.holder.CheckAdminHref(href, href_list))
- return
-
- if(href_list["purge_vines"])
- if(alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", "Yes", "No") != "Yes")
- return
- DeleteVines()
+/datum/spacevine_controller/vv_do_topic(href_list)
+ . = ..()
+ if(href_list[VV_HK_SPACEVINE_PURGE])
+ if(alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", "Yes", "No") == "Yes")
+ DeleteVines()
/datum/spacevine_controller/proc/DeleteVines() //this is kill
QDEL_LIST(vines) //this will also qdel us
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index c212c22c98..f10229f4bf 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -87,14 +87,6 @@
return
. = ..()
-/obj/machinery/computer/shuttle/mining/common
- name = "lavaland shuttle console"
- desc = "Used to call and send the lavaland shuttle."
- req_access = list()
- circuit = /obj/item/circuitboard/computer/mining_shuttle/common
- shuttleId = "mining_common"
- possible_destinations = "lavaland_common_away;commonmining_home"
-
/**********************Mining car (Crate like thing, not the rail car)**************************/
/obj/structure/closet/crate/miningcar
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 3c5ef91c41..fc85fc25c4 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -984,14 +984,121 @@
/mob/living/carbon/vv_get_dropdown()
. = ..()
- . += "---"
- .["Make AI"] = "?_src_=vars;[HrefToken()];makeai=[REF(src)]"
- .["Modify bodypart"] = "?_src_=vars;[HrefToken()];editbodypart=[REF(src)]"
- .["Modify organs"] = "?_src_=vars;[HrefToken()];editorgans=[REF(src)]"
- .["Hallucinate"] = "?_src_=vars;[HrefToken()];hallucinate=[REF(src)]"
- .["Give martial arts"] = "?_src_=vars;[HrefToken()];givemartialart=[REF(src)]"
- .["Give brain trauma"] = "?_src_=vars;[HrefToken()];givetrauma=[REF(src)]"
- .["Cure brain traumas"] = "?_src_=vars;[HrefToken()];curetraumas=[REF(src)]"
+ VV_DROPDOWN_OPTION("", "---------")
+ VV_DROPDOWN_OPTION(VV_HK_MAKE_AI, "Make AI")
+ VV_DROPDOWN_OPTION(VV_HK_MODIFY_BODYPART, "Modify bodypart")
+ VV_DROPDOWN_OPTION(VV_HK_MODIFY_ORGANS, "Modify organs")
+ VV_DROPDOWN_OPTION(VV_HK_HALLUCINATION, "Hallucinate")
+ VV_DROPDOWN_OPTION(VV_HK_MARTIAL_ART, "Give Martial Arts")
+ VV_DROPDOWN_OPTION(VV_HK_GIVE_TRAUMA, "Give Brain Trauma")
+ VV_DROPDOWN_OPTION(VV_HK_CURE_TRAUMA, "Cure Brain Traumas")
+
+/mob/living/carbon/vv_do_topic(list/href_list)
+ . = ..()
+ if(href_list[VV_HK_MODIFY_BODYPART])
+ if(!check_rights(R_SPAWN))
+ return
+ var/edit_action = input(usr, "What would you like to do?","Modify Body Part") as null|anything in list("add","remove", "augment")
+ if(!edit_action)
+ return
+ var/list/limb_list = list()
+ if(edit_action == "remove" || edit_action == "augment")
+ for(var/obj/item/bodypart/B in bodyparts)
+ limb_list += B.body_zone
+ if(edit_action == "remove")
+ limb_list -= BODY_ZONE_CHEST
+ else
+ limb_list = list(BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ for(var/obj/item/bodypart/B in bodyparts)
+ limb_list -= B.body_zone
+ var/result = input(usr, "Please choose which body part to [edit_action]","[capitalize(edit_action)] Body Part") as null|anything in limb_list
+ if(result)
+ var/obj/item/bodypart/BP = get_bodypart(result)
+ switch(edit_action)
+ if("remove")
+ if(BP)
+ BP.drop_limb()
+ else
+ to_chat(usr, "[src] doesn't have such bodypart.")
+ if("add")
+ if(BP)
+ to_chat(usr, "[src] already has such bodypart.")
+ else
+ if(!regenerate_limb(result))
+ to_chat(usr, "[src] cannot have such bodypart.")
+ if("augment")
+ if(ishuman(src))
+ if(BP)
+ BP.change_bodypart_status(BODYPART_ROBOTIC, TRUE, TRUE)
+ else
+ to_chat(usr, "[src] doesn't have such bodypart.")
+ else
+ to_chat(usr, "Only humans can be augmented.")
+ admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [src]")
+ if(href_list[VV_HK_MAKE_AI])
+ if(!check_rights(R_SPAWN))
+ return
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
+ return
+ usr.client.holder.Topic("vv_override", list("makeai"=href_list[VV_HK_TARGET]))
+ if(href_list[VV_HK_MODIFY_ORGANS])
+ if(!check_rights(NONE))
+ return
+ usr.client.manipulate_organs(src)
+ if(href_list[VV_HK_MARTIAL_ART])
+ if(!check_rights(NONE))
+ return
+ var/list/artpaths = subtypesof(/datum/martial_art)
+ var/list/artnames = list()
+ for(var/i in artpaths)
+ var/datum/martial_art/M = i
+ artnames[initial(M.name)] = M
+ var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames
+ if(!usr)
+ return
+ if(QDELETED(src))
+ to_chat(usr, "Mob doesn't exist anymore")
+ return
+ if(result)
+ var/chosenart = artnames[result]
+ var/datum/martial_art/MA = new chosenart
+ MA.teach(src)
+ log_admin("[key_name(usr)] has taught [MA] to [key_name(src)].")
+ message_admins("[key_name_admin(usr)] has taught [MA] to [key_name_admin(src)].")
+ if(href_list[VV_HK_GIVE_TRAUMA])
+ if(!check_rights(NONE))
+ return
+ var/list/traumas = subtypesof(/datum/brain_trauma)
+ var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas
+ if(!usr)
+ return
+ if(QDELETED(src))
+ to_chat(usr, "Mob doesn't exist anymore")
+ return
+ if(!result)
+ return
+ var/datum/brain_trauma/BT = gain_trauma(result)
+ if(BT)
+ log_admin("[key_name(usr)] has traumatized [key_name(src)] with [BT.name]")
+ message_admins("[key_name_admin(usr)] has traumatized [key_name_admin(src)] with [BT.name].")
+ if(href_list[VV_HK_CURE_TRAUMA])
+ if(!check_rights(NONE))
+ return
+ cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE)
+ log_admin("[key_name(usr)] has cured all traumas from [key_name(src)].")
+ message_admins("[key_name_admin(usr)] has cured all traumas from [key_name_admin(src)].")
+ if(href_list[VV_HK_HALLUCINATION])
+ if(!check_rights(NONE))
+ return
+ var/list/hallucinations = subtypesof(/datum/hallucination)
+ var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations
+ if(!usr)
+ return
+ if(QDELETED(src))
+ to_chat(usr, "Mob doesn't exist anymore")
+ return
+ if(result)
+ new result(src, TRUE)
/mob/living/carbon/can_resist()
return bodyparts.len > 2 && ..()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a515693047..94aba6851a 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -849,15 +849,95 @@
/mob/living/carbon/human/vv_get_dropdown()
. = ..()
- . += "---"
- .["Make monkey"] = "?_src_=vars;[HrefToken()];makemonkey=[REF(src)]"
- .["Set Species"] = "?_src_=vars;[HrefToken()];setspecies=[REF(src)]"
- .["Make cyborg"] = "?_src_=vars;[HrefToken()];makerobot=[REF(src)]"
- .["Make alien"] = "?_src_=vars;[HrefToken()];makealien=[REF(src)]"
- .["Make slime"] = "?_src_=vars;[HrefToken()];makeslime=[REF(src)]"
- .["Toggle Purrbation"] = "?_src_=vars;[HrefToken()];purrbation=[REF(src)]"
- .["Copy outfit"] = "?_src_=vars;[HrefToken()];copyoutfit=[REF(src)]"
- .["Add/Remove Quirks"] = "?_src_=vars;[HrefToken()];modquirks=[REF(src)]"
+ VV_DROPDOWN_OPTION("", "---------")
+ VV_DROPDOWN_OPTION(VV_HK_COPY_OUTFIT, "Copy Outfit")
+ VV_DROPDOWN_OPTION(VV_HK_MOD_QUIRKS, "Add/Remove Quirks")
+ VV_DROPDOWN_OPTION(VV_HK_MAKE_MONKEY, "Make Monkey")
+ VV_DROPDOWN_OPTION(VV_HK_MAKE_CYBORG, "Make Cyborg")
+ VV_DROPDOWN_OPTION(VV_HK_MAKE_SLIME, "Make Slime")
+ VV_DROPDOWN_OPTION(VV_HK_MAKE_ALIEN, "Make Alien")
+ VV_DROPDOWN_OPTION(VV_HK_SET_SPECIES, "Set Species")
+ VV_DROPDOWN_OPTION(VV_HK_PURRBATION, "Toggle Purrbation")
+
+/mob/living/carbon/human/vv_do_topic(list/href_list)
+ . = ..()
+ if(href_list[VV_HK_COPY_OUTFIT])
+ if(!check_rights(R_SPAWN))
+ return
+ copy_outfit()
+ if(href_list[VV_HK_MOD_QUIRKS])
+ if(!check_rights(R_SPAWN))
+ return
+
+ var/list/options = list("Clear"="Clear")
+ for(var/x in subtypesof(/datum/quirk))
+ var/datum/quirk/T = x
+ var/qname = initial(T.name)
+ options[has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T
+
+ var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
+ if(result)
+ if(result == "Clear")
+ for(var/datum/quirk/q in roundstart_quirks)
+ remove_quirk(q.type)
+ else
+ var/T = options[result]
+ if(has_quirk(T))
+ remove_quirk(T)
+ else
+ add_quirk(T,TRUE)
+ if(href_list[VV_HK_MAKE_MONKEY])
+ if(!check_rights(R_SPAWN))
+ return
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
+ return
+ usr.client.holder.Topic("vv_override", list("monkeyone"=href_list[VV_HK_TARGET]))
+ if(href_list[VV_HK_MAKE_CYBORG])
+ if(!check_rights(R_SPAWN))
+ return
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
+ return
+ usr.client.holder.Topic("vv_override", list("makerobot"=href_list[VV_HK_TARGET]))
+ if(href_list[VV_HK_MAKE_ALIEN])
+ if(!check_rights(R_SPAWN))
+ return
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
+ return
+ usr.client.holder.Topic("vv_override", list("makealien"=href_list[VV_HK_TARGET]))
+ if(href_list[VV_HK_MAKE_SLIME])
+ if(!check_rights(R_SPAWN))
+ return
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
+ return
+ usr.client.holder.Topic("vv_override", list("makeslime"=href_list[VV_HK_TARGET]))
+ if(href_list[VV_HK_SET_SPECIES])
+ if(!check_rights(R_SPAWN))
+ return
+ var/result = input(usr, "Please choose a new species","Species") as null|anything in GLOB.species_list
+ if(result)
+ var/newtype = GLOB.species_list[result]
+ admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [src] to [result]")
+ set_species(newtype)
+ if(href_list[VV_HK_PURRBATION])
+ if(!check_rights(R_SPAWN))
+ return
+ if(!ishumanbasic(src))
+ to_chat(usr, "This can only be done to the basic human species at the moment.")
+ return
+ var/success = purrbation_toggle(src)
+ if(success)
+ to_chat(usr, "Put [src] on purrbation.")
+ log_admin("[key_name(usr)] has put [key_name(src)] on purrbation.")
+ var/msg = "[key_name_admin(usr)] has put [key_name(src)] on purrbation."
+ message_admins(msg)
+ admin_ticket_log(src, msg)
+
+ else
+ to_chat(usr, "Removed [src] from purrbation.")
+ log_admin("[key_name(usr)] has removed [key_name(src)] from purrbation.")
+ var/msg = "[key_name_admin(usr)] has removed [key_name(src)] from purrbation."
+ message_admins(msg)
+ admin_ticket_log(src, msg)
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
if(pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
index 5a9b830bc8..bb2c08aa9b 100644
--- a/code/modules/mob/living/carbon/human/species_types/dwarves.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
@@ -92,6 +92,8 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
//These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world.
var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds.
var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds
+ var/last_filth_spam
+ var/last_alcohol_spam
/obj/item/organ/dwarfgland/prepare_eat()
var/obj/S = ..()
@@ -136,40 +138,39 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral.
switch(filth_counter)
if(11 to 25)
- if(prob(25))
- to_chat(owner, "Someone should really clean up in here!")
+ if(last_filth_spam + 40 SECONDS < world.time)
+ to_chat(owner, "Someone should really clean up in here!")
+ last_filth_spam = world.time
if(26 to 50)
- if(prob(30)) //Probability the message appears
+ if(prob(6)) //And then the probability they vomit along with it.
to_chat(owner, "The stench makes you queasy.")
- if(prob(20)) //And then the probability they vomit along with it.
- owner.vomit(20) //I think vomit should stay over a disgust adjustment.
+ owner.vomit(10) //I think vomit should stay over a disgust adjustment.
if(51 to 75)
- if(prob(35))
+ if(prob(9))
to_chat(owner, "By Armok! You won't be able to keep alcohol down at all!")
- if(prob(25))
- owner.vomit(20) //Its more funny
+ owner.vomit(20) //Its more funny
if(76 to 100)
- if(prob(40))
+ if(prob(11))
to_chat(owner, "You can't live in such FILTH!")
- if(prob(25))
- owner.adjustToxLoss(10) //Now they start dying.
- owner.vomit(20)
+ owner.adjustToxLoss(10) //Now they start dying.
+ owner.vomit(20)
if(101 to INFINITY) //Now they will really start dying
- if(prob(40))
+ if(last_filth_spam + 12 SECONDS < world.time)
to_chat(owner, " THERES TOO MUCH FILTH, OH GODS THE FILTH!")
+ last_filth_spam = world.time
+ if(prob(40))
owner.adjustToxLoss(15)
- owner.vomit(40)
+ owner.vomit(30)
CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least)
//Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker.
/obj/item/organ/dwarfgland/proc/dwarf_eth_cycle()
//BOOZE POWER
+ var/init_stored_alcohol = stored_alcohol
for(var/datum/reagent/R in owner.reagents.reagent_list)
if(istype(R, /datum/reagent/consumable/ethanol))
var/datum/reagent/consumable/ethanol/E = R
- stored_alcohol += (E.boozepwr / 50)
- if(stored_alcohol > max_alcohol) //Dwarves technically start at 250 alcohol stored.
- stored_alcohol = max_alcohol
+ stored_alcohol = CLAMP(stored_alcohol + E.boozepwr / 50, 0, max_alcohol)
var/heal_amt = heal_rate
stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
if(stored_alcohol > 400) //If they are over 400 they start regenerating
@@ -177,16 +178,27 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
owner.adjustFireLoss(-heal_amt) //Unless they drink casually all the time.
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt) //Also they will probably get brain damage if thats a thing here.
- if(prob(25))
- switch(stored_alcohol)
- if(0 to 24)
+ if(init_stored_alcohol + 0.5 < stored_alcohol) //recovering stored alcohol at a steady rate of +0.75, no spam.
+ return
+ switch(stored_alcohol)
+ if(0 to 24)
+ if(last_alcohol_spam + 8 SECONDS < world.time)
to_chat(owner, "DAMNATION INCARNATE, WHY AM I CURSED WITH THIS DRY-SPELL? I MUST DRINK.")
- owner.adjustToxLoss(35)
- if(25 to 50)
+ last_alcohol_spam = world.time
+ owner.adjustToxLoss(10)
+ if(25 to 50)
+ if(last_alcohol_spam + 20 SECONDS < world.time)
to_chat(owner, "Oh DAMN, I need some brew!")
- if(51 to 75)
+ last_alcohol_spam = world.time
+ if(51 to 75)
+ if(last_alcohol_spam + 35 SECONDS < world.time)
to_chat(owner, "Your body aches, you need to get ahold of some booze...")
- if(76 to 100)
+ last_alcohol_spam = world.time
+ if(76 to 100)
+ if(last_alcohol_spam + 40 SECONDS < world.time)
to_chat(owner, "A pint of anything would really hit the spot right now.")
- if(101 to 150)
+ last_alcohol_spam = world.time
+ if(101 to 150)
+ if(last_alcohol_spam + 50 SECONDS < world.time)
to_chat(owner, "You feel like you could use a good brew.")
+ last_alcohol_spam = world.time
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index ebb5a3dd31..7c6d0e8cdc 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -377,9 +377,15 @@
var/turf/open/miasma_turf = deceasedturf
- var/list/cached_gases = miasma_turf.air.gases
+ var/datum/gas_mixture/stank = new
- cached_gases[/datum/gas/miasma] += 0.1
+ stank.gases[/datum/gas/miasma] = 0.1
+
+ stank.temperature = BODYTEMP_NORMAL
+
+ miasma_turf.assume_air(stank)
+
+ miasma_turf.air_update_turf()
/mob/living/carbon/proc/handle_blood()
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 4ef741745f..5fa64e5ab5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1198,3 +1198,19 @@
gender = ngender
return TRUE
return FALSE
+
+/mob/living/vv_get_header()
+ . = ..()
+ var/refid = REF(src)
+ . += {"
+ [VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[ckey || "no ckey"]", NAMEOF(src, ckey))] / [VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[real_name || "no real name"]", NAMEOF(src, real_name))]
+
+ BRUTE:[getBruteLoss()]
+ FIRE:[getFireLoss()]
+ TOXIN:[getToxLoss()]
+ OXY:[getOxyLoss()]
+ CLONE:[getCloneLoss()]
+ BRAIN:[getOrganLoss(ORGAN_SLOT_BRAIN)]
+ STAMINA:[getStaminaLoss()]
+
+ "}
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 27ecaf30d5..9980d2b830 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -193,17 +193,6 @@
if(user == anchored || !isturf(user.loc))
return FALSE
- //pacifist vore check.
- if(user.pulling && HAS_TRAIT(user, TRAIT_PACIFISM) && user.voremode) //they can only do heals, noisy guts, absorbing (technically not harm)
- if(ismob(user.pulling))
- var/mob/P = user.pulling
- if(src != user)
- to_chat(user, "You can't risk digestion!")
- return FALSE
- else
- user.vore_attack(user, P, user)
- return
-
//normal vore check.
if(user.pulling && user.grab_state == GRAB_AGGRESSIVE && user.voremode)
if(ismob(user.pulling))
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index b41ca15948..89d9919981 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -285,9 +285,10 @@
if("Miner")
mob_species = pickweight(list(/datum/species/human = 70, /datum/species/lizard = 26, /datum/species/fly = 2, /datum/species/plasmaman = 2))
if(mob_species == /datum/species/plasmaman)
- uniform = /obj/item/clothing/under/plasmaman
- head = /obj/item/clothing/head/helmet/space/plasmaman
+ uniform = /obj/item/clothing/under/plasmaman/mining
+ head = /obj/item/clothing/head/helmet/space/plasmaman/mining
belt = /obj/item/tank/internals/plasmaman/belt
+ mask = /obj/item/clothing/mask/gas/explorer
else
uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland
if (prob(4))
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 86c0aa253c..d03443cf61 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -946,18 +946,65 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/vv_get_dropdown()
. = ..()
- . += "---"
- .["Gib"] = "?_src_=vars;[HrefToken()];gib=[REF(src)]"
- .["Give Spell"] = "?_src_=vars;[HrefToken()];give_spell=[REF(src)]"
- .["Remove Spell"] = "?_src_=vars;[HrefToken()];remove_spell=[REF(src)]"
- .["Give Disease"] = "?_src_=vars;[HrefToken()];give_disease=[REF(src)]"
- .["Toggle Godmode"] = "?_src_=vars;[HrefToken()];godmode=[REF(src)]"
- .["Drop Everything"] = "?_src_=vars;[HrefToken()];drop_everything=[REF(src)]"
- .["Regenerate Icons"] = "?_src_=vars;[HrefToken()];regenerateicons=[REF(src)]"
- .["Show player panel"] = "?_src_=vars;[HrefToken()];mob_player_panel=[REF(src)]"
- .["Toggle Build Mode"] = "?_src_=vars;[HrefToken()];build_mode=[REF(src)]"
- .["Assume Direct Control"] = "?_src_=vars;[HrefToken()];direct_control=[REF(src)]"
- .["Offer Control to Ghosts"] = "?_src_=vars;[HrefToken()];offer_control=[REF(src)]"
+ VV_DROPDOWN_OPTION("", "---------")
+ VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib")
+ VV_DROPDOWN_OPTION(VV_HK_GIVE_SPELL, "Give Spell")
+ VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell")
+ VV_DROPDOWN_OPTION(VV_HK_GIVE_DISEASE, "Give Disease")
+ VV_DROPDOWN_OPTION(VV_HK_GODMODE, "Toggle Godmode")
+ VV_DROPDOWN_OPTION(VV_HK_DROP_ALL, "Drop Everything")
+ VV_DROPDOWN_OPTION(VV_HK_REGEN_ICONS, "Regenerate Icons")
+ VV_DROPDOWN_OPTION(VV_HK_PLAYER_PANEL, "Show player panel")
+ VV_DROPDOWN_OPTION(VV_HK_BUILDMODE, "Toggle Buildmode")
+ VV_DROPDOWN_OPTION(VV_HK_DIRECT_CONTROL, "Assume Direct Control")
+ VV_DROPDOWN_OPTION(VV_HK_OFFER_GHOSTS, "Offer Control to Ghosts")
+
+/mob/vv_do_topic(list/href_list)
+ . = ..()
+ if(href_list[VV_HK_REGEN_ICONS])
+ if(!check_rights(NONE))
+ return
+ regenerate_icons()
+ if(href_list[VV_HK_PLAYER_PANEL])
+ if(!check_rights(NONE))
+ return
+ usr.client.holder.show_player_panel(src)
+ if(href_list[VV_HK_GODMODE])
+ if(!check_rights(R_ADMIN))
+ return
+ usr.client.cmd_admin_godmode(src)
+ if(href_list[VV_HK_GIVE_SPELL])
+ if(!check_rights(NONE))
+ return
+ usr.client.give_spell(src)
+ if(href_list[VV_HK_REMOVE_SPELL])
+ if(!check_rights(NONE))
+ return
+ usr.client.remove_spell(src)
+ if(href_list[VV_HK_GIVE_DISEASE])
+ if(!check_rights(NONE))
+ return
+ usr.client.give_disease(src)
+ if(href_list[VV_HK_GIB])
+ if(!check_rights(R_FUN))
+ return
+ usr.client.cmd_admin_gib(src)
+ if(href_list[VV_HK_BUILDMODE])
+ if(!check_rights(R_BUILDMODE))
+ return
+ togglebuildmode(src)
+ if(href_list[VV_HK_DROP_ALL])
+ if(!check_rights(NONE))
+ return
+ usr.client.cmd_admin_drop_everything(src)
+ if(href_list[VV_HK_DIRECT_CONTROL])
+ if(!check_rights(NONE))
+ return
+ usr.client.cmd_assume_direct_control(src)
+ if(href_list[VV_HK_OFFER_GHOSTS])
+ if(!check_rights(NONE))
+ return
+ offer_control(src)
/mob/vv_get_var(var_name)
switch(var_name)
@@ -965,6 +1012,10 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
return debug_variable(var_name, logging, 0, src, FALSE)
. = ..()
+/mob/vv_auto_rename(new_name)
+ //Do not do parent's actions, as we *usually* do this differently.
+ fully_replace_character_name(real_name, new_name)
+
/mob/verb/open_language_menu()
set name = "Open Language Menu"
set category = "IC"
diff --git a/code/modules/paperwork/paper_premade.dm b/code/modules/paperwork/paper_premade.dm
index 9a60158e73..2d03a17e0a 100644
--- a/code/modules/paperwork/paper_premade.dm
+++ b/code/modules/paperwork/paper_premade.dm
@@ -48,11 +48,113 @@
name = "paper- 'Chemical Information'"
info = "Known Onboard Toxins: \n\tGrade A Semi-Liquid Plasma: \n\t\tHighly poisonous. You cannot sustain concentrations above 15 units. \n\t\tA gas mask fails to filter plasma after 50 units. \n\t\tWill attempt to diffuse like a gas. \n\t\tFiltered by scrubbers. \n\t\tThere is a bottled version which is very different \n\t\t\tfrom the version found in canisters! \n \n\t\tWARNING: Highly Flammable. Keep away from heat sources \n\t\texcept in an enclosed fire area! \n\t\tWARNING: It is a crime to use this without authorization. \nKnown Onboard Anti-Toxin: \n\tAnti-Toxin Type 01P: Works against Grade A Plasma. \n\t\tBest if injected directly into bloodstream. \n\t\tA full injection is in every regular Med-Kit. \n\t\tSpecial toxin Kits hold around 7. \n \nKnown Onboard Chemicals (other): \n\tRejuvenation T#001: \n\t\tEven 1 unit injected directly into the bloodstream \n\t\t\twill cure unconscious and sleep toxins. \n\t\tIf administered to a dying patient it will prevent \n\t\t\tfurther damage for about units*3 seconds. \n\t\t\tit will not cure them or allow them to be cured. \n\t\tIt can be administered to a non-dying patient \n\t\t\tbut the chemicals disappear just as fast. \n\tMorphine T#054: \n\t\t5 units will induce precisely 1 minute of sleep. \n\t\t\tThe effect are cumulative. \n\t\tWARNING: It is a crime to use this without authorization"
-
/*
* Stations
*/
+/obj/item/paper/guides/cogstation/job_changes
+ name = "MEMO: Job Changes"
+ info = "To ensure minimal employee downtime, please take note of the following changes to select professions that Cogstation specifically requires: \n \n- Chemists are to have basic Research accessand an encryption key for the Science channel. \n- Roboticists are to have basic Medical and Morgue access. \n- Engineers and Atmospheric Technicians are to have Warehouse and Mining access. \n- The Cook should not have Morgue access \n- The Clown and Mime are to have Maintenance access. This is necessary due to the location of their offices. \n \nGenerated by Organic Resources Bot #2053"
+
+/obj/item/paper/guides/cogstation/letter_sec
+ name = "To future Security personnel"
+ info = "As this station's Head of Security prior to it being translocated to your sector, my hope is that Central Command will properly brief you on the ins and outs of this particular layout. I'm writing this in case they don't. 'CogStation' as it's called may be worlds different than other stations in your sector, so I wanted to mention a few things: \n \nFirst of all, the brig uses a 'genpop' prison system. While I'm sure books exist on the subject, the main thing to know is prisoners share a common area regardless of sentence length. There is a single solitary cell, but it should be reserved only for the particularly dangerous. \n \nYour auxiliary posts can be found in the fore and starboard quarter parts of the station; near arrivals and cargo, respectively. I've heard about stations with a post in each department - unfortunately, this isn't one of them. If it's any consolation, the security wing is rather centrally located. \n \nAfter a perp's done their time, you can let them out via the disposal unit right outside the prison wing. It'll plop them right outside your front desk without the potential hassle of escorting them through your office. \n \nHave a secure day! \n- Louis Cannon"
+
+/obj/item/paper/guides/cogstation/disposals
+ name = "Regarding the disposal system:"
+ info = "As you might have noticed, this station has far more disposal pipes than you may expect from your average Nanotrasen research facility. Part of the reason for this is specialization - mail, trash, even corpses have their own disposal systems. Unfortunately, the convenient color-coding was lost in translocation and we've had to compensate by marking the area around each bin. \n \n- WHITE/GRAY STRIPES is for DELIVERIES. \n- RED STRIPES is for CORPSES. \n- EVERYTHING ELSE is for TRASH, barring a few exceptions that should be labeled as such. \n \nIdeally the station won't sustain any heavy structural damage during your time here but if it does, or someone decides to tamper with/sabotage this system, you'll be forgiven if you can't put it back together perfectly. \n \n-C. Donnelly Architectural Analyst"
+
+/obj/item/paper/guides/cogstation/janitor
+ name = "a quick tip"
+ info = "I'm gonna tell you something I wish I knew my first day here: there's an auxiliary custodial closet on the other end of the station. Just head straight through maintenance behind the bathrooms next to engineering and you'll find it. \n \nNow this sounds great until you realize there's no quick way to the other end of the station without a spacesuit - then it sounds like a gift from the gods! \n \n- 'Squeaky' Kleiner"
+
+/obj/item/paper/guides/cogstation/cooks
+ name = "MEMO: Cooks"
+ info = "Please be aware that while a smartfridge has recently been installed in your kitchen, botanists may choose to use the produce delivery system instead. You'll find the outlet, in addition to your freezer in the adjacent service hall. You can also send food directly to the bar and prison inmates via the disposal bins marked with dark red and bright red tiling, respectively. \n \nGenerated by Organic Resources Bot #7004"
+
+/obj/item/paper/guides/cogstation/cdn_chap
+ name = "About the corpse disposal network"
+ info = "One of the medical staff has insisted I leave a message regarding the 'corpse disposal network' and its significance. From what I have been told, it has been designed so medical staff can deliver the deceased directly to you. However, bodies from the medical booth or detective's office next door will be sent your way first. \nThe delivery chute will allow you to send these bodies to the medical department so that they can attempt to revive them, if possible. I would recommend periodically checking the morgue for any unannounced arrivals, but make sure bodies are devoid of a soul before 'burying' or cremating them! \n \nSoulstone Obelisk \n \nDepartment of Higher-Dimensional Affairs"
+
+/obj/item/paper/guides/cogstation/letter_cmo
+ name = "To the future Medical Director..."
+ info = "From one Medical Director to another, I'm happy to say you won't have to rethink how you do things here, since saving lives is universal! That being said, you might want to consider the following: \n \n There's a medical booth over in the civilian wing, so ideally folks with minor cuts and bruises will head there first. While it can operate on a self-serve basis, you might want to send one of your doctors there to make sure it's run proper. \n \n The Geneticists and Virologists share the same pool of test subjects, so make sure they don't reintroduce them to the control group! A group of regular monkeys is dangerous enough, so do NOT attack one in view of the others! \n \nLastly, you might want to check the morgue regularly - it's one of the two main endpoints for the corpse disposal network. At the very least, make sure robotics gets your approval BEFORE borging someone! Robert hasn't been the same since he became Rob-Bot... \n \nEarl. E. Greaves"
+
+/obj/item/paper/guides/cogstation/cdn_med
+ name = "Corpse Disposal Network"
+ info = "It's come to my attention that this station has been outfitted with a Corpse Disposal Network (CDN), and disposal units incorporated into this network are marked with RED STRIPES surrounding them. This morgue is one of the network's major endpoints, the other being the chapel morgue. \n \nAs such, it should be checked routinely for any bodies that may have arrived unannounced. Cloned corpses or personnel that have proven unrevivable can be shipped to the chapel morgue via your delivery chute. The same can be done for bodies that arrived brainless, although if you want botany to have at them you should tag them accordingly. \n \nLiving persons who treat the CDN like a theme park ride are to be swiftly removed from the medical department, short of them being on the verge of death. In such cases, treatment is advised. \n \n-Dr. Halley"
+
+/obj/item/paper/guides/cogstation/letter_eng
+ name = "To future Engineering staff:"
+ info = "I'm not gonna sugarcoat this. Compared to other departments, you might have your work cut out for you. CogStation is an entirely different beast than your standard Box, but everyone's still gonna expect you to keep the place running. \n \n If there's any good news, it's your time to shine if you know how to run a thermo-electric generator. That's what this station runs on, and CentCom isn't planning on changing that. If it's absolutely critical you might be able to run a singularity or tesla engine east of mining, but it won't have any sort of shielding out there. \n \nThe air system's different too. It's multiple small networks instead of a single big one, with air hookups across the station. Fortunately it's not that complicated, but it comes at the expense of being able to filter out and reuse specific gases. Besides, you'll probably be busy enough with the engine and general upkeep anyway. \n \nThe disposal network in contrast is significantly more complicated, yet more capable. I've already elaborated on it, so I'll let you find and read my write-up for that. As for the routing system, it's just begging to get hit by a stray meteor so consider other utilities a higher priority. \n \nGood luck. You're gonna need it. \n \n-C. Donnelly Architectural Analyst"
+
+/obj/item/paper/guides/cogstation/letter_chief
+ name = "To the future Chief Engineer:"
+ info = "Considering some of the other heads are writing letters to their successors, I reckon I might as well do the same. If this place is heading where I think it is, I sure as hell hope they made sure you know how to run a TEG. Oh who am I kidding, of course they won't. Well, the good news is unlike that newfangled supermatter that can kill everyone from radiation before you know anything is wrong, you'll know if a Thermo-Electric Generator is failing, since you'll either have no power or be on fire. \n \nThere's two main ways to set it up, with the 'proper way' being to run plasma through the pipes. You hook them up on the hot side (the one with the red pipes), then use the heaters and freezers to keep the hot side hot and the cold side cold. Just keep an eye on pressures - too much on the hot side or too little on the cold side and you'll get reduced or even no power. Of course, the fun way is to get something cooking in the burn chamber for the hot side and use space itself for the cold side. You might want to throw a monkey into the burn chamber for good luck and an indication whether your gas is suitably hot or not. Just make sure that \n \nI found this on the CE's desk. My guess is he was going to finish it, but was interrupted at some point in his last shift and ultimately met his untimely demise. I just hope whatever he was going to warn you about wasn't critical... \n \n-C. Donnelly"
+
+/obj/item/paper/guides/cogstation/letter_hos
+ name = "To the future HoS"
+ info = "I'm gonna be rather disappointed if CentCom doesn't brief you about this station, but if they don't I wrote up another letter for your department that should cover it pretty well. Make sure your officers read it if they aren't up to speed. \n \nSomething you in particular should know is that if someone's getting to be too much to handle, the boys and I have constructed a 'discount transfer centre' just behind the router. Use it only as a last resort - the walls may be reinforced but they're still thin, and you'll have big trouble on your hands if the AI or any cyborgs find out about it. \n -LC"
+
+/obj/item/paper/guides/cogstation/letter_supp
+ name = "To future Supply Staff:"
+ info = "Cargo, move freight. Miners, don't die. Your jobs are pretty straightforward, which is likely why they originally fell under Engineering on this station as opposed to their own department. Although we've considerably readjusted this part of the station to accommodate you, there are potential differences you should be aware of. \n \nEngineeringwill have access to some of your department, namely the warehouse and mining dock. Mining operations on this station were originally asteroid-based, hence the catwalk into the great beyond. Although you won't need to worry about being space-worthy due to a newly installed shuttle dock, they might need to get out there. \n \nYou'll have all your usual means of shipping out goods, but the disposal network is more complex with a separate line for mail and trash. I've left another note that explains this in detail, but know trash is the janitor's responsibility, not yours. \n \nThe biggest difference has to be this station's router system, which allows departments to ship goods between themselves. Even if the belts aren't working properly they'll still have their own request consoles, so you'll want to check for orders regularly. \n \n-C. Donnelly \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/sleepers
+ name = "Re: Sleepers?"
+ info = "Yes, the sleepers are meant to be publicly accessible. Policies in this station's original location encouraged crew to visit the clinic or treat themselves when it came to minor injuries. \n \nThis is no excuse for you not to do your jobs. You may wish to keep an eye on the sleepers as to ensure they're being used responsibly. Remember, allowing an overdose to happen under your watch isn't much different from administering that overdose yourself. \n \n- Dr. Halley"
+
+/obj/item/paper/fluff/cogstation/cloner
+ name = "Re: Issue with the cloner?"
+ info = "I've yet to see any sentient small primates working in this sector, but if they aren't carrying the Devo gene they should be fine. The document was likely referring to the nonsapient ones you can get out of a monkey cube. \n \n- Dr. Halley"
+
+/obj/item/paper/fluff/cogstation/letter_rd
+ name = "To the future Research Director"
+ info = "Apologies if you were expecting a letter from the station's Research Director, but just prior to translocation we found out they were a BLF operative. I wouldn't trust a single word they wrote and while I'm not a scientist, something tells me your department will have the easiest time adjusting to this station. \n \nYou should have everything you need - this is a research facility after all. It's just a matter of finding it, which shouldn't be too hard. Folks like you are why we're out in deep space, after all! \n-Louis Cannon \nFormer Head of Security"
+
+/obj/item/paper/fluff/cogstation/letter_cap
+ name = "Captain's Log"
+ info = "So I guess some of the other heads have decided to leave little notes for future employees here. Heartwarming, but the most important thing I figure I can leave you is the truth. Nevermind the Syndicate, the xenomorphs, the apocalyptic death cults I hear are a thing way out there - I'm convinced we are our own worst enemy. \n \nDon't believe me? Maybe you can ask Chief Engineer Earp. Oh right, he vaporized himself trying to produce enough power to keep the lights on in Space China for a week, despite only needing a sliver of that to run this place as intended. Or maybe you can ask Head of Security Cannon, who executed our Research Director in plain sight of everyone. Even if he was in the right, the final frontier isn't the goddamn wild west! Hell, maybe you can ask one of your 'staff assistants', although in my experience the only ones they seem to want to help is themselves. \n \nOf course, the REAL problems are with the higher-ups that stationed us on this deathtrap before deciding to send it your way, but there's only so much I can say and get away with it, for instance that they only sent this station since they could care less if it was a total loss. By the time you read this, I'll already be long gone. Maybe it'll be a different story with your crew, but between you and me, I wouldn't hold my breath...unless they fuck up the air system. \n \nDom Kahn Former Captain of Nanotrasen CogStation"
+
+/obj/item/paper/fluff/cogstation/letter_qm
+ name = "To the future Quartermaster:"
+ info = "Sorry if this office seems like an afterthought - as I mentioned in my letter to your department at large, you used to be a sub-department of Engineering on this station. Fortunately that's not the case here and you have cargo techs as opposed to other quartermasters, but you should keep the following in mind: \n \n- Keep your miners focused on where they're supposed to mine. I get the allure of deep space can be tempting, but we want them somewhere we can be fairly confident they'll come back alive and with ores. \n \n- Anyone with maintenance access can enter the Routing Depot at the heart of the station, but you'll need a space suit to safely reach it. You've been given one for this very reason, but your techs will need to source their own. \n \n- The fact that you've been given an office and had a good portion of your department refurbished as opposed to being told to make do should be seen as an indication that there are people in this company that care about you, even if it doesn't feel that way sometimes. Remember that before trying to 'declare independence' as 'Cargonia'. \n \n-C. Donnelly \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/letter_chap
+ name = "A message from the DHDA"
+ info = "Regardless of what the name leads you to believe, CogStation is neither Ratvarian in origin nor designed by members of this so-called 'clock cult'. Despite a potential common enemy and instances of exhibiting peaceful behavior, their beliefs have been labeled 'Heretical' by the Department of Higher-Dimensional Affairs and following them is grounds for immediate termination. \nAs the station's designated Chaplain, it is advised you correct anyone who claims this station and/or its designers are Ratvarian. While they are most likely misinformed or 'joking around', untruths gain credibility the more they are repeated. \n \nSoulstone Obelisk \n \nDepartment of Higher-Dimensional Affairs"
+
+/obj/item/paper/fluff/cogstation/cluwne
+ name = "Mysterious Note"
+ info = "ThE rInGmAsTeR dOeSn'T rUn ThE cIrCus... HONK!!!"
+
+/obj/item/paper/fluff/cogstation/mime
+ name = "Au futur Mime"
+ info = "Toutes mes excuses pour toute mauvaise grammaire, je ne suis pas un haut-parleur naturel Français et a dû utiliser NanoTranslate. Bien que vous puissiez être mécontent de l’emplacement de votre bureau, s’il vous plaît comprendre que c’était le seul endroit où nous pourrions le mettre sans problèmes de sécurité et/ou CentClown se plaindre à ce sujet. Nous nous excusons également pour l’absence d’une zone de performance dédiée, mais nous espérons que vous accorder un accès à l’entretien compensera. \n \n-C. Donnelly \n \nAnalyste Architectural"
+
+/obj/item/paper/fluff/cogstation/bsrb
+ name = "Message from the NTBSRB"
+ info = "Congratulations, (sector name here)! You've been chosen as a candidate to receive a Nanotrasen icon via bluespace translocation! 'CogStation' as it's commonly known has a rich history and a unique layout. Our hope is that you'll be able to retrofit this station to serve your needs, ideally as one of your primary research hubs.
We look forward to seeing what you can accomplish here! \n \n-The Nanotrasen Bluespace Research Board"
+
+/obj/item/paper/fluff/cogstation/survey
+ name = "Fwd: Survey Report"
+ info = "After a thorough investigation, I'm happy to say that this translocation and its consequences weren't for naught. CogStation appears to have made it in one piece, with the only exception being a 'drone factory' satellite. I suspect it met a fate similar to parts of the station's original home, which means there's the possibility it's not terribly far from here. \n \nI can see some of CogStation's components being alien to local crews, but fortunately some of the station's previous staff appear to have anticipated this and left some advice. The assessment team and I have decided to do the same where appropriate, although I can see some areas that might be worth redesigning to better suit area protocol. I've brought them up to the Chief Architect, you should hear from them in a couple of hours. \n \n-C. Donnelly \n \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/router_off
+ name = "ROUTER STATUS: INACTIVE"
+ info = "This router line has been closed while we determine possible solutions. While you are free to use the request and supply consoles, you should plan on receiving your deliveries elsewhere. \n \n-C. Donnelly \n \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/router_verylimited
+ name = "ROUTER STATUS: VERY LIMITED"
+ info = "Currently, this router is only capable of making deliveries to Engineering, Cargo and the recycler, via manual input from the Routing Depot. It is not yet capable of receiving deliveries, meaning you should expect to receive any orders elsewhere. \n \n-C. Donnelly \n \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/router_limited
+ name = "ROUTER STATUS: LIMITED"
+ info = "Currently, this router cannot receive deliveries from the Airbridge, MedSci, Security, or Service Routers. Cargo and the recycler are the only points currently accepting deliveries from here, although manual input from the routing depot is currently required. \n \n-C. Donnelly \n \nArchitectural Analyst"
+
+/obj/item/paper/fluff/cogstation/router_cargo
+ name = "ROUTER STATUS: VERY LIMITED"
+ info = "Currently, this router cannot receive deliveries from the Airbridge, MedSci, Security, or Service Routers. It is not yet capable of making deliveries, beyond sending items to the recycler. \n \n-C. Donnelly \n \nArchitectural Analyst"
/////////// CentCom
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 9c96216ce8..1b23b1bb5d 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -84,7 +84,7 @@
var/lastused_equip = 0
var/lastused_environ = 0
var/lastused_total = 0
- var/main_status = 0
+ var/main_status = 0 // Whether or not there's external power. 0 is "none", 1 is "insufficient", 2 is "charging".
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
var/malfhack = 0 //New var for my changes to AI malf. --NeoFite
var/mob/living/silicon/ai/malfai = null //See above --NeoFite
@@ -1276,63 +1276,89 @@
var/last_eq = equipment
var/last_en = environ
var/last_ch = charging
-
var/excess = surplus()
-
- if(!src.avail())
+ if(!avail())
main_status = 0
else if(excess < 0)
main_status = 1
else
main_status = 2
+ var/cur_excess = excess
+ var/cur_used = lastused_total
+
+ // first: if we have enough power, power the essentials DIRECTLY
+
+ var/environ_satisfied = FALSE
+ var/equipment_satisfied = FALSE
+ var/lighting_satisfied = FALSE
+
+ if(cur_excess >= lastused_environ)
+ autoset(environ, 1)
+ add_load(lastused_environ)
+ cur_excess -= lastused_environ
+ cur_used -= lastused_environ
+ environ_satisfied = TRUE
+
+ if(cur_excess >= lastused_equip)
+ autoset(equipment, 1)
+ add_load(lastused_equip)
+ cur_excess -= lastused_equip
+ cur_used -= lastused_equip
+ equipment_satisfied = TRUE
+
+ if(cur_excess >= lastused_light)
+ autoset(lighting, 1)
+ add_load(lastused_light)
+ cur_excess -= lastused_light
+ cur_used -= lastused_light
+ lighting_satisfied = TRUE
+
+
+ // next: take from or charge to the cell, depending on how much is left
if(cell && !shorted)
- // draw power from cell as before to power the area
- var/cellused = min(cell.charge, GLOB.CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
- cell.use(cellused)
+ if(cur_excess > 0)
+ var/charging_cell = min(cur_excess, cell.maxcharge * GLOB.CHARGELEVEL)
+ cell.give(charging_cell)
+ add_load(charging_cell)
+ lastused_total += charging_cell
+ longtermpower = min(10,longtermpower + 1)
+ if(chargemode && !charging)
+ chargecount++
+ if(chargecount == 10)
- if(excess > lastused_total) // if power excess recharge the cell
- // by the same amount just used
- cell.give(cellused)
- add_load(cellused/GLOB.CELLRATE) // add the load used to recharge the cell
-
-
- else // no excess, and not enough per-apc
- if((cell.charge/GLOB.CELLRATE + excess) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
- cell.charge = min(cell.maxcharge, cell.charge + GLOB.CELLRATE * excess) //recharge with what we can
- add_load(excess) // so draw what we can from the grid
- charging = APC_NOT_CHARGING
-
- else // not enough power available to run the last tick!
- charging = APC_NOT_CHARGING
- chargecount = 0
+ chargecount = 0
+ charging = APC_CHARGING
+ else // not enough power available to run the last tick!
+ charging = APC_NOT_CHARGING
+ chargecount = 0
+ longtermpower = max(-10,longtermpower - 2)
+ if(cell.charge >= cur_used)
+ cell.use(GLOB.CELLRATE * cur_used)
+ else
// This turns everything off in the case that there is still a charge left on the battery, just not enough to run the room.
equipment = autoset(equipment, 0)
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
+ // set channels based on remaining charge
- // set channels depending on how much charge we have left
-
- // Allow the APC to operate as normal if the cell can charge
- if(charging && longtermpower < 10)
- longtermpower += 1
- else if(longtermpower > -10)
- longtermpower -= 2
+ var/cell_percent = cell.percent()
if(cell.charge <= 0) // zero charge, turn all off
equipment = autoset(equipment, 0)
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
area.poweralert(0, src)
- else if(cell.percent() < 15 && longtermpower < 0) // <15%, turn off lighting & equipment
+
+ else if(cell_percent < 15 && longtermpower < 0) // <15%, turn off lighting & equipment
equipment = autoset(equipment, 2)
lighting = autoset(lighting, 2)
environ = autoset(environ, 1)
area.poweralert(0, src)
- else if(cell.percent() < 30 && longtermpower < 0) // <30%, turn off equipment
- equipment = autoset(equipment, 2)
- lighting = autoset(lighting, 1)
+ else if(cell_percent < 30 && longtermpower < 0) // <30%, turn off lighting
+ equipment = autoset(equipment, 1)
+ lighting = autoset(lighting, 2)
environ = autoset(environ, 1)
area.poweralert(0, src)
else // otherwise all can be on
@@ -1340,50 +1366,21 @@
lighting = autoset(lighting, 1)
environ = autoset(environ, 1)
area.poweralert(1, src)
- if(cell.percent() > 75)
+ if(cell_percent > 75)
area.poweralert(1, src)
- // now trickle-charge the cell
- if(chargemode && charging == APC_CHARGING && operating)
- if(excess > 0) // check to make sure we have enough to charge
- // Max charge is capped to % per second constant
- var/ch = min(excess*GLOB.CELLRATE, cell.maxcharge*GLOB.CHARGELEVEL)
- add_load(ch/GLOB.CELLRATE) // Removes the power we're taking from the grid
- cell.give(ch) // actually recharge the cell
-
- else
- charging = APC_NOT_CHARGING // stop charging
- chargecount = 0
// show cell as fully charged if so
if(cell.charge >= cell.maxcharge)
cell.charge = cell.maxcharge
charging = APC_FULLY_CHARGED
- if(chargemode)
- if(!charging)
- if(excess > cell.maxcharge*GLOB.CHARGELEVEL)
- chargecount++
- else
- chargecount = 0
-
- if(chargecount == 10)
-
- chargecount = 0
- charging = APC_CHARGING
-
- else // chargemode off
- charging = 0
- chargecount = 0
-
- else // no cell, switch everything off
-
+ else // no cell, can still run but not very well
charging = APC_NOT_CHARGING
chargecount = 0
- equipment = autoset(equipment, 0)
- lighting = autoset(lighting, 0)
- environ = autoset(environ, 0)
- area.poweralert(0, src)
+ environ = autoset(environ, environ_satisfied)
+ equipment = autoset(equipment, equipment_satisfied)
+ lighting = autoset(lighting, lighting_satisfied)
// update icon & area power if anything changed
@@ -1398,17 +1395,13 @@
// on 0=off, 1=on, 2=autooff
/obj/machinery/power/apc/proc/autoset(val, on)
- if(on==0)
- if(val==2) // if on, return off
- return 0
- else if(val==3) // if auto-on, return auto-off
- return 1
- else if(on==1)
- if(val==1) // if auto-off, return auto-on
- return 3
- else if(on==2)
- if(val==3) // if auto-on, return auto-off
- return 1
+ if(val == 3 && (on == 2 || !on)) // if auto-on, return auto-off
+ return 1
+ else if(val == 2 && !on) // if on, return off
+ return 0
+ else if(on == 1 && val == 1) // if auto-off, return auto-on
+ return 3
+ // no, i don't understand these comments either
return val
/obj/machinery/power/apc/proc/reset(wire)
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 1c87c1901c..1e687816ff 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -235,7 +235,7 @@
/obj/structure/reagent_dispensers/keg/milk
name = "keg of milk"
- desc = "It's not quite what you were hoping for."
+ desc = "A keg of pasteurised, homogenised, filtered and semi-skimmed space milk."
icon_state = "whitekeg"
reagent_id = /datum/reagent/consumable/milk
@@ -250,4 +250,4 @@
desc = "A keg of... wow that's a long name."
icon_state = "bluekeg"
reagent_id = /datum/reagent/consumable/ethanol/gargle_blaster
- tank_volume = 100
\ No newline at end of file
+ tank_volume = 100
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index b9897db303..95d6c49529 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -505,13 +505,13 @@ datum/status_effect/rebreathing/tick()
/datum/status_effect/stabilized/purple/tick()
var/is_healing = FALSE
if(owner.getBruteLoss() > 0)
- owner.adjustBruteLoss(-0.2)
+ owner.adjustBruteLoss(-0.4)
is_healing = TRUE
if(owner.getFireLoss() > 0)
- owner.adjustFireLoss(-0.2)
+ owner.adjustFireLoss(-0.4)
is_healing = TRUE
if(owner.getToxLoss() > 0)
- owner.adjustToxLoss(-0.2, forced = TRUE) //Slimepeople should also get healed.
+ owner.adjustToxLoss(-0.4, forced = TRUE) //Slimepeople should also get healed.
is_healing = TRUE
if(is_healing)
examine_text = "SUBJECTPRONOUN is regenerating slowly, purplish goo filling in small injuries!"
@@ -933,7 +933,6 @@ datum/status_effect/stabilized/blue/on_remove()
return ..()
/datum/status_effect/stabilized/lightpink/tick()
- owner.adjustStaminaLoss(-4.5)
for(var/mob/living/carbon/human/H in range(1, get_turf(owner)))
if(H != owner && H.stat != DEAD && H.health <= 0 && !H.reagents.has_reagent(/datum/reagent/medicine/epinephrine))
to_chat(owner, "[linked_extract] pulses in sync with [H]'s heartbeat, trying to keep [H.p_them()] alive.")
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index 9452722183..1799a61406 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -436,14 +436,11 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(magic_flags & SPELL_SKIP_ALL_REQS)
return TRUE
- if(player_lock && (!user.mind || !(src in user.mind.spell_list)))
+ if(player_lock && (!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list)))
if(!silent)
to_chat(user, "You shouldn't have this spell! Something's wrong.")
return FALSE
- if(!(src in user.mob_spell_list))
- return FALSE
-
if(!centcom_cancast && !(magic_flags & SPELL_SKIP_CENTCOM)) //Certain spells are not allowed on the centcom zlevel
var/turf/T = get_turf(user)
if(is_centcom_level(T.z))
diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm
index cb53574653..990ff93595 100644
--- a/code/modules/vehicles/scooter.dm
+++ b/code/modules/vehicles/scooter.dm
@@ -40,11 +40,22 @@
. = ..()
/obj/vehicle/ridden/scooter/skateboard
- name = "skateboard"
- desc = "An unfinished scooter which can only barely be called a skateboard. It's still rideable, but probably unsafe. Looks like you'll need to add a few rods to make handlebars. Alt-click to adjust speed."
+ name = "improvised skateboard"
+ desc = "An unfinished scooter which can only barely be called a skateboard. It's still rideable, but probably unsafe. Looks like you'll need to add a few rods to make handlebars."
icon_state = "skateboard"
density = FALSE
- var/adjusted_speed = FALSE
+ arms_required = 0
+ var/datum/effect_system/spark_spread/sparks
+ ///Whether the board is currently grinding
+ var/grinding = FALSE
+ ///Stores the time of the last crash plus a short cooldown, affects availability and outcome of certain actions
+ var/next_crash
+ ///Stores the default icon state
+ var/board_icon = "skateboard"
+ ///The handheld item counterpart for the board
+ var/board_item_type = /obj/item/melee/skateboard
+ ///Stamina drain multiplier
+ var/instability = 10
/obj/vehicle/ridden/scooter/skateboard/Initialize()
. = ..()
@@ -54,6 +65,23 @@
D.set_vehicle_dir_layer(NORTH, OBJ_LAYER)
D.set_vehicle_dir_layer(EAST, OBJ_LAYER)
D.set_vehicle_dir_layer(WEST, OBJ_LAYER)
+ sparks = new
+ sparks.set_up(1, 0, src)
+ sparks.attach(src)
+
+/obj/vehicle/ridden/scooter/skateboard/Destroy()
+ if(sparks)
+ QDEL_NULL(sparks)
+ . = ..()
+
+/obj/vehicle/ridden/scooter/skateboard/relaymove()
+ if (grinding || world.time < next_crash)
+ return FALSE
+ return ..()
+
+/obj/vehicle/ridden/scooter/skateboard/generate_actions()
+ . = ..()
+ initialize_controller_action_type(/datum/action/vehicle/ridden/scooter/skateboard/ollie, VEHICLE_CONTROL_DRIVE)
/obj/vehicle/ridden/scooter/skateboard/post_buckle_mob(mob/living/M)//allows skateboards to be non-dense but still allows 2 skateboarders to collide with each other
density = TRUE
@@ -68,17 +96,52 @@
. = ..()
if(A.density && has_buckled_mobs())
var/mob/living/H = buckled_mobs[1]
- var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
- unbuckle_mob(H)
- H.throw_at(throw_target, 4, 3)
- H.DefaultCombatKnockdown(100)
- H.adjustStaminaLoss(40)
- var/head_slot = H.get_item_by_slot(SLOT_HEAD)
- if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
- H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3)
- H.updatehealth()
- visible_message("[src] crashes into [A], sending [H] flying!")
- playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ H.adjustStaminaLoss(instability*6)
+ playsound(src, 'sound/effects/bang.ogg', 40, TRUE)
+ if(!iscarbon(H) || H.getStaminaLoss() >= 100 || grinding || world.time < next_crash)
+ var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
+ unbuckle_mob(H)
+ H.throw_at(throw_target, 3, 2)
+ var/head_slot = H.get_item_by_slot(SLOT_HEAD)
+ if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
+ H.updatehealth()
+ visible_message("[src] crashes into [A], sending [H] flying!")
+ H.Knockdown(80)
+ else
+ var/backdir = turn(dir, 180)
+ vehicle_move(backdir)
+ H.spin(4, 1)
+ next_crash = world.time + 10
+
+///Moves the vehicle forward and if it lands on a table, repeats
+/obj/vehicle/ridden/scooter/skateboard/proc/grind()
+ vehicle_move(dir)
+ if(has_buckled_mobs() && locate(/obj/structure/table) in loc.contents)
+ var/mob/living/L = buckled_mobs[1]
+ L.adjustStaminaLoss(instability*0.5)
+ if (L.getStaminaLoss() >= 100)
+ playsound(src, 'sound/effects/bang.ogg', 20, TRUE)
+ unbuckle_mob(L)
+ var/atom/throw_target = get_edge_target_turf(src, pick(GLOB.cardinals))
+ L.throw_at(throw_target, 2, 2)
+ visible_message("[L] loses [L.p_their()] footing and slams on the ground!")
+ L.Knockdown(40)
+ grinding = FALSE
+ icon_state = board_icon
+ return
+ else
+ playsound(src, 'sound/vehicles/skateboard_roll.ogg', 50, TRUE)
+ if(prob (25))
+ var/turf/location = get_turf(loc)
+ if(location)
+ location.hotspot_expose(1000,1000)
+ sparks.start() //the most radical way to start plasma fires
+ addtimer(CALLBACK(src, .proc/grind), 2)
+ return
+ else
+ grinding = FALSE
+ icon_state = board_icon
/obj/vehicle/ridden/scooter/skateboard/MouseDrop(atom/over_object)
. = ..()
@@ -89,22 +152,42 @@
to_chat(M, "You can't lift this up when somebody's on it.")
return
if(over_object == M)
- var/obj/item/melee/skateboard/board = new /obj/item/melee/skateboard()
+ var/board = new board_item_type(get_turf(M))
M.put_in_hands(board)
qdel(src)
-/obj/vehicle/ridden/scooter/skateboard/AltClick(mob/user)
- . = ..()
- var/datum/component/riding/R = src.GetComponent(/datum/component/riding)
- if (!adjusted_speed)
- R.vehicle_move_delay = 0
- to_chat(user, "You adjust the wheels on [src] to make it go faster.")
- adjusted_speed = TRUE
+/obj/vehicle/ridden/scooter/skateboard/pro
+ name = "skateboard"
+ desc = "A RaDSTORMz brand professional skateboard. Looks a lot more stable than the average board."
+ icon_state = "skateboard2"
+ board_icon = "skateboard2"
+ board_item_type = /obj/item/melee/skateboard/pro
+ instability = 6
+
+/obj/vehicle/ridden/scooter/skateboard/hoverboard/
+ name = "hoverboard"
+ desc = "A blast from the past, so retro!"
+ board_item_type = /obj/item/melee/skateboard/hoverboard
+ instability = 3
+ icon_state = "hoverboard_red"
+ board_icon = "hoverboard_red"
+
+/obj/vehicle/ridden/scooter/skateboard/hoverboard/screwdriver_act(mob/living/user, obj/item/I)
+ return FALSE
+
+/obj/vehicle/ridden/scooter/skateboard/hoverboard/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/stack/rods))
+ return
else
- R.vehicle_move_delay = 1
- to_chat(user, "You adjust the wheels on [src] to make it go slower.")
- adjusted_speed = FALSE
- return TRUE
+ return ..()
+
+/obj/vehicle/ridden/scooter/skateboard/hoverboard/admin
+ name = "\improper Board Of Directors"
+ desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too."
+ board_item_type = /obj/item/melee/skateboard/hoverboard/admin
+ instability = 0
+ icon_state = "hoverboard_nt"
+ board_icon = "hoverboard_nt"
//CONSTRUCTION
/obj/item/scooter_frame
diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm
index c780ce6fd3..5de2c8961f 100644
--- a/code/modules/vehicles/vehicle_actions.dm
+++ b/code/modules/vehicles/vehicle_actions.dm
@@ -164,3 +164,41 @@
if(istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
C.RollTheDice(owner)
+
+
+/datum/action/vehicle/ridden/scooter/skateboard/ollie
+ name = "Ollie"
+ desc = "Get some air! Land on a table to do a gnarly grind."
+ button_icon_state = "skateboard_ollie"
+ ///Cooldown to next jump
+ var/next_ollie
+
+/datum/action/vehicle/ridden/scooter/skateboard/ollie/Trigger()
+ if(world.time > next_ollie)
+ var/obj/vehicle/ridden/scooter/skateboard/V = vehicle_target
+ if (V.grinding)
+ return
+ var/mob/living/L = owner
+ var/turf/landing_turf = get_step(V.loc, V.dir)
+ L.adjustStaminaLoss(V.instability*2)
+ if (L.getStaminaLoss() >= 100)
+ playsound(src, 'sound/effects/bang.ogg', 20, TRUE)
+ V.unbuckle_mob(L)
+ L.throw_at(landing_turf, 2, 2)
+ L.Knockdown(40)
+ V.visible_message("[L] misses the landing and falls on [L.p_their()] face!")
+ else
+ L.spin(4, 1)
+ animate(L, pixel_y = -6, time = 4)
+ animate(V, pixel_y = -6, time = 3)
+ playsound(V, 'sound/vehicles/skateboard_ollie.ogg', 50, TRUE)
+ passtable_on(L, VEHICLE_TRAIT)
+ V.pass_flags |= PASSTABLE
+ L.Move(landing_turf, vehicle_target.dir)
+ passtable_off(L, VEHICLE_TRAIT)
+ V.pass_flags &= ~PASSTABLE
+ if(locate(/obj/structure/table) in V.loc.contents)
+ V.grinding = TRUE
+ V.icon_state = "[V.board_icon]-grind"
+ addtimer(CALLBACK(V, /obj/vehicle/ridden/scooter/skateboard/.proc/grind), 2)
+ next_ollie = world.time + 5
diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm
index 14ce7a83b7..e663dca7ce 100644
--- a/code/modules/vending/games.dm
+++ b/code/modules/vending/games.dm
@@ -8,6 +8,8 @@
/obj/item/toy/cards/deck/cas = 3,
/obj/item/toy/cards/deck/cas/black = 3)
contraband = list(/obj/item/dice/fudge = 9)
+ premium = list(/obj/item/melee/skateboard/pro = 3,
+ /obj/item/melee/skateboard/hoverboard = 1)
refill_canister = /obj/item/vending_refill/games
/obj/item/vending_refill/games
diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm
index ea15892a30..965648eb5a 100644
--- a/code/modules/vore/eating/bellymodes.dm
+++ b/code/modules/vore/eating/bellymodes.dm
@@ -60,187 +60,181 @@
var/sound/pred_digest = sound(get_sfx("digest_pred"))
var/sound/pred_death = sound(get_sfx("death_pred"))
-///////////////////////////// DM_HOLD /////////////////////////////
- if(digest_mode == DM_HOLD)
- return SSBELLIES_PROCESSED
+ switch(digest_mode)
+ if(DM_HOLD)
+ return SSBELLIES_PROCESSED
-//////////////////////////// DM_DIGEST ////////////////////////////
- else if(digest_mode == DM_DIGEST)
- if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //obvious.
- digest_mode = DM_NOISY
- return
+ if(DM_DIGEST)
+ if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //obvious.
+ digest_mode = DM_NOISY
+ return
- for (var/mob/living/M in contents)
- if(prob(25))
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
+ for (var/mob/living/M in contents)
+ if(prob(25))
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
- //Pref protection!
- if (!M.digestable || M.absorbed)
- continue
+ //Pref protection!
+ if (!M.digestable || M.absorbed)
+ continue
+
+ //Person just died in guts!
+ if(M.stat == DEAD)
+ var/digest_alert_owner = pick(digest_messages_owner)
+ var/digest_alert_prey = pick(digest_messages_prey)
+
+ //Replace placeholder vars
+ digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
+ digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
+ digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
+
+ digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
+ digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
+ digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
+
+ //Send messages
+ to_chat(owner, "[digest_alert_owner]")
+ to_chat(M, "[digest_alert_prey]")
+ M.visible_message("You watch as [owner]'s form loses its additions.")
+
+ owner.nutrition += 400 // so eating dead mobs gives you *something*.
+ play_sound = pick(pred_death)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_death)
+ M.stop_sound_channel(CHANNEL_PREYLOOP)
+ digestion_death(M)
+ owner.update_icons()
+ to_update = TRUE
+ continue
+
+
+ // Deal digestion damage (and feed the pred)
+ if(!(M.status_flags & GODMODE))
+ M.adjustFireLoss(digest_burn)
+ owner.nutrition += 1
+
+ //Contaminate or gurgle items
+ var/obj/item/T = pick(touchable_items)
+ if(istype(T))
+ if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
+ digest_item(T)
+
+ if(DM_HEAL)
+ for (var/mob/living/M in contents)
+ if(prob(25))
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
+ if(M.stat != DEAD)
+ if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth))
+ M.adjustBruteLoss(-3)
+ M.adjustFireLoss(-3)
+ owner.nutrition -= 5
+
+ //for when you just want people to squelch around
+ if(DM_NOISY)
+ if(prob(35))
+ for(var/mob/M in contents)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
+
+
+ if(DM_ABSORB)
+
+ for (var/mob/living/M in contents)
+
+ if(prob(10))//Less often than gurgles. People might leave this on forever.
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_digest)
+ play_sound = pick(pred_digest)
+
+ if(M.absorbed)
+ continue
+
+ if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them.
+ var/oldnutrition = (M.nutrition * 0.05)
+ M.nutrition = (M.nutrition * 0.95)
+ owner.nutrition += oldnutrition
+ else if(M.nutrition < 100) //When they're finally drained.
+ absorb_living(M)
+ to_update = TRUE
+
+ if(DM_UNABSORB)
+
+ for (var/mob/living/M in contents)
+ if(M.absorbed && owner.nutrition >= 100)
+ M.absorbed = FALSE
+ to_chat(M,"You suddenly feel solid again ")
+ to_chat(owner,"You feel like a part of you is missing.")
+ owner.nutrition -= 100
+ to_update = TRUE
+
+ //because dragons need snowflake guts
+ if(DM_DRAGON)
+ if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //imagine var editing this when you're a pacifist. smh
+ digest_mode = DM_NOISY
+ return
+
+ for (var/mob/living/M in contents)
+ if(prob(55)) //if you're hearing this, you're a vore ho anyway.
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+ last_hearcheck = world.time
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H?.client && (H in contents))
+ SEND_SOUND(H,prey_digest)
+
+ //No digestion protection for megafauna.
//Person just died in guts!
- if(M.stat == DEAD)
- var/digest_alert_owner = pick(digest_messages_owner)
- var/digest_alert_prey = pick(digest_messages_prey)
+ if(M.stat == DEAD)
+ var/digest_alert_owner = pick(digest_messages_owner)
+ var/digest_alert_prey = pick(digest_messages_prey)
- //Replace placeholder vars
- digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
- digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
- digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
+ //Replace placeholder vars
+ digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
+ digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
+ digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
- digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
- digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
- digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
+ digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
+ digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
+ digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
- //Send messages
- to_chat(owner, "[digest_alert_owner]")
- to_chat(M, "[digest_alert_prey]")
- M.visible_message("You watch as [owner]'s form loses its additions.")
-
- owner.nutrition += 400 // so eating dead mobs gives you *something*.
- play_sound = pick(pred_death)
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_death)
- M.stop_sound_channel(CHANNEL_PREYLOOP)
- digestion_death(M)
- owner.update_icons()
- to_update = TRUE
- continue
+ //Send messages
+ to_chat(owner, "[digest_alert_owner]")
+ to_chat(M, "[digest_alert_prey]")
+ M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.")
+ play_sound = pick(pred_death)
+ if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
+ SEND_SOUND(M,prey_death)
+ M.spill_organs(FALSE,TRUE,TRUE)
+ M.stop_sound_channel(CHANNEL_PREYLOOP)
+ digestion_death(M)
+ owner.update_icons()
+ to_update = TRUE
+ continue
- // Deal digestion damage (and feed the pred)
- if(!(M.status_flags & GODMODE))
- M.adjustFireLoss(digest_burn)
- owner.nutrition += 1
+ // Deal digestion damage (and feed the pred)
+ if(!(M.status_flags & GODMODE))
+ M.adjustFireLoss(digest_burn)
+ M.adjustToxLoss(2) // something something plasma based acids
+ M.adjustCloneLoss(1) // eventually this'll kill you if you're healing everything else, you nerds.
+ //Contaminate or gurgle items
+ var/obj/item/T = pick(touchable_items)
+ if(istype(T))
+ if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
+ digest_item(T)
- //Contaminate or gurgle items
- var/obj/item/T = pick(touchable_items)
- if(istype(T))
- if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
- digest_item(T)
-
-///////////////////////////// DM_HEAL /////////////////////////////
- if(digest_mode == DM_HEAL)
- for (var/mob/living/M in contents)
- if(prob(25))
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
- if(M.stat != DEAD)
- if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth))
- M.adjustBruteLoss(-3)
- M.adjustFireLoss(-3)
- owner.nutrition -= 5
-
-////////////////////////// DM_NOISY /////////////////////////////////
-//for when you just want people to squelch around
- if(digest_mode == DM_NOISY)
- if(prob(35))
- for(var/mob/M in contents)
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
-
-//////////////////////////// DM_ABSORB ////////////////////////////
- else if(digest_mode == DM_ABSORB)
-
- for (var/mob/living/M in contents)
-
- if(prob(10))//Less often than gurgles. People might leave this on forever.
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_digest)
- play_sound = pick(pred_digest)
-
- if(M.absorbed)
- continue
-
- if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them.
- var/oldnutrition = (M.nutrition * 0.05)
- M.nutrition = (M.nutrition * 0.95)
- owner.nutrition += oldnutrition
- else if(M.nutrition < 100) //When they're finally drained.
- absorb_living(M)
- to_update = TRUE
-
-//////////////////////////// DM_UNABSORB ////////////////////////////
- else if(digest_mode == DM_UNABSORB)
-
- for (var/mob/living/M in contents)
- if(M.absorbed && owner.nutrition >= 100)
- M.absorbed = FALSE
- to_chat(M,"You suddenly feel solid again ")
- to_chat(owner,"You feel like a part of you is missing.")
- owner.nutrition -= 100
- to_update = TRUE
-
-//////////////////////////DM_DRAGON /////////////////////////////////////
-//because dragons need snowflake guts
- if(digest_mode == DM_DRAGON)
- if(HAS_TRAIT(owner, TRAIT_PACIFISM)) //imagine var editing this when you're a pacifist. smh
- digest_mode = DM_NOISY
- return
-
- for (var/mob/living/M in contents)
- if(prob(55)) //if you're hearing this, you're a vore ho anyway.
- if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
- LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, owner))
- if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
- continue
- LAZYADD(hearing_mobs, H)
- last_hearcheck = world.time
- for(var/mob/living/H in hearing_mobs)
- if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
- SEND_SOUND(H,pred_digest)
- else if(H?.client && (H in contents))
- SEND_SOUND(H,prey_digest)
-
- //No digestion protection for megafauna.
-
- //Person just died in guts!
- if(M.stat == DEAD)
- var/digest_alert_owner = pick(digest_messages_owner)
- var/digest_alert_prey = pick(digest_messages_prey)
-
- //Replace placeholder vars
- digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
- digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
- digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
-
- digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
- digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
- digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
-
- //Send messages
- to_chat(owner, "[digest_alert_owner]")
- to_chat(M, "[digest_alert_prey]")
- M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.")
- play_sound = pick(pred_death)
- if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES)
- SEND_SOUND(M,prey_death)
- M.spill_organs(FALSE,TRUE,TRUE)
- M.stop_sound_channel(CHANNEL_PREYLOOP)
- digestion_death(M)
- owner.update_icons()
- to_update = TRUE
- continue
-
-
- // Deal digestion damage (and feed the pred)
- if(!(M.status_flags & GODMODE))
- M.adjustFireLoss(digest_burn)
- M.adjustToxLoss(2) // something something plasma based acids
- M.adjustCloneLoss(1) // eventually this'll kill you if you're healing everything else, you nerds.
- //Contaminate or gurgle items
- var/obj/item/T = pick(touchable_items)
- if(istype(T))
- if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
- digest_item(T)
-
-/////////////////////////// Make any noise ///////////////////////////
+ /////////////////////////// Make any noise ///////////////////////////
if(play_sound)
if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
@@ -252,7 +246,7 @@
for(var/mob/M in hearing_mobs) //so we don't fill the whole room with the sound effect
if(M && M.client && (isturf(M.loc) || (M.loc != src.contents))) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check
M.playsound_local(owner.loc, play_sound, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF)
- //these are all external sound triggers now, so it's ok.
+ //these are all external sound triggers now, so it's ok.
if(to_update)
for(var/mob/living/M in contents)
if(M.client)
@@ -260,4 +254,4 @@
if(owner.client)
owner.updateVRPanel()
- return SSBELLIES_PROCESSED
\ No newline at end of file
+ return SSBELLIES_PROCESSED
diff --git a/icons/mob/actions/actions_vehicle.dmi b/icons/mob/actions/actions_vehicle.dmi
index cee683c60d..0d8d322653 100644
Binary files a/icons/mob/actions/actions_vehicle.dmi and b/icons/mob/actions/actions_vehicle.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 4ca4a351c6..1cd090a3e9 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 8546a78a73..24c9a2d777 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index acf6bb4021..6ee7873469 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi
index 67079de3e2..8d5d9208ab 100644
Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ
diff --git a/sound/vehicles/skateboard_ollie.ogg b/sound/vehicles/skateboard_ollie.ogg
new file mode 100644
index 0000000000..5f0f2fc30b
Binary files /dev/null and b/sound/vehicles/skateboard_ollie.ogg differ
diff --git a/sound/vehicles/skateboard_roll.ogg b/sound/vehicles/skateboard_roll.ogg
new file mode 100644
index 0000000000..326c175d77
Binary files /dev/null and b/sound/vehicles/skateboard_roll.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 7eff305581..8187a4db16 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -156,6 +156,7 @@
#include "code\__HELPERS\text_vr.dm"
#include "code\__HELPERS\time.dm"
#include "code\__HELPERS\type2type.dm"
+#include "code\__HELPERS\type_processing.dm"
#include "code\__HELPERS\typelists.dm"
#include "code\__HELPERS\unsorted.dm"
#include "code\__HELPERS\vector.dm"
@@ -1231,6 +1232,7 @@
#include "code\modules\admin\stickyban.dm"
#include "code\modules\admin\topic.dm"
#include "code\modules\admin\whitelist.dm"
+#include "code\modules\admin\callproc\callproc.dm"
#include "code\modules\admin\DB_ban\functions.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminjump.dm"
@@ -1254,8 +1256,6 @@
#include "code\modules\admin\verbs\map_template_loadverb.dm"
#include "code\modules\admin\verbs\mapping.dm"
#include "code\modules\admin\verbs\maprotation.dm"
-#include "code\modules\admin\verbs\massmodvar.dm"
-#include "code\modules\admin\verbs\modifyvariables.dm"
#include "code\modules\admin\verbs\one_click_antag.dm"
#include "code\modules\admin\verbs\onlyone.dm"
#include "code\modules\admin\verbs\panicbunker.dm"
@@ -1269,6 +1269,16 @@
#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm"
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
+#include "code\modules\admin\view_variables\admin_delete.dm"
+#include "code\modules\admin\view_variables\debug_variables.dm"
+#include "code\modules\admin\view_variables\get_variables.dm"
+#include "code\modules\admin\view_variables\mark_datum.dm"
+#include "code\modules\admin\view_variables\mass_edit_variables.dm"
+#include "code\modules\admin\view_variables\modify_variables.dm"
+#include "code\modules\admin\view_variables\topic.dm"
+#include "code\modules\admin\view_variables\topic_basic.dm"
+#include "code\modules\admin\view_variables\topic_list.dm"
+#include "code\modules\admin\view_variables\view_variables.dm"
#include "code\modules\antagonists\_common\antag_datum.dm"
#include "code\modules\antagonists\_common\antag_helpers.dm"
#include "code\modules\antagonists\_common\antag_hud.dm"
diff --git a/tgui/package-lock.json b/tgui/package-lock.json
index d2567aba36..1de061b1c5 100644
--- a/tgui/package-lock.json
+++ b/tgui/package-lock.json
@@ -5480,9 +5480,9 @@
}
},
"minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-rIqbOrKb8GJmx/5bc2M0QchhUouMXSpd1RTclXsB41JdL+VtnojfaJR+h7F9k18/4kHUsBFgk80Uk+q569vjPA=="
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.3.tgz",
+ "integrity": "sha512-+bMdgqjMN/Z77a6NlY/I3U5LlRDbnmaAk6lDveAPKwSpcPM4tKAuYsvYF8xjhOPXhOYGe/73vVLVez5PW+jqhw=="
},
"mixin-deep": {
"version": "1.3.2",
diff --git a/tgui/package.json b/tgui/package.json
index 85d47ecfe7..0e47e25e76 100644
--- a/tgui/package.json
+++ b/tgui/package.json
@@ -35,7 +35,7 @@
"html5shiv": "3.7.3",
"ie8": "0.8.1",
"lodash": "^4.17.15",
- "minimist": "1.2.2",
+ "minimist": "1.2.3",
"paths-js": "0.4.10",
"pleeease-filters": "2.0.0",
"postcss": "7.0.18",