"
@@ -1051,7 +1047,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
ResetJobs()
SetChoices(user)
if("random")
- if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_CIVILIAN)
+ if(alternate_option == GET_RANDOM_JOB || alternate_option == BE_ASSISTANT)
alternate_option += 1
else if(alternate_option == RETURN_TO_LOBBY)
alternate_option = 0
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index dc1504b80b6..40c29c1d991 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -134,7 +134,7 @@
update_icon()
/obj/item/clothing/gloves/fingerless/rapid
- name = "Gloves of the north star"
+ name = "Gloves of the North Star"
desc = "Just looking at these fills you with an urge to beat the shit out of people."
/obj/item/clothing/gloves/fingerless/rapid/Touch(mob/living/target, proximity = TRUE)
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 4ee5182844d..22f293aedfc 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -8,7 +8,7 @@
gas_transfer_coefficient = 0.90
put_on_delay = 20
var/resist_time = 0 //deciseconds of how long you need to gnaw to get rid of the gag, 0 to make it impossible to remove
- var/mute = MUTE_ALL
+ var/mute = MUZZLE_MUTE_ALL
var/security_lock = FALSE // Requires brig access to remove 0 - Remove as normal
var/locked = FALSE //Indicates if a mask is locked, should always start as 0.
species_fit = list("Vox")
@@ -93,7 +93,7 @@
item_state = null
w_class = WEIGHT_CLASS_TINY
resist_time = 150
- mute = MUTE_MUFFLE
+ mute = MUZZLE_MUTE_MUFFLE
flags = DROPDEL
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
sprite_sheets = list(
@@ -117,7 +117,7 @@
name = "safety muzzle"
desc = "A muzzle designed to prevent biting."
resist_time = 600
- mute = MUTE_NONE
+ mute = MUZZLE_MUTE_NONE
security_lock = TRUE
locked = FALSE
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 141d9ed0bf6..a229b72f745 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -1370,4 +1370,13 @@
/obj/item/clothing/suit/fluff/vetcoat/navy //Furasian: Fillmoore Grayson
icon_state = "alchemistcoatnavy"
- item_state = "alchemistcoatnavy"
\ No newline at end of file
+ item_state = "alchemistcoatnavy"
+
+/obj/item/clothing/accessory/medal/fluff/panzermedal //PanzerSkull: GRN-DER
+ name = "Cross of Valor"
+ desc = "A medal from the bygone Asteroid Wars. Its Ruby shines with a strange intensity."
+ icon = 'icons/obj/custom_items.dmi'
+ icon_state = "panzermedal"
+ item_state = "panzermedal"
+ item_color = "panzermedal"
+ slot_flags = SLOT_TIE
\ No newline at end of file
diff --git a/code/modules/economy/Economy.dm b/code/modules/economy/Economy.dm
index 028c2810ae7..57d76e98c5c 100644
--- a/code/modules/economy/Economy.dm
+++ b/code/modules/economy/Economy.dm
@@ -38,7 +38,7 @@
#define MINERALS 8
#define EMERGENCY 9
-#define GAS 10
+#define EGAS 10
#define MAINTENANCE 11
#define ELECTRICAL 12
#define ROBOTICS 13
diff --git a/code/modules/economy/Economy_Events.dm b/code/modules/economy/Economy_Events.dm
index c1e5b95273e..10e0d574f98 100644
--- a/code/modules/economy/Economy_Events.dm
+++ b/code/modules/economy/Economy_Events.dm
@@ -29,16 +29,16 @@
if(INDUSTRIAL_ACCIDENT)
dearer_goods = list(EMERGENCY, BIOMEDICAL, ROBOTICS)
if(BIOHAZARD_OUTBREAK)
- dearer_goods = list(BIOMEDICAL, GAS)
+ dearer_goods = list(BIOMEDICAL, EGAS)
if(PIRATES)
dearer_goods = list(SECURITY, MINERALS)
if(CORPORATE_ATTACK)
dearer_goods = list(SECURITY, MAINTENANCE)
if(ALIEN_RAIDERS)
dearer_goods = list(BIOMEDICAL, ANIMALS)
- cheaper_goods = list(GAS, MINERALS)
+ cheaper_goods = list(EGAS, MINERALS)
if(AI_LIBERATION)
- dearer_goods = list(EMERGENCY, GAS, MAINTENANCE)
+ dearer_goods = list(EMERGENCY, EGAS, MAINTENANCE)
if(MOURNING)
cheaper_goods = list(MINERALS, MAINTENANCE)
if(CULT_CELL_REVEALED)
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index b514924abfa..cf2e3621498 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -11,7 +11,7 @@
/datum/event/disease_outbreak/start()
if(!virus_type)
- virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
+ virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
if(issmall(H)) //don't infect monkies; that's a waste
diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm
index c5a5873afa0..d11a1227ddf 100644
--- a/code/modules/events/infestation.dm
+++ b/code/modules/events/infestation.dm
@@ -107,7 +107,6 @@
#undef LOC_HYDRO
#undef LOC_VAULT
#undef LOC_TECH
-#undef LOC_TACTICAL
#undef VERM_MICE
#undef VERM_LIZARDS
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index 584fdd5b93c..412c5407ddc 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -1,6 +1,6 @@
//////////////////////////////
-// Fish Tanks! //
+// Fish Tanks //
//////////////////////////////
@@ -9,44 +9,41 @@
desc = "So generic, it might as well have no description at all."
icon = 'icons/obj/fish_items.dmi'
icon_state = "tank1"
- density = 0
- anchored = 0
+ density = FALSE
+ anchored = FALSE
pass_flags = 0
var/tank_type = "" // Type of aquarium, used for icon updating
var/water_capacity = 0 // Number of units the tank holds (varies with tank type)
var/water_level = 0 // Number of units currently in the tank (new tanks start empty)
var/light_switch = 0 // 0 = off, 1 = on (off by default)
- var/filth_level = 0.0 // How dirty the tank is (max 10)
+ var/filth_level = 0 // How dirty the tank is (max 10)
var/lid_switch = 0 // 0 = open, 1 = closed (open by default)
var/max_fish = 0 // How many fish the tank can support (varies with tank type, 1 fish per 50 units sounds reasonable)
var/food_level = 0 // Amount of fishfood floating in the tank (max 10)
var/fish_count = 0 // Number of fish in the tank
- var/list/fish_list = null // Tracks the current types of fish in the tank
+ var/list/fish_list = list() // Tracks the current types of fish in the tank
var/egg_count = 0 // How many fish eggs can be harvested from the tank (capped at the max_fish value)
- var/list/egg_list = null // Tracks the current types of harvestable eggs in the tank
+ var/list/egg_list = list() // Tracks the current types of harvestable eggs in the tank
- var/has_lid = 0 // 0 if the tank doesn't have a lid/light, 1 if it does
- var/max_health = 0 // Can handle a couple hits
- var/cur_health = 0 // Current health, starts at max_health
- var/leaking = 0 // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default)
+ var/has_lid = FALSE // 0 if the tank doesn't have a lid/light, 1 if it does
+ var/leaking = FALSE // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default)
var/shard_count = 0 // Number of glass shards to salvage when broken (1 less than the number of sheets to build the tank)
/obj/machinery/fishtank/bowl
name = "fish bowl"
desc = "A small bowl capable of housing a single fish, commonly found on desks. This one has a tiny treasure chest in it!"
icon_state = "bowl1"
- density = 0 // Small enough to not block stuff
- anchored = 0 // Small enough to move even when filled
+ density = FALSE // Small enough to not block stuff
+ anchored = FALSE // Small enough to move even when filled
pass_flags = PASSTABLE | LETPASSTHROW // Just like at the county fair, you can't seem to throw the ball in to win the goldfish, and it's small enough to pull onto a table
tank_type = "bowl"
water_capacity = 50 // Not very big, therefore it can't hold much
max_fish = 1 // What a lonely fish
- has_lid = 0
- max_health = 15 // Not very sturdy
- cur_health = 15
+ has_lid = FALSE
+ max_integrity = 15 // Not very sturdy
shard_count = 0 // No salvageable shards
/obj/machinery/fishtank/tank
@@ -54,17 +51,16 @@
desc = "A large glass tank designed to house aquatic creatures. Contains an integrated water circulation system."
icon = 'icons/obj/fish_items.dmi'
icon_state = "tank1"
- density = 1
- anchored = 1
+ density = TRUE
+ anchored = TRUE
pass_flags = LETPASSTHROW
tank_type = "tank"
water_capacity = 200 // Decent sized, holds almost 2 full buckets
max_fish = 4 // Room for a few fish
- has_lid = 1
- max_health = 50 // Average strength, will take a couple hits from a toolbox.
- cur_health = 50
+ has_lid = TRUE
+ max_integrity = 50 // Average strength, will take a couple hits from a toolbox.
shard_count = 2
@@ -72,17 +68,16 @@
name = "wall aquarium"
desc = "This aquarium is massive! It completely occupies the same space as a wall, and looks very sturdy too!"
icon_state = "wall1"
- density = 1
- anchored = 1
+ density = TRUE
+ anchored = TRUE
pass_flags = 0 // This thing is the size of a wall, you can't throw past it.
tank_type = "wall"
water_capacity = 500 // This thing fills an entire tile, it holds a lot.
max_fish = 10 // Plenty of room for a lot of fish
- has_lid = 1
- max_health = 100 // This thing is a freaking wall, it can handle abuse.
- cur_health = 100
+ has_lid = TRUE
+ max_integrity = 100 // This thing is a freaking wall, it can handle abuse.
shard_count = 3
@@ -94,9 +89,10 @@
set name = "Toggle Tank Lid"
set category = "Object"
set src in view(1)
- toggle_lid(usr)
-/obj/machinery/fishtank/proc/toggle_lid(var/mob/living/user)
+ toggle_lid()
+
+/obj/machinery/fishtank/proc/toggle_lid()
lid_switch = !lid_switch
update_icon()
@@ -104,12 +100,13 @@
set name = "Toggle Tank Light"
set category = "Object"
set src in view(1)
- toggle_light(usr)
-/obj/machinery/fishtank/proc/toggle_light(var/mob/living/user)
+ toggle_light()
+
+/obj/machinery/fishtank/proc/toggle_light()
light_switch = !light_switch
if(light_switch)
- set_light(2,2,"#a0a080")
+ set_light(2, 2, "#a0a080")
else
adjust_tank_light()
@@ -119,8 +116,6 @@
/obj/machinery/fishtank/New()
..()
- fish_list = new/list()
- egg_list = new/list()
if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then
verbs -= /obj/machinery/fishtank/verb/toggle_lid_verb
verbs -= /obj/machinery/fishtank/verb/toggle_light_verb
@@ -154,7 +149,8 @@
overlays += "over_leak_[leaking]" //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak
//Update water overlay
- if(water_level == 0) return //Skip the rest of this if there is no water in the aquarium
+ if(!water_level)
+ return //Skip the rest of this if there is no water in the aquarium
var/water_type = "_clean" //Default to clean water
if(filth_level > 5) water_type = "_dirty" //Show dirty water above filth_level 5 (breeding threshold)
if(water_level > (water_capacity * 0.85)) //Show full if the water_level is over 85% of water_capacity
@@ -162,15 +158,13 @@
else if(water_level > (water_capacity * 0.35)) //Show half-full if the water_level is over 35% of water_capacity
overlays += "over_[tank_type]_half[water_type]"
- return
-
//////////////////////////////
// PROCESS PROC //
//////////////////////////////
//Stops atmos from passing wall tanks, since they are effectively full-windows.
-/obj/machinery/fishtank/wall/CanAtmosPass(var/turf/T)
- return 0
+/obj/machinery/fishtank/wall/CanAtmosPass(turf/T)
+ return FALSE
/obj/machinery/fishtank/process()
//Start by counting fish in the tank
@@ -238,9 +232,7 @@
adjust_tank_light()
/obj/machinery/fishtank/proc/adjust_tank_light()
- if(light_switch) //tank light overrides fish lights
- return
- else
+ if(!light_switch) //tank light overrides fish lights
var/glo_light = 0
for(var/datum/fish/fish in fish_list)
if(istype(fish, /datum/fish/glofish))
@@ -261,19 +253,13 @@
food_level = min(10, max(0, food_level + amount))
/obj/machinery/fishtank/proc/check_health()
- //Max value check
- if(cur_health > max_health) //Cur_health cannot exceed max_health, set it to max_health if it does
- cur_health = max_health
//Leaking status check
- if(cur_health <= (max_health * 0.25)) //Major leak at or below 25% health (-10 water/cycle)
+ if(obj_integrity <= (max_integrity * 0.25)) //Major leak at or below 25% health (-10 water/cycle)
leaking = 2
- else if(cur_health <= (max_health * 0.5)) //Minor leak at or below 50% health (-1 water/cycle)
+ else if(obj_integrity <= (max_integrity * 0.5)) //Minor leak at or below 50% health (-1 water/cycle)
leaking = 1
else //Not leaking above 50% health
leaking = 0
- //Destruction check
- if(cur_health <= 0) //The tank is broken, destroy it
- destroy()
/obj/machinery/fishtank/proc/kill_fish(datum/fish/fish_type = null)
//Check if we were passed a fish to kill, otherwise kill a random one
@@ -292,12 +278,12 @@
fish_list.Add(fish_type) //Add a fish of the specified type
fish_count++ //Increase fish_count to reflect the introduction of a fish, so the everything else works fine
//Announce the new fish
- visible_message("A new [fish_type.fish_name] has hatched in \the [src]!")
+ visible_message("A new [fish_type.fish_name] has hatched in [src]!")
//Null type fish are dud eggs, give a message to inform the player
else
to_chat(usr, "The eggs disolve in the water. They were duds!")
-/obj/machinery/fishtank/proc/harvest_eggs(var/mob/user)
+/obj/machinery/fishtank/proc/harvest_eggs(mob/user)
if(!egg_count) //Can't harvest non-existant eggs
return
@@ -312,62 +298,39 @@
egg_list.Cut() //Destroy any excess eggs, clearing the egg_list
-/obj/machinery/fishtank/proc/harvest_fish(var/mob/user)
- if(fish_count <= 0) //Can't catch non-existant fish!
- to_chat(usr, "There are no fish in \the [src] to catch!")
+/obj/machinery/fishtank/proc/harvest_fish(mob/user)
+ if(fish_count <= 0) //Can't catch non-existant fish!
+ to_chat(user, "There are no fish in [src] to catch!")
return
var/list/fish_names_list = list()
for(var/datum/fish/fish_type in fish_list)
fish_names_list += list("[fish_type.fish_name]" = fish_type)
var/caught_fish = input("Select a fish to catch.", "Fishing") as null|anything in fish_names_list //Select a fish from the tank
if(fish_count <= 0)
- to_chat(usr, "There are no fish in \the [src] to catch!")
+ to_chat(user, "There are no fish in [src] to catch!")
return
else if(caught_fish)
- user.visible_message("[user.name] harvests \a [caught_fish] from \the [src].", "You scoop \a [caught_fish] out of \the [src].")
+ user.visible_message("[user.name] harvests \a [caught_fish] from [src].", "You scoop \a [caught_fish] out of [src].")
var/datum/fish/fish_type = fish_names_list[caught_fish]
var/fish_item = fish_type.fish_item
if(fish_item)
new fish_item(get_turf(user)) //Spawn the appropriate fish_item at the user's feet.
kill_fish(fish_type) //Kill the caught fish from the tank
-
-/obj/machinery/fishtank/proc/destroy(var/deconstruct = 0)
- var/turf/T = get_turf(src) //Store the tank's turf for atmos updating after deletion of tank
- if(!deconstruct) //Check if we are deconstructing or breaking the tank
- var/shards_left = shard_count
- while(shards_left > 0) //Produce the appropriate number of glass shards
- new /obj/item/shard(get_turf(src))
- shards_left --
- if(water_level) //Spill any water that was left in the tank when it broke
- spill_water()
- else //We are deconstructing, make glass sheets instead of shards
- var/sheets = shard_count + 1 //Deconstructing it salvages all the glass used to build the tank
- new /obj/item/stack/sheet/glass(get_turf(src), sheets) //Produce the appropriate number of glass sheets, in a single stack
- qdel(src) //qdel the tank and it's contents
- T.air_update_turf(1) //Update the air for the turf, to avoid permanent atmos sealing with wall tanks
-
+ //Update the air for the turf, to avoid permanent atmos sealing with wall tanks
/obj/machinery/fishtank/proc/spill_water()
+ var/turf/simulated/T = get_turf(src)
switch(tank_type)
if("bowl") //Fishbowl: Wets it's own tile
- var/turf/T = get_turf(src)
- if(!istype(T, /turf/simulated)) return
- var/turf/simulated/S = T
- S.MakeSlippery()
+ if(istype(T))
+ T.MakeSlippery()
if("tank") //Fishtank: Wets it's own tile and the 4 adjacent tiles (cardinal directions)
- var/turf/ST = get_turf(src)
- if(istype(ST, /turf/simulated))
- var/turf/simulated/ST2 = ST
- ST2.MakeSlippery()
- var/list/L = ST.CardinalTurfs()
- for(var/turf/T in L)
- if(!istype(T, /turf/simulated)) continue
- var/turf/simulated/S = T
- S.MakeSlippery()
+ if(istype(T))
+ T.MakeSlippery()
+ for(var/turf/simulated/ST in T.CardinalTurfs())
+ ST.MakeSlippery()
if("wall") //Wall-tank: Wets it's own tile and the surrounding 8 tiles (3x3 square)
- for(var/turf/T in spiral_range_turfs(1, src.loc))
- if(!istype(T, /turf/simulated)) continue
- var/turf/simulated/S = T
- S.MakeSlippery()
+ for(var/turf/simulated/ST in spiral_range_turfs(1, loc))
+ ST.MakeSlippery()
/obj/machinery/fishtank/proc/breed_fish()
var/list/breed_candidates = fish_list.Copy()
@@ -412,20 +375,20 @@
examine_message += "Water level: "
- if(water_level == 0)
- examine_message += "\The [src] is empty! "
+ if(!water_level)
+ examine_message += "[src] is empty! "
else if(water_level < water_capacity * 0.1)
- examine_message += "\The [src] is nearly empty! "
+ examine_message += "[src] is nearly empty! "
else if(water_level <= water_capacity * 0.25)
- examine_message += "\The [src] is about one-quarter filled. "
+ examine_message += "[src] is about one-quarter filled. "
else if(water_level <= water_capacity * 0.5)
- examine_message += "\The [src] is about half filled. "
+ examine_message += "[src] is about half filled. "
else if(water_level <= water_capacity * 0.75)
- examine_message += "\The [src] is about three-quarters filled. "
+ examine_message += "[src] is about three-quarters filled. "
else if(water_level < water_capacity)
- examine_message += "\The [src] is nearly full! "
+ examine_message += "[src] is nearly full! "
else if(water_level == water_capacity)
- examine_message += "\The [src] is full! "
+ examine_message += "[src] is full! "
examine_message += " Cleanliness level: "
@@ -467,7 +430,7 @@
//Report the number and types of live fish if there is water in the tank
if(fish_count == 0)
- examine_message += "\The [src] doesn't contain any live fish. "
+ examine_message += "[src] doesn't contain any live fish. "
else
//Build a message reporting the types of fish
var/fish_num = fish_count
@@ -483,7 +446,7 @@
message +=", "
message +="." //No more fish, end the message with a period
//Display the number of fish and previously constructed message
- examine_message += "\The [src] contains [fish_count] live fish. [message] "
+ examine_message += "[src] contains [fish_count] live fish. [message] "
examine_message += " "
@@ -498,12 +461,16 @@
examine_message += " "
//Report if the tank is leaking/cracked
- if(water_level > 0) //Tank has water, so it's actually leaking
- if(leaking == 1) examine_message += "\The [src] is leaking."
- if(leaking == 2) examine_message += "\The [src] is leaking profusely!"
+ if(water_level) //Tank has water, so it's actually leaking
+ if(leaking == 1)
+ examine_message += "[src] is leaking."
+ if(leaking == 2)
+ examine_message += "[src] is leaking profusely!"
else //No water, report the cracks instead
- if(leaking == 1) examine_message += "\The [src] is cracked."
- if(leaking == 2) examine_message += "\The [src] is nearly shattered!"
+ if(leaking == 1)
+ examine_message += "[src] is cracked."
+ if(leaking == 2)
+ examine_message += "[src] is nearly shattered!"
//Finally, report the full examine_message constructed from the above reports
@@ -514,127 +481,113 @@
// ATACK PROCS //
//////////////////////////////
-/obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M as mob)
+/obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M)
if(istype(M, /mob/living/simple_animal/pet/cat))
if(M.a_intent == INTENT_HELP) //Cats can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
- M.visible_message("[M.name] stares at into \the [src] while sitting perfectly still.", "The lid is closed, so you stare into \the [src] intently.")
+ M.visible_message("[M.name] stares at into [src] while sitting perfectly still.", "The lid is closed, so you stare into [src] intently.")
else
if(fish_count) //Tank must actually have fish to try catching one
- M.visible_message("[M.name] leaps up onto \the[src] and attempts to fish through the opening!", "You jump up onto \the [src] and begin fishing through the opening!")
- spawn(10)
- if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens
- M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!")
- if(istype(M, /mob/living/simple_animal/pet/cat/Syndi))
- var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- else //No water or didn't slip, get that fish!
- M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
- kill_fish() //Kill a random fish
- M.health = M.maxHealth //Eating fish heals the predator
+ M.visible_message("[M.name] leaps up onto [src] and attempts to fish through the opening!", "You jump up onto [src] and begin fishing through the opening!")
+ if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens
+ M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!")
+ if(istype(M, /mob/living/simple_animal/pet/cat/Syndi))
+ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
+ s.set_up(3, 1, src)
+ s.start()
+ else //No water or didn't slip, get that fish!
+ M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
+ kill_fish() //Kill a random fish
+ M.health = M.maxHealth //Eating fish heals the predator
else
- to_chat(usr, "There are no fish in [src]!")
+ to_chat(M, "There are no fish in [src]!")
else
- attack_generic(M, M.harm_intent_damage)
+ return ..()
else if(istype(M, /mob/living/simple_animal/hostile/bear))
if(M.a_intent == INTENT_HELP) //Bears can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
- M.visible_message("[M.name] scrapes it's claws along \the [src]'s lid.", "The lid is closed, so you scrape your claws against \the [src]'s lid.")
+ M.visible_message("[M.name] scrapes it's claws along [src]'s lid.", "The lid is closed, so you scrape your claws against [src]'s lid.")
else
if(fish_count) //Tank must actually have fish to try catching one
- M.visible_message("[M.name] reaches into \the[src] and attempts to fish through the opening!", "You reach into \the [src] and begin fishing through the opening!")
- spawn(5)
- if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail
- M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!")
- else //No water or didn't slip, get that fish!
- M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
- kill_fish() //Kill a random fish
- M.health = M.maxHealth //Eating fish heals the predator
+ M.visible_message("[M.name] reaches into [src] and attempts to fish through the opening!", "You reach into [src] and begin fishing through the opening!")
+ if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail
+ M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!")
+ else //No water or didn't slip, get that fish!
+ M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
+ kill_fish() //Kill a random fish
+ M.health = M.maxHealth //Eating fish heals the predator
else
- to_chat(usr, "There are no fish in [src]!")
+ to_chat(M, "There are no fish in [src]!")
else
- attack_generic(M, M.harm_intent_damage)
+ return ..()
else
- if(M.melee_damage_upper > 0) //If the simple_animal has a melee_damage_upper defined, use that for the damage
- attack_generic(M, M.melee_damage_upper)
- else if(M.a_intent == INTENT_HARM) //Let any simple_animal try to break tanks when on harm intent
- if(M.harm_intent_damage <= 0) return //If it doesn't do damage, don't bother with the attack
- attack_generic(M, M.harm_intent_damage)
- check_health()
+ return ..()
-/obj/machinery/fishtank/attack_alien(mob/living/user as mob)
- if(islarva(user)) return
- attack_generic(user, 15)
-
-/obj/machinery/fishtank/attack_slime(mob/living/user as mob)
- var/mob/living/carbon/slime/S = user
- if(!S.is_adult)
- return
- attack_generic(user, rand(10, 15))
-
-/obj/machinery/fishtank/attack_hand(mob/user as mob)
- if(HULK in user.mutations)
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
- user.visible_message("[user] smashes through [src]!")
- destroy()
- else if(usr.a_intent == INTENT_HARM)
- user.changeNext_move(CLICK_CD_MELEE)
+/obj/machinery/fishtank/attack_hand(mob/user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ if(user.a_intent == INTENT_HARM)
playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1)
- usr.visible_message("[usr.name] bangs against the [src.name]!", \
- "You bang against the [src.name]!", \
+ user.visible_message("[user.name] bangs against the [name]!", \
+ "You bang against the [name]!", \
"You hear a banging sound.")
else
- user.changeNext_move(CLICK_CD_MELEE)
- playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1)
- usr.visible_message("[usr.name] taps on the [src.name].", \
- "You tap on the [src.name].", \
+ playsound(loc, 'sound/effects/glassknock.ogg', 80, 1)
+ user.visible_message("[user.name] taps on the [name].", \
+ "You tap on the [name].", \
"You hear a knocking sound.")
- return
-/obj/machinery/fishtank/proc/hit(var/damage, var/sound_effect = 1)
- cur_health = max(0, cur_health - damage)
- if(sound_effect)
- playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
- check_health()
-
-/obj/machinery/fishtank/attack_generic(mob/living/user, damage = 0) //used by attack_alien, attack_animal, and attack_slime
- user.changeNext_move(CLICK_CD_MELEE)
- user.do_attack_animation(src)
- cur_health -= damage
- if(cur_health <= 0)
- user.visible_message("[user] smashes through \the [src]!")
- destroy()
- else //for nicer text~
- user.visible_message("[user] smashes into \the [src]!")
- playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
+/obj/machinery/fishtank/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
+ . = ..()
+ if(.) //received damage
check_health()
-/obj/machinery/fishtank/attackby(var/obj/item/O, var/mob/user as mob)
+/obj/machinery/fishtank/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
+ switch(damage_type)
+ if(BRUTE)
+ if(damage_amount)
+ playsound(src, 'sound/effects/Glasshit.ogg', 75, 1)
+ else
+ playsound(src, 'sound/weapons/tap.ogg', 50, 1)
+ if(BURN)
+ playsound(src, 'sound/items/Welder.ogg', 100, 1)
+
+/obj/machinery/fishtank/deconstruct(disassembled = TRUE)
+ if(QDELETED(src))
+ return
+ if(!disassembled)
+ playsound(src, "shatter", 70, 1)
+ for(var/i in 1 to shard_count) //Produce the appropriate number of glass shards
+ var/obj/item/shard/S = new /obj/item/shard(get_turf(src))
+ transfer_fingerprints_to(S)
+ if(water_level) //Spill any water that was left in the tank when it broke
+ spill_water()
+ else //We are deconstructing, make glass sheets instead of shards
+ new /obj/item/stack/sheet/glass(get_turf(src), shard_count + 1) //Produce the appropriate number of glass sheets, in a single stack
+ qdel(src)
+
+/obj/machinery/fishtank/attackby(obj/item/O, mob/user)
//Welders repair damaged tanks on help intent, damage on all others
- if(istype(O, /obj/item/weldingtool))
+ if(iswelder(O))
var/obj/item/weldingtool/W = O
if(user.a_intent == INTENT_HELP)
if(W.isOn())
- if(cur_health < max_health)
+ if(obj_integrity < max_integrity)
playsound(loc, W.usesound, 50, 1)
- to_chat(usr, "You repair some of the cracks on \the [src].")
- cur_health += 20
+ to_chat(user, "You repair some of the cracks on [src].")
+ obj_integrity = min(obj_integrity + 20, max_integrity)
check_health()
else
- to_chat(usr, "There is no damage to fix!")
+ to_chat(user, "There is no damage to fix!")
else
- if(cur_health < max_health)
- to_chat(usr, "[W.name] must be on to repair this damage.")
+ if(obj_integrity < max_integrity)
+ to_chat(user, "[W] must be on to repair this damage.")
else
- user.changeNext_move(CLICK_CD_MELEE)
- hit(W.force)
- return
+ return ..()
//Open reagent containers add and remove water
- if(O.is_open_container())
+ else if(O.is_open_container())
if(istype(O, /obj/item/reagent_containers/glass))
if(lid_switch)
- to_chat(usr, "Open the lid on \the [src] first!")
+ to_chat(user, "Open the lid on [src] first!")
return
var/obj/item/reagent_containers/glass/C = O
//Containers with any reagents will get dumped in
@@ -652,57 +605,52 @@
C.reagents.clear_reagents()
else
if(water_level == water_capacity)
- to_chat(usr, "[src] is already full!")
- return
+ to_chat(user, "[src] is already full!")
else
message = "The filtration process purifies the water, raising the water level."
if((water_level + water_value) == water_capacity)
- message += " You filled \the [src] to the brim!"
+ message += " You filled [src] to the brim!"
if((water_level + water_value) > water_capacity)
- message += " You overfilled \the [src] and some water runs down the side, wasted."
+ message += " You overfilled [src] and some water runs down the side, wasted."
C.reagents.clear_reagents()
adjust_water_level(water_value)
- user.visible_message("[user.name] pours the contents of [C.name] into \the [src].", "[message]")
- return
+ user.visible_message("[user.name] pours the contents of [C.name] into [src].", "[message]")
//Empty containers will scoop out water, filling the container as much as possible from the water_level
else
- if(water_level == 0)
- to_chat(usr, "[src] is empty!")
+ if(!water_level)
+ to_chat(user, "[src] is empty!")
else
if(water_level >= C.volume) //Enough to fill the container completely
C.reagents.add_reagent("fishwater", C.volume)
adjust_water_level(-C.volume)
- user.visible_message("[user.name] scoops out some water from \the [src].", "You completely fill [C.name] from \the [src].")
+ user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [C.name] from [src].")
else //Fill the container as much as possible with the water_level
C.reagents.add_reagent("fishwater", water_level)
adjust_water_level(-water_level)
- user.visible_message("[user.name] scoops out some water from \the [src].", "You fill [C.name] with the last of the water in \the [src].")
- return
+ user.visible_message("[user.name] scoops out some water from [src].", "You fill [C.name] with the last of the water in [src].")
//Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process
- if(istype(O, /obj/item/wrench))
- if(water_level == 0)
- to_chat(usr, "Now disassembling [src].")
- playsound(src.loc, O.usesound, 50, 1)
+ else if(iswrench(O))
+ if(!water_level)
+ to_chat(user, "Now disassembling [src].")
+ playsound(loc, O.usesound, 50, 1)
if(do_after(user, 50 * O.toolspeed, target = src))
- destroy(1)
+ deconstruct(TRUE)
else
- to_chat(usr, "[src] must be empty before you disassemble it!")
- return
+ to_chat(user, "[src] must be empty before you disassemble it!")
//Fish eggs
else if(istype(O, /obj/item/fish_eggs))
var/obj/item/fish_eggs/egg = O
//Don't add eggs if there is no water (they kinda need that to live)
- if(water_level == 0)
- to_chat(usr, "[src] has no water; [egg.name] won't hatch without water!")
+ if(!water_level)
+ to_chat(user, "[src] has no water; [egg.name] won't hatch without water!")
else
//Don't add eggs if the tank already has the max number of fish
if(fish_count >= max_fish)
- to_chat(usr, "[src] can't hold any more fish.")
+ to_chat(user, "[src] can't hold any more fish.")
else
add_fish(egg.fish_type)
qdel(egg)
- return
//Fish food
else if(istype(O, /obj/item/fishfood))
//Only add food if there is water and it isn't already full of food
@@ -711,33 +659,28 @@
if(fish_count == 0)
user.visible_message("[user.name] shakes some fish food into the empty [src]... How sad.", "You shake some fish food into the empty [src]... If only it had fish.")
else
- user.visible_message("[user.name] feeds the fish in \the [src]. The fish look excited!", "You feed the fish in \the [src]. They look excited!")
+ user.visible_message("[user.name] feeds the fish in [src]. The fish look excited!", "You feed the fish in [src]. They look excited!")
adjust_food_level(10)
else
- to_chat(usr, "[src] already has plenty of food in it. You decide to not add more.")
+ to_chat(user, "[src] already has plenty of food in it. You decide to not add more.")
else
- to_chat(usr, "[src] doesn't have any water in it. You should fill it with water first.")
- return
+ to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.")
//Fish egg scoop
else if(istype(O, /obj/item/egg_scoop))
if(egg_count)
- user.visible_message("[user.name] harvests some fish eggs from \the [src].", "You scoop the fish eggs out of \the [src].")
+ user.visible_message("[user.name] harvests some fish eggs from [src].", "You scoop the fish eggs out of [src].")
harvest_eggs(user)
else
- user.visible_message("[user.name] fails to harvest any fish eggs from \the [src].", "There are no fish eggs in \the [src] to scoop out.")
- return
+ user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.")
//Fish net
- if(istype(O, /obj/item/fish_net))
+ else if(istype(O, /obj/item/fish_net))
harvest_fish(user)
- return
//Tank brush
- if(istype(O, /obj/item/tank_brush))
+ else if(istype(O, /obj/item/tank_brush))
if(filth_level == 0)
- to_chat(usr, "[src] is already spotless!")
+ to_chat(user, "[src] is already spotless!")
else
adjust_filth_level(-filth_level)
- user.visible_message("[user.name] scrubs the inside of \the [src], cleaning the filth.", "You scrub the inside of \the [src], cleaning the filth.")
- else if(O && O.force)
- user.visible_message("\The [src] has been attacked by [user.name] with \the [O]!")
- hit(O.force)
- return
+ user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.")
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index bc442486d5c..5dc010bfae9 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -99,6 +99,7 @@
U.overlays += I
var/obj/item/reagent_containers/food/snacks/collected = new type
+ collected.name = name
collected.loc = U
collected.reagents.remove_any(collected.reagents.total_volume)
collected.trash = null
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index b4a787ea4c8..6f6d9132fdf 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -58,7 +58,7 @@
C.emote("scream")
user.changeNext_move(CLICK_CD_MELEE)
C.apply_damage(25, BURN, "head") //25 fire damage and disfigurement because your face was just deep fried!
- head.disfigure("burn")
+ head.disfigure()
add_attack_logs(user, G.affecting, "Deep-fried with [src]")
qdel(G) //Removes the grip so the person MIGHT have a small chance to run the fuck away and to prevent rapid dunks.
return 0
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 1ef887c2527..0a151babe67 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -341,20 +341,28 @@
//Pod turfs and objects
//Window
+/obj/structure/window/shuttle/survival_pod
+ name = "pod window"
+ icon = 'icons/obj/smooth_structures/pod_window.dmi'
+ icon_state = "smooth"
+ dir = FULLTILE_WINDOW_DIR
+ max_integrity = 100
+ fulltile = TRUE
+ reinf = TRUE
+ heat_resistance = 1600
+ armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100)
+ smooth = SMOOTH_MORE
+ canSmoothWith = list(/turf/simulated/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod)
+ explosion_block = 3
+ level = 3
+ glass_type = /obj/item/stack/sheet/titaniumglass
+ glass_amount = 2
+
/obj/structure/window/reinforced/survival_pod
name = "pod window"
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "pwindow"
-// This override can be removed whenever we get rid of the stupid fucking `dir = 9` = full tile!!!! shit
-/obj/structure/window/reinforced/survival_pod/CanPass(atom/movable/mover, turf/target, height=0)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir)
- return !density
- else
- return 1
-
//Floors
/turf/simulated/floor/pod
name = "pod floor"
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index e706b89ca85..8f74fbce413 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -1,7 +1,3 @@
-#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
-#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
-#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point
-
/mob/living/carbon/alien
name = "alien"
voice_name = "alien"
@@ -229,10 +225,6 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/can_use_vents()
return
-#undef HEAT_DAMAGE_LEVEL_1
-#undef HEAT_DAMAGE_LEVEL_2
-#undef HEAT_DAMAGE_LEVEL_3
-
/mob/living/carbon/alien/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["xeno"])
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
index 41ebc8d8247..3fa08702605 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
@@ -1,16 +1,25 @@
+/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ ..(user, TRUE)
+ adjustBruteLoss(15)
+ var/hitverb = "punched"
+ if(mob_size < MOB_SIZE_LARGE)
+ Paralyse(1)
+ spawn(0)
+ step_away(src, user, 15)
+ sleep(1)
+ step_away(src, user, 15)
+ hitverb = "slammed"
+ playsound(loc, "punch", 25, 1, -1)
+ visible_message("[user] has [hitverb] [src]!", "[user] has [hitverb] [src]!")
+ return TRUE
+
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
if(..())
switch(M.a_intent)
if(INTENT_HARM)
var/damage = rand(1, 9)
if(prob(90))
- if(HULK in M.mutations)//HULK SMASH
- damage = 15
- spawn(0)
- Paralyse(1)
- step_away(src, M, 15)
- sleep(3)
- step_away(src, M, 15)
playsound(loc, "punch", 25, 1, -1)
visible_message("[M] has punched [src]!", \
"[M] has punched [src]!")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index f1bcfc0eeaf..44287493718 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -3,7 +3,7 @@
#define X_SUIT_LAYER 2
#define X_L_HAND_LAYER 3
#define X_R_HAND_LAYER 4
-#define TARGETED_LAYER 5
+#define X_TARGETED_LAYER 5
#define X_FIRE_LAYER 6
#define X_TOTAL_LAYERS 6
/////////////////////////////////
@@ -161,6 +161,6 @@
#undef X_SUIT_LAYER
#undef X_L_HAND_LAYER
#undef X_R_HAND_LAYER
-#undef TARGETED_LAYER
+#undef X_TARGETED_LAYER
#undef X_FIRE_LAYER
#undef X_TOTAL_LAYERS
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
index ef38327b5ee..919eecee8d8 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
@@ -2,13 +2,6 @@
if(..())
var/damage = rand(1, 9)
if(prob(90))
- if(HULK in M.mutations)
- damage += 5
- spawn(0)
- Paralyse(1)
- step_away(src, M, 15)
- sleep(3)
- step_away(src, M, 15)
playsound(loc, "punch", 25, 1, -1)
add_attack_logs(M, src, "Melee attacked with fists")
visible_message("[M] has kicked [src]!", \
@@ -23,6 +16,18 @@
visible_message("[M] has attempted to kick [src]!", \
"[M] has attempted to kick [src]!")
+
+/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ ..(user, TRUE)
+ adjustBruteLoss(5 + rand(1, 9))
+ spawn(0)
+ Paralyse(1)
+ step_away(src, user, 15)
+ sleep(3)
+ step_away(src, user, 15)
+ return TRUE
+
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_BITE
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 2abc612f758..8c02bac91d1 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -15,6 +15,7 @@
parent_organ = "head"
slot = "brain"
vital = 1
+ hidden_pain = TRUE //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type.
var/mmi_icon = 'icons/obj/assemblies.dmi'
var/mmi_icon_state = "mmi_full"
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 84b4608b233..37749c0dd76 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -139,9 +139,11 @@
/mob/living/carbon/human/proc/makeSkeleton()
var/obj/item/organ/external/head/H = get_organ("head")
- if(SKELETON in src.mutations) return
+ if(SKELETON in src.mutations)
+ return
if(istype(H))
+ H.disfigured = TRUE
if(H.f_style)
H.f_style = initial(H.f_style)
if(H.h_style)
@@ -159,16 +161,17 @@
mutations.Add(SKELETON)
mutations.Add(NOCLONE)
- status_flags |= DISFIGURED
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/ChangeToHusk()
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
- if(HUSK in mutations) return
+ if(HUSK in mutations)
+ return
if(istype(H))
+ H.disfigured = TRUE //makes them unknown without fucking up other stuff like admintools
if(H.f_style)
H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(H.h_style)
@@ -177,7 +180,6 @@
update_hair(0)
mutations.Add(HUSK)
- status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
update_body(0)
update_mutantrace()
return
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index fcb0e3d8b25..0a7b781cf03 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -513,7 +513,7 @@
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
/mob/living/carbon/human/proc/get_face_name()
var/obj/item/organ/external/head = get_organ("head")
- if( !head || head.disfigured || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
+ if(!head || head.disfigured || cloneloss > 50 || !real_name || (HUSK in mutations)) //disfigured. use id-name if possible
return "Unknown"
return real_name
@@ -1203,7 +1203,7 @@
return 0
if(!L.is_bruised())
- src.custom_pain("You feel a stabbing pain in your chest!", 1)
+ custom_pain("You feel a stabbing pain in your chest!")
L.damage = L.min_bruised_damage
//returns 1 if made bloody, returns 0 otherwise
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index c45154e4931..5b78b450357 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -348,6 +348,18 @@ emp_act
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
+/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ var/hulk_verb = pick("smash", "pummel")
+ if(check_shields(user, 15, "the [hulk_verb]ing"))
+ return
+ ..(user, TRUE)
+ playsound(loc, user.species.unarmed.attack_sound, 25, 1, -1)
+ var/message = "[user] has [hulk_verb]ed [src]!"
+ visible_message("[message]", "[message]")
+ adjustBruteLoss(15)
+ return TRUE
+
/mob/living/carbon/human/attack_hand(mob/user)
if(..()) //to allow surgery to return properly.
return
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index 3af9130fa7d..9a78eafadd8 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -20,7 +20,7 @@
//Moving around with fractured ribs won't do you any good
if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
var/obj/item/organ/internal/I = pick(E.internal_organs)
- custom_pain("You feel broken bones moving in your [E.name]!", 1)
+ custom_pain("You feel broken bones moving in your [E.name]!")
I.receive_damage(rand(3,5))
//handle_stance()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a8deeff60a6..22e2e0ffe25 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -832,7 +832,8 @@
/mob/living/carbon/human/handle_vision()
if(machine)
- if(!machine.check_eye(src)) reset_perspective(null)
+ if(!machine.check_eye(src))
+ reset_perspective(null)
else
var/isRemoteObserve = 0
if((REMOTE_VIEW in mutations) && remoteview_target)
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 25d3fd342c5..4de74d63e5a 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -21,7 +21,7 @@
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/tail // Name of tail image in species effects icon file.
- var/unarmed //For empty hand harm-intent attack
+ var/datum/unarmed_attack/unarmed //For empty hand harm-intent attack
var/unarmed_type = /datum/unarmed_attack
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/silent_steps = 0 // Stops step noises
@@ -375,9 +375,6 @@
var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting))
var/armor_block = target.run_armor_check(affecting, "melee")
- if(HULK in user.mutations)
- target.adjustBruteLoss(15)
-
playsound(target.loc, attack.attack_sound, 25, 1, -1)
target.visible_message("[user] [pick(attack.attack_verb)]ed [target]!")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index ec7592d4d3f..328e4c14ab8 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -205,7 +205,7 @@ var/global/list/damage_icon_parts = list()
DI = damage_icon_parts[cache_index]
standing_image.overlays += DI
- overlays_standing[DAMAGE_LAYER] = standing_image
+ overlays_standing[H_DAMAGE_LAYER] = standing_image
if(update_icons) update_icons()
diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm
index 79bcd54775b..506cc804bd3 100644
--- a/code/modules/mob/living/carbon/slime/slime.dm
+++ b/code/modules/mob/living/carbon/slime/slime.dm
@@ -234,6 +234,24 @@
adjustBruteLoss(damage)
updatehealth()
+/mob/living/carbon/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ if(Victim || Target)
+ Victim = null
+ Target = null
+ anchored = 0
+ if(prob(80) && !client)
+ Discipline++
+ spawn(0)
+ step_away(src, user, 15)
+ sleep(3)
+ step_away(src, user, 15)
+ ..(user, TRUE)
+ playsound(loc, "punch", 25, 1, -1)
+ visible_message("[user] has punched [src]!", "[user] has punched [src]!")
+ adjustBruteLoss(15)
+ return TRUE
+
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M)
if(Victim)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
@@ -301,20 +319,6 @@
var/damage = rand(1, 9)
attacked += 10
if(prob(90))
- if(HULK in M.mutations)
- damage += 15
- if(Victim || Target)
- Victim = null
- Target = null
- anchored = 0
- if(prob(80) && !client)
- Discipline++
- spawn(0)
- step_away(src,M,15)
- sleep(3)
- step_away(src,M,15)
-
-
playsound(loc, "punch", 25, 1, -1)
add_attack_logs(M, src, "Melee attacked with fists")
visible_message("[M] has punched [src]!", \
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 2f0d341f697..d008bf060c4 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -137,10 +137,12 @@
if(!AM.anchored)
now_pushing = 1
var/t = get_dir(src, AM)
- if(istype(AM, /obj/structure/window/full))
- for(var/obj/structure/window/win in get_step(AM, t))
- now_pushing = 0
- return
+ if(istype(AM, /obj/structure/window))
+ var/obj/structure/window/W = AM
+ if(W.fulltile)
+ for(var/obj/structure/window/win in get_step(W, t))
+ now_pushing = 0
+ return
if(pulling == AM)
stop_pulling()
var/current_dir
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index b2755e2b7d8..55e8536cd10 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -164,10 +164,10 @@ proc/get_radio_key_from_channel(var/channel)
if(is_muzzled())
var/obj/item/clothing/mask/muzzle/G = wear_mask
- if(G.mute == MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you
+ if(G.mute == MUZZLE_MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you
to_chat(src, "You're muzzled and cannot speak!")
return
- else if(G.mute == MUTE_MUFFLE)
+ else if(G.mute == MUZZLE_MUTE_MUFFLE)
message = muffledspeech(message)
verb = "mumbles"
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 09b62f1c89c..bf11356b3a5 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -87,11 +87,12 @@ var/list/ai_verbs_default = list(
var/mob/living/simple_animal/bot/Bot
var/turf/waypoint //Holds the turf of the currently selected waypoint.
var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking.
+ var/apc_override = FALSE //hack for letting the AI use its APC even when visionless
var/nuking = 0
var/obj/machinery/doomsday_device/doomsday_device
var/obj/machinery/hologram/holopad/holo = null
- var/mob/camera/aiEye/eyeobj = new()
+ var/mob/camera/aiEye/eyeobj
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
@@ -191,9 +192,7 @@ var/list/ai_verbs_default = list(
spawn(5)
new /obj/machinery/ai_powersupply(src)
- eyeobj.ai = src
- eyeobj.name = "[src.name] (AI Eye)" // Give it a name
- eyeobj.loc = src.loc
+ create_eye()
builtInCamera = new /obj/machinery/camera/portable(src)
builtInCamera.c_tag = name
@@ -1163,6 +1162,17 @@ var/list/ai_verbs_default = list(
client.eye = eyeobj
return TRUE
+
+/mob/living/silicon/ai/proc/can_see(atom/A)
+ if(isturf(loc)) //AI in core, check if on cameras
+ //get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
+ //apc_override is needed here because AIs use their own APC when depowered
+ return (cameranet && cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
+ //AI is carded/shunted
+ //view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
+ var/list/viewscale = getviewsize(client.view)
+ return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
+
/mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking)
if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
if(speaking)
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
index eeeeed8e8bb..6737be463d6 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
@@ -28,7 +28,7 @@
eye.visibleCameraChunks += src
visible++
seenby += eye
- if(changed && !updating)
+ if(changed)
update()
// Remove an AI eye from the chunk, then update if changed.
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index 71a2e6cba36..2728a1af55e 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -20,7 +20,6 @@
// It will also stream the chunk that the new loc is in.
/mob/camera/aiEye/setLoc(T)
-
if(ai)
if(!isturf(ai.loc))
return
@@ -30,8 +29,9 @@
if(ai.client)
ai.client.eye = src
//Holopad
- if(ai.holo)
- ai.holo.move_hologram()
+ if(istype(ai.current, /obj/machinery/hologram/holopad))
+ var/obj/machinery/hologram/holopad/H = ai.current
+ H.move_hologram(ai, T)
/mob/camera/aiEye/Move()
return 0
@@ -41,8 +41,22 @@
return ai.client
return null
+
+/mob/camera/aiEye/proc/RemoveImages()
+ var/client/C = GetViewerClient()
+ if(C)
+ for(var/V in visibleCameraChunks)
+ var/datum/camerachunk/chunk = V
+ C.images -= chunk.obscured
+
+
/mob/camera/aiEye/Destroy()
- ai = null
+ if(ai)
+ //ai.all_eyes -= src
+ ai = null
+ for(var/V in visibleCameraChunks)
+ var/datum/camerachunk/chunk = V
+ chunk.remove(src)
return ..()
/atom/proc/move_camera_by_click()
@@ -102,12 +116,18 @@
src.eyeobj.loc = src.loc
else
to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
- src.eyeobj = new(src.loc)
- src.eyeobj.ai = src
- src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name
+ create_eye()
eyeobj.setLoc(loc)
+/mob/living/silicon/ai/proc/create_eye()
+ if(eyeobj)
+ return
+ eyeobj = new /mob/camera/aiEye()
+ eyeobj.ai = src
+ eyeobj.setLoc(loc)
+ eyeobj.name = "[name] (AI Eye)"
+
/mob/living/silicon/ai/proc/toggle_acceleration()
set category = "AI Commands"
set name = "Toggle Camera Acceleration"
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 1755674b4f6..42f132e39d4 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -129,8 +129,10 @@
to_chat(src, "Receiving control information from APC.")
sleep(2)
//bring up APC dialog
- aiRestorePowerRoutine = 3
+ apc_override = 1
theAPC.attack_ai(src)
+ apc_override = 0
+ aiRestorePowerRoutine = 3
to_chat(src, "Here are your current laws:")
src.show_laws() //WHY THE FUCK IS THIS HERE
sleep(50)
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 0de811224dc..0a3ed47b933 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -74,8 +74,8 @@
if(!message)
return
- var/obj/machinery/hologram/holopad/T = src.holo
- if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user.
+ var/obj/machinery/hologram/holopad/T = current
+ if(istype(T) && T.masters[src])
//Human-like, sorta, heard by those who understand humans.
var/rendered_a
@@ -112,8 +112,8 @@
if(!message)
return
- var/obj/machinery/hologram/holopad/T = src.holo
- if(T && T.hologram && T.master == src)
+ var/obj/machinery/hologram/holopad/T = current
+ if(istype(T) && T.masters[src])
var/rendered = "[name][message]"
to_chat(src, "Holopad action relayed, [real_name][message]")
@@ -127,8 +127,8 @@
return 1
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
- var/obj/machinery/hologram/holopad/T = src.holo
- if(T && T.hologram && T.master == src) //Is the AI using a holopad?
+ var/obj/machinery/hologram/holopad/T = current
+ if(istype(T) && T.masters[src])//Is the AI using a holopad?
src.holopad_emote(message)
else //Emote normally, then.
..()
diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm
index 070ed327163..a903b6999dc 100644
--- a/code/modules/mob/living/silicon/silicon_defense.dm
+++ b/code/modules/mob/living/silicon/silicon_defense.dm
@@ -41,6 +41,15 @@
if(L.a_intent == INTENT_HELP)
visible_message("[L.name] rubs its head against [src].")
+/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ ..(user, TRUE)
+ adjustBruteLoss(rand(10, 15))
+ playsound(loc, "punch", 25, 1, -1)
+ visible_message("[user] has punched [src]!", "[user] has punched [src]!")
+ return TRUE
+ return FALSE
+
/mob/living/silicon/attack_hand(mob/living/carbon/human/M)
switch(M.a_intent)
if(INTENT_HELP)
@@ -51,15 +60,6 @@
else
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(loc, 'sound/effects/bang.ogg', 10, 1)
- if(HULK in M.mutations)
- var/damage = rand(10,15)
- adjustBruteLoss(damage)
- add_attack_logs(M, src, "Melee attacked with fists")
- playsound(loc, "punch", 25, 1, -1)
- visible_message("[M] has punched [src]!", \
- "[M] has punched [src]!")
- return 1
- else
- visible_message("[M] punches [src], but doesn't leave a dent.", \
+ visible_message("[M] punches [src], but doesn't leave a dent.", \
"[M] punches [src], but doesn't leave a dent.!")
- return 0
+ return FALSE
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 972759812b4..309a13468a3 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -19,6 +19,14 @@
updatehealth()
return 1
+/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
+ if(user.a_intent == INTENT_HARM)
+ ..(user, TRUE)
+ playsound(loc, "punch", 25, 1, -1)
+ visible_message("[user] has punched [src]!", "[user] has punched [src]!")
+ adjustBruteLoss(15)
+ return TRUE
+
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent.
var/damage = rand(15, 30)
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 9e96a16fb0f..90c44f19286 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -282,73 +282,66 @@
log_game("[key_name(user)] has renamed a robot to [t]")
//Medbot Assembly
-/obj/item/firstaid_arm_assembly
- name = "incomplete medibot assembly."
- desc = "A first aid kit with a robot arm permanently grafted to it."
- icon = 'icons/obj/aibots.dmi'
- icon_state = "firstaid_arm"
- var/build_step = 0
- var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess
- var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
- w_class = WEIGHT_CLASS_NORMAL
- var/treatment_brute = "salglu_solution"
- var/treatment_oxy = "salbutamol"
- var/treatment_fire = "salglu_solution"
- var/treatment_tox = "charcoal"
- var/treatment_virus = "spaceacillin"
- req_one_access = list(access_medical, access_robotics)
-
- /obj/item/firstaid_arm_assembly/New()
- ..()
- spawn(5)
- if(skin)
- overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
-
-/obj/item/storage/firstaid/attackby(obj/item/robot_parts/S, mob/user, params)
-
- if((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
- ..()
- return
+/obj/item/storage/firstaid/attackby(obj/item/I, mob/user, params)
+ if(!istype(I, /obj/item/robot_parts/l_arm) && !istype(I, /obj/item/robot_parts/r_arm))
+ return ..()
//Making a medibot!
- if(contents.len >= 1)
+ if(contents.len)
to_chat(user, "You need to empty [src] out first!")
return
- var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly
- if(istype(src,/obj/item/storage/firstaid/fire))
- A.skin = "ointment"
- else if(istype(src,/obj/item/storage/firstaid/toxin))
- A.skin = "tox"
- else if(istype(src,/obj/item/storage/firstaid/o2))
- A.skin = "o2"
- else if(istype(src,/obj/item/storage/firstaid/brute))
- A.skin = "brute"
- else if(istype(src,/obj/item/storage/firstaid/adv))
- A.skin = "adv"
- else if(istype(src,/obj/item/storage/firstaid/tactical))
- A.skin = "bezerk"
- else if(istype(src,/obj/item/storage/firstaid/aquatic_kit))
- A.skin = "fish"
+ var/obj/item/firstaid_arm_assembly/A = new /obj/item/firstaid_arm_assembly(loc, med_bot_skin)
A.req_one_access = req_one_access
+ A.syndicate_aligned = syndicate_aligned
A.treatment_oxy = treatment_oxy
A.treatment_brute = treatment_brute
A.treatment_fire = treatment_fire
A.treatment_tox = treatment_tox
A.treatment_virus = treatment_virus
- qdel(S)
+ qdel(I)
user.put_in_hands(A)
to_chat(user, "You add the robot arm to the first aid kit.")
user.unEquip(src, 1)
qdel(src)
+/obj/item/firstaid_arm_assembly
+ name = "incomplete medibot assembly."
+ desc = "A first aid kit with a robot arm permanently grafted to it."
+ icon = 'icons/obj/aibots.dmi'
+ icon_state = "firstaid_arm"
+ w_class = WEIGHT_CLASS_NORMAL
+ req_one_access = list(access_medical, access_robotics)
+ var/build_step = 0
+ var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess
+ var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
+ var/syndicate_aligned = FALSE
+ var/treatment_brute = "salglu_solution"
+ var/treatment_oxy = "salbutamol"
+ var/treatment_fire = "salglu_solution"
+ var/treatment_tox = "charcoal"
+ var/treatment_virus = "spaceacillin"
-/obj/item/firstaid_arm_assembly/attackby(obj/item/W, mob/user, params)
+/obj/item/firstaid_arm_assembly/New(loc, new_skin)
..()
- if(istype(W, /obj/item/pen))
- var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN)
+ if(new_skin)
+ skin = new_skin
+ update_icon()
+
+/obj/item/firstaid_arm_assembly/update_icon()
+ overlays.Cut()
+ if(skin)
+ overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
+ if(build_step > 0)
+ overlays += image('icons/obj/aibots.dmi', "na_scanner")
+
+
+/obj/item/firstaid_arm_assembly/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(istype(I, /obj/item/pen))
+ var/t = stripped_input(user, "Enter new robot name", name, created_name, MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, user) && loc != user)
@@ -358,32 +351,34 @@
else
switch(build_step)
if(0)
- if(istype(W, /obj/item/healthanalyzer))
- if(!user.unEquip(W))
+ if(istype(I, /obj/item/healthanalyzer))
+ if(!user.drop_item())
return
- qdel(W)
+ qdel(I)
build_step++
to_chat(user, "You add the health sensor to [src].")
name = "First aid/robot arm/health analyzer assembly"
- overlays += image('icons/obj/aibots.dmi', "na_scanner")
+ update_icon()
if(1)
- if(isprox(W))
- if(!user.unEquip(W))
+ if(isprox(I))
+ if(!user.drop_item())
return
- qdel(W)
+ qdel(I)
build_step++
to_chat(user, "You complete the Medibot. Beep boop!")
var/turf/T = get_turf(src)
- var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T)
- S.skin = skin
- S.name = created_name
- S.bot_core.req_one_access = req_one_access
- S.treatment_oxy = treatment_oxy
- S.treatment_brute = treatment_brute
- S.treatment_fire = treatment_fire
- S.treatment_tox = treatment_tox
- S.treatment_virus = treatment_virus
+ if(!syndicate_aligned)
+ var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T, skin)
+ S.name = created_name
+ S.bot_core.req_one_access = req_one_access
+ S.treatment_oxy = treatment_oxy
+ S.treatment_brute = treatment_brute
+ S.treatment_fire = treatment_fire
+ S.treatment_tox = treatment_tox
+ S.treatment_virus = treatment_virus
+ else
+ new /mob/living/simple_animal/bot/medbot/syndicate(T) //Syndicate medibots are a special case that have so many unique vars on them, it's not worth passing them through construction phases
user.unEquip(src, 1)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index 1d9c13b54fc..9d7fa39ed87 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -17,7 +17,7 @@
bot_filter = RADIO_SECBOT
model = "ED-209"
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
- bot_core = /obj/machinery/bot_core/secbot
+ bot_core_type = /obj/machinery/bot_core/secbot
window_id = "autoed209"
window_name = "Automatic Security Unit v2.6"
path_image_color = "#FF0000"
@@ -61,12 +61,14 @@
shot_delay = 6//Longer shot delay because JESUS CHRIST
check_records = 0//Don't actively target people set to arrest
arrest_type = 1//Don't even try to cuff
- bot_core.req_access = list(access_maint_tunnels, access_theatre)
- arrest_type = 1
- if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
- name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
- if((lasercolor == "r") && (name == "\improper ED-209 Security Robot"))
- name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
+ declare_arrests = 0 // Don't spam sec
+ bot_core.req_access = list(access_maint_tunnels, access_theatre, access_robotics)
+
+ if(created_name == initial(name) || !created_name)
+ if(lasercolor == "b")
+ name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
+ else if (lasercolor == "r")
+ name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
//SECHUD
var/datum/atom_hud/secsensor = huds[DATA_HUD_SECURITY_ADVANCED]
@@ -101,30 +103,30 @@
dat += hack(user)
dat += showpai(user)
dat += text({"
-Security Unit v2.6 controls
-Status: []
-Behaviour controls are [locked ? "locked" : "unlocked"]
-Maintenance panel panel is [open ? "opened" : "closed"] "},
+ Security Unit v2.6 controls
+ Status: []
+ Behaviour controls are [locked ? "locked" : "unlocked"]
+ Maintenance panel panel is [open ? "opened" : "closed"] "},
-"[on ? "On" : "Off"]" )
+ "[on ? "On" : "Off"]" )
if(!locked || issilicon(user) || user.can_admin_interact())
+ dat += "Auto Patrol [auto_patrol ? "On" : "Off"] "
+
if(!lasercolor)
dat += text({"
-Arrest Unidentifiable Persons: []
-Arrest for Unauthorized Weapons: []
-Arrest for Warrant: []
-
-Operating Mode: []
-Report Arrests[]
-Auto Patrol[]"},
+ Arrest Unidentifiable Persons: []
+ Arrest for Unauthorized Weapons: []
+ Arrest for Warrant: []
+
+ Operating Mode: []
+ Report Arrests[] "},
-"[idcheck ? "Yes" : "No"]",
-"[weaponscheck ? "Yes" : "No"]",
-"[check_records ? "Yes" : "No"]",
-"[arrest_type ? "Detain" : "Arrest"]",
-"[declare_arrests ? "Yes" : "No"]",
-"[auto_patrol ? "On" : "Off"]" )
+ "[idcheck ? "Yes" : "No"]",
+ "[weaponscheck ? "Yes" : "No"]",
+ "[check_records ? "Yes" : "No"]",
+ "[arrest_type ? "Detain" : "Arrest"]",
+ "[declare_arrests ? "Yes" : "No"]")
return dat
@@ -239,13 +241,18 @@ Auto Patrol[]"},
if(target) // make sure target exists
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
stun_attack(target)
+ if(!lasercolor)
+ mode = BOT_PREP_ARREST
+ anchored = 1
+ target_lastloc = target.loc
+ return
+ else
+ mode = BOT_HUNT
+ target = null
+ target_lastloc = null
+ return
- mode = BOT_PREP_ARREST
- anchored = 1
- target_lastloc = target.loc
- return
-
- else // not next to perp
+ else if(!disabled) // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
@@ -406,7 +413,7 @@ Auto Patrol[]"},
shoot_sound = 'sound/weapons/laser.ogg'
if(emagged == 2)
if(lasercolor)
- projectile = /obj/item/projectile/beam/lasertag
+ projectile = /obj/item/projectile/beam/disabler
else
projectile = /obj/item/projectile/beam
else
@@ -501,6 +508,7 @@ Auto Patrol[]"},
if(lasertag_check)
icon_state = "[lasercolor]ed2090"
disabled = 1
+ walk_to(src, 0)
target = null
spawn(100)
disabled = 0
@@ -569,4 +577,4 @@ Auto Patrol[]"},
if(!C.handcuffed)
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
C.update_handcuffed()
- back_to_idle()
+ back_to_idle()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 9ad8837520d..b1133cb0e08 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -14,7 +14,7 @@
bot_filter = RADIO_FLOORBOT
model = "Floorbot"
bot_purpose = "seek out damaged or missing floor tiles, and repair or replace them as necessary"
- bot_core = /obj/machinery/bot_core/floorbot
+ bot_core_type = /obj/machinery/bot_core/floorbot
window_id = "autofloor"
window_name = "Automatic Station Floor Repairer v1.1"
path_image_color = "#FFA500"
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 7c737690ec0..6cdffd48f16 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -44,6 +44,7 @@
var/treatment_virus = "spaceacillin"
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
var/shut_up = 0 //self explanatory :)
+ var/syndicate_aligned = FALSE // Will it only treat operatives?
/mob/living/simple_animal/bot/medbot/tox
skin = "tox"
@@ -68,8 +69,8 @@
desc = "International Medibot of mystery."
skin = "bezerk"
treatment_oxy = "perfluorodecalin"
- treatment_brute = "styptic_powder"
- treatment_fire = "silver_sulfadiazine"
+ treatment_brute = "bicaridine"
+ treatment_fire = "kelotane"
treatment_tox = "charcoal"
/mob/living/simple_animal/bot/medbot/syndicate
@@ -77,9 +78,10 @@
desc = "You'd better have insurance!"
skin = "bezerk"
treatment_oxy = "perfluorodecalin"
- treatment_brute = "styptic_powder"
- treatment_fire = "silver_sulfadiazine"
+ treatment_brute = "bicaridine"
+ treatment_fire = "kelotane"
treatment_tox = "charcoal"
+ syndicate_aligned = TRUE
bot_core_type = /obj/machinery/bot_core/medbot/syndicate
control_freq = BOT_FREQ + 1000 // make it not show up on lists
radio_channel = "Syndicate"
@@ -90,6 +92,9 @@
Radio.syndie = 1
/mob/living/simple_animal/bot/medbot/update_icon()
+ overlays.Cut()
+ if(skin)
+ overlays += "medskin_[skin]"
if(!on)
icon_state = "medibot0"
return
@@ -101,22 +106,21 @@
else
icon_state = "medibot1"
-/mob/living/simple_animal/bot/medbot/New()
+/mob/living/simple_animal/bot/medbot/New(loc, new_skin)
..()
- update_icon()
-
- spawn(4)
- if(skin)
- overlays += image('icons/obj/aibots.dmi', "medskin_[skin]")
-
- var/datum/job/doctor/J = new/datum/job/doctor
- access_card.access += J.get_access()
- prev_access = access_card.access
+ var/datum/job/doctor/J = new /datum/job/doctor
+ access_card.access += J.get_access()
+ prev_access = access_card.access
+ qdel(J)
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
permanent_huds |= medsensor
+ if(new_skin)
+ skin = new_skin
+ update_icon()
+
/mob/living/simple_animal/bot/medbot/bot_reset()
..()
patient = null
@@ -271,8 +275,10 @@
if(assess_patient(H))
last_found = world.time
if((last_newpatient_speak + 300) < world.time) //Don't spam these messages!
- var/message = pick("Hey, [H.name]! Hold on, I'm coming.","Wait [H.name]! I want to help!","[H.name], you appear to be injured!")
+ var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/mcoming.ogg', "Wait [H.name]! I want to help!" = 'sound/voice/mhelp.ogg', "[H.name], you appear to be injured!" = 'sound/voice/minjured.ogg')
+ var/message = pick(messagevoice)
speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
last_newpatient_speak = world.time
return H
else
@@ -304,8 +310,10 @@
if(!patient)
if(!shut_up && prob(1))
- var/message = pick("Radar, put a mask on!","There's always a catch, and it's the best there is.","I knew it, I should've been a plastic surgeon.","What kind of medbay is this? Everyone's dropping like dead flies.","Delicious!")
+ var/list/messagevoice = list("Radar, put a mask on!" = 'sound/voice/mradar.ogg', "There's always a catch, and I'm the best there is." = 'sound/voice/mcatch.ogg', "I knew it, I should've been a plastic surgeon." = 'sound/voice/msurgeon.ogg', "What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/mflies.ogg', "Delicious!" = 'sound/voice/mdelicious.ogg')
+ var/message = pick(messagevoice)
speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients.
patient = scan(/mob/living/carbon/human, oldpatient, scan_range)
oldpatient = patient
@@ -371,7 +379,7 @@
if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins)
return 1
- if((skin == "bezerk") && (!("syndicate" in C.faction)))
+ if(syndicate_aligned && (!("syndicate" in C.faction)))
return 0
if(declare_crit && C.health <= 0) //Critical condition! Call for help!
@@ -440,9 +448,11 @@
soft_reset()
return
- if(C.stat == 2)
- var/death_message = pick("No! NO!","Live, damnit! LIVE!","I...I've never lost a patient before. Not today, I mean.")
- speak(death_message)
+ if(C.stat == DEAD || (C.status_flags & FAKEDEATH))
+ var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/mno.ogg', "Live, damnit! LIVE!" = 'sound/voice/mlive.ogg', "I...I've never lost a patient before. Not today, I mean." = 'sound/voice/mlost.ogg')
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
oldpatient = patient
soft_reset()
return
@@ -492,8 +502,10 @@
break
if(!reagent_id) //If they don't need any of that they're probably cured!
- var/message = pick("All patched up!","An apple a day keeps me away.","Feel better soon!")
+ var/list/messagevoice = list("All patched up!" = 'sound/voice/mpatchedup.ogg', "An apple a day keeps me away." = 'sound/voice/mapple.ogg', "Feel better soon!" = 'sound/voice/mfeelbetter.ogg')
+ var/message = pick(messagevoice)
speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
bot_reset()
return
else
@@ -554,7 +566,8 @@
if("adv")
new /obj/item/storage/firstaid/adv/empty(Tsec)
if("bezerk")
- new /obj/item/storage/firstaid/tactical/empty(Tsec)
+ var/obj/item/storage/firstaid/tactical/empty/T = new(Tsec)
+ T.syndicate_aligned = syndicate_aligned //This is a special case since Syndicate medibots and the mysterious medibot look the same; we also dont' want crew building Syndicate medibots if the mysterious medibot blows up.
if("fish")
new /obj/item/storage/firstaid/aquatic_kit(Tsec)
else
@@ -571,6 +584,9 @@
if(prob(50))
new /obj/item/robot_parts/l_arm(Tsec)
+ if(emagged && prob(25))
+ playsound(loc, 'sound/voice/minsult.ogg', 50, 0)
+
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -579,7 +595,7 @@
/mob/living/simple_animal/bot/medbot/proc/declare(crit_patient)
if(declare_cooldown)
return
- if((skin == "bezerk"))
+ if(syndicate_aligned)
return
var/area/location = get_area(src)
speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!", radio_channel)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
index 9133b8cc14c..532c2b7357a 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
@@ -39,7 +39,7 @@
var/lastnestsetup = 0
var/neststep = 0
var/hasnested = 0
- var/spider_max_per_nest = 25 // above this, AI queens become stable
+ var/spider_max_per_nest = 35 // above this, AI queens become stable
var/canlay = 4 // main counter for egg-laying ability! # = num uses, incremented at intervals
var/eggslaid = 0
var/spider_can_fakelings = 3 // spawns defective spiderlings that don't grow up, used to freak out crew, atmosphere
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index ef456ddcb0e..235a161c595 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -201,11 +201,6 @@ var/global/list/ts_spiderling_list = list()
spider_specialattack(G,can_poison)
else
G.attack_animal(src)
- else if(istype(target, /obj/structure/alien/resin))
- var/obj/structure/alien/resin/E = target
- do_attack_animation(E)
- E.health -= rand(melee_damage_lower, melee_damage_upper)
- E.healthcheck()
else
target.attack_animal(src)
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 63b248ffd41..fb62ad3a629 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -4,6 +4,7 @@
lastKnownIP = client.address
computer_id = client.computer_id
log_access_in(client)
+ create_attack_log("Logged in at [atom_loc_line(get_turf(src))]")
if(config.log_access)
for(var/mob/M in player_list)
if(M == src) continue
diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm
index a0f8594e870..cbcd51c44a7 100644
--- a/code/modules/mob/logout.dm
+++ b/code/modules/mob/logout.dm
@@ -3,6 +3,7 @@
unset_machine()
player_list -= src
log_access_out(src)
+ create_attack_log("Logged out at [atom_loc_line(get_turf(src))]")
// `holder` is nil'd out by now, so we check the `admin_datums` array directly
//Only report this stuff if we are currently playing.
if(admin_datums[ckey] && ticker && ticker.current_state == GAME_STATE_PLAYING)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index bbe6caed8a3..beba84eaa3f 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -543,11 +543,11 @@ var/list/slot_equipment_priority = list( \
client.screen = list()
hud_used.show_hud(hud_used.hud_version)
-/mob/setDir(new_dir)
+/mob/setDir(new_dir)
if(forced_look)
if(isnum(forced_look))
dir = forced_look
- else
+ else
var/atom/A = locateUID(forced_look)
if(istype(A))
dir = get_cardinal_dir(src, A)
@@ -592,7 +592,7 @@ var/list/slot_equipment_priority = list( \
return
if(!src || !isturf(src.loc))
return 0
- if(istype(A, /obj/effect/decal/point))
+ if(istype(A, /obj/effect/temp_visual/point))
return 0
var/tile = get_turf(A)
@@ -600,12 +600,8 @@ var/list/slot_equipment_priority = list( \
return 0
changeNext_move(CLICK_CD_POINT)
- var/obj/P = new /obj/effect/decal/point(tile)
+ var/obj/P = new /obj/effect/temp_visual/point(tile)
P.invisibility = invisibility
- spawn (20)
- if(P)
- qdel(P)
-
return 1
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 6d1f856fbd3..274c1602e04 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -26,6 +26,7 @@
/mob/new_player/proc/handle_tos_consent()
if(!GLOB.join_tos)
+ tos_consent = TRUE
return TRUE
establish_db_connection()
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 9a911400fd5..0520630dcac 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -10,6 +10,7 @@
move_self = 1 //Do we move on our own?
grav_pull = 5 //How many tiles out do we pull?
consume_range = 6 //How many tiles out do we eat
+ gender = FEMALE
/obj/singularity/narsie/large
name = "Nar-Sie"
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index e69abc5b00f..27229a2d8b3 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -224,8 +224,6 @@
/obj/machinery/power/smes/proc/chargedisplay()
return round(5.5*charge/(capacity ? capacity : 5e6))
-#define SMESRATE 0.05
-
/obj/machinery/power/smes/process()
if(stat & BROKEN) return
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index e589936a935..d4d232d2ed7 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -1,7 +1,3 @@
-#define SOLID 1
-#define LIQUID 2
-#define GAS 3
-
/obj/machinery/chem_dispenser
name = "chem dispenser"
density = 1
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index a979d350c2a..d1b44798b85 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -115,7 +115,11 @@
M.adjustToxLoss(-3)
M.adjustBruteLoss(-12)
M.adjustFireLoss(-12)
- M.status_flags &= ~DISFIGURED
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/head/head = H.get_organ("head")
+ if(head)
+ head.disfigured = FALSE
..()
/datum/reagent/medicine/rezadone
@@ -131,7 +135,11 @@
M.adjustCloneLoss(-1) //What? We just set cloneloss to 0. Why? Simple; this is so external organs properly unmutate.
M.adjustBruteLoss(-1)
M.adjustFireLoss(-1)
- M.status_flags &= ~DISFIGURED
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/head/head = H.get_organ("head")
+ if(head)
+ head.disfigured = FALSE
..()
/datum/reagent/medicine/rezadone/overdose_process(mob/living/M, severity)
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 0dbd2224e92..7bff61218c6 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -611,11 +611,11 @@
return
if(!H.unacidable)
- var/obj/item/organ/external/affecting = H.get_organ("head")
- affecting.receive_damage(0, 75)
+ var/obj/item/organ/external/head/affecting = H.get_organ("head")
+ if(affecting)
+ affecting.receive_damage(0, 75)
H.UpdateDamageIcon()
H.emote("scream")
- H.status_flags |= DISFIGURED
/datum/reagent/facid/reaction_obj(obj/O, volume)
if((istype(O, /obj/item) || istype(O, /obj/structure/glowshroom)))
@@ -947,8 +947,7 @@
/datum/reagent/glyphosate/reaction_obj(obj/O, volume)
if(istype(O,/obj/structure/alien/weeds))
var/obj/structure/alien/weeds/alien_weeds = O
- alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast
- alien_weeds.healthcheck()
+ alien_weeds.take_damage(rand(15, 35), BRUTE, 0) // Kills alien weeds pretty fast
else if(istype(O, /obj/structure/glowshroom)) //even a small amount is enough to kill it
qdel(O)
else if(istype(O, /obj/structure/spacevine))
diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm
index 39d3babf4bc..6b0dc98dd37 100644
--- a/code/modules/reagents/reagent_containers/glass_containers.dm
+++ b/code/modules/reagents/reagent_containers/glass_containers.dm
@@ -42,7 +42,8 @@
/obj/machinery/constructable_frame,
/obj/machinery/icemachine,
/obj/item/bombcore/chemical,
- /obj/machinery/vending)
+ /obj/machinery/vending,
+ /obj/machinery/fishtank)
/obj/item/reagent_containers/glass/New()
..()
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 02d71db8719..fa709fd7d98 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -49,14 +49,14 @@
user.newtonian_move(get_dir(A, user))
if(reagents.has_reagent("sacid"))
- msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(src)].")
- log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(src)].")
+ msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(user)].")
+ log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(user)].")
if(reagents.has_reagent("facid"))
- msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(src)].")
- log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(src)].")
+ msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(user)].")
+ log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(user)].")
if(reagents.has_reagent("lube"))
- msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(src)].")
- log_game("[key_name(user)] fired space lube from \a [src] at [COORD(src)].")
+ msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(user)].")
+ log_game("[key_name(user)] fired space lube from \a [src] at [COORD(user)].")
return
diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm
index fe45e8dacad..a043d90fb19 100644
--- a/code/modules/research/designs/smelting_designs.dm
+++ b/code/modules/research/designs/smelting_designs.dm
@@ -25,6 +25,22 @@
build_path = /obj/item/stack/sheet/plasmaglass
category = list("initial")
+/datum/design/titaniumglass_alloy
+ name = "Titanium + Glass alloy"
+ id = "titaniumglass"
+ build_type = SMELTER
+ materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
+ build_path = /obj/item/stack/sheet/titaniumglass
+ category = list("initial")
+
+/datum/design/plastitaniumglass_alloy
+ name = "Plasma + Titanium + Glass alloy"
+ id = "plastitaniumglass"
+ build_type = SMELTER
+ materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT, MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
+ build_path = /obj/item/stack/sheet/plastitaniumglass
+ category = list("initial")
+
/datum/design/alienalloy
name = "Alien Alloy"
desc = "A sheet of reverse-engineered alien alloy."
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index f7976645bc4..dcae187b028 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -22,7 +22,6 @@
desc = "A computer used for remotely handling slimes."
networks = list("SS13")
circuit = /obj/item/circuitboard/xenobiology
- off_action = new /datum/action/innate/camera_off/xenobio
var/datum/action/innate/slime_place/slime_place_action = new
var/datum/action/innate/slime_pick_up/slime_up_action = new
var/datum/action/innate/feed_slime/feed_slime_action = new
@@ -43,23 +42,27 @@
eyeobj.icon_state = "camera_target"
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/carbon/user)
- off_action.target = user
- off_action.Grant(user)
+ ..()
+ if(slime_up_action)
+ slime_up_action.target = src
+ slime_up_action.Grant(user)
+ actions += slime_up_action
+
+ if(slime_place_action)
+ slime_place_action.target = src
+ slime_place_action.Grant(user)
+ actions += slime_place_action
+
+ if(feed_slime_action)
+ feed_slime_action.target = src
+ feed_slime_action.Grant(user)
+ actions += feed_slime_action
+
+ if(monkey_recycle_action)
+ monkey_recycle_action.target = src
+ monkey_recycle_action.Grant(user)
+ actions += monkey_recycle_action
- jump_action.target = user
- jump_action.Grant(user)
-
- slime_up_action.target = src
- slime_up_action.Grant(user)
-
- slime_place_action.target = src
- slime_place_action.Grant(user)
-
- feed_slime_action.target = src
- feed_slime_action.Grant(user)
-
- monkey_recycle_action.target = src
- monkey_recycle_action.Grant(user)
/obj/machinery/computer/camera_advanced/xenobio/attack_hand(mob/user)
@@ -87,31 +90,6 @@
return
..()
-/datum/action/innate/camera_off/xenobio/Activate()
- if(!target || !ishuman(target))
- return
- var/mob/living/carbon/C = target
- var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
- var/obj/machinery/computer/camera_advanced/xenobio/origin = remote_eye.origin
- C.remote_view = 0
- origin.current_user = null
- origin.jump_action.Remove(C)
- origin.slime_place_action.Remove(C)
- origin.slime_up_action.Remove(C)
- origin.feed_slime_action.Remove(C)
- origin.monkey_recycle_action.Remove(C)
- //All of this stuff below could probably be a proc for all advanced cameras, only the action removal needs to be camera specific
- remote_eye.eye_user = null
- C.reset_perspective(null)
- if(C.client)
- C.client.images -= remote_eye.user_image
- for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
- C.client.images -= chunk.obscured
- C.remote_control = null
- C.unset_machine()
- src.Remove(C)
-
-
/datum/action/innate/slime_place
name = "Place Slimes"
button_icon_state = "slime_down"
diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm
index 16640a8b4c8..a24a9522b38 100644
--- a/code/modules/scripting/Implementations/Telecomms.dm
+++ b/code/modules/scripting/Implementations/Telecomms.dm
@@ -24,14 +24,22 @@
interpreter.GC()
+//temp
+/datum/TCS_Compiler
+ var/datum/n_scriptOptions/nS_Options/options
+ var/datum/n_Scanner/nS_Scanner/scanner
+ var/list/tokens
+ var/datum/n_Parser/nS_Parser/parser
+ var/datum/node/BlockDefinition/GlobalBlock/program
+
/* -- Compile a raw block of text -- */
-/datum/TCS_Compiler/proc/Compile(code as message)
- var/datum/n_scriptOptions/nS_Options/options = new()
- var/datum/n_Scanner/nS_Scanner/scanner = new(code, options)
- var/list/tokens = scanner.Scan()
- var/datum/n_Parser/nS_Parser/parser = new(tokens, options)
- var/datum/node/BlockDefinition/GlobalBlock/program = parser.Parse()
+/datum/TCS_Compiler/proc/Compile(list/code)
+ options = new()
+ scanner = new(code, options)
+ tokens = scanner.Scan()
+ parser = new(tokens, options)
+ program = parser.Parse()
var/list/returnerrors = list()
diff --git a/code/modules/scripting/Interpreter/Interpreter.dm b/code/modules/scripting/Interpreter/Interpreter.dm
index 79802ff2fa5..c24e9ba5e3a 100644
--- a/code/modules/scripting/Interpreter/Interpreter.dm
+++ b/code/modules/scripting/Interpreter/Interpreter.dm
@@ -184,6 +184,8 @@ Runs each statement in a block of code.
else
RaiseError(new/datum/runtimeError/UnknownInstruction())
+ CHECK_TICK
+
if(status)
break
diff --git a/code/modules/scripting/Options.dm b/code/modules/scripting/Options.dm
index b27acff91d3..be471756359 100644
--- a/code/modules/scripting/Options.dm
+++ b/code/modules/scripting/Options.dm
@@ -36,11 +36,12 @@ File: Options
if(!CanStartID(id)) //don't need to grab first char in id, since text2ascii does it automatically
return 0
- if(length(id) == 1)
+ var/list/charmap = string2charlist(id)
+ if(charmap.len == 1)
return 1
- for(var/i=2 to length(id))
- if(!IsValidIDChar(copytext(id, i, i + 1)))
+ for(var/i = 2 to charmap.len)
+ if(!IsValidIDChar(charmap[i]))
return 0
return 1
diff --git a/code/modules/scripting/Scanner/Scanner.dm b/code/modules/scripting/Scanner/Scanner.dm
index 011621c8ea8..da6a2c04803 100644
--- a/code/modules/scripting/Scanner/Scanner.dm
+++ b/code/modules/scripting/Scanner/Scanner.dm
@@ -6,7 +6,7 @@
An object responsible for breaking up source code into tokens for use by the parser.
*/
/datum/n_Scanner
- var/code
+ var/list/code
/*
Var: errors
A list of fatal errors found by the scanner. If there are any items in this list, then it is not safe to parse the returned tokens.
@@ -25,7 +25,7 @@
Proc: LoadCode
Loads source code.
*/
-/datum/n_Scanner/proc/LoadCode(var/c)
+/datum/n_Scanner/proc/LoadCode(var/list/c)
code=c
/*
@@ -100,24 +100,23 @@
code - The source code to tokenize.
options - An object used to configure the scanner.
*/
-/datum/n_Scanner/nS_Scanner/New(var/code, var/datum/n_scriptOptions/nS_Options/options)
+/datum/n_Scanner/nS_Scanner/New(var/list/c, var/datum/n_scriptOptions/nS_Options/options)
. = ..()
ignore += ascii2text(13) //Carriage return
delim += ignore + options.symbols + end_stmt + string_delim
src.options = options
- LoadCode(code)
+ LoadCode(c)
/datum/n_Scanner/nS_Scanner/Scan() //Creates a list of tokens from source code
var/list/tokens = new
- for(, src.codepos <= length(code), src.codepos++)
-
- var/char = copytext(code, codepos, codepos + 1)
- var/nextchar = copytext(code, codepos + 1, codepos + 2)
+ for(, src.codepos <= code.len, src.codepos++)
+ var/char = code[codepos]
+ var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1)
if(char == "\n")
line++
linepos = codepos
- if(ignore.Find(char))
+ if(char in ignore)
continue
else if(char == "/" && (nextchar == "*" || nextchar == "/"))
@@ -139,6 +138,7 @@
else if(options.symbols.Find(char))
tokens += ReadSymbol()
+ CHECK_TICK
codepos = initial(codepos)
line = initial(line)
@@ -155,12 +155,12 @@
*/
/datum/n_Scanner/nS_Scanner/proc/ReadString(start)
var/buf
- for(, codepos <= length(code), codepos++)//codepos to length(code))
- var/char = copytext(code, codepos, codepos + 1)
+ for(, codepos <= code.len, codepos++)//codepos to length(code))
+ var/char = code[codepos]
switch(char)
if("\\") //Backslash (\) encountered in string
codepos++ //Skip next character in string, since it was escaped by a backslash
- char = copytext(code, codepos, codepos+1)
+ char = TCOMMS_SAFE_INDEX(code, codepos)
switch(char)
if("\\") //Double backslash
buf += "\\"
@@ -190,12 +190,14 @@
Reads characters separated by an item in into a token.
*/
/datum/n_Scanner/nS_Scanner/proc/ReadWord()
- var/char = copytext(code, codepos, codepos + 1)
+ var/char = code[codepos]
var/buf
- while(!delim.Find(char) && codepos <= length(code))
+ while(!delim.Find(char))
buf += char
- char = copytext(code, ++codepos, codepos + 1)
+ if(++codepos > code.len) break
+ char = code[codepos]
+
codepos-- //allow main Scan() proc to read the delimiter
if(options.keywords.Find(buf))
return new/datum/token/keyword(buf, line, COL)
@@ -207,13 +209,13 @@
Reads a symbol into a token.
*/
/datum/n_Scanner/nS_Scanner/proc/ReadSymbol()
- var/char=copytext(code, codepos, codepos + 1)
+ var/char = code[codepos]
var/buf
while(options.symbols.Find(buf + char))
buf += char
- if(++codepos > length(code)) break
- char = copytext(code, codepos, codepos + 1)
+ if(++codepos > code.len) break
+ char = code[codepos]
codepos-- //allow main Scan() proc to read the next character
return new /datum/token/symbol(buf, line, COL)
@@ -223,7 +225,7 @@
Reads a number into a token.
*/
/datum/n_Scanner/nS_Scanner/proc/ReadNumber()
- var/char = copytext(code, codepos, codepos + 1)
+ var/char = code[codepos]
var/buf
var/dec = 0
@@ -233,7 +235,7 @@
buf += char
codepos++
- char = copytext(code, codepos, codepos + 1)
+ char = TCOMMS_SAFE_INDEX(code, codepos)
var/datum/token/number/T = new(buf, line, COL)
if(isnull(text2num(buf)))
@@ -249,8 +251,8 @@
*/
/datum/n_Scanner/nS_Scanner/proc/ReadComment()
- var/char = copytext(code, codepos, codepos + 1)
- var/nextchar = copytext(code, codepos + 1, codepos + 2)
+ var/char = code[codepos]
+ var/nextchar = TCOMMS_SAFE_INDEX(code, codepos + 1)
var/charstring = char + nextchar
var/comm = 1
// 1: single-line comment
@@ -262,23 +264,23 @@
comm = 2 // starts a multi-line comment
while(comm)
- if(++codepos > length(code))
+ if(++codepos > code.len)
break
if(expectedend) // ending statement expected...
- char = copytext(code, codepos, codepos + 1)
+ char = code[codepos]
if(char == "/") // ending statement found - beak the comment
comm = 0
break
if(comm == 2)
// multi-line comments are broken by ending statements
- char = copytext(code, codepos, codepos + 1)
+ char = code[codepos]
if(char == "*")
expectedend = 1
continue
else
- char = copytext(code, codepos, codepos + 1)
+ char = code[codepos]
if(char == "\n")
comm = 0
break
diff --git a/code/modules/scripting/__defines.dm b/code/modules/scripting/__defines.dm
new file mode 100644
index 00000000000..52f30e68fdc
--- /dev/null
+++ b/code/modules/scripting/__defines.dm
@@ -0,0 +1 @@
+#define TCOMMS_SAFE_INDEX(list, index) list.len > index ? list[index] : null
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index c8f36cfa37e..54f4836ff5b 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -1,4 +1,5 @@
//use this define to highlight docking port bounding boxes (ONLY FOR DEBUG USE)
+// also uncomment the #undef at the bottom of the file
//#define DOCKING_PORT_HIGHLIGHT
//NORTH default dir
@@ -909,7 +910,7 @@ var/global/trade_dockrequest_timelimit = 0
shuttleId = "trade_sol"
docking_request_message = "A trading ship of Sol origin has requested docking aboard the NSS Cyberiad for trading. This request can be accepted or denied using a communications console."
-#undef DOCKING_PORT_HIGHLIGHT
+//#undef DOCKING_PORT_HIGHLIGHT
/turf/proc/copyTurf(turf/T)
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index 794e5f69bfe..97e34eee154 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -1,6 +1,6 @@
#define DAMAGE 1
#define FIRE 2
-#define LIGHT 1
+#define POD_LIGHT 1
#define WINDOW 2
#define RIM 3
#define PAINT 4
@@ -78,7 +78,7 @@
var/part = input(user, "Choose part", null) as null|anything in list("Lights","Rim","Paint","Windows")
switch(part)
if("Lights")
- part_type = LIGHT
+ part_type = POD_LIGHT
if("Rim")
part_type = RIM
if("Paint")
@@ -101,7 +101,7 @@
pod_overlays[FIRE] = image(icon, icon_state="pod_fire")
if(!pod_paint_effect)
pod_paint_effect = new/list(4)
- pod_paint_effect[LIGHT] = image(icon,icon_state = "LIGHTS")
+ pod_paint_effect[POD_LIGHT] = image(icon,icon_state = "LIGHTS")
pod_paint_effect[WINDOW] = image(icon,icon_state = "Windows")
pod_paint_effect[RIM] = image(icon,icon_state = "RIM")
pod_paint_effect[PAINT] = image(icon,icon_state = "PAINT")
@@ -162,7 +162,7 @@
if(!pod_paint_effect)
pod_paint_effect = new/list(4)
- pod_paint_effect[LIGHT] = image(icon,icon_state = "LIGHTS")
+ pod_paint_effect[POD_LIGHT] = image(icon,icon_state = "LIGHTS")
pod_paint_effect[WINDOW] = image(icon,icon_state = "Windows")
pod_paint_effect[RIM] = image(icon,icon_state = "RIM")
pod_paint_effect[PAINT] = image(icon,icon_state = "PAINT")
@@ -170,9 +170,9 @@
if(has_paint)
var/image/to_add
- if(!isnull(pod_paint_effect[LIGHT]))
- to_add = pod_paint_effect[LIGHT]
- to_add.color = colors[LIGHT]
+ if(!isnull(pod_paint_effect[POD_LIGHT]))
+ to_add = pod_paint_effect[POD_LIGHT]
+ to_add.color = colors[POD_LIGHT]
overlays += to_add
if(!isnull(pod_paint_effect[WINDOW]))
to_add = pod_paint_effect[WINDOW]
@@ -1077,6 +1077,6 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v
#undef DAMAGE
#undef FIRE
#undef WINDOW
-#undef LIGHT
+#undef POD_LIGHT
#undef RIM
#undef PAINT
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index dfe2c0feb8c..a053b568dc7 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -49,7 +49,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.name] with \the [tool]." , \
"You start applying medication to the damaged bones in [target]'s [affected.name] with \the [tool].")
- target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1)
+ target.custom_pain("Something in your [affected.name] is causing you a lot of pain!")
..()
/datum/surgery_step/glue_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -83,7 +83,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] is beginning to set the bone in [target]'s [affected.name] in place with \the [tool]." , \
"You are beginning to set the bone in [target]'s [affected.name] in place with \the [tool].")
- target.custom_pain("The pain in your [affected.name] is going to make you pass out!",1)
+ target.custom_pain("The pain in your [affected.name] is going to make you pass out!")
..()
/datum/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -136,7 +136,7 @@
"Your hand slips, damaging [target]'s face with \the [tool]!")
var/obj/item/organ/external/head/h = affected
h.receive_damage(10)
- h.disfigured = 1
+ h.disfigure()
return 0
/datum/surgery_step/finish_bone
diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm
index 0e88927e1a2..2ab2aca37c7 100644
--- a/code/modules/surgery/cavity_implant.dm
+++ b/code/modules/surgery/cavity_implant.dm
@@ -78,7 +78,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
"You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!",1)
+ target.custom_pain("The pain in your chest is living hell!")
..()
/datum/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -104,7 +104,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \
"You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!",1)
+ target.custom_pain("The pain in your chest is living hell!")
..()
/datum/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -155,7 +155,7 @@
else //no internal items..but we still need a message!
user.visible_message("[user] checks for items in [target]'s [target_zone].", "You check for items in [target]'s [target_zone]...")
- target.custom_pain("The pain in your [target_zone] is living hell!",1)
+ target.custom_pain("The pain in your [target_zone] is living hell!")
..()
/datum/surgery_step/cavity/place_item/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -190,7 +190,7 @@
if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT)))
to_chat(user, " You tear some vessels trying to fit the object in the cavity.")
affected.internal_bleeding = TRUE
- affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1)
+ affected.owner.custom_pain("You feel something rip in your [affected.name]!")
user.drop_item()
affected.hidden = tool
tool.forceMove(affected)
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index eddf116a45d..b9a33fcecab 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -38,7 +38,7 @@
user.visible_message("[user] begins to cut through [target]'s [affected.encased] with \the [tool].", \
"You begin to cut through [target]'s [affected.encased] with \the [tool].")
- target.custom_pain("Something hurts horribly in your [affected.name]!",1)
+ target.custom_pain("Something hurts horribly in your [affected.name]!")
..()
/datum/surgery_step/open_encased/saw/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -86,7 +86,7 @@
var/msg = "[user] starts to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]."
var/self_msg = "You start to force open the [affected.encased] in [target]'s [affected.name] with \the [tool]."
user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your [affected.name]!",1)
+ target.custom_pain("Something hurts horribly in your [affected.name]!")
..()
/datum/surgery_step/open_encased/retract/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -137,7 +137,7 @@
var/msg = "[user] starts bending [target]'s [affected.encased] back into place with \the [tool]."
var/self_msg = "You start bending [target]'s [affected.encased] back into place with \the [tool]."
user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your [affected.name]!",1)
+ target.custom_pain("Something hurts horribly in your [affected.name]!")
..()
/datum/surgery_step/open_encased/close/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -187,7 +187,7 @@
var/msg = "[user] starts applying \the [tool] to [target]'s [affected.encased]."
var/self_msg = "You start applying \the [tool] to [target]'s [affected.encased]."
user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your [affected.name]!",1)
+ target.custom_pain("Something hurts horribly in your [affected.name]!")
..()
/datum/surgery_step/open_encased/mend/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
deleted file mode 100644
index d96db814b78..00000000000
--- a/code/modules/surgery/face.dm
+++ /dev/null
@@ -1,147 +0,0 @@
-//Procedures in this file: Facial reconstruction surgery
-//////////////////////////////////////////////////////////////////
-// FACE SURGERY //
-//////////////////////////////////////////////////////////////////
-/datum/surgery/plastic_surgery
- name = "Face Repair"
- steps = list(/datum/surgery_step/generic/cut_face, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/face/mend_vocal, /datum/surgery_step/face/fix_face,/datum/surgery_step/face/cauterize)
- possible_locs = list("head")
-
-
-
-/datum/surgery/plastic_surgery/can_start(mob/user, mob/living/carbon/target)
- if(istype(target,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = target
- var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
- if(!affected)
- return 0
- if(affected.status & ORGAN_ROBOT)
- return 0
- if(!affected.disfigured)
- return 0
- return 1
-
-/datum/surgery_step/face
- priority = 2
- can_infect = 0
-
-/datum/surgery_step/generic/cut_face
- name = "make incision"
- allowed_tools = list(
- /obj/item/scalpel = 100, \
- /obj/item/kitchen/knife = 90, \
- /obj/item/shard = 60, \
- )
-
- time = 16
-
-/datum/surgery_step/generic/cut_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \
- "You start to cut open [target]'s face and neck with \the [tool].")
- ..()
-
-/datum/surgery_step/generic/cut_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message(" [user] has cut open [target]'s face and neck with \the [tool]." , \
- " You have cut open [target]'s face and neck with \the [tool].",)
-
- return 1
-
-/datum/surgery_step/generic/cut_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \
- " Your hand slips, slicing [target]'s throat wth \the [tool]!" )
- affected.receive_damage(60)
- target.AdjustLoseBreath(4)
-
- return 0
-
-/datum/surgery_step/face/mend_vocal
- name = "mend vocal cords"
- allowed_tools = list(
- /obj/item/scalpel/laser/manager = 100, \
- /obj/item/hemostat = 100, \
- /obj/item/stack/cable_coil = 90, \
- /obj/item/assembly/mousetrap = 12 //I don't know. Don't ask me. But I'm leaving it because hilarity.
- )
-
- time = 24
-
-/datum/surgery_step/face/mend_vocal/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \
- "You start mending [target]'s vocal cords with \the [tool].")
- ..()
-
-/datum/surgery_step/face/mend_vocal/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message(" [user] mends [target]'s vocal cords with \the [tool].", \
- " You mend [target]'s vocal cords with \the [tool].")
- return 1
-
-/datum/surgery_step/face/mend_vocal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message(" [user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \
- " Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!")
- target.AdjustLoseBreath(4)
- return 0
-
-/datum/surgery_step/face/fix_face
- name = "reshape face"
- allowed_tools = list(
- /obj/item/scalpel/laser/manager = 100, \
- /obj/item/retractor = 100, \
- /obj/item/crowbar = 65, \
- /obj/item/kitchen/utensil/fork = 90)
-
- time = 64
-
-/datum/surgery_step/face/fix_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \
- "You start pulling skin on [target]'s face back in place with \the [tool].")
- ..()
-
-/datum/surgery_step/face/fix_face/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message(" [user] pulls skin on [target]'s face back in place with \the [tool].", \
- " You pull skin on [target]'s face back in place with \the [tool].")
- return 1
-
-/datum/surgery_step/face/fix_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \
- " Your hand slips, tearing skin on [target]'s face with \the [tool]!")
- target.apply_damage(10, BRUTE, affected, sharp = 1)
- return 0
-
-/datum/surgery_step/face/cauterize
- name = "close incision"
- allowed_tools = list(
- /obj/item/scalpel/laser = 100, \
- /obj/item/cautery = 100, \
- /obj/item/clothing/mask/cigarette = 90, \
- /obj/item/lighter = 60, \
- /obj/item/weldingtool = 30
- )
-
- time = 24
-
-/datum/surgery_step/face/cauterize/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \
- "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].")
- ..()
-
-/datum/surgery_step/face/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \
- " You cauterize the incision on [target]'s face and neck with \the [tool].")
- affected.open = 0
- var/obj/item/organ/external/head/h = affected
- h.disfigured = 0
- h.update_icon()
- target.regenerate_icons()
-
- return 1
-
-/datum/surgery_step/face/cauterize/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message(" [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \
- " Your hand slips, leaving a small burn on [target]'s face with \the [tool]!")
- target.apply_damage(4, BURN, affected)
-
- return 0
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index 158656f8c01..1e1b3a10365 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -37,7 +37,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts the incision on [target]'s [affected.name] with \the [tool].", \
"You start the incision on [target]'s [affected.name] with \the [tool].")
- target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!",1)
+ target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.name]!")
..()
/datum/surgery_step/generic/cut_open/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -71,7 +71,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts clamping bleeders in [target]'s [affected.name] with \the [tool].", \
"You start clamping bleeders in [target]'s [affected.name] with \the [tool].")
- target.custom_pain("The pain in your [affected.name] is maddening!",1)
+ target.custom_pain("The pain in your [affected.name] is maddening!")
..()
/datum/surgery_step/generic/clamp_bleeders/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -111,7 +111,7 @@
msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]."
self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]."
user.visible_message(msg, self_msg)
- target.custom_pain("It feels like the skin on your [affected.name] is on fire!",1)
+ target.custom_pain("It feels like the skin on your [affected.name] is on fire!")
..()
/datum/surgery_step/generic/retract_skin/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -160,7 +160,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.name] with \the [tool]." , \
"You are beginning to cauterize the incision on [target]'s [affected.name] with \the [tool].")
- target.custom_pain("Your [affected.name] is being burned!",1)
+ target.custom_pain("Your [affected.name] is being burned!")
..()
/datum/surgery_step/generic/cauterize/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -219,7 +219,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] is beginning to amputate [target]'s [affected.name] with \the [tool]." , \
"You are beginning to cut through [target]'s [affected.amputation_point] with \the [tool].")
- target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1)
+ target.custom_pain("Your [affected.amputation_point] is being ripped apart!")
..()
/datum/surgery_step/generic/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm
index 7518cc701af..c36df974ea3 100644
--- a/code/modules/surgery/implant_removal.dm
+++ b/code/modules/surgery/implant_removal.dm
@@ -45,7 +45,7 @@
I = locate(/obj/item/implant) in target
user.visible_message("[user] starts poking around inside [target]'s [affected.name] with \the [tool].", \
"You start poking around inside [target]'s [affected.name] with \the [tool]." )
- target.custom_pain("The pain in your [affected.name] is living hell!",1)
+ target.custom_pain("The pain in your [affected.name] is living hell!")
..()
/datum/surgery_step/extract_implant/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index 8a29c148253..4908133d2c0 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -30,6 +30,7 @@
var/sterile = FALSE //can the organ be infected by germs?
var/tough = FALSE //can organ be easily damaged?
var/emp_proof = FALSE //is the organ immune to EMPs?
+ var/hidden_pain = FALSE //will it skip pain messages?
/obj/item/organ/Destroy()
@@ -232,7 +233,7 @@
if(owner && parent_organ && amount > 0)
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
if(parent && !silent)
- owner.custom_pain("Something inside your [parent.name] hurts a lot.", 1)
+ owner.custom_pain("Something inside your [parent.name] hurts a lot.")
//check if we've hit max_damage
if(damage >= max_damage)
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index 794c19e2655..960ce7c0da1 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -239,7 +239,6 @@
#undef LIMB_SHARP_THRESH_INT_DMG
#undef LIMB_THRESH_INT_DMG
#undef LIMB_DMG_PROB
-#undef LIMB_NO_BONE_DMG_PROB
/obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0)
if(status & ORGAN_ROBOT && !robo_repair)
@@ -273,8 +272,7 @@ This function completely restores a damaged organ to perfect condition.
burn_dam = 0
open = 0 //Closing all wounds.
internal_bleeding = FALSE
- if(istype(src, /obj/item/organ/external/head) && disfigured) //If their head's disfigured, refigure it.
- disfigured = 0
+ disfigured = FALSE
// handle internal organs
for(var/obj/item/organ/internal/current_organ in internal_organs)
@@ -409,7 +407,7 @@ Note that amputating the affected organ does in fact remove the infection from t
var/local_damage = brute_dam + damage
if(damage > 15 && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT))
internal_bleeding = TRUE
- owner.custom_pain("You feel something rip in your [name]!", 1)
+ owner.custom_pain("You feel something rip in your [name]!")
// new damage icon system
// returns just the brute/burn damage code
@@ -737,19 +735,14 @@ Note that amputating the affected organ does in fact remove the infection from t
qdel(spark_system)
qdel(src)
-/obj/item/organ/external/proc/disfigure(var/type = "brute")
+/obj/item/organ/external/proc/disfigure()
if(disfigured)
return
if(owner)
- if(type == "brute")
- owner.visible_message("You hear a sickening cracking sound coming from \the [owner]'s [name].", \
- "Your [name] becomes a mangled mess!", \
- "You hear a sickening crack.")
- else
- owner.visible_message("\The [owner]'s [name] melts away, turning into mangled mess!", \
- "Your [name] melts away!", \
- "You hear a sickening sizzle.")
- disfigured = 1
+ owner.visible_message("You hear a sickening sound coming from \the [owner]'s [name] as it turns into a mangled mess!", \
+ "Your [name] becomes a mangled mess!", \
+ "You hear a sickening sound.")
+ disfigured = TRUE
/obj/item/organ/external/is_primary_organ(var/mob/living/carbon/human/O = null)
if(isnull(O))
diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm
index d107c7439c6..e3386aef1b3 100644
--- a/code/modules/surgery/organs/pain.dm
+++ b/code/modules/surgery/organs/pain.dm
@@ -1,41 +1,28 @@
-mob/var/list/pain_stored = list()
-mob/var/last_pain_message = ""
-mob/var/next_pain_time = 0
+/mob/living/carbon/human
+ var/last_pain_message = ""
+ var/next_pain_time = 0
// partname is the name of a body part
// amount is a num from 1 to 100
-mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0)
- if(stat >= 2) return
+/mob/living/carbon/human/proc/pain(partname, amount)
+ if(stat >= UNCONSCIOUS)
+ return
if(reagents.has_reagent("sal_acid"))
return
if(reagents.has_reagent("morphine"))
return
if(reagents.has_reagent("hydrocodone"))
return
- if(world.time < next_pain_time && !force)
+ if(world.time < next_pain_time)
return
- if(amount > 10 && istype(src,/mob/living/carbon/human))
- if(paralysis)
- AdjustParalysis(-round(amount/10))
- if(amount > 50 && prob(amount / 5))
- src:drop_item()
var/msg
- if(burning)
- switch(amount)
- if(1 to 10)
- msg = "Your [partname] burns."
- if(11 to 90)
- msg = "Your [partname] burns badly!"
- if(91 to 10000)
- msg = "OH GOD! Your [partname] is on fire!"
- else
- switch(amount)
- if(1 to 10)
- msg = "Your [partname] hurts."
- if(11 to 90)
- msg = "Your [partname] hurts badly."
- if(91 to 10000)
- msg = "OH GOD! Your [partname] is hurting terribly!"
+ switch(amount)
+ if(1 to 10)
+ msg = "Your [partname] hurts."
+ if(11 to 90)
+ msg = "Your [partname] hurts badly."
+ if(91 to INFINITY)
+ msg = "OH GOD! Your [partname] is hurting terribly!"
if(msg && (msg != last_pain_message || prob(10)))
last_pain_message = msg
to_chat(src, msg)
@@ -43,20 +30,18 @@ mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0
// message is the custom message to be displayed
-// flash_strength is 0 for weak pain flash, 1 for strong pain flash
-mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength)
- if(stat >= 1) return
+mob/living/carbon/human/proc/custom_pain(message)
+ if(stat >= UNCONSCIOUS)
+ return
if(NO_PAIN in species.species_traits)
return
-
if(reagents.has_reagent("morphine"))
return
if(reagents.has_reagent("hydrocodone"))
return
- var/msg = "[message]"
- if(flash_strength >= 1)
- msg = "[message]"
+
+ var/msg = "[message]"
// Anti message spam checks
if(msg && ((msg != last_pain_message) || (world.time >= next_pain_time)))
@@ -67,70 +52,33 @@ mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength)
mob/living/carbon/human/proc/handle_pain()
// not when sleeping
- if(NO_PAIN in species.species_traits)
- //While synthetics don't feel pain, they will notice their gears gunking up with residue (toxins)
- if(isSynthetic())
- var/toxDamageMessage = null
- var/toxMessageProb = 1
- switch(getToxLoss())
- if(25 to 50)
- toxMessageProb = 1
- toxDamageMessage = "Your servos seem to be working harder."
- if(50 to 75)
- toxMessageProb = 2
- toxDamageMessage = "Your joints seem to stick randomly."
- if(75 to INFINITY)
- toxMessageProb = 5
- toxDamageMessage = "Your motors seem to slip; it really grinds your gears!"
- if(toxDamageMessage && prob(toxMessageProb))
- src.custom_pain(toxDamageMessage, getToxLoss() >= 15)
+ if(stat >= UNCONSCIOUS)
+ return
+ if(NO_PAIN in species.species_traits)
return
-
- if(stat >= 2) return
if(reagents.has_reagent("morphine"))
return
if(reagents.has_reagent("hydrocodone"))
return
+
var/maxdam = 0
var/obj/item/organ/external/damaged_organ = null
for(var/obj/item/organ/external/E in bodyparts)
- if(E.status & ORGAN_DEAD|ORGAN_ROBOT) continue
+ if((E.status & ORGAN_DEAD|ORGAN_ROBOT) || E.hidden_pain)
+ continue
var/dam = E.get_damage()
// make the choice of the organ depend on damage,
// but also sometimes use one of the less damaged ones
- if(dam > maxdam && (maxdam == 0 || prob(70)) )
+ if(dam > maxdam && (maxdam == 0 || prob(70)))
damaged_organ = E
maxdam = dam
if(damaged_organ)
- pain(damaged_organ.name, maxdam, 0)
-
+ pain(damaged_organ.name, maxdam)
// Damage to internal organs hurts a lot.
for(var/obj/item/organ/internal/I in internal_organs)
- if(istype(I, /obj/item/organ/internal/brain)) //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type.
+ if(I.hidden_pain)
continue
- if(I.damage > 2) if(prob(2))
+ if(I.damage > 2 && prob(2))
var/obj/item/organ/external/parent = get_organ(I.parent_organ)
- src.custom_pain("You feel a sharp pain in your [parent.limb_name]", 1)
-
- var/toxDamageMessage = null
- var/toxMessageProb = 1
- switch(getToxLoss())
- if(1 to 5)
- toxMessageProb = 1
- toxDamageMessage = "Your body stings slightly."
- if(6 to 10)
- toxMessageProb = 2
- toxDamageMessage = "Your whole body hurts a little."
- if(11 to 15)
- toxMessageProb = 2
- toxDamageMessage = "Your whole body hurts."
- if(15 to 25)
- toxMessageProb = 3
- toxDamageMessage = "Your whole body hurts badly."
- if(26 to INFINITY)
- toxMessageProb = 5
- toxDamageMessage = "Your body aches all over, it's driving you mad."
-
- if(toxDamageMessage && prob(toxMessageProb))
- src.custom_pain(toxDamageMessage, getToxLoss() >= 15)
+ custom_pain("You feel a sharp pain in your [parent.limb_name]")
\ No newline at end of file
diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm
index 3fd8effd56a..30c4e173cdc 100644
--- a/code/modules/surgery/organs/subtypes/standard.dm
+++ b/code/modules/surgery/organs/subtypes/standard.dm
@@ -211,11 +211,8 @@
/obj/item/organ/external/head/receive_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE)
..(brute, burn, sharp, used_weapon, forbidden_limbs, ignore_resists)
if(!disfigured)
- if(brute_dam > 40)
- if(prob(50))
- disfigure("brute")
- if(burn_dam > 40)
- disfigure("burn")
+ if(brute_dam + burn_dam > 50)
+ disfigure()
/obj/item/organ/external/head/proc/handle_alt_icon()
if(alt_head && alt_heads_list[alt_head])
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index 1af925c3166..4c0094592e9 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -116,7 +116,7 @@
if(affected)
user.visible_message("[user] starts transplanting [tool] into [target]'s [affected.name].", \
"You start transplanting [tool] into [target]'s [affected.name].")
- H.custom_pain("Someone's rooting around in your [affected.name]!",1)
+ H.custom_pain("Someone's rooting around in your [affected.name]!")
else
user.visible_message("[user] starts transplanting [tool] into [target]'s [parse_zone(target_zone)].", \
"You start transplanting [tool] into [target]'s [parse_zone(target_zone)].")
@@ -143,7 +143,7 @@
self_msg = "You begin injecting [tool] into [target]'s [I.name]."
user.visible_message(msg, self_msg)
if(H && affected)
- H.custom_pain("Something burns horribly in your [affected.name]!",1)
+ H.custom_pain("Something burns horribly in your [affected.name]!")
else if(implement_type in implements_finsh)
//same as surgery step /datum/surgery_step/open_encased/close/
@@ -159,7 +159,7 @@
user.visible_message(msg, self_msg)
if(H && affected)
- H.custom_pain("Something hurts horribly in your [affected.name]!",1)
+ H.custom_pain("Something hurts horribly in your [affected.name]!")
else if(implement_type in implements_extract)
current_type = "extract"
@@ -188,7 +188,7 @@
user.visible_message("[user] starts to separate [target]'s [I] with [tool].", \
"You start to separate [target]'s [I] with [tool] for removal." )
if(H && affected)
- H.custom_pain("The pain in your [affected.name] is living hell!",1)
+ H.custom_pain("The pain in your [affected.name] is living hell!")
else
return -1
@@ -221,7 +221,7 @@
to_chat(user, "[I] does not appear to be damaged.")
if(affected)
- H.custom_pain("The pain in your [affected.name] is living hell!", 1)
+ H.custom_pain("The pain in your [affected.name] is living hell!")
else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ))
to_chat(user, "[tool] was bitten by someone! It's too damaged to use!")
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 012f7ad3c5b..455a6a8de04 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -80,7 +80,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.name] with \the [tool]." , \
"You start patching the damaged vein in [target]'s [affected.name] with \the [tool].")
- target.custom_pain("The pain in [affected.name] is unbearable!",1)
+ target.custom_pain("The pain in [affected.name] is unbearable!")
..()
/datum/surgery_step/fix_vein/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -133,7 +133,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]." , \
"You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].")
- target.custom_pain("The pain in [affected.name] is unbearable!",1)
+ target.custom_pain("The pain in [affected.name] is unbearable!")
..()
/datum/surgery_step/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -191,7 +191,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]." , \
"You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].")
- target.custom_pain("Something in your [affected.name] is causing you a lot of pain!",1)
+ target.custom_pain("Something in your [affected.name] is causing you a lot of pain!")
..()
/datum/surgery_step/treat_necrosis/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
@@ -241,7 +241,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery/remove_thrall
name = "Remove Shadow Tumor"
- steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/open_encased/saw,/datum/surgery_step/open_encased/retract, /datum/surgery_step/internal/dethrall, /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone,/datum/surgery_step/finish_bone,/datum/surgery_step/generic/cauterize)
+ steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/dethrall, /datum/surgery_step/generic/cauterize)
possible_locs = list("head", "chest", "groin")
/datum/surgery/remove_thrall/synth
diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm
new file mode 100644
index 00000000000..4d14d2e8a79
--- /dev/null
+++ b/code/modules/surgery/plastic_surgery.dm
@@ -0,0 +1,56 @@
+/datum/surgery/plastic_surgery
+ name = "Plastic Surgery"
+ steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/reshape_face, /datum/surgery_step/generic/cauterize)
+ possible_locs = list("head")
+
+/datum/surgery/plastic_surgery/can_start(mob/user, mob/living/carbon/target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ var/obj/item/organ/external/head/head = H.get_organ(user.zone_sel.selecting)
+ if(!head)
+ return FALSE
+ if(head.status & ORGAN_ROBOT)
+ return FALSE
+ return TRUE
+
+
+/datum/surgery_step/reshape_face
+ name = "reshape face"
+ allowed_tools = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, /obj/item/wirecutters = 35)
+ time = 64
+
+/datum/surgery_step/reshape_face/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to alter [target]'s appearance.", "You begin to alter [target]'s appearance...")
+
+/datum/surgery_step/reshape_face/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/organ/external/head/head = target.get_organ(target_zone)
+ var/species_names = target.get_species()
+ if(head.disfigured)
+ head.disfigured = FALSE
+ user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.")
+ else
+ var/list/names = list()
+ if(!isabductor(user))
+ for(var/i in 1 to 10)
+ names += random_name(target.gender, species_names)
+ else
+ for(var/_i in 1 to 9)
+ names += "Subject [target.gender == MALE ? "i" : "o"]-[pick("a", "b", "c", "d", "e")]-[rand(10000, 99999)]"
+ names += random_name(target.gender, species_names) //give one normal name in case they want to do regular plastic surgery
+ var/chosen_name = input(user, "Choose a new name to assign.", "Plastic Surgery") as null|anything in names
+ if(!chosen_name)
+ return
+ var/oldname = target.real_name
+ target.real_name = chosen_name
+ var/newname = target.real_name //something about how the code handles names required that I use this instead of target.real_name
+ user.visible_message("[user] alters [oldname]'s appearance completely, [target.p_they()] [target.p_are()] now [newname]!", "You alter [oldname]'s appearance completely, [target.p_they()] [target.p_are()] now [newname].")
+ target.sec_hud_set_ID()
+ return TRUE
+
+
+/datum/surgery_step/reshape_face/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/obj/item/organ/external/head/head = target.get_organ(target_zone)
+ user.visible_message(" [user]'s hand slips, tearing skin on [target]'s face with [tool]!", \
+ " Your hand slips, tearing skin on [target]'s face with [tool]!")
+ target.apply_damage(10, BRUTE, head, sharp = TRUE)
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 58b570eb5e3..ed82328c47d 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -248,10 +248,7 @@
user.visible_message(" [user] finishes patching damage to [target]'s [affected.name] with \the [tool].", \
" You finish patching damage to [target]'s [affected.name] with \the [tool].")
affected.heal_damage(rand(30,50),0,1,1)
- if(affected.disfigured)
- affected.disfigured = 0
- affected.update_icon()
- target.regenerate_icons()
+ affected.disfigured = FALSE
if("burn")
user.visible_message(" [user] finishes splicing cable into [target]'s [affected.name].", \
" You finishes splicing new cable into [target]'s [affected.name].")
@@ -325,7 +322,7 @@
user.visible_message("[user] begins reattaching [target]'s [tool].", \
"You start reattaching [target]'s [tool].")
- target.custom_pain("Someone's rooting around in your [affected.name]!",1)
+ target.custom_pain("Someone's rooting around in your [affected.name]!")
else if(istype(tool,/obj/item/mmi))
current_type = "install"
@@ -386,7 +383,7 @@
user.visible_message("[user] starts to decouple [target]'s [I] with \the [tool].", \
"You start to decouple [target]'s [I] with \the [tool]." )
- target.custom_pain("The pain in your [affected.name] is living hell!",1)
+ target.custom_pain("The pain in your [affected.name] is living hell!")
else
return -1
@@ -407,7 +404,7 @@
to_chat(user, "There are no damaged components in [affected].")
return -1
- target.custom_pain("The pain in your [affected.name] is living hell!",1)
+ target.custom_pain("The pain in your [affected.name] is living hell!")
else if(implement_type in implements_finish)
current_type = "finish"
@@ -522,7 +519,7 @@
user.visible_message("[user] starts to decouple [target]'s [affected.name] with \the [tool].", \
"You start to decouple [target]'s [affected.name] with \the [tool]." )
- target.custom_pain("Your [affected.amputation_point] is being ripped apart!",1)
+ target.custom_pain("Your [affected.amputation_point] is being ripped apart!")
..()
/datum/surgery_step/robotics/external/amputate/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery)
diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt
index a962b4b685c..37768b61732 100644
--- a/config/example/dbconfig.txt
+++ b/config/example/dbconfig.txt
@@ -9,7 +9,7 @@
## This value must be set to the version of the paradise schema in use.
## If this value does not match, the SQL database will not be loaded and an error will be generated.
## Roundstart will be delayed.
-DB_VERSION 2
+DB_VERSION 3
## Server the MySQL database can be found at.
# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc.
diff --git a/html/changelog.html b/html/changelog.html
index 464012c5cb9..dc33ff72343 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,97 @@
-->
+
13 June 2018
+
Aurorablade updated:
+
+
Fluff for Panzerskull
+
+
Fox McCloud updated:
+
+
Medibots now actually talk, like beepsky
+
Adds Plastic surgery; fix someone's face or give them a new identity!
+
Having more than 50 cloneloss will render you "Unknown"
+
head disfigurement requires you to have more than 50 combined brute and burn damage, rather than tracking it separately
+
Fixes Cryoxadone and Rezadone not fixing disfigurement, Fixes fluorosulfuric acid not causing disfigurement at proper thresholds
+
Fixes syndicate medibot not being constructable from tactical medkits
+
Syndicate medibot and the mysterious medibot are better at treating brute and burn damage
+
+
MINIMAN10000 updated:
+
+
Airlock electronics lock
+
Airlock electronics close button
+
+
Piccione updated:
+
+
Added Magboots to the Paramedic's EVA gear closet
+
+
Tayyyyyyy updated:
+
+
Shadowling dethrall has been shortened to scalpel, hemostat, retractor, shine light, cautery
+
+
+
11 June 2018
+
FalseIncarnate updated:
+
+
Food on utensils now properly inherits the name of the source dish.
+
Joined Souls rune can now properly can summon restrained targets with 3+ invokers.
+
+
+
09 June 2018
+
Fox McCloud updated:
+
+
Fixes holobarrier icons being missing
+
+
+
08 June 2018
+
Alffd updated:
+
+
Adds an automated emergency var on air alarms for mappers
+
+
Anasari updated:
+
+
Fixes admin log for spray displaying (0,0,0) all the time.
+
+
Desolate updated:
+
+
ED-209 code corrected to work properly. Floorbot code corrected to work properly.
+
+
and Dumbdumb updated:
+
+
Unathi and Vox Sec Hardsuit update
+
+
+
05 June 2018
+
Kyep updated:
+
+
The Terror Spider away mission now has spiders colonizing the west side of the map. Only the gateway room is safe.
+
+
+
04 June 2018
+
Fox McCloud updated:
+
+
Hulk mutation no longer works at range (ie: punching/breaking windows/walls at range)
+
You must be on harm intent to damage things if you have hulk
+
Having hulk allows you to punch and damage just about anything
+
+
uraniummeltdown updated:
+
+
You can smelt titanium and glass together to form titanium glass for building shuttle windows
+
You can smelt titanium, plasma and glass together to form plastitanium glass for building plastitanium windows
+
Fulltile windows now smooth, windows crack as they get damaged and can be repaired with help intent welder
+
Windows have deconstruction hints and show whether they can be rotated or not
+
Plasma glass no longer gets auto-colored
+
RCDs can deconstruct airlocks again, they have no force now though
+
Wielded fireaxe does a lot of damage to windows and grilles instead of just deleting them
+
Glass stacks now use stack recipes instead of a custom menu
+
+
+
31 May 2018
+
FalseIncarnate updated:
+
+
The singulo no longer feeds on attention.
+
+
26 May 2018
Birdtalon updated:
@@ -64,7 +155,7 @@
Citinited updated:
-
Hopefully fixes all issues with disposals sending you to disposals.
+
Hopefully fixes all issues with disposals sending you to nullspace.
Fox McCloud updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 04b66ec89a7..9304a5f6086 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -6426,7 +6426,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
for charger models.
- bugfix: laser tag gun projectiles now play appropriate sound when striking.
Citinited:
- - bugfix: Hopefully fixes all issues with disposals sending you to disposals.
+ - bugfix: Hopefully fixes all issues with disposals sending you to nullspace.
Fox McCloud:
- bugfix: Fixes not being able to propel yourself through space by farting if you
possessed both superfart and toxic farts
@@ -6437,3 +6437,70 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- bugfix: Newscasters properly check for feed channel creation and wanted issue
creation
- bugfix: ERT should deploy properly without admins now.
+2018-05-31:
+ FalseIncarnate:
+ - bugfix: The singulo no longer feeds on attention.
+2018-06-04:
+ Fox McCloud:
+ - bugfix: 'Hulk mutation no longer works at range (ie: punching/breaking windows/walls
+ at range)'
+ - tweak: You must be on harm intent to damage things if you have hulk
+ - rscadd: Having hulk allows you to punch and damage just about anything
+ uraniummeltdown:
+ - rscadd: You can smelt titanium and glass together to form titanium glass for building
+ shuttle windows
+ - rscadd: You can smelt titanium, plasma and glass together to form plastitanium
+ glass for building plastitanium windows
+ - rscadd: Fulltile windows now smooth, windows crack as they get damaged and can
+ be repaired with help intent welder
+ - rscadd: Windows have deconstruction hints and show whether they can be rotated
+ or not
+ - bugfix: Plasma glass no longer gets auto-colored
+ - bugfix: RCDs can deconstruct airlocks again, they have no force now though
+ - tweak: Wielded fireaxe does a lot of damage to windows and grilles instead of
+ just deleting them
+ - tweak: Glass stacks now use stack recipes instead of a custom menu
+2018-06-05:
+ Kyep:
+ - bugfix: The Terror Spider away mission now has spiders colonizing the west side
+ of the map. Only the gateway room is safe.
+2018-06-08:
+ Alffd:
+ - rscadd: Adds an automated emergency var on air alarms for mappers
+ Anasari:
+ - bugfix: Fixes admin log for spray displaying (0,0,0) all the time.
+ Desolate:
+ - bugfix: ED-209 code corrected to work properly. Floorbot code corrected to work
+ properly.
+ and Dumbdumb:
+ - rscadd: Unathi and Vox Sec Hardsuit update
+2018-06-09:
+ Fox McCloud:
+ - bugfix: Fixes holobarrier icons being missing
+2018-06-11:
+ FalseIncarnate:
+ - bugfix: Food on utensils now properly inherits the name of the source dish.
+ - bugfix: Joined Souls rune can now properly can summon restrained targets with
+ 3+ invokers.
+2018-06-13:
+ Aurorablade:
+ - rscadd: Fluff for Panzerskull
+ Fox McCloud:
+ - rscadd: Medibots now actually talk, like beepsky
+ - rscadd: Adds Plastic surgery; fix someone's face or give them a new identity!
+ - tweak: Having more than 50 cloneloss will render you "Unknown"
+ - tweak: head disfigurement requires you to have more than 50 combined brute and
+ burn damage, rather than tracking it separately
+ - bugfix: Fixes Cryoxadone and Rezadone not fixing disfigurement, Fixes fluorosulfuric
+ acid not causing disfigurement at proper thresholds
+ - bugfix: Fixes syndicate medibot not being constructable from tactical medkits
+ - tweak: Syndicate medibot and the mysterious medibot are better at treating brute
+ and burn damage
+ MINIMAN10000:
+ - rscdel: Airlock electronics lock
+ - bugfix: Airlock electronics close button
+ Piccione:
+ - rscadd: Added Magboots to the Paramedic's EVA gear closet
+ Tayyyyyyy:
+ - tweak: Shadowling dethrall has been shortened to scalpel, hemostat, retractor,
+ shine light, cautery
diff --git a/html/changelogs/AutoChangeLog-pr-9066.yml b/html/changelogs/AutoChangeLog-pr-9066.yml
new file mode 100644
index 00000000000..82fb8ff76dc
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9066.yml
@@ -0,0 +1,4 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "Toxin damage is stealthier and will no longer cause stinging spam message"
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index 2fdc968ebd6..a5195cc0167 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index fa6f26fefe6..060d8b77a27 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi
index f969705ec83..14b099f3f45 100644
Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ
diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi
index ebbfa5f9c73..1d0bcf81f27 100644
Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ
diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi
index c9227ce2119..bf06b4d2057 100644
Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ
diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi
index ca8289a3ccb..a3d89179bf6 100644
Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ
diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi
index b3f92a3b57f..db92d8c21a6 100644
Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index a63ff4f5daa..d1aa0e9805a 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/clothing/species/unathi/hats.dmi b/icons/obj/clothing/species/unathi/hats.dmi
index be2fb4f62aa..1ee46571f66 100644
Binary files a/icons/obj/clothing/species/unathi/hats.dmi and b/icons/obj/clothing/species/unathi/hats.dmi differ
diff --git a/icons/obj/clothing/species/unathi/suits.dmi b/icons/obj/clothing/species/unathi/suits.dmi
index 34c3ea75105..30b590cc7ed 100644
Binary files a/icons/obj/clothing/species/unathi/suits.dmi and b/icons/obj/clothing/species/unathi/suits.dmi differ
diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi
index 940f2ba25da..8296c4ceb7d 100644
Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ
diff --git a/icons/obj/doors/windoor.dmi b/icons/obj/doors/windoor.dmi
index 8104686b483..9bf105faaf6 100644
Binary files a/icons/obj/doors/windoor.dmi and b/icons/obj/doors/windoor.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 22dc1384904..288785052cd 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index d828f2ee9de..5714fcf4c9f 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/smooth_structures/clockwork_window.dmi b/icons/obj/smooth_structures/clockwork_window.dmi
new file mode 100644
index 00000000000..90309ac3d52
Binary files /dev/null and b/icons/obj/smooth_structures/clockwork_window.dmi differ
diff --git a/icons/obj/smooth_structures/plasma_window.dmi b/icons/obj/smooth_structures/plasma_window.dmi
new file mode 100644
index 00000000000..3d57d156f01
Binary files /dev/null and b/icons/obj/smooth_structures/plasma_window.dmi differ
diff --git a/icons/obj/smooth_structures/plastitanium_window.dmi b/icons/obj/smooth_structures/plastitanium_window.dmi
new file mode 100644
index 00000000000..82ac0306159
Binary files /dev/null and b/icons/obj/smooth_structures/plastitanium_window.dmi differ
diff --git a/icons/obj/smooth_structures/pod_window.dmi b/icons/obj/smooth_structures/pod_window.dmi
new file mode 100644
index 00000000000..0fe7501225c
Binary files /dev/null and b/icons/obj/smooth_structures/pod_window.dmi differ
diff --git a/icons/obj/smooth_structures/reinforced_window.dmi b/icons/obj/smooth_structures/reinforced_window.dmi
index b5f24ebbd30..ed9a2a143e6 100644
Binary files a/icons/obj/smooth_structures/reinforced_window.dmi and b/icons/obj/smooth_structures/reinforced_window.dmi differ
diff --git a/icons/obj/smooth_structures/rice_window.dmi b/icons/obj/smooth_structures/rice_window.dmi
index e3a82935cf2..f5e7a6dd57a 100644
Binary files a/icons/obj/smooth_structures/rice_window.dmi and b/icons/obj/smooth_structures/rice_window.dmi differ
diff --git a/icons/obj/smooth_structures/rplasma_window.dmi b/icons/obj/smooth_structures/rplasma_window.dmi
new file mode 100644
index 00000000000..c64f42c7f5a
Binary files /dev/null and b/icons/obj/smooth_structures/rplasma_window.dmi differ
diff --git a/icons/obj/smooth_structures/shuttle_window.dmi b/icons/obj/smooth_structures/shuttle_window.dmi
index 3db34cf1ba1..85924dc449b 100644
Binary files a/icons/obj/smooth_structures/shuttle_window.dmi and b/icons/obj/smooth_structures/shuttle_window.dmi differ
diff --git a/icons/obj/smooth_structures/tinted_window.dmi b/icons/obj/smooth_structures/tinted_window.dmi
index ab992353275..be9affafeea 100644
Binary files a/icons/obj/smooth_structures/tinted_window.dmi and b/icons/obj/smooth_structures/tinted_window.dmi differ
diff --git a/icons/obj/smooth_structures/window.dmi b/icons/obj/smooth_structures/window.dmi
index 0197f5b20a7..670713bcfe0 100644
Binary files a/icons/obj/smooth_structures/window.dmi and b/icons/obj/smooth_structures/window.dmi differ
diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi
index 997642dcf29..d4b8e837db6 100755
Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index 0b17038ade5..838503bbda1 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 62908577586..530eff9fc13 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -224,6 +224,7 @@
#include "code\datums\datum.dm"
#include "code\datums\datumvars.dm"
#include "code\datums\gas_mixture.dm"
+#include "code\datums\holocall.dm"
#include "code\datums\hud.dm"
#include "code\datums\mind.dm"
#include "code\datums\mixed.dm"
@@ -630,7 +631,6 @@
#include "code\game\machinery\computer\computer.dm"
#include "code\game\machinery\computer\crew.dm"
#include "code\game\machinery\computer\HolodeckControl.dm"
-#include "code\game\machinery\computer\hologram.dm"
#include "code\game\machinery\computer\honkputer.dm"
#include "code\game\machinery\computer\law.dm"
#include "code\game\machinery\computer\medical.dm"
@@ -960,7 +960,6 @@
#include "code\game\objects\structures\false_walls.dm"
#include "code\game\objects\structures\flora.dm"
#include "code\game\objects\structures\foodcart.dm"
-#include "code\game\objects\structures\fullwindow.dm"
#include "code\game\objects\structures\girders.dm"
#include "code\game\objects\structures\grille.dm"
#include "code\game\objects\structures\guillotine.dm"
@@ -2106,6 +2105,7 @@
#include "code\modules\research\xenobiology\xenobio_camera.dm"
#include "code\modules\research\xenobiology\xenobiology.dm"
#include "code\modules\ruins\ruin_areas.dm"
+#include "code\modules\scripting\__defines.dm"
#include "code\modules\scripting\Errors.dm"
#include "code\modules\scripting\Options.dm"
#include "code\modules\scripting\AST\AST Nodes.dm"
@@ -2156,7 +2156,6 @@
#include "code\modules\surgery\cavity_implant.dm"
#include "code\modules\surgery\dental_implant.dm"
#include "code\modules\surgery\encased.dm"
-#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
#include "code\modules\surgery\helpers.dm"
#include "code\modules\surgery\implant_removal.dm"
@@ -2164,6 +2163,7 @@
#include "code\modules\surgery\limb_reattach.dm"
#include "code\modules\surgery\organs_internal.dm"
#include "code\modules\surgery\other.dm"
+#include "code\modules\surgery\plastic_surgery.dm"
#include "code\modules\surgery\remove_embedded_object.dm"
#include "code\modules\surgery\rig_removal.dm"
#include "code\modules\surgery\robotics.dm"
diff --git a/sound/voice/mapple.ogg b/sound/voice/mapple.ogg
new file mode 100644
index 00000000000..21e26742ca1
Binary files /dev/null and b/sound/voice/mapple.ogg differ
diff --git a/sound/voice/mcatch.ogg b/sound/voice/mcatch.ogg
new file mode 100644
index 00000000000..07b8aaab75c
Binary files /dev/null and b/sound/voice/mcatch.ogg differ
diff --git a/sound/voice/mcoming.ogg b/sound/voice/mcoming.ogg
new file mode 100644
index 00000000000..d3eb9e467f4
Binary files /dev/null and b/sound/voice/mcoming.ogg differ
diff --git a/sound/voice/mdelicious.ogg b/sound/voice/mdelicious.ogg
new file mode 100644
index 00000000000..5158538580e
Binary files /dev/null and b/sound/voice/mdelicious.ogg differ
diff --git a/sound/voice/mfeelbetter.ogg b/sound/voice/mfeelbetter.ogg
new file mode 100644
index 00000000000..fdbe57fd2e9
Binary files /dev/null and b/sound/voice/mfeelbetter.ogg differ
diff --git a/sound/voice/mflies.ogg b/sound/voice/mflies.ogg
new file mode 100644
index 00000000000..831281ebbee
Binary files /dev/null and b/sound/voice/mflies.ogg differ
diff --git a/sound/voice/mhelp.ogg b/sound/voice/mhelp.ogg
new file mode 100644
index 00000000000..516d5db068d
Binary files /dev/null and b/sound/voice/mhelp.ogg differ
diff --git a/sound/voice/minjured.ogg b/sound/voice/minjured.ogg
new file mode 100644
index 00000000000..0e968b3980c
Binary files /dev/null and b/sound/voice/minjured.ogg differ
diff --git a/sound/voice/minsult.ogg b/sound/voice/minsult.ogg
new file mode 100644
index 00000000000..017292977a1
Binary files /dev/null and b/sound/voice/minsult.ogg differ
diff --git a/sound/voice/mlive.ogg b/sound/voice/mlive.ogg
new file mode 100644
index 00000000000..ceb0dec9a34
Binary files /dev/null and b/sound/voice/mlive.ogg differ
diff --git a/sound/voice/mlost.ogg b/sound/voice/mlost.ogg
new file mode 100644
index 00000000000..7b332ac346a
Binary files /dev/null and b/sound/voice/mlost.ogg differ
diff --git a/sound/voice/mno.ogg b/sound/voice/mno.ogg
new file mode 100644
index 00000000000..030e43a0109
Binary files /dev/null and b/sound/voice/mno.ogg differ
diff --git a/sound/voice/mpatchedup.ogg b/sound/voice/mpatchedup.ogg
new file mode 100644
index 00000000000..1314f6ee471
Binary files /dev/null and b/sound/voice/mpatchedup.ogg differ
diff --git a/sound/voice/mradar.ogg b/sound/voice/mradar.ogg
new file mode 100644
index 00000000000..ad347a6d891
Binary files /dev/null and b/sound/voice/mradar.ogg differ
diff --git a/sound/voice/msurgeon.ogg b/sound/voice/msurgeon.ogg
new file mode 100644
index 00000000000..a300ee57ef6
Binary files /dev/null and b/sound/voice/msurgeon.ogg differ